Copy upstream release-38-1
Change-Id: I826e6439fc0edd14c213603a7c692d5183f49a79
diff --git a/tools/build.xml b/tools/build.xml
index 91cfa67..3b81928 100644
--- a/tools/build.xml
+++ b/tools/build.xml
@@ -1,7 +1,7 @@
<project name="CLDR Distribution" default="all" basedir=".">
<target name="init">
<tstamp/>
- <property name="version" value="37.0"/>
+ <property name="version" value="38.1"/>
<property name="dist.dir" value="dist"/>
<property name="dist.conf.dir" value="dist.conf"/>
<property name="excludes.file" value="${dist.conf.dir}/distExcludes.txt"/>
diff --git a/tools/cldr-unittest/.settings/org.eclipse.jdt.ui.prefs b/tools/cldr-unittest/.settings/org.eclipse.jdt.ui.prefs
index 07f0b5b..0785818 100644
--- a/tools/cldr-unittest/.settings/org.eclipse.jdt.ui.prefs
+++ b/tools/cldr-unittest/.settings/org.eclipse.jdt.ui.prefs
@@ -28,7 +28,7 @@
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=true
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
@@ -36,13 +36,15 @@
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=true
sp_cleanup.remove_redundant_type_arguments=true
-sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_imports=true
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
diff --git a/tools/cldr-unittest/build.xml b/tools/cldr-unittest/build.xml
index 3775348..a2d9700 100644
--- a/tools/cldr-unittest/build.xml
+++ b/tools/cldr-unittest/build.xml
@@ -17,7 +17,7 @@
<property name="doc.params" value="" />
<!-- Load local definitions from an optional properties file, if
- available. build.properties is NOT checked into SVN. -->
+ available. build.properties is NOT checked into version control. -->
<property file="build.properties" />
<!-- Load environment variables -->
<property environment="env" />
@@ -35,7 +35,7 @@
2) JVM_EXTRA_OPTIONS=xxx in build.properties
3) Environment variable - JVM_EXTRA_OPTIONS=xxx
4) Final fallback - "-Xmx6g" below -->
- <property name="env.JVM_EXTRA_OPTIONS" value="-Xmx6g" />
+ <property name="env.JVM_EXTRA_OPTIONS" value="-Xmx6g -enableassertions" />
<property name="JVM_EXTRA_OPTIONS" value="${env.JVM_EXTRA_OPTIONS}" />
<property name="jvm_options" value="${JVM_OPTIONS} ${JVM_EXTRA_OPTIONS}" />
@@ -43,6 +43,9 @@
<pathelement path="${java.class.path}/" />
<pathelement path="${build.dir}" />
<pathelement path="${CLDR_TOOLS}/classes" />
+ <!-- tools/java/dist/for-build/ can contain cldr.jar in lieu of the
+ classes dir. Must be earlier than other libs. -->
+ <fileset erroronmissingdir="false" dir="${CLDR_TOOLS}/dist/for-build" includes="cldr.jar" />
<fileset dir="${CLDR_TOOLS}/libs" includes="*.jar" /> <!-- all libs -->
</path>
</target>
@@ -92,6 +95,7 @@
<mkdir dir="${log.dir}" />
<javac srcdir="${src.dir}"
includes="org/unicode/cldr/**/*.java"
+ excludes="**/TestShim.java"
destdir="${build.dir}" classpathref="project.class.path" source="1.8"
target="1.8" debug="on" deprecation="off" includeantruntime="false"
encoding="UTF-8" />
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckLanguageCodeConverter.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckLanguageCodeConverter.java
index 5a1d7cb..3c0ac0f 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckLanguageCodeConverter.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckLanguageCodeConverter.java
@@ -103,7 +103,7 @@
}
}
- LikelySubtags likely = new LikelySubtags(supplementalDataInfo);
+ LikelySubtags likely = new LikelySubtags();
LanguageTagParser ltp = new LanguageTagParser();
// get targets of language aliases for macros
Map<String, String> macroToEncompassed = new HashMap<String, String>();
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckYear.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckYear.java
index e2f99fb..433dffc 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckYear.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/CheckYear.java
@@ -25,7 +25,7 @@
import org.unicode.cldr.util.With;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -365,7 +365,7 @@
PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY
+ "datecheck/", filename);
out.println("Name\tid\t"
- + CollectionUtilities.join(Category.values(), "\t"));
+ + Joiner.on("\t").join(Category.values()));
for (Entry<String, String> entry : sorted.entrySet()) {
String localeId = entry.getValue();
boolean priority = getPriority(localeId);
@@ -378,7 +378,7 @@
for (Category item : Category.values()) {
Set<String> items = localeInfo.category2base.get(item);
if (items != null) {
- out.print("\t" + CollectionUtilities.join(items, " "));
+ out.print("\t" + Joiner.on(" ").join(items));
} else {
out.print("\t");
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/DataDrivenTestHelper.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/DataDrivenTestHelper.java
index 3a3fa25..3ee29e4 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/DataDrivenTestHelper.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/DataDrivenTestHelper.java
@@ -8,10 +8,10 @@
import org.unicode.cldr.draft.FileUtilities;
+import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.util.ICUUncheckedIOException;
abstract public class DataDrivenTestHelper {
@@ -44,7 +44,7 @@
} else {
String first = components.iterator().next();
String sep = first.startsWith("@") ? "=" : SEPARATOR;
- out.append(CollectionUtilities.join(components, sep));
+ out.append(Joiner.on(sep).join(components));
if (!comment.isEmpty()) {
out.append("\t# ").append(comment);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LanguageInfoTest.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LanguageInfoTest.java
index 25a8f94..53825e4 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LanguageInfoTest.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LanguageInfoTest.java
@@ -42,7 +42,7 @@
public void testGetData() {
Set<Pair<String, String>> alreadySeen = new HashSet<>();
- for (R4<String, String, Integer, Boolean> foo : testInfo.getSupplementalDataInfo().getLanguageMatcherData("written")) {
+ for (R4<String, String, Integer, Boolean> foo : testInfo.getSupplementalDataInfo().getLanguageMatcherData("written_new")) {
// assertTrue("check bounds", foo.get2() >= 0 && foo.get2() <= 100);
String desired = foo.get0();
@@ -75,7 +75,7 @@
}
public static String getName(String item) {
- return item.contains("*") ? "n/a" : testInfo.getEnglish().getName(item);
+ return item.contains("*") ? "n/a" : item.contains("$") ? item : testInfo.getEnglish().getName(item);
}
public static void main(String[] args) {
@@ -83,6 +83,9 @@
}
public void testBasics() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = new LocaleMatcher(LocalePriorityList
.add(ULocale.FRENCH).add(ULocale.UK).add(ULocale.ENGLISH)
.build(), data);
@@ -103,6 +106,9 @@
// "Problems with language matcher TestChinese.")) {
// return;
// }
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
LocaleMatcher matcher = new LocaleMatcher(LocalePriorityList.add(
"zh_CN, zh_TW, iw").build(), data);
ULocale taiwanChinese = new ULocale("zh_TW");
@@ -127,8 +133,10 @@
static final ULocale MUL = new ULocale("mul");
public void testFallbacks() {
-
- for (R4<String, String, Integer, Boolean> foo : testInfo.getSupplementalDataInfo().getLanguageMatcherData("written")) {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+ for (R4<String, String, Integer, Boolean> foo : testInfo.getSupplementalDataInfo().getLanguageMatcherData("written_new")) {
String rawDesired = foo.get0();
if (rawDesired.contains("*")) {
continue;
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LikelySubtagsTest.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LikelySubtagsTest.java
index 21ea72c..a7e5a96 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LikelySubtagsTest.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LikelySubtagsTest.java
@@ -34,8 +34,7 @@
.getInstance().getSupplementalDataInfo();
static final Map<String, String> likely = SUPPLEMENTAL_DATA_INFO
.getLikelySubtags();
- static final LikelySubtags LIKELY = new LikelySubtags(
- SUPPLEMENTAL_DATA_INFO, likely);
+ static final LikelySubtags LIKELY = new LikelySubtags();
public static void main(String[] args) {
new LikelySubtagsTest().run(args);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherShim.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherShim.java
index cc2b904..e637e13 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherShim.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherShim.java
@@ -12,7 +12,7 @@
static final SupplementalDataInfo INFO = CONFIG.getSupplementalDataInfo();
static final LanguageMatcherData LANGUAGE_MATCHER_DATA = new LanguageMatcherData();
static {
- for (R4<String, String, Integer, Boolean> foo : INFO.getLanguageMatcherData("written")) {
+ for (R4<String, String, Integer, Boolean> foo : INFO.getLanguageMatcherData("written_new")) {
LANGUAGE_MATCHER_DATA.addDistance(foo.get0(), foo.get1(), foo.get2(), foo.get3());
}
LANGUAGE_MATCHER_DATA.freeze();
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherTest.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherTest.java
index c3e7956..ecf696f 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherTest.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/LocaleMatcherTest.java
@@ -52,6 +52,10 @@
}
public void testParentLocales() {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+
assertCloser("es_AR", "es_419", "es_ES");
assertCloser("es_AR", "es_419", "es");
@@ -106,6 +110,9 @@
// }
public void testChinese() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
ULocale taiwanChinese = new ULocale("zh_TW");
ULocale chinaChinese = new ULocale("zh_CN");
@@ -119,6 +126,10 @@
}
public void testenGB() {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+
final LocaleMatcher matcher = newLocaleMatcher("fr, en, en_GB, es_MX, es_419, es");
assertEquals("en_GB", matcher.getBestMatch("en_NZ").toString());
assertEquals("es", matcher.getBestMatch("es_ES").toString());
@@ -127,12 +138,18 @@
}
public void testFallbacks() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
LocalePriorityList lpl = LocalePriorityList.add("en, hi").build();
final LocaleMatcher matcher = newLocaleMatcher(lpl, null, 0.09);
assertEquals("hi", matcher.getBestMatch("sa").toString());
}
public void testOverrideData() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
double threshold = 0.05;
LanguageMatcherData localeMatcherData = new LanguageMatcherData()
.addDistance("br", "fr", 10, true)
@@ -154,6 +171,9 @@
}
public void testBasics() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(ULocale.FRENCH).add(ULocale.UK)
.add(ULocale.ENGLISH).build());
logln(matcher.toString());
@@ -165,6 +185,9 @@
}
public void testFallback() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// check that script fallbacks are handled right
final LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant"));
@@ -175,6 +198,9 @@
}
public void testSpecials() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// check that nearby languages are handled
final LocaleMatcher matcher = newLocaleMatcher("en, fil, ro, nn");
assertEquals(new ULocale("fil"), matcher.getBestMatch("tl"));
@@ -185,6 +211,10 @@
}
public void testRegionalSpecials() {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+
// verify that en_AU is closer to en_GB than to en (which is en_US)
final LocaleMatcher matcher = newLocaleMatcher("en, en_GB, es, es_419");
assertEquals("es_MX in {en, en_GB, es, es_419}", new ULocale("es_419"), matcher.getBestMatch("es_MX"));
@@ -193,6 +223,10 @@
}
public void testHK() {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+
// HK and MO are closer to each other for Hant than to TW
final LocaleMatcher matcher = newLocaleMatcher("zh, zh_TW, zh_MO");
assertEquals("zh_HK in {zh, zh_TW, zh_MO}", ZH_MO, matcher.getBestMatch("zh_HK"));
@@ -201,6 +235,9 @@
}
public void TestLocaleMatcherCoverage() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// Add tests for better code coverage
LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(null, 0).build(), null);
logln(matcher.toString());
@@ -227,6 +264,9 @@
}
public void testEmpty() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("");
assertNull(matcher.getBestMatch(ULocale.FRENCH));
}
@@ -234,11 +274,17 @@
static final ULocale ENGLISH_CANADA = new ULocale("en_CA");
public void testMatch_exact() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
assertEquals(1.0,
LocaleMatcher.match(ENGLISH_CANADA, ENGLISH_CANADA));
}
public void testMatch_none() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
double match = LocaleMatcher.match(
new ULocale("ar_MK"),
ENGLISH_CANADA);
@@ -247,6 +293,9 @@
}
public void testMatch_matchOnMazimized() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
ULocale undTw = new ULocale("und_TW");
ULocale zhHant = new ULocale("zh_Hant");
double matchZh = LocaleMatcher.match(undTw, new ULocale("zh"));
@@ -264,18 +313,27 @@
matchEnHantTw < matchZh);
}
- public void testMatchGrandfatheredCode() {
+ public void testMatchLegacyCode() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("fr, i_klingon, en_Latn_US");
assertEquals("en_Latn_US", matcher.getBestMatch("en_GB_oed").toString());
// assertEquals("tlh", matcher.getBestMatch("i_klingon").toString());
}
public void testGetBestMatchForList_exactMatch() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
assertEquals("ja", matcher.getBestMatch("ja, de").toString());
}
public void testGetBestMatchForList_simpleVariantMatch() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
// Intentionally avoiding a perfect_match or two candidates for variant
// matches.
@@ -285,6 +343,9 @@
}
public void testGetBestMatchForList_matchOnMaximized() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("en, ja");
// final LocaleMatcher matcher =
// newLocaleMatcher("fr, en, ja, es_ES, es_MX");
@@ -304,6 +365,9 @@
}
public void testGetBestMatchForList_noMatchOnMaximized() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// Regression test for http://b/5714572 .
final LocaleMatcher matcher = newLocaleMatcher("en, de, fr, ja");
// de maximizes to de_DE. Pick the exact match for the secondary
@@ -312,6 +376,9 @@
}
public void testBestMatchForTraditionalChinese() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// Scenario: An application that only supports Simplified Chinese (and
// some other languages),
// but does not support Traditional Chinese. zh_Hans_CN could be
@@ -341,6 +408,9 @@
}
public void testUndefined() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// When the undefined language doesn't match anything in the list,
// getBestMatch returns
// the default, as usual.
@@ -377,6 +447,9 @@
// }
public void testGetBestMatch_googlePseudoLocales() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
// Google pseudo locales are primarily based on variant subtags.
// See http://sites/intl_eng/pseudo_locales.
// (See below for the region code based fall back options.)
@@ -389,6 +462,10 @@
}
public void testGetBestMatch_regionDistance() {
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
+
LocaleMatcher matcher = newLocaleMatcher("es_AR, es");
assertEquals("es_AR", matcher.getBestMatch("es_MX").toString());
@@ -420,8 +497,11 @@
* itself most closely
*/
public void testExactMatches() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
String lastBase = "";
- TreeSet<ULocale> sorted = new TreeSet<ULocale>();
+ TreeSet<ULocale> sorted = new TreeSet<>();
for (ULocale loc : ULocale.getAvailableLocales()) {
String language = loc.getLanguage();
if (!lastBase.equals(language)) {
@@ -480,9 +560,9 @@
// }
public void testGetBestMatchForList_matchOnMaximized2() {
-// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
-// return;
-// }
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("fr, en-GB, ja, es-ES, es-MX");
// ja-JP matches ja on likely subtags, and it's listed first, thus it wins over
// thus it wins over the second preference en-GB.
@@ -494,20 +574,18 @@
}
public void testGetBestMatchForList_closeEnoughMatchOnMaximized() {
-// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
-// return;
-// }
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("en-GB, en, de, fr, ja");
assertEquals("de", matcher.getBestMatch("de-CH, fr").toString());
assertEquals("en", matcher.getBestMatch("en-US, ar, nl, de, ja").toString());
}
public void testGetBestMatchForPortuguese() {
-
-// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
-// return;
-// }
-
+ if (logKnownIssue("ICU-21241", "waiting on LocaleMatcherData update")) {
+ return;
+ }
final LocaleMatcher withPTExplicit = newLocaleMatcher("pt_PT, pt_BR, es, es_419");
final LocaleMatcher withPTImplicit = newLocaleMatcher("pt_PT, pt, es, es_419");
// Could happen because "pt_BR" is a tier_1 language and "pt_PT" is tier_2.
@@ -533,23 +611,26 @@
}
public void testVariantWithScriptMatch() {
-// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
-// return;
-// }
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("fr, en, sv");
assertEquals("en", matcher.getBestMatch("en-GB").toString());
assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
}
public void testVariantWithScriptMatch2() {
-// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
-// return;
-// }
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final LocaleMatcher matcher = newLocaleMatcher("en, sv");
assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
}
public void testPerf() {
+ if (logKnownIssue("CLDR-14166", "Skip until CLDR updated for new ICU4J LocaleMatcher")) {
+ return;
+ }
final String desired = "sv, en";
final LocaleMatcher matcherShort = newLocaleMatcher(desired);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/ObjectMatcherFactory.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/ObjectMatcherFactory.java
index 9831330..7396f4a 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/ObjectMatcherFactory.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/ObjectMatcherFactory.java
@@ -3,12 +3,12 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.unicode.cldr.util.PatternCache;
import com.google.common.base.Splitter;
-import com.ibm.icu.dev.util.CollectionUtilities.ObjectMatcher;
/**
* Factory for ObjectMatchers that are not tightly coupled
@@ -23,7 +23,7 @@
* @param pattern
* @return
*/
- public static ObjectMatcher<String> createRegexMatcher(String pattern) {
+ public static Predicate<String> createRegexMatcher(String pattern) {
return new RegexMatcher().set(pattern);
}
@@ -34,7 +34,7 @@
* @param flags
* @return
*/
- public static ObjectMatcher<String> createRegexMatcher(String pattern,
+ public static Predicate<String> createRegexMatcher(String pattern,
int flags) {
return new RegexMatcher().set(pattern, flags);
}
@@ -45,18 +45,18 @@
* @param col
* @return
*/
- public static ObjectMatcher<String> createCollectionMatcher(
+ public static Predicate<String> createCollectionMatcher(
Collection<String> col) {
return new CollectionMatcher().set(col);
}
- public static ObjectMatcher<String> createOrMatcher(
- ObjectMatcher<String> m1, ObjectMatcher<String> m2) {
+ public static Predicate<String> createOrMatcher(
+ Predicate<String> m1, Predicate<String> m2) {
return new OrMatcher().set(m1, m2);
}
- public static ObjectMatcher<String> createListMatcher(
- ObjectMatcher<String> matcher) {
+ public static Predicate<String> createListMatcher(
+ Predicate<String> matcher) {
return new ListMatcher().set(matcher);
}
@@ -65,7 +65,7 @@
*
* @return
*/
- public static ObjectMatcher<String> createDefaultingMatcher(boolean retVal) {
+ public static Predicate<String> createDefaultingMatcher(boolean retVal) {
return new DefaultingMatcher(retVal);
}
@@ -78,7 +78,7 @@
* @param valueIfAbsent
* @return
*/
- public static ObjectMatcher<String> createNullHandlingMatcher(
+ public static Predicate<String> createNullHandlingMatcher(
Map<String, ObjectMatcherFactory.MatcherPattern> m, String key,
boolean valueIfAbsent) {
return new NullHandlingMatcher(m, key, valueIfAbsent);
@@ -91,74 +91,78 @@
* @param toMatch
* @return
*/
- public static ObjectMatcher<String> createStringMatcher(String toMatch) {
+ public static Predicate<String> createStringMatcher(String toMatch) {
return new StringMatcher(toMatch);
}
- private static class RegexMatcher implements ObjectMatcher<String> {
+ private static class RegexMatcher implements Predicate<String> {
private java.util.regex.Matcher matcher;
- public ObjectMatcher<String> set(String pattern) {
+ public Predicate<String> set(String pattern) {
matcher = PatternCache.get(pattern).matcher("");
return this;
}
- public ObjectMatcher<String> set(String pattern, int flags) {
+ public Predicate<String> set(String pattern, int flags) {
matcher = Pattern.compile(pattern, flags).matcher("");
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
matcher.reset(value.toString());
return matcher.matches();
}
}
- private static class CollectionMatcher implements ObjectMatcher<String> {
+ private static class CollectionMatcher implements Predicate<String> {
private Collection<String> collection;
- public ObjectMatcher<String> set(Collection<String> collection) {
+ public Predicate<String> set(Collection<String> collection) {
this.collection = collection;
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
return collection.contains(value);
}
}
- private static class OrMatcher implements ObjectMatcher<String> {
- private ObjectMatcher<String> a;
- private ObjectMatcher<String> b;
+ private static class OrMatcher implements Predicate<String> {
+ private Predicate<String> a;
+ private Predicate<String> b;
- public ObjectMatcher<String> set(ObjectMatcher<String> a,
- ObjectMatcher<String> b) {
+ public Predicate<String> set(Predicate<String> a,
+ Predicate<String> b) {
this.a = a;
this.b = b;
return this;
}
- public boolean matches(String value) {
- return a.matches(value) || b.matches(value);
+ @Override
+ public boolean test(String value) {
+ return a.test(value) || b.test(value);
}
}
- private static class ListMatcher implements ObjectMatcher<String> {
- private ObjectMatcher<String> other;
+ private static class ListMatcher implements Predicate<String> {
+ private Predicate<String> other;
private static final Splitter WHITESPACE_SPLITTER = Splitter
.on(PatternCache.get("\\s+"));
- public ObjectMatcher<String> set(ObjectMatcher<String> other) {
+ public Predicate<String> set(Predicate<String> other) {
this.other = other;
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
List<String> values = WHITESPACE_SPLITTER.splitToList(value.trim());
if (values.size() == 1 && values.get(0).length() == 0)
return true;
for (String toMatch : values) {
- if (!other.matches(toMatch)) {
+ if (!other.test(toMatch)) {
return false;
}
}
@@ -166,21 +170,22 @@
}
}
- private static class DefaultingMatcher implements ObjectMatcher<String> {
+ private static class DefaultingMatcher implements Predicate<String> {
private final boolean defaultValue;
public DefaultingMatcher(boolean val) {
defaultValue = val;
}
- public boolean matches(String o) {
+ @Override
+ public boolean test(String o) {
return defaultValue;
}
}
- private static class NullHandlingMatcher implements ObjectMatcher<String> {
+ private static class NullHandlingMatcher implements Predicate<String> {
- final ObjectMatcher<String> matcher;
+ final Predicate<String> matcher;
public NullHandlingMatcher(
Map<String, ObjectMatcherFactory.MatcherPattern> col,
@@ -191,23 +196,24 @@
}
@Override
- public boolean matches(String o) {
- return matcher.matches(o);
+ public boolean test(String o) {
+ return matcher.test(o);
}
}
public static class MatcherPattern {
public String value;
- public ObjectMatcher<String> matcher;
+ public Predicate<String> matcher;
public String pattern;
+ @Override
public String toString() {
return matcher.getClass().getName() + "\t" + pattern;
}
}
- private static class StringMatcher implements ObjectMatcher<String> {
+ private static class StringMatcher implements Predicate<String> {
private final String value;
public StringMatcher(String value) {
@@ -215,7 +221,7 @@
}
@Override
- public boolean matches(String o) {
+ public boolean test(String o) {
return o.equals(value);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/RegexTransform.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/RegexTransform.java
index 901592c..f61c13b 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/RegexTransform.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/RegexTransform.java
@@ -18,6 +18,7 @@
private final Processing processing;
private final List<Row.R2<Matcher, String>> entries = new ArrayList<Row.R2<Matcher, String>>();
+ @Override
public String transform(String source) {
main: while (true) {
for (R2<Matcher, String> entry : entries) {
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAll.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAll.java
index 476cb43..3f0cace 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAll.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAll.java
@@ -134,6 +134,7 @@
millis = (int) (m - (seconds * 1000));
}
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (hours > 0) {
@@ -157,6 +158,16 @@
}
public static void main(String[] args) {
+ int errCount = runTests(args);
+ if (errCount != 0) {
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Run all tests, but do not System.exit at the end.
+ */
+ public static int runTests(String[] args) {
final boolean doTimeStamps = false;
TimeStampingPrintWriter tspw = new TimeStampingPrintWriter(System.out);
if (!doTimeStamps) {
@@ -171,9 +182,7 @@
sb.append("Tests took ");
sb.append(dispBean.toString());
System.out.println(sb.toString());
- if (errCount != 0) {
- System.exit(1);
- }
+ return errCount;
}
public TestAll() {
@@ -226,6 +235,8 @@
"org.unicode.cldr.unittest.TestCldrFactory",
"org.unicode.cldr.unittest.TestUnContainment",
"org.unicode.cldr.unittest.TestUnits",
+ "org.unicode.cldr.unittest.TestNumbers",
+ "org.unicode.cldr.unittest.TestLocaleCanonicalizer",
// "org.unicode.cldr.unittest.TestCollators" See Ticket #8288
"org.unicode.cldr.api.AllTests",
},
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAlt.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAlt.java
index 3592e31..be84f35 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAlt.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAlt.java
@@ -14,10 +14,10 @@
import org.unicode.cldr.util.PathStarrer;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R4;
import com.ibm.icu.util.Output;
@@ -70,7 +70,7 @@
}
}
for (Entry<String, Collection<R4<String, String, String, String>>> entry : altStarred.asMap().entrySet()) {
- System.out.println(entry.getKey() + "\t" + CollectionUtilities.join(entry.getValue(), "\t"));
+ System.out.println(entry.getKey() + "\t" + Joiner.on("\t").join(entry.getValue()));
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAnnotations.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAnnotations.java
index b7af13e..8212baa 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAnnotations.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAnnotations.java
@@ -16,6 +16,7 @@
import java.util.TreeSet;
import java.util.regex.Pattern;
+import org.unicode.cldr.test.CoverageLevel2;
import org.unicode.cldr.util.Annotations;
import org.unicode.cldr.util.Annotations.AnnotationSet;
import org.unicode.cldr.util.CLDRConfig;
@@ -24,20 +25,21 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Emoji;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.PathHeader.PageId;
import org.unicode.cldr.util.SimpleFactory;
+import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.XListFormatter;
import org.unicode.cldr.util.XListFormatter.ListTypeLength;
import com.google.common.base.CharMatcher;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.dev.util.UnicodeMap;
-import com.ibm.icu.dev.util.UnicodeMap.EntryRange;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R3;
import com.ibm.icu.impl.Row.R4;
@@ -48,9 +50,6 @@
public class TestAnnotations extends TestFmwkPlus {
private static final boolean DEBUG = false;
- private static final boolean SHOW_LIST = false;
- private static final boolean SHOW_ENGLISH = false;
-
public static void main(String[] args) {
new TestAnnotations().run(args);
}
@@ -101,19 +100,6 @@
}
}
- public void TestList() {
- if (!SHOW_LIST) {
- return;
- }
- if (isVerbose()) {
- for (String locale : Annotations.getAvailable()) {
- for (EntryRange<Annotations> s : Annotations.getData(locale).entryRanges()) {
- logln(s.toString());
- }
- }
- }
- }
-
final AnnotationSet eng = Annotations.getDataSet("en");
public void TestNames() {
@@ -134,10 +120,10 @@
{ "👩👩👧", "family: woman, woman, girl", "family | woman | girl" },
{ "👦🏻", "boy: light skin tone", "boy | young | light skin tone" },
{ "👩🏿", "woman: dark skin tone", "adult | woman | dark skin tone" },
- { "👨⚖", "man judge", "justice | man | man judge | scales" },
- { "👨🏿⚖", "man judge: dark skin tone", "justice | man | man judge | scales | dark skin tone" },
- { "👩⚖", "woman judge", "judge | scales | woman" },
- { "👩🏼⚖", "woman judge: medium-light skin tone", "judge | scales | woman | medium-light skin tone" },
+ { "👨⚖", "man judge", "justice | man | judge | scales" },
+ { "👨🏿⚖", "man judge: dark skin tone", "justice | man | judge | scales | dark skin tone" },
+ { "👩⚖", "woman judge", "judge | justice | scales | woman" },
+ { "👩🏼⚖", "woman judge: medium-light skin tone", "judge | justice | scales | woman | medium-light skin tone" },
{ "👮", "police officer", "cop | officer | police" },
{ "👮🏿", "police officer: dark skin tone", "cop | officer | police | dark skin tone" },
{ "👮♂️", "man police officer", "cop | man | officer | police" },
@@ -171,7 +157,7 @@
final Set<String> keywords = eng.getKeywords(emoji);
System.out.println("{\"" + emoji
+ "\",\"" + shortName
- + "\",\"" + CollectionUtilities.join(keywords, " | ")
+ + "\",\"" + Joiner.on(" | ").join(keywords)
+ "\"},");
}
}
@@ -191,7 +177,7 @@
}
}
}
-
+
public void TestCategories() {
if (DEBUG) System.out.println();
@@ -206,7 +192,8 @@
}
String minorCategory = Emoji.getMinorCategory(emoji);
long emojiOrder = Emoji.getEmojiToOrder(emoji);
- R3<String, String, String> row2 = Row.of(emoji, annotations.getShortName(), CollectionUtilities.join(annotations.getKeywords(), " | "));
+ R3<String, String, String> row2 = Row.of(emoji, annotations.getShortName(),
+ Joiner.on(" | ").join(annotations.getKeywords()));
R4<PageId, Long, String, R3<String, String, String>> row = Row.of(majorCategory, emojiOrder, minorCategory, row2);
sorted.add(row);
}
@@ -218,7 +205,7 @@
String emoji = row2.get0();
String shortName = row2.get1();
String keywords = row2.get2();
- if (DEBUG) System.out.println(majorCategory
+ if (DEBUG) System.out.println(majorCategory
+ "\t" + emojiOrder
+ "\t" + minorCategory
+ "\t" + emoji
@@ -229,87 +216,63 @@
}
public void TestUniqueness() {
-// if (logKnownIssue("cldrbug:10104", "Disable until the uniqueness problems are fixed")) {
-// return;
-// }
Set<String> locales = new TreeSet<>();
-
locales.add("en");
locales.addAll(Annotations.getAvailable());
locales.remove("root");
-// if (getInclusion() < 6) {
-// locales.retainAll(CLDRConfig.getInstance().getStandardCodes().getLocaleCoverageLocales(Organization.cldr));
-// }
- //locales.remove("sr_Latn");
- Multimap<String, String> localeToNameToEmoji = TreeMultimap.create();
- Multimap<String, String> nameToEmoji = TreeMultimap.create();
- UnicodeMap<Annotations> english = Annotations.getData("en");
- UnicodeSet englishKeys = getCurrent(english.keySet());
- Map<String, UnicodeSet> localeToMissing = new TreeMap<>();
+ /*
+ * Note: "problems" here is a work-around for what appears to be a deficiency
+ * in the function sourceLocation, involving the call stack. Seemingly sourceLocation
+ * can't handle the "->" notation used for parallelStream().forEach() if
+ * uniquePerLocale calls errln directly.
+ */
+ Set<String> problems = new HashSet<>();
+ locales.parallelStream().forEach(locale -> uniquePerLocale(locale, problems));
+ if (!problems.isEmpty()) {
+ problems.forEach(s -> errln(s));
+ }
+ }
- for (String locale : locales) {
- logln("uniqueness: " + locale);
- AnnotationSet data = Annotations.getDataSet(locale);
- nameToEmoji.clear();
- localeToMissing.put(locale, new UnicodeSet(englishKeys).removeAll(data.keySet()).freeze());
- for (String emoji : Emoji.getAllRgi()) { // Entry<String, Annotations> value : data.entrySet()) {
- String name = data.getShortName(emoji);
- if (name == null) {
- continue;
- }
- if (name.contains(CldrUtility.INHERITANCE_MARKER)) {
- throw new IllegalArgumentException(CldrUtility.INHERITANCE_MARKER + " in name of " + emoji + " in " + locale);
- }
- nameToEmoji.put(name, emoji);
+ private void uniquePerLocale(String locale, Set<String> problems) {
+ logln("uniqueness: " + locale);
+ Multimap<String, String> nameToEmoji = TreeMultimap.create();
+ AnnotationSet data = Annotations.getDataSet(locale);
+ for (String emoji : Emoji.getAllRgi()) {
+ String name = data.getShortName(emoji);
+ if (name == null) {
+ continue;
}
- for (Entry<String, Collection<String>> entry : nameToEmoji.asMap().entrySet()) {
- String name = entry.getKey();
- Collection<String> emojis = entry.getValue();
- if (emojis.size() > 1) {
- errln("Duplicate name in " + locale + ": “" + name + "” for "
- + CollectionUtilities.join(emojis, " & "));
- localeToNameToEmoji.putAll(locale + "\t" + name, emojis);
+ if (name.contains(CldrUtility.INHERITANCE_MARKER)) {
+ throw new IllegalArgumentException(CldrUtility.INHERITANCE_MARKER + " in name of " + emoji + " in " + locale);
+ }
+ nameToEmoji.put(name, emoji);
+ }
+ Multimap<String, String> duplicateNameToEmoji = null;
+ for (Entry<String, Collection<String>> entry : nameToEmoji.asMap().entrySet()) {
+ String name = entry.getKey();
+ Collection<String> emojis = entry.getValue();
+ if (emojis.size() > 1) {
+ synchronized(problems) {
+ if (problems.add("Duplicate name in " + locale + ": “" + name + "” for "
+ + Joiner.on(" & ").join(emojis))) {
+ int debug = 0;
+ }
}
+ if (duplicateNameToEmoji == null) {
+ duplicateNameToEmoji = TreeMultimap.create();
+ }
+ duplicateNameToEmoji.putAll(name, emojis);
}
}
- if (isVerbose() && !localeToNameToEmoji.isEmpty()) {
+ if (isVerbose() && duplicateNameToEmoji != null && !duplicateNameToEmoji.isEmpty()) {
System.out.println("\nCollisions");
- for (Entry<String, String> entry : localeToNameToEmoji.entries()) {
- String locale = entry.getKey();
+ for (Entry<String, String> entry : duplicateNameToEmoji.entries()) {
String emoji = entry.getValue();
System.out.println(locale
+ "\t" + eng.getShortName(emoji)
+ "\t" + emoji);
}
}
- if (SHOW_LIST && !localeToMissing.isEmpty()) {
- System.out.println("\nMissing");
- int count = 2;
- for (Entry<String, UnicodeSet> entry : localeToMissing.entrySet()) {
- String locale = entry.getKey();
- for (String emoji : entry.getValue()) {
- System.out.println(locale
- + "\t" + emoji
- + "\t" + eng.getShortName(emoji)
- + "\t" + "=GOOGLETRANSLATE(C" + count + ",\"en\",A" + count + ")"
- // =GOOGLETRANSLATE(C2,"en",A2)
- );
- ++count;
- }
- }
- }
-
- }
-
- private UnicodeSet getCurrent(UnicodeSet keySet) {
- UnicodeSet currentAge = new UnicodeSet("[:age=9.0:]");
- UnicodeSet result = new UnicodeSet();
- for (String s : keySet) {
- if (currentAge.containsAll(s)) {
- result.add(s);
- }
- }
- return result.freeze();
}
public void testAnnotationPaths() {
@@ -322,16 +285,21 @@
Pattern.compile("//ldml/annotations/annotation.*tts.*").matcher(""),
new TreeSet<>());
Set<String> annotationPathsExpected = Emoji.getNamePaths();
- checkAMinusBIsC("(" + locale + ".xml - Emoji.getNamePaths)", annotationPaths, annotationPathsExpected, Collections.<String> emptySet());
+ if (!checkAMinusBIsC("(" + locale + ".xml - Emoji.getNamePaths)", annotationPaths, annotationPathsExpected, Collections.<String> emptySet())) {
+ System.out.println("Check Emoji.SPECIALS");
+ }
checkAMinusBIsC("(Emoji.getNamePaths - " + locale + ".xml)", annotationPathsExpected, annotationPaths, Collections.<String> emptySet());
}
}
public void testEmojiImages() {
+ if (CLDRPaths.ANNOTATIONS_DIRECTORY.contains("cldr-staging/production/")) {
+ return; // don't bother checking production for this: the images are only in master, not production
+ }
Factory factoryAnnotations = SimpleFactory.make(CLDRPaths.ANNOTATIONS_DIRECTORY, ".*");
CLDRFile enAnnotations = factoryAnnotations.make("en", false);
- String emojiImageDir = CLDRPaths.BASE_DIRECTORY + "/tools/cldr-apps/WebContent/images/emoji";
- for (String emoji : Emoji.getNonConstructed()) {
+ String emojiImageDir = CLDRPaths.BASE_DIRECTORY + "/tools/cldr-apps/src/main/webapp/images/emoji";
+ for (String emoji : Emoji.getNonConstructed()) {
String noVs = emoji.replace(Emoji.EMOJI_VARIANT, "");
// example: emoji_1f1e7_1f1ec.png
@@ -386,11 +354,11 @@
int errorType = ERR;
if (logKnownIssue("cldr13660", "slightly out of order")) {
errorType = WARN;
- };
- msg("Out of order: "
- + lastEmoji + " (" + lastEmojiOrdering + ") " + lastName
- + " > "
- + emoji + " (" + emojiOrdering + ") " + name, errorType, true, true);
+ }
+ msg("Out of order: "
+ + lastEmoji + " (" + lastEmojiOrdering + ") " + lastName
+ + " > "
+ + emoji + " (" + emojiOrdering + ") " + name, errorType, true, true);
}
String major = Emoji.getMajorCategory(emoji);
@@ -401,7 +369,7 @@
String oldMajor = minorToMajor.get(minor);
// never get major1:minor1 and major2:minor1
if (oldMajor == null) {
- minorToMajor.put(minor, major);
+ minorToMajor.put(minor, major);
} else {
assertEquals(minor + " maps to different majors for " + Utility.hex(emoji), oldMajor, major);
}
@@ -440,6 +408,9 @@
public void testSuperfluousAnnotationPaths() {
+ if (CLDRPaths.ANNOTATIONS_DIRECTORY.contains("cldr-staging/production/")) {
+ return; // don't bother checking production for this: root is empty
+ }
Factory factoryAnnotations = SimpleFactory.make(CLDRPaths.ANNOTATIONS_DIRECTORY, ".*");
ImmutableSet<String> rootPaths = ImmutableSortedSet.copyOf(factoryAnnotations.make("root", false).iterator("//ldml/annotations/"));
@@ -460,7 +431,9 @@
for (String locale : factoryAnnotations.getAvailable()) {
ImmutableSet<String> currentPaths = ImmutableSortedSet.copyOf(factoryAnnotations.make(locale, false).iterator("//ldml/annotations/"));
Set<String> superfluous = setDifference(currentPaths, rootPaths);
- assertTrue("root contains " + locale, superfluous.isEmpty());
+ if (!assertTrue("root contains " + locale, superfluous.isEmpty())) {
+ int debug = 0;
+ }
allSuperfluous.addAll(superfluous);
for (String s : currentPaths) {
if (s.contains("\uFE0F")) {
@@ -485,7 +458,7 @@
return superfluous;
}
- private void checkAMinusBIsC(String title, Set<String> a, Set<String> b, Set<String> c) {
+ private boolean checkAMinusBIsC(String title, Set<String> a, Set<String> b, Set<String> c) {
Set<String> aMb = new TreeSet<>(a);
aMb.removeAll(b);
for (Iterator<String> it = aMb.iterator(); it.hasNext();) {
@@ -494,7 +467,7 @@
it.remove();
}
}
- assertEquals(title + " (" + aMb.size() + ")", c, aMb);
+ return assertEquals(title + " (" + aMb.size() + ")", c, aMb);
}
public void testListFormatter() {
@@ -515,4 +488,39 @@
assertEquals(test[0] + ", " + listTypeLength + ", " + source, expected, actual);
}
}
+
+ public void testCoverage() {
+ UnicodeMap<Level> levels = new UnicodeMap<>();
+ UnicodeSet shouldBeComprehensive = new UnicodeSet("[‾‽‸⁂↚↛↮↙↜↝↞↟↠↡↢↣↤↥↦↧↨↫↬↭↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇇⇈⇉⇊⇋⇌⇐⇍⇑⇒⇏⇓⇔⇎⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇵∀∂∃∅∉∋∎∏∑≮≯∓∕⁄∗∘∙∝∟∠∣∥∧∫∬∮∴∵∶∷∼∽∾≃≅≌≒≖≣≦≧≪≫≬≳≺≻⊁⊃⊆⊇⊕⊖⊗⊘⊙⊚⊛⊞⊟⊥⊮⊰⊱⋭⊶⊹⊿⋁⋂⋃⋅⋆⋈⋒⋘⋙⋮⋯⋰⋱■□▢▣▤▥▦▧▨▩▬▭▮▰△▴▵▷▸▹►▻▽▾▿◁◂◃◄◅◆◇◈◉◌◍◎◐◑◒◓◔◕◖◗◘◙◜◝◞◟◠◡◢◣◤◥◦◳◷◻◽◿⨧⨯⨼⩣⩽⪍⪚⪺₢₣₤₰₳₶₷₨﷼]").freeze();
+ for (String minorCategory : Emoji.getMinorCategoriesWithExtras()) {
+ for (String s : Emoji.getEmojiInMinorCategoriesWithExtras(minorCategory)) {
+ if (s.contentEquals("‾")) {
+ int debug = 0;
+ }
+ CoverageLevel2 coverageLevel = CoverageLevel2.getInstance(SupplementalDataInfo.getInstance(), "en");
+ final String pathKeyword = "//ldml/annotations/annotation[@cp=\"" + s + "\"]";
+ final String pathName = pathKeyword + "[@type=\"tts\"]";
+ Level levelKeyword = coverageLevel.getLevel(pathKeyword);
+ Level levelName = coverageLevel.getLevel(pathName);
+ assertEquals(s, levelName, levelKeyword);
+ levels.put(s, levelName);
+ }
+ }
+ for (Level level : Level.values()) {
+ UnicodeSet us = levels.getSet(level);
+ System.out.println(level + "\t" + us.size());
+ switch(level) {
+ case COMPREHENSIVE:
+ UnicodeSet us2 = new UnicodeSet(us).removeAll(us.strings());
+ assertEquals(level.toString(), shouldBeComprehensive.toPattern(false), us2.toPattern(false));
+ break;
+ case MODERN:
+ assertNotEquals(level.toString(), 0, us.size());
+ break;
+ default:
+ assertEquals(level.toString(), 0, us.size());
+ break;
+ }
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAttributeValues.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAttributeValues.java
index ff4830b..5b240a5 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAttributeValues.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestAttributeValues.java
@@ -23,6 +23,7 @@
import java.util.stream.Stream;
import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -45,9 +46,9 @@
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.StandardCodes.LstrField;
import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.StripUTF8BOMInputStream;
import org.unicode.cldr.util.SupplementalDataInfo.AttributeValidityInfo;
import org.unicode.cldr.util.Validity;
-import org.unicode.cldr.util.XMLFileReader.FilterBomInputStream;
import org.unicode.cldr.util.XPathParts;
import org.xml.sax.Attributes;
@@ -59,7 +60,6 @@
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Multimap;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row.R3;
import com.ibm.icu.util.ICUException;
import com.ibm.icu.util.Output;
@@ -84,7 +84,7 @@
String dtdTypeArg = params.props == null ? null : (String) params.props.get("dtdtype");
// short- circuits for testing. null means do all
- Set<DtdType> checkTypes = dtdTypeArg == null ? DtdType.STANDARD_SET
+ Set<DtdType> checkTypes = dtdTypeArg == null ? DtdType.STANDARD_SET
: Collections.singleton(DtdType.valueOf(dtdTypeArg)) ;
ImmutableSet<ValueStatus> showStatuses = null ; // ImmutableSet.of(ValueStatus.invalid, ValueStatus.unknown);
@@ -94,14 +94,14 @@
Set<String> files = new TreeSet<>();
for (String stringDir : dtdType.directories) {
addXMLFiles(dtdType, mainDirs + stringDir, files);
- if (isVerbose())
+ if (isVerbose())
synchronized (pathChecker.testLog) {
warnln(mainDirs + stringDir);
}
}
Stream<String> stream = SERIAL ? files.stream() : files.parallelStream();
stream.forEach(file -> checkFile(pathChecker, file));
-
+
// for (String file : files) {
// checkFile(pathChecker, file);
// }
@@ -134,7 +134,7 @@
return;
}
if (!dirFile.isDirectory()) {
- if (getInclusion() <= 5
+ if (getInclusion() <= 5
&& dtdType == DtdType.ldml) {
if (path.contains("/annotationsDerived/")) {
return;
@@ -171,7 +171,7 @@
try {
// should convert these over to new io.
try (InputStream fis0 = new FileInputStream(fullFile);
- InputStream fis = new FilterBomInputStream(fis0);
+ InputStream fis = new StripUTF8BOMInputStream(fis0);
InputStreamReader inputStreamReader = new InputStreamReader(fis, Charset.forName("UTF-8"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
) {
@@ -180,7 +180,7 @@
while(r.hasNext()) {
try {
switch(r.next()){
- case XMLStreamReader.START_ELEMENT:
+ case XMLStreamConstants.START_ELEMENT:
element = r.getLocalName();
++_elementCount;
int attributeSize = r.getAttributeCount();
@@ -215,7 +215,7 @@
}
static class PathChecker {
- private final ChainedMap.M5<ValueStatus, String, String, String, Boolean> valueStatusInfo
+ private final ChainedMap.M5<ValueStatus, String, String, String, Boolean> valueStatusInfo
= ChainedMap.of(new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), Boolean.class);
private final Set<String> seen = new HashSet<>();
private final Map<String,Map<String,Map<String,Boolean>>> seenEAV = new ConcurrentHashMap<>();
@@ -302,7 +302,7 @@
boolean haveProblems = false;
// if (testLog.logKnownIssue("cldrbug 10120", "Don't enable error until complete")) {
// testLog.warnln("Counts: " + counter.toString());
-// } else
+// } else
for (ValueStatus valueStatus : ValueStatus.values()) {
if (valueStatus == ValueStatus.valid) {
continue;
@@ -324,7 +324,7 @@
out.append("attribute\tCount:\t" + dtdData.dtdType + "\t" + attributeCount + "\n");
out.append("\nStatus\tDtdType\tElement\tAttribute\tMatch expression\t#Failures\tFailing values\n");
-
+
for (Entry<ValueStatus, Map<String, Map<String, Map<String, Boolean>>>> entry : valueStatusInfo) {
ValueStatus valueStatus = entry.getKey();
if (retain != null && !retain.contains(valueStatus)) {
@@ -340,17 +340,17 @@
Set<String> validFound = entry3.getValue().keySet();
String matchValue = matchValues.get(elementName + "\t" + attributeName);
out.append(
- valueStatus
- + "\t" + dtdData.dtdType
- + "\t" + elementName
- + "\t" + attributeName
+ valueStatus
+ + "\t" + dtdData.dtdType
+ + "\t" + elementName
+ + "\t" + attributeName
+ "\t" + (matchValue == null ? "" : matchValue)
+ "\t" + validFound.size()
- + "\t" + CollectionUtilities.join(validFound, ", ")
+ + "\t" + Joiner.on(", ").join(validFound)
+ "\n"
);
if (valueStatus == ValueStatus.valid) try {
- LstrType lstr = LstrType.valueOf(elementName);
+ LstrType lstr = LstrType.fromString(elementName);
Map<String, Validity.Status> codeToStatus = VALIDITY.getCodeToStatus(lstr);
Set<String> missing = new TreeSet<>(codeToStatus.keySet());
if (lstr == LstrType.variant) {
@@ -366,19 +366,19 @@
}
if (!missing.isEmpty()) {
out.append(
- "unused"
- + "\t" + dtdData.dtdType
- + "\t" + elementName
- + "\t" + attributeName
- + "\t" + ""
- + "\t" + ""
- + "\t" + CollectionUtilities.join(missing, ", ")
+ "unused"
+ + "\t" + dtdData.dtdType
+ + "\t" + elementName
+ + "\t" + attributeName
+ + "\t" + ""
+ + "\t" + ""
+ + "\t" + Joiner.on(", ").join(missing)
+ "\n"
);
}
} catch (Exception e) {}
}
- }
+ }
}
synchronized (testLog) {
testLog.errln(out.toString());
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBCP47.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBCP47.java
index cb914e7..994373d 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBCP47.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBCP47.java
@@ -46,20 +46,20 @@
String.class);
static {
for (String path : With.in(ENGLISH.iterator("//ldml/localeDisplayNames/keys/key"))) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path);
String value = ENGLISH.getStringValue(path);
String key = parts.getAttributeValue(-1, "type");
keyTypeTranslations.put(key, "", value);
}
for (String path : With.in(ENGLISH.iterator("//ldml/localeDisplayNames/types/type"))) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path);
String value = ENGLISH.getStringValue(path);
String key = parts.getAttributeValue(-1, "key");
String type = parts.getAttributeValue(-1, "type");
keyTypeTranslations.put(key, type, value);
}
for (String path : With.in(ENGLISH.iterator("//ldml/localeDisplayNames/transformNames/transformName"))) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path);
String value = ENGLISH.getStringValue(path);
String type = parts.getAttributeValue(-1, "type");
keyTypeTranslations.put("d0", type, value);
@@ -129,7 +129,7 @@
}
}
- static final ImmutableSet<String> SKIP_TYPES = ImmutableSet.of("REORDER_CODE", "RG_KEY_VALUE", "SUBDIVISION_CODE", "CODEPOINTS", "PRIVATE_USE");
+ static final ImmutableSet<String> SKIP_TYPES = ImmutableSet.of("REORDER_CODE", "RG_KEY_VALUE", "SCRIPT_CODE", "SUBDIVISION_CODE", "CODEPOINTS", "PRIVATE_USE");
private void checkKeyType(
String bcp47Key,
@@ -181,7 +181,7 @@
return "key: " + key + "\taliases: " + keyAliases + (type.isEmpty() ? "" : "\ttype: " + type + "\taliases: " + typeAliases) + "\tbcp: "
+ bcp47Description + ",\teng: " + eng;
}
-
+
static final Set<String> BOGUS_TZIDS = ImmutableSet.of(
"ACT", "AET", "AGT", "ART", "AST", "BET", "BST", "CAT", "CET", "CNT", "CST", "CTT", "EAT", "ECT", "EET", "Factory", "IET", "IST", "JST", "MET", "MIT",
"NET", "NST", "PLT", "PNT", "PRT", "PST", "SST", "SystemV/AST4", "SystemV/AST4ADT", "SystemV/CST6", "SystemV/CST6CDT", "SystemV/EST5",
@@ -212,7 +212,7 @@
}
}
}
-
+
warnln("CLDR deprecated bcp47 ids: " + deprecatedBcp47s);
warnln("CLDR deprecated tzids: " + deprecatedAliases);
@@ -250,7 +250,7 @@
} else if (!bcp47IdsNotUsed.isEmpty()) {
warnln("CLDR has unused (but deprecated) bcp47 ids: " + bcp47IdsNotUsed);
}
-
+
diff = new LinkedHashSet<>(missingAliases);
diff.removeAll(deprecatedAliases);
if (!diff.isEmpty()) {
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBagFormatter.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBagFormatter.java
index 3439ef3..25a58f9 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBagFormatter.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBagFormatter.java
@@ -71,6 +71,7 @@
}
static class NumberComparator implements Comparator {
+ @Override
public int compare(Object o1, Object o2) {
if (o1 == o2) return 0;
if (o1 == null) return 1;
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBasic.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBasic.java
index df09443..b802e57 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBasic.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestBasic.java
@@ -50,6 +50,7 @@
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.Pair;
import org.unicode.cldr.util.PathHeader;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
@@ -61,12 +62,12 @@
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
+import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -169,13 +170,13 @@
List<TimingInfo> data) throws IOException {
boolean deepCheck = getInclusion() >= 10;
File[] listFiles = directoryFile.listFiles();
- String canonicalPath = directoryFile.getCanonicalPath();
+ String normalizedPath = PathUtilities.getNormalizedPathString(directoryFile);
String indent = Utility.repeat("\t", level);
if (listFiles == null) {
throw new IllegalArgumentException(indent + "Empty directory: "
- + canonicalPath);
+ + normalizedPath);
}
- logln("Checking files for DTD errors in: " + indent + canonicalPath);
+ logln("Checking files for DTD errors in: " + indent + normalizedPath);
for (File fileName : listFiles) {
String name = fileName.getName();
if (CLDRConfig.isJunkFile(name)) {
@@ -318,16 +319,19 @@
}
class MyErrorHandler implements ErrorHandler {
+ @Override
public void error(SAXParseException exception) throws SAXException {
errln("error: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
errln("fatalError: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void warning(SAXParseException exception) throws SAXException {
errln("warning: " + XMLFileReader.showSAX(exception));
throw exception;
@@ -371,7 +375,7 @@
Set<String> currencies = testInfo.getStandardCodes().getAvailableCodes(
"currency");
- final UnicodeSet CHARACTERS_THAT_SHOULD_HAVE_FALLBACKS = (UnicodeSet) new UnicodeSet(
+ final UnicodeSet CHARACTERS_THAT_SHOULD_HAVE_FALLBACKS = new UnicodeSet(
"[[:sc:]-[\\u0000-\\u00FF]]").freeze();
CharacterFallbacks fallbacks = CharacterFallbacks.make();
@@ -381,7 +385,7 @@
if (file.isNonInheriting())
continue;
- final UnicodeSet OK_CURRENCY_FALLBACK = (UnicodeSet) new UnicodeSet(
+ final UnicodeSet OK_CURRENCY_FALLBACK = new UnicodeSet(
"[\\u0000-\\u00FF]").addAll(safeExemplars(file, ""))
.addAll(safeExemplars(file, "auxiliary"))
.freeze();
@@ -720,6 +724,14 @@
Set<String> defaultContents = Inheritance.defaultContents;
Multimap<String, String> parentToChildren = Inheritance.parentToChildren;
+ // Put a list of locales that should be default content here.
+ final String expectDC[] = {
+ "os_GE" // see CLDR-14118
+ };
+ for(final String locale : expectDC) {
+ assertTrue("expect "+locale+" to be a default content locale", defaultContents.contains(locale));
+ }
+
if (DEBUG) {
Inheritance.showChain("", "", "root");
}
@@ -895,9 +907,9 @@
int debug = 0;
}
if (leaves.size() == 1) {
- System.out.println(prefix + CollectionUtilities.join(presentation, " "));
+ System.out.println(prefix + Joiner.on(" ").join(presentation));
} else {
- System.out.println(prefix + "{" + CollectionUtilities.join(presentation, " ") + "}");
+ System.out.println(prefix + "{" + Joiner.on(" ").join(presentation) + "}");
}
}
for (String parent : parents) {
@@ -1447,7 +1459,7 @@
MyHandler myHandler = new MyHandler(overrideDtdType);
XMLFileReader xfr = new XMLFileReader().setHandler(myHandler);
try {
- myHandler.fileName = fileToRead.getCanonicalPath();
+ myHandler.fileName = PathUtilities.getNormalizedPathString(fileToRead);
xfr.read(myHandler.fileName, -1, true);
logln(myHandler.fileName);
} catch (Exception e) {
@@ -1475,6 +1487,7 @@
dtdType = overrideDtdType;
}
+ @Override
public void handlePathValue(String path, @SuppressWarnings("unused") String value) {
if (dtdType == null) {
try {
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRFile.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRFile.java
index 06ffc4d..3e6fdd8 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRFile.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRFile.java
@@ -1,6 +1,7 @@
package org.unicode.cldr.unittest;
import java.io.File;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -26,25 +27,37 @@
import org.unicode.cldr.util.CLDRLocale;
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.Counter;
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.GrammarInfo;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.PathHeader;
+import org.unicode.cldr.util.PathHeader.PageId;
+import org.unicode.cldr.util.PathHeader.SectionId;
import org.unicode.cldr.util.PatternCache;
+import org.unicode.cldr.util.PatternPlaceholders;
+import org.unicode.cldr.util.PatternPlaceholders.PlaceholderStatus;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.Relation;
+import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.UTF16;
+import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.Output;
public class TestCLDRFile extends TestFmwk {
@@ -81,6 +94,8 @@
static final Pattern COUNT_MATCHER = Pattern
.compile("\\[@count=\"([^\"]+)\"]");
+ static final UnicodeSet DIGITS = new UnicodeSet('0', '9').freeze();
+
private void checkPlurals(String locale) {
CLDRFile cldrFile = testInfo.getCLDRFile(locale, true);
Matcher m = COUNT_MATCHER.matcher("");
@@ -96,6 +111,9 @@
if (!m.reset(path).find()) {
throw new IllegalArgumentException();
}
+ if (DIGITS.containsAll(m.group(1))) {
+ continue;
+ }
String skeleton = path.substring(0, m.start(1)) + ".*"
+ path.substring(m.end(1));
skeletonToKeywords.put(skeleton, m.group(1));
@@ -113,7 +131,7 @@
static class LocaleInfo {
final String locale;
final CLDRFile cldrFile;
- final Set<String> paths = new HashSet<String>();
+ final Set<String> paths = new HashSet<>();
LocaleInfo(String locale) {
this.locale = locale;
@@ -132,8 +150,100 @@
}
}
+ static final boolean DEBUG = false;
+ static final boolean DEBUG_testExtraPaths = true;
+
public void testExtraPaths() {
- Map<String, LocaleInfo> localeInfos = new LinkedHashMap<String, LocaleInfo>();
+ // for debugging
+ final CLDRFile german = CLDRConfig.getInstance().getCldrFactory().make("de", true);
+ System.out.println();
+ Set<String> sorted = new TreeSet<>(german.getExtraPaths());
+ PathHeader.Factory phf = PathHeader.getFactory();
+ PatternPlaceholders pph = PatternPlaceholders.getInstance();
+
+ for (String path : sorted) {
+ if (DEBUG_testExtraPaths && path.equals("//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"acceleration-g-force\"]/unitPattern")) {
+ List<String> failures = new ArrayList<>();
+ phf.fromPath(path, failures );
+ }
+ PathHeader ph = phf.fromPath(path);
+ if (ph.getPageId() != PageId.Deprecated) {
+ assertNotEquals("bad placeholder: " + path + " ; " + ph, SectionId.Special, ph.getSectionId());
+ }
+ PlaceholderStatus phStatus = pph.getStatus(path);
+
+ PlaceholderStatus expected = path.contains("/metazone") || path.contains("/timeZoneNames") || path.contains("/gender")
+ || path.startsWith("//ldml/numbers/currencies/currency") ? PlaceholderStatus.DISALLOWED
+ : path.contains("/compoundUnitPattern1") ? PlaceholderStatus.REQUIRED
+ : PlaceholderStatus.LOCALE_DEPENDENT;
+ if (!assertEquals(path, expected, phStatus)) {
+ int debug = 0;
+ }
+
+ if (DEBUG) {
+ if (GrammaticalFeature.pathHasFeature(path) != null || path.endsWith("/gender")) {
+ System.out.println(path + "\t" + german.getStringValue(path));
+ String newPath = path.replace("[@case=\"accusative\"]", "");
+ if (!newPath.contentEquals(path) && !sorted.contains(newPath)) {
+ System.out.println(newPath + "\t" + german.getStringValue(newPath));
+ }
+ }
+ }
+ }
+
+ Set<String> badCoverage = new TreeSet<>();
+ Counter<String> extraPaths = new Counter<>();
+ final Factory fullCldrFactory = CLDRConfig.getInstance().getFullCldrFactory();
+
+ for (String locale : sdi.hasGrammarInfo()) {
+ if (sdi.getGrammarInfo(locale).hasInfo(GrammaticalTarget.nominal)) {
+ if (!fullCldrFactory.getAvailable().contains(locale)) {
+ if (CLDRConfig.SKIP_SEED) {
+ continue; // don't check if skipping seed, for production
+ }
+ }
+ final CLDRFile cldrFile = fullCldrFactory.make(locale, true);
+ Set<String> sorted2 = new TreeSet<>(cldrFile.getExtraPaths());
+ for (String path : sorted2) {
+ if (path.contains("/gender") || path.contains("@gender") || path.contains("@case")) {
+ Level level = sdi.getCoverageLevel(path, locale);
+ if (level.compareTo(Level.MODERN) > 0) {
+ badCoverage.add(path);
+ }
+ extraPaths.add(locale, 1);
+ }
+ }
+
+ }
+ }
+ System.out.println("Units with grammar info: " + GrammarInfo.SPECIAL_TRANSLATION_UNITS.size());
+ System.out.println("Inflection Paths");
+ for (R2<Long, String> locale : extraPaths.getEntrySetSortedByCount(false, null)) {
+ System.out.println(locale.get0() + "\t" + locale.get1());
+ }
+ if (!badCoverage.isEmpty()) {
+ errln("Paths not at modern: " + Joiner.on("\n\t").join(badCoverage));
+ }
+
+// Set<String> validUnits = Validity.getInstance().getStatusToCodes(LstrType.unit).get(Validity.Status.regular);
+// validUnits.forEach(System.out::println);
+//
+// grammarInfo = testInfo.getSupplementalDataInfo().getGrammarInfo();
+// for (Entry<String, GrammarInfo> entry : grammarInfo.entrySet()) {
+// System.out.println(entry);
+// }
+
+// CLDRFile toCheck = testInfo.getCldrFactory().make("de", true); // testInfo.getFullCldrFactory().make("en", false);
+// Set<String> sorted = new TreeSet<>(CLDRFile.getComparator(DtdType.ldml));
+// sorted.addAll(toCheck.getExtraPaths());
+// for (String path : sorted) {
+// XPathParts parts = XPathParts.getFrozenInstance(path);
+// assertEquals("parts: ", parts.toString(), path);
+// System.out.println(path);
+// }
+// int debug = 0;
+
+ Map<String, LocaleInfo> localeInfos = new LinkedHashMap<>();
Relation<String, String> missingPathsToLocales = Relation.of(
new TreeMap<String, Set<String>>(CLDRFile
.getComparator(DtdType.ldml)),
@@ -237,9 +347,11 @@
String originalLocale = englishInfo.cldrFile.getSourceLocaleID(
path, status);
String engName = "en"
- + (englishInfo.cldrFile.isHere(path) ? "" : " (source_locale:"
+ + (englishInfo.cldrFile.isHere(path) ? ""
+ : " (source_locale:"
+ originalLocale
- + (path.equals(status.pathWhereFound) ? "" : ", source_path: "
+ + (path.equals(status.pathWhereFound) ? ""
+ : ", source_path: "
+ status)
+ ")");
if (path.startsWith("//ldml/localeDisplayNames/")
@@ -367,7 +479,7 @@
}
private Set<String> getNonAliased(Set<String> paths, CLDRFile file) {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
for (String path : paths) {
if (file.isHere(path)) {
result.add(path);
@@ -426,10 +538,10 @@
CLDRFile cldrFileUnresolved = testInfo.getCLDRFile(locale, false);
Status status = new Status();
- Output<String> localeWhereFound = new Output<String>();
- Output<String> pathWhereFound = new Output<String>();
+ Output<String> localeWhereFound = new Output<>();
+ Output<String> pathWhereFound = new Output<>();
- Map<String, String> diff = new TreeMap<String, String>(
+ Map<String, String> diff = new TreeMap<>(
CLDRFile.getComparator(DtdType.ldml));
Size countSuperfluous = new Size();
@@ -437,8 +549,7 @@
Size countOrdinary = new Size();
for (String path : cldrFile.fullIterable()) {
- String baileyValue = cldrFile.getBaileyValue(path,
- pathWhereFound, localeWhereFound);
+ String baileyValue = cldrFile.getBaileyValue(path, pathWhereFound, localeWhereFound);
String topValue = cldrFileUnresolved.getStringValue(path);
String resolvedValue = cldrFile.getStringValue(path);
@@ -450,22 +561,34 @@
if (topValue != null && !CldrUtility.INHERITANCE_MARKER.equals(topValue)) {
assertEquals(
"top≠resolved\t" + locale + "\t" + phf.fromPath(path),
- topValue,
- resolvedValue);
+ topValue,
+ resolvedValue);
} else {
- String locale2 = cldrFile.getSourceLocaleID(path,
- status);
- assertEquals(
+ String locale2 = cldrFile.getSourceLocaleID(path, status);
+ if (!assertEquals(
"bailey value≠\t" + locale + "\t" + phf.fromPath(path),
- resolvedValue,
- baileyValue);
- assertEquals(
+ resolvedValue,
+ baileyValue)) {
+ int debug = 0;
+ baileyValue = cldrFile.getBaileyValue(path, pathWhereFound, localeWhereFound);
+ topValue = cldrFileUnresolved.getStringValue(path);
+ resolvedValue = cldrFile.getStringValue(path);
+ }
+ if (!assertEquals(
"bailey locale≠\t" + locale + "\t" + phf.fromPath(path),
- locale2,
- localeWhereFound.value);
- assertEquals(
+ locale2,
+ localeWhereFound.value)) {
+ baileyValue = cldrFile.getBaileyValue(path, pathWhereFound, localeWhereFound);
+ topValue = cldrFileUnresolved.getStringValue(path);
+ resolvedValue = cldrFile.getStringValue(path);
+ }
+ if (!assertEquals(
"bailey path≠\t" + locale + "\t" + phf.fromPath(path),
- status.pathWhereFound, pathWhereFound.value);
+ status.pathWhereFound, pathWhereFound.value)) {
+ baileyValue = cldrFile.getBaileyValue(path, pathWhereFound, localeWhereFound);
+ topValue = cldrFileUnresolved.getStringValue(path);
+ resolvedValue = cldrFile.getStringValue(path);
+ }
}
}
@@ -530,6 +653,9 @@
"COLLATION_DIRECTORY is not a directory: "
+ CLDRPaths.COLLATION_DIRECTORY);
}
+ if (CLDRConfig.SKIP_SEED) {
+ return;
+ }
File seedDir = new File(CLDRPaths.SEED_DIRECTORY);
if (!seedDir.isDirectory()) {
throw new IllegalArgumentException(
@@ -542,6 +668,7 @@
"SEED_COLLATION_DIRECTORY is not a directory: "
+ CLDRPaths.SEED_COLLATION_DIRECTORY);
}
+
File[] md = { mainDir, mainCollationDir };
File[] sd = { seedDir, seedCollationDir };
Factory mf = SimpleFactory.make(md, ".*", DraftStatus.unconfirmed);
@@ -560,7 +687,7 @@
TreeSet<String> mainList = new TreeSet<>(Arrays.asList(new File(CLDRPaths.MAIN_DIRECTORY).list()));
for (String dir : DtdType.ldml.directories) {
- Set<String> dirFiles = new TreeSet<String>(Arrays.asList(new File(CLDRPaths.BASE_DIRECTORY + "common/" + dir).list()));
+ Set<String> dirFiles = new TreeSet<>(Arrays.asList(new File(CLDRPaths.BASE_DIRECTORY + "common/" + dir).list()));
if (!mainList.containsAll(dirFiles)) {
dirFiles.removeAll(mainList);
errln(dir + " has extra files" + dirFiles);
@@ -617,7 +744,7 @@
}
}
- // establish that the parent of locale is somewhere in the same
+ // establish that the parent of locale is somewhere in the same
// assertEquals(dir + " locale file has minimal id: ", min, loc);
// if (!dir.endsWith("exemplars")) {
// continue;
@@ -694,7 +821,7 @@
}
String value = swissHighGerman.getStringValue(xpath);
if (value.indexOf('ß') >= 0) {
- System.err.println("«" + value + "» contains ß at " + xpath);
+ warnln("«" + value + "» contains ß at " + xpath);
}
}
}
@@ -702,8 +829,7 @@
public void TestExtraPaths() {
List<String> testCases = Arrays.asList(
"//ldml/localeDisplayNames/languages/language[@type=\"ccp\"]",
- "//ldml/dates/calendars/calendar[@type=\"generic\"]/dateTimeFormats/intervalFormats/intervalFormatItem[@id=\"Gy\"]/greatestDifference[@id=\"G\"]"
- );
+ "//ldml/dates/calendars/calendar[@type=\"generic\"]/dateTimeFormats/intervalFormats/intervalFormatItem[@id=\"Gy\"]/greatestDifference[@id=\"G\"]");
CLDRFile af = testInfo.getCldrFactory().make("af", true);
Set<String> missing = new HashSet<>(testCases);
CoverageLevel2 coverageLevel2 = CoverageLevel2.getInstance("af");
@@ -719,16 +845,22 @@
System.out.println(""
+ "\nPathHeader:\t" + ph
+ "\nValue:\t" + value
- + "\nLevel:\t" + level
- + "\nReq. Locale:\t" + "af"
+ + "\nLevel:\t" + level
+ + "\nReq. Locale:\t" + "af"
+ "\nSource Locale:\t" + source
- + "\nReq. XPath:\t" + xpath
- + "\nSource Path:\t" + status
- );
+ + "\nReq. XPath:\t" + xpath
+ + "\nSource Path:\t" + status);
missing.remove(xpath);
}
}
assertTrue("Should be empty", missing.isEmpty());
}
+ public void TestExtraPaths13954() {
+ CLDRFile es = cldrFactory.make("es", true);
+ CLDRFile es_US = cldrFactory.make("es_US", true);
+ if (!es_US.getRawExtraPaths().containsAll(es.getRawExtraPaths())) {
+ errln("Failure: " + Joiner.on('\n').join(Sets.difference(es.getRawExtraPaths(), es_US.getRawExtraPaths())));
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRLocaleCoverage.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRLocaleCoverage.java
index 050d988..f3b925e 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRLocaleCoverage.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRLocaleCoverage.java
@@ -28,13 +28,13 @@
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.text.UnicodeSet;
public class TestCLDRLocaleCoverage extends TestFmwkPlus {
@@ -171,7 +171,7 @@
}
private boolean assertContains(String title, Collection<String> set, Collection<String> subset) {
- boolean result = assertTrue(title, set.containsAll(subset));
+ boolean result = set.containsAll(subset);
if (!result) {
Set<String> temp = new LinkedHashSet<>(subset);
temp.removeAll(set);
@@ -179,8 +179,9 @@
for (String locale : temp) {
temp2.add(locale + "\t" + ENGLISH.getName(locale));
}
- warnln("Missing:\t" + temp.size() + "\n\t" + CollectionUtilities.join(temp2, "\n\t"));
+ warnln("Missing:\t" + temp.size() + "\n\t" + Joiner.on("\n\t").join(temp2));
}
+ assertTrue(title, result);
return result;
}
@@ -231,7 +232,7 @@
diff2.removeAll(skip);
if (!diff2.isEmpty()) {
String diffString = diff2.toString();
- String levelString = CollectionUtilities.join(level, "+");
+ String levelString = Joiner.on("+").join(level);
for (String localeId : diff2) {
diffString += "\n\t" + localeId + "\t" + CLDRConfig.getInstance().getEnglish().getName(localeId);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRUtils.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRUtils.java
index d7e1728..b285fa7 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRUtils.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCLDRUtils.java
@@ -29,6 +29,7 @@
public class TestCLDRUtils extends TestFmwk {
static Transform<String, String> SHORT_ALT_PICKER = new Transform<String, String>() {
+ @Override
public String transform(@SuppressWarnings("unused") String source) {
return "short";
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckCLDR.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckCLDR.java
index f3cbdec..a31014b 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckCLDR.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckCLDR.java
@@ -37,6 +37,7 @@
import org.unicode.cldr.util.CLDRInfo.PathValueInfo;
import org.unicode.cldr.util.CLDRInfo.UserInfo;
import org.unicode.cldr.util.CLDRLocale;
+import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Counter;
import org.unicode.cldr.util.DayPeriodInfo;
import org.unicode.cldr.util.DayPeriodInfo.DayPeriod;
@@ -59,6 +60,7 @@
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
import org.unicode.cldr.util.VoteResolver.VoterInfo;
+import org.unicode.cldr.util.XMLSource;
import com.google.common.collect.ImmutableSet;
import com.ibm.icu.dev.test.TestFmwk;
@@ -68,7 +70,7 @@
public class TestCheckCLDR extends TestFmwk {
static CLDRConfig testInfo = CLDRConfig.getInstance();
- private final Set<String> eightPointLocales = new TreeSet<String>(
+ private final Set<String> eightPointLocales = new TreeSet<>(
Arrays.asList("ar ca cs da de el es fi fr he hi hr hu id it ja ko lt lv nb nl pl pt pt_PT ro ru sk sl sr sv th tr uk vi zh zh_Hant".split(" ")));
public static void main(String[] args) {
@@ -108,8 +110,8 @@
public static void TestCheckConsistentCasing() {
CheckConsistentCasing c = new CheckConsistentCasing(
testInfo.getCldrFactory());
- Map<String, String> options = new LinkedHashMap<String, String>();
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ Map<String, String> options = new LinkedHashMap<>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
final CLDRFile english = testInfo.getEnglish();
c.setCldrFileToCheck(english, options, possibleErrors);
for (String path : english) {
@@ -126,7 +128,7 @@
CLDRLocale locale = CLDRLocale.getInstance(localeString);
CheckCLDR.Options checkCldrOptions = new Options(locale, Phase.SUBMISSION, "default", "basic");
TestCache testCache = new TestCache();
- testCache.setFactory(testInfo.getCldrFactory(), ".*");
+ testCache.setFactory(testInfo.getCldrFactory(), ".*");
TestResultBundle bundle = testCache.getBundle(checkCldrOptions);
final CLDRFile cldrFile = testInfo.getCLDRFile(localeString, true);
/*
@@ -140,7 +142,7 @@
int maxPathCount = (getInclusion() < 5) ? 1000 : 100000;
double[] deltaTime = {0, 0};
for (int i = 0; i < 2; i++) {
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
int pathCount = 0;
double startTime = System.currentTimeMillis();
for (String path : cldrFile) {
@@ -155,7 +157,7 @@
/*
* Expect possibleErrors to have size zero.
* A future enhancement of this test could modify some values to force errors,
- * and confirm that the errors are returned identically the first and second times.
+ * and confirm that the errors are returned identically the first and second times.
*/
assertEquals("possibleErrors, loop index " + i, possibleErrors.size(), 0);
}
@@ -178,7 +180,88 @@
private static final boolean DEBUG = true;
+ static final Factory cldrFactory = CLDRConfig.getInstance().getCldrFactory();
+
+ public void testPlaceholderSamples() {
+ CLDRFile root = cldrFactory.make("root", true);
+ String[][] tests = {
+ {"he", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"one\"]", "שנה"},
+ // test edge cases
+ // locale, path, value, 0..n Subtype errors
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "{0}huh?{1}"},
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "huh?", "missingPlaceholders"},
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "huh?{0}", "missingPlaceholders"},
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "huh?{1}", "missingPlaceholders", "gapsInPlaceholderNumbers"},
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "{0}huh?{1}{2}", "extraPlaceholders"},
+ {"en", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "{0}huh?{1}{0}", "duplicatePlaceholders"},
+
+ {"fr", "//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal=\"other\"]", "Prenez la e à droite.", "missingPlaceholders"},
+ {"fr", "//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal=\"other\"]", "Prenez la {0}e à droite."},
+
+ {"fr", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "jours", "missingPlaceholders"},
+ {"fr", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "{0} jours"},
+
+ {"cy", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "ci cath", "missingPlaceholders"},
+ {"cy", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "{0} ci"},
+ {"cy", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "{0} ci, {0} cath"},
+
+ {"pl", "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"accusative\"]", "biernik", "missingPlaceholders"},
+ {"pl", "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"accusative\"]", "{0} biernik"},
+
+ {"fr", "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"feminine\"]", "de genre féminin", "missingPlaceholders"},
+ {"fr", "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"feminine\"]", "la {0}"},
+
+ {"ar", "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"duration-hour\"]/unitPattern[@count=\"one\"]", "ساعة"},
+ {"ar", "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"duration-hour\"]/unitPattern[@count=\"one\"]", "{0} ساعة"},
+ {"ar", "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"duration-hour\"]/unitPattern[@count=\"one\"]", "{1}{0} ساعة", "extraPlaceholders"},
+
+ {"he", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"one\"]", "שנה"},
+ {"he", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"two\"]", "שנתיים"},
+ {"he", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"many\"]", "שנה", "missingPlaceholders"},
+ {"he", "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]", "שנים", "missingPlaceholders"},
+ };
+ for (String[] row : tests) {
+ String localeId = row[0];
+ String path = row[1];
+ String value = row[2];
+ Set<Subtype> expected = new TreeSet<>();
+ for (int i = 3; i < row.length; ++i) {
+ expected.add(Subtype.valueOf(row[i]));
+ }
+ List<CheckStatus> possibleErrors = new ArrayList<>();
+ checkPathValue(root, localeId, path, value, possibleErrors);
+ Set<Subtype> actual = new TreeSet<>();
+ for (CheckStatus item : possibleErrors) {
+ if (PatternPlaceholders.PLACEHOLDER_SUBTYPES.contains(item.getSubtype())) {
+ actual .add(item.getSubtype());
+ }
+ }
+ if (!assertEquals(Arrays.asList(row).toString(), expected, actual)) {
+ int debug = 0;
+ }
+ }
+ }
+
+ public void checkPathValue(CLDRFile root, String localeId, String path, String value, List<CheckStatus> possibleErrors) {
+ XMLSource localeSource = new SimpleXMLSource(localeId);
+ localeSource.putValueAtPath(path, value);
+
+ TestFactory currFactory = makeTestFactory(root, localeSource);
+ CLDRFile cldrFile = currFactory.make(localeSource.getLocaleID(), true);
+ CheckForExemplars check = new CheckForExemplars(currFactory);
+
+ Options options = new Options();
+ check.setCldrFileToCheck(cldrFile , options, possibleErrors);
+ check.handleCheck(path, path, value, options, possibleErrors);
+ }
+
public void TestPlaceholders() {
+ CheckCLDR.setDisplayInformation(english);
+ checkPlaceholders(english);
+ checkPlaceholders(factory.make("de", true));
+ }
+
+ public void checkPlaceholders(CLDRFile cldrFileToTest) {
// verify that every item with {0} has a pattern in pattern
// placeholders,
// and that every one generates an error in CheckCDLR for patterns when
@@ -190,14 +273,14 @@
.getInstance();
CheckCLDR test = CheckCLDR.getCheckAll(factory, ".*");
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
Options options = new Options();
- test.setCldrFileToCheck(english, options, possibleErrors);
- List<CheckStatus> result = new ArrayList<CheckStatus>();
+ test.setCldrFileToCheck(cldrFileToTest, options, possibleErrors);
+ List<CheckStatus> result = new ArrayList<>();
- PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(english);
- Set<PathHeader> sorted = new TreeSet<PathHeader>();
- for (String path : english.fullIterable()) {
+ PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(cldrFileToTest);
+ Set<PathHeader> sorted = new TreeSet<>();
+ for (String path : cldrFileToTest.fullIterable()) {
sorted.add(pathHeaderFactory.fromPath(path));
}
final String testPath = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"duration-day-future\"]/unitPattern[@count=\"0\"]";
@@ -205,9 +288,9 @@
for (PathHeader pathHeader : sorted) {
String path = pathHeader.getOriginalPath();
- String value = english.getStringValue(path);
+ String value = cldrFileToTest.getStringValue(path);
if (value == null) {
- value = "?";
+ continue;
}
boolean containsMessagePattern = messagePlaceholder.reset(value)
.find();
@@ -215,72 +298,35 @@
.get(path);
final PlaceholderStatus placeholderStatus = patternPlaceholders
.getStatus(path);
- if (containsMessagePattern && placeholderStatus == PlaceholderStatus.DISALLOWED
- || !containsMessagePattern && placeholderStatus == PlaceholderStatus.REQUIRED) {
- errln("Value (" + value + ") looks like placeholder = "
- + containsMessagePattern + ", but placeholder info = "
- + placeholderStatus + "\t" + path);
- continue;
- } else if (placeholderStatus != PlaceholderStatus.DISALLOWED) {
+ if (placeholderStatus == PlaceholderStatus.DISALLOWED) {
if (containsMessagePattern) {
- Set<String> found = new HashSet<String>();
- do {
- found.add(messagePlaceholder.group());
- } while (messagePlaceholder.find());
- if (!found.equals(placeholderInfo.keySet())) {
- // ^//ldml/characterLabels/characterLabelPattern[@type="category_list"] ; {0}=CATEGORY_TYPE family; {1}=REMAINING_ITEMS man, woman, girl
- if (path.equals("//ldml/characterLabels/characterLabelPattern[@type=\"category-list\"]")) {
- logKnownIssue("cldrbug:9534", "commenting out characterLabelPattern[@type=\"category-list\"] for now, pending real fix.");
- } else {
- errln("Value ("
- + value
- + ") has different placeholders than placeholder info ("
- + placeholderInfo.keySet() + ")\t" + path);
- }
- continue;
- } else {
- logln("placeholder info = " + placeholderInfo + "\t"
- + path);
- }
+ errln(cldrFileToTest.getLocaleID() + " Value (" + value + ") contains placeholder, but placeholder info = «" + placeholderStatus + "»\t" + path);
+ continue;
}
-
- // check that the error messages are right
-
- test.handleCheck(path, english.getFullXPath(path), "?",
- options, result);
- CheckStatus gotIt = null;
- for (CheckStatus i : result) {
- if (i.getSubtype() == Subtype.missingPlaceholders) {
- gotIt = i;
- }
+ } else { // not disallowed
+ if (!containsMessagePattern) {
+ errln(cldrFileToTest.getLocaleID() + " Value (" + value + ") contains placeholder, but placeholder info = «" + placeholderStatus + "»\t" + path);
+ continue;
}
- if (placeholderStatus == PlaceholderStatus.REQUIRED
- && gotIt == null) {
- errln("CheckForExemplars SHOULD have detected "
- + Subtype.missingPlaceholders + " for "
- + placeholderStatus + " in " + path);
- if (DEBUG) {
- test.handleCheck(path, english.getFullXPath(path), "?",
- options, result);
- }
- } else if (placeholderStatus == PlaceholderStatus.OPTIONAL
- && gotIt != null) {
- errln("CheckForExemplars should NOT have detected "
- + Subtype.missingPlaceholders + " for "
- + placeholderStatus + " in " + path);
- if (DEBUG) {
- test.handleCheck(path, english.getFullXPath(path), "?",
- options, result);
+ // get the set of placeholders
+ HashSet<String> found = new HashSet<>();
+ do {
+ found.add(messagePlaceholder.group()); // we loaded first one up above
+ } while (messagePlaceholder.find());
+
+ if (!found.equals(placeholderInfo.keySet())) {
+ if (placeholderStatus != PlaceholderStatus.LOCALE_DEPENDENT) {
+ errln(cldrFileToTest.getLocaleID() + " Value (" + value + ") has different placeholders than placeholder info «" + placeholderInfo.keySet() + "»\t" + path);
}
} else {
- logln("CheckForExemplars found " + result);
+ logln("placeholder info = " + placeholderInfo + "\t"
+ + path);
}
}
}
}
public void TestFullErrors() {
-
CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS);
CheckCLDR.setDisplayInformation(english);
@@ -291,9 +337,9 @@
public void TestAllLocales() {
CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS);
CheckCLDR.setDisplayInformation(english);
- Set<String> unique = new HashSet<String>();
+ Set<String> unique = new HashSet<>();
LanguageTagParser ltp = new LanguageTagParser();
- Set<String> locales = new HashSet<String>();
+ Set<String> locales = new HashSet<>();
for (String locale : getInclusion() <= 5 ? eightPointLocales : factory.getAvailable()) {
/*
* Only test locales without regions. E.g., test "pt", skip "pt_PT"
@@ -303,7 +349,7 @@
}
}
// With ICU4J libs of 2020-03-23, using locales.parallelStream().forEach below
- // hangs, or crashes with NPE. Likely an ICU4J issue, but we don't really need
+ // hangs, or crashes with NPE. Likely an ICU4J issue, but we don't really need
// parallelStream() here anyway since we are only handling around 35 locales.
// (And in fact this test seems faster without it)
locales.forEach(locale -> checkLocale(test, locale, null, unique));
@@ -314,7 +360,7 @@
CheckCLDR test = CheckCLDR.getCheckAll(factory, INDIVIDUAL_TESTS);
CheckCLDR.setDisplayInformation(english);
- Set<String> unique = new HashSet<String>();
+ Set<String> unique = new HashSet<>();
checkLocale(test, "ko", null, unique);
}
@@ -327,14 +373,14 @@
public void checkLocale(CheckCLDR test, CLDRFile nativeFile,
String dummyValue, Set<String> unique) {
String localeID = nativeFile.getLocaleID();
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
CheckCLDR.Options options = new CheckCLDR.Options();
test.setCldrFileToCheck(nativeFile, options, possibleErrors);
- List<CheckStatus> result = new ArrayList<CheckStatus>();
+ List<CheckStatus> result = new ArrayList<>();
CLDRFile patched = nativeFile; // new CLDRFile(override);
PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(english);
- Set<PathHeader> sorted = new TreeSet<PathHeader>();
+ Set<PathHeader> sorted = new TreeSet<>();
for (String path : patched) {
final PathHeader pathHeader = pathHeaderFactory.fromPath(path);
if (pathHeader != null) {
@@ -404,8 +450,8 @@
public void TestCheckNames() {
CheckCLDR c = new CheckNames();
- Map<String, String> options = new LinkedHashMap<String, String>();
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ Map<String, String> options = new LinkedHashMap<>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
final CLDRFile english = testInfo.getEnglish();
c.setCldrFileToCheck(english, options, possibleErrors);
String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"mga\"]";
@@ -427,7 +473,7 @@
// * run GenerateBirths (if you haven't done so)
// * look at readable results in the log file in CLDRPaths.TMP_DIRECTORY + "dropbox/births/"
// * for fr.txt (or may change locale)
- // * find a path that is outdated.
+ // * find a path that is outdated.
// * To work on both limited and full submissions, choose one with English = trunk
// * Sometimes the English change is suppressed in a limited release if the change is small. Pick another in that case.
// * check the data files to ensure that it is in fact outdated.
@@ -436,8 +482,8 @@
String locale = "fr";
String path = "//ldml/localeDisplayNames/territories/territory[@type=\"MO\"][@alt=\"short\"]";
CheckCLDR c = new CheckNew(testInfo.getCommonAndSeedAndMainAndAnnotationsFactory());
- List<CheckStatus> result = new ArrayList<CheckStatus>();
- Map<String, String> options = new HashMap<String, String>();
+ List<CheckStatus> result = new ArrayList<>();
+ Map<String, String> options = new HashMap<>();
c.setCldrFileToCheck(testInfo.getCLDRFile(locale, true), options, result);
c.check(path, path, "foobar", options, result);
for (CheckStatus status : result) {
@@ -453,6 +499,56 @@
errln("No failure message.");
}
+ public void TestCheckNewRootFailure() {
+ // Check that we get an error with the root value for an emoji.
+ final Factory annotationsFactory = testInfo.getAnnotationsFactory();
+ String locale = "yo"; // the name doesn't matter, since we're going to create a new one
+ String path = "//ldml/annotations/annotation[@cp=\"😀\"][@type=\"tts\"]";
+ CheckCLDR c = new CheckNew(annotationsFactory);
+ List<CheckStatus> result = new ArrayList<>();
+ Map<String, String> options = new HashMap<>();
+ for (Phase phase : Phase.values()) {
+ options.put(Options.Option.phase.getKey(), phase.toString());
+ for (String value : Arrays.asList("E10-836", CldrUtility.INHERITANCE_MARKER)) {
+
+ // make a fake locale, starting with real root
+
+ CLDRFile root = annotationsFactory.make("root", false);
+ XMLSource localeSource = new SimpleXMLSource(locale);
+ localeSource.putValueAtPath(path, value);
+
+ TestFactory currFactory = makeTestFactory(root, localeSource);
+ CLDRFile cldrFile = currFactory.make(localeSource.getLocaleID(), true);
+
+ c.setCldrFileToCheck(cldrFile, options, result);
+ c.check(path, path, value, options, result);
+ boolean gotOne = false;
+ for (CheckStatus status : result) {
+ if (status.getSubtype() == Subtype.valueMustBeOverridden) {
+ gotOne = true;
+ assertEquals(
+ phase + " Error message check",
+ "This value must be a real translation, NOT the name/keyword placeholder.",
+ status.getMessage());
+ }
+ }
+ if (!gotOne) {
+ errln(phase + " Missing failure message for value=" + value + "; path=" + path);
+ }
+ }
+ }
+ }
+
+ public TestFactory makeTestFactory(CLDRFile root, XMLSource localeSource) {
+ CLDRFile localeCldr = new CLDRFile(localeSource);
+
+ TestFactory factory = new TestFactory();
+ factory.addFile(root);
+ factory.addFile(localeCldr);
+ return factory;
+ }
+
+
public void TestCheckDates() {
CheckCLDR.setDisplayInformation(testInfo.getEnglish()); // just in case
String prefix = "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"";
@@ -461,7 +557,7 @@
TestFactory testFactory = new TestFactory();
- List<CheckStatus> result = new ArrayList<CheckStatus>();
+ List<CheckStatus> result = new ArrayList<>();
Options options = new Options();
final String collidingValue = "foobar";
@@ -628,7 +724,7 @@
Map<Key,Pair<Boolean,String>> actionToExamplePath = new TreeMap<>();
Counter<Key> counter = new Counter<>();
- for (String locale : Arrays.asList("jv", "fr", "vo")) {
+ for (String locale : Arrays.asList("jv", "fr", "nds")) {
DummyPathValueInfo dummyPathValueInfo = new DummyPathValueInfo();
dummyPathValueInfo.locale = CLDRLocale.getInstance(locale);
CLDRFile cldrFile = testInfo.getCldrFactory().make(locale, true);
@@ -652,9 +748,9 @@
dummyPathValueInfo.xpath = path;
dummyPathValueInfo.baselineValue = cldrFileUnresolved.getStringValue(path);
StatusAction action = phase.getShowRowAction(
- dummyPathValueInfo,
- InputMethod.DIRECT,
- surveyToolStatus,
+ dummyPathValueInfo,
+ InputMethod.DIRECT,
+ surveyToolStatus,
dummyUserInfo);
if (surveyToolStatus == SurveyToolStatus.HIDE) {
@@ -677,9 +773,9 @@
// for debugging
if (locale.equals("vo") && action == StatusAction.ALLOW) {
StatusAction action2 = phase.getShowRowAction(
- dummyPathValueInfo,
- InputMethod.DIRECT,
- surveyToolStatus,
+ dummyPathValueInfo,
+ InputMethod.DIRECT,
+ surveyToolStatus,
dummyUserInfo);
}
actionToExamplePath.put(key, Pair.of(dummyPathValueInfo.baselineValue != null, path));
@@ -716,11 +812,12 @@
// private static final CoverageInfo coverageInfo = new CoverageInfo(testInfo.getSupplementalDataInfo());
- private static final VoterInfo dummyVoterInfo = new VoterInfo(Organization.cldr,
- org.unicode.cldr.util.VoteResolver.Level.vetter,
+ private static final VoterInfo dummyVoterInfo = new VoterInfo(Organization.cldr,
+ org.unicode.cldr.util.VoteResolver.Level.vetter,
"somename");
private static final UserInfo dummyUserInfo = new UserInfo() {
+ @Override
public VoterInfo getVoterInfo() {
return dummyVoterInfo;
}
@@ -750,24 +847,31 @@
};
+ @Override
public Collection<? extends CandidateInfo> getValues() {
throw new UnsupportedOperationException();
}
+ @Override
public CandidateInfo getCurrentItem() {
return candidateInfo;
}
+ @Override
public String getBaselineValue() {
return baselineValue;
}
+ @Override
public Level getCoverageLevel() {
return Level.MODERN;
}
+ @Override
public boolean hadVotesSometimeThisRelease() {
throw new UnsupportedOperationException();
}
+ @Override
public CLDRLocale getLocale() {
return locale;
}
+ @Override
public String getXpath() {
return xpath;
}
@@ -826,9 +930,9 @@
case "sat": desiredScript = "Olck"; break;
case "mni": desiredScript = "Beng"; break;
case "chr": desiredScript = "Cher"; break;
- default:
- if (!explicitScript.isEmpty()) {
- desiredScript = explicitScript;
+ default:
+ if (!explicitScript.isEmpty()) {
+ desiredScript = explicitScript;
}
break;
}
@@ -838,13 +942,13 @@
}
final Set<String> sampleNewPaths = ImmutableSet.of(
- "//ldml/annotations/annotation[@cp=\\\"🐻❄\\\"][@type=\\\"tts\\\"]",
- "//ldml/annotations/annotation[@cp=\\\"√\\\"][@type=\\\"tts\\\"]",
- "//ldml/units/unitLength[@type=\\\"short\\\"]/compoundUnit[@type=\\\"10p-1\\\"]/unitPrefixPattern",
- "//ldml/localeDisplayNames/languages/language[@type=\\\"fa_AF\\\"]",
+ "//ldml/annotations/annotation[@cp=\\\"🐻❄\\\"][@type=\\\"tts\\\"]",
+ "//ldml/annotations/annotation[@cp=\\\"√\\\"][@type=\\\"tts\\\"]",
+ "//ldml/units/unitLength[@type=\\\"short\\\"]/compoundUnit[@type=\\\"10p-1\\\"]/unitPrefixPattern",
+ "//ldml/localeDisplayNames/languages/language[@type=\\\"fa_AF\\\"]",
"//ldml/units/unitLength[@type=\\\"long\\\"]/compoundUnit[@type=\\\"power2\\\"]/compoundUnitPattern1"
);
-
+
final Set<String> SAMPLE_EXCEPTIONAL_PATHS = ImmutableSet.of(
"//ldml/annotations/annotation[@cp=\"🤵\"]",
"//ldml/annotations/annotation[@cp=\"🤵♂\"][@type=\"tts\"]"
@@ -859,28 +963,52 @@
if (!CheckCLDR.LIMITED_SUBMISSION) {
return;
}
-
+
for (String path : sampleNewPaths) {
assertTrue(path, SubmissionLocales.allowEvenIfLimited("fr", path, false, true));
}
-
+
for (String path : SAMPLE_EXCEPTIONAL_PATHS) {
assertTrue(path, SubmissionLocales.allowEvenIfLimited("fr", path, false, false));
}
-
- assertFalse(sampleDisallowedInLimitedSubmission,
+
+ assertFalse(sampleDisallowedInLimitedSubmission,
SubmissionLocales.allowEvenIfLimited("fr", sampleDisallowedInLimitedSubmission, false, false));
// test non-cldr locale
-
+
for (String path : sampleNewPaths) {
assertFalse(path, SubmissionLocales.allowEvenIfLimited("xx", path, false, true));
}
for (String path : SAMPLE_EXCEPTIONAL_PATHS) {
assertFalse(path, SubmissionLocales.allowEvenIfLimited("xx", path, false, false));
}
-
+
// TODO enhance to check more conditions
// like old: assertFalse("vo, !engSame, !isError, !isMissing", SubmissionLocales.allowEvenIfLimited("vo", pathNotSameValue, false, false));
- }
+ }
+
+ public void TestInfohubLinks13979() {
+ CLDRFile root = cldrFactory.make("root", true);
+ List<CheckStatus> possibleErrors = new ArrayList<>();
+ String[][] tests = {
+ // test edge cases
+ // locale, path, value, expected
+ {"fr", "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"feminine\"]", "de genre féminin",
+ "Need at least 1 placeholder(s), but only have 0. Placeholders are: {{0}={GENDER}, e.g. “‹noun phrase in this gender›”}; see <a href='http://cldr.unicode.org/translation/error-codes#missingPlaceholders' target='cldr_error_codes'>missing placeholders</a>."},
+ };
+ for (String[] row : tests) {
+ String localeId = row[0];
+ String path = row[1];
+ String value = row[2];
+ String expected = row[3];
+
+ checkPathValue(root, localeId, path,value, possibleErrors);
+ for (CheckStatus error : possibleErrors) {
+ if (error.getSubtype() == Subtype.missingPlaceholders) {
+ assertEquals("message", expected, error.getMessage());
+ }
+ }
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckDisplayCollisions.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckDisplayCollisions.java
index 8d10933..9db66a2 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckDisplayCollisions.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckDisplayCollisions.java
@@ -19,24 +19,25 @@
import org.unicode.cldr.util.XMLSource;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
public class TestCheckDisplayCollisions extends TestFmwkPlus {
private static final String ukRegion = "//ldml/localeDisplayNames/territories/territory[@type=\"GB\"]";
private static final String englandSubdivision = "//ldml/localeDisplayNames/subdivisions/subdivision[@type=\"gbeng\"]";
-
+
private static final String scorpioEmoji = "//ldml/annotations/annotation[@cp=\"♏\"][@type=\"tts\"]";
private static final String scorpionEmoji = "//ldml/annotations/annotation[@cp=\"🦂\"][@type=\"tts\"]";
-
+
private static final String japanRegion = "//ldml/localeDisplayNames/territories/territory[@type=\"JP\"]";
private static final String japanMap = "//ldml/annotations/annotation[@cp=\"🗾\"][@type=\"tts\"]";
-
+
private static final String milli = "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"10p-3\"]/unitPrefixPattern";
private static final String mega = "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"10p6\"]/unitPrefixPattern";
-
+
private static final String deciLong = "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"10p-1\"]/unitPrefixPattern";
private static final String deciNarrow = "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"10p-1\"]/unitPrefixPattern";
private static final String deciShort = "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"10p-1\"]/unitPrefixPattern";
-
+
public static void main(String[] args) {
new TestCheckDisplayCollisions().run(args);
}
@@ -57,7 +58,7 @@
frSource.putValueAtDPath(japanMap, "carte du Japon");
frSource.putValueAtDPath(milli, "m{0}");
frSource.putValueAtDPath(mega, "M{0}");
-
+
frSource.putValueAtDPath(deciLong, "d{0}");
frSource.putValueAtDPath(deciNarrow, "d{0}");
frSource.putValueAtDPath(deciShort, "d{0}");
@@ -78,15 +79,69 @@
CheckDisplayCollisions cdc = new CheckDisplayCollisions(factory);
cdc.setEnglishFile(CLDRConfig.getInstance().getEnglish());
-
+
CLDRFile frResolved = factory.make("fr", true);
checkFile(cdc, fr, frResolved);
CLDRFile frCaResolved = factory.make("fr_CA", false);
- checkFile(cdc, frCA, frCaResolved,
+ checkFile(cdc, frCA, frCaResolved,
scorpioEmoji, ukRegion);
}
-
+
+ public void testUnitPatternCollisions() {
+ final String unitPattern1 = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-dot\"]/unitPattern[@count=\"one\"]";
+ /**
+ * different count as # 1. MUST NOT COLLIDE WITH #1
+ */
+ final String unitPattern2 = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-dot\"]/unitPattern[@count=\"other\"]";
+ /**
+ * different unit as # 1. MUST COLLIDE WITH #1
+ */
+ final String unitPattern3 = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"length-point\"]/unitPattern[@count=\"one\"]";
+ /**
+ * #4 and #5 must NOT collide; case="nominative" and case="accusative" when paths are otherwise identical and have the same value
+ */
+ final String unitPattern4 = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-dram\"]/unitPattern[@count=\"other\"][@case=\"nominative\"]";
+ final String unitPattern5 = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-dram\"]/unitPattern[@count=\"other\"][@case=\"accusative\"]";
+
+ mustCollide(false, unitPattern1, unitPattern2);
+ mustCollide(true, unitPattern1, unitPattern3);
+ mustCollide(false, unitPattern4, unitPattern5);
+ }
+
+ private void mustCollide(boolean expectCollisionErrors, String unitPatternA, String unitPatternB) {
+ final String testLocale = "pt";
+ final String duplicatedValue = "{0}pontos";
+
+ final XMLSource rootSource = new SimpleXMLSource("root");
+ final CLDRFile root = new CLDRFile(rootSource);
+
+ final XMLSource enSource = new SimpleXMLSource("en");
+ final CLDRFile en = new CLDRFile(enSource);
+
+ final XMLSource source = new SimpleXMLSource(testLocale);
+
+ source.putValueAtPath(unitPatternA, duplicatedValue);
+ source.putValueAtPath(unitPatternB, duplicatedValue);
+
+ CLDRFile file = new CLDRFile(source);
+
+ TestFactory factory = new TestFactory();
+ factory.addFile(root);
+ factory.addFile(en);
+ factory.addFile(file);
+
+ CheckDisplayCollisions cdc = new CheckDisplayCollisions(factory);
+ cdc.setEnglishFile(CLDRConfig.getInstance().getEnglish());
+
+ CLDRFile ptResolved = factory.make(testLocale, true);
+ if (expectCollisionErrors) {
+ checkFile(cdc, file, ptResolved, unitPatternA, unitPatternB);
+ } else {
+ checkFile(cdc, file, ptResolved);
+ }
+ }
+
private void checkFile(CheckDisplayCollisions cdc, CLDRFile cldrFile, CLDRFile cldrFileResolved, String... expectedErrors) {
List<CheckStatus> possibleErrors = new ArrayList<>();
Options options = new Options();
@@ -119,7 +174,52 @@
} else {
errln(cldrFile.getLocaleID() + " unexpected error: " + path + " : " + entry.getValue());
}
+ checkUnknown(path, entry);
}
assertEquals(cldrFile.getLocaleID() + " expected to be errors: ", Collections.emptySet(), expected);
}
+
+ /**
+ * Report an error if the CheckStatus parameters contain the word "Unknown",
+ * which can be a symptom of errors such as removal of required "count" attribute.
+ * "Unknown" may not always be an error, but for the data used in this test we don't expect it.
+ *
+ * @param path
+ * @param entry
+ */
+ private void checkUnknown(String path, Entry<String, List<CheckStatus>> entry) {
+ CheckStatus cs = entry.getValue().get(0);
+ String s = cs.getParameters()[0].toString();
+ if (s.contains("Unknown")) {
+ errln("Found Unknown in : " + path + ":\n" + s);
+ }
+ }
+
+ public void TestDotPixel14031 () {
+ TestFactory factory = new TestFactory();
+ XMLSource rootSource = new SimpleXMLSource("root");
+ factory.addFile(new CLDRFile(rootSource));
+
+ XMLSource localeSource = new SimpleXMLSource("de");
+ Map<String,String> m = ImmutableMap.of(
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-dot\"]/displayName", "Punkt",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-pixel\"]/displayName", "Punkt",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-pixel-per-centimeter\"]/displayName", "Punkt pro Zentimeter",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"graphics-dot-per-centimeter\"]/displayName", "Punkt pro Zentimeter"
+ );
+ for (Entry<String, String> entry : m.entrySet()) {
+ localeSource.putValueAtPath(entry.getKey(), entry.getValue());
+ }
+ factory.addFile(new CLDRFile(localeSource));
+
+ CheckDisplayCollisions cdc = new CheckDisplayCollisions(factory);
+ cdc.setEnglishFile(CLDRConfig.getInstance().getEnglish());
+
+ List<CheckStatus> possibleErrors = new ArrayList<>();
+ cdc.setCldrFileToCheck(factory.make("de", true), ImmutableMap.of(), possibleErrors);
+ for (Entry<String, String> entry : m.entrySet()) {
+ cdc.check(entry.getKey(), entry.getKey(), entry.getValue(), ImmutableMap.of(), possibleErrors);
+ assertEquals(entry.toString(), Collections.emptyList(), possibleErrors);
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckNumbers.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckNumbers.java
new file mode 100644
index 0000000..36a10ae
--- /dev/null
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCheckNumbers.java
@@ -0,0 +1,66 @@
+package org.unicode.cldr.unittest;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.unicode.cldr.test.CheckCLDR.CheckStatus;
+import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
+import org.unicode.cldr.test.CheckCLDR.CheckStatus.Type;
+import org.unicode.cldr.test.CheckNumbers;
+import org.unicode.cldr.unittest.TestXMLSource.DummyXMLSource;
+import org.unicode.cldr.util.CLDRConfig;
+import org.unicode.cldr.util.CLDRFile;
+import org.unicode.cldr.util.XMLSource;
+
+public class TestCheckNumbers extends TestFmwkPlus {
+
+
+ public static void main(String[] args) {
+ new TestCheckNumbers().run(args);
+ }
+
+ public void TestSingularity() {
+ CheckNumbers checkNumbers = new CheckNumbers(CLDRConfig.getInstance().getCldrFactory());
+
+ // construct fake locale and test
+
+ // should succeed, since "one" only has one number in ast.
+ checkSingularity(checkNumbers, "en",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"short\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"1000\"][@count=\"one\"]",
+ "K", null
+ );
+ // should fail, "one" may match both 1 and zero in french
+ checkSingularity(checkNumbers, "fr",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"short\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"1000\"][@count=\"one\"]",
+ "K", Subtype.missingZeros
+ );
+
+ }
+
+ public void checkSingularity(CheckNumbers checkNumbers, String locale, final String path, final String value, Subtype expectedSubtype) {
+ XMLSource xmlSource = new DummyXMLSource();
+ xmlSource.putValueAtDPath(path, value);
+ xmlSource.setLocaleID(locale);
+ CLDRFile cldrFileToCheck = new CLDRFile(xmlSource);
+
+ Map<String, String> options = Collections.emptyMap();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
+ checkNumbers.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
+ assertEquals("setCldrFileToCheck", Collections.EMPTY_LIST, possibleErrors);
+ possibleErrors.clear();
+
+ checkNumbers.check(path, path, value, options, possibleErrors);
+ if (expectedSubtype == null) {
+ assertEquals("should have no errors: ", Collections.emptyList(), possibleErrors);
+ } else {
+ if (assertEquals("should have one error: ", 1, possibleErrors.size())) {
+ CheckStatus err = possibleErrors.get(0);
+ assertEquals("errorType", Type.Error, err.getType());
+ Subtype exp = err.getSubtype();
+ assertEquals("errorSubType", expectedSubtype, err.getSubtype());
+ }
+ }
+ }
+}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrFactory.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrFactory.java
index 58c799c..f9c0076 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrFactory.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrFactory.java
@@ -24,7 +24,6 @@
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class TestCldrFactory extends TestFmwkPlus {
private static final boolean DEBUG = false;
@@ -138,8 +137,8 @@
private String differentPathValue(CLDRFile a, CLDRFile b) {
int debugCount = 0;
Set<String> paths = new TreeSet<>();
- CollectionUtilities.addAll(a.iterator(), paths);
- CollectionUtilities.addAll(b.iterator(), paths);
+ a.forEach(paths::add);
+ b.forEach(paths::add);
for (String xpath : paths) {
if (++debugCount < 100) {
logln(debugCount + "\t" + xpath);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrResolver.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrResolver.java
index 5abee87..502407a 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrResolver.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCldrResolver.java
@@ -151,18 +151,18 @@
// Check to make sure that all paths from the tool-resolved
// version are
// also in the CLDR-resolved version
- for (String canonicalPath : toolResolved.keySet()) {
+ for (String normalizedPath : toolResolved.keySet()) {
// Check if path should be ignored
- if (!shouldIgnorePath(canonicalPath, cldrResolved)) {
+ if (!shouldIgnorePath(normalizedPath, cldrResolved)) {
assertTrue(
"Path "
- + canonicalPath
+ + normalizedPath
+ " is present in tool resolved file for locale "
+ locale
+ " but not in CLDR resolved file.",
- cldrPaths.contains(canonicalPath)
+ cldrPaths.contains(normalizedPath)
|| toolResolved
- .get(canonicalPath)
+ .get(normalizedPath)
.equals(CldrUtility.NO_INHERITANCE_MARKER));
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCollationMapMaker.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCollationMapMaker.java
index a3b5919..eec810c 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCollationMapMaker.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCollationMapMaker.java
@@ -53,7 +53,7 @@
UnicodeSetPrettyPrinter pretty = new UnicodeSetPrettyPrinter().setOrdering(
Collator.getInstance(ULocale.ROOT)).setSpaceComparator(
Collator.getInstance(ULocale.ROOT).setStrength2(
- RuleBasedCollator.PRIMARY));
+ Collator.PRIMARY));
for (String target : inverse.keySet()) {
unicodeSet.clear();
unicodeSet.addAll(inverse.getAll(target));
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestComparisonBuilder.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestComparisonBuilder.java
index 8498e47..cec13b5 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestComparisonBuilder.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestComparisonBuilder.java
@@ -242,6 +242,7 @@
for (Ordering order : Ordering.values()) {
Builder<String> builder = new Builder<String>(order);
builder.setFallbackComparator(new Comparator<String>() {
+ @Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCompatibility.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCompatibility.java
index 36ec8e6..7c0670c 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCompatibility.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCompatibility.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.unittest;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPathString;
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@@ -8,6 +10,7 @@
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.PathUtilities;
public class TestCompatibility extends TestFmwkPlus {
private static final File ARCHIVE = new File(CLDRPaths.ARCHIVE_DIRECTORY);
@@ -33,23 +36,23 @@
// for now, only look at common main
private void checkXmlFile(File file) throws IOException {
- if (!file.getCanonicalPath().contains("cldr-27.0")) {
+ if (!getNormalizedPathString(file).contains("cldr-27.0")) {
return;
}
- Factory factory = Factory.make(file.getCanonicalPath(), ".*");
+ Factory factory = Factory.make(getNormalizedPathString(file), ".*");
for (String language : factory.getAvailableLanguages()) {
CLDRFile cldrFile;
try {
cldrFile = factory.make(language, false);
} catch (Exception e) {
- errln("Couldn't read " + language + ":\t" + e.getLocalizedMessage() + ", in " + file.getCanonicalPath());
+ errln("Couldn't read " + language + ":\t" + e.getLocalizedMessage() + ", in " + getNormalizedPathString(file));
continue;
}
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);) {
cldrFile.write(pw);
} catch (Exception e) {
- errln("Couldn't write " + language + ":\t" + e.getLocalizedMessage() + ", in " + file.getCanonicalPath());
+ errln("Couldn't write " + language + ":\t" + e.getLocalizedMessage() + ", in " + getNormalizedPathString(file));
}
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCoverageLevel.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCoverageLevel.java
index b4edb6b..50b8890 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCoverageLevel.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestCoverageLevel.java
@@ -1,10 +1,13 @@
package org.unicode.cldr.unittest;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -24,9 +27,11 @@
import org.unicode.cldr.util.DtdData;
import org.unicode.cldr.util.DtdData.Element;
import org.unicode.cldr.util.DtdType;
+import org.unicode.cldr.util.GrammarInfo;
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.LogicalGrouping;
+import org.unicode.cldr.util.LogicalGrouping.PathType;
import org.unicode.cldr.util.PathHeader;
import org.unicode.cldr.util.PathHeader.Factory;
import org.unicode.cldr.util.PathStarrer;
@@ -40,10 +45,12 @@
import org.unicode.cldr.util.SupplementalDataInfo.PopulationData;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.text.CompactDecimalFormat;
@@ -88,7 +95,7 @@
SupplementalDataInfo sdi = SupplementalDataInfo
.getInstance(CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY);
- Set<String> allPaths = new HashSet<String>();
+ Set<String> allPaths = new HashSet<>();
M4<String, String, Level, Boolean> starredToLocalesToLevels = ChainedMap
.of(new TreeMap<String, Object>(),
new TreeMap<String, Object>(),
@@ -106,7 +113,7 @@
}
Set<Level> levelsFound = EnumSet.noneOf(Level.class);
- Set<String> localesWithUniqueLevels = new TreeSet<String>();
+ Set<String> localesWithUniqueLevels = new TreeSet<>();
for (Entry<String, Map<String, Map<Level, Boolean>>> entry : starredToLocalesToLevels) {
String starred = entry.getKey();
Map<String, Map<Level, Boolean>> localesToLevels = entry.getValue();
@@ -131,15 +138,14 @@
System.out.println(maxLevelCount
+ "\t"
+ localesWithUniqueLevels.size()
- / localeCount
+ / localeCount
+ "\t"
+ starred
+ "\t"
- + CollectionUtilities.join(levelsFound, ", ")
+ + Joiner.on(", ").join(levelsFound)
+ "\t"
+ (maxLevelCount == 1 ? "all" : localesWithUniqueLevels
- .size() == 0 ? "none" : CollectionUtilities.join(
- localesWithUniqueLevels, ", ")));
+ .size() == 0 ? "none" : Joiner.on(", ").join(localesWithUniqueLevels)));
}
}
@@ -154,12 +160,12 @@
static Relation<String, LanguageStatus> languageStatus = Relation.of(
new HashMap<String, Set<LanguageStatus>>(), TreeSet.class);
- static Counter2<String> languageLiteratePopulation = new Counter2<String>();
- static Map<String, Date> currencyToLast = new HashMap<String, Date>();
- static Set<String> officialSomewhere = new HashSet<String>();
+ static Counter2<String> languageLiteratePopulation = new Counter2<>();
+ static Map<String, Date> currencyToLast = new HashMap<>();
+ static Set<String> officialSomewhere = new HashSet<>();
static {
- Counter2<String> territoryLiteratePopulation = new Counter2<String>();
+ Counter2<String> territoryLiteratePopulation = new Counter2<>();
LanguageTagParser parser = new LanguageTagParser();
// cf
// http://cldr.unicode.org/development/development-process/design-proposals/languages-to-show-for-translation
@@ -253,15 +259,15 @@
switch (field) {
case CLDRFile.LANGUAGE_NAME:
dep = SDI.getLocaleAliasInfo()
- .get("language");
+ .get("language");
break;
case CLDRFile.TERRITORY_NAME:
dep = SDI.getLocaleAliasInfo()
- .get("territory");
+ .get("territory");
break;
case CLDRFile.SCRIPT_NAME:
dep = SDI.getLocaleAliasInfo()
- .get("script");
+ .get("script");
break;
default:
dep = null;
@@ -269,6 +275,7 @@
}
}
+ @Override
public String transform(String source) {
String result = ENGLISH.getName(field, source);
String extra = "";
@@ -292,11 +299,12 @@
RegexLookup<Level> exceptions = RegexLookup.of(null,
new Transform<String, Level>() {
- public Level transform(String source) {
- return Level.fromLevel(Integer.parseInt(source));
- }
- }, null).loadFromFile(TestCoverageLevel.class,
- "TestCoverageLevel.txt");
+ @Override
+ public Level transform(String source) {
+ return Level.fromLevel(Integer.parseInt(source));
+ }
+ }, null).loadFromFile(TestCoverageLevel.class,
+ "TestCoverageLevel.txt");
public void TestExceptions() {
for (Map.Entry<Finder, Level> x : exceptions) {
@@ -370,7 +378,7 @@
+ "kj|anp|an|niu|mni|dv|swb|pau|gor|nqo|krc|crs|gwi|zza|mad|nog|lez|byn|sad|ssy|mag|iba|"
+ "tpi|kum|wal|mos|dzg|gez|io|tn|snk|mai|ady|chy|mwl|sco|av|efi|war|mic|loz|scn|smj|tem|"
+ "dgr|mak|inh|lun|ts|fj|na|kpe|sr_ME|trv|rap|bug|ban|xal|oc|alt|nia|myv|ain|rar|krl|ay|"
- + "syr|kv|umb|)");
+ + "syr|kv|umb|cu|prg|vo)");
final Pattern script100 = PatternCache.get("("
+ "Adlm|Afak|Aghb|Ahom|Aran|Armi|Avst|Bali|Bamu|Bass|Batk|Bhks|Blis|Brah|Bugi|Buhd|"
@@ -613,7 +621,9 @@
}
} else if (path.startsWith("//ldml/units")) {
// Skip paths for narrow unit fields.
- if ("narrow".equals(xpp.findAttributeValue("unitLength", "type"))) {
+ if ("narrow".equals(xpp.findAttributeValue("unitLength", "type"))
+ || path.endsWith("/compoundUnitPattern1")
+ ) {
continue;
}
}
@@ -661,4 +671,145 @@
++count;
}
}
+
+ public void testLogicalGroupingSamples() {
+ System.out.println(GrammarInfo.SEED_LOCALES);
+ String[][] test = {
+ {"de",
+ "SINGLETON",
+ "//ldml/localeDisplayNames/localeDisplayPattern/localePattern",
+ },
+ {"de",
+ "METAZONE",
+ "//ldml/dates/timeZoneNames/metazone[@type=\"Alaska\"]/long/generic",
+ "//ldml/dates/timeZoneNames/metazone[@type=\"Alaska\"]/long/standard",
+ "//ldml/dates/timeZoneNames/metazone[@type=\"Alaska\"]/long/daylight",
+ },
+ {"de",
+ "DAYS",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"sun\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"mon\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"tue\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"wed\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"thu\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"fri\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/days/dayContext[@type=\"format\"]/dayWidth[@type=\"wide\"]/day[@type=\"sat\"]",
+ },
+ {"nl",
+ "DAY_PERIODS",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"morning1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"afternoon1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"evening1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"night1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"midnight\"]",
+ },
+ {"de",
+ "QUARTERS",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/quarters/quarterContext[@type=\"format\"]/quarterWidth[@type=\"wide\"]/quarter[@type=\"1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/quarters/quarterContext[@type=\"format\"]/quarterWidth[@type=\"wide\"]/quarter[@type=\"2\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/quarters/quarterContext[@type=\"format\"]/quarterWidth[@type=\"wide\"]/quarter[@type=\"3\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/quarters/quarterContext[@type=\"format\"]/quarterWidth[@type=\"wide\"]/quarter[@type=\"4\"]",
+ },
+ {"de",
+ "MONTHS",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"1\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"2\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"3\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"4\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"5\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"6\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"7\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"8\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"9\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"10\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"11\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"wide\"]/month[@type=\"12\"]",
+ },
+ {"de",
+ "RELATIVE",
+ "//ldml/dates/fields/field[@type=\"week-short\"]/relative[@type=\"-1\"]",
+ "//ldml/dates/fields/field[@type=\"week-short\"]/relative[@type=\"0\"]",
+ "//ldml/dates/fields/field[@type=\"week-short\"]/relative[@type=\"1\"]",
+ },
+ {"de",
+ "DECIMAL_FORMAT_LENGTH",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"1000\"][@count=\"one\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"1000\"][@count=\"other\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"10000\"][@count=\"one\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"10000\"][@count=\"other\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"100000\"][@count=\"one\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength[@type=\"long\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"100000\"][@count=\"other\"]",
+ },
+ {"cs",
+ "COUNT",
+ "//ldml/numbers/currencies/currency[@type=\"BMD\"]/displayName[@count=\"one\"]",
+ "//ldml/numbers/currencies/currency[@type=\"BMD\"]/displayName[@count=\"few\"]",
+ "//ldml/numbers/currencies/currency[@type=\"BMD\"]/displayName[@count=\"many\"]",
+ "//ldml/numbers/currencies/currency[@type=\"BMD\"]/displayName[@count=\"other\"]",
+ },
+ {"de",
+ "COUNT",
+ "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"one\"]",
+ "//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"other\"]",
+ },
+ {"de",
+ "COUNT_CASE",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"one\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"one\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"one\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"other\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"other\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"other\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"area-square-kilometer\"]/unitPattern[@count=\"other\"]",
+ },
+ {"hi",
+ "COUNT_CASE_GENDER",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@case=\"oblique\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"][@case=\"oblique\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@case=\"oblique\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"][@case=\"oblique\"]"
+ }
+ };
+ Set<PathType> seenPt = new TreeSet<>(Arrays.asList(PathType.values()));
+ for (String[] row : test) {
+ String locale = row[0];
+ PathType expectedPathType = PathType.valueOf(row[1]);
+ CLDRFile cldrFile = testInfo.getCldrFactory().make(locale, true);
+ List<String> paths = Arrays.asList(row);
+ paths = paths.subList(2, paths.size());
+ Set<String> expected = new TreeSet<>(paths);
+ Set<Multimap<String, String>> seen = new LinkedHashSet<>();
+ for (String path : expected) {
+ Set<String> grouping = new TreeSet<>(LogicalGrouping.getPaths(cldrFile, path));
+ final Multimap<String, String> deltaValue = delta(expected, grouping);
+ if (seen.add(deltaValue)) {
+ assertEquals("Logical group for " + path, ImmutableListMultimap.of(), deltaValue);
+ }
+ PathType actualPathType = PathType.getPathTypeFromPath(path);
+ assertEquals("PathType", expectedPathType, actualPathType);
+ }
+ seenPt.remove(expectedPathType);
+ }
+ assertEquals("PathTypes tested", Collections.emptySet(), seenPt);
+ logKnownIssue("CLDR-13951", "Add more LogicalGrouping tests, fix DECIMAL_FORMAT_LENGTH, etc.");
+ }
+
+ private Multimap<String,String> delta(Set<String> expected, Set<String> grouping) {
+ if (expected.equals(grouping)) {
+ return ImmutableListMultimap.of();
+ }
+ Multimap<String,String> result = LinkedHashMultimap.create();
+ TreeSet<String> aMinusB = new TreeSet<>(expected);
+ aMinusB.removeAll(grouping);
+ result.putAll("expected-actual", aMinusB);
+ TreeSet<String> bMinusA = new TreeSet<>(grouping);
+ bMinusA.removeAll(expected);
+ result.putAll("actual-expected", bMinusA);
+ return result;
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDayPeriods.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDayPeriods.java
index 80863b2..2805666 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDayPeriods.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDayPeriods.java
@@ -51,7 +51,7 @@
for (int i = 0; i < dayPeriodInfo.getPeriodCount(); ++i) {
R3<Integer, Boolean, DayPeriod> info = dayPeriodInfo.getPeriod(i);
int start = info.get0();
- assertEquals("Time is even hours", (int) (start / DayPeriodInfo.HOUR) * DayPeriodInfo.HOUR, (int) start);
+ assertEquals("Time is even hours", start / DayPeriodInfo.HOUR * DayPeriodInfo.HOUR, start);
R2<Integer, DayPeriod> row = Row.of(start, info.get2());
sorted.add(row);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDisplayAndInputProcessor.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDisplayAndInputProcessor.java
index 322fc64..282f500 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDisplayAndInputProcessor.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDisplayAndInputProcessor.java
@@ -382,4 +382,14 @@
}
return "?";
}
+
+ /**
+ * Test whether DisplayAndInputProcessor.processInput removes backspaces
+ */
+ public void TestBackspaceFilter() {
+ DisplayAndInputProcessor daip = new DisplayAndInputProcessor(info.getEnglish(), false);
+ String xpath = "//ldml/localeDisplayNames/languages/language[@type=\"fr\"]";
+ String value = daip.processInput(xpath, "\btest\bTEST\b", null);
+ assertEquals("Backspaces are filtered out", "testTEST", value);
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDtdData.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDtdData.java
index b6fb43b..38d6c37 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDtdData.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestDtdData.java
@@ -30,10 +30,10 @@
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class TestDtdData extends TestFmwk {
private static final String COMMON_DIR = CLDRPaths.BASE_DIRECTORY + "common/";
@@ -50,7 +50,7 @@
/*
* TODO: re-enable the first test or something like it.
- * It began to fail as a result of copying dtdData in XPathParts.cloneAsThawed rather than always making it null.
+ * It began to fail as a result of copying dtdData in XPathParts.cloneAsThawed rather than always making it null.
* Reference: https://unicode.org/cldr/trac/ticket/12007
*/
// has a value & value attribute
@@ -130,7 +130,7 @@
actual.add(item + "==VALUE");
}
}
- TreeSet<String> temp = new TreeSet<String>(actual);
+ TreeSet<String> temp = new TreeSet<>(actual);
temp.removeAll(expected);
assertEquals("too many, extra: " + path, Collections.emptySet(), temp);
temp.clear();
@@ -176,7 +176,7 @@
DtdData dtdData = DtdData.getInstance(type);
Element special = dtdData.getElementFromName().get("special");
checkEmpty(m, type, dtdData.ROOT, special, new HashSet<Element>(),
- new ArrayList<Element>(Arrays.asList(dtdData.ROOT)));
+ new ArrayList<>(Arrays.asList(dtdData.ROOT)));
}
Collection<String> items = m.get("error");
if (items != null) {
@@ -195,9 +195,9 @@
}
/** make sure that if the final element is empty, there is a value attribute required somewhere in the path
- * @param m
- * @param type
- * @param seen
+ * @param m
+ * @param type
+ * @param seen
*/
private void checkEmpty(Multimap<String, String> m, DtdType type, Element element, Element special, HashSet<Element> seen,
List<Element> parents) {
@@ -284,7 +284,7 @@
}
private String showPath(List<Element> parents) {
- return "!//" + CollectionUtilities.join(parents, "/");
+ return "!//" + Joiner.on("/").join(parents);
}
public void TestNewDtdData() {
@@ -339,17 +339,17 @@
// continue;
// }
// switch (attribute.getStatus()) {
-// case value:
+// case value:
// errln(type + "\t" + element + "\t" + attribute + "\t");
// }
// }
// }
// }
-//
+//
// }
// TESTING CODE
- static final Set<String> orderedElements = Collections.unmodifiableSet(new HashSet<String>(Arrays
+ static final Set<String> orderedElements = Collections.unmodifiableSet(new HashSet<>(Arrays
.asList(
// can prettyprint with TestAttributes
@@ -462,7 +462,14 @@
|| (elementName.equals("parseLenients") && (attribute.equals("scope") || attribute.equals("level")))
|| (elementName.equals("parseLenient") && attribute.equals("sample"))
|| (elementName.equals("ordinalMinimalPairs") && attribute.equals("ordinal"))
- || (elementName.equals("styleName") && attribute.equals("subtype"));
+ || (elementName.equals("styleName") && attribute.equals("subtype"))
+ || (elementName.equals("unitPattern") && attribute.equals("case"))
+ || (elementName.equals("compoundUnitPattern") && attribute.equals("case"))
+ || (elementName.equals("compoundUnitPattern1") && (attribute.equals("case") || attribute.equals("gender")))
+ || (elementName.equals("genderMinimalPairs") && attribute.equals("gender"))
+ || (elementName.equals("caseMinimalPairs") && attribute.equals("case"))
+ ;
+
case ldmlBCP47:
return attribute.equals("_q")
//|| attribute.equals("alias")
@@ -570,9 +577,17 @@
|| (elementName.equals("transform") && (attribute.equals("source") || attribute.equals("target") || attribute.equals("direction") || attribute
.equals("variant")))
|| (elementName.equals("grammaticalFeatures") && (attribute.equals("locales") || attribute.equals("targets")))
+ || (elementName.equals("grammaticalDefiniteness") && attribute.equals("scope"))
+ || (elementName.equals("grammaticalCase") && attribute.equals("scope"))
+ || (elementName.equals("grammaticalGender") && attribute.equals("scope"))
|| (elementName.equals("convertUnit") && (attribute.equals("source") || attribute.equals("target")))
|| (elementName.equals("unitConstant") && attribute.equals("constant"))
|| (elementName.equals("unitQuantity") && attribute.equals("baseUnit"))
+
+ || attribute.equals("scope")
+ || elementName.equals("deriveComponent") && (attribute.equals("feature") || attribute.equals("structure"))
+ || elementName.equals("grammaticalDerivations") && attribute.equals("locales")
+ || elementName.equals("deriveCompound") && (attribute.equals("feature")|| attribute.equals("structure"))
;
case keyboard:
@@ -642,7 +657,7 @@
final String inputText = (String)test[1];
int startOfValues = test[2] instanceof String ? 3 : 2;
String expectedFormat = startOfValues == 3 ? (String) test[2] : inputText;
- Set<Enum> expected = new TreeSet<Enum>();
+ Set<Enum> expected = new TreeSet<>();
for (Object item : Arrays.asList(test).subList(startOfValues, test.length)) {
expected.add((Enum)item);
}
@@ -664,7 +679,7 @@
MatchValue matcher = MatchValue.of((String)test[0]);
final String toMatch = (String)test[1];
boolean expectedValue = test.length < 3 ? true : Boolean.valueOf((String)test[2]);
-
+
final boolean actual = matcher.is(toMatch);
assertEquals(Arrays.asList(test).toString(), expectedValue, actual);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleDependencies.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleDependencies.java
index 3592a68..03c7a9d 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleDependencies.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleDependencies.java
@@ -1,8 +1,10 @@
package org.unicode.cldr.unittest;
+import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -18,20 +20,28 @@
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.PathStarrer;
+import org.unicode.cldr.util.RecordingCLDRFile;
import org.unicode.cldr.util.XMLSource;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class TestExampleDependencies extends TestFmwk {
- CLDRConfig info = CLDRConfig.getInstance();
- static boolean testDependencies = false; // make true to test
+ private final boolean USE_STARRED_PATHS = true;
+ private final boolean USE_RECORDING = true;
+ private final String fileExtension = USE_RECORDING ? ".java" : ".json";
+
+ private CLDRConfig info;
+ private CLDRFile englishFile;
+ private Factory factory;
+ private Set<String> locales;
+ private String outputDir;
+ private PathStarrer pathStarrer;
public static void main(String[] args) {
- testDependencies = true;
new TestExampleDependencies().run(args);
- testDependencies = false;
}
/**
@@ -39,95 +49,146 @@
*
* The goal is to optimize example caching by only regenerating examples when necessary.
*
- * Still under construction. Reference: https://unicode-org.atlassian.net/browse/CLDR-13331
+ * Reference: https://unicode-org.atlassian.net/browse/CLDR-13636
*
* @throws IOException
*/
public void TestExampleGeneratorDependencies() throws IOException {
- if (!testDependencies) {
- return;
+ info = CLDRConfig.getInstance();
+ englishFile = info.getEnglish();
+ factory = info.getCldrFactory();
+ locales = factory.getAvailable();
+ outputDir = CLDRPaths.GEN_DIRECTORY + "test" + File.separator;
+ pathStarrer = USE_STARRED_PATHS ? new PathStarrer().setSubstitutionPattern("*") : null;
+
+ System.out.println("...");
+ System.out.println("Looping through " + locales.size() + " locales ...");
+
+ if (USE_RECORDING) {
+ /*
+ * Fast method: use RecordingCLDRFile to learn which paths are checked
+ * to produce the example for a given path. This is fast enough that we
+ * can do it for all locales at once to produce a single file.
+ */
+ useRecording();
+ } else {
+ /*
+ * Slow method: loop through all paths, modifying the value for each path
+ * and then doing an inner loop through all paths to see whether the example
+ * changed for each other path. This is extremely slow, so we produce one file
+ * for each locale, with the intention of merging the files afterwards.
+ */
+ useModifying();
}
- final boolean JUST_LIST_PATHS = false;
- final boolean USE_STARRED_PATHS = true;
+ }
- /*
- * Different localeId gives different dependencies.
- * So far, have tested with these locales:
- * "fr": 650 "type A"
- * "de": 652 "type A"
- * "am": 618 "type A"
- * "zh": 12521 "type A"!
- * "ar": ?
- */
- final String localeId = "sr_Cyrl_BA";
+ private void useRecording() throws IOException {
+ final Multimap<String, String> dependencies = TreeMultimap.create();
+ for (String localeId : locales) {
+ System.out.println(localeId);
+ addDependenciesForLocale(dependencies, localeId);
+ }
+ String fileName = "ExampleDependencies" + fileExtension;
+ System.out.println("Creating " + outputDir + fileName + " ...");
+ writeDependenciesToFile(dependencies, outputDir, fileName);
+ }
- CLDRFile englishFile = info.getEnglish();
+ private void addDependenciesForLocale(Multimap<String, String> dependencies, String localeId) {
+ RecordingCLDRFile cldrFile = makeRecordingCldrFile(localeId);
+ cldrFile.disableCaching();
- Factory factory = CLDRConfig.getInstance().getCldrFactory();
+ Set<String> paths = new TreeSet<>(cldrFile.getComparator());
+ // time-consuming
+ cldrFile.forEach(paths::add);
+
+ ExampleGenerator egTest = new ExampleGenerator(cldrFile, englishFile, CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY);
+ egTest.setCachingEnabled(false); // will not employ a cache -- this should save some time, since cache would be wasted
+
+ for (String pathB : paths) {
+ if (skipPathForDependencies(pathB)) {
+ continue;
+ }
+ String valueB = cldrFile.getStringValue(pathB);
+ if (valueB == null) {
+ continue;
+ }
+ String starredB = USE_STARRED_PATHS ? pathStarrer.set(pathB) : null;
+ cldrFile.clearRecordedPaths();
+ egTest.getExampleHtml(pathB, valueB);
+ HashSet<String> pathsA = cldrFile.getRecordedPaths();
+ for (String pathA: pathsA) {
+ if (pathA.equals(pathB) || skipPathForDependencies(pathA)) {
+ continue;
+ }
+ String starredA = USE_STARRED_PATHS ? pathStarrer.set(pathA) : null;
+ dependencies.put(USE_STARRED_PATHS ? starredA : pathA,
+ USE_STARRED_PATHS ? starredB : pathB);
+ }
+ }
+ }
+
+ private RecordingCLDRFile makeRecordingCldrFile(String localeId) {
+ XMLSource topSource = factory.makeSource(localeId);
+ List<XMLSource> parents = getParentSources(factory, localeId);
+ XMLSource[] a = new XMLSource[parents.size()];
+ return new RecordingCLDRFile(topSource, parents.toArray(a));
+ }
+
+ private void useModifying() throws IOException {
+ for (String localeId : locales) {
+ String fileName = "example_dependencies_A_"
+ + localeId
+ + (USE_STARRED_PATHS ? "_star" : "")
+ + fileExtension;
+
+ if (new File(outputDir, fileName).exists()) {
+ System.out.println("Locale: " + localeId + " -- skipping since " +
+ outputDir + fileName + " already exists");
+ } else {
+ System.out.println("Locale: " + localeId + " -- creating "
+ + outputDir + fileName + " ...");
+ writeOneLocale(localeId, outputDir, fileName);
+ }
+ }
+ }
+
+ private void writeOneLocale(String localeId, String outputDir, String fileName) throws IOException {
CLDRFile cldrFile = makeMutableResolved(factory, localeId); // time-consuming
cldrFile.disableCaching();
- CLDRFile top = cldrFile.getUnresolved(); // can mutate top
- Set<String> paths = new TreeSet<String>(cldrFile.getComparator());
- CollectionUtilities.addAll(cldrFile.iterator(), paths); // time-consuming
- if (JUST_LIST_PATHS) {
- String dir = CLDRPaths.GEN_DIRECTORY + "test/";
- String name = "allpaths_" + localeId + ".txt";
- PrintWriter writer = FileUtilities.openUTF8Writer(dir, name);
- ArrayList<String> list = new ArrayList<String>(paths);
- Collections.sort(list);
- for (String path : list) {
- // writer.println(path);
- writer.println(path.replaceAll("\"", "\\\\\""));
- }
- return;
- }
- final PathStarrer pathStarrer = USE_STARRED_PATHS ? new PathStarrer().setSubstitutionPattern("*") : null;
+ Set<String> paths = new TreeSet<>(cldrFile.getComparator());
+ // time-consuming
+ cldrFile.forEach(paths::add);
ExampleGenerator egBase = new ExampleGenerator(cldrFile, englishFile, CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY);
- HashMap<String, String> originalValues = new HashMap<String, String>();
+ HashMap<String, String> originalValues = new HashMap<>();
- /*
- * Get all the examples so they'll be added to the cache for egBase.
- */
- for (String path : paths) {
- if (path.endsWith("/alias") || path.startsWith("//ldml/identity")) {
- continue;
- }
- String value = cldrFile.getStringValue(path);
- if (value == null) {
- continue;
- }
- originalValues.put(path, value);
- if (false && path.equals("//ldml/numbers/currencies/currency[@type=\"EUR\"]/symbol")) {
- System.out.println("Got " + path + " in first loop ...");
- }
- egBase.getExampleHtml(path, value);
- }
+ getExamplesForBase(egBase, cldrFile, paths, originalValues);
/*
* Make egBase "cacheOnly" so that getExampleHtml will throw an exception if future queries
* are not found in the cache. Alternatively, could just make a local hashmap originalExamples,
* similar to originalValues. That might be more robust, require more memory, faster or slower?
* Should try both ways.
*/
- egBase.makeCacheOnly();
+ egBase.setCacheOnly(true);
ExampleGenerator egTest = new ExampleGenerator(cldrFile, englishFile, CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY);
- egTest.disableCaching(); // will not employ a cache -- this should save some time, since cache would be wasted
+ egTest.setCachingEnabled(false); // will not employ a cache -- this should save some time, since cache would be wasted
+
+ CLDRFile top = cldrFile.getUnresolved(); // can mutate top
+
+ final Multimap<String, String> dependencies = TreeMultimap.create();
+ long count = 0;
+ long skipCount = 0;
+ long dependencyCount = 0;
/*
* For each path (A), temporarily change its value, and then check each other path (B),
* to see whether changing the value for A changed the example for B.
*/
- HashMap<String, HashSet<String>> dependenciesA = new HashMap<String, HashSet<String>>();
- // HashMap<String, HashSet<String>> dependenciesB = new HashMap<String, HashSet<String>>();
- long count = 0;
- long skipCount = 0;
- long dependencyCount = 0;
-
for (String pathA : paths) {
- if (skipPathForDependencies(pathA, true)) {
+ if (skipPathForDependencies(pathA)) {
++skipCount;
continue;
}
@@ -141,6 +202,7 @@
if (count > 500000) {
break;
}
+ String starredA = USE_STARRED_PATHS ? pathStarrer.set(pathA) : null;
/*
* Modify the value for pathA in some random way
*/
@@ -157,21 +219,14 @@
* Reality check, did we really change the value returned by cldrFile.getStringValue?
*/
String valueAX = cldrFile.getStringValue(pathA);
- if (valueAX.equals(newValue)) {
- // Good, expected
- // System.out.println("Changing top changed cldrFile: newValue = " + newValue
- // + "; valueAX = " + valueAX + "; valueA = " + valueA);
- } else {
+ if (!valueAX.equals(newValue)) {
// Bad, didn't work as expected
System.out.println("Changing top did not change cldrFile: newValue = " + newValue
+ "; valueAX = " + valueAX + "; valueA = " + valueA);
}
- String starredA = USE_STARRED_PATHS ? pathStarrer.set(pathA) : null;
- HashSet<String> a = USE_STARRED_PATHS ? dependenciesA.get(starredA) : null;
- boolean maybeTypeA = ExampleGenerator.pathMightBeTypeA(pathA);
for (String pathB : paths) {
- if (pathA.equals(pathB) || skipPathForDependencies(pathB, false)) {
+ if (pathA.equals(pathB) || skipPathForDependencies(pathB)) {
continue;
}
/*
@@ -182,14 +237,9 @@
* pathB and the original valueB.
*/
String valueB = originalValues.get(pathB);
- // String valueB = cldrFile.getStringValue(pathB);
if (valueB == null) {
continue;
}
- if (false && pathA.equals("//ldml/localeDisplayNames/languages/language[@type=\"aa\"]")
- && pathB.equals("//ldml/numbers/currencies/currency[@type=\"EUR\"]/symbol")) {
- System.out.println("Got our paths in inner loop...");
- }
pathB = pathB.intern();
// egTest.icuServiceBuilder.setCldrFile(cldrFile); // clear caches in icuServiceBuilder; has to be public
@@ -198,29 +248,10 @@
if ((exTest == null) != (exBase == null)) {
throw new InternalError("One null but not both? " + pathA + " --- " + pathB);
} else if (exTest != null && !exTest.equals(exBase)) {
- if (!maybeTypeA) {
- System.out.println("Warning: !maybeTypeA: " + pathA);
- }
- if (a == null) {
- a = new HashSet<String>();
- }
- a.add(USE_STARRED_PATHS ? pathStarrer.set(pathB).intern() : pathB);
-
- /***
- HashSet<String> b = dependenciesB.get(pathB);
- if (b == null) {
- b = new HashSet<String>();
- }
- b.add(pathA);
- dependenciesB.put(pathB, b);
- ***/
-
+ dependencies.put(USE_STARRED_PATHS ? starredA : pathA, USE_STARRED_PATHS ? pathStarrer.set(pathB).intern() : pathB);
++dependencyCount;
}
}
- if (a != null && !a.isEmpty()) {
- dependenciesA.put(USE_STARRED_PATHS ? starredA : pathA, a);
- }
/*
* Restore the original value, so that the changes due to this pathA don't get
* carried over to the next pathA. Again call valueChanged to clear getSourceLocaleIDCache.
@@ -233,21 +264,41 @@
+ "; valueA = " + valueA);
}
}
- final boolean countOnly = false;
- writeDependenciesToFile(dependenciesA, "example_dependencies_A_" + localeId
- + (USE_STARRED_PATHS ? "_star" : ""), countOnly);
- // writeDependenciesToFile(dependenciesB, "example_dependencies_B_" + localeId, countOnly);
+ writeDependenciesToFile(dependencies, outputDir, fileName);
System.out.println("count = " + count + "; skipCount = " + skipCount + "; dependencyCount = " + dependencyCount);
}
/**
+ * Get all the examples so they'll be added to the cache for egBase.
+ * Also fill originalValues.
+ *
+ * @param egBase
+ * @param cldrFile
+ * @param paths
+ * @param originalValues
+ */
+ private void getExamplesForBase(ExampleGenerator egBase, CLDRFile cldrFile, Set<String> paths, HashMap<String, String> originalValues) {
+ for (String path : paths) {
+ if (skipPathForDependencies(path)) {
+ continue;
+ }
+ String value = cldrFile.getStringValue(path);
+ if (value == null) {
+ continue;
+ }
+ originalValues.put(path, value);
+ egBase.getExampleHtml(path, value);
+ }
+ }
+
+ /**
* Modify the given value string for testing dependencies
*
* @param value
* @return the modified value, guaranteed to be different from value
*
- * TODO: avoid IllegalArgumentException thrown/caught in, e.g., ICUServiceBuilder.getSymbolString;
- * this function might need path as parameter, to generate only "legal" values for specific paths.
+ * Note: it might be best to avoid IllegalArgumentException thrown/caught in, e.g., ICUServiceBuilder.getSymbolString;
+ * in which case this function might need path as parameter, to generate only "legal" values for specific paths.
*/
private String modifyValueRandomly(String value) {
/*
@@ -268,7 +319,6 @@
* String concatenation, e.g., change "foo" to "foo1"
*/
return value + "1";
- // return "1".equals(value) ? "2" : "1";
}
/**
@@ -280,12 +330,12 @@
* will be a SimpleXMLSource.
*
* @param factory
- * @param localeID
+ * @param localeId
* @return the CLDRFile
*/
- private static CLDRFile makeMutableResolved(Factory factory, String localeID) {
- XMLSource topSource = factory.makeSource(localeID).cloneAsThawed(); // make top one modifiable
- List<XMLSource> parents = getParentSources(factory, localeID);
+ private static CLDRFile makeMutableResolved(Factory factory, String localeId) {
+ XMLSource topSource = factory.makeSource(localeId).cloneAsThawed(); // make top one modifiable
+ List<XMLSource> parents = getParentSources(factory, localeId);
XMLSource[] a = new XMLSource[parents.size()];
return new CLDRFile(topSource, parents.toArray(a));
}
@@ -294,14 +344,14 @@
* Get the parent sources for the given localeId
*
* @param factory
- * @param localeID
+ * @param localeId
* @return the List of XMLSource objects
*
* Called only by makeMutableResolved
*/
- private static List<XMLSource> getParentSources(Factory factory, String localeID) {
+ private static List<XMLSource> getParentSources(Factory factory, String localeId) {
List<XMLSource> parents = new ArrayList<>();
- for (String currentLocaleID = LocaleIDParser.getParent(localeID);
+ for (String currentLocaleID = LocaleIDParser.getParent(localeId);
currentLocaleID != null;
currentLocaleID = LocaleIDParser.getParent(currentLocaleID)) {
parents.add(factory.makeSource(currentLocaleID));
@@ -316,58 +366,62 @@
* @param isTypeA true if path is playing role of pathA not pathB
* @return true to skip, else false
*/
- private static boolean skipPathForDependencies(String path, boolean isTypeA) {
+ private static boolean skipPathForDependencies(String path) {
if (path.endsWith("/alias") || path.startsWith("//ldml/identity")) {
return true;
}
- if (false && isTypeA) {
- final String[] toSkip = {
- "//ldml/characters/ellipsis",
- "//ldml/characters/exemplarCharacters",
- "//ldml/characters/parseLenients",
- "//ldml/layout/orientation/lineOrder",
- "//ldml/localeDisplayNames/codePatterns/codePattern",
- "//ldml/localeDisplayNames/keys/key",
- "//ldml/localeDisplayNames/languages/language",
- "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern",
- "//ldml/localeDisplayNames/localeDisplayPattern/localePattern",
- "//ldml/localeDisplayNames/scripts/script",
- "//ldml/localeDisplayNames/territories/territory",
- "//ldml/localeDisplayNames/types/type",
- "//ldml/localeDisplayNames/variants/variant",
- };
- for (String s: toSkip) {
- if (path.startsWith(s)) {
- return true;
- }
- }
- }
return false;
}
/**
- * Write the given map of example-generator path dependencies to a json file.
+ * Write the given map of example-generator path dependencies to a json or java file.
*
- * If this function is to be used and revised long-term, it would be better to use JSONObject,
+ * If this function is to be used for json and revised long-term, it would be better to use JSONObject,
* or write a format other than json.
* JSONObject isn't currently linked to cldr-unittest TestAll, package org.unicode.cldr.unittest.
*
- * @param dependencies the map of example-generator path dependencies
- * @param fileName the name of the file to create, without path or extension
- * @param countOnly true to show only the count of the set for each key path in the map
- * false to include all the paths
+ * @param dependencies the multimap of example-generator path dependencies
+ * @param dir the directory in which to create the file
+ * @param fileName the name of the file to create
*
* @throws IOException
*/
- private void writeDependenciesToFile(HashMap<String, HashSet<String>> dependencies, String fileName, boolean countOnly) throws IOException {
- // JSONObject json = new JSONObject(dependencies);
- // json.write(writer);
- String dir = CLDRPaths.GEN_DIRECTORY + "test/";
- String name = fileName + ".json";
+ private void writeDependenciesToFile(Multimap<String, String> dependencies, String dir, String name) throws IOException {
PrintWriter writer = FileUtilities.openUTF8Writer(dir, name);
- writer.println("{");
+ if (fileExtension.equals(".json")) {
+ writeJson(dependencies, dir, name, writer);
+ } else {
+ writeJava(dependencies, dir, name, writer);
+ }
+ }
- ArrayList<String> list = new ArrayList<String>(dependencies.keySet());
+ private void writeJava(Multimap<String, String> dependencies, String dir, String name, PrintWriter writer) {
+ writer.println("package org.unicode.cldr.test;");
+ writer.println("import com.google.common.collect.ImmutableSetMultimap;");
+ writer.println("public class ExampleDependencies {");
+ writer.println(" public static ImmutableSetMultimap<String, String> dependencies");
+ writer.println(" = new ImmutableSetMultimap.Builder<String, String>()");
+ int dependenciesWritten = 0;
+ ArrayList<String> listA = new ArrayList<>(dependencies.keySet());
+ Collections.sort(listA);
+ for (String pathA : listA) {
+ ArrayList<String> listB = new ArrayList<>(dependencies.get(pathA));
+ Collections.sort(listB);
+ String a = "\"" + pathA.replaceAll("\"", "\\\\\"") + "\"";
+ for (String pathB : listB) {
+ String b = "\"" + pathB.replaceAll("\"", "\\\\\"") + "\"";
+ writer.println(" .put(" + a + ", " + b + ")");
+ ++dependenciesWritten;
+ }
+ }
+ writer.println(" .build();");
+ writer.println("}");
+ writer.close();
+ System.out.println("Wrote " + dependenciesWritten + " dependencies to " + dir + name);
+ }
+
+ private void writeJson(Multimap<String, String> dependencies, String dir, String name, PrintWriter writer) {
+ ArrayList<String> list = new ArrayList<>(dependencies.keySet());
Collections.sort(list);
boolean firstPathA = true;
int keysWritten = 0;
@@ -377,28 +431,22 @@
} else {
writer.println(",");
}
- HashSet<String> set = dependencies.get(pathA);
+ Collection<String> values = dependencies.get(pathA);
writer.print(" " + "\"" + pathA.replaceAll("\"", "\\\\\"") + "\"" + ": ");
- if (countOnly) {
- Integer count = set.size();
- writer.println(count.toString());
- } else {
- writer.println("[");
- boolean firstPathB = true;
- for (String pathB : set) {
- if (firstPathB) {
- firstPathB = false;
- } else {
- writer.println(",");
- }
- writer.print(" " + "\"" + pathB.replaceAll("\"", "\\\\\"") + "\"");
+ writer.println("[");
+ boolean firstPathB = true;
+ for (String pathB : values) {
+ if (firstPathB) {
+ firstPathB = false;
+ } else {
+ writer.println(",");
}
- writer.println("");
- writer.print(" ]");
+ writer.print(" " + "\"" + pathB.replaceAll("\"", "\\\\\"") + "\"");
}
+ writer.println("");
+ writer.print(" ]");
++keysWritten;
}
-
writer.println("");
writer.println("}");
writer.close();
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleGenerator.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleGenerator.java
index 8b6f8ba..539148f 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleGenerator.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestExampleGenerator.java
@@ -1,6 +1,7 @@
package org.unicode.cldr.unittest;
import java.io.IOException;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -14,11 +15,11 @@
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.PathStarrer;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
+import org.unicode.cldr.util.UnitPathType;
import org.unicode.cldr.util.With;
import com.google.common.collect.ImmutableSet;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class TestExampleGenerator extends TestFmwk {
CLDRConfig info = CLDRConfig.getInstance();
@@ -65,7 +66,7 @@
}
}
- /**
+ /**
* Only add to this if the example should NEVER appear.
* <br>WARNING - do not disable the test by putting in too broad a match. Make sure the paths are reasonably granular.
*/
@@ -104,7 +105,7 @@
);
// Only add to above if the example should NEVER appear.
- /**
+ /**
* Add to this if the example SHOULD appear, but we don't have it yet.
* <br>TODO Add later
*/
@@ -160,14 +161,14 @@
"//ldml/localeDisplayNames/subdivisions/subdivision[@type=\"([^\"]*+)\"]",
- "//ldml/dates/timeZoneNames/zone[@type=\"([^\"]*+)\"]/long/standard" // Error: (TestExampleGenerator.java:245) No background: <Coordinated Universal Time> 〖Coordinated Universal Time〗
+ "//ldml/dates/timeZoneNames/zone[@type=\"([^\"]*+)\"]/long/standard" // Error: (TestExampleGenerator.java:245) No background: <Coordinated Universal Time> 〖Coordinated Universal Time〗
);
// Add to above if the example SHOULD appear, but we don't have it yet. TODO Add later
- /**
+ /**
* Only add to this if the background should NEVER appear.
- * <br>The background is used when the element is used as part of another format.
+ * <br>The background is used when the element is used as part of another format.
* <br>WARNING - do not disable the test by putting in too broad a match. Make sure the paths are reasonably granular.
*/
static final Set<String> DELIBERATE_OK_TO_MISS_BACKGROUND = ImmutableSet.of(
@@ -193,9 +194,9 @@
// Only add to above if the background should NEVER appear.
- /**
+ /**
* Add to this if the background SHOULD appear, but we don't have them yet.
- * <br> The background is used when the element is used as part of another format.
+ * <br> The background is used when the element is used as part of another format.
* <br> TODO Add later
*/
static final Set<String> TEMPORARY_OK_TO_MISS_BACKGROUND = ImmutableSet.of(
@@ -210,10 +211,11 @@
public void TestAllPaths() {
ExampleGenerator exampleGenerator = getExampleGenerator("en");
PathStarrer ps = new PathStarrer();
- Set<String> seen = new HashSet<String>();
+ Set<String> seen = new HashSet<>();
CLDRFile cldrFile = exampleGenerator.getCldrFile();
- for (String path : CollectionUtilities.addAll(cldrFile.fullIterable()
- .iterator(), new TreeSet<String>(cldrFile.getComparator()))) {
+ TreeSet<String> target = new TreeSet<>(cldrFile.getComparator());
+ cldrFile.fullIterable().forEach(target::add);
+ for (String path : target) {
String plainStarred = ps.set(path);
String value = cldrFile.getStringValue(path);
if (value == null || path.endsWith("/alias")
@@ -241,6 +243,10 @@
if (simplified.contains("null")) {
if (true || !seen.contains(javaEscapedStarred)) {
+ // debug
+ exampleGenerator.getExampleHtml(path, value);
+ ExampleGenerator.simplify(example, false);
+
errln("'null' in message:\t<" + value + ">\t"
+ simplified + "\t" + javaEscapedStarred);
// String example2 =
@@ -307,17 +313,17 @@
}
public void TestCompoundUnit() {
- String[][] tests = {
+ String[][] tests = {
{ "per", "LONG", "one", "〖❬1 meter❭ per ❬second❭〗" },
{ "per", "SHORT", "one", "〖❬1 m❭/❬sec❭〗" },
{ "per", "NARROW", "one", "〖❬1m❭/❬s❭〗" },
{ "per", "LONG", "other", "〖❬1.5 meters❭ per ❬second❭〗" },
{ "per", "SHORT", "other", "〖❬1.5 m❭/❬sec❭〗" },
{ "per", "NARROW", "other", "〖❬1.5m❭/❬s❭〗" },
- { "times", "LONG", "one", "〖❬1 newton❭⋅❬meter❭〗" },
+ { "times", "LONG", "one", "〖❬1 newton❭-❬meter❭〗" },
{ "times", "SHORT", "one", "〖❬1 N❭⋅❬m❭〗" },
{ "times", "NARROW", "one", "〖❬1N❭⋅❬m❭〗" },
- { "times", "LONG", "other", "〖❬1.5 newton❭⋅❬meters❭〗" },
+ { "times", "LONG", "other", "〖❬1.5 newton❭-❬meters❭〗" },
{ "times", "SHORT", "other", "〖❬1.5 N❭⋅❬m❭〗" },
{ "times", "NARROW", "other", "〖❬1.5N❭⋅❬m❭〗" },
};
@@ -333,7 +339,7 @@
ExampleGenerator exampleGenerator = getExampleGenerator(locale);
for (String[] test : tests) {
String actual = exampleGenerator.handleCompoundUnit(
- UnitLength.valueOf(test[1]),
+ UnitLength.valueOf(test[1]),
test[0],
Count.valueOf(test[2]));
assertEquals("CompoundUnit", test[3],
@@ -341,8 +347,34 @@
}
}
+ public void TestTranslationPaths() {
+ for (String locale : Arrays.asList("en", "el")) {
+ CLDRFile cldrFile = CLDRConfig.getInstance().getCldrFactory().make(locale, true);
+ ExampleGenerator exampleGenerator = getExampleGenerator(locale);
+
+ for (UnitPathType pathType : UnitPathType.values()) {
+ for (String width : Arrays.asList("long", "short", "narrow")) {
+ if (pathType == UnitPathType.gender && !width.equals("long")) {
+ continue;
+ }
+ for (String unit : pathType.sampleShortUnitType) {
+ String path = pathType.getTranslationPath(cldrFile, width, unit, "one", "nominative", null);
+ String value = cldrFile.getStringValue(path);
+ if (value != null) {
+ String example = exampleGenerator.getExampleHtml(path, value);
+ if (assertNotNull(locale + "/" + path, example)) {
+ String simplified = ExampleGenerator.simplify(example, false);
+ warnln(locale + "/" + pathType.toString() + " ==>" + simplified);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
public void TestCompoundUnit2() {
- String[][] tests = {
+ String[][] tests = {
{ "de", "LONG", "other", "Quadrat{0}", "〖❬1,5 ❭Quadrat❬meter❭〗" },
{ "en", "SHORT", "one", "z{0}", "〖❬1 ❭z❬m❭〗" },
@@ -362,7 +394,7 @@
ExampleGenerator exampleGenerator = getExampleGenerator(test[0]);
String actual = exampleGenerator.handleCompoundUnit1(
- UnitLength.valueOf(test[1]),
+ UnitLength.valueOf(test[1]),
Count.valueOf(test[2]),
test[3]);
assertEquals("CompoundUnit", test[4],
@@ -372,35 +404,35 @@
public void TestCompoundUnit3() {
final Factory cldrFactory = CLDRConfig.getInstance().getCldrFactory();
- String[][] tests = {
+ String[][] tests = {
// locale, path, value, expected-example
- { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
"LOCALE", "〖square ❬meters❭〗" }, //
- { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
"LOCALE", "〖❬1 ❭square ❬meter❭〗" }, //
- { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ { "en", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
"LOCALE", "〖❬1.5 ❭square ❬meters❭〗" }, //
- { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
"LOCALE", "〖❬m❭²〗" },
- { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
"LOCALE", "〖❬1m❭²〗" },
- { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ { "en", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
"LOCALE", "〖❬1.5m❭²〗" },
// warning, french patterns has U+00A0 in them
- { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
"Square {0}", "〖Square ❬mètres❭〗" },
- { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
"square {0}", "〖❬1,5 ❭square ❬mètre❭〗" },
- { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ { "fr", "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
"squares {0}", "〖❬3,5 ❭squares ❬mètres❭〗" },
- { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
"LOCALE", "〖❬m❭²〗" },
- { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
"LOCALE", "〖❬1,5m❭²〗" },
- { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ { "fr", "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
"LOCALE", "〖❬3,5m❭²〗" },
};
@@ -411,22 +443,22 @@
final String xpath = test[1];
String value = test[2];
String expected = test[3];
-
+
ExampleGenerator exampleGenerator = getExampleGenerator(localeID);
if (value.equals("LOCALE")) {
value = cldrFactory.make(localeID, true).getStringValue(xpath);
}
String actual = exampleGenerator.getExampleHtml(xpath, value);
- assertEquals(++lineCount + ") "
- + localeID
+ assertEquals(++lineCount + ") "
+ + localeID
+ ", CompoundUnit3", expected,
ExampleGenerator.simplify(actual, false));
}
}
- HashMap<String, ExampleGenerator> ExampleGeneratorCache = new HashMap<String, ExampleGenerator>();
+ HashMap<String, ExampleGenerator> ExampleGeneratorCache = new HashMap<>();
private ExampleGenerator getExampleGenerator(String locale) {
ExampleGenerator result = ExampleGeneratorCache.get(locale);
@@ -637,16 +669,17 @@
}
String value = cldrFile.getStringValue(xpath);
checkPathValue(exampleGenerator, xpath, value, null);
- if (xpath.contains("count=\"one\"")) {
- String xpath2 = xpath.replace("count=\"one\"", "count=\"1\"");
- checkPathValue(exampleGenerator, xpath2, value, null);
- }
+ // remove this, no longer used
+// if (xpath.contains("count=\"one\"")) {
+// String xpath2 = xpath.replace("count=\"one\"", "count=\"1\"");
+// checkPathValue(exampleGenerator, xpath2, value, null);
+// }
}
}
private void checkPathValue(ExampleGenerator exampleGenerator,
String xpath, String value, String expected) {
- Set<String> alreadySeen = new HashSet<String>();
+ Set<String> alreadySeen = new HashSet<>();
try {
String text = exampleGenerator.getExampleHtml(xpath, value);
if (text == null) {
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestFmwkPlus.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestFmwkPlus.java
index ded46bc..91eacb1 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestFmwkPlus.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestFmwkPlus.java
@@ -7,8 +7,8 @@
import org.unicode.cldr.util.CldrUtility;
+import com.google.common.base.Joiner;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.text.Transform;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UnicodeSet;
@@ -160,7 +160,7 @@
@Override
public String toString() {
- return CollectionUtilities.join(others, " and ");
+ return Joiner.on(" and ").join(others);
}
}
@@ -185,7 +185,7 @@
@Override
public String toString() {
- return CollectionUtilities.join(others, " or ");
+ return Joiner.on(" or ").join(others);
}
}
@@ -336,6 +336,7 @@
return true;
}
+ @Override
public String showFirst(UnicodeSet a) {
return show(a.toPattern(false));
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestIdentity.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestIdentity.java
index dea2afa..384fe73 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestIdentity.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestIdentity.java
@@ -27,12 +27,10 @@
List<Factory> factories = new ArrayList<Factory>();
factories.add(testInfo.getFullCldrFactory());
- if (getInclusion() > 5) { // Only do these in exhaustive move
- factories.add(testInfo.getExemplarsFactory());
- factories.add(testInfo.getCollationFactory());
- factories.add(testInfo.getRBNFFactory());
- factories.add(testInfo.getAnnotationsFactory());
- }
+ factories.add(testInfo.getExemplarsFactory());
+ factories.add(testInfo.getCollationFactory());
+ factories.add(testInfo.getRBNFFactory());
+ factories.add(testInfo.getAnnotationsFactory());
for (Factory factory : factories) {
for (String locale : factory.getAvailable()) {
String canonicalLocaleID = ltc.transform(locale);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestInheritance.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestInheritance.java
index 8f6ec8b..9aa2a69 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestInheritance.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestInheritance.java
@@ -36,8 +36,8 @@
import org.unicode.cldr.util.SupplementalDataInfo.OfficialStatus;
import org.unicode.cldr.util.SupplementalDataInfo.PopulationData;
+import com.google.common.base.Joiner;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
@@ -66,7 +66,7 @@
public void TestLocalesHaveOfficial() {
// If we have a language, we have all the region locales where the
// language is official
- Set<String> SKIP_TERRITORIES = new HashSet<String>(Arrays.asList("001",
+ Set<String> SKIP_TERRITORIES = new HashSet<>(Arrays.asList("001",
"150"));
for (Entry<String, R2<List<String>, String>> s : dataInfo
.getLocaleAliasInfo().get("territory").entrySet()) {
@@ -145,7 +145,7 @@
}
Set<String> officalChildren = entry.getValue().keySet();
if (!children.containsAll(officalChildren)) {
- Set<String> missing = new TreeSet<String>(officalChildren);
+ Set<String> missing = new TreeSet<>(officalChildren);
missing.removeAll(children);
String message = "Missing CLDR locales for " + status
+ " languages: " + missing;
@@ -159,7 +159,7 @@
}
if (DEBUG) {
- Set<String> languages = new TreeSet<String>(
+ Set<String> languages = new TreeSet<>(
languageToChildren.keySet());
languages.addAll(languageToOfficialChildren.keySet());
System.out.print("\ncode\tlanguage");
@@ -247,18 +247,18 @@
// find multiscript locales
Relation<String, String> base2scripts = Relation.of(
new TreeMap<String, Set<String>>(), TreeSet.class);
- Map<String, String> parent2default = new TreeMap<String, String>();
- Map<String, String> default2parent = new TreeMap<String, String>();
+ Map<String, String> parent2default = new TreeMap<>();
+ Map<String, String> default2parent = new TreeMap<>();
Relation<String, String> base2locales = Relation.of(
new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> knownMultiScriptLanguages = new HashSet<String>(Arrays.asList("bm", "ha"));
+ Set<String> knownMultiScriptLanguages = new HashSet<>(Arrays.asList("bm", "ha"));
// get multiscript locales
for (String localeID : availableLocales) {
String script = ltp.set(localeID).getScript();
final String base = ltp.getLanguage();
- if (!availableLocales.contains(base)) {
- errln("Missing base locale for: " + localeID);
+ if (!availableLocales.contains(base) && !base.equals("und")) {
+ errln("Missing lang-subtag for: " + localeID);
}
base2locales.put(base, localeID);
if (!script.isEmpty() && !base.equals("en")) { // HACK for en
@@ -290,8 +290,8 @@
checkLocale(likelyAndMaximized.getKey(), true);
checkLocale(likelyAndMaximized.getValue(), true);
}
- Map<String, String> exceptionDcLikely = new HashMap<String, String>();
- Map<String, String> exceptionLikelyDc = new HashMap<String, String>();
+ Map<String, String> exceptionDcLikely = new HashMap<>();
+ Map<String, String> exceptionLikelyDc = new HashMap<>();
for (String[] s : new String[][] { { "ar_001", "ar_Arab_EG" }, }) {
exceptionDcLikely.put(s[0], s[1]);
exceptionLikelyDc.put(s[1], s[0]);
@@ -372,7 +372,7 @@
for (String loc : availableLocales) {
String currentLoc = loc;
boolean foundError = false;
- List<String> inheritanceChain = new ArrayList<String>(Arrays.asList(loc));
+ List<String> inheritanceChain = new ArrayList<>(Arrays.asList(loc));
while (currentLoc != null && !foundError) {
currentLoc = LocaleIDParser.getParent(currentLoc);
if (inheritanceChain.contains(currentLoc)) {
@@ -392,7 +392,7 @@
Set<String> skip = Builder.with(new HashSet<String>())
.addAll("root", "und")
.freeze();
- Set<String> languagesWithOneOrLessLocaleScriptInCommon = new HashSet<String>(Arrays.asList("bm", "ha", "hi", "ms", "iu", "mn"));
+ Set<String> languagesWithOneOrLessLocaleScriptInCommon = new HashSet<>(Arrays.asList("bm", "ha", "hi", "ms", "iu", "mn"));
// for each base we have to have,
// if multiscript, we have default contents for base+script,
// base+script+region;
@@ -465,7 +465,7 @@
// Then default contents la => la_Scrp && la_Scrp => la_Scrp_RG
// or default contents la => la_RG && ! la_Scrp => la_Scrp_RG
- TreeSet<String> additionalDefaultContents = new TreeSet<String>();
+ TreeSet<String> additionalDefaultContents = new TreeSet<>();
for (Entry<String, String> entry : likely2Maximized.entrySet()) {
String source = entry.getKey();
@@ -540,7 +540,7 @@
}
if (additionalDefaultContents.size() != 0) {
errln("Suggested additions to supplementalMetadata/../defaultContent:\n"
- + CollectionUtilities.join(additionalDefaultContents, " "));
+ + Joiner.on(" ").join(additionalDefaultContents));
}
}
@@ -677,7 +677,7 @@
}
public void TestDeprecatedTerritoryDataLocaleIds() {
- HashSet<String> checked = new HashSet<String>();
+ HashSet<String> checked = new HashSet<>();
for (String language : dataInfo
.getLanguagesForTerritoriesPopulationData()) {
checkLocale(language, false); // checks la_Scrp and la
@@ -925,7 +925,7 @@
// TODO move this into central utilities
private <K, V> String showDifferences(Map<K, V> a, Map<K, V> b) {
StringBuilder result = new StringBuilder();
- Set<K> keys = new LinkedHashSet<K>();
+ Set<K> keys = new LinkedHashSet<>();
keys.addAll(a.keySet());
keys.addAll(b.keySet());
for (K key : keys) {
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestKeyboard.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestKeyboard.java
index a4fac48..c6d712d 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestKeyboard.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestKeyboard.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.unittest;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPathString;
+
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
@@ -10,22 +12,15 @@
import org.unicode.cldr.draft.Keyboard;
import org.unicode.cldr.draft.Keyboard.KeyboardWarningException;
import org.unicode.cldr.util.CLDRConfig;
+import org.unicode.cldr.util.PathUtilities;
public class TestKeyboard extends TestFmwkPlus {
public static void main(String[] args) {
new TestKeyboard().run(args);
}
- static final String dtdLocation;
- static {
- try {
- dtdLocation = CLDRConfig.getInstance().getCldrBaseDirectory()
- .getCanonicalPath()
- + "/keyboards/dtd/ldmlKeyboard.dtd";
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
- }
+ static final String dtdLocation =
+ getNormalizedPathString(CLDRConfig.getInstance().getCldrBaseDirectory()) + "/keyboards/dtd/ldmlKeyboard.dtd";
public void TestGoodSample() throws IOException {
// preload these to make debugging easier
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2ICU.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2ICU.java
deleted file mode 100644
index 2b478a1..0000000
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2ICU.java
+++ /dev/null
@@ -1,263 +0,0 @@
-package org.unicode.cldr.unittest;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.unicode.cldr.icu.NewLdml2IcuConverter;
-import org.unicode.cldr.util.CLDRConfig;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CLDRFile.DraftStatus;
-import org.unicode.cldr.util.CLDRPaths;
-import org.unicode.cldr.util.CldrUtility.VariableReplacer;
-import org.unicode.cldr.util.Pair;
-import org.unicode.cldr.util.RegexFileParser;
-import org.unicode.cldr.util.RegexFileParser.RegexLineParser;
-import org.unicode.cldr.util.RegexFileParser.VariableProcessor;
-import org.unicode.cldr.util.RegexLookup;
-import org.unicode.cldr.util.RegexLookup.RegexFinder;
-import org.unicode.cldr.util.XMLFileReader;
-import org.unicode.cldr.util.XPathParts;
-
-import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.text.Transform;
-import com.ibm.icu.util.Output;
-
-/**
- * Tests the parts of the Ldml2IcuConverter that uses RegexLookups to convert
- * values to ICU. Data that is converted using other methods isn't tested here.
- *
- * @author jchye
- */
-public class TestLdml2ICU extends TestFmwk {
- private static final boolean DEBUG = false;
-
- static final CLDRConfig info = CLDRConfig.getInstance();
-
- private static final Transform<String, RegexFinder> XPATH_TRANSFORM = new Transform<String, RegexFinder>() {
- public RegexFinder transform(String source) {
- final String newSource = source.replace("[@", "\\[@");
- return new RegexFinder("^" + newSource + "$");
- }
- };
-
- public static void main(String[] args) {
- new TestLdml2ICU().run(args);
- }
-
- enum ExclusionType {
- UNCONVERTED, IGNORE, // May be converted or not, but we don't care
- WARNING;
- public static Transform<String, Pair<ExclusionType, String>> TRANSFORM = new Transform<String, Pair<ExclusionType, String>>() {
- public Pair<ExclusionType, String> transform(String source) {
- String value = null;
- if (source.contains(";")) {
- String[] split = source.split("\\s*;\\s*");
- source = split[0];
- value = split[1];
- }
- ExclusionType type = ExclusionType
- .valueOf(source.toUpperCase());
- return Pair.of(type, value);
- }
- };
- }
-
- static final RegexLookup<Pair<ExclusionType, String>> exclusions = RegexLookup
- .of(ExclusionType.TRANSFORM)
- .setPatternTransform(RegexLookup.RegexFinderTransformPath)
- .loadFromFile(TestLdml2ICU.class, "../util/data/testLdml2Icu.txt");
-
- public void TestEnglish() {
- checkLocaleRegexes("en");
- }
-
- public void TestArabic() {
- checkLocaleRegexes("ar");
- }
-
- public void TestRoot() {
- checkLocaleRegexes("root");
- }
-
- public void TestRussian() {
- checkLocaleRegexes("ru");
- }
-
- public void TestJapanese() {
- checkLocaleRegexes("ja");
- }
-
- public void TestTamil() {
- checkLocaleRegexes("ta");
- }
-
- public void TestSupplemental() {
- checkSupplementalRegexes("supplementalData");
- }
-
- public void TestSupplmentalMetadata() {
- checkSupplementalRegexes("supplementalMetadata");
- }
-
-// public void TestTelephoneCodeData() {
-// checkSupplementalRegexes("telephoneCodeData");
-// }
-//
- public void TestMetaZones() {
- checkSupplementalRegexes("metaZones");
- }
-
- public void TestLanguageInfo() {
- checkSupplementalRegexes("languageInfo");
- }
-
- public void TestLikelySubtags() {
- checkSupplementalRegexes("likelySubtags");
- }
-
- public void TestNumberingSystems() {
- checkSupplementalRegexes("numberingSystems");
- }
-
- public void TestWindowsZones() {
- checkSupplementalRegexes("windowsZones");
- }
-
- public void TestGenderList() {
- checkSupplementalRegexes("genderList");
- }
-
-// public void TestPostalCodeData() {
-// checkSupplementalRegexes("postalCodeData");
-// }
-
- /**
- * Loads the regex files used to convert XPaths to ICU paths.
- */
- private static RegexLookup<Object> loadRegexes(String filename) {
- final RegexLookup<Object> lookup = RegexLookup.of()
- .setPatternTransform(XPATH_TRANSFORM);
- RegexFileParser parser = new RegexFileParser();
- parser.setLineParser(new RegexLineParser() {
- int patternNum = 0;
-
- @Override
- public void parse(String line) {
- int pos = line.indexOf(";");
- // We only care about the patterns.
- if (pos == 0)
- return;
- String pattern = pos < 0 ? line : line.substring(0, pos).trim();
- lookup.add(pattern, patternNum++);
- }
- });
- parser.setVariableProcessor(new VariableProcessor() {
- VariableReplacer variables = new VariableReplacer();
-
- @Override
- public void add(String variableName, String value) {
- if (value.startsWith("//")) { // is xpath
- value = "[^\"]++";
- }
- variables.add(variableName, value);
- }
-
- @Override
- public String replace(String str) {
- return variables.replace(str);
- }
-
- });
- parser.parse(NewLdml2IcuConverter.class, filename);
- return lookup;
- }
-
- /**
- * Checks conversion of XML files in the supplemental directory.
- *
- * @param name
- * the name of the XML file to be converted (minus the extension)
- */
- private void checkSupplementalRegexes(String name) {
- RegexLookup<Object> lookup = loadRegexes("ldml2icu_supplemental.txt");
- List<Pair<String, String>> cldrData = new ArrayList<Pair<String, String>>();
- XMLFileReader.loadPathValues(CLDRPaths.DEFAULT_SUPPLEMENTAL_DIRECTORY
- + name + ".xml", cldrData, true);
- for (Pair<String, String> pair : cldrData) {
- String xpath = CLDRFile.getNondraftNonaltXPath(pair.getFirst());
- XPathParts parts = XPathParts.getFrozenInstance(xpath);
- xpath = parts.toString();
- checkPath(lookup, xpath, pair.getSecond());
- }
- }
-
- Set<String> unconverted = new HashSet<String>();
-
- /**
- * Checks if an xpath was matched by a RegexLookup.
- */
- private <T> void checkPath(RegexLookup<T> lookup, String xpath, String value) {
- Pair<ExclusionType, String> exclusionInfo = exclusions.get(xpath);
- ExclusionType exclusionType = null;
- if (exclusionInfo != null) {
- exclusionType = exclusionInfo.getFirst();
- }
-
- if (lookup.get(xpath) == null) {
- String errorMessage = "CLDR xpath <" + xpath + "> with value <"
- + value + "> was not converted to ICU.";
- if (exclusionType == null) {
- logRegexLookup(this, lookup, xpath);
- errln(errorMessage);
- } else if (exclusionType == ExclusionType.WARNING) {
- logln(errorMessage);
- } else if (exclusionType == ExclusionType.UNCONVERTED) {
- String template = xpath.replaceAll("\"[^\"]++\"", "*");
- if (!unconverted.add(template)) {
- logln("Not converted: " + xpath);
- }
- }
- } else if (exclusionType == ExclusionType.UNCONVERTED) {
- logRegexLookup(this, exclusions, xpath);
- errln("CLDR xpath <"
- + xpath
- + "> is in the exclusions list but was matched. "
- + "To make the test pass, remove the relevant regex from org/unicode/cldr/util/data/testLdml2Icu.txt");
- }
- }
-
- private static <T> void logRegexLookup(TestFmwk testFramework, RegexLookup<T> lookup, String toLookup) {
- Output<String[]> arguments = new Output<>();
- Output<RegexLookup.Finder> matcherFound = new Output<>();
- List<String> failures = new ArrayList<String>();
- lookup.get(toLookup, null, arguments, matcherFound, failures);
- testFramework.logln("lookup arguments: " + (arguments.value == null ? "null" : Arrays.asList(arguments.value)));
- testFramework.logln("lookup matcherFound: " + matcherFound);
- for (String s : failures) {
- testFramework.logln(s);
- }
- }
-
- /**
- * Checks conversion of XML locale files.
- *
- * @param name
- * the name of the XML file to be converted (minus the extension)
- */
- private void checkLocaleRegexes(String locale) {
- CLDRFile plain = info.getCldrFactory().make(locale, false,
- DraftStatus.contributed);
- RegexLookup<Object> lookup = loadRegexes("ldml2icu_locale.txt");
- for (String xpath : plain) {
- if (DEBUG && xpath.contains("defaultNumberingSystem")) {
- int debug = 0;
- }
- String fullPath = CLDRFile.getNondraftNonaltXPath(plain
- .getFullXPath(xpath));
- checkPath(lookup, fullPath, plain.getStringValue(xpath));
- }
- }
-}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2IcuCompleteness.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2IcuCompleteness.java
deleted file mode 100644
index d97e7c7..0000000
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLdml2IcuCompleteness.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.unicode.cldr.unittest;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.unicode.cldr.util.CLDRConfig;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.util.ICUUncheckedIOException;
-
-public class TestLdml2IcuCompleteness extends TestFmwk {
-
- private static final String CLDR_BASE = CLDRConfig.getInstance().getCldrBaseDirectory() + "/common";
- private static final String ICU_BASE = CLDRConfig.getInstance().getCldrBaseDirectory() + "/../icu4c/data/"; // "/Users/markdavis/workspace/icu4c/data";
-
- static Multimap<String, File> icuFiles = TreeMultimap.create();
- static Multimap<String, File> cldrFiles = TreeMultimap.create();
-
- static Set<String> SKIP_DIRS = ImmutableSet.of(
- "transforms", "translit", // temp
- "unidata",
- "sprep",
- "mappings");
- static Set<String> SKIP_FILES = ImmutableSet.of(
- "attributeValueValidity",
- "tzdbNames");
-
- static {
- fillMap(new File(ICU_BASE), ".txt", icuFiles);
-// for (Entry<String, Collection<File>> s : icuFiles.asMap().entrySet()) {
-// System.out.println(s.getKey() + "\t\t" + s.getValue());
-// }
-
- fillMap(new File(CLDR_BASE), ".xml", cldrFiles);
- for (Entry<String, Collection<File>> s : cldrFiles.asMap().entrySet()) {
- System.out.println(s.getKey() + "\t\t" + s.getValue());
- }
- }
-
- static void fillMap(File file, String suffix, Multimap<String, File> fileList) {
- try {
- for (File f : file.listFiles()) {
- String name = f.getName();
- if (f.isDirectory()) {
- if (SKIP_DIRS.contains(name)) {
- continue;
- }
- fillMap(f, suffix, fileList);
- } else {
- if (!name.endsWith(suffix)) {
- continue;
- }
- // hack
- if (name.endsWith("dict.txt") || name.contains("readme")) {
- continue;
- }
- name = name.substring(0, name.length() - suffix.length());
- if (SKIP_FILES.contains(name)) {
- continue;
- }
- fileList.put(name, f.getParentFile().getCanonicalFile());
- }
- }
- } catch (IOException e) {
- throw new ICUUncheckedIOException(e);
- }
- }
-
- public static void main(String[] args) {
- new TestLdml2IcuCompleteness().run(args);
- }
-
- public void TestFiles() {
- verifySuperset("cldrFiles-icuFiles", cldrFiles.keySet(), icuFiles.keySet());
- verifySuperset("icuFiles-cldrFiles", icuFiles.keySet(), cldrFiles.keySet());
- }
-
- private void verifySuperset(String title, Set<String> set1, Set<String> set2) {
- LinkedHashSet<String> diff = new LinkedHashSet<>(set1);
- diff.removeAll(set2);
- assertEquals(title, Collections.EMPTY_SET, diff);
- }
-
- public void TestLocales() {
- for (Entry<String, Collection<File>> entry : cldrFiles.asMap().entrySet()) {
- String file = entry.getKey();
- Set<String> values = collectCldrValues(file, entry.getValue());
- }
- }
-
- // TODO flesh out
- private Set<String> collectCldrValues(String file, Collection<File> value) {
- for (File f : value) {
- //org.unicode.cldr.util.XMLFileReader.loadPathValues(filename, data, validating)
- }
- return null;
- }
-}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocalCurrency.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocalCurrency.java
index 0914753..f43e36c 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocalCurrency.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocalCurrency.java
@@ -15,6 +15,7 @@
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.CurrencyDateInfo;
+import com.google.common.collect.ImmutableSet;
import com.ibm.icu.dev.test.TestFmwk;
public class TestLocalCurrency extends TestFmwk {
@@ -24,11 +25,12 @@
new TestLocalCurrency().run(args);
}
+ static final Set<String> regionsWithTwoCurrencySymbols = ImmutableSet.of("AE", "AZ",
+ "BA", "CA", "CN", "DZ", "ET", "IQ", "IR", "LK", "KM", "MA", "MR", "MK", "PK",
+ "NE", "GW", "CM", "SN", "BF", // << ff_Adlm regions are multiscript, Latn+Adlm
+ "RS", "SD", "SY", "TN", "UZ");
+
private int maxLocalizedSymbols(String region) {
- final List<String> regionsWithTwoCurrencySymbols = Arrays.asList("AE", "AZ",
- "BA", "CN", "DZ", "ET", "IQ", "IR", "LK", "KM", "MA", "MR", "MK", "PK",
- "NE", "GW", "CM", "SN", "BF", // << ff_Adlm regions are multiscript, Latn+Adlm
- "RS", "SD", "SY", "TN", "UZ");
if (regionsWithTwoCurrencySymbols.contains(region)) {
return 2;
}
@@ -40,9 +42,9 @@
LanguageTagParser ltp = new LanguageTagParser();
SupplementalDataInfo supplementalDataInfo = testInfo
.getSupplementalDataInfo();
- Map<String, String> localeToLocalCurrencySymbol = new HashMap<String, String>();
- Map<String, Set<String>> localizedCurrencySymbols = new HashMap<String, Set<String>>();
- Map<String, Set<String>> regionToLocales = new HashMap<String, Set<String>>();
+ Map<String, String> localeToLocalCurrencySymbol = new HashMap<>();
+ Map<String, Set<String>> localizedCurrencySymbols = new HashMap<>();
+ Map<String, Set<String>> regionToLocales = new HashMap<>();
List<String> nonLocalizedOK = Arrays.asList("AED", "AZN", "CHF", "CVE", "GEL",
"HRK", "HUF", "IQD", "IRR", "ISK", "KPW", "LTL", "MAD", "MDL", "RON", "RSD",
@@ -84,7 +86,7 @@
Set<String> localSymbols = localizedCurrencySymbols.get(region);
if (localSymbols == null) {
- localSymbols = new TreeSet<String>();
+ localSymbols = new TreeSet<>();
}
if (localCurrencySymbol.equals(localCurrency)
@@ -98,7 +100,7 @@
Set<String> regionLocales = regionToLocales.get(region);
if (regionLocales == null) {
- regionLocales = new TreeSet<String>();
+ regionLocales = new TreeSet<>();
}
regionLocales.add(locale);
@@ -118,7 +120,7 @@
+ localeToLocalCurrencySymbol.get(locale));
errmsg.append('\n');
}
- errln(errmsg.toString());
+ errln(errmsg.toString()); // if this fails, see if it warrants changing regionsWithTwoCurrencySymbols.
}
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocale.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocale.java
index b7f88ee..dd49e2d 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocale.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLocale.java
@@ -43,7 +43,6 @@
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -543,6 +542,9 @@
case "tz":
showName(cldrFile, seen, localeBase, "uslax", "gblon", "chzrh");
continue keyLoop;
+ case "dx":
+ // skip for now, probably need to fix something in CLDRFile
+ continue keyLoop;
}
for (String value : keyValues.getValue()) {
if ("true".equals(deprecatedMap.get(Row.of(key, value)))) {
@@ -707,6 +709,9 @@
case "REORDER_CODE": // [u, kr, REORDER_CODE]
valuesSet = ImmutableSet.of("arab", "digit-deva-latn");
break;
+ case "SCRIPT_CODE": // [u, dx, SCRIPT_CODE]
+ valuesSet = ImmutableSet.of("thai", "thai-laoo");
+ break;
case "RG_KEY_VALUE": // [u, rg, RG_KEY_VALUE]
valuesSet = ImmutableSet.of("ustx", "gbeng");
break;
@@ -726,7 +731,7 @@
private void showItem(LanguageTagParser ltp, String extension, String key, String gorp, String... values) {
String locale = "en-GB-" + extension + (extension.equals("t") ? "-hi" : "")
- + "-" + key + "-" + CollectionUtilities.join(values, "-") + gorp;
+ + "-" + key + "-" + String.join("-", values) + gorp;
ltp.set(locale);
logln(ltp.toString(Format.bcp47)
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLsrvCanonicalizer.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLsrvCanonicalizer.java
new file mode 100644
index 0000000..d0987e0
--- /dev/null
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestLsrvCanonicalizer.java
@@ -0,0 +1,255 @@
+package org.unicode.cldr.unittest;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.unicode.cldr.util.CLDRConfig;
+import org.unicode.cldr.util.CLDRFile;
+import org.unicode.cldr.util.LsrvCanonicalizer;
+import org.unicode.cldr.util.LsrvCanonicalizer.ReplacementRule;
+import org.unicode.cldr.util.LsrvCanonicalizer.TestDataTypes;
+import org.unicode.cldr.util.LsrvCanonicalizer.XLanguageTag;
+import org.unicode.cldr.util.StandardCodes;
+import org.unicode.cldr.util.StandardCodes.LstrField;
+import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.SupplementalDataInfo;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.impl.Row.R2;
+
+/**
+ * TestLsrvCanonicalizer is used to verify the correctness of the specification algorithm,
+ * sanity-check the supplementalMetadata.xml alias data,
+ * and generate test files for use by implementations.
+ */
+public class TestLsrvCanonicalizer extends TestFmwk {
+
+ static final LsrvCanonicalizer rrs = LsrvCanonicalizer.getInstance();
+ private static final boolean DEBUG = false;
+
+ public static void main(String[] args) {
+ final TestLsrvCanonicalizer testLocaleCanonicalizer = new TestLsrvCanonicalizer();
+ testLocaleCanonicalizer.run(args);
+ }
+
+ public void testAgainstData() {
+ if (DEBUG) {
+ System.out.println(Joiner.on('\n').join(rrs.filter(LstrType.variant, null)));
+ System.out.println(Joiner.on('\n').join(rrs.filter(LstrType.language, "no")));
+ }
+
+ List<ReplacementRule> rules = new ArrayList<>();
+ for (Entry<TestDataTypes, Map<String, String>> mainEntry : rrs.getTestData(null).entrySet()) {
+ TestDataTypes type = mainEntry.getKey();
+ for (Entry<String, String> entry : mainEntry.getValue().entrySet()) {
+ String toTest = entry.getKey();
+ String expected = entry.getValue();
+ final XLanguageTag source2 = XLanguageTag.fromTag(LstrType.language, toTest);
+ XLanguageTag newTag = rrs.canonicalizeToX(source2, rules);
+ String actual = newTag.toLocaleString();
+ if (DEBUG && rules.size() > 1) {
+ System.out.println(
+ "source: " + toTest
+ + ", expected: " + expected
+ + ", actual: " + actual
+ + ", rules: " + rules
+ );
+ }
+ if (!Objects.equal(expected, actual)) {
+ errln("Error: "
+ + "source: " + toTest
+ + ", expected: " + expected
+ + ", actual: " + actual
+ + ", rules: " + rules
+ );
+ }
+ }
+ }
+ }
+
+ public void TestAgainstLanguageSubtagRegistry() {
+ Map<String,String> exceptions = ImmutableMap.<String, String>builder()
+ .put("drh", "mn") // Darkhat => Halh Mongolian
+ .put("drw", "fa_af") // Darwazi => Dari
+ .put("tnf", "fa_af") // Tangshewi => Dari
+ .put("AN", "CW SX BQ") // Netherlands Antilles => list
+ .put("CS", "RS ME") // Serbia and Montenegro => list
+ .put("NT", "SA IQ") // Neutral Zone => ???
+ .put("SU", "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ") // Union of Soviet Socialist Republics => list
+ .put("YU", "RS ME") // Yugoslavia => list
+ .put("cel-gaulish", "xtg")
+ .put("i-enochian", "und_x_i_enochian")
+ .put("zh-guoyu", "zh") // Mandarin Chinese
+ .put("zh-min", "nan_x_zh_min") // special code
+ .put("sgn-NO", "nsi") // Norwegian Sign Language
+ .put("zh-cmn", "zh") // Chinese
+ .put("zh-cmn-Hans", "zh_Hans") // Simplified Chinese
+ .put("zh-cmn-Hant", "zh_Hant") // Traditional Chinese
+ .put("agp", "apf") // Paranan => ???
+ .put("ais", "ami") // Nataoran Amis => ???
+ .put("baz", "nvo") // Tunen => ???
+ .put("bhk", "fbl") // Albay Bicolano => ???
+ .put("bjq", "bzc") // Southern Betsimisaraka Malagasy => ???
+ .put("bkb", "ebk") // Finallig => ???
+ .put("btb", "beb") // Beti (Cameroon) => ???
+ .put("daf", "dnj") // Dan => ???
+ .put("dap", "njz") // Nisi (India) => ???
+ .put("djl", "dze") // Djiwarli => ???
+ .put("dkl", "aqd") // Kolum So Dogon => ???
+ .put("dud", "uth") // Hun-Saare => ???
+ .put("duj", "dwu") // Dhuwal => ???
+ .put("dwl", "dbt") // Walo Kumbe Dogon => ???
+ .put("elp", "amq") // Elpaputih => ???
+ .put("gbc", "wny") // Garawa => ???
+ .put("ggo", "esg") // Southern Gondi => ???
+ .put("ggr", "gtu") // Aghu Tharnggalu => ???
+ .put("gio", "aou") // Gelao => ???
+ .put("ill", "ilm") // Iranun => ???
+ .put("izi", "eza") // Izi-Ezaa-Ikwo-Mgbo => ???
+ .put("jar", "jgk") // Jarawa (Nigeria) => ???
+ .put("kdv", "zkd") // Kado => ???
+ .put("kgd", "ncq") // Kataang => ???
+ .put("kpp", "jkm") // Paku Karen => ???
+ .put("kzh", "dgl") // Kenuzi-Dongola => ???
+ .put("leg", "enl") // Lengua => ???
+ .put("mgx", "jbk") // Omati => ???
+ .put("mnt", "wnn") // Maykulan => ???
+ .put("mof", "xnt") // Mohegan-Montauk-Narragansett => ???
+ .put("mwd", "dmw") // Mudbura => ???
+ .put("nbf", "nru") // Naxi => ???
+ .put("nbx", "ekc") // Ngura => ???
+ .put("nln", "azd") // Durango Nahuatl => ???
+ .put("nlr", "nrk") // Ngarla => ???
+ .put("noo", "dtd") // Nootka => ???
+ .put("rmr", "emx") // Caló => ???
+ .put("sap", "aqt") // Sanapaná => ???
+ .put("sgl", "isk") // Sanglechi-Ishkashimi => ???
+ .put("sul", "sgd") // Surigaonon => ???
+ .put("sum", "ulw") // Sumo-Mayangna => ???
+ .put("tgg", "bjp") // Tangga => ???
+ .put("tid", "itd") // Tidong => ???
+ .put("unp", "wro") // Worora => ???
+ .put("wgw", "wgb") // Wagawaga => ???
+ .put("wit", "nol") // Wintu => ???
+ .put("wiw", "nwo") // Wirangu => ???
+ .put("yen", "ynq") // Yendang => ???
+ .put("yiy", "yrm") // Yir Yoront => ???
+ .build();
+ Set<String> SKIP = ImmutableSet.of(
+ // handled via languageAliases
+ "arevela", "arevmda",
+ // newly added
+ "bmy", "btl", "bxx", "byy", "cbe", "cbh", "cum", "dha", "dzd", "emo", "iap", "ime", "kbf", "kox", "lba", "lsg", "mhh", "mja", "mld", "mwx",
+ "mwy", "myi", "myq", "ome", "pbz", "pgy", "pod", "prb", "puk", "rie", "rna", "rsi", "sgo", "snh", "svr", "toe", "xbx", "xip", "yds", "ynh", "yri"
+ );
+
+// Error: (TestLsrvCanonicalizer.java:110) : drh: expected "khk", got "mn"
+// Error: (TestLsrvCanonicalizer.java:110) : drw: expected "prs", got "fa_af"
+// Error: (TestLsrvCanonicalizer.java:110) : tnf: expected "prs", got "fa_af"
+// Error: (TestLsrvCanonicalizer.java:110) : AN: expected null, got "CW SX BQ"
+// Error: (TestLsrvCanonicalizer.java:110) : CS: expected null, got "RS ME"
+// Error: (TestLsrvCanonicalizer.java:110) : NT: expected null, got "SA IQ"
+// Error: (TestLsrvCanonicalizer.java:110) : SU: expected null, got "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ"
+// Error: (TestLsrvCanonicalizer.java:110) : YU: expected null, got "RS ME"
+// Error: (TestLsrvCanonicalizer.java:110) : cel_gaulish: expected null, got "xtg"
+// Error: (TestLsrvCanonicalizer.java:110) : i_enochian: expected null, got "und_x_i_enochian"
+// Error: (TestLsrvCanonicalizer.java:110) : zh_guoyu: expected "cmn", got "zh"
+// Error: (TestLsrvCanonicalizer.java:110) : zh_min: expected null, got "nan_x_zh_min"
+// Error: (TestLsrvCanonicalizer.java:110) : sgn_NO: expected "nsl", got "nsi"
+// Error: (TestLsrvCanonicalizer.java:119) Can't access aliasInfo for the following. Suggested additions are:
+
+ SupplementalDataInfo SDI = SupplementalDataInfo.getInstance();
+ Map<String, Map<String, R2<List<String>, String>>> aliasInfo = SDI.getLocaleAliasInfo();
+ Set<String> shouldHave = new LinkedHashSet<>();
+ Set<String> shouldSkip = new LinkedHashSet<>();
+ Set<String> addExceptions = new LinkedHashSet<>();
+
+ for ( Entry<LstrType, Map<String, Map<LstrField, String>>> entry1 : StandardCodes.getEnumLstreg().entrySet()) {
+ LstrType type = entry1.getKey();
+ if (type == LstrType.extlang) {
+ continue;
+ }
+ final String typeCompat = type.toCompatString();
+ Map<String, R2<List<String>, String>> aliasInfo2 = aliasInfo.get(typeCompat);
+ if (aliasInfo2 == null) {
+ errln("Can't access aliasInfo for: " + type);
+ continue;
+ }
+
+ for (Entry<String, Map<LstrField, String>> entry2 : entry1.getValue().entrySet()) {
+ String subtag = entry2.getKey();
+ final Map<LstrField, String> subtagInfo = entry2.getValue();
+ String deprecated = subtagInfo.get(LstrField.Deprecated);
+ if (deprecated == null) {
+ continue;
+ }
+ String preferredValue = subtagInfo.get(LstrField.Preferred_Value);
+ final String preferredValueCompat = preferredValue == null ? null : preferredValue.replace('-', '_');
+ final String subtagCompat = subtag.replace('-', '_');
+ R2<List<String>, String> aliasInfo3 = aliasInfo2.get(subtagCompat);
+ if (aliasInfo3 == null) {
+ if (SKIP.contains(subtag)) {
+ continue;
+ }
+ String possibleReplacement = preferredValueCompat != null ? preferredValueCompat : subtagInfo.get(LstrField.Comments);
+ // <languageAlias type="sgn_BR" replacement="bzs" reason="deprecated"/>
+ if (possibleReplacement != null) {
+ shouldHave.add("<" + typeCompat + "Alias"
+ + " type=\"" + subtagCompat + "\""
+ + (possibleReplacement == null || possibleReplacement.isEmpty() ? "" : " replacement=\"" + possibleReplacement + "\"")
+ + " reason=\"" + (type == LstrType.legacy || type == LstrType.redundant ? type.toString() : "deprecated") + "\""
+ + "/> <!-- " + subtagInfo.get(LstrField.Description) + " -->");
+ } else {
+ shouldSkip.add(subtag);
+ }
+ continue;
+ }
+ List<String> replacement = aliasInfo3.get0();
+ String reason = aliasInfo3.get1();
+ final String replacementString = Joiner.on(' ').join(replacement);
+ if (!Objects.equal(preferredValueCompat, replacementString)) {
+ String exception = exceptions.get(subtag);
+ if (Objects.equal(exception, replacementString)) {
+ continue;
+ }
+ CLDRFile english = CLDRConfig.getInstance().getEnglish();
+ String typeName = english.getName(typeCompat, subtag);
+ String replacementName = preferredValueCompat == null ? "???" : english.getName(typeCompat, replacementString);
+ addExceptions.add(".put(\"" + subtag + "\", \"" + replacementString + "\")" + " // " + typeName + " => " + replacementName);
+ }
+
+// for (Entry<LstrField, String> entry3 : entry2.getValue().entrySet()) {
+// LstrField field = entry3.getKey();
+// String data = entry3.getValue();
+// }
+ }
+ }
+ if (!addExceptions.isEmpty()) {
+ errln("The following have different replacements.\n"
+ + " Here are suggested exception values to add to the test code, but research each one:");
+ System.out.println(Joiner.on('\n').join(addExceptions));
+ System.out.println();
+ }
+
+ if (!shouldHave.isEmpty()) {
+ errln("Can't access aliasInfo for the following.\n"
+ + " Here are suggested additions to supplementalMetadata , but check them:");
+ System.out.println(Joiner.on('\n').join(shouldHave));
+ System.out.println();
+ }
+ if (!shouldSkip.isEmpty()) {
+ errln("No replacement.\n"
+ + " Here are suggested additions to SKIP in the test code, but check them:");
+ System.out.println("\"" + Joiner.on("\", \"").join(shouldSkip) + "\"");
+ System.out.println();
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestMetazoneTransitions.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestMetazoneTransitions.java
index 8854c43..3f3112e 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestMetazoneTransitions.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestMetazoneTransitions.java
@@ -90,11 +90,13 @@
int offset;
+ @Override
public boolean equals(Object that) {
ZoneTransition other = (ZoneTransition) that;
return date == other.date && offset == other.offset;
}
+ @Override
public int hashCode() {
return (int) (date ^ (date >>> 32) ^ offset);
}
@@ -111,6 +113,7 @@
* @param o
* @return
*/
+ @Override
public int compareTo(ZoneTransition o) {
int delta = offset - o.offset;
if (delta != 0)
@@ -133,11 +136,13 @@
private static class ZoneTransitions implements Comparable<ZoneTransitions> {
List<ZoneTransition> chronologicalList = new ArrayList<ZoneTransition>();
+ @Override
public boolean equals(Object that) {
ZoneTransitions other = (ZoneTransitions) that;
return chronologicalList.equals(other.chronologicalList);
}
+ @Override
public int hashCode() {
return chronologicalList.hashCode();
}
@@ -173,6 +178,7 @@
chronologicalList.add(new ZoneTransition(date, offset));
}
+ @Override
public int compareTo(ZoneTransitions other) {
int minSize = Math.min(chronologicalList.size(),
other.chronologicalList.size());
@@ -204,6 +210,7 @@
return CldrUtility.join(chronologicalList, separator);
}
+ @Override
public String toString() {
return toString("; ", -1);
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathHeader.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathHeader.java
index d18f44f..4c67d23 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathHeader.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathHeader.java
@@ -53,12 +53,12 @@
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -101,6 +101,8 @@
assertRelation("pathheader", true, ph3, TestFmwkPlus.LEQ, ph2);
}
+ static final String[] MIN_LOCALES = {"root", "en", "de", "ru", "ko"}; // choose locales with range of case/gender structures
+
public void tempTestCompletenessLdmlDtd() {
// List<String> failures = null;
pathHeaderFactory.clearCache();
@@ -108,7 +110,7 @@
for (String directory : DtdType.ldml.directories) {
Factory factory2 = CLDRConfig.getInstance().getMainAndAnnotationsFactory();
Set<String> source = factory2.getAvailable();
- for (String file : getFilesToTest(source, "root", "en", "da")) {
+ for (String file : getFilesToTest(source, MIN_LOCALES)) {
if (DEBUG) warnln(" TestCompletenessLdmlDtd: " + directory + ", " + file);
DtdData dtdData = null;
CLDRFile cldrFile = factory2.make(file, true);
@@ -268,7 +270,7 @@
}
public void TestPluralOrder() {
- Set<PathHeader> sorted = new TreeSet<PathHeader>();
+ Set<PathHeader> sorted = new TreeSet<>();
for (String locale : new String[] { "ru", "ar", "ja" }) {
sorted.clear();
CLDRFile cldrFile = info.getCLDRFile(locale, true);
@@ -340,7 +342,7 @@
public void TestOptional() {
if (true) return;
- Map<PathHeader, String> sorted = new TreeMap<PathHeader, String>();
+ Map<PathHeader, String> sorted = new TreeMap<>();
for (String locale : new String[] { "af" }) {
sorted.clear();
CLDRFile cldrFile = info.getCLDRFile(locale, true);
@@ -368,7 +370,7 @@
locale + "\t" + status + "\t" + p + "\t"
+ p.getOriginalPath());
}
- Set<String> codes = new LinkedHashSet<String>();
+ Set<String> codes = new LinkedHashSet<>();
PathHeader old = null;
String line = null;
for (Entry<PathHeader, String> s : sorted.entrySet()) {
@@ -450,7 +452,7 @@
}
public void TestCoverage() {
- Map<Row.R2<SectionId, PageId>, Counter<Level>> data = new TreeMap<Row.R2<SectionId, PageId>, Counter<Level>>();
+ Map<Row.R2<SectionId, PageId>, Counter<Level>> data = new TreeMap<>();
CLDRFile cldrFile = english;
for (String path : cldrFile.fullIterable()) {
if (supplemental.isDeprecated(DtdType.ldml, path)) {
@@ -478,7 +480,7 @@
p.getPageId());
Counter<Level> counter = data.get(key);
if (counter == null) {
- data.put(key, counter = new Counter<Level>());
+ data.put(key, counter = new Counter<>());
}
counter.add(level, 1);
}
@@ -503,9 +505,9 @@
public void Test00AFile() {
final String localeId = "en";
- Counter<Level> counter = new Counter<Level>();
- Map<String, PathHeader> uniqueness = new HashMap<String, PathHeader>();
- Set<String> alreadySeen = new HashSet<String>();
+ Counter<Level> counter = new Counter<>();
+ Map<String, PathHeader> uniqueness = new HashMap<>();
+ Set<String> alreadySeen = new HashSet<>();
check(localeId, true, uniqueness, alreadySeen);
// check paths
for (Entry<SectionId, Set<PageId>> sectionAndPages : PathHeader.Factory
@@ -586,7 +588,7 @@
}
public Set<PathHeader> getPathHeaders(CLDRFile nativeFile) {
- Set<PathHeader> pathHeaders = new TreeSet<PathHeader>();
+ Set<PathHeader> pathHeaders = new TreeSet<>();
for (String path : nativeFile.fullIterable()) {
PathHeader p = pathHeaderFactory.fromPath(path);
pathHeaders.add(p);
@@ -627,34 +629,38 @@
}
public void TestUniqueness() {
- CLDRFile nativeFile = info.getEnglish();
- Map<PathHeader, String> headerToPath = new HashMap<PathHeader, String>();
- Map<String, String> headerVisibleToPath = new HashMap<String, String>();
- for (String path : nativeFile.fullIterable()) {
- PathHeader p = pathHeaderFactory.fromPath(path);
- if (p.getSectionId() == SectionId.Special) {
- continue;
- }
- String old = headerToPath.get(p);
- if (old == null) {
- headerToPath.put(p, path);
- } else if (!old.equals(path)) {
- if (true) { // for debugging
- pathHeaderFactory.clearCache();
- List<String> failuresOld = new ArrayList<>();
- pathHeaderFactory.fromPath(old, failuresOld);
- List<String> failuresPath = new ArrayList<>();
- pathHeaderFactory.fromPath(path, failuresPath);
+ Factory factory2 = CLDRConfig.getInstance().getMainAndAnnotationsFactory();
+ Set<String> source = factory2.getAvailable();
+ for (String file : getFilesToTest(source, MIN_LOCALES)) {
+ CLDRFile nativeFile = factory2.make(file,true);
+ Map<PathHeader, String> headerToPath = new HashMap<>();
+ Map<String, String> headerVisibleToPath = new HashMap<>();
+ for (String path : nativeFile.fullIterable()) {
+ PathHeader p = pathHeaderFactory.fromPath(path);
+ if (p.getSectionId() == SectionId.Special) {
+ continue;
}
- errln("Collision with path " + p + "\t" + old + "\t" + path);
- }
- final String visible = p.toString();
- old = headerVisibleToPath.get(visible);
- if (old == null) {
- headerVisibleToPath.put(visible, path);
- } else if (!old.equals(path)) {
- errln("Collision with path " + visible + "\t" + old + "\t"
- + path);
+ String old = headerToPath.get(p);
+ if (old == null) {
+ headerToPath.put(p, path);
+ } else if (!old.equals(path)) {
+ if (true) { // for debugging
+ pathHeaderFactory.clearCache();
+ List<String> failuresOld = new ArrayList<>();
+ pathHeaderFactory.fromPath(old, failuresOld);
+ List<String> failuresPath = new ArrayList<>();
+ pathHeaderFactory.fromPath(path, failuresPath);
+ }
+ errln(file + " collision with path " + p + "\t" + old + "\t" + path);
+ }
+ final String visible = p.toString();
+ old = headerVisibleToPath.get(visible);
+ if (old == null) {
+ headerVisibleToPath.put(visible, path);
+ } else if (!old.equals(path)) {
+ errln("Collision with path " + visible + "\t" + old + "\t"
+ + path);
+ }
}
}
}
@@ -662,11 +668,11 @@
public void TestStatus() {
CLDRFile nativeFile = info.getEnglish();
PathStarrer starrer = new PathStarrer();
- EnumMap<SurveyToolStatus, Relation<String, String>> info2 = new EnumMap<SurveyToolStatus, Relation<String, String>>(
+ EnumMap<SurveyToolStatus, Relation<String, String>> info2 = new EnumMap<>(
SurveyToolStatus.class);
- Set<String> nuked = new HashSet<String>();
- Set<String> deprecatedStar = new HashSet<String>();
- Set<String> differentStar = new HashSet<String>();
+ Set<String> nuked = new HashSet<>();
+ Set<String> deprecatedStar = new HashSet<>();
+ Set<String> differentStar = new HashSet<>();
for (String path : nativeFile.fullIterable()) {
@@ -718,7 +724,7 @@
data = Relation.of(new TreeMap<String, Set<String>>(),
TreeSet.class));
}
- data.put(starred, CollectionUtilities.join(attr, "|"));
+ data.put(starred, Joiner.on("|").join(attr));
}
for (Entry<SurveyToolStatus, Relation<String, String>> entry : info2
.entrySet()) {
@@ -736,11 +742,11 @@
}
public void TestPathsNotInEnglish() {
- Set<String> englishPaths = new HashSet<String>();
+ Set<String> englishPaths = new HashSet<>();
for (String path : english.fullIterable()) {
englishPaths.add(path);
}
- Set<String> alreadySeen = new HashSet<String>(englishPaths);
+ Set<String> alreadySeen = new HashSet<>(englishPaths);
for (String locale : factory.getAvailable()) {
CLDRFile nativeFile = info.getCLDRFile(locale, false);
@@ -768,7 +774,7 @@
Matcher normal = PatternCache.get(
"http://cldr.org/translation/[-a-zA-Z0-9_]").matcher("");
// http://cldr.unicode.org/translation/plurals#TOC-Minimal-Pairs
- Set<String> alreadySeen = new HashSet<String>();
+ Set<String> alreadySeen = new HashSet<>();
PathStarrer starrer = new PathStarrer();
checkPathDescriptionCompleteness(pathDescription, normal,
@@ -816,7 +822,7 @@
public void TestTerritoryOrder() {
final Set<String> goodAvailableCodes = CLDRConfig.getInstance()
.getStandardCodes().getGoodAvailableCodes("territory");
- Set<String> results = showContained("001", 0, new HashSet<String>(
+ Set<String> results = showContained("001", 0, new HashSet<>(
goodAvailableCodes));
results.remove("ZZ");
for (String territory : results) {
@@ -854,8 +860,8 @@
}
public void TestZCompleteness() {
- Map<String, PathHeader> uniqueness = new HashMap<String, PathHeader>();
- Set<String> alreadySeen = new HashSet<String>();
+ Map<String, PathHeader> uniqueness = new HashMap<>();
+ Set<String> alreadySeen = new HashSet<>();
LanguageTagParser ltp = new LanguageTagParser();
int count = 0;
for (String locale : factory.getAvailable()) {
@@ -973,10 +979,10 @@
PathStarrer pathStarrer = new PathStarrer();
pathStarrer.setSubstitutionPattern("%A");
- Set<PathHeader> sorted = new TreeSet<PathHeader>();
- Map<String, String> missing = new TreeMap<String, String>();
- Map<String, String> skipped = new TreeMap<String, String>();
- Map<String, String> collide = new TreeMap<String, String>();
+ Set<PathHeader> sorted = new TreeSet<>();
+ Map<String, String> missing = new TreeMap<>();
+ Map<String, String> skipped = new TreeMap<>();
+ Map<String, String> collide = new TreeMap<>();
logln("Traversing Paths");
for (String path : english) {
@@ -998,7 +1004,7 @@
String lastHeader = "";
String lastPage = "";
String lastSection = "";
- List<String> threeLevel = new ArrayList<String>();
+ List<String> threeLevel = new ArrayList<>();
Status status = new Status();
CoverageLevel2 coverageLevel2 = CoverageLevel2.getInstance("en");
@@ -1060,7 +1066,7 @@
for (String item : threeLevel) {
logln(item);
}
- LinkedHashMap<String, Set<String>> sectionsToPages = pathHeaderFactory
+ LinkedHashMap<String, Set<String>> sectionsToPages = org.unicode.cldr.util.PathHeader.Factory
.getSectionsToPages();
logln("\nMenus:\t" + sectionsToPages.size());
for (Entry<String, Set<String>> item : sectionsToPages.entrySet()) {
@@ -1077,6 +1083,16 @@
}
}
+ public static final Set<String> GERMAN_UNIT_ORDER = ImmutableSet.of(
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"power2\"]",
+ "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"volume-liter\"]",
+ "//ldml/units/unitLength[@type=\"narrrow\"]/unit[@type=\"volume-liter\"]",
+ "//ldml/numbers/minimalPairs/caseMinimalPairs",
+ "//ldml/numbers/minimalPairs/genderMinimalPairs"
+ );
public void TestOrder() {
String[] paths = {
"//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"narrow\"]/dayPeriod[@type=\"noon\"]",
@@ -1090,7 +1106,90 @@
}
pathHeaderLast = pathHeader;
}
+ CLDRFile german = factory.make("de", true);
+ Multimap<PathHeader, String> pathHeaderToPaths = TreeMultimap.create();
+ for (String path : german.fullIterable()) {
+ for (String prefix : GERMAN_UNIT_ORDER) {
+ if (path.startsWith(prefix)) {
+ PathHeader pathHeader = pathHeaderFactory.fromPath(path);
+ pathHeaderToPaths.put(pathHeader, path);
+ }
+ }
+ }
+ String[] germanExpected = {
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/gender",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/displayName",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/perUnitPattern",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"one\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"one\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"one\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"other\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"other\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"other\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"other\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"volume-liter\"]/displayName",
+ "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"volume-liter\"]/perUnitPattern",
+ "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"volume-liter\"]/unitPattern[@count=\"other\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"masculine\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"masculine\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"masculine\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"masculine\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"masculine\"][@case=\"accusative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"masculine\"][@case=\"dative\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"masculine\"][@case=\"genitive\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"masculine\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]",
+ "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]",
+ "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"accusative\"]",
+ "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"dative\"]",
+ "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"genitive\"]",
+ "//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"nominative\"]",
+ "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"feminine\"]",
+ "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"masculine\"]",
+ "//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"neuter\"]",
+ "//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ "//ldml/units/unitLength[@type=\"short\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1",
+ "//ldml/units/unitLength[@type=\"narrow\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1"};
+ int germanExpectedIndex = 0;
+ int errorCount = 0;
+ for (Entry<PathHeader, Collection<String>> entry : pathHeaderToPaths.asMap().entrySet()) {
+ PathHeader ph = entry.getKey();
+ Collection<String> epaths = entry.getValue();
+ if (!assertEquals(entry.toString(), 1, epaths.size())) {
+ ++errorCount;
+ }
+ if (!assertEquals("PathHeader order", germanExpected[germanExpectedIndex++], epaths.iterator().next())) {
+ ++errorCount;
+ }
+ }
+ if (errorCount != 0) {
+ for (Entry<PathHeader, Collection<String>> entry : pathHeaderToPaths.asMap().entrySet()) {
+ PathHeader ph = entry.getKey();
+ Collection<String> epaths = entry.getValue();
+ System.out.println("\"" + epaths.iterator().next().replace("\"", "\\\"") + "\",\t// " + ph);
+ }
+ }
}
public void Test8414() {
@@ -1144,7 +1243,6 @@
}
pathChecker.checkPathHeader(dtdData, path);
}
- ;
}
}
}
@@ -1216,7 +1314,7 @@
String star = starrer.set(path);
if (badHeaders.add(star)) {
errln(star + message + ", " + ph);
- System.out.println("\tNo match in PathHeader.txt for " + path
+ System.out.println("\tNo match in PathHeader.txt for " + path
+ "\n\tYou get only one message for all paths matching " + star
+ "\n\tFor example, check to see if the field in PathHeader.txt is in PathHeader.PageId."
+ "\n\tIf not, either correct PathHeader.txt or add it to PageId"
@@ -1272,7 +1370,7 @@
// Moved from TestAnnotations and generalized
public void testPathHeaderSize() {
String locale = "ar"; // choose one with lots of plurals
- int maxSize = 700;
+ int maxSize = 750;
boolean showTable = false; // only printed if test fails or verbose
Factory factory = CLDRConfig.getInstance().getCommonAndSeedAndMainAndAnnotationsFactory();
@@ -1343,4 +1441,16 @@
}
}
+ public void TestQuotes() {
+ // quotes should never appear in result
+ PathHeader.Factory phf = PathHeader.getFactory();
+ String[] tests = {
+ "//supplementalData/plurals[@type=\"ordinal\"]/pluralRules[@locales=\"ig\"]/pluralRule[@count=\"other\"]",
+ "//supplementalData/transforms/transform[@source=\"und-Khmr\"][@target=\"und-Latn\"]"
+ };
+ for (String test : tests) {
+ PathHeader trial = phf.fromPath(test);
+ assertEquals("No quotes in pathheader", false, trial.toString().contains("\""));
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPaths.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPaths.java
index 9bfc693..6816fee 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPaths.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPaths.java
@@ -36,7 +36,6 @@
import org.unicode.cldr.util.XPathParts;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class TestPaths extends TestFmwkPlus {
static CLDRConfig testInfo = CLDRConfig.getInstance();
@@ -46,11 +45,10 @@
}
public void VerifyEnglishVsRoot() {
- Set<String> rootPaths = CollectionUtilities.addAll(testInfo
- .getRoot().iterator(),
- new HashSet<String>());
- Set<String> englishPaths = CollectionUtilities.addAll(testInfo
- .getEnglish().iterator(), new HashSet<String>());
+ HashSet<String> rootPaths = new HashSet<String>();
+ testInfo.getRoot().forEach(rootPaths::add);
+ HashSet<String> englishPaths = new HashSet<String>();
+ testInfo.getEnglish().forEach(englishPaths::add);
englishPaths.removeAll(rootPaths);
if (englishPaths.size() == 0) {
return;
@@ -92,10 +90,10 @@
StringBuilder b = new StringBuilder();
for (PathHeader path : altPaths) {
b.append("\n\t\t")
- .append(path)
- .append(":\t")
- .append(testInfo.getEnglish().getStringValue(
- path.getOriginalPath()));
+ .append(path)
+ .append(":\t")
+ .append(testInfo.getEnglish().getStringValue(
+ path.getOriginalPath()));
}
return b.toString();
}
@@ -151,22 +149,28 @@
String fullPath = file.getFullXPath(path);
String value = file.getStringValue(path);
String source = file.getSourceLocaleID(path, status);
+
+ assertEquals("CanonicalOrder", XPathParts.getFrozenInstance(path).toString(), path);
+
if (fullPath == null) {
- errln("Locale: " + locale + ",\t FullPath: " + path);
+ errln("Locale: " + locale + ",\t Null FullPath: " + path);
+ } else if (!path.equals(fullPath)) {
+ assertEquals("CanonicalOrder (FP)", XPathParts.getFrozenInstance(fullPath).toString(), fullPath);
}
+
if (value == null) {
- /*
- * Allow null value for some exceptional extra paths.
- */
- if (!isExtraPath || !extraPathAllowsNullValue(path)) {
- errln("Locale: " + locale + ",\t Value: " + path);
+ if (isExtraPath && extraPathAllowsNullValue(path)) {
+ return;
}
+ errln("Locale: " + locale + ",\t Null Value: " + path);
}
+
if (source == null) {
- errln("Locale: " + locale + ",\t Source: " + path);
+ errln("Locale: " + locale + ",\t Null Source: " + path);
}
+
if (status.pathWhereFound == null) {
- errln("Locale: " + locale + ",\t Found Path: " + path);
+ errln("Locale: " + locale + ",\t Null Found Path: " + path);
}
}
@@ -195,9 +199,14 @@
* Reference: https://unicode-org.atlassian.net/browse/CLDR-11238
*/
private boolean extraPathAllowsNullValue(String path) {
- if (path.contains("timeZoneNames/metazone") ||
- path.contains("timeZoneNames/zone") ||
- path.contains("dayPeriods/dayPeriodContext")) {
+ if (path.contains("/timeZoneNames/metazone")
+ || path.contains("/timeZoneNames/zone")
+ || path.contains("/dayPeriods/dayPeriodContext")
+ || path.contains("/unitPattern")
+ || path.contains("/gender")
+ || path.contains("/caseMinimalPairs")
+ || path.contains("/genderMinimalPairs")
+ ) {
return true;
}
return false;
@@ -226,10 +235,9 @@
}
private Collection<String> getLocalesToTest() {
- return params.inclusion <= 5 ? Arrays.asList("root", "en", "ja", "ar")
- : params.inclusion < 10 ? testInfo.getCldrFactory()
- .getAvailableLanguages() : testInfo.getCldrFactory()
- .getAvailable();
+ return params.inclusion <= 5 ? Arrays.asList("root", "en", "ja", "ar", "de", "ru")
+ : params.inclusion < 10 ? testInfo.getCldrFactory().getAvailableLanguages()
+ : testInfo.getCldrFactory().getAvailable();
}
/**
@@ -270,11 +278,20 @@
for (Entry<String, String> attributeNValue : parts.getAttributes(i).entrySet()) {
String attributeName = attributeNValue.getKey();
if (dtdData.isDeprecated(elementName, attributeName, "*")) {
- testPaths.errln("Deprecated attribute in data: "
- + dtdData.dtdType
- + ":" + elementName
- + ":" + attributeName
- + " \t;" + fullName);
+ if (attributeName.equals("draft")) {
+ testPaths.errln("Deprecated attribute in data: "
+ + dtdData.dtdType
+ + ":" + elementName
+ + ":" + attributeName
+ + " \t;" + fullName +
+ " - consider adding to DtdData.DRAFT_ON_NON_LEAF_ALLOWED if you are sure this is ok.");
+ } else {
+ testPaths.errln("Deprecated attribute in data: "
+ + dtdData.dtdType
+ + ":" + elementName
+ + ":" + attributeName
+ + " \t;" + fullName);
+ }
return true;
}
String attributeValue = attributeNValue.getValue();
@@ -359,7 +376,7 @@
String[] normalizedPath = { "" };
int counter = 0;
- for (String directory : Arrays.asList("keyboards/", "common/")) {
+ for (String directory : Arrays.asList("keyboards/", "common/", "seed/", "exemplars/")) {
String dirPath = CLDRPaths.BASE_DIRECTORY + directory;
for (String fileName : new File(dirPath).list()) {
File dir2 = new File(dirPath + fileName);
@@ -370,7 +387,7 @@
// || fileName.equals("dtd") // TODO as flat files
// || fileName.equals(".project") // TODO as flat files
// //|| dir.equals("uca") // TODO as flat files
- ) {
+ ) {
continue;
}
@@ -391,7 +408,7 @@
for (Pair<String, String> pathValue : XMLFileReader.loadPathValues(fullName, new ArrayList<Pair<String, String>>(), true)) {
String path = pathValue.getFirst();
final String value = pathValue.getSecond();
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for removeNonDistinguishing
+ XPathParts parts = XPathParts.getFrozenInstance(path);
if (dtdData == null) {
type = DtdType.valueOf(parts.getElement(0));
dtdData = DtdData.getInstance(type);
@@ -441,6 +458,7 @@
if (!normalizedPath.equals(path) && !normalizedPath[0].equals(dpath)) {
checkParts(normalizedPath[0], dtdData);
}
+ parts = parts.cloneAsThawed();
counter = removeNonDistinguishing(parts, dtdData, counter, removed, nonFinalValues);
String cleaned = parts.toString();
Pair<String, String> pair = Pair.of(type == DtdType.ldml ? file : type.toString(), cleaned);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathsModule.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathsModule.java
index fb3a8da..acfaf00 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathsModule.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPathsModule.java
@@ -17,6 +17,7 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.DtdType;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XMLFileReader.SimpleHandler;
@@ -62,7 +63,7 @@
// Only test against /main for now.
File dir = new File(CLDRPaths.MAIN_DIRECTORY);
for (File file : dir.listFiles()) {
- String fullFileName = file.getCanonicalPath();
+ String fullFileName = PathUtilities.getNormalizedPathString(file);
String filename = file.getName();
if (filename.startsWith("#") || !filename.endsWith(".xml")
|| !FILE_FILTER.reset(filename).find())
@@ -99,6 +100,7 @@
}
}
+ @Override
public void handlePathValue(String path, String value) {
if (!PATH_FILTER.reset(path).find()) {
return;
@@ -197,6 +199,7 @@
private Map<String, OrderedChildren> orderedChildrenStatus = new TreeMap<String, OrderedChildren>();
+ @Override
public void test(XPathParts fullParts, String value) {
super.test(fullParts, value);
int size = fullParts.size();
@@ -268,6 +271,7 @@
return firstQ;
}
+ @Override
public void finish() {
super.finish();
for (R3<DtdType, String, String> item : nonFinalNonDistingishing
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPerf.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPerf.java
index c0b17d3..51ccd7f 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPerf.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPerf.java
@@ -15,7 +15,6 @@
import org.unicode.cldr.util.Timer;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.util.Output;
public class TestPerf extends TestFmwkPlus {
@@ -33,8 +32,8 @@
static {
Set<String> testPaths_ = new HashSet<String>();
- CollectionUtilities.addAll(CLDRConfig.getInstance().getEnglish()
- .iterator(), testPaths_);
+ CLDRConfig.getInstance().getEnglish()
+ .forEach(testPaths_::add);
testPaths = Collections.unmodifiableSet(testPaths_);
Set<String> sorted = new TreeSet<String>(
CLDRFile.getComparator(DtdType.ldml));
@@ -124,7 +123,7 @@
int size = 0;
for (String p : testPaths) {
for (int i = 0; i < ITERATIONS; ++i) {
- XPathParts xpp = XPathParts.getInstance(p);
+ XPathParts xpp = XPathParts.getFrozenInstance(p);
size += xpp.size();
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPluralRuleGeneration.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPluralRuleGeneration.java
index ee00053..e865bd9 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPluralRuleGeneration.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestPluralRuleGeneration.java
@@ -1,6 +1,10 @@
package org.unicode.cldr.unittest;
+import java.text.ParseException;
+import java.util.Arrays;
import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@@ -9,8 +13,24 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
+import com.ibm.icu.math.BigDecimal;
+import com.ibm.icu.number.Notation;
+import com.ibm.icu.number.NumberFormatter;
+import com.ibm.icu.number.NumberFormatter.UnitWidth;
+import com.ibm.icu.number.Precision;
+import com.ibm.icu.number.UnlocalizedNumberFormatter;
+import com.ibm.icu.text.DecimalFormat;
+import com.ibm.icu.text.FixedDecimal;
import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.PluralRules.IFixedDecimal;
+import com.ibm.icu.text.PluralRules.Operand;
import com.ibm.icu.text.PluralRules.SampleType;
+import com.ibm.icu.util.ICUException;
+import com.ibm.icu.util.MeasureUnit;
+import com.ibm.icu.util.ULocale;
public class TestPluralRuleGeneration extends TestFmwkPlus {
public static void main(String[] args) {
@@ -89,4 +109,274 @@
}
}
+
+ public void TestEFixedDecimal() {
+ PluralRules test;
+ try {
+ test = PluralRules.parseDescription("many: e = 0 and i != 0 and i % 1000000 = 0 and v = 0 or e != 0 .. 5 @integer 1000000");
+ } catch (ParseException e) {
+ throw new ICUException(e);
+ }
+ Object[][] checkItems = {
+ // compare each group of items against one another, where a group is bounded by {},
+ // source, f, v, e, plural (, skipString — if toString doesn't roundtrip)?
+ {"2300000", 2300000d, 0, 0, "other"},
+ {"2.3e6", 2300000d, 0, 6, "many"},
+ {},
+ {"1.20050e3",1200.5d, 2, 3, "other", "skipString"},
+ {},
+ {"1200.5", 1200.5d, 1, 0, "other"},
+ {"1.2005e3", 1200.5d, 1, 3, "other"},
+ {},
+ {"1200000", 1200000d, 0, 0, "other"},
+ {"1.2e6", 1200000d, 0, 6, "many"},
+ {"1.20e6", 1200000d, 0, 6, "many", "skipString"},
+ {},
+ {"1234567.8", 1234567.8, 1, 0, "other"},
+ {"123456.78e1", 1234567.8, 1, 1, "other"},
+ {"12.345678e5", 1234567.8, 1, 5, "other"},
+ {"1.2345678e6", 1234567.8, 1, 6, "many"},
+ };
+ String lastSource = null;
+ FixedDecimal lastFromString = null;
+ Map<Operand, Double> lastOperands = null;
+ for (Object[] row : checkItems) {
+ if (row.length == 0) {
+ // reset to different group
+ lastSource = null;
+ lastFromString = null;
+ lastOperands = null;
+ continue;
+ }
+ String rowString = Arrays.asList(row).toString();
+
+ final String source = (String)row[0];
+ final double fExpected = (double)row[1];
+ final int vExpected = (int)row[2];
+ final int eExpected = (int)row[3];
+ final String pluralExpected = (String)row[4];
+ final boolean checkString = row.length < 6 || !"skipString".equals(row[5]);
+
+ // basics
+
+ FixedDecimal fromString = new FixedDecimal(source);
+
+ final String fromToString = fromString.toString();
+ if (checkString && !assertEquals(rowString + " source vs fromString", source, fromToString)) {
+ fromString.toString(); // for debugging
+ }
+ if (!assertEquals(rowString + " double vs toString", fExpected, fromString.doubleValue())) {
+ fromString.doubleValue(); // for debugging
+ }
+ String pluralActual = test.select(fromString);
+ assertEquals(rowString + " plural category", pluralExpected, pluralActual);
+
+ // previous in group
+
+ Map<Operand, Double> operands = getOperandMap(fromString);
+ if (lastFromString != null) {
+ if (!assertTrue(lastSource + (checkString ? " < " : " ≤ ") + source, lastFromString.compareTo(fromString) < (checkString ? 0 : 1))) {
+ lastFromString.compareTo(fromString); // for debugging
+ }
+ assertEquals("double " + lastSource + " vs " + source, lastFromString.doubleValue(), lastFromString.doubleValue());
+ assertEquals("operands " + lastSource + " vs " + source, lastOperands, operands);
+ }
+
+ // different constructor
+
+ FixedDecimal fromDoubleAndExponent = FixedDecimal.createWithExponent(fExpected, vExpected, eExpected);
+
+ if (!assertEquals(rowString + " fromString vs fromDoubleAndExponent", fromString, fromDoubleAndExponent)) {
+ FixedDecimal.createWithExponent(fExpected, vExpected, eExpected);
+ }
+ assertEquals(rowString + " double vs fromDoubleAndExponent", fExpected, fromDoubleAndExponent.doubleValue());
+
+ assertEquals(rowString + " exponent, fromString vs fromDoubleAndExponent", fromString.getPluralOperand(Operand.e), fromDoubleAndExponent.getPluralOperand(Operand.e));
+
+ assertEquals(rowString + " fromString vs fromDoubleAndExponent", 0, fromString.compareTo(fromDoubleAndExponent));
+
+
+ lastSource = source;
+ lastFromString = fromString;
+ lastOperands = operands;
+ }
+ }
+
+ private Map<Operand,Double> getOperandMap(FixedDecimal fixedDecimal) {
+ Map<Operand,Double> result = new LinkedHashMap<>();
+ for (Operand op : Operand.values()) {
+ switch (op) {
+ case e: case j:
+ continue;
+ }
+ result.put(op, fixedDecimal.getPluralOperand(op));
+ }
+ return ImmutableMap.copyOf(result);
+ }
+
+ static final Set<Operand> orderedOperands = ImmutableSet.of(Operand.n, Operand.i, Operand.v, Operand.w, Operand.f, Operand.t, Operand.e);
+
+ public void TestEFixedDecimal2() {
+ UnlocalizedNumberFormatter unfScientific = NumberFormatter.with()
+ .unit(MeasureUnit.KILOMETER)
+ .unitWidth(UnitWidth.FULL_NAME)
+ .notation(Notation.engineering());
+
+ UnlocalizedNumberFormatter unfCompact = unfScientific.notation(Notation.compactLong());
+ unfScientific = unfScientific.precision(Precision.minMaxSignificantDigits(1, 3));
+
+ ImmutableSet<ULocale> locales = ImmutableSet.of(ULocale.ENGLISH, ULocale.FRENCH);
+ ImmutableSet<String> tests = ImmutableSet.of(
+ "1", "1.0", "1.00",
+ "1.3", "1.30", "1.03", "1.230",
+ "1200000", "1.2e6",
+ "123e6",
+ "123e5",
+ "1200.50",
+ "1.20050e3"
+ );
+
+ for (String test : tests) {
+ final FixedDecimal source = new FixedDecimal(test);
+ assertEquals("check toString", test, source.toString());
+ }
+
+ System.out.println();
+ String ops = "";
+ for (Operand op : orderedOperands) {
+ ops += "\t" + op.toString();
+ }
+ System.out.println("locale\tsource"
+ + ops
+ + "\tpluralCat"
+ );
+ for (ULocale locale : locales) {
+ PluralRules pr = PluralRules.forLocale(locale);
+
+ for (String test : tests) {
+ final FixedDecimal source = new FixedDecimal(test);
+ System.out.println(locale
+ + "\t" + FixedDecimal.toSampleString(source)
+ + "\t" + pluralInfo(pr, source)
+ );
+ }
+ System.out.println();
+
+ }
+ }
+
+ public void TestDecimalQuantity() {
+ ImmutableSet<String> tests = ImmutableSet.of(
+ "1000.5",
+ "1.0005e3",
+ "1",
+ "1.0",
+ "1.00",
+ "1.3",
+ "1.30",
+ "1.03",
+ "1.230",
+ "1200000",
+ "1.2e6",
+ "123e6",
+ "123e5",
+ "1200.5",
+ "1.2005e3",
+ "2300000",
+ "2.3e6",
+ //"1.20050e3",
+ "1200.5",
+ "1.2005e3",
+ "1200000",
+ "1.2e6",
+ //"1.20e6",
+ "1234567.8",
+ "123456.78e1",
+ "12.345678e5",
+ "1.2345678e6",
+ "1.20050e3"
+ );
+
+ boolean ok;
+ for (int i = 0; i < 3; ++i) {
+ for (String test : tests) {
+ IFixedDecimal sourceFixedDecimal = new FixedDecimal(test);
+ DecimalQuantity_DualStorageBCD sourceDecimalQuantity = quantityFromSampleString(test);
+ switch(i) {
+ case 0:
+ ok = assertEquals(test + " — check FixedDecimal toString", test, sourceFixedDecimal.toString());
+ if (!ok) {
+ sourceFixedDecimal = new FixedDecimal(test); // for debugging
+ sourceFixedDecimal.toString();
+ }
+ break;
+ case 1:
+ ok = assertEquals(test + " — check quantity toScientificString",
+ test, FixedDecimal.toSampleString(sourceDecimalQuantity));
+ if (!ok) {
+ sourceFixedDecimal = quantityFromSampleString(test); // for debugging
+ }
+ break;
+ case 2:
+ ok = assertEquals(test + " — check operands FixedDecimal vs DecimalQuantity", "",
+ showOperandDifferences("FD", sourceFixedDecimal, "DC", sourceDecimalQuantity));
+ break;
+ }
+ }
+ }
+ }
+
+ public static String showOperandDifferences(String myTitle, IFixedDecimal me, String otherTitle, IFixedDecimal other) {
+ StringBuilder result = new StringBuilder();
+ for (Operand op : Operand.values()) {
+ if (me.getPluralOperand(op) != other.getPluralOperand(op)) {
+ if (result.length() != 0) {
+ result.append("; ");
+ }
+ result.append(op)
+ .append(": "
+ + myTitle
+ + "=").append(me.getPluralOperand(op))
+ .append(" "
+ + otherTitle
+ + "=").append(other.getPluralOperand(op))
+ ;
+ }
+ }
+ return result.toString();
+ }
+
+ public static DecimalQuantity_DualStorageBCD quantityFromSampleString(String num) {
+ final DecimalQuantity_DualStorageBCD sourceQuantity;
+ int exponent = 0;
+ int ePos = num.indexOf('e');
+ if (ePos >= 0) {
+ String exponentStr = num.substring(ePos + 1);
+ exponent = Integer.parseInt(exponentStr);
+ num = num.substring(0, ePos);
+ }
+
+ int v = FixedDecimal.getVisibleFractionCount(num) + exponent;
+
+ BigDecimal altBD = new BigDecimal(num);
+ altBD = altBD.movePointRight(exponent);
+ sourceQuantity = new DecimalQuantity_DualStorageBCD(altBD);
+ sourceQuantity.setMinFraction(v-exponent); //"1.20050e3" v should be 2, is 4
+ sourceQuantity.adjustMagnitude(-exponent);
+ sourceQuantity.adjustExponent(exponent);
+
+ return sourceQuantity;
+ }
+
+ static final DecimalFormat nf = new DecimalFormat("0.#####");
+
+ public CharSequence pluralInfo(PluralRules pr, final FixedDecimal formatted) {
+ StringBuilder buffer = new StringBuilder();
+ for (Operand op :orderedOperands) {
+ double opValue = formatted.getPluralOperand(op);
+ buffer.append(nf.format(opValue) + "\t");
+ }
+ buffer.append(pr.select(formatted));
+ return buffer;
+ }
}
\ No newline at end of file
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestScriptMetadata.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestScriptMetadata.java
index c171045..2017e0a 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestScriptMetadata.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestScriptMetadata.java
@@ -24,7 +24,7 @@
import org.unicode.cldr.util.With;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.lang.UCharacter;
@@ -69,11 +69,11 @@
if (ScriptMetadata.errors.size() == 1) {
logln("ScriptMetadata initialization errors\t"
+ ScriptMetadata.errors.size() + "\t"
- + CollectionUtilities.join(ScriptMetadata.errors, "\n"));
+ + Joiner.on("\n").join(ScriptMetadata.errors));
} else {
errln("ScriptMetadata initialization errors\t"
+ ScriptMetadata.errors.size() + "\t"
- + CollectionUtilities.join(ScriptMetadata.errors, "\n"));
+ + Joiner.on("\n").join(ScriptMetadata.errors));
}
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestShim.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestShim.java
new file mode 100644
index 0000000..84040b5
--- /dev/null
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestShim.java
@@ -0,0 +1,34 @@
+package org.unicode.cldr.unittest;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.unicode.cldr.util.TestShimUtils;
+
+// NOTE: When not under Maven, you'll see compile errs in eclipse.
+// Ignore them.
+
+/**
+ * a JUnit test that calls TestAll.
+ */
+class TestShim {
+ @Test
+ public void TestAll() {
+ String args[] = TestShimUtils.getArgs(TestShim.class, "-n -q");
+ // regular main() will System.exit() which is not too friendly.
+ // call this instead.
+ int errCount = TestAll.runTests(args);
+ assertEquals(0, errCount, "Test had errors");
+ }
+
+ @Test
+ public void TestTestShimUtilTest() {
+ // Note: checks the system property corresponding to java.lang
+ // We expect the system property "java.lang.testArgs" will not be set,
+ // and so the default "-a -b -c" will be used.
+ String args[] = TestShimUtils.getArgs(java.lang.String.class, "-a -b -c");
+ String expectArgs[] = { "-a", "-b", "-c" };
+ assertArrayEquals(args, expectArgs, "Expected arg parse");
+ }
+}
\ No newline at end of file
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestSupplementalInfo.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestSupplementalInfo.java
index ad27b34..3fcdf6c 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestSupplementalInfo.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestSupplementalInfo.java
@@ -33,6 +33,10 @@
import org.unicode.cldr.util.CLDRFile.WinningChoice;
import org.unicode.cldr.util.CLDRLocale;
import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.GrammarInfo;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
import org.unicode.cldr.util.Iso639Data;
import org.unicode.cldr.util.Iso639Data.Scope;
import org.unicode.cldr.util.IsoCurrencyParser;
@@ -64,10 +68,10 @@
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -80,6 +84,7 @@
import com.ibm.icu.text.PluralRules.FixedDecimal;
import com.ibm.icu.text.PluralRules.FixedDecimalRange;
import com.ibm.icu.text.PluralRules.FixedDecimalSamples;
+import com.ibm.icu.text.PluralRules.Operand;
import com.ibm.icu.text.PluralRules.SampleType;
import com.ibm.icu.text.StringTransform;
import com.ibm.icu.text.UnicodeSet;
@@ -88,6 +93,8 @@
import com.ibm.icu.util.ULocale;
public class TestSupplementalInfo extends TestFmwkPlus {
+ private static final boolean DEBUG = true;
+
static CLDRConfig testInfo = CLDRConfig.getInstance();
private static final StandardCodes STANDARD_CODES = testInfo
@@ -101,7 +108,7 @@
}
public void TestPluralSampleOrder() {
- HashSet<PluralInfo> seen = new HashSet<PluralInfo>();
+ HashSet<PluralInfo> seen = new HashSet<>();
for (String locale : SUPPLEMENTAL.getPluralLocales()) {
if (locale.equals("root")) {
continue;
@@ -125,7 +132,7 @@
FixedDecimalRange lastSample = null;
for (FixedDecimalRange sample : sSamples.samples) {
if (lastSample != null) {
- if (lastSample.start.compareTo(sample.start) > 0) {
+ if (compare(lastSample.start,sample.start) > 0) {
errln(locale + ":" + c + ": out of order with "
+ lastSample + " > " + sample);
} else if (false) {
@@ -140,9 +147,33 @@
}
}
+ /**
+ * Hack until ICU's FixedDecimal is fixed
+ *
+ */
+ public static int compare(PluralRules.FixedDecimal me, PluralRules.FixedDecimal other) {
+ if (me.getPluralOperand(Operand.e) != other.getPluralOperand(Operand.e)) {
+ return me.getPluralOperand(Operand.e) < other.getPluralOperand(Operand.e) ? -1 : 1;
+ }
+ if (me.getIntegerValue() != other.getIntegerValue()) {
+ return me.getIntegerValue() < other.getIntegerValue() ? -1 : 1;
+ }
+ if (me.getSource() != other.getSource()) {
+ return me.getSource() < other.getSource() ? -1 : 1;
+ }
+ if (me.getVisibleDecimalDigitCount() != other.getVisibleDecimalDigitCount()) {
+ return me.getVisibleDecimalDigitCount() < other.getVisibleDecimalDigitCount() ? -1 : 1;
+ }
+ long diff = me.getDecimalDigits() - other.getDecimalDigits();
+ if (diff != 0) {
+ return diff < 0 ? -1 : 1;
+ }
+ return 0;
+ }
+
public void TestPluralRanges() {
PluralRulesFactory prf = PluralRulesFactory.getInstance(SUPPLEMENTAL);
- Set<String> localesToTest = new TreeSet<String>(
+ Set<String> localesToTest = new TreeSet<>(
SUPPLEMENTAL.getPluralRangesLocales());
for (String locale : StandardCodes.make().getLocaleCoverageLocales(
"google")) { // superset
@@ -155,8 +186,8 @@
.getLocaleCoverageLocales(Organization.cldr,
EnumSet.of(Level.MODERN));
- Output<FixedDecimal> maxSample = new Output<FixedDecimal>();
- Output<FixedDecimal> minSample = new Output<FixedDecimal>();
+ Output<FixedDecimal> maxSample = new Output<>();
+ Output<FixedDecimal> minSample = new Output<>();
for (String locale : localesToTest) {
final String templateLine = "Template for " + ULocale.getDisplayName(locale, "en") + " (" + locale + ") translators to fix:";
@@ -190,8 +221,8 @@
&& !counts.contains(count)) {
assertTrue(
locale
- + "\t pluralRanges categories must be valid for locale:\t"
- + count + " must be in " + counts,
+ + "\t pluralRanges categories must be valid for locale:\t"
+ + count + " must be in " + counts,
!pluralRanges.isExplicitlySet(count));
}
for (Count end : Count.values()) {
@@ -382,7 +413,7 @@
PluralInfo pluralInfo = SUPPLEMENTAL.getPlurals(
PluralType.valueOf(row[1]), row[0]);
Count count = pluralInfo.getCount(new FixedDecimal(row[2]));
- assertEquals(CollectionUtilities.join(row, ", "),
+ assertEquals(String.join(", ", row),
Count.valueOf(row[3]), count);
}
@@ -391,7 +422,7 @@
for (PluralType type : PluralType.values()) {
Relation<PluralInfo, String> pluralsToLocale = Relation.of(
new HashMap<PluralInfo, Set<String>>(), TreeSet.class);
- for (String locale : new TreeSet<String>(
+ for (String locale : new TreeSet<>(
SUPPLEMENTAL.getPluralLocales(type))) {
PluralInfo pluralInfo = SUPPLEMENTAL.getPlurals(type, locale);
pluralsToLocale.put(pluralInfo, locale);
@@ -418,7 +449,7 @@
}
assertFalse(
"Rule '" + rule + "' for " + Arrays.asList(locales)
- + " doesn't contain 'within'",
+ + " doesn't contain 'within'",
rule.contains("within"));
}
}
@@ -437,25 +468,25 @@
{ "en", "other", "4", "1000-9999, 1000.0, 1000.1, 1000.2, …" },
{ "hr", "one", "1", "1, 0.1, 2.10, 1.1, …" },
{ "hr", "one", "2",
- "21, 31, 41, 51, 61, 71, …, 10.1, 12.10, 11.1, …" },
+ "21, 31, 41, 51, 61, 71, …, 10.1, 12.10, 11.1, …" },
{ "hr", "one", "3",
- "101, 121, 131, 141, 151, 161, …, 100.1, 102.10, 101.1, …" },
+ "101, 121, 131, 141, 151, 161, …, 100.1, 102.10, 101.1, …" },
{ "hr", "one", "4",
- "1001, 1021, 1031, 1041, 1051, 1061, …, 1000.1, 1002.10, 1001.1, …" },
+ "1001, 1021, 1031, 1041, 1051, 1061, …, 1000.1, 1002.10, 1001.1, …" },
{ "hr", "few", "1", "2-4, 0.2, 0.3, 0.4, …" },
{ "hr", "few", "2",
- "22-24, 32-34, 42-44, …, 10.2, 10.3, 10.4, …" },
+ "22-24, 32-34, 42-44, …, 10.2, 10.3, 10.4, …" },
{ "hr", "few", "3",
- "102-104, 122-124, 132-134, …, 100.2, 100.3, 100.4, …" },
+ "102-104, 122-124, 132-134, …, 100.2, 100.3, 100.4, …" },
{ "hr", "few", "4",
- "1002-1004, 1022-1024, 1032-1034, …, 1000.2, 1000.3, 1000.4, …" },
+ "1002-1004, 1022-1024, 1032-1034, …, 1000.2, 1000.3, 1000.4, …" },
{ "hr", "other", "1", "0, 5-9, 0.0, 0.5, 0.6, …" },
{ "hr", "other", "2",
- "10-20, 25-30, 35-40, …, 10.0, 10.5, 10.6, …" },
+ "10-20, 25-30, 35-40, …, 10.0, 10.5, 10.6, …" },
{ "hr", "other", "3",
- "100, 105-120, 125-130, 135-140, …, 100.0, 100.5, 100.6, …" },
+ "100, 105-120, 125-130, 135-140, …, 100.0, 100.5, 100.6, …" },
{ "hr", "other", "4",
- "1000, 1005-1020, 1025-1030, 1035-1040, …, 1000.0, 1000.5, 1000.6, …" }, };
+ "1000, 1005-1020, 1025-1030, 1035-1040, …, 1000.0, 1000.5, 1000.6, …" }, };
for (String[] row : tests) {
PluralInfo plurals = SUPPLEMENTAL.getPlurals(row[0]);
SampleList uset = plurals.getSamples9999(Count.valueOf(row[1]),
@@ -468,7 +499,8 @@
public void TestDigitPluralCompleteness() {
String[][] exceptionStrings = {
// defaults
- { "*", "zero", "0,00,000,0000" }, { "*", "one", "0" },
+ { "*", "zero", "0,00,000,0000" },
+ { "*", "one", "0" },
{ "*", "two", "0,00,000,0000" },
{ "*", "few", "0,00,000,0000" },
{ "*", "many", "0,00,000,0000" },
@@ -555,9 +587,10 @@
// % 100 = 1
{"kw", "many", "00,000,0000"}, // n != 1 and n % 100 = 1,21,41,61,81
{"kw", "zero", "0"}, // n = 0
+ {"fr", "many", ""}, // e is special
};
// parse out the exceptions
- Map<PluralInfo, Relation<Count, Integer>> exceptions = new HashMap<PluralInfo, Relation<Count, Integer>>();
+ Map<PluralInfo, Relation<Count, Integer>> exceptions = new HashMap<>();
Relation<Count, Integer> fallback = Relation.of(
new EnumMap<Count, Set<Integer>>(Count.class), TreeSet.class);
for (String[] row : exceptionStrings) {
@@ -582,8 +615,8 @@
countToDigits.put(c, digit.length());
}
}
- Set<PluralInfo> seen = new HashSet<PluralInfo>();
- Set<String> sorted = new TreeSet<String>(
+ Set<PluralInfo> seen = new HashSet<>();
+ Set<String> sorted = new TreeSet<>(
SUPPLEMENTAL.getPluralLocales(PluralType.cardinal));
Relation<String, String> ruleToExceptions = Relation.of(
new TreeMap<String, Set<String>>(), TreeSet.class);
@@ -598,7 +631,7 @@
countToDigits = fallback;
}
for (Count c : plurals.getCounts()) {
- List<String> compose = new ArrayList<String>();
+ List<String> compose = new ArrayList<>();
boolean needLine = false;
Set<Integer> digitSet = countToDigits.get(c);
if (digitSet == null) {
@@ -620,14 +653,14 @@
c.toString());
ruleToExceptions.put(countRules == null ? "" : countRules,
"{\"" + locale + "\", \"" + c + "\", \""
- + CollectionUtilities.join(compose, ",")
+ + Joiner.on(",").join(compose)
+ "\"},");
}
}
}
if (!ruleToExceptions.isEmpty()) {
System.out
- .println("To fix the above, review the following, then replace in TestDigitPluralCompleteness");
+ .println("To fix the above, review the following, then replace in TestDigitPluralCompleteness");
for (Entry<String, String> entry : ruleToExceptions.entrySet()) {
System.out.println(entry.getValue() + "\t// " + entry.getKey());
}
@@ -670,8 +703,8 @@
}
public void TestEquivalentLocales() {
- Set<Set<String>> seen = new HashSet<Set<String>>();
- Set<String> toTest = new TreeSet<String>(testInfo.getCldrFactory()
+ Set<Set<String>> seen = new HashSet<>();
+ Set<String> toTest = new TreeSet<>(testInfo.getCldrFactory()
.getAvailable());
toTest.addAll(SUPPLEMENTAL.getLikelySubtags().keySet());
toTest.addAll(SUPPLEMENTAL.getLikelySubtags().values());
@@ -687,7 +720,7 @@
}
// System.out.println(s + " => " + VettingViewer.gatherCodes(s));
- List<String> ss = new ArrayList<String>(s);
+ List<String> ss = new ArrayList<>(s);
String last = ss.get(ss.size() - 1);
ltp.set(last);
if (!ltp.getVariants().isEmpty() || !ltp.getExtensions().isEmpty()) {
@@ -736,14 +769,14 @@
private String showLocaleParts(Set<String> s) {
LanguageTagParser ltp = new LanguageTagParser();
- Set<String> b = new LinkedHashSet<String>();
+ Set<String> b = new LinkedHashSet<>();
for (String ss : s) {
ltp.set(ss);
addName(CLDRFile.LANGUAGE_NAME, ltp.getLanguage(), b);
addName(CLDRFile.SCRIPT_NAME, ltp.getScript(), b);
addName(CLDRFile.TERRITORY_NAME, ltp.getRegion(), b);
}
- return CollectionUtilities.join(b, "; ");
+ return Joiner.on("; ").join(b);
}
private void addName(int languageName, String code, Set<String> b) {
@@ -792,14 +825,14 @@
public void TestTimeData() {
Map<String, PreferredAndAllowedHour> timeData = SUPPLEMENTAL
.getTimeData();
- Set<String> regionsSoFar = new HashSet<String>();
- Set<String> current24only = new HashSet<String>();
- Set<String> current12preferred = new HashSet<String>();
+ Set<String> regionsSoFar = new HashSet<>();
+ Set<String> current24only = new HashSet<>();
+ Set<String> current12preferred = new HashSet<>();
boolean haveWorld = false;
-
+
ImmutableSet<HourStyle> oldSchool = ImmutableSet.copyOf(EnumSet.of(HourStyle.H, HourStyle.h, HourStyle.K, HourStyle.k));
-
+
for (Entry<String, PreferredAndAllowedHour> e : timeData.entrySet()) {
String region = e.getKey();
if (region.equals("001")) {
@@ -808,10 +841,10 @@
regionsSoFar.add(region);
PreferredAndAllowedHour preferredAndAllowedHour = e.getValue();
assertNotNull("Preferred must not be null", preferredAndAllowedHour.preferred);
-
+
// find first h or H
HourStyle found = null;
-
+
for (HourStyle item : preferredAndAllowedHour.allowed) {
if (oldSchool.contains(item)) {
found = item;
@@ -819,7 +852,7 @@
String message = "Inconsistent values for " + region + ": preferred=" + preferredAndAllowedHour.preferred
+ " but that isn't the first " + oldSchool + " in allowed: " + preferredAndAllowedHour.allowed;
//if (!logKnownIssue("cldrbug:11448", message)) {
- errln(message);
+ errln(message);
//}
}
break;
@@ -854,7 +887,7 @@
current12preferred.add(region);
}
}
- Set<String> missing = new TreeSet<String>(
+ Set<String> missing = new TreeSet<>(
STANDARD_CODES.getGoodAvailableCodes(CodeType.territory));
missing.removeAll(regionsSoFar);
for (Iterator<String> it = missing.iterator(); it.hasNext();) {
@@ -874,13 +907,13 @@
// The feedback gathered from our translators is that the following use
// 24 hour time ONLY:
- Set<String> only24lang = new TreeSet<String>(
+ Set<String> only24lang = new TreeSet<>(
Arrays.asList(("sq, br, bu, ca, hr, cs, da, de, nl, et, eu, fi, "
+ "fr, gl, he, is, id, it, nb, pt, ro, ru, sr, sk, sl, sv, tr, hy")
- .split(",\\s*")));
- // With the new preferences, this is changed
- Set<String> only24region = new TreeSet<String>();
- Set<String> either24or12region = new TreeSet<String>();
+ .split(",\\s*")));
+ // With the new preferences, this is changed
+ Set<String> only24region = new TreeSet<>();
+ Set<String> either24or12region = new TreeSet<>();
// get all countries where official or de-facto official
// add them two one of two lists, based on the above list of languages
@@ -913,7 +946,7 @@
only24region.removeAll(current12preferred);
// now verify
if (!current24only.containsAll(only24region)) {
- Set<String> missing24only = new TreeSet<String>(only24region);
+ Set<String> missing24only = new TreeSet<>(only24region);
missing24only.removeAll(current24only);
errln("24-hour-only doesn't include needed items:\n"
@@ -978,8 +1011,8 @@
}
}
- Set<R3<String, List<String>, List<String>>> failures = new LinkedHashSet<R3<String, List<String>, List<String>>>();
- Set<String> nullReplacements = new TreeSet<String>();
+ Set<R3<String, List<String>, List<String>>> failures = new LinkedHashSet<>();
+ Set<String> nullReplacements = new TreeSet<>();
for (Entry<String, R2<List<String>, String>> codeRep : codeReplacement
.entrySet()) {
String code = codeRep.getKey();
@@ -988,7 +1021,7 @@
nullReplacements.add(code);
continue;
}
- Set<String> fixedReplacements = new LinkedHashSet<String>();
+ Set<String> fixedReplacements = new LinkedHashSet<>();
for (String replacement : replacements) {
R2<List<String>, String> newReplacement = codeReplacement
.get(replacement);
@@ -1001,7 +1034,7 @@
fixedReplacements.add(replacement);
}
}
- List<String> fixedList = new ArrayList<String>(
+ List<String> fixedList = new ArrayList<>(
fixedReplacements);
if (!replacements.equals(fixedList)) {
R3<String, List<String>, List<String>> row = Row.of(code,
@@ -1020,7 +1053,7 @@
errln(code + "\t=>\t" + oldReplacement + "\tshould be:\n\t"
+ "<" + type + "Alias type=\"" + code
+ "\" replacement=\""
- + CollectionUtilities.join(newReplacement, " ")
+ + Joiner.on(" ").join(newReplacement)
+ "\" reason=\"XXX\"/> <!-- YYY -->\n");
}
}
@@ -1038,7 +1071,7 @@
Relation<String, String> map = SUPPLEMENTAL
.getTerritoryToContained(ContainmentStyle.all);
Relation<String, String> mapCore = SUPPLEMENTAL.getContainmentCore();
- Set<String> mapItems = new LinkedHashSet<String>();
+ Set<String> mapItems = new LinkedHashSet<>();
// get all the items
for (String item : map.keySet()) {
mapItems.add(item);
@@ -1048,7 +1081,7 @@
.getLStreg().get("region");
// verify that all regions are covered
- Set<String> bcp47Regions = new LinkedHashSet<String>(
+ Set<String> bcp47Regions = new LinkedHashSet<>(
bcp47RegionData.keySet());
bcp47Regions.remove("ZZ"); // We don't care about ZZ since it is the
// unknown region...
@@ -1100,7 +1133,7 @@
private void errlnDiff(String title, Set<String> mapItems,
Set<String> keySet) {
- Set<String> diff = new LinkedHashSet<String>(mapItems);
+ Set<String> diff = new LinkedHashSet<>(mapItems);
diff.removeAll(keySet);
if (diff.size() != 0) {
errln(title + diff);
@@ -1313,11 +1346,11 @@
}
// these are settings for exceptional cases we want to allow
- private static final Set<String> EXCEPTION_CURRENCIES_WITH_NEW = new TreeSet<String>(
+ private static final Set<String> EXCEPTION_CURRENCIES_WITH_NEW = new TreeSet<>(
Arrays.asList("ILS", "NZD", "PGK", "TWD"));
// ok since there is no problem with confusion
- private static final Set<String> OK_TO_NOT_HAVE_OLD = new TreeSet<String>(
+ private static final Set<String> OK_TO_NOT_HAVE_OLD = new TreeSet<>(
Arrays.asList("ADP", "ATS", "BEF", "CYP", "DEM", "ESP", "FIM",
"FRF", "GRD", "IEP", "ITL", "LUF", "MTL", "MTP", "NLG",
"PTE", "YUM", "ARA", "BAD", "BGL", "BOP", "BRC", "BRN",
@@ -1329,6 +1362,7 @@
private static final Date LIMIT_FOR_NEW_CURRENCY = new Date(
new Date().getYear() - 5, 1, 1);
private static final Date NOW = new Date();
+
private Matcher oldMatcher = Pattern.compile(
"\\bold\\b|\\([0-9]{4}-[0-9]{4}\\)", Pattern.CASE_INSENSITIVE)
.matcher("");
@@ -1351,10 +1385,10 @@
Relation<String, Pair<String, CurrencyDateInfo>> modernCurrencyCodes = Relation
.of(new TreeMap<String, Set<Pair<String, CurrencyDateInfo>>>(),
TreeSet.class);
- Set<String> territoriesWithoutModernCurrencies = new TreeSet<String>(
+ Set<String> territoriesWithoutModernCurrencies = new TreeSet<>(
STANDARD_CODES.getGoodAvailableCodes("territory"));
- Map<String, Date> currencyFirstValid = new TreeMap<String, Date>();
- Map<String, Date> currencyLastValid = new TreeMap<String, Date>();
+ Map<String, Date> currencyFirstValid = new TreeMap<>();
+ Map<String, Date> currencyLastValid = new TreeMap<>();
territoriesWithoutModernCurrencies.remove("ZZ");
for (String territory : STANDARD_CODES
@@ -1376,7 +1410,7 @@
final Date end = dateInfo.getEnd();
if (dateInfo.getErrors().length() != 0) {
logln("parsing " + territory + "\t" + dateInfo.toString()
- + "\t" + dateInfo.getErrors());
+ + "\t" + dateInfo.getErrors());
}
Date firstValue = currencyFirstValid.get(currency);
if (firstValue == null || firstValue.compareTo(start) < 0) {
@@ -1390,12 +1424,12 @@
// is
// OK...
modernCurrencyCodes.put(currency,
- new Pair<String, CurrencyDateInfo>(territory,
+ new Pair<>(territory,
dateInfo));
territoriesWithoutModernCurrencies.remove(territory);
} else {
nonModernCurrencyCodes.put(currency,
- new Pair<String, CurrencyDateInfo>(territory,
+ new Pair<>(territory,
dateInfo));
}
logln(territory
@@ -1414,7 +1448,7 @@
// now print error messages
logln("Modern Codes: " + modernCurrencyCodes.size() + "\t"
+ modernCurrencyCodes);
- Set<String> missing = new TreeSet<String>(
+ Set<String> missing = new TreeSet<>(
isoCurrenciesToCountries.keySet());
missing.removeAll(modernCurrencyCodes.keySet());
if (missing.size() != 0) {
@@ -1430,10 +1464,10 @@
Set<String> isoCountries = isoCurrenciesToCountries
.getAll(currency);
if (isoCountries == null) {
- isoCountries = new TreeSet<String>();
+ isoCountries = new TreeSet<>();
}
- TreeSet<String> cldrCountries = new TreeSet<String>();
+ TreeSet<String> cldrCountries = new TreeSet<>();
for (Pair<String, CurrencyDateInfo> x : data) {
cldrCountries.add(x.getFirst());
}
@@ -1472,7 +1506,7 @@
}
}
logln("Non-Modern Codes (with dates): " + nonModernCurrencyCodes.size()
- + "\t" + nonModernCurrencyCodes);
+ + "\t" + nonModernCurrencyCodes);
for (String currency : nonModernCurrencyCodes.keySet()) {
final String name = testInfo.getEnglish().getName(
CLDRFile.CURRENCY_NAME, currency);
@@ -1516,7 +1550,7 @@
}
}
- Set<String> remainder = new TreeSet<String>();
+ Set<String> remainder = new TreeSet<>();
remainder.addAll(currencyCodes);
remainder.removeAll(nonModernCurrencyCodes.keySet());
// TODO make this an error, except for allowed exceptions.
@@ -1564,7 +1598,7 @@
public void TestDefaultScripts() {
SupplementalDataInfo supp = SUPPLEMENTAL;
Map<String, String> likelyData = supp.getLikelySubtags();
- Map<String, String> baseToDefaultContentScript = new HashMap<String, String>();
+ Map<String, String> baseToDefaultContentScript = new HashMap<>();
for (CLDRLocale locale : supp.getDefaultContentCLDRLocales()) {
String script = locale.getScript();
if (!script.isEmpty() && locale.getCountry().isEmpty()) {
@@ -1655,7 +1689,7 @@
}
CoverageIssue needsCoverage = testLocales.contains(locale)
? CoverageIssue.error
- : CoverageIssue.log;
+ : CoverageIssue.log;
CoverageIssue needsCoverage2 = needsCoverage == CoverageIssue.error ? CoverageIssue.warn : needsCoverage;
// if (logKnownIssue("Cldrbug:8809", "Missing plural rules/samples be and ga locales")) {
@@ -1678,7 +1712,7 @@
// if (counts.size() == 1) {
// continue; // skip checking samples
// }
- HashSet<String> samples = new HashSet<String>();
+ HashSet<String> samples = new HashSet<>();
EnumSet<Count> countsWithNoSamples = EnumSet
.noneOf(Count.class);
Relation<String, Count> samplesToCounts = Relation.of(
@@ -1687,7 +1721,7 @@
type.standardType);
StringBuilder failureCases = new StringBuilder();
for (Count count : counts) {
- String pattern = prf.getSamplePattern(locale, type.standardType, count);
+ String pattern = PluralRulesFactory.getSamplePattern(locale, type.standardType, count);
final String rangeLine = getRangeLine(count, pluralInfo.getPluralRules(), pattern);
failureCases.append('\n').append(locale).append('\t').append(type).append('\t').append(rangeLine);
if (countsFound == null || !countsFound.contains(count)) {
@@ -1707,7 +1741,7 @@
.keyValuesSet()) {
if (entry.getValue().size() != 1) {
errOrLog(needsCoverage, locale + "\t" + type + "\t duplicate samples: " + entry.getValue()
- + " => «" + entry.getKey() + "»", "cldrbug:7119", "Some duplicate minimal pairs");
+ + " => «" + entry.getKey() + "»", "cldrbug:7119", "Some duplicate minimal pairs");
errOrLog(needsCoverage2, failureCases.toString());
}
}
@@ -1770,7 +1804,7 @@
}
public void TestNumberingSystemDigitCompleteness() {
- List<Integer> unicodeDigits = new ArrayList<Integer>();
+ List<Integer> unicodeDigits = new ArrayList<>();
for (int cp = UCharacter.MIN_CODE_POINT; cp <= UCharacter.MAX_CODE_POINT; cp++) {
if (UCharacter.getType(cp) == UCharacterEnums.ECharacterCategory.DECIMAL_DIGIT_NUMBER) {
unicodeDigits.add(Integer.valueOf(cp));
@@ -1838,7 +1872,7 @@
assertTrue("yue*10 < zh", yueCNData.getPopulation() < zhCNData.getPopulation());
}
- public void Test10765() { //
+ public void Test10765() { //
Set<String> surveyToolLanguages = SUPPLEMENTAL.getCLDRLanguageCodes(); // codes that show up in Survey Tool
Set<String> mainLanguages = new TreeSet<>();
LanguageTagParser ltp = new LanguageTagParser();
@@ -1881,4 +1915,35 @@
}
return tempNames;
}
+
+ public void TestGrammarInfo() {
+ Multimap<String,String> allValues = TreeMultimap.create();
+ for (String locale : SUPPLEMENTAL.hasGrammarInfo()) {
+ if (locale.contentEquals("tr")) {
+ int debug = 0;
+ }
+ GrammarInfo grammarInfo = SUPPLEMENTAL.getGrammarInfo(locale);
+ for (GrammaticalTarget target : GrammaticalTarget.values()) {
+ for (GrammaticalFeature feature : GrammaticalFeature.values()) {
+ Collection<String> general = grammarInfo.get(target, feature, GrammaticalScope.general);
+ for (GrammaticalScope scope : GrammaticalScope.values()) {
+ Collection<String> units = grammarInfo.get(target, feature, scope);
+ allValues.putAll(target + "/" + feature + "/" + scope, units);
+ if (scope != GrammaticalScope.general) {
+ assertTrue(general + " > " + scope + " " + units, general.containsAll(units));
+ }
+ }
+ }
+ }
+ if (DEBUG) {
+ System.out.println(grammarInfo.toString("\n" + locale + "\t"));
+ }
+ }
+ if (DEBUG) {
+ System.out.println();
+ for (Entry<String, Collection<String>> entry : allValues.asMap().entrySet()) {
+ System.out.println(entry.getKey() + "\t" + Joiner.on(", ").join(entry.getValue()));
+ }
+ }
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestTransforms.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestTransforms.java
index c230606..7707ca3 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestTransforms.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestTransforms.java
@@ -24,12 +24,14 @@
import org.unicode.cldr.util.CLDRTransforms;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.lang.UCharacterEnums.ECharacterCategory;
import com.ibm.icu.text.Normalizer2;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UnicodeSet;
@@ -130,9 +132,9 @@
}
}
logln("Success! " + latinFromCyrillicSucceeds.size() + "\n"
- + CollectionUtilities.join(latinFromCyrillicSucceeds, "\n"));
+ + Joiner.on("\n").join(latinFromCyrillicSucceeds));
logln("\nFAILS!" + latinFromCyrillicFails.size() + "\n"
- + CollectionUtilities.join(latinFromCyrillicFails, "\n"));
+ + Joiner.on("\n").join(latinFromCyrillicFails));
}
}
@@ -140,8 +142,8 @@
String prefixSource, String suffix) {
String result = cyrillicToLatin.transform(prefixSource);
if (!result.isEmpty()
- && UCharacter.getType(suffix.codePointAt(0)) != UCharacter.UPPERCASE_LETTER
- && UCharacter.getType(result.codePointAt(0)) == UCharacter.UPPERCASE_LETTER) {
+ && UCharacter.getType(suffix.codePointAt(0)) != ECharacterCategory.UPPERCASE_LETTER
+ && UCharacter.getType(result.codePointAt(0)) == ECharacterCategory.UPPERCASE_LETTER) {
result = UCharacter.toTitleCase(result, null);
}
return result + suffix;
@@ -409,7 +411,7 @@
}
name = name.substring(5);
File fileDirectory = new File(CLDRPaths.TEST_DATA + "transforms/");
- String fileDirectoryName = fileDirectory.getCanonicalPath();
+ String fileDirectoryName = PathUtilities.getNormalizedPathString(fileDirectory);
assertTrue(fileDirectoryName, fileDirectory.exists());
logln("Testing files in: " + fileDirectoryName);
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUnits.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUnits.java
index 2d3a19c..e5184df 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUnits.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUnits.java
@@ -25,17 +25,35 @@
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import org.unicode.cldr.draft.FileUtilities;
+import org.unicode.cldr.test.CheckCLDR.CheckStatus;
+import org.unicode.cldr.test.CheckCLDR.Options;
+import org.unicode.cldr.test.CheckUnits;
import org.unicode.cldr.test.ExampleGenerator;
import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRFile;
+import org.unicode.cldr.util.ChainedMap;
+import org.unicode.cldr.util.ChainedMap.M3;
+import org.unicode.cldr.util.ChainedMap.M4;
import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.Counter;
+import org.unicode.cldr.util.DtdData;
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.GrammarDerivation;
+import org.unicode.cldr.util.GrammarInfo;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
+import org.unicode.cldr.util.LocaleStringProvider;
import org.unicode.cldr.util.MapComparator;
+import org.unicode.cldr.util.Organization;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathHeader;
import org.unicode.cldr.util.Rational;
import org.unicode.cldr.util.Rational.ContinuedFraction;
import org.unicode.cldr.util.Rational.FormatStyle;
@@ -50,16 +68,20 @@
import org.unicode.cldr.util.UnitConverter.Continuation;
import org.unicode.cldr.util.UnitConverter.ConversionInfo;
import org.unicode.cldr.util.UnitConverter.TargetInfo;
+import org.unicode.cldr.util.UnitConverter.UnitComplexity;
import org.unicode.cldr.util.UnitConverter.UnitId;
+import org.unicode.cldr.util.UnitPathType;
import org.unicode.cldr.util.UnitPreferences;
import org.unicode.cldr.util.UnitPreferences.UnitPreference;
import org.unicode.cldr.util.Units;
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
import org.unicode.cldr.util.XMLSource;
+import org.unicode.cldr.util.XPathParts;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
+import com.google.common.collect.BiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -70,18 +92,22 @@
import com.google.common.collect.Multimaps;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.impl.Row.R2;
+import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.ICUUncheckedIOException;
import com.ibm.icu.util.Output;
public class TestUnits extends TestFmwk {
+ private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance();
+ private static final Integer INTEGER_ONE = Integer.valueOf(1);
private static final boolean SHOW_DATA = CldrUtility.getProperty("TestUnits:SHOW_DATA", false); // set for verbose debugging information
private static final boolean GENERATE_TESTS = CldrUtility.getProperty("TestUnits:GENERATE_TESTS", false);
private static final String TEST_SEP = ";\t";
private static final ImmutableSet<String> WORLD_SET = ImmutableSet.of("001");
- private static final CLDRConfig info = CLDRConfig.getInstance();
+ private static final CLDRConfig info = CLDR_CONFIG;
private static final SupplementalDataInfo SDI = info.getSupplementalDataInfo();
static final UnitConverter converter = SDI.getUnitConverter();
@@ -98,7 +124,7 @@
private Map<String, String> BASE_UNIT_TO_QUANTITY = converter.getBaseUnitToQuantity();
public void TestSpaceInNarrowUnits() {
- final CLDRFile english = CLDRConfig.getInstance().getEnglish();
+ final CLDRFile english = CLDR_CONFIG.getEnglish();
final Matcher m = Pattern.compile("narrow.*unitPattern").matcher("");
for (String path : english) {
if (m.reset(path).find()) {
@@ -205,10 +231,10 @@
static final String PATH_METER_PATTERN = "//ldml/units/unitLength[@type=\"{0}\"]/unit[@type=\"length-meter\"]/unitPattern[@count=\"{1}\"]";
static final String PATH_MILLIMETER_PATTERN = "//ldml/units/unitLength[@type=\"{0}\"]/unit[@type=\"length-millimeter\"]/unitPattern[@count=\"{1}\"]";
- static final String PATH_SQUARE_METER_PATTERN = "//ldml/units/unitLength[@type=\"{0}\"]/unit[@type=\"area-square-meter\"]/unitPattern[@count=\"{1}\"]";
+ static final String PATH_SQUARE_METER_PATTERN = "//ldml/units/unitLength[@type=\"{0}\"]/unit[@type=\"area-square-meter\"]/unitPattern[@count=\"{1}\"]";
public void TestCompoundUnit3() {
- Factory factory = CLDRConfig.getInstance().getCldrFactory();
+ Factory factory = CLDR_CONFIG.getCldrFactory();
Map<String,String> prefixToType = new LinkedHashMap<>();
for (String[] prefixRow : PREFIX_NAME_TYPE) {
@@ -233,7 +259,7 @@
final boolean isPrefix = prefixType.startsWith("1");
for (String len : Arrays.asList("long", "short", "narrow")) {
- String prefixPath = ExampleGenerator.format(isPrefix ? PATH_PREFIX_PATTERN
+ String prefixPath = ExampleGenerator.format(isPrefix ? PATH_PREFIX_PATTERN
: PATH_SUFFIX_PATTERN,
len, prefixType);
String prefixValue = file.getStringValue(prefixPath);
@@ -253,14 +279,14 @@
continue;
}
}
- if (!assertEquals2(errMsg, testCount++ + ") "
- + locale + "/" + len + "/" + count + "/" + prefix + "+" + baseUnit
+ if (!assertEquals2(errMsg, testCount++ + ") "
+ + locale + "/" + len + "/" + count + "/" + prefix + "+" + baseUnit
+ ": constructed pattern",
- targetUnitPattern,
+ targetUnitPattern,
composedTargetUnitPattern)) {
Units.combinePattern(baseUnitPattern, prefixValue, lowercaseIfSpaced);
int debug = 0;
- };
+ }
}
}
}
@@ -305,7 +331,7 @@
String value = english.getStringValue(path);
prefixes.add(value.replace("{0}", "").trim());
}
- }
+ }
Map<Status, Set<String>> unitValidity = Validity.getInstance().getStatusToCodes(LstrType.unit);
Multimap<String, String> from = LinkedHashMultimap.create();
for (String unit : unitValidity.get(Status.regular)) {
@@ -342,7 +368,6 @@
static final boolean DEBUG = false;
public void TestConversion() {
- UnitConverter converter = SDI.getUnitConverter();
Object[][] tests = {
{"foot", 12, "inch"},
{"gallon", 4, "quart"},
@@ -432,7 +457,7 @@
String canonicalUnit = converter.getBaseUnit(simple);
UnitId unitId = converter.createUnitId(canonicalUnit);
String output = unitId.toString();
- if (!assertEquals(simple + ": targets should be in canonical form",
+ if (!assertEquals(simple + ": targets should be in canonical form",
output, canonicalUnit)) {
// for debugging
converter.createUnitId(canonicalUnit);
@@ -445,7 +470,7 @@
try {
UnitId unitId = converter.createUnitId(baseUnit);
String output = unitId.toString();
- if (!assertEquals(quantity + ": targets should be in canonical form",
+ if (!assertEquals(quantity + ": targets should be in canonical form",
output, baseUnit)) {
// for debugging
converter.createUnitId(baseUnit);
@@ -461,7 +486,7 @@
UnitId unitId = converter.createUnitId(baseUnit);
assertNotNull("Can't parse baseUnit: " + baseUnit, unitId);
} catch (Exception e) {
- UnitId unitId = converter.createUnitId(baseUnit); // for debugging
+ converter.createUnitId(baseUnit); // for debugging
errln("Can't parse baseUnit: " + baseUnit);
}
}
@@ -483,7 +508,7 @@
assertEquals(source, expectedRational, unitInfo.factor);
}
- // check all
+ // check all
if (GENERATE_TESTS) System.out.println();
Set<String> badUnits = new LinkedHashSet<>();
Set<String> noQuantity = new LinkedHashSet<>();
@@ -501,9 +526,9 @@
}
if (GENERATE_TESTS) { // test data
System.out.println(
- "# Test data for unit conversions\n"
+ "# Test data for unit conversions\n"
+ CldrUtility.getCopyrightString("# ") + "\n"
- + "#\n"
+ + "#\n"
+ "# Format:\n"
+ "#\tQuantity\t;\tx\t;\ty\t;\tconversion to y (rational)\t;\ttest: 1000 x ⟹ y\n"
+ "#\n"
@@ -524,8 +549,8 @@
static final Set<String> NOT_CONVERTABLE = ImmutableSet.of("generic");
- private void checkUnitConvertability(UnitConverter converter, Output<String> compoundBaseUnit,
- Set<String> badUnits, Set<String> noQuantity, String type, String unit,
+ private void checkUnitConvertability(UnitConverter converter, Output<String> compoundBaseUnit,
+ Set<String> badUnits, Set<String> noQuantity, String type, String unit,
Multimap<Pair<String, Double>, String> testPrintout) {
if (converter.isBaseUnit(unit)) {
@@ -614,7 +639,7 @@
assertEquals("", 6.02214076E+23d, parser.parse("6.02214076E+23").toBigDecimal().doubleValue());
Rational temp = parser.parse("gal_to_m3");
//System.out.println(" " + temp);
- assertEquals("", 0.003785411784, temp.numerator.doubleValue()/temp.denominator.doubleValue());
+ assertEquals("", 0.003785411784, temp.numerator.doubleValue()/temp.denominator.doubleValue());
}
@@ -656,7 +681,7 @@
errln("Null quantity " + coreUnit);
} else if (!unitType.equals(quantity)) {
switch (unitType) {
- case "concentr":
+ case "concentr":
switch (quantity) {
case "portion": case "mass-density": case "concentration": case "substance-amount": continue;
}
@@ -666,7 +691,7 @@
case "consumption-inverse": continue;
}
break;
- case "duration":
+ case "duration":
switch (quantity) {
case "year-duration": continue;
}
@@ -683,7 +708,7 @@
break;
case "light":
switch (quantity) {
- case "luminous-flux": case "power": case "luminous-intensity": continue;
+ case "lumen": case "luminous-flux": case "power": case "luminous-intensity": case "luminance": case "illuminance": continue;
}
break;
case "mass":
@@ -772,7 +797,7 @@
}
static final UnicodeSet ALLOWED_IN_COMPONENT = new UnicodeSet("[a-z0-9]").freeze();
- static final Set<String> GRANDFATHERED_SIMPLES = ImmutableSet.of("em", "g-force", "therm-us");
+ static final Set<String> STILL_RECOGNIZED_SIMPLES = ImmutableSet.of("em", "g-force", "therm-us");
public void TestOrder() {
if (SHOW_DATA) System.out.println();
@@ -783,7 +808,7 @@
}
}
for (String unit : CORE_TO_TYPE.keySet()) {
- if (!GRANDFATHERED_SIMPLES.contains(unit)) {
+ if (!STILL_RECOGNIZED_SIMPLES.contains(unit)) {
for (String part : unit.split("-")) {
assertTrue(unit + " has no parts < 2 in length", part.length() > 2);
assertTrue(unit + " has only allowed characters", ALLOWED_IN_COMPONENT.containsAll(part));
@@ -798,7 +823,7 @@
public void TestConversionLineOrder() {
Map<String, TargetInfo> data = converter.getInternalConversionData();
- Multimap<TargetInfo, String> sorted = TreeMultimap.create(converter.targetInfoComparator,
+ Multimap<TargetInfo, String> sorted = TreeMultimap.create(converter.targetInfoComparator,
Comparator.naturalOrder());
Multimaps.invertFrom(Multimaps.forMap(data), sorted);
@@ -811,7 +836,9 @@
final TargetInfo tInfo = entry.getKey();
final String unit = entry.getValue();
if (lastUnit != null) {
- assertTrue(lastUnit + " < " + unit, conversionOrder.compare(lastUnit, unit) < 0);
+ if (!(conversionOrder.compare(lastUnit, unit) < 0)) {
+ warnln("Expected " + lastUnit + " < " + unit);
+ }
}
lastUnit = unit;
if (SHOW_DATA) {
@@ -876,7 +903,7 @@
static final Pattern ukSystemPattern = Pattern.compile("\\b(lb_to_kg|ft_to_m|ft2_to_m2|ft3_to_m3|in3_to_m3|gal_imp_to_m3)\\b");
static final Set<String> OK_BOTH = ImmutableSet.of(
- "ounce-troy", "nautical-mile", "fahrenheit", "inch-ofhg",
+ "ounce-troy", "nautical-mile", "fahrenheit", "inch-ofhg",
"british-thermal-unit", "foodcalorie", "knot");
static final Set<String> OK_US = ImmutableSet.of(
@@ -899,14 +926,14 @@
if (inputFactor == null) {
inputFactor = "";
}
- boolean usSystem = !NOT_US.contains(unit) &&
+ boolean usSystem = !NOT_US.contains(unit) &&
(OK_BOTH.contains(unit)
- || OK_US.contains(unit)
+ || OK_US.contains(unit)
|| usSystemPattern.matcher(inputFactor).find());
- boolean ukSystem = !NOT_UK.contains(unit) &&
+ boolean ukSystem = !NOT_UK.contains(unit) &&
(OK_BOTH.contains(unit)
- || OK_UK.contains(unit)
+ || OK_UK.contains(unit)
|| ukSystemPattern.matcher(inputFactor).find());
Collection<String> systems = toSystems.get(unit);
@@ -928,7 +955,7 @@
Output<String> metricUnit = new Output<>();
Stream<String> lines;
try {
- lines = Files.lines(testFile.toPath());
+ lines = Files.lines(testFile.toPath());
} catch (IOException e) {
throw new ICUUncheckedIOException("Couldn't process " + testFile);
}
@@ -983,7 +1010,7 @@
int count = 0;
for (String[] test : tests) {
final Rational sourceValue = Rational.of(test[0]);
- final String sourceUnit = test[1];
+ final String sourceUnit = test[1];
final String targetUnit = test[2];
final Rational expectedValue = Rational.of(test[3]);
final Rational conversion = converter.convert(sourceValue, sourceUnit, targetUnit, SHOW_DATA);
@@ -1061,7 +1088,7 @@
for (String targetUnit : comparableUnits) {
Rational rational = converter.convert(Rational.ONE, sourceUnit, targetUnit, false);
if (SHOW_DATA) System.out.print("\t" + rational.toBigDecimal(MathContext.DECIMAL64).doubleValue());
- }
+ }
if (SHOW_DATA) System.out.println();
}
}
@@ -1085,9 +1112,10 @@
for (Object[] test : tests0) {
ContinuedFraction source = (ContinuedFraction) test[0];
Rational expected = (Rational) test[1];
+ @SuppressWarnings("unchecked")
List<Rational> expectedIntermediates = (List<Rational>) test[2];
List<Rational> intermediates = new ArrayList<>();
- final Rational actual = source.toRational(intermediates);
+ final Rational actual = source.toRational(intermediates);
assertEquals("continued", expected, actual);
assertEquals("continued", expectedIntermediates, intermediates);
}
@@ -1119,9 +1147,9 @@
final BigDecimal dec64 = item.toBigDecimal(MathContext.DECIMAL64);
final BigDecimal dec128 = item.toBigDecimal(MathContext.DECIMAL128);
final boolean goodEnough = bigPiD == item.toBigDecimal(MathContext.DECIMAL128).doubleValue();
- System.out.println(item
+ System.out.println(item
+ "\t" + dec64
- + "x\t" + dec128
+ + "x\t" + dec128
+ "x\t" + goodEnough
+ "\t" + item.toBigDecimal(MathContext.DECIMAL128).subtract(bigPi));
if (goodEnough && goodCount++ > 6) {
@@ -1189,7 +1217,7 @@
Set<Set<String>> regionSets = regionsToUnitPreference.keySet();
// all quantity + usage pairs must contain 001 (one exception)
- assertTrue("For " + quantityPlusUsage + ", the set of sets of regions must contain 001", regionSets.contains(WORLD_SET)
+ assertTrue("For " + quantityPlusUsage + ", the set of sets of regions must contain 001", regionSets.contains(WORLD_SET)
|| quantityPlusUsage.contentEquals("concentration/blood-glucose"));
// Check that regions don't overlap for same quantity/usage
@@ -1258,7 +1286,7 @@
String baseUnit = converter.getBaseUnitFromQuantity(unitQuantity);
Rational size = converter.convert(up.geq, topUnit, baseUnit, false);
if (lastSize != null) { // ensure descending order
- if (!assertTrue("Successive items must be ≥ previous:\n\t" + quantityPlusUsage
+ if (!assertTrue("Successive items must be ≥ previous:\n\t" + quantityPlusUsage
+ "; unit: " + up.unit
+ "; size: " + size
+ "; regions: " + regions
@@ -1368,9 +1396,9 @@
if (GENERATE_TESTS) {
System.out.println(
- "\n# Test data for unit preferences\n"
+ "\n# Test data for unit preferences\n"
+ CldrUtility.getCopyrightString("# ") + "\n"
- + "#\n"
+ + "#\n"
+ "# Format:\n"
+ "#\tQuantity;\tUsage;\tRegion;\tInput (r);\tInput (d);\tInput Unit;\tOutput (r);\tOutput (d);\tOutput Unit\n"
+ "#\n"
@@ -1416,9 +1444,6 @@
// show samples
Set<String> regions = entry3.getKey();
String sampleRegion = regions.iterator().next();
- if (usage.equals("person-age")) {
- int debug = 0;
- }
Collection<UnitPreference> uprefs = entry3.getValue();
for (Rational sample : samples) {
showSample(quantity, usage, sampleRegion, sample, baseUnit, uprefs);
@@ -1469,7 +1494,7 @@
formattedUnit.append(sample + TEST_SEP + sample.doubleValue() + TEST_SEP + unit);
}
}
- System.out.println(quantity + TEST_SEP + usage + TEST_SEP + sampleRegion
+ System.out.println(quantity + TEST_SEP + usage + TEST_SEP + sampleRegion
+ TEST_SEP + originalSampleBaseValue + TEST_SEP + originalSampleBaseValue.doubleValue() + TEST_SEP + baseUnit
+ TEST_SEP + formattedUnit);
}
@@ -1504,9 +1529,9 @@
remainingCldrUnits.remove(data.source);
remainingCldrUnits.remove(data.target);
if (SHOW_DATA) System.out.println("*Converted"
- + "\t" + cldrResult.doubleValue()
- + "\t" + externalResult.doubleValue()
- + "\t" + symmetricDiff.doubleValue()
+ + "\t" + cldrResult.doubleValue()
+ + "\t" + externalResult.doubleValue()
+ + "\t" + symmetricDiff.doubleValue()
+ "\t" + data);
}
}
@@ -1604,7 +1629,7 @@
System.out.println("*CANT CONVERT-" + e);
}
}
- Output<String> baseUnit = new Output<String>();
+ Output<String> baseUnit = new Output<>();
for (ExternalUnitConversionData s : couldAdd) {
String target = s.target;
Rational endFactor = s.info.factor;
@@ -1623,9 +1648,9 @@
}
}
System.out.println("Could add 10^X conversion from a"
- + "\t" + s.source
+ + "\t" + s.source
+ "\tto" + mark
- + "\t" + endFactor.toString(FormatStyle.simple)
+ + "\t" + endFactor.toString(FormatStyle.simple)
+ "\t" + target);
}
}
@@ -1703,4 +1728,463 @@
Rational roundtrip = Rational.of(formatted);
assertEquals("roundtrip " + formatted, source, roundtrip);
}
+
+ /** Check that units to be translated are as expected. */
+ public void testDistinguishedSetsOfUnits() {
+ Set<String> comparatorUnitIds = new LinkedHashSet<>(DtdData.unitOrder.getOrder());
+ Set<String> validLongUnitIds = Validity.getInstance().getStatusToCodes(LstrType.unit).get(Validity.Status.regular);
+ final BiMap<String, String> shortToLong = Units.LONG_TO_SHORT.inverse();
+ Set<String> errors = new LinkedHashSet<>();
+ Set<String> unitsConvertibleLongIds = converter.canConvert().stream()
+ .map(x -> {
+ String result = shortToLong.get(x);
+ if (result == null) {
+ errors.add("No short form of " + x);
+ }
+ return result;
+ })
+ .collect(Collectors.toSet());
+ assertEquals("", Collections.emptySet(), errors);
+
+ Set<String> simpleConvertibleLongIds = converter.canConvert().stream()
+ .filter(x -> converter.isSimple(x))
+ .map((String x) -> Units.LONG_TO_SHORT.inverse().get(x))
+ .collect(Collectors.toSet());
+ CLDRFile root = CLDR_CONFIG.getCldrFactory().make("root", true);
+ ImmutableSet<String> unitLongIdsRoot = ImmutableSet.copyOf(getUnits(root, new TreeSet<>()));
+ ImmutableSet<String> unitLongIdsEnglish = ImmutableSet.copyOf(getUnits(CLDR_CONFIG.getEnglish(), new TreeSet<>()));
+
+ assertSameCollections("root unit IDs", "English", unitLongIdsRoot, unitLongIdsEnglish);
+ final Set<String> validLongUnitIdsMinusOddballs = minus(validLongUnitIds, Arrays.asList("concentr-item", "concentr-portion", "length-100-kilometer", "pressure-ofhg"));
+ assertSameCollections("root unit IDs", "valid regular", unitLongIdsRoot, validLongUnitIdsMinusOddballs);
+ assertSameCollections("comparatorUnitIds (DtdData)", "valid regular", comparatorUnitIds, validLongUnitIds);
+
+ assertSuperset("valid regular", "specials", validLongUnitIds, GrammarInfo.SPECIAL_TRANSLATION_UNITS);
+
+ assertSuperset("root unit IDs", "specials", unitLongIdsRoot, GrammarInfo.SPECIAL_TRANSLATION_UNITS);
+
+ //assertSuperset("long convertible units", "valid regular", unitsConvertibleLongIds, validLongUnitIds);
+ Output<String> baseUnit = new Output<>();
+ for (String longUnit : validLongUnitIds) {
+ if (longUnit.equals("temperature-generic")) {
+ continue;
+ }
+ String shortUnit = Units.getShort(longUnit);
+ ConversionInfo conversionInfo = converter.parseUnitId(shortUnit, baseUnit, false);
+ if (!assertNotNull("Can convert " + longUnit, conversionInfo)) {
+ converter.getUnitInfo(shortUnit, baseUnit);
+ int debug = 0;
+ }
+ }
+
+ assertSuperset("valid regular", "simple convertible units", validLongUnitIds, simpleConvertibleLongIds);
+
+ SupplementalDataInfo.getInstance().getUnitConverter();
+ }
+
+ public void assertSameCollections(String title1, String title2, Collection<String> c1, Collection<String> c2) {
+ assertSuperset(title1, title2, c1, c2);
+ assertSuperset(title2, title1, c2, c1);
+ }
+
+ public void assertSuperset(String title1, String title2, Collection<String> c1, Collection<String> c2) {
+ if (!assertEquals(title1 + " ⊇ " + title2, Collections.emptySet(), minus(c2, c1))) {
+ int debug = 0;
+ }
+ }
+
+ public Set<String> minus(Collection<String> a, Collection<String> b) {
+ Set<String> result = new LinkedHashSet<>(a);
+ result.removeAll(b);
+ return result;
+ }
+
+ public Set<String> getUnits(CLDRFile root, Set<String> unitLongIds) {
+ for (String path : root) {
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ int item = parts.findElement("unit");
+ if (item == -1) {
+ continue;
+ }
+ String type = parts.getAttributeValue(item, "type");
+ unitLongIds.add(type);
+ // "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + unit + "\"]/gender"
+ }
+ return unitLongIds;
+ }
+
+ static final Pattern NORM_SPACES = Pattern.compile("[ \u00A0\u200E]");
+
+ public void TestGender() {
+ Output<String> source = new Output<>();
+ Multimap<UnitPathType, String> partsUsed = TreeMultimap.create();
+ Factory factory = CLDR_CONFIG.getFullCldrFactory();
+ Set<String> available = factory.getAvailable();
+
+ for (String locale : SDI.hasGrammarInfo()) {
+ // skip ones without gender info
+ GrammarInfo gi = SDI.getGrammarInfo("fr");
+ Collection<String> genderInfo = gi.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.general);
+ if (genderInfo.isEmpty()) {
+ continue;
+ }
+ if (CLDRConfig.SKIP_SEED && !available.contains(locale)) {
+ continue;
+ }
+ // check others
+ CLDRFile resolvedFile = factory.make(locale, true);
+ for (Entry<String, String> entry : converter.SHORT_TO_LONG_ID.entrySet()) {
+ final String shortUnitId = entry.getKey();
+ final String longUnitId = entry.getValue();
+ final UnitId unitId = converter.createUnitId(shortUnitId);
+ partsUsed.clear();
+ String rawGender = UnitPathType.gender.getTrans(resolvedFile, "long", shortUnitId, null, null, null, partsUsed);
+
+ if (rawGender != null) {
+ String gender = unitId.getGender(resolvedFile, source, partsUsed);
+ if (gender != null && !shortUnitId.equals(source.value)) {
+ assertEquals("See if computed gender = raw gender for " + locale + "/" + shortUnitId + "\n\t" + Joiner.on("\n\t\t").join(partsUsed.asMap().entrySet()), rawGender, gender);
+ }
+ }
+ }
+ }
+ }
+
+ public void TestFallbackNames() {
+ String[][] sampleUnits = {
+ {"fr", "square-meter", "one", "nominative", "{0} mètre carré"},
+ {"fr", "square-meter", "other", "nominative", "{0} mètres carrés"},
+ {"fr", "square-decimeter", "other", "nominative", "{0} décimètres carrés"},
+ {"fr", "meter-per-square-second", "one", "nominative", "{0} mètre par seconde carrée"},
+ {"fr", "meter-per-square-second", "other", "nominative", "{0} mètres par seconde carrée"},
+
+ {"de", "square-meter", "other", "nominative", "{0} Quadratmeter"},
+ {"de", "square-decimeter", "other", "nominative", "{0} Quadratdezimeter"}, // real fail
+
+ {"de", "per-meter", "other", "nominative", "{0} pro Meter"},
+ {"de", "per-square-meter", "other", "nominative", "{0} pro Quadratmeter"},
+ {"de", "second-per-meter", "other", "nominative", "{0} Sekunden pro Meter"},
+ {"de", "meter-per-second", "other", "nominative", "{0} Meter pro Sekunde"},
+ {"de", "meter-per-square-second", "other", "nominative", "{0} Meter pro Quadratsekunde"},
+
+ {"de", "gigasecond-per-decimeter", "other", "nominative", "{0} Gigasekunden pro Dezimeter"},
+ {"de", "decimeter-per-gigasecond", "other", "nominative", "{0} Dezimeter pro Gigasekunde"}, // real fail
+
+ {"de", "gigasecond-milligram-per-centimeter-decisecond", "other", "nominative", "{0} Milligramm⋅Gigasekunden pro Zentimeter⋅Dezisekunde"},
+ {"de", "milligram-per-centimeter-decisecond", "other", "nominative", "{0} Milligramm pro Zentimeter⋅Dezisekunde"},
+ {"de", "per-centimeter-decisecond", "other", "nominative", "{0} pro Zentimeter⋅Dezisekunde"},
+ {"de", "gigasecond-milligram-per-centimeter", "other", "nominative", "{0} Milligramm⋅Gigasekunden pro Zentimeter"},
+ {"de", "gigasecond-milligram", "other", "nominative", "{0} Milligramm⋅Gigasekunden"},
+
+ {"de", "dessert-spoon-imperial-per-dessert-spoon-imperial", "one", "nominative", "{0} Imp. Dessertlöffel pro Imp. Dessertlöffel"},
+ {"de", "dessert-spoon-imperial-per-dessert-spoon-imperial", "one", "accusative", "{0} Imp. Dessertlöffel pro Imp. Dessertlöffel"},
+ {"de", "dessert-spoon-imperial-per-dessert-spoon-imperial", "other", "dative", "{0} Imp. Dessertlöffeln pro Imp. Dessertlöffel"},
+ {"de", "dessert-spoon-imperial-per-dessert-spoon-imperial", "one", "genitive", "{0} Imp. Dessertlöffels pro Imp. Dessertlöffel"},
+
+ // TODO: pick names (eg in Polish) that show differences in case.
+ // {"de", "foebar-foobar-per-fiebar-faebar", "other", "genitive", null},
+
+ };
+ ImmutableMap<String, String> frOverrides = ImmutableMap.<String, String>builder() // insufficient data in French as yet
+ .put("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"]", "{0} carré") //
+ .put("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"]", "{0} carrés") //
+ .put("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"one\"][@gender=\"feminine\"]", "{0} carrée") //
+ .put("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1[@count=\"other\"][@gender=\"feminine\"]", "{0} carrées") //
+ .build();
+
+ Multimap<UnitPathType, String> partsUsed = TreeMultimap.create();
+ int count = 0;
+ for (String[] row : sampleUnits) {
+ ++count;
+ final String locale = row[0];
+ CLDRFile resolvedFileRaw = CLDR_CONFIG.getCLDRFile(locale, true);
+ LocaleStringProvider resolvedFile;
+ switch(locale) {
+ case "fr": resolvedFile = resolvedFileRaw.makeOverridingStringProvider(frOverrides); break;
+ default: resolvedFile = resolvedFileRaw;
+ }
+
+ String shortUnitId = row[1];
+ String pluralCategory = row[2];
+ String caseVariant = row[3];
+ String expectedName = row[4];
+ final UnitId unitId = converter.createUnitId(shortUnitId);
+ final String actual = unitId.toString(resolvedFile, "long", pluralCategory, caseVariant, partsUsed, false);
+ assertEquals(count + ") " + Arrays.asList(row).toString() + "\n\t" + Joiner.on("\n\t").join(partsUsed.asMap().entrySet()), fixSpaces(expectedName), fixSpaces(actual));
+ }
+
+ }
+ public void TestFileFallbackNames() {
+ Multimap<UnitPathType, String> partsUsed = TreeMultimap.create();
+
+ // first gather all the examples
+ Set<String> skippedUnits = new LinkedHashSet<>();
+ Set<String> testSet = CLDR_CONFIG.getStandardCodes().getLocaleCoverageLocales(Organization.cldr);
+ Counter<String> localeToErrorCount = new Counter<>();
+ for (String localeId : testSet) {
+ if (localeId.contains("_")) {
+ continue; // skip to make test shorter
+ }
+ CLDRFile resolvedFile = CLDR_CONFIG.getCLDRFile(localeId, true);
+ PluralInfo pluralInfo = CLDR_CONFIG.getSupplementalDataInfo().getPlurals(localeId);
+ PluralRules pluralRules = pluralInfo.getPluralRules();
+ GrammarInfo grammarInfo =CLDR_CONFIG.getSupplementalDataInfo().getGrammarInfo(localeId);
+ Collection<String> caseVariants = grammarInfo == null ? null
+ : grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+ if (caseVariants == null || caseVariants.isEmpty()) {
+ caseVariants = Collections.singleton("nominative");
+ }
+
+
+ for (Entry<String, String> entry : converter.SHORT_TO_LONG_ID.entrySet()) {
+ final String shortUnitId = entry.getKey();
+ if (converter.getComplexity(shortUnitId) == UnitComplexity.simple) {
+ continue;
+ }
+ if (UnitConverter.HACK_SKIP_UNIT_NAMES.contains(shortUnitId)) {
+ skippedUnits.add(shortUnitId);
+ continue;
+ }
+ final String longUnitId = entry.getValue();
+ final UnitId unitId = converter.createUnitId(shortUnitId);
+ for (String width : Arrays.asList("long")) { // , "short", "narrow"
+ for (String pluralCategory : pluralRules.getKeywords()) {
+ for (String caseVariant : caseVariants) {
+ String composedName;
+ try {
+ composedName = unitId.toString(resolvedFile, width, pluralCategory, caseVariant, partsUsed, false);
+ } catch (Exception e) {
+ composedName = "ERROR:" + e.getMessage();
+ }
+ if (composedName != null && (composedName.contains("′") || composedName.contains("″"))) { // skip special cases
+ continue;
+ }
+ partsUsed.clear();
+ String transName = UnitPathType.unit.getTrans(resolvedFile, width, shortUnitId, pluralCategory, caseVariant, null, isVerbose() ? partsUsed : null);
+
+ // HACK to fix different spaces around placeholder
+ if (!Objects.equals(fixSpaces(transName), fixSpaces(composedName))) {
+ logln("\t" + localeId
+ + "\t" + shortUnitId
+ + "\t" + width
+ + "\t" + pluralCategory
+ + "\t" + caseVariant
+ + "\texpected ≠ fallback\t«" + transName + "»\t≠\t«" + composedName+ "»"
+ + partsUsed);
+ localeToErrorCount.add(localeId, 1);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!localeToErrorCount.isEmpty()) {
+ warnln("Use -v for details");
+ for (R2<Long, String> entry : localeToErrorCount.getEntrySetSortedByCount(false, null)) {
+ warnln("composed name ≠ translated name: " + entry.get0() + "\t" + entry.get1());
+ }
+ }
+
+ if (!skippedUnits.isEmpty()) {
+ warnln("Skipping unsupported unit: " + skippedUnits);
+ }
+ }
+
+ public String fixSpaces(String transName) {
+ return transName == null ? null : NORM_SPACES.matcher(transName).replaceAll(" ");
+ }
+
+ public void TestCheckUnits() {
+ CheckUnits checkUnits = new CheckUnits();
+ PathHeader.Factory phf = PathHeader.getFactory();
+ for (String locale : Arrays.asList("en", "fr", "de", "pl", "el")) {
+ CLDRFile cldrFile = CLDR_CONFIG.getCldrFactory().make(locale, true);
+
+ Options options = new Options();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
+ checkUnits.setCldrFileToCheck(cldrFile, options, possibleErrors);
+
+ for (String path : StreamSupport.stream(cldrFile.spliterator(), false).sorted().collect(Collectors.toList())) {
+ UnitPathType pathType = UnitPathType.getPathType(XPathParts.getFrozenInstance(path));
+ if (pathType == null || pathType == UnitPathType.unit) {
+ continue;
+ }
+ String value = cldrFile.getStringValue(path);
+ checkUnits.check(path, path, value, options, possibleErrors);
+ if (!possibleErrors.isEmpty()) {
+ PathHeader ph = phf.fromPath(path);
+ logln(locale + "\t" + ph.getCode() + "\t" + possibleErrors.toString());
+ }
+ }
+ }
+ }
+
+ public void TestDerivedCase() {
+ // needs further work
+ if (logKnownIssue("CLDR-13920", "finish this as part of unit derivation work")) {
+ return;
+ }
+ for (String locale : Arrays.asList("pl", "ru")) {
+ CLDRFile cldrFile = CLDR_CONFIG.getCldrFactory().make(locale, true);
+ GrammarInfo gi = SDI.getGrammarInfo(locale);
+ Collection<String> rawCases = gi.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+
+ PluralInfo plurals = SupplementalDataInfo.getInstance().getPlurals(PluralType.cardinal, locale);
+ Collection<Count> adjustedPlurals = plurals.getCounts();
+
+ Output<String> sourceCase = new Output<>();
+ Output<String> sourcePlural = new Output<>();
+
+ M4<String, String, String, Boolean> myInfo = ChainedMap.of(new TreeMap<String,Object>(), new TreeMap<String,Object>(), new TreeMap<String,Object>(), Boolean.class);
+
+ int count = 0;
+ for (String longUnit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ final String shortUnit = converter.getShortId(longUnit);
+ String gender = UnitPathType.gender.getTrans(cldrFile, "long", shortUnit, null, null, null, null);
+
+ for (String desiredCase : rawCases) {
+ // gather some general information
+ for (Count plural : adjustedPlurals) {
+ String value = UnitPathType.unit.getTrans(cldrFile, "long", shortUnit, plural.toString(), desiredCase, gender, null);
+ myInfo.put(gender, shortUnit + "\t" + value, plural.toString() + "+" + desiredCase, true);
+ }
+
+ // do actual test
+ if (desiredCase.contentEquals("nominative")) {
+ continue;
+ }
+ for (String desiredPlural : Arrays.asList("few", "other")) {
+
+ String value = UnitPathType.unit.getTrans(cldrFile, "long", shortUnit, desiredPlural, desiredCase, gender, null);
+ gi.getSourceCaseAndPlural(locale, gender, value, desiredCase, desiredPlural, sourceCase, sourcePlural);
+ String sourceValue = UnitPathType.unit.getTrans(cldrFile, "long", shortUnit, sourcePlural.value, sourceCase.value, gender, null);
+ assertEquals(count++ + ") " + locale
+ + ",\tshort unit/gender: " + shortUnit
+ + " / " + gender
+ + ",\tdesired case/plural: " + desiredCase
+ + " / " + desiredPlural
+ + ",\tsource case/plural: " + sourceCase
+ + " / " + sourcePlural
+ , value, sourceValue);
+ }
+ }
+ }
+ for (Entry<String, Map<String, Map<String, Boolean>>> m : myInfo) {
+ for (Entry<String, Map<String, Boolean>> t : m.getValue().entrySet()) {
+ System.out.println(m.getKey() + "\t" + t.getKey() + "\t" + t.getValue().keySet());
+ }
+ }
+ }
+ }
+ public void TestGenderOfCompounds() {
+ Set<String> skipUnits = ImmutableSet.of("kilocalorie", "kilopascal", "terabyte", "gigabyte", "kilobyte", "gigabit", "kilobit", "megabit", "megabyte", "terabit");
+ final ImmutableSet<String> keyValues = ImmutableSet.of("length", "mass", "duration", "power");
+ for (String localeID : GrammarInfo.SEED_LOCALES) {
+ GrammarInfo grammarInfo = SDI.getGrammarInfo(localeID);
+ if (grammarInfo == null) {
+ logln("No grammar info for: " + localeID);
+ continue;
+ }
+ UnitConverter converter = SDI.getUnitConverter();
+ Collection<String> genderInfo = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+ if (genderInfo.isEmpty()) {
+ continue;
+ }
+ CLDRFile cldrFile = info.getCldrFactory().make(localeID, true);
+ Map<String,String> shortUnitToGender = new TreeMap<>();
+ Output<String> source = new Output<>();
+ Multimap<UnitPathType, String> partsUsed = LinkedHashMultimap.create();
+
+ Set<String> units = new HashSet<>();
+ M4<String, String, String, Boolean> quantityToGenderToUnits = ChainedMap.of(new TreeMap<String,Object>(), new TreeMap<String,Object>(), new TreeMap<String,Object>(), Boolean.class);
+ M4<String, String, String, Boolean> genderToQuantityToUnits = ChainedMap.of(new TreeMap<String,Object>(), new TreeMap<String,Object>(), new TreeMap<String,Object>(), Boolean.class);
+
+ for (String path : cldrFile) {
+ if (!path.startsWith("//ldml/units/unitLength[@type=\"long\"]/unit[@type=")) {
+ continue;
+ }
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ final String shortId = converter.getShortId(parts.getAttributeValue(-2, "type"));
+ String quantity;
+ try {
+ quantity = converter.getQuantityFromUnit(shortId, false);
+ } catch (Exception e) {
+ continue;
+ }
+
+ //ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/gender
+ String gender = null;
+ if (parts.size() == 5 && parts.getElement(-1).equals("gender")) {
+ gender = cldrFile.getStringValue(path);
+ if (true) {
+ quantityToGenderToUnits.put(quantity, gender, shortId, true);
+ genderToQuantityToUnits.put(quantity, gender, shortId, true);
+ }
+ } else {
+ if (units.contains(shortId)) {
+ continue;
+ }
+ units.add(shortId);
+ }
+ UnitId unitId = converter.createUnitId(shortId);
+ String constructedGender = unitId.getGender(cldrFile, source, partsUsed);
+ boolean multiUnit = unitId.denUnitsToPowers.size() + unitId.denUnitsToPowers.size() > 1;
+ if (gender == null && (constructedGender == null || !multiUnit)) {
+ continue;
+ }
+
+ final boolean areEqual = Objects.equals(gender, constructedGender);
+ if (false) {
+ final String printInfo = localeID + "\t" + unitId + "\t" + gender + "\t" + multiUnit + "\t" + quantity + "\t" + constructedGender + "\t" + areEqual;
+ System.out.println(printInfo);
+ }
+ if (gender != null && !areEqual && !skipUnits.contains(shortId)) {
+ unitId.getGender(cldrFile, source, partsUsed);
+ shortUnitToGender.put(shortId, unitId + "\t" + gender + "\t" + constructedGender + "\t" + areEqual);
+ }
+ }
+ for (Entry<String,String> entry : shortUnitToGender.entrySet()) {
+ errln(localeID + "\t" + entry);
+ }
+
+ Set<String> missing = new LinkedHashSet<>(genderInfo);
+ for (String quantity : keyValues) {
+ M3<String, String, Boolean> genderToUnits = quantityToGenderToUnits.get(quantity);
+ showData(localeID, null, quantity, genderToUnits);
+ missing.removeAll(genderToUnits.keySet());
+ }
+ for (String quantity : quantityToGenderToUnits.keySet()) {
+ M3<String, String, Boolean> genderToUnits = quantityToGenderToUnits.get(quantity);
+ showData(localeID, missing, quantity, genderToUnits);
+ }
+ for (String gender : missing) {
+ System.out.println(localeID + "\t" + "?" + "\t" + gender + "\t?");
+ }
+ }
+ }
+
+ public void showData(String localeID, Set<String> genderFilter, String quantity, final M3<String, String, Boolean> genderToUnits) {
+ for (Entry<String, Map<String, Boolean>> entry2 : genderToUnits) {
+ String gender = entry2.getKey();
+ if (genderFilter != null) {
+ if(!genderFilter.contains(gender)) {
+ continue;
+ }
+ genderFilter.remove(gender);
+ }
+ for (String unit : entry2.getValue().keySet()) {
+ System.out.println(localeID + "\t" + quantity + "\t" + gender + "\t" + unit);
+ }
+ }
+ }
+
+ public void testDerivation() {
+ int count = 0;
+ for (String locale : SDI.hasGrammarDerivation()) {
+ GrammarDerivation gd = SDI.getGrammarDerivation(locale);
+ System.out.println(locale + " => " + gd);
+ ++count;
+ }
+ assertNotEquals("hasGrammarDerivation", 0, count);
+ }
}
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUtilities.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUtilities.java
index 0317dc6..6a2295d 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUtilities.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestUtilities.java
@@ -108,6 +108,7 @@
id = i;
}
+ @Override
public void run() {
logln("Starting thread: " + this);
for (int i = 0; i < STRING_ID_TEST_COUNT; ++i) {
@@ -121,6 +122,7 @@
logln("Ending thread: " + this);
}
+ @Override
public String toString() {
return "StringIdThread " + id;
}
@@ -230,6 +232,7 @@
Comparator<String> uca = new Comparator<String>() {
Collator col = Collator.getInstance(ULocale.ENGLISH);
+ @Override
public int compare(String o1, String o2) {
return col.compare(o1, o2);
}
@@ -909,8 +912,10 @@
public void TestSpecialLocales() {
assertSpecialLocale("sr", null);
+ assertSpecialLocale("ha_NE", SpecialLocales.Type.readonly);
assertSpecialLocale("sr_Latn", SpecialLocales.Type.readonly);
assertSpecialLocale("sr_Latn_BA", SpecialLocales.Type.readonly);
+ assertSpecialLocale("yue_Hans", null); // not readonly, because it is not policy DISCARD
assertSpecialLocale("en", SpecialLocales.Type.readonly);
assertSpecialLocale("en_ZZ", SpecialLocales.Type.readonly);
assertSpecialLocale("en_ZZ_PROGRAMMERESE", null); // not defined
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestValidity.java b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestValidity.java
index 33597df..1f78fc3 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestValidity.java
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/TestValidity.java
@@ -161,7 +161,7 @@
if (ALLOWED_MISSING.contains(code)) {
continue;
}
- errln(messages, type + ":" + code + ":" + oldStatus + " => " + newStatus
+ errln(messages, type + ":" + code + ":" + oldStatus + " => " + newStatus
+ " — missing in new data");
}
@@ -184,7 +184,7 @@
// logln(messages, "OK: " + type + ":" + code + " was " + oldStatus + " => " + newStatus);
continue;
}
- errln(messages, type + ":" + code + ":" + oldStatus + " => " + newStatus
+ errln(messages, type + ":" + code + ":" + oldStatus + " => " + newStatus
+ " — regular item changed, and didn't become deprecated");
}
if (oldStatus == Status.deprecated) {
@@ -363,7 +363,7 @@
String source = test[0];
String expectedLanguageSubtagParserIcu = test[1];
String expectedLanguageSubtagParserBCP = test[2];
-
+
// check that field 2 is the same as ICU
ULocale icuFromICU = new ULocale(expectedLanguageSubtagParserIcu);
ULocale icuFromBCP = ULocale.forLanguageTag(expectedLanguageSubtagParserBCP);
@@ -379,9 +379,9 @@
public void TestLanguageTagCanonicalizer() {
String[][] tests = {
- { "de-fonipa", "de_FONIPA" },
- { "el-1901-polytoni-aaland", "el_AX_1901_POLYTON" },
- { "en-POLYTONI-WHATEVER-ANYTHING-AALAND", "en_AX_ANYTHING_POLYTON_WHATEVER" },
+ { "dE-foniPa", "de_fonipa" },
+// { "el-1901-polytoni-aaland", "el_AX_1901_polyton" }, // doesn't yet handle polyton
+// { "en-POLYTONI-WHATEVER-ANYTHING-AALAND", "en_AX_anything_polyton_whatever" }, // doesn't yet handle polyton
{ "eng-840", "en" },
{ "sh_ba", "sr_Latn_BA" },
{ "iw-arab-010", "he_Arab_AQ" },
@@ -411,7 +411,7 @@
}
- ImmutableSet<LstrType> LstrTypesToSkip = ImmutableSet.of(LstrType.extlang, LstrType.grandfathered, LstrType.redundant);
+ ImmutableSet<LstrType> LstrTypesToSkip = ImmutableSet.of(LstrType.extlang, LstrType.legacy, LstrType.redundant);
Set<LstrType> lstrTypesToTest = EnumSet.allOf(LstrType.class);
lstrTypesToTest.removeAll(LstrTypesToSkip);
Set<String> missingAliases = new LinkedHashSet<>();
diff --git a/tools/cldr-unittest/src/org/unicode/cldr/unittest/data/localeMatcherTest.txt b/tools/cldr-unittest/src/org/unicode/cldr/unittest/data/localeMatcherTest.txt
index 28589e9..41ba341 100644
--- a/tools/cldr-unittest/src/org/unicode/cldr/unittest/data/localeMatcherTest.txt
+++ b/tools/cldr-unittest/src/org/unicode/cldr/unittest/data/localeMatcherTest.txt
@@ -147,7 +147,7 @@
en-Hant-TW, und-TW ; zh ; und-TW # zh should be closer to und-TW than to en-Hant-TW
##################################################
-# testMatchGrandfatheredCode
+# testMatchLegacyCode
fr, i-klingon, en-Latn-US ; en-GB-oed ; en-Latn-US
diff --git a/tools/java/.settings/org.eclipse.jdt.ui.prefs b/tools/java/.settings/org.eclipse.jdt.ui.prefs
index f421aab..7d8a0d5 100644
--- a/tools/java/.settings/org.eclipse.jdt.ui.prefs
+++ b/tools/java/.settings/org.eclipse.jdt.ui.prefs
@@ -1,3 +1,63 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_modifiers=false
+cleanup.remove_redundant_semicolons=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=false
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_CLDR
+cleanup_settings_version=2
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_CLDR
@@ -32,21 +92,23 @@
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=true
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=true
sp_cleanup.remove_redundant_type_arguments=true
-sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_imports=true
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
diff --git a/tools/java/build.xml b/tools/java/build.xml
index bfe314a..f62fec3 100644
--- a/tools/java/build.xml
+++ b/tools/java/build.xml
@@ -151,7 +151,6 @@
<target name="init-githash" depends="init" description="calculate build.githash">
<exec executable="git" outputproperty="build.githash" failifexecutionfails="false">
<arg value="rev-parse" />
- <arg value="--short" />
<arg value="HEAD" />
</exec>
<condition property="build.githash" value="(unknown)">
diff --git a/tools/java/com/ibm/icu/dev/test/AbstractTestLog.java b/tools/java/com/ibm/icu/dev/test/AbstractTestLog.java
index 5fdf3f1..1aad275 100644
--- a/tools/java/com/ibm/icu/dev/test/AbstractTestLog.java
+++ b/tools/java/com/ibm/icu/dev/test/AbstractTestLog.java
@@ -45,6 +45,7 @@
/**
* Add a message.
*/
+ @Override
public final void log(String message) {
msg(message, LOG, true, false);
}
@@ -52,6 +53,7 @@
/**
* Add a message and newline.
*/
+ @Override
public final void logln(String message) {
msg(message, LOG, true, true);
}
@@ -59,6 +61,7 @@
/**
* Report an error.
*/
+ @Override
public final void err(String message) {
msg(message, ERR, true, false);
}
@@ -66,6 +69,7 @@
/**
* Report an error and newline.
*/
+ @Override
public final void errln(String message) {
msg(message, ERR, true, true);
}
@@ -73,6 +77,7 @@
/**
* Report a warning (generally missing tests or data).
*/
+ @Override
public final void warn(String message) {
msg(message, WARN, true, false);
}
@@ -80,6 +85,7 @@
/**
* Report a warning (generally missing tests or data) and newline.
*/
+ @Override
public final void warnln(String message) {
msg(message, WARN, true, true);
}
@@ -93,6 +99,7 @@
* @param incCount if true, increments the warning or error count
* @param newln if true, forces a newline after the message
*/
+ @Override
public abstract void msg(String message, int level, boolean incCount, boolean newln);
/**
@@ -107,6 +114,7 @@
this.delegate = delegate;
}
+ @Override
public void msg(String message, int level, boolean incCount, boolean newln) {
if (delegate != null) {
delegate.msg(message, level, incCount, newln);
diff --git a/tools/java/com/ibm/icu/dev/test/TestFmwk.java b/tools/java/com/ibm/icu/dev/test/TestFmwk.java
index a3f7491..e491c85 100644
--- a/tools/java/com/ibm/icu/dev/test/TestFmwk.java
+++ b/tools/java/com/ibm/icu/dev/test/TestFmwk.java
@@ -184,10 +184,12 @@
this(null, classnames, null);
}
+ @Override
protected String getDescription() {
return description;
}
+ @Override
protected Target getTargets(String targetName) {
Target target = null;
if (targetName != null) {
@@ -236,6 +238,7 @@
return target;
}
+ @Override
protected TestFmwk getSubtest(String testName) throws TestFmwkException {
finishInit();
@@ -363,6 +366,7 @@
super(name);
}
+ @Override
protected boolean validate() {
return true;
}
@@ -376,14 +380,17 @@
testMethod = method;
}
+ @Override
protected boolean validate() {
return testMethod != null && validateMethod(name);
}
+ @Override
protected String getDescription() {
return getMethodDescription(name);
}
+ @Override
protected void execute() throws Exception{
if (params.inDocMode()) {
// nothing to execute
@@ -436,14 +443,17 @@
this.targetName = targetName;
}
+ @Override
protected boolean validate() {
return TestFmwk.this.validate();
}
+ @Override
protected String getDescription() {
return TestFmwk.this.getDescription();
}
+ @Override
protected void execute() throws Exception {
params.indentLevel++;
Target target = randomize(getTargets(targetName));
@@ -469,6 +479,7 @@
// so we sort them (always, and then randomize them, so that
// forcing a seed will also work across jvms).
Arrays.sort(arr, new Comparator() {
+ @Override
public int compare(Object lhs, Object rhs) {
// sort in reverse order, later we link up in
// forward order
@@ -830,6 +841,7 @@
return params.inclusion == 0;
}
+ @Override
public void msg(String message, int level, boolean incCount, boolean newln) {
params.msg(message, level, incCount, newln);
}
@@ -842,7 +854,7 @@
* Log the known issue.
* This method returns true unless -prop:logKnownIssue=no is specified
* in the argument list.
- *
+ *
* @param ticket A ticket number string. For an ICU ticket, use numeric characters only,
* such as "10245". For a CLDR ticket, use prefix "cldrbug:" followed by ticket number,
* such as "cldrbug:5013".
@@ -873,11 +885,11 @@
}
if (params.knownIssues == null) {
- params.knownIssues = new TreeMap<String, List<String>>();
+ params.knownIssues = new TreeMap<>();
}
List<String> lines = params.knownIssues.get(ticketLink);
if (lines == null) {
- lines = new ArrayList<String>();
+ lines = new ArrayList<>();
params.knownIssues.put(ticketLink, lines);
}
if (!lines.contains(description)) {
@@ -1085,12 +1097,16 @@
public NullWriter() {
super(System.out, false);
}
+ @Override
public void write(int c) {
}
+ @Override
public void write(char[] buf, int off, int len) {
}
+ @Override
public void write(String s, int off, int len) {
}
+ @Override
public void println() {
}
}
@@ -1110,6 +1126,7 @@
super(os, autoFlush);
}
+ @Override
public void write(int c) {
synchronized (lock) {
buffer.setLength(0);
@@ -1122,6 +1139,7 @@
}
}
+ @Override
public void write(char[] buf, int off, int len) {
synchronized (lock) {
buffer.setLength(0);
@@ -1140,6 +1158,7 @@
}
}
+ @Override
public void write(String s, int off, int len) {
write(s.substring(off, off + len).toCharArray(), 0, len);
}
@@ -1922,7 +1941,7 @@
protected void fail(String message) {
if (message == null) {
- message = "";
+ message = "";
}
if (!message.equals("")) {
message = ": " + message;
@@ -1977,7 +1996,7 @@
String source = st.getFileName();
if (source != null && !source.equals("TestFmwk.java") && !source.equals("AbstractTestLog.java")) {
String methodName = st.getMethodName();
- if (methodName != null &&
+ if (methodName != null &&
(methodName.startsWith("Test") || methodName.startsWith("test") || methodName.equals("main"))) {
return "(" + source + ":" + st.getLineNumber() + ") ";
}
diff --git a/tools/java/com/ibm/icu/dev/test/TestLog.java b/tools/java/com/ibm/icu/dev/test/TestLog.java
index b845dcb..1211d82 100644
--- a/tools/java/com/ibm/icu/dev/test/TestLog.java
+++ b/tools/java/com/ibm/icu/dev/test/TestLog.java
@@ -27,7 +27,7 @@
* Warn about missing tests or data.
*/
void warn(String message);
-
+
void warnln(String message);
diff --git a/tools/java/com/ibm/icu/dev/test/TestLogWriter.java b/tools/java/com/ibm/icu/dev/test/TestLogWriter.java
index 3f2e01d..44b9171 100644
--- a/tools/java/com/ibm/icu/dev/test/TestLogWriter.java
+++ b/tools/java/com/ibm/icu/dev/test/TestLogWriter.java
@@ -20,10 +20,12 @@
this.level = level;
}
+ @Override
public void write(char cbuf[], int off, int len) throws IOException {
write(new String(cbuf, off, len));
}
+ @Override
public void write(String str) throws IOException {
if (closed) {
throw new IOException("stream closed");
@@ -35,9 +37,11 @@
}
}
+ @Override
public void flush() throws IOException {
}
+ @Override
public void close() throws IOException {
closed = true;
}
diff --git a/tools/java/com/ibm/icu/dev/test/TestUtil.java b/tools/java/com/ibm/icu/dev/test/TestUtil.java
index 74f2104..2d5abed 100644
--- a/tools/java/com/ibm/icu/dev/test/TestUtil.java
+++ b/tools/java/com/ibm/icu/dev/test/TestUtil.java
@@ -170,6 +170,7 @@
lock.inc();
}
+ @Override
public void run() {
try {
synchronized (lock) {
diff --git a/tools/java/com/ibm/icu/dev/test/UTF16Util.java b/tools/java/com/ibm/icu/dev/test/UTF16Util.java
index 145e767..d2965d2 100644
--- a/tools/java/com/ibm/icu/dev/test/UTF16Util.java
+++ b/tools/java/com/ibm/icu/dev/test/UTF16Util.java
@@ -8,7 +8,7 @@
package com.ibm.icu.dev.test;
/**
- * Utility class for supplementary code point
+ * Utility class for supplementary code point
* support. This one is written purely for updating
* Normalization sample from the unicode.org site.
* If you want the real thing, use UTF16 class
@@ -20,7 +20,7 @@
/**
* Method nextCodePoint. Returns the next code point
- * in a string.
+ * in a string.
* @param s String in question
* @param i index from which we want a code point
* @return int codepoint at index i
@@ -38,7 +38,7 @@
/**
* Method prevCodePoint. Gets the code point preceding
- * index i (predecrement).
+ * index i (predecrement).
* @param s String in question
* @param i index in string
* @return int codepoint at index --i
@@ -56,7 +56,7 @@
/**
* Method nextCodePoint. Returns the next code point
- * in a string.
+ * in a string.
* @param s StringBuffer in question
* @param i index from which we want a code point
* @return int codepoint at index i
@@ -74,7 +74,7 @@
/**
* Method prevCodePoint. Gets the code point preceding
- * index i (predecrement).
+ * index i (predecrement).
* @param s StringBuffer in question
* @param i index in string
* @return int codepoint at index --i
@@ -91,7 +91,7 @@
}
/**
- * Method codePointLength. Returns the length
+ * Method codePointLength. Returns the length
* in UTF-16 code units of a given code point
* @param c code point in question
* @return int length in UTF-16 code units. Can be 1 or 2
@@ -111,7 +111,7 @@
buffer.append((char)ch);
} else {
buffer.append((char)(0xd7c0 + (ch >> 10)));
- buffer.append((char)(0xdc00 + (ch & 0x3ff)));
+ buffer.append((char)(0xdc00 + (ch & 0x3ff)));
}
}
@@ -126,10 +126,10 @@
if (ch <= 0xffff) {
buffer.insert(i, (char)ch);
} else {
- buffer.insert(i, (char)(0xd7c0 + (ch >> 10))).insert(i + 1, (char)(0xdc00 + (ch & 0x3ff)));
+ buffer.insert(i, (char)(0xd7c0 + (ch >> 10))).insert(i + 1, (char)(0xdc00 + (ch & 0x3ff)));
}
}
-
+
/**
* Method setCodePointAt. Changes a code point at a
* given index. Can change the length of the string.
@@ -140,7 +140,7 @@
*/
public static final int setCodePointAt(StringBuffer buffer, int i, int ch) {
int cp = nextCodePoint(buffer, i);
-
+
if (ch <= 0xffff && cp <= 0xffff) { // Both BMP
buffer.setCharAt(i, (char)ch);
return 0;
@@ -154,8 +154,8 @@
return -1;
} else { //if (ch > 0xffff && cp <= 0xffff) { // putting supplementary instead of BMP, buffer grows
buffer.setCharAt(i, (char)(0xd7c0 + (ch >> 10)));
- buffer.insert(i+1, (char)(0xdc00 + (ch & 0x3ff)));
- return 1;
+ buffer.insert(i+1, (char)(0xdc00 + (ch & 0x3ff)));
+ return 1;
}
}
@@ -165,13 +165,13 @@
* @param source String in question.
* @return int number of code points in this string
*/
- public static final int countCodePoint(String source)
- {
+ public static final int countCodePoint(String source)
+ {
int result = 0;
char ch;
boolean hadLeadSurrogate = false;
-
- for (int i = 0; i < source.length(); ++ i)
+
+ for (int i = 0; i < source.length(); ++ i)
{
ch = source.charAt(i);
if (hadLeadSurrogate && 0xdc00 <= ch && ch <= 0xdfff) {
@@ -183,23 +183,23 @@
++ result; // count others as 1
}
}
-
+
return result;
}
-
+
/**
* Method countCodePoint. Counts the UTF-32 code points
* in a UTF-16 encoded string.
* @param source StringBuffer in question.
* @return int number of code points in this string
*/
- public static final int countCodePoint(StringBuffer source)
- {
+ public static final int countCodePoint(StringBuffer source)
+ {
int result = 0;
char ch;
boolean hadLeadSurrogate = false;
-
- for (int i = 0; i < source.length(); ++ i)
+
+ for (int i = 0; i < source.length(); ++ i)
{
ch = source.charAt(i);
if (hadLeadSurrogate && 0xdc00 <= ch && ch <= 0xdfff) {
@@ -211,22 +211,22 @@
++ result; // count others as 1
}
}
-
+
return result;
}
/**
* The minimum value for Supplementary code points
*/
- public static final int SUPPLEMENTARY_MIN_VALUE = 0x10000;
+ public static final int SUPPLEMENTARY_MIN_VALUE = 0x10000;
/**
* Determines how many chars this char32 requires.
* If a validity check is required, use <code>
- * <a href="../UCharacter.html#isLegal(char)">isLegal()</a></code> on
+ * <a href="../UCharacter.html#isLegal(char)">isLegal()</a></code> on
* char32 before calling.
* @param char32 the input codepoint.
- * @return 2 if is in supplementary space, otherwise 1.
+ * @return 2 if is in supplementary space, otherwise 1.
*/
- public static int getCharCount(int char32)
+ public static int getCharCount(int char32)
{
if (char32 < SUPPLEMENTARY_MIN_VALUE) {
return 1;
@@ -243,12 +243,12 @@
* @stable ICU 2.1
*/
public static final int LEAD_SURROGATE_MIN_VALUE = 0xD800;
-
+
/**
* Trail surrogate minimum value
* @stable ICU 2.1
*/
- public static final int TRAIL_SURROGATE_MIN_VALUE = 0xDC00;
+ public static final int TRAIL_SURROGATE_MIN_VALUE = 0xDC00;
/**
* Trail surrogate maximum value
* @stable ICU 2.1
@@ -260,44 +260,44 @@
* @return true iff the input character is a surrogate.
* @stable ICU 2.1
*/
- public static boolean isSurrogate(char char16)
+ public static boolean isSurrogate(char char16)
{
- return LEAD_SURROGATE_MIN_VALUE <= char16 &&
+ return LEAD_SURROGATE_MIN_VALUE <= char16 &&
char16 <= TRAIL_SURROGATE_MAX_VALUE;
}
-
+
/**
* Determines whether the character is a trail surrogate.
* @param char16 the input character.
* @return true iff the input character is a trail surrogate.
* @stable ICU 2.1
*/
- public static boolean isTrailSurrogate(char char16)
+ public static boolean isTrailSurrogate(char char16)
{
- return (TRAIL_SURROGATE_MIN_VALUE <= char16 &&
+ return (TRAIL_SURROGATE_MIN_VALUE <= char16 &&
char16 <= TRAIL_SURROGATE_MAX_VALUE);
}
-
+
/**
* Determines whether the character is a lead surrogate.
* @param char16 the input character.
* @return true iff the input character is a lead surrogate
* @stable ICU 2.1
*/
- public static boolean isLeadSurrogate(char char16)
+ public static boolean isLeadSurrogate(char char16)
{
- return LEAD_SURROGATE_MIN_VALUE <= char16 &&
+ return LEAD_SURROGATE_MIN_VALUE <= char16 &&
char16 <= LEAD_SURROGATE_MAX_VALUE;
}
/**
* Extract a single UTF-32 value from a substring.
* Used when iterating forwards or backwards (with
* <code>UTF16.getCharCount()</code>, as well as random access. If a
- * validity check is required, use
+ * validity check is required, use
* <code><a href="../UCharacter.html#isLegal(char)">UCharacter.isLegal()
* </a></code> on the return value.
* If the char retrieved is part of a surrogate pair, its supplementary
- * character will be returned. If a complete supplementary character is
+ * character will be returned. If a complete supplementary character is
* not found the incomplete character will be returned
* @param source array of UTF-16 chars
* @param start offset to substring in the source array for analyzing
@@ -306,26 +306,26 @@
* @return UTF-32 value for the UTF-32 value that contains the char at
* offset16. The boundaries of that codepoint are the same as in
* <code>bounds32()</code>.
- * @exception IndexOutOfBoundsException thrown if offset16 is not within
+ * @exception IndexOutOfBoundsException thrown if offset16 is not within
* the range of start and limit.
* @stable ICU 2.1
*/
- public static int charAt(char source[], int start, int limit,
+ public static int charAt(char source[], int start, int limit,
int offset16)
{
offset16 += start;
if (offset16 < start || offset16 >= limit) {
throw new ArrayIndexOutOfBoundsException(offset16);
}
-
+
char single = source[offset16];
if (!isSurrogate(single)) {
return single;
}
// Convert the UTF-16 surrogate pair if necessary.
- // For simplicity in usage, and because the frequency of pairs is
- // low, look both directions.
+ // For simplicity in usage, and because the frequency of pairs is
+ // low, look both directions.
if (single <= LEAD_SURROGATE_MAX_VALUE) {
offset16 ++;
if (offset16 >= limit) {
@@ -335,7 +335,7 @@
if (isTrailSurrogate(trail)) {
return getRawSupplementary(single, trail);
}
- }
+ }
else { // isTrailSurrogate(single), so
if (offset16 == start) {
return single;
@@ -351,17 +351,17 @@
* Shift value for lead surrogate to form a supplementary character.
*/
private static final int LEAD_SURROGATE_SHIFT_ = 10;
-
- /**
+
+ /**
* Offset to add to combined surrogate pair to avoid msking.
*/
- private static final int SURROGATE_OFFSET_ =
- SUPPLEMENTARY_MIN_VALUE -
- (LEAD_SURROGATE_MIN_VALUE <<
- LEAD_SURROGATE_SHIFT_) -
- TRAIL_SURROGATE_MIN_VALUE;
+ private static final int SURROGATE_OFFSET_ =
+ SUPPLEMENTARY_MIN_VALUE -
+ (LEAD_SURROGATE_MIN_VALUE <<
+ LEAD_SURROGATE_SHIFT_) -
+ TRAIL_SURROGATE_MIN_VALUE;
-
+
/**
* Forms a supplementary code point from the argument character<br>
* Note this is for internal use hence no checks for the validity of the
@@ -374,5 +374,5 @@
{
return (lead << LEAD_SURROGATE_SHIFT_) + trail + SURROGATE_OFFSET_;
}
-
+
}
diff --git a/tools/java/com/ibm/icu/text/FixedDecimal.java b/tools/java/com/ibm/icu/text/FixedDecimal.java
new file mode 100644
index 0000000..9fc076c
--- /dev/null
+++ b/tools/java/com/ibm/icu/text/FixedDecimal.java
@@ -0,0 +1,684 @@
+package com.ibm.icu.text;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Locale;
+
+import com.ibm.icu.text.PluralRules.IFixedDecimal;
+import com.ibm.icu.text.PluralRules.Operand;
+
+/**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+@Deprecated
+public class FixedDecimal extends Number implements Comparable<FixedDecimal>, IFixedDecimal {
+ private static final long serialVersionUID = -4756200506571685661L;
+
+ final double source;
+
+ final int visibleDecimalDigitCount;
+
+ final int visibleDecimalDigitCountWithoutTrailingZeros;
+
+ final long decimalDigits;
+
+ final long decimalDigitsWithoutTrailingZeros;
+
+ final long integerValue;
+
+ final boolean hasIntegerValue;
+
+ final boolean isNegative;
+
+ final int exponent;
+
+ private final int baseFactor;
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public double getSource() {
+ return source;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public int getVisibleDecimalDigitCount() {
+ return visibleDecimalDigitCount;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public int getVisibleDecimalDigitCountWithoutTrailingZeros() {
+ return visibleDecimalDigitCountWithoutTrailingZeros;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public long getDecimalDigits() {
+ return decimalDigits;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public long getDecimalDigitsWithoutTrailingZeros() {
+ return decimalDigitsWithoutTrailingZeros;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public long getIntegerValue() {
+ return integerValue;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public boolean isHasIntegerValue() {
+ return hasIntegerValue;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public boolean isNegative() {
+ return isNegative;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public int getBaseFactor() {
+ return baseFactor;
+ }
+
+ static final long MAX = (long)1E18;
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ * @param n is the original number
+ * @param v number of digits to the right of the decimal place. e.g 1.00 = 2 25. = 0
+ * @param f Corresponds to f in the plural rules grammar.
+ * The digits to the right of the decimal place as an integer. e.g 1.10 = 10
+ * @param e Suppressed exponent for scientific and compact notation
+ */
+ @Deprecated
+ public FixedDecimal(double n, int v, long f, int e) {
+ isNegative = n < 0;
+ source = isNegative ? -n : n;
+ visibleDecimalDigitCount = v;
+ decimalDigits = f;
+ integerValue = n > MAX
+ ? MAX
+ : (long)n;
+ exponent = e;
+ hasIntegerValue = source == integerValue;
+ // check values. TODO make into unit test.
+ //
+ // long visiblePower = (int) Math.pow(10, v);
+ // if (fractionalDigits > visiblePower) {
+ // throw new IllegalArgumentException();
+ // }
+ // double fraction = intValue + (fractionalDigits / (double) visiblePower);
+ // if (fraction != source) {
+ // double diff = Math.abs(fraction - source)/(Math.abs(fraction) + Math.abs(source));
+ // if (diff > 0.00000001d) {
+ // throw new IllegalArgumentException();
+ // }
+ // }
+ if (f == 0) {
+ decimalDigitsWithoutTrailingZeros = 0;
+ visibleDecimalDigitCountWithoutTrailingZeros = 0;
+ } else {
+ long fdwtz = f;
+ int trimmedCount = v;
+ while ((fdwtz%10) == 0) {
+ fdwtz /= 10;
+ --trimmedCount;
+ }
+ decimalDigitsWithoutTrailingZeros = fdwtz;
+ visibleDecimalDigitCountWithoutTrailingZeros = trimmedCount;
+ }
+ baseFactor = (int) Math.pow(10, v);
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public FixedDecimal(double n, int v, long f) {
+ this(n, v, f, 0);
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public static FixedDecimal createWithExponent(double n, int v, int e) {
+ return new FixedDecimal(n,v,getFractionalDigits(n, v), e);
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public FixedDecimal(double n, int v) {
+ this(n,v,getFractionalDigits(n, v));
+ }
+
+ private static int getFractionalDigits(double n, int v) {
+ if (v == 0) {
+ return 0;
+ } else {
+ if (n < 0) {
+ n = -n;
+ }
+ int baseFactor = (int) Math.pow(10, v);
+ long scaled = Math.round(n * baseFactor);
+ return (int) (scaled % baseFactor);
+ }
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public FixedDecimal(double n) {
+ this(n, decimals(n));
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public FixedDecimal(long n) {
+ this(n,0);
+ }
+
+ private static final long MAX_INTEGER_PART = 1000000000;
+ /**
+ * Return a guess as to the number of decimals that would be displayed. This is only a guess; callers should
+ * always supply the decimals explicitly if possible. Currently, it is up to 6 decimals (without trailing zeros).
+ * Returns 0 for infinities and nans.
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ *
+ */
+ @Deprecated
+ public static int decimals(double n) {
+ // Ugly...
+ if (Double.isInfinite(n) || Double.isNaN(n)) {
+ return 0;
+ }
+ if (n < 0) {
+ n = -n;
+ }
+ if (n == Math.floor(n)) {
+ return 0;
+ }
+ if (n < MAX_INTEGER_PART) {
+ long temp = (long)(n * 1000000) % 1000000; // get 6 decimals
+ for (int mask = 10, digits = 6; digits > 0; mask *= 10, --digits) {
+ if ((temp % mask) != 0) {
+ return digits;
+ }
+ }
+ return 0;
+ } else {
+ String buf = String.format(Locale.ENGLISH, "%1.15e", n);
+ int ePos = buf.lastIndexOf('e');
+ int expNumPos = ePos + 1;
+ if (buf.charAt(expNumPos) == '+') {
+ expNumPos++;
+ }
+ String exponentStr = buf.substring(expNumPos);
+ int exponent = Integer.parseInt(exponentStr);
+ int numFractionDigits = ePos - 2 - exponent;
+ if (numFractionDigits < 0) {
+ return 0;
+ }
+ for (int i=ePos-1; numFractionDigits > 0; --i) {
+ if (buf.charAt(i) != '0') {
+ break;
+ }
+ --numFractionDigits;
+ }
+ return numFractionDigits;
+ }
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only
+ */
+ @Deprecated
+ private FixedDecimal (FixedDecimal other) {
+ // Ugly, but necessary, because constructors must only call other
+ // constructors in the first line of the body, and
+ // FixedDecimal(String) was refactored to support exponents.
+ this.source = other.source;
+ this.visibleDecimalDigitCount = other.visibleDecimalDigitCount;
+ this.visibleDecimalDigitCountWithoutTrailingZeros =
+ other.visibleDecimalDigitCountWithoutTrailingZeros;
+ this.decimalDigits = other.decimalDigits;
+ this.decimalDigitsWithoutTrailingZeros =
+ other.decimalDigitsWithoutTrailingZeros;
+ this.integerValue = other.integerValue;
+ this.hasIntegerValue = other.hasIntegerValue;
+ this.isNegative = other.isNegative;
+ this.exponent = other.exponent;
+ this.baseFactor = other.baseFactor;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public FixedDecimal (String n) {
+ // Ugly, but for samples we don't care.
+ this(parseDecimalSampleRangeNumString(n));
+ }
+
+// /**
+// * @internal CLDR
+// * @deprecated This API is ICU internal only
+// */
+// @Deprecated
+// private static FixedDecimal parseDecimalSampleRangeNumString(String num) {
+// if (num.contains("e")) {
+// int ePos = num.lastIndexOf('e');
+// int expNumPos = ePos + 1;
+// String exponentStr = num.substring(expNumPos);
+// int exponent = Integer.parseInt(exponentStr);
+// String fractionStr = num.substring(0, ePos);
+// return FixedDecimal.createWithExponent(
+// Double.parseDouble(fractionStr),
+// getVisibleFractionCount(fractionStr),
+// exponent);
+// } else {
+// return new FixedDecimal(Double.parseDouble(num), getVisibleFractionCount(num));
+// }
+// }
+
+ // The value of n needs to take the exponent into account
+ public static FixedDecimal parseDecimalSampleRangeNumString(String num) {
+ double n;
+ int v;
+ int exponent = 0;
+ String fractionStr = num; // default
+ if (num.contains("e")) {
+ int ePos = num.lastIndexOf('e');
+ int expNumPos = ePos + 1;
+ String exponentStr = num.substring(expNumPos);
+ exponent = Integer.parseInt(exponentStr);
+ fractionStr = num.substring(0, ePos);
+
+ // now adjust the fraction string according to the exponent
+ // not the most efficient, but more reliable code for testing
+ if (exponent != 0) {
+ int decimalPos = fractionStr.indexOf('.');
+ int decimalCount = 0;
+ String integerPart = fractionStr;
+ String fractionPart = "";
+ if (decimalPos >= 0) {
+ decimalCount = fractionStr.length() - decimalPos - 1;
+ integerPart = fractionStr.substring(0,decimalPos);
+ fractionPart = fractionStr.substring(decimalPos+1);
+ }
+
+ if (decimalCount == exponent) { // 2.123e3 => 2123
+ fractionStr = integerPart + fractionPart;
+ } else if (decimalCount > exponent) { // 2.1234e3 => 2123.4
+ fractionStr = integerPart + fractionPart.substring(0,exponent) + "." + fractionPart.substring(exponent);
+ } else { // decimalCount < exponent // // 2.1e3 => 2100
+ fractionStr = integerPart + padEnd(fractionPart, exponent, '0');
+ }
+ }
+ }
+ n = Double.parseDouble(fractionStr);
+ v = getVisibleFractionCount(fractionStr);
+ return new FixedDecimal(n, v, getFractionalDigits(n, v), exponent);
+ }
+
+
+ private static String padEnd(String string, int minLength, char c) {
+ StringBuilder sb = new StringBuilder(minLength);
+ sb.append(string);
+ for (int i = string.length(); i < minLength; i++) {
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ public static int getVisibleFractionCount(String value) {
+ value = value.trim();
+ int decimalPos = value.indexOf('.') + 1;
+ if (decimalPos == 0) {
+ return 0;
+ } else {
+ return value.length() - decimalPos;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Override
+ @Deprecated
+ public double getPluralOperand(Operand operand) {
+ switch(operand) {
+ case n: return source;
+ case i: return integerValue;
+ case f: return decimalDigits;
+ case t: return decimalDigitsWithoutTrailingZeros;
+ case v: return visibleDecimalDigitCount;
+ case w: return visibleDecimalDigitCountWithoutTrailingZeros;
+ case e: return exponent;
+ default: return source;
+ }
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public static Operand getOperand(String t) {
+ return Operand.valueOf(t);
+ }
+
+ /**
+ * We're not going to care about NaN.
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Override
+ @Deprecated
+ public int compareTo(FixedDecimal other) {
+ if (exponent != other.exponent) {
+ return exponent < other.exponent ? -1 : 1;
+ }
+ if (integerValue != other.integerValue) {
+ return integerValue < other.integerValue ? -1 : 1;
+ }
+ if (source != other.source) {
+ return source < other.source ? -1 : 1;
+ }
+ if (visibleDecimalDigitCount != other.visibleDecimalDigitCount) {
+ return visibleDecimalDigitCount < other.visibleDecimalDigitCount ? -1 : 1;
+ }
+ long diff = decimalDigits - other.decimalDigits;
+ if (diff != 0) {
+ return diff < 0 ? -1 : 1;
+ }
+ return 0;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public boolean equals(Object arg0) {
+ if (arg0 == null) {
+ return false;
+ }
+ if (arg0 == this) {
+ return true;
+ }
+ if (!(arg0 instanceof FixedDecimal)) {
+ return false;
+ }
+ FixedDecimal other = (FixedDecimal)arg0;
+ return source == other.source && visibleDecimalDigitCount == other.visibleDecimalDigitCount && decimalDigits == other.decimalDigits
+ && exponent == other.exponent;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public int hashCode() {
+ // TODO Auto-generated method stub
+ return (int)(decimalDigits + 37 * (visibleDecimalDigitCount + (int)(37 * source)));
+ }
+
+ public static String toSampleString(IFixedDecimal source) {
+ final double n = source.getPluralOperand(Operand.n);
+ final int exponent = (int) source.getPluralOperand(Operand.e);
+ final int visibleDecimalDigitCount = (int) source.getPluralOperand(Operand.v);
+ if (exponent == 0) {
+ return String.format(Locale.ROOT, "%." + visibleDecimalDigitCount + "f", n);
+ } else {
+ // we need to slide the exponent back
+
+ int fixedV = visibleDecimalDigitCount + exponent;
+ String baseString = String.format(Locale.ROOT, "%." + fixedV + "f",n/Math.pow(10,exponent));
+
+ // HACK
+ // However, we don't have enough information to round-trip if v == 0
+ // So in that case we choose the shortest form,
+ // so we have to have a hack to strip trailing fraction spaces.
+ if (visibleDecimalDigitCount == 0) {
+ for (int i = visibleDecimalDigitCount; i < fixedV; ++i) {
+ // TODO this code could and should be optimized, but for now...
+ if (baseString.endsWith("0")) {
+ baseString = baseString.substring(0,baseString.length()-1);
+ continue;
+ }
+ break;
+ }
+ if (baseString.endsWith(".")) {
+ baseString = baseString.substring(0,baseString.length()-1);
+ }
+ }
+ return baseString + "e" + exponent;
+ }
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public String toString() {
+ return toSampleString(this);
+// if (exponent == 0) {
+// return String.format(Locale.ROOT, "%." + visibleDecimalDigitCount + "f", source);
+// } else {
+// // we need to slide the exponent back
+//
+// int fixedV = visibleDecimalDigitCount + exponent;
+// String baseString = String.format(Locale.ROOT, "%." + fixedV + "f", getSource()/Math.pow(10,exponent));
+//
+// // However, we don't have enough information to round-trip if v == 0
+// // So in that case we choose the shortest form,
+// // so we have to have a hack to strip trailing fraction spaces.
+// if (visibleDecimalDigitCount == 0) {
+// for (int i = visibleDecimalDigitCount; i < fixedV; ++i) {
+// // TODO this code could and should be optimized, but for now...
+// if (baseString.endsWith("0")) {
+// baseString = baseString.substring(0,baseString.length()-1);
+// continue;
+// }
+// break;
+// }
+// if (baseString.endsWith(".")) {
+// baseString = baseString.substring(0,baseString.length()-1);
+// }
+// }
+//
+// return baseString + "e" + exponent;
+// }
+ }
+
+// // FixedDecimal.toString isn't working right.
+// public String xtoString() {
+// // we need to slide v up
+// final int v = getVisibleDecimalDigitCount();
+// final int exponent = getExponent();
+// if (exponent == 0) {
+// return String.format(Locale.ROOT, "%." + v + "f", getSource());
+// }
+// int fixedV = v + exponent;
+// String baseString = String.format(Locale.ROOT, "%." + fixedV + "f", getSource()/Math.pow(10,exponent));
+// // however, the format does not round trip.
+// // so we have to have a hack to strip trailing fraction spaces.
+// for (int i = v; i < fixedV; ++i) {
+// // TODO this code could and should be optimized, but for now...
+// if (baseString.endsWith("0")) {
+// baseString = baseString.substring(0,baseString.length()-1);
+// continue;
+// }
+// break;
+// }
+// if (baseString.endsWith(".")) {
+// baseString = baseString.substring(0,baseString.length()-1);
+// }
+// return baseString + "e" + exponent;
+// }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public boolean hasIntegerValue() {
+ return hasIntegerValue;
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public int intValue() {
+ // TODO Auto-generated method stub
+ return (int) longValue();
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public long longValue() {
+ if (exponent == 0) {
+ return integerValue;
+ } else {
+ return (long) (Math.pow(10, exponent) * integerValue);
+ }
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public float floatValue() {
+ return (float) (source * Math.pow(10, exponent));
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public double doubleValue() {
+ return (isNegative ? -source : source);
+ }
+
+ /**
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public long getShiftedValue() {
+ return integerValue * baseFactor + decimalDigits;
+ }
+
+ private void writeObject(
+ ObjectOutputStream out)
+ throws IOException {
+ throw new NotSerializableException();
+ }
+
+ private void readObject(ObjectInputStream in
+ ) throws IOException, ClassNotFoundException {
+ throw new NotSerializableException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public boolean isNaN() {
+ return Double.isNaN(source);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @internal CLDR
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ public boolean isInfinite() {
+ return Double.isInfinite(source);
+ }
+
+ // would be convenient to have getExponent, like the other methods
+ public int getExponent() {
+ return exponent;
+ }
+
+}
diff --git a/tools/java/com/ibm/icu/text/GenderInfo.java b/tools/java/com/ibm/icu/text/GenderInfo.java
index ad6ee7e..b611e2e 100644
--- a/tools/java/com/ibm/icu/text/GenderInfo.java
+++ b/tools/java/com/ibm/icu/text/GenderInfo.java
@@ -139,7 +139,7 @@
// TODO Get this data from a resource bundle generated from CLDR.
// For now, hard coded.
- private static Map<ULocale, ListGenderStyle> localeToListGender = new HashMap<ULocale, ListGenderStyle>();
+ private static Map<ULocale, ListGenderStyle> localeToListGender = new HashMap<>();
static {
for (String locale : Arrays.asList("ar", "ca", "cs", "hr", "es", "fr", "he", "hi", "it", "lt", "lv", "mr",
"nl", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "uk", "ur", "zh")) {
diff --git a/tools/java/com/ibm/icu/text/ListFormat.java b/tools/java/com/ibm/icu/text/ListFormat.java
index fd2ff92..9d645fe 100644
--- a/tools/java/com/ibm/icu/text/ListFormat.java
+++ b/tools/java/com/ibm/icu/text/ListFormat.java
@@ -135,7 +135,7 @@
// TODO Replace by use of RB
// Verify in building that all of the patterns contain {0}, {1}.
- static Map<ULocale, ListFormat> localeToData = new HashMap<ULocale, ListFormat>();
+ static Map<ULocale, ListFormat> localeToData = new HashMap<>();
static void add(String locale, String... data) {
localeToData.put(new ULocale(locale), new ListFormat(data[0], data[1], data[2], data[3]));
diff --git a/tools/java/com/ibm/icu/util/LocaleMatcher.java b/tools/java/com/ibm/icu/util/LocaleMatcher.java
index e0c301b..0423399 100644
--- a/tools/java/com/ibm/icu/util/LocaleMatcher.java
+++ b/tools/java/com/ibm/icu/util/LocaleMatcher.java
@@ -320,7 +320,7 @@
private void addFiltered(String desired, R3<ULocale, ULocale, Double> localeToMaxAndWeight) {
Set<R3<ULocale, ULocale, Double>> map = desiredLanguageToPossibleLocalesToMaxLocaleToData.get(desired);
if (map == null) {
- desiredLanguageToPossibleLocalesToMaxLocaleToData.put(desired, map = new LinkedHashSet<R3<ULocale, ULocale, Double>>());
+ desiredLanguageToPossibleLocalesToMaxLocaleToData.put(desired, map = new LinkedHashSet<>());
}
map.add(localeToMaxAndWeight);
if (DEBUG) {
@@ -328,8 +328,8 @@
}
}
- Set<Row.R3<ULocale, ULocale, Double>> localeToMaxLocaleAndWeight = new LinkedHashSet<Row.R3<ULocale, ULocale, Double>>();
- Map<String, Set<Row.R3<ULocale, ULocale, Double>>> desiredLanguageToPossibleLocalesToMaxLocaleToData = new LinkedHashMap<String, Set<Row.R3<ULocale, ULocale, Double>>>();
+ Set<Row.R3<ULocale, ULocale, Double>> localeToMaxLocaleAndWeight = new LinkedHashSet<>();
+ Map<String, Set<Row.R3<ULocale, ULocale, Double>>> desiredLanguageToPossibleLocalesToMaxLocaleToData = new LinkedHashMap<>();
// =============== Special Mapping Information ==============
@@ -377,7 +377,7 @@
static Pattern pattern = Pattern.compile(
"([a-z]{1,8}|\\*)"
+ "(?:[_-]([A-Z][a-z]{3}|\\*))?"
- + "(?:[_-]([A-Z]{2}|[0-9]{3}|\\*))?");
+ + "(?:[_-]([$]!?[a-zA-Z]+|[A-Z]{2}|[0-9]{3}|\\*))?");
public LocalePatternMatcher(String toMatch) {
Matcher matcher = pattern.matcher(toMatch);
@@ -429,6 +429,7 @@
return (region == null ? "*" : region);
}
+ @Override
public String toString() {
String result = getLanguage();
if (level != Level.language) {
@@ -483,7 +484,7 @@
@SuppressWarnings("unused")
private static final double maxUnequal_changeEqual = 0.75;
- LinkedHashSet<Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double>> scores = new LinkedHashSet<R3<LocalePatternMatcher, LocalePatternMatcher, Double>>();
+ LinkedHashSet<Row.R3<LocalePatternMatcher, LocalePatternMatcher, Double>> scores = new LinkedHashSet<>();
final Level level;
public ScoreData(Level level) {
@@ -536,6 +537,7 @@
return level.worst;
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder().append(level);
for (R3<LocalePatternMatcher, LocalePatternMatcher, Double> score : scores) {
@@ -544,6 +546,7 @@
return result.toString();
}
+ @Override
@SuppressWarnings("unchecked")
public ScoreData cloneAsThawed() {
try {
@@ -559,10 +562,12 @@
private volatile boolean frozen = false;
+ @Override
public ScoreData freeze() {
return this;
}
+ @Override
public boolean isFrozen() {
return frozen;
}
@@ -615,6 +620,7 @@
* @internal
* @deprecated This API is ICU internal only.
*/
+ @Override
@Deprecated
public String toString() {
return languageScores + "\n\t" + scriptScores + "\n\t" + regionScores;
@@ -744,6 +750,7 @@
* @internal
* @deprecated This API is ICU internal only.
*/
+ @Override
@Deprecated
public LanguageMatcherData cloneAsThawed() {
LanguageMatcherData result;
@@ -764,6 +771,7 @@
* @internal
* @deprecated This API is ICU internal only.
*/
+ @Override
@Deprecated
public LanguageMatcherData freeze() {
languageScores.freeze();
@@ -779,6 +787,7 @@
* @internal
* @deprecated This API is ICU internal only.
*/
+ @Override
@Deprecated
public boolean isFrozen() {
return frozen;
@@ -789,7 +798,7 @@
private static final LanguageMatcherData defaultWritten;
- private static HashMap<String, String> canonicalMap = new HashMap<String, String>();
+ private static HashMap<String, String> canonicalMap = new HashMap<>();
static {
canonicalMap.put("iw", "he");
diff --git a/tools/java/libs/gson-sources.jar b/tools/java/libs/gson-sources.jar
index a64f4e7..1e07df4 100644
--- a/tools/java/libs/gson-sources.jar
+++ b/tools/java/libs/gson-sources.jar
Binary files differ
diff --git a/tools/java/libs/gson-version.txt b/tools/java/libs/gson-version.txt
index 0eaa996..24fb605 100644
--- a/tools/java/libs/gson-version.txt
+++ b/tools/java/libs/gson-version.txt
@@ -1 +1 @@
-gson 2.8.5 2018-05-22
+gson 2.8.6 2019-10-04
diff --git a/tools/java/libs/gson.jar b/tools/java/libs/gson.jar
index 0d5baf3..4765c4a 100644
--- a/tools/java/libs/gson.jar
+++ b/tools/java/libs/gson.jar
Binary files differ
diff --git a/tools/java/libs/guava-sources.jar b/tools/java/libs/guava-sources.jar
index cbaee13..66dd8bd 100644
--- a/tools/java/libs/guava-sources.jar
+++ b/tools/java/libs/guava-sources.jar
Binary files differ
diff --git a/tools/java/libs/guava-version.txt b/tools/java/libs/guava-version.txt
index cc749ed..2db85c2 100644
--- a/tools/java/libs/guava-version.txt
+++ b/tools/java/libs/guava-version.txt
@@ -1 +1 @@
-guava 28.1 2019-08-28
+guava 29.0-jre 2020-04-13
diff --git a/tools/java/libs/guava.jar b/tools/java/libs/guava.jar
index 081cd11..e1fc179 100644
--- a/tools/java/libs/guava.jar
+++ b/tools/java/libs/guava.jar
Binary files differ
diff --git a/tools/java/libs/icu4j-src.jar b/tools/java/libs/icu4j-src.jar
index ff6059d..0852f85 100644
--- a/tools/java/libs/icu4j-src.jar
+++ b/tools/java/libs/icu4j-src.jar
Binary files differ
diff --git a/tools/java/libs/icu4j-version.txt b/tools/java/libs/icu4j-version.txt
index e754f91..3769e80 100644
--- a/tools/java/libs/icu4j-version.txt
+++ b/tools/java/libs/icu4j-version.txt
@@ -1 +1 @@
-icu4j b9d1ba87f545744f2b81f1f413484f55a0da3d2f 2020-04-14 (from maint/maint-67, ICU 67 post rc)
+icu4j 766088ddb360a3494acbd140cf6c2625008f6bbf 2020-10-21 (from maint/maint-68 branch)
diff --git a/tools/java/libs/icu4j.jar b/tools/java/libs/icu4j.jar
index 942b634..5ff19ab 100644
--- a/tools/java/libs/icu4j.jar
+++ b/tools/java/libs/icu4j.jar
Binary files differ
diff --git a/tools/java/libs/utilities-src.jar b/tools/java/libs/utilities-src.jar
index ebd553f..ab03668 100644
--- a/tools/java/libs/utilities-src.jar
+++ b/tools/java/libs/utilities-src.jar
Binary files differ
diff --git a/tools/java/libs/utilities.jar b/tools/java/libs/utilities.jar
index 35b0f5c..3285691 100644
--- a/tools/java/libs/utilities.jar
+++ b/tools/java/libs/utilities.jar
Binary files differ
diff --git a/tools/java/org/unicode/cldr/ant/CLDRBuild.java b/tools/java/org/unicode/cldr/ant/CLDRBuild.java
deleted file mode 100644
index 47bc489..0000000
--- a/tools/java/org/unicode/cldr/ant/CLDRBuild.java
+++ /dev/null
@@ -1,677 +0,0 @@
-package org.unicode.cldr.ant;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.unicode.cldr.ant.CLDRConverterTool.AliasDeprecates;
-import org.unicode.cldr.icu.ResourceSplitter.SplitInfo;
-import org.unicode.cldr.util.PatternCache;
-
-import com.ibm.icu.dev.tool.UOption;
-
-public class CLDRBuild extends Task {
- private String toolName;
- private String srcFile;
- private String destFile;
- private boolean noArgs;
- private List<Run> runs = new ArrayList<Run>();
-
- private UOption srcDir = UOption.SOURCEDIR();
- private UOption destDir = UOption.DESTDIR();
-
- private static class PatternFilter implements FileFilter {
- private final Pattern filePattern;
-
- public PatternFilter(String filePattern) {
- this.filePattern = filePattern == null ? null : PatternCache.get(filePattern);
- }
-
- public boolean accept(File pathname) {
- return filePattern != null && filePattern.matcher(pathname.getName()).matches();
- }
- }
-
- public static boolean matchesLocale(List<String> locales, String locale) {
- for (String localePattern : locales) {
- if (localePattern.equals(locale) || locale.matches(localePattern)) {
- return true;
- }
- }
- return false;
- }
-
- public Map<String, String> getLocalesList(Config config, String src, String dest) {
- File srcdir = new File(src);
- File[] srcFiles = srcdir.listFiles(new PatternFilter(srcFile));
- File destdir = new File(dest);
- File[] destFiles = destdir.listFiles(new PatternFilter(destFile));
-
- Map<String, String> ret = new TreeMap<String, String>();
-
- if (config != null) {
- List<InExclude> localesList = config.locales.localesList;
- for (InExclude inex : localesList) {
- for (File file : srcFiles) {
- String fileName = file.getName();
- if (inex.matchesFileName(fileName)) {
- if (inex.include) {
- ret.put(fileName, inex.draft);
- } else {
- ret.remove(fileName);
- }
- }
- }
- }
- } else {
- for (File file : srcFiles) {
- ret.put(file.getName(), ".*");
- }
- }
-
- // Only build the files that need to be built
- if (srcFile == null) {
- // Don't rebuild dstFiles that already exist
- for (File file : destFiles) {
- if (file.exists()) {
- ret.remove(file.getName());
- }
- }
- } else if (srcFiles.length > 0) {
- // Don't rebuild files that are newer than the corresponding source file
-
- // In the grand scheme of things, the number of files is relatively
- // small and n * m operations isn't noticeable, so don't optimize.
- // The previous code tried to optimize but the optimization was broken
- // so this performs about the same as before.
- for (File dstFile : destFiles) {
- String destName = stripExtension(dstFile.getName());
- for (File srcFile : srcFiles) {
- String srcName = stripExtension(srcFile.getName());
- if (srcName.equals(destName) && dstFile.lastModified() > srcFile.lastModified()) {
- ret.remove(srcFile.getName());
- }
- }
- }
- }
-
- if (ret.size() == 0 && destFiles.length == 1) {
- return null;
- }
-
- return ret;
- }
-
- public Set<String> getIncludedLocales(Config config) {
-
- Set<String> ret = new HashSet<String>();
- if (config != null) {
- List<InExclude> localesList = config.locales.localesList;
- for (InExclude inex : localesList) {
- if (inex.include) {
- for (String str : inex.locales) {
- ret.add(str);
- }
- }
- }
- }
- return ret;
- }
-
- private static String stripExtension(String fileName) {
- int index = fileName.lastIndexOf('.');
- return index == -1 ? fileName : fileName.substring(0, index);
- }
-
- static void exitWithException(Throwable t) {
- errln(t.getMessage());
- t.printStackTrace(System.err);
- System.exit(-1);
- }
-
- static void exitWithError(String msg) {
- errln(msg);
- System.exit(-1);
- }
-
- static void errln(String msg) {
- System.err.println("ERROR: " + msg);
- }
-
- static void warnln(String msg) {
- System.out.println("WARNING: " + msg);
- }
-
- static void infoln(String msg) {
- System.out.println("INFO: " + msg);
- }
-
- private String getDirString(Args runArgs, UOption key) {
- String value = runArgs.map.get("--" + key.longName);
- if (value == null) {
- value = runArgs.map.get("-" + key.shortName);
- }
- return value;
- }
-
- // The method executing the task
- @Override
- public void execute() throws BuildException {
- if (toolName == null) {
- throw new BuildException("Tool name not set");
- }
-
- try {
- for (Run run : runs) {
-
- Args runArgs = run.args;
-
- Set<String> includedLocales = getIncludedLocales(run.config);
- Map<String, String> localesMap = getLocalesList(
- run.config, getDirString(runArgs, srcDir), getDirString(runArgs, destDir));
- if (localesMap == null || (localesMap.size() == 0 && !noArgs)) {
- continue;
- }
-
- List<String> argList = new ArrayList<String>();
- StringBuilder printArgs = new StringBuilder();
- for (Map.Entry<String, String> e : runArgs.map.entrySet()) {
- String key = e.getKey();
- String value = e.getValue();
- printArgs.append(key).append(' ');
- argList.add(key);
- if (value != null && value.length() > 0) {
- printArgs.append(value).append(' ');
- argList.add(value);
- }
- }
-
- Object obj = createObject(toolName);
- if (!(obj instanceof CLDRConverterTool)) {
- exitWithError(toolName + " not a subclass of CLDRConverterTool!");
- }
-
- CLDRConverterTool tool = (CLDRConverterTool) obj;
- tool.setLocalesMap(localesMap);
- tool.setIncludedLocales(includedLocales);
-
- if (run.deprecates != null) {
- AliasDeprecates aliasDeprecates = new AliasDeprecates(
- run.deprecates.aliasList,
- run.deprecates.aliasLocaleList,
- run.deprecates.emptyLocaleList);
- tool.setAliasDeprecates(aliasDeprecates);
- }
-
- if (run.config != null) {
- if (run.config.paths != null) {
- tool.setPathList(run.config.paths.pathList);
- }
-
- if (run.config.ofb != null) {
- tool.setOverrideFallbackList(run.config.ofb.pathsList);
- }
- }
-
- if (run.remapper != null) {
- List<SplitInfo> infos = new ArrayList<SplitInfo>();
- for (Remap remap : run.remapper.remaps) {
- infos.add(new SplitInfo(remap.sourcePath, remap.targetDir, remap.targetPath));
- }
- tool.setSplitInfos(infos);
- }
-
- tool.processArgs(argList.toArray(new String[argList.size()]));
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private static Object createObject(String className) {
- Object object = null;
- try {
- Class<?> classDefinition = Class.forName(className);
- object = classDefinition.newInstance();
- } catch (InstantiationException e) {
- exitWithException(e);
- } catch (IllegalAccessException e) {
- exitWithException(e);
- } catch (ClassNotFoundException e) {
- exitWithException(e);
- } catch (Throwable t) {
- exitWithException(t);
- }
- return object;
- }
-
- public void addConfiguredRun(Run run) {
- runs.add(run);
- }
-
- public void setToolName(String name) {
- toolName = name;
- }
-
- public void setSrcFile(String sf) {
- srcFile = sf;
- }
-
- public void setDestFile(String df) {
- destFile = df;
- }
-
- public void setNoArgs(String bool) {
- noArgs = bool.equals("true");
- }
-
- public static class Run extends Task {
- String type;
- Args args;
- Config config;
- Deprecates deprecates;
- Remapper remapper;
-
- public void setType(String type) {
- this.type = type;
- }
-
- public void addConfiguredArgs(Args args) {
- this.args = args;
- }
-
- public void addConfiguredConfig(Config config) {
- this.config = config;
- }
-
- public void addConfiguredDeprecates(Deprecates deprecates) {
- this.deprecates = deprecates;
- }
-
- public void addConfiguredRemapper(Remapper remapper) {
- if (remapper.remaps.isEmpty()) {
- exitWithError("remaps must not be empty");
- }
- this.remapper = remapper;
- }
- }
-
- public static class Args extends Task {
- Map<String, String> map = new HashMap<String, String>();
-
- public void addConfiguredArg(Arg arg) {
- if (arg.name == null) {
- throw new IllegalArgumentException("argument missing name");
- }
- map.put(arg.name, arg.value);
- }
- }
-
- public static class Arg extends Task {
- String name;
- String value;
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- public static class Config extends Task {
- Locales locales;
- Paths paths;
- OverrideFallback ofb;
- String type;
-
- public void addConfiguredLocales(Locales loc) {
- if (locales != null) {
- exitWithError("Multiple <locales> elements not supported");
- }
- locales = loc;
- }
-
- public void addConfiguredPaths(Paths ps) {
- if (paths != null) {
- exitWithError("Multiple <paths> elements not supported");
- }
- paths = ps;
- }
-
- public void addConfiguredOverrideFallback(OverrideFallback ofb) {
- if (this.ofb != null) {
- exitWithError("Multiple <overrideFallback> elements not allowed!");
- }
- this.ofb = ofb;
- }
-
- public void setType(String type) {
- this.type = type;
- }
- }
-
- public static class Locales extends Task {
- List<InExclude> localesList = new ArrayList<InExclude>();
-
- public void addConfiguredInclude(Include include) {
- addInEx(include);
- }
-
- public void addConfiguredExclude(Exclude exclude) {
- addInEx(exclude);
- }
-
- private void addInEx(InExclude inex) {
- inex.validate();
- localesList.add(inex);
- }
- }
-
- public static class InExclude extends Task {
- static final List<String> ANY = Collections.emptyList();
-
- final boolean include;
- List<String> locales;
- String draft;
- String xpath;
- String alt;
-
- protected InExclude(boolean include) {
- this.include = include;
- }
-
- public void setDraft(String draft) {
- this.draft = draft;
- }
-
- public void setLocales(String locales) {
- if (".*".equals(locales)) {
- this.locales = ANY;
- } else {
- this.locales = Arrays.asList(locales.split("\\s+"));
- }
- }
-
- public void setXpath(String xpath) {
- this.xpath = xpath;
- }
-
- public void setAlt(String alt) {
- this.alt = alt;
- }
-
- void validate() {
- if (locales == null) {
- exitWithError("locales attribute not set for include/exclude element!");
- }
- }
-
- boolean matchesFileName(String fileName) {
- if (locales == ANY) {
- return true;
- }
- String localePattern = fileName.substring(0, fileName.indexOf(".xml"));
- return matchesLocale(locales, localePattern);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof InExclude)) {
- return false;
- }
-
- if (o == this) {
- return true;
- }
-
- InExclude rhs = (InExclude) o;
- return include == rhs.include &&
- equalLists(locales, rhs.locales) &&
- equalStrings(draft, rhs.draft) &&
- equalStrings(xpath, rhs.xpath) &&
- equalStrings(alt, rhs.alt);
- }
-
- @Override
- public int hashCode() {
- return hash(locales, hash(draft, hash(xpath, hash(alt, 0))));
- }
-
- private boolean equalStrings(String lhs, String rhs) {
- return lhs == rhs || (lhs != null && lhs.equals(rhs));
- }
-
- private <T> boolean equalLists(List<? extends T> lhs, List<? extends T> rhs) {
- return lhs == rhs || (lhs != null && lhs.equals(rhs));
- }
-
- private int hash(Object rhs, int hash) {
- return rhs == null ? hash : (hash * 31) ^ rhs.hashCode();
- }
- }
-
- public static class Include extends InExclude {
- public Include() {
- super(true);
- }
- }
-
- public static class Exclude extends InExclude {
- public Exclude() {
- super(false);
- }
- }
-
- public static class Deprecates extends Task {
- List<String> aliasLocaleList;
- List<String> emptyLocaleList;
- List<CLDRConverterTool.Alias> aliasList;
-
- public void addConfiguredAlias(Alias alias) {
- if (aliasList == null) {
- aliasList = new ArrayList<CLDRConverterTool.Alias>();
- }
- aliasList.add(new CLDRConverterTool.Alias(alias.from, alias.to, alias.xpath, alias.rbPath, alias.value));
- }
-
- public void addConfiguredEmptyLocale(EmptyLocale alias) {
- if (emptyLocaleList == null) {
- emptyLocaleList = new ArrayList<String>();
- }
- emptyLocaleList.add(alias.locale);
- }
-
- public void addConfiguredAliasLocale(AliasLocale alias) {
- if (aliasLocaleList == null) {
- aliasLocaleList = new ArrayList<String>();
- }
- aliasLocaleList.add(alias.locale);
- }
- }
-
- public static class Alias extends Task {
- String from;
- String to;
- // TODO(jchye): remove xpath field after old converter is deleted.
- String xpath;
- String rbPath;
- String value;
-
- public void setFrom(String from) {
- this.from = from;
- }
-
- public void setTo(String to) {
- this.to = to;
- }
-
- public void setXpath(String xpath) {
- this.xpath = xpath;
- }
-
- public void setRbPath(String rbPath) {
- this.rbPath = rbPath;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- public static class AliasLocale extends Task {
- String locale;
-
- public void setLocale(String locale) {
- this.locale = locale;
- }
- }
-
- public static class EmptyLocale extends Task {
- String locale;
- String list;
-
- public void setLocale(String locale) {
- this.locale = locale;
- }
-
- public void setList(String list) {
- this.list = list;
- }
- }
-
- public static class Paths extends Task {
- public String fallback;
- public String locales;
- public String draft;
-
- private List<Task> pathList = new ArrayList<Task>();
-
- public void addConfiguredInclude(Include include) {
- pathList.add(include);
- }
-
- public void addConfiguredExclude(Exclude exclude) {
- pathList.add(exclude);
- }
-
- public void setFallback(String fallback) {
- this.fallback = fallback;
- }
-
- public void setLocales(String locales) {
- this.locales = locales;
- }
-
- public void setDraft(String draft) {
- this.draft = draft;
- }
-
- public void addConfiguredCoverageLevel(CoverageLevel level) {
- level.validate();
- pathList.add(level);
- }
- }
-
- public static class CoverageLevel extends Task {
- public String group;
- public String level;
- public String locales;
- public String draft;
- public String org;
-
- public void setDraft(String draft) {
- this.draft = draft;
- }
-
- public void setLevel(String level) {
- this.level = level;
- }
-
- public void setLocales(String locales) {
- this.locales = locales;
- }
-
- public void setOrg(String org) {
- this.org = org;
- }
-
- public void setGroup(String group) {
- this.group = group;
- }
-
- void validate() {
- if ((group == null) != (org == null)) {
- exitWithError("Invalid specification of coverageLevel element; org && group not set!");
- }
-
- if (level == null) {
- exitWithError("Invalid specification of coverageLevel element; level not set!");
- }
- }
- }
-
- public static class OverrideFallback extends Task {
- List<Paths> pathsList = new ArrayList<Paths>();
-
- public void addConfiguredPaths(Paths paths) {
- pathsList.add(paths);
- }
- }
-
- public static class Remap extends Task {
- public String sourcePath;
- public String targetPath;
- public String targetDir;
-
- public void setSourcePath(String sourcePath) {
- this.sourcePath = sourcePath;
- }
-
- public void setTargetPath(String targetPath) {
- this.targetPath = targetPath;
- }
-
- public void setTargetDir(String targetDir) {
- this.targetDir = targetDir;
- }
- }
-
- public static class Remapper extends Task {
- public String baseDir;
- List<Remap> remaps = new ArrayList<Remap>();
-
- public void setBaseDir(String baseDir) {
- this.baseDir = baseDir;
- }
-
- public void addConfiguredRemap(Remap remap) {
- if (remap.sourcePath == null || remap.sourcePath.trim().isEmpty()) {
- exitWithError("remap source path must not be empty");
- }
- remap.sourcePath = remap.sourcePath.trim();
-
- if (remap.targetPath != null && remap.targetPath.trim().isEmpty()) {
- remap.targetPath = null;
- }
-
- if (remap.targetDir != null && remap.targetDir.trim().isEmpty()) {
- remap.targetDir = null;
- }
-
- remaps.add(remap);
- }
- }
-}
diff --git a/tools/java/org/unicode/cldr/ant/CLDRConverterTool.java b/tools/java/org/unicode/cldr/ant/CLDRConverterTool.java
deleted file mode 100644
index 687d958..0000000
--- a/tools/java/org/unicode/cldr/ant/CLDRConverterTool.java
+++ /dev/null
@@ -1,457 +0,0 @@
-package org.unicode.cldr.ant;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.tools.ant.Task;
-import org.unicode.cldr.ant.CLDRBuild.Paths;
-import org.unicode.cldr.icu.LDMLConstants;
-import org.unicode.cldr.icu.ResourceSplitter.SplitInfo;
-import org.unicode.cldr.util.CLDRConfig;
-import org.unicode.cldr.util.CoverageInfo;
-import org.unicode.cldr.util.Level;
-import org.unicode.cldr.util.StandardCodes;
-import org.unicode.cldr.util.XPathParts;
-import org.w3c.dom.Node;
-
-/**
- * All tools that would like to make use of CLDR Build process
- * through the ant plug-in should extend this class. For implementing
- * the processArgs method basically move the implementation of main into
- * this method and add code to deal with situation where localesMap field
- * is set, see {@link org.unicode.cldr.icu.LDML2ICUConverter#processArgs(String[])}.
- * The subclasses are also expected to invoke computeConvertibleXPaths method
- * for all the xpaths in the file that they are currently processing and at
- * every leaf node should verify if an XPath is convertible or not. Please see
- * {@link org.unicode.cldr.icu.LDML2ICUConverter#isNodeNotConvertible(Node, StringBuilder)}.
- *
- * @author ram
- *
- */
-public abstract class CLDRConverterTool {
- /**
- * Information from the deprecates build rules.
- */
- protected AliasDeprecates aliasDeprecates;
-
- /**
- * Map of locales that need to processed.
- * Key : locale name
- * Value: draft attribute
- */
- private Map<String, String> localesMap;
-
- private Set<String> includedLocales;
-
- /**
- * List of xpaths to include or exclude
- */
- protected List<Task> pathList;
-
- /**
- * Override fallbacks list
- */
- protected List<CLDRBuild.Paths> overrideFallbackList;
-
- /**
- * Information used by ResourceSplitter, if not null.
- */
- protected List<SplitInfo> splitInfos;
-
- /**
- * Object that holds information about aliases on the
- * <alias from="in" to="id" /> elements.
- *
- * @author ram
- *
- */
- public static class Alias {
- public final String from;
- public final String to;
- public final String xpath;
- public final String rbPath;
- public final String value;
-
- public Alias(String from, String to, String xpath, String rbPath, String value) {
- this.from = from;
- this.to = to;
- this.xpath = xpath;
- this.rbPath = rbPath;
- this.value = value;
- }
- }
-
- public static class AliasDeprecates {
- public final List<Alias> aliasList;
- public final List<String> aliasLocaleList;
- public final List<String> emptyLocaleList;
-
- public AliasDeprecates(List<Alias> aliasList, List<String> aliasLocaleList,
- List<String> emptyLocaleList) {
- this.aliasList = aliasList;
- this.aliasLocaleList = aliasLocaleList;
- this.emptyLocaleList = emptyLocaleList;
- }
- }
-
- /**
- * Process the arguments
- *
- * @param args
- */
- public abstract void processArgs(String[] args);
-
- /**
- * For support and interpretation of
- * <deprecates>
- * <alias from="no_NO_NY" to="nn_NO" />
- * <alias from="en_RH" to="en_ZW" />
- * <aliasLocale locale="zh_SG" />
- * <aliasLocale locale="zh_TW" />
- * <emptyLocale locale="hi_" />
- * <emptyLocale locale="zh_" />
- * </deprecates>
- */
- public void setAliasDeprecates(AliasDeprecates aliasDeprecates) {
- this.aliasDeprecates = aliasDeprecates;
- }
-
- /**
- *
- * @param map
- */
- public void setLocalesMap(Map<String, String> map) {
- localesMap = map;
- }
-
- public void setIncludedLocales(Set<String> set) {
- includedLocales = set;
- }
-
- /**
- * Sets the list of objects that contain information in
- * include and exclude elements
- *
- * <include xpath="//ldml/.* /dateTimeElements/.*" draft=".*"/>
- * <exclude xpath="//ldml/.* /language.*" preferAlt="proposed" draft=".*"/>
- *
- * @param list
- */
- public void setPathList(List<Task> list) {
- pathList = list;
- }
-
- /**
- * Set the fallback override list
- */
- public void setOverrideFallbackList(List<Paths> list) {
- // overrideFallbackList = list;
- }
-
- public void setSplitInfos(List<SplitInfo> infos) {
- this.splitInfos = Collections.unmodifiableList(infos);
- }
-
- protected Node mergeOverrideFallbackNodes(Node main, String locale) {
- // for (int i = 0; i < overrideFallbackList.size(); i++) {
- // CLDRBuild.Paths path = overrideFallbackList.get(i);
- // if (CLDRBuild.matchesLocale(path.locales, locale)){
- // //TODO write the merging algorithm
- // }
- // }
- return main;
- }
-
- /**
- * Computes the convertible xpaths by walking through the xpathList given and applying the rules
- * in children of <path> elements.
- *
- * @param xpathList
- * A sorted list of all xpaths for the current run
- * @param localeName
- * The name of locale being processed
- * @return an ArrayList of the computed convertible xpaths
- */
- protected List<String> computeConvertibleXPaths(
- List<String> xpathList, boolean exemplarsContainA_Z, String localeName,
- String supplementalDir) {
- /*
- * Assumptions:
- * 1. Vetted nodes do not have draft attribute
- * 2. Nodes with draft attribute set and alt atrribute not set do not have a vetted
- * counterpart
- * 3. Nodes with alt attribute may or may not have a draft attribute
- * 4. If no draft field is set in the preferences object assume vetted node is requested
- */
-
- // fast path
- String draft = getLocalesMap() == null ? null : getLocalesMap().get(localeName + ".xml");
- if (draft != null) {
- for (int i = 0; i < xpathList.size(); i++) {
- XPathParts parts = XPathParts.getFrozenInstance(xpathList.get(i));
- Map<String, String> attr = parts.getAttributes(parts.size() - 1);
- String draftVal = attr.get(LDMLConstants.DRAFT);
- String altVal = attr.get(LDMLConstants.ALT);
- if (draftVal != null && !draftVal.matches(draft)) {
- xpathList.remove(i);
- }
- // remove xpaths with alt attribute set
- if (altVal != null) {
- xpathList.remove(i);
- }
- }
- return xpathList;
- }
-
- if (pathList == null) {
- // include everything!
- return xpathList;
- }
-
- ArrayList<String> myXPathList = new ArrayList<String>(xpathList.size());
- StandardCodes sc = StandardCodes.make();
- // Instantiate CoverageInfo outside the loop
- CoverageInfo covInfo = CLDRConfig.getInstance().getCoverageInfo();
- // iterator of xpaths of the current CLDR file being processed
- // this map only contains xpaths of the leaf nodes
- for (int i = 0; i < xpathList.size(); i++) {
- String xpath = xpathList.get(i);
- XPathParts parts = XPathParts.getFrozenInstance(xpath);
- Map<String, String> attr = parts.getAttributes(parts.size() - 1);
-
- boolean include = false;
-
- for (Task obj : pathList) {
- if (obj instanceof CLDRBuild.CoverageLevel) {
- CLDRBuild.CoverageLevel level = (CLDRBuild.CoverageLevel) obj;
- if (level.locales != null) {
- List<String> localeList = Arrays.asList(level.locales.split("\\s+"));
- if (CLDRBuild.matchesLocale(localeList, localeName) == false) {
- continue;
- }
- }
-
- // process further only if the current locale is part of the given group and org
- if (level.group != null
- && !sc.isLocaleInGroup(localeName, level.group, level.org)) {
- continue;
- }
-
- Level cv = Level.get(level.level);
- // only include the xpaths that have the coverage level at least the coverage
- // level specified by the locale
- if (covInfo.getCoverageLevel(xpath, localeName).compareTo(cv) <= 0) {
- String draftVal = attr.get(LDMLConstants.DRAFT);
- if (level.draft != null) {
- if (draftVal == null
- && (level.draft.equals("false") || level.draft.equals(".*"))) {
- include = true;
- } else if (draftVal != null && draftVal.matches(level.draft)) {
- include = true;
- } else {
- include = false;
- }
- } else {
- if (draftVal == null) {
- include = true;
- }
- }
- }
- } else if (obj instanceof CLDRBuild.Exclude) {
- CLDRBuild.Exclude exc = (CLDRBuild.Exclude) obj;
- // fast path if locale attribute is set
- if (exc.locales != null
- && CLDRBuild.matchesLocale(exc.locales, localeName) == false) {
- continue;
- }
- if (exc.xpath != null && xpath.matches(exc.xpath)) {
- /*
- * Now starts struggle for figuring out which xpaths should be excluded
- * The following cases need to be handled:
- * 1. <exclude xpath="//ldml/localeDisplayNames/languages/.*" draft="false">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = true
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = false
- * 2. <exclude xpath="//ldml/localeDisplayNames/languages/.*" draft="true">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = false
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test'] then
- * include = true
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = true
- * 3. <exclude xpath="//ldml/localeDisplayNames/languages/.*" draft=".*">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = false
- * 4. <exclude xpath="//ldml/localeDisplayNames/languages/.*" draft="false" preferAlt='true'>
- * if xp of //ldml/localeDisplayNames/languages/language[@type='en' alt='.*'] exists then
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = true
- * else
- * apply rules for processing draft and alt attribute together.
- * else
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = false
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test'] then
- * include = true
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = true
- */
- String draftVal = attr.get(LDMLConstants.DRAFT);
- String altVal = attr.get(LDMLConstants.ALT);
- boolean altExc = false, draftExc = false;
- if (exc.alt == null && altVal == null) {
- altExc = true;
- } else if (exc.alt == null && altVal != null) {
- altExc = true;
- } else if (exc.alt != null && altVal == null) {
- altExc = false;
- } else {
- if (altVal.matches(exc.alt)) {
- altExc = true;
- }
- }
- if (exc.draft == null && draftVal == null) {
- draftExc = true;
- } else if (exc.draft != null && draftVal == null) {
- if ((exc.draft.equals("false") || exc.draft.equals(".*"))) {
- draftExc = true;
- }
- } else if (exc.draft == null && draftVal != null) {
- draftExc = false;
- } else {
- if (draftVal.matches(exc.draft)) {
- draftExc = true;
- }
- }
- if (altExc == true && draftExc == true) {
- include = false;
- }
- }
- } else if (obj instanceof CLDRBuild.Include) {
- CLDRBuild.Include inc = (CLDRBuild.Include) obj;
- // fast path if locale attribute is set
- if (inc.locales != null
- && CLDRBuild.matchesLocale(inc.locales, localeName) == false) {
- continue;
- }
- if (inc.xpath != null && xpath.matches(inc.xpath)) {
- /*
- * The following cases need to be handled:
- * 1. <include xpath="//ldml/localeDisplayNames/languages/.*" draft="false">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = false
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = true
- * 2. <include xpath="//ldml/localeDisplayNames/languages/.*" draft="true">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = true
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test'] then
- * include = false
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = false
- * 3. <include xpath="//ldml/localeDisplayNames/languages/.*" draft=".*">
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = true
- * 4. <include xpath="//ldml/localeDisplayNames/languages/.*" draft="false" preferAlt='true'>
- * if xp of //ldml/localeDisplayNames/languages/language[@type='en' alt='.*'] exists then
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test']
- * or xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = false
- * else
- * apply rules for processing draft and alt attribute together.
- * else
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en'] then
- * include = true
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='test'] then
- * include = false
- * if xp is //ldml/localeDisplayNames/languages/language[@type='en' and draft='true'] then
- * include = false
- */
- String draftVal = attr.get(LDMLConstants.DRAFT);
- String altVal = attr.get(LDMLConstants.ALT);
- boolean altInc = false;
- if (inc.alt == null && altVal == null) {
- altInc = true;
- } else if (inc.alt == null && altVal != null) {
- altInc = false;
- } else if (inc.alt != null && altVal == null) {
- // the current xpath does not have the alt attribute set
- // since the list is sorted we can be sure that if the
- // next xpath matches the current one and there is an alt
- // attibute available for this path, that next entry is
- // where we should expect to find it.
- // now check if next xpath contains alt attribute
- if (i + 1 < xpathList.size()) {
- String nxp = xpathList.get(i + 1);
- XPathParts nparts = XPathParts.getFrozenInstance(nxp);
- // make sure the type attribute is the same
- if (parts.isLike(nparts)) {
- Map<String, String> nattr = nparts.getAttributes(nparts.size() - 1);
- if (nattr != null) {
- altVal = nattr.get(LDMLConstants.ALT);
- if (altVal != null && altVal.matches(inc.alt)) {
- draftVal = nattr.get(LDMLConstants.DRAFT);
- xpath = nxp;
- i++;
- altInc = true;
- }
- }
- }
- }
- } else {
- if (altVal.matches(inc.alt)) {
- altInc = true;
- }
- }
- boolean draftInc = false;
- if (inc.draft == null && draftVal == null) {
- draftInc = true;
- } else if (inc.draft != null && draftVal == null) {
- if ((inc.draft.equals("false") || inc.draft.equals(".*"))) {
- draftInc = true;
- }
- } else if (inc.draft == null && draftVal != null) {
- draftInc = false;
- } else {
- if (draftVal.matches(inc.draft)) {
- draftInc = true;
- }
- }
- if (altInc == true && draftInc == true) {
- include = true;
- }
- }
- } else {
- System.err.println(
- "ERROR: computeConvertibleXPath method cannot handle object of type: "
- + obj.getClass().toString());
- }
- }
- if (include == true) {
- myXPathList.add(xpath);
- }
- }
-
- return myXPathList;
- }
-
- protected Map<String, String> getLocalesMap() {
- return localesMap;
- }
-
- protected Set<String> getIncludedLocales() {
- return includedLocales;
- }
-}
diff --git a/tools/java/org/unicode/cldr/ant/package.html b/tools/java/org/unicode/cldr/ant/package.html
deleted file mode 100644
index 4f44f0d..0000000
--- a/tools/java/org/unicode/cldr/ant/package.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-Copyright (C) 2004-2007, Unicode, Inc., International Business Machines Corporation, and others.
-For terms of use, see http://www.unicode.org/terms_of_use.html
--->
-</head>
-<body bgcolor="white">
- <h3>Terms of Use</h3>
- <pre>* All files Copyright (c) 2004-2007, Unicode Inc, and others. All Rights Reserved.
-* For terms of use, see <a
- href="http://unicode.org/copyright.html#Exhibit1">http://unicode.org/copyright.html#Exhibit1</a>
- </pre>
- <p> </p>
-</body>
-</html>
diff --git a/tools/java/org/unicode/cldr/draft/Array2D.java b/tools/java/org/unicode/cldr/draft/Array2D.java
index dbd7025..9b4b6a9 100644
--- a/tools/java/org/unicode/cldr/draft/Array2D.java
+++ b/tools/java/org/unicode/cldr/draft/Array2D.java
@@ -4,14 +4,14 @@
import java.util.ArrayList;
class Array2D<T> {
- private ArrayList<ArrayList<T>> data = new ArrayList<ArrayList<T>>();
+ private ArrayList<ArrayList<T>> data = new ArrayList<>();
private int columnSize;
void set(int row, int column, T value) {
ensureSize(data, row + 1);
ArrayList<T> rowList = data.get(row);
if (rowList == null) {
- data.set(row, rowList = new ArrayList<T>());
+ data.set(row, rowList = new ArrayList<>());
}
ensureSize(rowList, column + 1);
if (columnSize < rowList.size()) {
diff --git a/tools/java/org/unicode/cldr/draft/CharEncoder.java b/tools/java/org/unicode/cldr/draft/CharEncoder.java
index 3f89267..3125375 100644
--- a/tools/java/org/unicode/cldr/draft/CharEncoder.java
+++ b/tools/java/org/unicode/cldr/draft/CharEncoder.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.unicode.cldr.draft;
@@ -47,7 +47,7 @@
* the bytes
* converted, and fill in the destination. In either case, if isVerifyRoundtrip() then check that the roundtrip
* works.
- *
+ *
* @param codepoint
* @param destination
* @param offset
diff --git a/tools/java/org/unicode/cldr/draft/CharacterListCompressor.java b/tools/java/org/unicode/cldr/draft/CharacterListCompressor.java
index 10c7533..59a1cfb 100644
--- a/tools/java/org/unicode/cldr/draft/CharacterListCompressor.java
+++ b/tools/java/org/unicode/cldr/draft/CharacterListCompressor.java
@@ -14,13 +14,13 @@
/**
* Compresses list of Unicode character ranges given as starting and ending char
* into a Base88 string.
- *
+ *
* Compression usage:
* String encodedStr = base88EncodeList(List<Interval>);
- *
+ *
* Decompression usage:
* List<Interval> decodedStrList = base88DecodeList(encodedStr);
- *
+ *
* Interval has two integers - first, last - to represent the range.
*/
@@ -35,6 +35,7 @@
this.last = last;
}
+ @Override
public String toString() {
return "«" + first + "-" + last + "»";
}
@@ -54,7 +55,7 @@
public static List<Integer> unicode2Base88(int code) {
- List<Integer> list = new ArrayList<Integer>();
+ List<Integer> list = new ArrayList<>();
int rem = code % 88;
list.add(rem);
code = code / 88;
@@ -103,7 +104,7 @@
List<Integer> list = str2list(str);
int metawindowsize = 8;
- List<List<Integer>> result = new ArrayList<List<Integer>>();
+ List<List<Integer>> result = new ArrayList<>();
int i = 0;
while (i < list.size()) {
@@ -133,14 +134,14 @@
}
public static void addPair(List<List<Integer>> pairs, int value, int type) {
- List<Integer> pair = new ArrayList<Integer>();
+ List<Integer> pair = new ArrayList<>();
pair.add(value);
pair.add(type);
pairs.add(pair);
}
public static String encodeValueTypePairs2Base88(List<List<Integer>> pairs) {
- List<Integer> result = new ArrayList<Integer>();
+ List<Integer> result = new ArrayList<>();
for (int i = 0; i < pairs.size(); i++) {
List<Integer> pair = pairs.get(i);
result.addAll(compressPair2Base88(pair));
@@ -161,7 +162,7 @@
}
public static List<Integer> str2list(String str) {
- List<Integer> list = new ArrayList<Integer>();
+ List<Integer> list = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
int code = ascii.indexOf(ch);
@@ -189,7 +190,7 @@
// Value Type pairs -- Str Range List
public static List<List<Integer>> getValueTypePairsFromStrRangeList(List<Interval> ilist) {
- List<List<Integer>> result = new ArrayList<List<Integer>>();
+ List<List<Integer>> result = new ArrayList<>();
int lastCode = 0;
for (int i = 0; i < ilist.size(); i++) {
@@ -225,7 +226,7 @@
}
public static List<Interval> getStrRangeListFromValueTypePairs(List<List<Integer>> pairs) {
- ArrayList<Interval> result = new ArrayList<Interval>();
+ ArrayList<Interval> result = new ArrayList<>();
int lastCode = 0;
for (int i = 0; i < pairs.size(); i++) {
@@ -258,7 +259,7 @@
// Str Range List -- Range Str
public static List<Interval> getStrRangeListFromRangeStr(String str) {
- ArrayList<Interval> result = new ArrayList<Interval>();
+ ArrayList<Interval> result = new ArrayList<>();
final UCharacterIterator it = UCharacterIterator.getInstance(str);
int first;
diff --git a/tools/java/org/unicode/cldr/draft/CodePoints.java b/tools/java/org/unicode/cldr/draft/CodePoints.java
index 05cf6a3..1f324b6 100644
--- a/tools/java/org/unicode/cldr/draft/CodePoints.java
+++ b/tools/java/org/unicode/cldr/draft/CodePoints.java
@@ -2,7 +2,7 @@
/**
* Alternate way to iterate through code points
- *
+ *
* @author markdavis
*/
public final class CodePoints {
@@ -16,7 +16,7 @@
/**
* Set up the iterator.
- *
+ *
* @param s
*/
public CodePoints(CharSequence s) {
@@ -39,7 +39,7 @@
/**
* Get the next code point. False if at end of string. After successful next(), the codePoint field has the value.
- *
+ *
* @return
*/
public boolean next() {
@@ -61,20 +61,21 @@
/**
* After calling next(), if it comes back true, this contains the code point; if not, it has U+FFFF.
- *
+ *
* @return
*/
public int getCodePoint() {
return codePoint;
}
+ @Override
public String toString() {
return buffer.subSequence(0, position) + "|||" + buffer.subSequence(position, buffer.length());
}
/**
* When iterating over full strings, this method is the fastest (as long as the string is not huge).
- *
+ *
* @param s
* @return
*/
diff --git a/tools/java/org/unicode/cldr/draft/Compacter.java b/tools/java/org/unicode/cldr/draft/Compacter.java
index baf79f2..2f1fb6d 100644
--- a/tools/java/org/unicode/cldr/draft/Compacter.java
+++ b/tools/java/org/unicode/cldr/draft/Compacter.java
@@ -58,7 +58,7 @@
*/
public static List<String> decodeString(String encodedString) {
List<Interval> intermediate = CharacterListCompressor.base88DecodeList(encodedString);
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (Interval interval : intermediate) {
for (int i = interval.first; i <= interval.last; ++i) {
result.add(UTF16.valueOf(i));
@@ -68,7 +68,7 @@
}
private static List<Interval> codePointsToIntervals(Collection<String> set2) {
- List<Interval> result = new ArrayList<Interval>();
+ List<Interval> result = new ArrayList<>();
int first = -1;
int last = -1;
for (String item : set2) {
@@ -149,7 +149,7 @@
if (Compacter.useCibus) {
return decodeString(in);
}
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
int cp;
int first = 0;
for (int i = 0; i < in.length(); i += Character.charCount(cp)) {
diff --git a/tools/java/org/unicode/cldr/draft/CompoundTransform.java b/tools/java/org/unicode/cldr/draft/CompoundTransform.java
index 19b736d..d30c10a 100644
--- a/tools/java/org/unicode/cldr/draft/CompoundTransform.java
+++ b/tools/java/org/unicode/cldr/draft/CompoundTransform.java
@@ -7,7 +7,7 @@
/**
* Immutable class that does a compound transform
- *
+ *
* @author markdavis
*/
@@ -15,9 +15,10 @@
private final List<StringTransform> transforms;
public CompoundTransform(List<StringTransform> transforms) {
- this.transforms = new ArrayList<StringTransform>(transforms);
+ this.transforms = new ArrayList<>(transforms);
}
+ @Override
public String transform(String source) {
for (int i = 0; i < transforms.size(); ++i) {
source = transforms.get(i).transform(source);
@@ -25,6 +26,7 @@
return source;
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < transforms.size(); ++i) {
diff --git a/tools/java/org/unicode/cldr/draft/DraftUtils.java b/tools/java/org/unicode/cldr/draft/DraftUtils.java
deleted file mode 100644
index 60cdae4..0000000
--- a/tools/java/org/unicode/cldr/draft/DraftUtils.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.unicode.cldr.draft;
-
-import org.unicode.cldr.util.CLDRPaths;
-import org.unicode.cldr.util.CldrUtility;
-
-/**
- * Stuff used by the 'draft' class that doesn't belong in CLDR core.
- * @author srl
- *
- */
-public class DraftUtils {
-
- /**
- * This actually refers into the unicodetools project.
- */
- public static final String UCD_DIRECTORY = CldrUtility.getPath(CLDRPaths.SVN_DIRECTORY, "unicodetools/data/ucd/9.0.0-Update");
-
-}
diff --git a/tools/java/org/unicode/cldr/draft/EnumLookup.java b/tools/java/org/unicode/cldr/draft/EnumLookup.java
index 64aa912..ccf5d61 100644
--- a/tools/java/org/unicode/cldr/draft/EnumLookup.java
+++ b/tools/java/org/unicode/cldr/draft/EnumLookup.java
@@ -10,7 +10,7 @@
public class EnumLookup<T extends Enum<?>> {
private final String name;
- private final Map<String, T> map = new HashMap<String, T>();
+ private final Map<String, T> map = new HashMap<>();
private Transform<String, String> transform;
public static <T extends Enum<?>> EnumLookup<T> of(Class<T> className) {
@@ -20,7 +20,7 @@
@SuppressWarnings("unchecked")
public static <T extends Enum<?>> EnumLookup<T> of(Class<T> className, Transform<String, String> t, String from,
T to, Object... extras) {
- Map<String, T> newExtras = new HashMap<String, T>();
+ Map<String, T> newExtras = new HashMap<>();
newExtras.put(from, to);
for (int i = 0; i < extras.length; i += 2) {
newExtras.put(extras[i].toString(), (T) extras[i + 1]);
@@ -32,7 +32,7 @@
Map<String, T> extras) {
String name_ = className.getName();
int lastDot = name_.lastIndexOf('.');
- EnumLookup<T> result = new EnumLookup<T>(name_.substring(lastDot + 1));
+ EnumLookup<T> result = new EnumLookup<>(name_.substring(lastDot + 1));
try {
result.transform = t = t == null ? CLEAN : t;
diff --git a/tools/java/org/unicode/cldr/draft/ExemplarInfo.java b/tools/java/org/unicode/cldr/draft/ExemplarInfo.java
index 0e5fe79..c93506a 100644
--- a/tools/java/org/unicode/cldr/draft/ExemplarInfo.java
+++ b/tools/java/org/unicode/cldr/draft/ExemplarInfo.java
@@ -26,7 +26,7 @@
import com.ibm.icu.util.ULocale;
/**
- *
+ *
*/
public class ExemplarInfo {
@@ -46,7 +46,7 @@
private static UnicodeSetPrettyPrinter pp = new UnicodeSetPrettyPrinter();
- private static Map<String, ExemplarInfo> languageToExemplars = new TreeMap<String, ExemplarInfo>();
+ private static Map<String, ExemplarInfo> languageToExemplars = new TreeMap<>();
private static UnicodeSet az = new UnicodeSet("[a-z]").freeze();
static {
@@ -124,7 +124,7 @@
UnicodeSet auxiliariesX;
UnicodeSet exemplarScripts;
UnicodeSet auxiliaryScripts;
- UnicodeMap<String> educationLevels = new UnicodeMap<String>();
+ UnicodeMap<String> educationLevels = new UnicodeMap<>();
static Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
@@ -327,7 +327,7 @@
}
public static void main(String[] args) {
- Set<String> missingExemplars = new TreeSet<String>();
+ Set<String> missingExemplars = new TreeSet<>();
System.out.println(Charset.availableCharsets());
System.out.println(ExemplarInfo.make("ja", missingExemplars).getEducationLevel("\u4e00"));
diff --git a/tools/java/org/unicode/cldr/draft/ExtractCountItems.java b/tools/java/org/unicode/cldr/draft/ExtractCountItems.java
index 9377b5e..ffa58d1 100644
--- a/tools/java/org/unicode/cldr/draft/ExtractCountItems.java
+++ b/tools/java/org/unicode/cldr/draft/ExtractCountItems.java
@@ -32,7 +32,7 @@
Factory factory = testInfo.getCldrFactory();
static class SampleData {
- EnumMap<Count, String> countToString = new EnumMap<Count, String>(Count.class);
+ EnumMap<Count, String> countToString = new EnumMap<>(Count.class);
Relation<String, Count> stringToCount = Relation.of(new HashMap<String, Set<Count>>(), HashSet.class);
String basePath;
@@ -46,6 +46,7 @@
return stringToCount.size();
}
+ @Override
public String toString() {
return countToString.toString();
}
@@ -55,7 +56,7 @@
}
}
- Map<String, SampleData> samples = new LinkedHashMap<String, SampleData>();
+ Map<String, SampleData> samples = new LinkedHashMap<>();
public static void main(String[] args) {
@@ -63,8 +64,8 @@
}
void gatherData() {
- Set<String> singletonLanguages = new LinkedHashSet<String>();
- Map<String, Map<String, SampleData>> defectiveLocales = new LinkedHashMap<String, Map<String, SampleData>>();
+ Set<String> singletonLanguages = new LinkedHashSet<>();
+ Map<String, Map<String, SampleData>> defectiveLocales = new LinkedHashMap<>();
for (String locale : factory.getAvailableLanguages()) {
Map<String, Level> locale_status = StandardCodes.make().getLocaleToLevel(Organization.google);
@@ -87,7 +88,7 @@
}
CLDRFile cldr = factory.make(locale, true);
- Map<String, SampleData> data = new LinkedHashMap<String, SampleData>();
+ Map<String, SampleData> data = new LinkedHashMap<>();
SampleData sampleData = getSamples(cldr, keywordCount, "//ldml/units/unit", data);
if (sampleData == null) {
// try currencies
@@ -115,13 +116,13 @@
for (String s : keywords) {
realKeywords.add(Count.valueOf(s));
}
- Set<Pair<Count, Count>> missingPairs = new HashSet<Pair<Count, Count>>();
+ Set<Pair<Count, Count>> missingPairs = new HashSet<>();
for (Count i : realKeywords) {
for (Count j : realKeywords) {
if (i.compareTo(j) >= 0) {
continue;
}
- missingPairs.add(new Pair<Count, Count>(i, j));
+ missingPairs.add(new Pair<>(i, j));
}
}
showMinimalPairs(missingPairs, entry.getValue());
@@ -158,7 +159,7 @@
}
String value = cldr.getStringValue(path).toLowerCase(Locale.ENGLISH);
// get the path without the count = basepath
- XPathParts parts = XPathParts.getInstance(path); // not frozen, setAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); // not frozen, setAttribute
Count count = PluralInfo.Count.valueOf(parts.getAttributeValue(-1, "count"));
parts.setAttribute(-1, "count", null);
String basePath = parts.toString();
diff --git a/tools/java/org/unicode/cldr/draft/FileUtilities.java b/tools/java/org/unicode/cldr/draft/FileUtilities.java
index 7345857..2da3047 100644
--- a/tools/java/org/unicode/cldr/draft/FileUtilities.java
+++ b/tools/java/org/unicode/cldr/draft/FileUtilities.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.draft;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPathString;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
@@ -19,6 +21,7 @@
import java.util.regex.Pattern;
import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.With;
import org.unicode.cldr.util.With.SimpleIterator;
@@ -48,7 +51,7 @@
File file = dir.length() == 0 ? new File(filename) : new File(dir, filename);
if (SHOW_FILES && log != null) {
log.println("Opening File: "
- + file.getCanonicalPath());
+ + getNormalizedPathString(file));
}
return new BufferedReader(
new InputStreamReader(
@@ -64,8 +67,7 @@
public static PrintWriter openWriter(String dir, String filename, String encoding) throws IOException {
File file = new File(dir, filename);
if (SHOW_FILES && log != null) {
- log.println("Creating File: "
- + file.getCanonicalPath());
+ log.println("Creating File: " + getNormalizedPathString(file));
}
String parentName = file.getParent();
if (parentName != null) {
@@ -85,6 +87,7 @@
protected abstract boolean handleLine(int lineCount, int start, int end, String[] items);
+ @Override
protected void handleEnd() {
}
@@ -124,7 +127,7 @@
/**
* Return false to abort
- *
+ *
* @param lineCount
* @param line
* @return
@@ -204,7 +207,7 @@
in.close();
handleEnd();
} catch (Exception e) {
- throw (RuntimeException) new ICUUncheckedIOException(lineCount + ":\t" + line, e);
+ throw new ICUUncheckedIOException(lineCount + ":\t" + line, e);
}
return this;
}
@@ -241,15 +244,15 @@
return bufferedReader;
} catch (Exception e) {
String className = class1 == null ? null : class1.getCanonicalName();
- String canonicalName = null;
+ String normalizedPath = null;
try {
String relativeFileName = getRelativeFileName(class1, "../util/");
- canonicalName = new File(relativeFileName).getCanonicalPath();
+ normalizedPath = getNormalizedPathString(relativeFileName);
} catch (Exception e1) {
throw new ICUUncheckedIOException("Couldn't open file: " + file + "; relative to class: "
+ className, e);
}
- throw new ICUUncheckedIOException("Couldn't open file " + file + "; in path " + canonicalName + "; relative to class: "
+ throw new ICUUncheckedIOException("Couldn't open file " + file + "; in path " + normalizedPath + "; relative to class: "
+ className, e);
}
}
@@ -285,7 +288,7 @@
// each item is of the form abc...
// or "..." (required if a comma or quote is contained)
// " in a field is represented by ""
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
StringBuilder item = new StringBuilder();
boolean inQuote = false;
for (int i = 0; i < line.length(); ++i) {
@@ -442,9 +445,9 @@
* for (String s : FileUtilities.in(directory,name)) {
* ...
* }
- *
+ *
* @author markdavis
- *
+ *
*/
public static Iterable<String> in(Class<?> class1, String file) {
return With.in(new FileLines(openFile(class1, file, UTF8)));
@@ -455,9 +458,9 @@
* for (String s : FileUtilities.in(directory,name)) {
* ...
* }
- *
+ *
* @author markdavis
- *
+ *
*/
public static Iterable<String> in(Class<?> class1, String file, Charset charset) {
return With.in(new FileLines(openFile(class1, file, charset)));
@@ -468,9 +471,9 @@
* for (String s : FileUtilities.in(directory,name)) {
* ...
* }
- *
+ *
* @author markdavis
- *
+ *
*/
public static Iterable<String> in(String directory, String file) {
return With.in(new FileLines(openFile(directory, file, UTF8)));
@@ -481,9 +484,9 @@
* for (String s : FileUtilities.in(directory,name)) {
* ...
* }
- *
+ *
* @author markdavis
- *
+ *
*/
public static Iterable<String> in(BufferedReader reader) {
return With.in(new FileLines(reader));
@@ -494,9 +497,9 @@
* for (String s : FileUtilities.in(directory,name)) {
* ...
* }
- *
+ *
* @author markdavis
- *
+ *
*/
public static Iterable<String> in(String directory, String file, Charset charset) {
return With.in(new FileLines(openFile(directory, file, charset)));
@@ -546,7 +549,7 @@
public interface LineHandler {
/**
* Return false if line was skipped
- *
+ *
* @param line
* @return
*/
diff --git a/tools/java/org/unicode/cldr/draft/FilteredTransform.java b/tools/java/org/unicode/cldr/draft/FilteredTransform.java
index 45ab8fe..9e88425 100644
--- a/tools/java/org/unicode/cldr/draft/FilteredTransform.java
+++ b/tools/java/org/unicode/cldr/draft/FilteredTransform.java
@@ -4,9 +4,9 @@
/**
* Immutable filtered transform
- *
+ *
* @author markdavis
- *
+ *
*/
public abstract class FilteredTransform implements StringTransform {
private final StringTransform transform;
@@ -15,6 +15,7 @@
transform = result;
}
+ @Override
public String transform(String source) {
int last = 0;
// TODO optimize later
@@ -38,6 +39,7 @@
/**
* Subclasses will modify
*/
+ @Override
public String toString() {
return transform.toString();
}
diff --git a/tools/java/org/unicode/cldr/draft/GapString.java b/tools/java/org/unicode/cldr/draft/GapString.java
index 2277faa..fd818a2 100644
--- a/tools/java/org/unicode/cldr/draft/GapString.java
+++ b/tools/java/org/unicode/cldr/draft/GapString.java
@@ -6,7 +6,7 @@
* that such changes are generally not random; instead they tend to happen more often in either nearby or successive
* locations.
* The structure of the class keeps 2 buffers; one for the front and one for the end.
- *
+ *
* @author markdavis
*/
// TODO investigate whether keeping the future in reverse order is the right approach in terms of performance.
@@ -24,6 +24,7 @@
insert(0, s);
}
+ @Override
public char charAt(int index) {
try {
return buffer[index < pastLength ? index : index + gapLength];
@@ -32,15 +33,18 @@
}
}
+ @Override
public int length() {
return buffer.length - gapLength;
}
+ @Override
public CharSequence subSequence(int start, int end) {
// TODO optimize this
return toString().subSequence(start, end);
}
+ @Override
public String toString() {
StringBuilder b = new StringBuilder();
// check to see whether second argument is length or count
@@ -210,6 +214,7 @@
return this;
}
+ @Override
public boolean equals(Object other) {
try {
return equals((CharSequence) other);
@@ -239,6 +244,7 @@
return true;
}
+ @Override
public int hashCode() {
int result = 0;
int i = 0;
diff --git a/tools/java/org/unicode/cldr/draft/GenerateLanguageData.java b/tools/java/org/unicode/cldr/draft/GenerateLanguageData.java
index a333795..c039292 100644
--- a/tools/java/org/unicode/cldr/draft/GenerateLanguageData.java
+++ b/tools/java/org/unicode/cldr/draft/GenerateLanguageData.java
@@ -19,7 +19,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.OfficialStatus;
import org.unicode.cldr.util.SupplementalDataInfo.PopulationData;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.text.NumberFormat;
public class GenerateLanguageData {
@@ -39,10 +39,10 @@
private void run() throws IOException {
try (PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY + "langData/", "generatedLanguageData.txt")) {
- Counter2<String> langToPopulation = new Counter2<String>();
+ Counter2<String> langToPopulation = new Counter2<>();
// Counter2<String> langToGDP = new Counter2<String>();
LanguageTagParser ltp = new LanguageTagParser();
- Map<String, String> languageNameToCode = new TreeMap<String, String>();
+ Map<String, String> languageNameToCode = new TreeMap<>();
for (String languageCode : info.getLanguages()) {
languageNameToCode.put(english.getName(languageCode), languageCode);
}
@@ -131,8 +131,8 @@
String lang = entry.getKey();
out.println(fixLang(lang)
- + "\t" + (top.size() < 6 ? CollectionUtilities.join(top, ", ")
- : CollectionUtilities.join(top.subList(0, 5), ", ") + ", …"));
+ + "\t" + (top.size() < 6 ? Joiner.on(", ").join(top)
+ : Joiner.on(", ").join(top.subList(0, 5)) + ", …"));
missing.remove(lang);
}
for (String lang : missing) {
diff --git a/tools/java/org/unicode/cldr/draft/IdentifierInfo.java b/tools/java/org/unicode/cldr/draft/IdentifierInfo.java
index 627163d..587b645 100644
--- a/tools/java/org/unicode/cldr/draft/IdentifierInfo.java
+++ b/tools/java/org/unicode/cldr/draft/IdentifierInfo.java
@@ -26,7 +26,7 @@
* <li>call getRestrictionLevel to see what the UTS36 restriction level is. (This has some proposed changes from the
* current one, however.)
* </ol>
- *
+ *
* @author markdavis
* @internal
*/
@@ -63,7 +63,7 @@
private String identifier;
private final BitSet requiredScripts = new BitSet();
- private final Set<BitSet> scriptSetSet = new HashSet<BitSet>();
+ private final Set<BitSet> scriptSetSet = new HashSet<>();
private final BitSet commonAmongAlternates = new BitSet();
private final UnicodeSet numerics = new UnicodeSet();
private final UnicodeSet identifierProfile = new UnicodeSet(0, 0x10FFFF);
@@ -149,7 +149,7 @@
public static boolean isMultiScript(String identifier) {
// Non-optimized code, for simplicity
- Set<BitSet> setOfScriptSets = new HashSet<BitSet>();
+ Set<BitSet> setOfScriptSets = new HashSet<>();
BitSet temp = new BitSet();
int cp;
for (int i = 0; i < identifier.length(); i += Character.charCount(i)) {
@@ -213,7 +213,7 @@
}
public Set<BitSet> getAlternates() {
- Set<BitSet> result = new HashSet<BitSet>();
+ Set<BitSet> result = new HashSet<>();
for (BitSet item : scriptSetSet) {
result.add((BitSet) item.clone());
}
@@ -323,7 +323,7 @@
}
public static Set<BitSet> parseAlternates(String scriptsSetString) {
- Set<BitSet> result = new HashSet<BitSet>();
+ Set<BitSet> result = new HashSet<>();
for (String item : scriptsSetString.trim().split("\\s*;\\s*")) {
if (!item.isEmpty()) {
result.add(parseScripts(item));
@@ -334,7 +334,7 @@
/**
* Test containment. Should be a method on BitSet...
- *
+ *
* @param container
* @param containee
* @return
@@ -350,7 +350,7 @@
/**
* Sets a number of values at once. Should be on BitSet.
- *
+ *
* @param container
* @param containee
* @return
diff --git a/tools/java/org/unicode/cldr/draft/IntDistanceNode.java b/tools/java/org/unicode/cldr/draft/IntDistanceNode.java
index 3cbae27..4aee3ef 100644
--- a/tools/java/org/unicode/cldr/draft/IntDistanceNode.java
+++ b/tools/java/org/unicode/cldr/draft/IntDistanceNode.java
@@ -24,6 +24,7 @@
this.distanceTable = distanceTable;
}
+ @Override
public IntDistanceNode.IntDistanceTable getDistanceTable() {
return distanceTable;
}
@@ -49,8 +50,8 @@
}
static class IntDistanceTable extends DistanceTable {
- private static final IdMakerFull[] ids = { new IdMakerFull<String>("lang", XLocaleDistance.ANY), new IdMakerFull<String>("script", XLocaleDistance.ANY),
- new IdMakerFull<String>("region", XLocaleDistance.ANY) };
+ private static final IdMakerFull[] ids = { new IdMakerFull<>("lang", XLocaleDistance.ANY), new IdMakerFull<>("script", XLocaleDistance.ANY),
+ new IdMakerFull<>("region", XLocaleDistance.ANY) };
private static final IdMakerFull<IntDistanceNode.IntDistanceTable> cache = new IdMakerFull<>("table");
private final IdMakerFull<String> id;
@@ -93,7 +94,7 @@
distanceNodes[desired][supported] = node;
}
}
- // now, to make star work,
+ // now, to make star work,
// copy all the zero columns/rows down to any null value
for (int row = 0; row < size; ++row) {
for (int column = 0; column < size; ++column) {
@@ -131,7 +132,6 @@
if (!id.equals(other.id)) {
return false;
}
- ;
return Arrays.deepEquals(distanceNodes, other.distanceNodes);
}
diff --git a/tools/java/org/unicode/cldr/draft/Iterables.java b/tools/java/org/unicode/cldr/draft/Iterables.java
index d5f244b..18466e9 100644
--- a/tools/java/org/unicode/cldr/draft/Iterables.java
+++ b/tools/java/org/unicode/cldr/draft/Iterables.java
@@ -9,7 +9,7 @@
public final class Iterables<T> implements Iterable<T>, Iterator<T> {
- private List<Iterator<T>> iterators = new ArrayList<Iterator<T>>();
+ private List<Iterator<T>> iterators = new ArrayList<>();
private Iterator<T> current = null;
private int position = 0;
@@ -30,11 +30,11 @@
}
public <S> Iterables<T> and(Transform<S, T> transform, Iterator<S> iteratorsIn) {
- return and(new TransformIterator<S, T>(transform, iteratorsIn));
+ return and(new TransformIterator<>(transform, iteratorsIn));
}
public <S> Iterables<T> and(Transform<S, T> transform, Iterable<S> iteratorsIn) {
- return and(new TransformIterator<S, T>(transform, iteratorsIn.iterator()));
+ return and(new TransformIterator<>(transform, iteratorsIn.iterator()));
}
public <S> Iterables<T> and(Transform<S, T> transform, S... iteratorsIn) {
@@ -67,10 +67,12 @@
// return new Iterables<T>().and(iteratorsIn);
// }
+ @Override
public Iterator<T> iterator() {
return this;
}
+ @Override
public boolean hasNext() {
while (current != null) {
if (current.hasNext()) {
@@ -86,10 +88,12 @@
return false;
}
+ @Override
public T next() {
return current.next();
}
+ @Override
public void remove() {
current.remove();
}
@@ -104,14 +108,17 @@
this.transform = transform;
}
+ @Override
public boolean hasNext() {
return iterator.hasNext();
}
+ @Override
public T next() {
return transform.transform(iterator.next());
}
+ @Override
public void remove() {
iterator.remove();
}
diff --git a/tools/java/org/unicode/cldr/draft/JsonConverter.java b/tools/java/org/unicode/cldr/draft/JsonConverter.java
index 373628e..2ea13b9 100644
--- a/tools/java/org/unicode/cldr/draft/JsonConverter.java
+++ b/tools/java/org/unicode/cldr/draft/JsonConverter.java
@@ -37,9 +37,9 @@
// //CldrUtility.MAIN_DIRECTORY;
private static final String OUT_DIRECTORY = CLDRPaths.GEN_DIRECTORY + "/jason/"; // CldrUtility.MAIN_DIRECTORY;
private static boolean COMPACT = false;
- static final Set<String> REPLACING_BASE = !COMPACT ? Collections.EMPTY_SET : new HashSet<String>(
+ static final Set<String> REPLACING_BASE = !COMPACT ? Collections.EMPTY_SET : new HashSet<>(
Arrays.asList("type id key count".split("\\s")));
- static final Set<String> EXTRA_DISTINGUISHING = new HashSet<String>(
+ static final Set<String> EXTRA_DISTINGUISHING = new HashSet<>(
Arrays.asList("locales territory desired supported".split("\\s")));
static final Relation<String, String> mainInfo = ElementAttributeInfo.getInstance(DtdType.ldml)
.getElement2Attributes();
@@ -49,7 +49,7 @@
public static void main(String[] args) throws IOException {
final String subdirectory = new File(MAIN_DIRECTORY).getName();
final Factory cldrFactory = Factory.make(MAIN_DIRECTORY, FILES);
- final Set<String> locales = new TreeSet<String>(cldrFactory.getAvailable());
+ final Set<String> locales = new TreeSet<>(cldrFactory.getAvailable());
/*
* TODO: "parts" is always empty, so all the code using it is wasted!
*/
@@ -64,7 +64,7 @@
final String xpath = it.next();
final String fullXpath = file.getFullXPath(xpath);
String value = file.getStringValue(xpath);
- XPathParts oldParts = XPathParts.getInstance(fullXpath); // not frozen, rewrite can modify
+ XPathParts oldParts = XPathParts.getFrozenInstance(fullXpath).cloneAsThawed(); // not frozen, rewrite can modify
if (dtdType == null) {
dtdType = DtdType.valueOf(parts.getElement(0));
}
@@ -230,6 +230,7 @@
suffix.append('$').append(attribute).append('=').append(attributeValue);
}
+ @Override
public String toString() {
if (suffix == null) {
return base;
@@ -309,6 +310,7 @@
return result.append('"');
}
+ @Override
public String toString() {
return print(new StringBuilder(), 0).toString();
}
@@ -342,12 +344,13 @@
super(parent);
}
- private Map<String, Item> map = new LinkedHashMap<String, Item>();
+ private Map<String, Item> map = new LinkedHashMap<>();
public Item get(String element) {
return map.get(element);
}
+ @Override
public void put(String element, String value) {
Item old = map.get(element);
if (old != null) {
@@ -362,6 +365,7 @@
map.put(element, new StringItem(value));
}
+ @Override
public Item makeSubItem(String element, Type ordered) {
Item result = map.get(element);
if (result != null) {
@@ -374,6 +378,7 @@
return result;
}
+ @Override
public Appendable print(Appendable result, int i) {
try {
if (map.size() == 0) {
@@ -412,7 +417,7 @@
super(parent);
}
- private List<Row.R2<String, Item>> list = new ArrayList<Row.R2<String, Item>>();
+ private List<Row.R2<String, Item>> list = new ArrayList<>();
@Override
public Appendable print(Appendable result, int i) {
@@ -443,12 +448,14 @@
}
}
+ @Override
public Item makeSubItem(String element, Type ordered) {
Item result = create(ordered);
list.add(Row.of(element, result));
return result;
}
+ @Override
public void put(String element, String value) {
list.add(Row.of(element, (Item) new StringItem(value)));
}
diff --git a/tools/java/org/unicode/cldr/draft/Keyboard.java b/tools/java/org/unicode/cldr/draft/Keyboard.java
index 5030433..3fde460 100644
--- a/tools/java/org/unicode/cldr/draft/Keyboard.java
+++ b/tools/java/org/unicode/cldr/draft/Keyboard.java
@@ -22,13 +22,13 @@
import org.unicode.cldr.util.XMLFileReader.SimpleHandler;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.text.UnicodeSet;
/**
* A first, very rough cut at reading the keyboard data.
* Every public structure is immutable, eg all returned maps, sets.
- *
+ *
* @author markdavis
*/
public class Keyboard {
@@ -113,7 +113,7 @@
// }
public static Set<String> getPlatformIDs() {
- Set<String> results = new LinkedHashSet<String>();
+ Set<String> results = new LinkedHashSet<>();
File file = new File(BASE);
for (String f : file.list())
if (!f.equals("dtd") && !f.startsWith(".") && !f.startsWith("_")) {
@@ -123,7 +123,7 @@
}
public static Set<String> getKeyboardIDs(String platformId) {
- Set<String> results = new LinkedHashSet<String>();
+ Set<String> results = new LinkedHashSet<>();
File base = new File(BASE + platformId + "/");
for (String f : base.list())
if (f.endsWith(".xml") && !f.startsWith(".") && !f.startsWith("_")) {
@@ -183,7 +183,7 @@
.read(fileName, -1, true);
return keyboardHandler.getKeyboard();
} catch (Exception e) {
- throw new KeyboardException(fileName + "\n" + CollectionUtilities.join(errors, ", "), e);
+ throw new KeyboardException(fileName + "\n" + Joiner.on(", ").join(errors), e);
}
}
@@ -265,6 +265,7 @@
return gestures;
}
+ @Override
public String toString() {
return "{" + output + "," + transformStatus + ", " + gestures + "}";
}
@@ -287,6 +288,7 @@
return iso2output;
}
+ @Override
public String toString() {
return "{" + modifiers + "," + iso2output + "}";
}
@@ -300,7 +302,7 @@
}
public Map<String, String> getMatch(String prefix) {
- Map<String, String> results = new LinkedHashMap<String, String>();
+ Map<String, String> results = new LinkedHashMap<>();
for (Entry<String, String> entry : string2string.entrySet()) {
String key = entry.getKey();
if (key.startsWith(prefix)) {
@@ -380,8 +382,9 @@
private static class PlatformHandler extends SimpleHandler {
String id;
- Map<String, Iso> hardwareMap = new HashMap<String, Iso>();
+ Map<String, Iso> hardwareMap = new HashMap<>();
+ @Override
public void handlePathValue(String path, @SuppressWarnings("unused") String value) {
XPathParts parts = XPathParts.getFrozenInstance(path);
// <platform id='android'/>
@@ -394,7 +397,7 @@
Iso.valueOf(parts.getAttributeValue(2, "iso")));
}
}
- };
+ }
public Platform getPlatform() {
return new Platform(id, hardwareMap);
@@ -410,22 +413,22 @@
private static class KeyboardHandler extends SimpleHandler {
Set<Exception> errors; // = new LinkedHashSet<Exception>();
- Set<String> errors2 = new LinkedHashSet<String>();
+ Set<String> errors2 = new LinkedHashSet<>();
// doesn't do any error checking for collisions, etc. yet.
String locale; // TODO
String version; // TODO
String platformVersion; // TODO
- Set<String> names = new LinkedHashSet<String>();
+ Set<String> names = new LinkedHashSet<>();
Fallback fallback = Fallback.BASE;
KeyboardModifierSet keyMapModifiers = null;
- Map<Iso, Output> iso2output = new EnumMap<Iso, Output>(Iso.class);
- Set<KeyMap> keyMaps = new LinkedHashSet<KeyMap>();
+ Map<Iso, Output> iso2output = new EnumMap<>(Iso.class);
+ Set<KeyMap> keyMaps = new LinkedHashSet<>();
TransformType currentType = null;
Map<String, String> currentTransforms = null;
- Map<TransformType, Transforms> transformMap = new EnumMap<TransformType, Transforms>(TransformType.class);
+ Map<TransformType, Transforms> transformMap = new EnumMap<>(TransformType.class);
LanguageTagParser ltp = new LanguageTagParser();
@@ -443,6 +446,7 @@
return new Keyboard(locale, version, platformVersion, names, fallback, keyMaps, transformMap);
}
+ @Override
public void handlePathValue(String path, @SuppressWarnings("unused") String value) {
try {
XPathParts parts = XPathParts.getFrozenInstance(path);
@@ -477,7 +481,7 @@
if (keyMapModifiers != null) {
addToKeyMaps();
}
- iso2output = new LinkedHashMap<Iso, Output>();
+ iso2output = new LinkedHashMap<>();
keyMapModifiers = newMods;
}
String isoString = parts.getAttributeValue(2, "iso");
@@ -496,7 +500,7 @@
transformMap.put(currentType, new Transforms(currentTransforms));
}
currentType = type;
- currentTransforms = new LinkedHashMap<String, String>();
+ currentTransforms = new LinkedHashMap<>();
}
final String from = fixValue(parts.getAttributeValue(2, "from"));
final String to = fixValue(parts.getAttributeValue(2, "to"));
@@ -563,7 +567,7 @@
public Output getOutput(XPathParts parts) {
String chars = null;
TransformStatus transformStatus = TransformStatus.DEFAULT;
- Map<Gesture, List<String>> gestures = new EnumMap<Gesture, List<String>>(Gesture.class);
+ Map<Gesture, List<String>> gestures = new EnumMap<>(Gesture.class);
for (Entry<String, String> attributeAndValue : parts.getAttributes(-1).entrySet()) {
String attribute = attributeAndValue.getKey();
@@ -581,7 +585,7 @@
} else if (attribute.equals("iso") || attribute.equals("base")) {
// ignore, handled above
} else {
- LinkedHashSet<String> list = new LinkedHashSet<String>();
+ LinkedHashSet<String> list = new LinkedHashSet<>();
for (String item : attributeValue.trim().split(" ")) {
final String fixedValue = fixValue(item);
if (fixedValue.isEmpty()) {
@@ -591,14 +595,14 @@
list.add(fixedValue);
}
gestures.put(Gesture.fromString(attribute),
- Collections.unmodifiableList(new ArrayList<String>(list)));
+ Collections.unmodifiableList(new ArrayList<>(list)));
if (DEBUG) {
System.out.println("\tgesture=" + attribute + ";\tto=" + list + ";");
}
}
}
return new Output(chars, gestures, transformStatus);
- };
+ }
}
public static class KeyboardException extends RuntimeException {
diff --git a/tools/java/org/unicode/cldr/draft/KeyboardModifierSet.java b/tools/java/org/unicode/cldr/draft/KeyboardModifierSet.java
index 6ca2aee..43f1979 100644
--- a/tools/java/org/unicode/cldr/draft/KeyboardModifierSet.java
+++ b/tools/java/org/unicode/cldr/draft/KeyboardModifierSet.java
@@ -20,21 +20,21 @@
* This definition can be expanded across multiple combinations. For example {@code optR+caps? cmd+shift} gets
* transformed into {@code optR+caps, optR,
* cmd+shiftL, cmd+shiftR, cmd+shiftL+shiftR} .
- *
+ *
* <h1>Usage</h1>
* <p>
* There is a 1 to 1 relationship between a {@link KeyboardModifierSet} and a particular key map (a mapping from
* physical keys to their output).
- *
+ *
* <pre>
- * {@code
+ * {@code
* // Create the set from the XML modifier=".." attribute
- * ModifierSet modifierSet = ModifierSet.parseSet(<modifier=".." value from XML>);
+ * ModifierSet modifierSet = ModifierSet.parseSet(<modifier=".." value from XML>);
* // Test if this set is active for a particular input combination provided by the keyboard
* modifierSet.contains(<some combination to test>);
* }
* </pre>
- *
+ *
* @author [email protected] (Raymond Wainman)
*/
public class KeyboardModifierSet {
@@ -45,7 +45,7 @@
cmd, ctrlL, ctrlR, caps, altL, altR, optL, optR, shiftL, shiftR;
}
- static final SetComparator<Modifier> SINGLETON_COMPARATOR = new SetComparator<Modifier>();
+ static final SetComparator<Modifier> SINGLETON_COMPARATOR = new SetComparator<>();
/** Initial input string */
private final String input;
@@ -54,14 +54,14 @@
/**
* Private constructor. See factory {@link #parseSet} method.
- *
+ *
* @param variants
* A set containing all possible variants of the combination
* provided in the input string.
*/
private KeyboardModifierSet(String input, Set<EnumSet<Modifier>> variants) {
this.input = input;
- Set<Set<Modifier>> safe = new TreeSet<Set<Modifier>>(SINGLETON_COMPARATOR);
+ Set<Set<Modifier>> safe = new TreeSet<>(SINGLETON_COMPARATOR);
for (EnumSet<Modifier> item : variants) {
safe.add(Collections.unmodifiableSet(item));
}
@@ -70,7 +70,7 @@
/**
* Return all possible variants for this combination.
- *
+ *
* @return Set containing all possible variants.
*/
public Set<Set<Modifier>> getVariants() {
@@ -79,7 +79,7 @@
/**
* Determines if the given combination is valid within this set.
- *
+ *
* @param combination
* A combination of Modifier elements.
* @return True if the combination is valid, false otherwise.
@@ -118,7 +118,7 @@
* </ul>
* <p>
* The '?' symbol appended to some modifiers indicates that this modifier is optional (it can be ON or OFF).
- *
+ *
* @param input
* String representing the sets of modifier sets. This string
* must match the format defined in the LDML Keyboard Standard.
@@ -133,7 +133,7 @@
}
String modifierSetInputs[] = input.trim().split(" ");
- Set<EnumSet<Modifier>> variants = new HashSet<EnumSet<Modifier>>();
+ Set<EnumSet<Modifier>> variants = new HashSet<>();
for (String modifierSetInput : modifierSetInputs) {
variants.addAll(parseSingleSet(modifierSetInput));
}
@@ -146,7 +146,7 @@
* containing all possible variants for that particular modifier set.
* <p>
* For example {@code alt+caps+cmd?} gets expanded into {@code alt+caps+cmd?, alt+caps} .
- *
+ *
* @param input
* The input string representing the modifiers. This String must
* match the format defined in the LDML Keyboard Standard.
@@ -164,13 +164,13 @@
String modifiers[] = input.trim().split("\\+");
- List<EnumSet<Modifier>> variants = new ArrayList<EnumSet<Modifier>>();
+ List<EnumSet<Modifier>> variants = new ArrayList<>();
variants.add(EnumSet.noneOf(Modifier.class)); // Add an initial set
// which is empty
// Trivial case
if (input.isEmpty()) {
- return new HashSet<EnumSet<Modifier>>(variants);
+ return new HashSet<>(variants);
}
for (String modifier : modifiers) {
@@ -183,7 +183,7 @@
// Keep a collection of the new variants that need to be added
// while iterating over the
// existing ones
- Set<EnumSet<Modifier>> newVariants = new HashSet<EnumSet<Modifier>>();
+ Set<EnumSet<Modifier>> newVariants = new HashSet<>();
for (EnumSet<Modifier> variant : variants) {
// A parent key gets exploded into {Left, Right, Left+Right}
// or {Left, Right, Left+Right,
@@ -228,7 +228,7 @@
// Don't care case, make a copy of the existing variants and add
// the new key to it.
else {
- List<EnumSet<Modifier>> newVariants = new ArrayList<EnumSet<Modifier>>();
+ List<EnumSet<Modifier>> newVariants = new ArrayList<>();
for (EnumSet<Modifier> variant : variants) {
EnumSet<Modifier> newVariant = EnumSet.copyOf(variant);
newVariant.add(modifierElement);
@@ -239,7 +239,7 @@
}
}
- return new HashSet<EnumSet<Modifier>>(variants);
+ return new HashSet<>(variants);
}
/**
@@ -260,7 +260,7 @@
/**
* Determines if the String passed in is a valid parent key.
- *
+ *
* @param modifier
* The modifier string to verify.
* @return True if it is a parent key, false otherwise.
diff --git a/tools/java/org/unicode/cldr/draft/MainCache.java b/tools/java/org/unicode/cldr/draft/MainCache.java
index 9dd2284..6518bc6 100644
--- a/tools/java/org/unicode/cldr/draft/MainCache.java
+++ b/tools/java/org/unicode/cldr/draft/MainCache.java
@@ -4,13 +4,13 @@
import java.util.Map;
public abstract class MainCache {
- private static Map<Class<?>, Map<Object, Object>> cache = new HashMap<Class<?>, Map<Object, Object>>();
+ private static Map<Class<?>, Map<Object, Object>> cache = new HashMap<>();
protected synchronized Object get(Object key) {
Class<?> classKey = this.getClass();
Map<Object, Object> submap = cache.get(classKey);
if (submap == null) {
- cache.put(classKey, submap = new HashMap<Object, Object>());
+ cache.put(classKey, submap = new HashMap<>());
}
Object result = submap.get(key);
if (result == null) {
diff --git a/tools/java/org/unicode/cldr/draft/Misc.java b/tools/java/org/unicode/cldr/draft/Misc.java
index aa8337e..25c3a41 100644
--- a/tools/java/org/unicode/cldr/draft/Misc.java
+++ b/tools/java/org/unicode/cldr/draft/Misc.java
@@ -26,7 +26,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.BasicLanguageData;
import org.unicode.cldr.util.Timer;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.lang.UCharacter;
@@ -62,7 +62,7 @@
String[] locales = "zh en es hi fr ar pt ru id bn ur ja de fil sw pa jv ko tr vi it te mr th fa ta pl lah gu my ms uk zh_Hant kn su ml nl az or ro uz bho ps ha ku mad yo ig si mg sd hu am om kk el ne be mai sr cs km as sv mag mwr sn ny ca bg hne tg bgc ii he dcc ug fuv qu rw min af zu mn bjn so ki hr ak tk fi sq da bya sk gn bal nb lua xh bs ht syl ka bjj ban sat hy za luy rn bug bem luo wtm st lo gl ti shn ceb ks mfa ace lt ky bm lg shi tn bcl glk war kok bew kln kam umb bo suk ee kmb ay pam bhk sas bbc swv nso tpi rjb gbm lmn ff kab sl ts ba cv kri gon ndc guz wo tzm mak kfy ln ljp mk efi ibb doi awa mos nyn vmw mer kru lv sid pag gno sck tcy wbq nd lrc ss cgg brh xog nn sg xnr dyu rmt teo kxm mdh hno lu eu khn wbr tsg rej rif brx ilo kbd et ce kg fy hil kj cy ast av ve udm ga tt sah myv tet gaa ady mt dv fj nr is mdf kum kha sm kpv lez pap krc inh oc se tyv zdj dz bi gag to koi lbe mi ab os ty kl gil iu ch fo rm mh chk haw pon lb pau tvl sa kos na ho yap gd uli niu la tkl eo kl"
.split(" ");
SupplementalDataInfo sdi = SupplementalDataInfo.getInstance();
- Set<String> scripts = new LinkedHashSet<String>();
+ Set<String> scripts = new LinkedHashSet<>();
for (String locale : locales) {
Set<BasicLanguageData> items = sdi.getBasicLanguageData(locale);
if (items == null) {
@@ -88,7 +88,7 @@
} else if (locale.equals("zh_Hant")) {
scripts.add("Hant");
}
- System.out.println(locale + "\t" + CollectionUtilities.join(scripts, " "));
+ System.out.println(locale + "\t" + Joiner.on(" ").join(scripts));
}
StringTransform unicode = Transliterator.getInstance("hex/unicode");
@@ -237,7 +237,7 @@
LanguageTagParser ltp = new LanguageTagParser();
String[] locales = "en ru nl en-GB fr de it pl pt-BR es tr th ja zh-CN zh-TW ko ar bg sr uk ca hr cs da fil fi hu id lv lt no pt-PT ro sk sl es-419 sv vi el iw fa hi am af et is ms sw zu bn mr ta eu fr-CA gl zh-HK ur gu kn ml te"
.split(" ");
- Set<String> nameAndInfo = new TreeSet<String>(info.getCollator());
+ Set<String> nameAndInfo = new TreeSet<>(info.getCollator());
for (String localeCode : locales) {
String baseLanguage = ltp.set(localeCode).getLanguage();
R2<List<String>, String> temp = lang2replacement.get(baseLanguage);
diff --git a/tools/java/org/unicode/cldr/draft/NormalizedIdentifierParser.java b/tools/java/org/unicode/cldr/draft/NormalizedIdentifierParser.java
index 6a2d206..ac8e0b2 100644
--- a/tools/java/org/unicode/cldr/draft/NormalizedIdentifierParser.java
+++ b/tools/java/org/unicode/cldr/draft/NormalizedIdentifierParser.java
@@ -17,18 +17,18 @@
Illegal, NameContinueNFC, NameContinueOther, NameStartNFC, NameStartOther, Whitespace, Other
}
- static final UnicodeSet XmlNameStartChar = (UnicodeSet) new UnicodeSet("[\\: A-Z _ a-z " +
+ static final UnicodeSet XmlNameStartChar = new UnicodeSet("[\\: A-Z _ a-z " +
"\\u00C0-\\u00D6 \\u00D8-\\u00F6 \\u00F8-\\u02FF \\u0370-\\u037D \\u037F-\\u1FFF \\u200C-\\u200D" +
"\\u2070-\\u218F \\u2C00-\\u2FEF \\u3001-\\uD7FF \\uF900-\\uFDCF \\uFDF0-\\uFFFD \\U00010000-\\U000EFFFF]")
.freeze();
- static final UnicodeSet XmlNameContinueChar = (UnicodeSet) new UnicodeSet(
+ static final UnicodeSet XmlNameContinueChar = new UnicodeSet(
"[- . 0-9 \\u00B7 \\u0300-\\u036F \\u203F-\\u2040]").freeze();
- static final UnicodeSet XmlNameChar = (UnicodeSet) new UnicodeSet(XmlNameStartChar).addAll(XmlNameContinueChar)
+ static final UnicodeSet XmlNameChar = new UnicodeSet(XmlNameStartChar).addAll(XmlNameContinueChar)
.freeze();
- static final UnicodeSet XmlWhiteSpace = (UnicodeSet) new UnicodeSet("[\\u0009\\u000D\\u000A\\u0020]").freeze();
- static final UnicodeSet XmlIllegal = (UnicodeSet) new UnicodeSet(
+ static final UnicodeSet XmlWhiteSpace = new UnicodeSet("[\\u0009\\u000D\\u000A\\u0020]").freeze();
+ static final UnicodeSet XmlIllegal = new UnicodeSet(
"[^\\u0009\\u000D\\u000A\\u0020-\uD7FF\\uE000-\\uFFFD\\U00010000-\\U000EFFFF]").freeze();
- static final UnicodeSet NfcSafe = (UnicodeSet) new UnicodeSet("[:nfkcqc=yes:]").freeze();
+ static final UnicodeSet NfcSafe = new UnicodeSet("[:nfkcqc=yes:]").freeze();
private String input;
private int endPosition;
@@ -141,7 +141,7 @@
}
static void showDiffs() {
- Map<Status, Map<Status, UnicodeSet>> map = new TreeMap<Status, Map<Status, UnicodeSet>>();
+ Map<Status, Map<Status, UnicodeSet>> map = new TreeMap<>();
NormalizedIdentifierParser parser = new NormalizedIdentifierParser();
for (int codePoint = 0; codePoint <= 0x10FFFF; ++codePoint) {
String source = new StringBuilder().appendCodePoint(codePoint).toString();
@@ -153,7 +153,7 @@
}
Map<Status, UnicodeSet> map2 = map.get(sourceStatus);
if (map2 == null) {
- map.put(sourceStatus, map2 = new TreeMap<Status, UnicodeSet>());
+ map.put(sourceStatus, map2 = new TreeMap<>());
}
UnicodeSet set = map2.get(targetStatus);
if (set == null) {
diff --git a/tools/java/org/unicode/cldr/draft/Parser.java b/tools/java/org/unicode/cldr/draft/Parser.java
index 4292a86..6a92c89 100644
--- a/tools/java/org/unicode/cldr/draft/Parser.java
+++ b/tools/java/org/unicode/cldr/draft/Parser.java
@@ -5,13 +5,13 @@
/**
* @author markdavis
- *
+ *
*/
public interface Parser<T, S extends CharSequence> {
/**
* Parses text from the beginning of the given string to produce an object.
* The method may not use the entire text of the given string.
- *
+ *
* @param source
* A <code>String</code> whose beginning should be parsed.
* @return An <code>Object</code> parsed from the string.
@@ -30,7 +30,7 @@
* be used to indicate the starting point for the next call to this method. If an error occurs, then the index of
* <code>pos</code> is not changed, the error index of <code>pos</code> is set to the index of the character where
* the error occurred, and null is returned.
- *
+ *
* @param source
* A <code>String</code>, part of which should be parsed.
* @param pos
diff --git a/tools/java/org/unicode/cldr/draft/PatternFixer.java b/tools/java/org/unicode/cldr/draft/PatternFixer.java
index 1b6c7bc..42c7ed4 100644
--- a/tools/java/org/unicode/cldr/draft/PatternFixer.java
+++ b/tools/java/org/unicode/cldr/draft/PatternFixer.java
@@ -21,7 +21,7 @@
* TODO be sensitive to COMMENTS
* <p>
* TODO add support for (?#)
- *
+ *
* @author markdavis
*/
public class PatternFixer {
@@ -37,7 +37,7 @@
/**
* Create for particular regex target.
- *
+ *
* @param target
*/
public PatternFixer(Target target) {
@@ -50,11 +50,11 @@
private enum State {
BASE, HAVE_SLASH, HAVE_Q, HAVE_Q_SLASH
- };
+ }
/**
* Produce a modified pattern that fixes character classes. (See class description.)
- *
+ *
* @param regexPattern
* @param patternOptions
* @return
diff --git a/tools/java/org/unicode/cldr/draft/RegexTransform.java b/tools/java/org/unicode/cldr/draft/RegexTransform.java
index 8d23163..60dafce 100644
--- a/tools/java/org/unicode/cldr/draft/RegexTransform.java
+++ b/tools/java/org/unicode/cldr/draft/RegexTransform.java
@@ -7,7 +7,7 @@
/**
* Immutable class that performs transformations
- *
+ *
* @author markdavis
*/
public class RegexTransform implements com.ibm.icu.text.StringTransform {
@@ -16,13 +16,13 @@
private final List<Rule>[] buckets = new List[BUCKETSIZE];
public RegexTransform(List<Rule> rules2) {
- rules = new ArrayList<Rule>(rules2);
+ rules = new ArrayList<>(rules2);
// we now fill the buckets with rules, in order, that might match that bucket.
for (int i = 0; i < BUCKETSIZE; ++i) {
- buckets[i] = new ArrayList<Rule>();
+ buckets[i] = new ArrayList<>();
}
- List<Matcher> matchers = new ArrayList<Matcher>();
+ List<Matcher> matchers = new ArrayList<>();
for (Rule rule : rules) {
matchers.add(rule.getPostmatcher(""));
}
@@ -40,7 +40,7 @@
/**
* right now, this doesn't do anything; later we can optimize by picking just those rules that could match
- *
+ *
* @param toProcess
* @return
*/
@@ -54,10 +54,12 @@
return rules.iterator();
}
+ @Override
public String transform(String text) {
return new RegexTransformState(this, text).toString();
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < rules.size(); ++i) {
diff --git a/tools/java/org/unicode/cldr/draft/RegexTransformBuilder.java b/tools/java/org/unicode/cldr/draft/RegexTransformBuilder.java
index 5f9d103..1187706 100644
--- a/tools/java/org/unicode/cldr/draft/RegexTransformBuilder.java
+++ b/tools/java/org/unicode/cldr/draft/RegexTransformBuilder.java
@@ -19,12 +19,12 @@
// initially just very rough rule parser, for proof-of-concept
public static StringTransform createFromRules(String string) {
- List<StringTransform> compound = new ArrayList<StringTransform>();
+ List<StringTransform> compound = new ArrayList<>();
- List<Rule> rules = new ArrayList<Rule>();
+ List<Rule> rules = new ArrayList<>();
String[] ruleSet = string.split(";");
Matcher m = RULE_PATTERN.matcher("");
- List<String> results = new ArrayList<String>();
+ List<String> results = new ArrayList<>();
Matcher variable = VARIABLE.matcher("");
UnicodeSet filter = null;
diff --git a/tools/java/org/unicode/cldr/draft/RegexTransformState.java b/tools/java/org/unicode/cldr/draft/RegexTransformState.java
index 9b5d7de..5118c66 100644
--- a/tools/java/org/unicode/cldr/draft/RegexTransformState.java
+++ b/tools/java/org/unicode/cldr/draft/RegexTransformState.java
@@ -58,7 +58,7 @@
/**
* return true if the rule matches at offset in text, without touching text before start or after finish
- *
+ *
* @param text
* @param offset
* @param start
@@ -112,6 +112,7 @@
return Status.MATCH;
}
+ @Override
public String toString() {
return processedAlready.toString();
}
diff --git a/tools/java/org/unicode/cldr/draft/Rule.java b/tools/java/org/unicode/cldr/draft/Rule.java
index 308582d..a60160d 100644
--- a/tools/java/org/unicode/cldr/draft/Rule.java
+++ b/tools/java/org/unicode/cldr/draft/Rule.java
@@ -9,7 +9,7 @@
private final Pattern prematch;
private final boolean prematchFindAtEnd;
private final Pattern postmatch;
- private final List<Item> results = new ArrayList<Item>();
+ private final List<Item> results = new ArrayList<>();
/**
* if negative, is position before start position; otherwise is position relative to end of replacement.
* To put *at* the start position, put a CURSOR at the start of the results.
@@ -19,7 +19,7 @@
/**
* contains a replacement text with a set of replacements (up to 10) plus a new cursor point
- *
+ *
* @author markdavis
*/
// TODO add function calls &foo(....)
@@ -35,10 +35,12 @@
replacement = s;
}
+ @Override
public String compose(Matcher prematcher, Matcher postmatcher) {
return replacement;
}
+ @Override
public String toString() {
return replacement;
}
@@ -53,10 +55,12 @@
post = b;
}
+ @Override
public String compose(Matcher prematcher, Matcher postmatcher) {
return post ? postmatcher.group(number) : prematcher.group(number);
}
+ @Override
public String toString() {
return "$" + number;
}
@@ -65,10 +69,12 @@
public static class CursorItem implements Item {
static Item CURSOR = new CursorItem();
+ @Override
public String compose(Matcher prematcher, Matcher postmatcher) {
throw new UnsupportedOperationException();
}
+ @Override
public String toString() {
return "|";
}
@@ -101,7 +107,7 @@
/**
* Modifies result, returns new cursor
- *
+ *
* @param result
* @param offset
* @param matcher
@@ -123,6 +129,7 @@
: result.length() + outOfBoundsCursor;
}
+ @Override
public String toString() {
String main = postmatch.toString();
return (prematch == null ? "" : prematch.toString())
diff --git a/tools/java/org/unicode/cldr/draft/ScriptMetadata.java b/tools/java/org/unicode/cldr/draft/ScriptMetadata.java
index 1355a94..0beb56f 100644
--- a/tools/java/org/unicode/cldr/draft/ScriptMetadata.java
+++ b/tools/java/org/unicode/cldr/draft/ScriptMetadata.java
@@ -19,7 +19,7 @@
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.With;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Transform;
@@ -46,7 +46,7 @@
"Origin Country"), DENSITY("~Density"), LANG_CODE, HAS_CASE("Has Case?");
int columnNumber = -1;
- final Set<String> names = new HashSet<String>();
+ final Set<String> names = new HashSet<>();
Column(String... alternateNames) {
names.add(this.name());
@@ -172,7 +172,7 @@
density = Column.DENSITY.getInt(items, -1);
final String countryRaw = Column.ORIGIN_COUNTRY.getItem(items);
- String country = CountryCodeConverter.getCodeFromName(countryRaw);
+ String country = CountryCodeConverter.getCodeFromName(countryRaw, false);
// NAME_TO_REGION_CODE.get(countryRaw.toUpperCase(Locale.ENGLISH));
if (country == null) {
errors.add("Can't map " + countryRaw + " to country/region");
@@ -209,6 +209,7 @@
.replace("RTL", "YES");
}
+ @Override
public String toString() {
return rank
+ "\tSample: " + sampleChar
@@ -238,11 +239,11 @@
}
}
- public static Set<String> errors = new LinkedHashSet<String>();
- static HashMap<String, Integer> titleToColumn = new HashMap<String, Integer>();
+ public static Set<String> errors = new LinkedHashSet<>();
+ static HashMap<String, Integer> titleToColumn = new HashMap<>();
private static class MyFileReader extends SemiFileReader {
- private Map<String, Info> data = new HashMap<String, Info>();
+ private Map<String, Info> data = new HashMap<>();
@Override
protected boolean isCodePoint() {
@@ -252,7 +253,7 @@
@Override
protected String[] splitLine(String line) {
return CldrUtility.splitCommaSeparated(line);
- };
+ }
@Override
protected boolean handleLine(int lineCount, int start, int end, String[] items) {
@@ -299,7 +300,7 @@
private Map<String, Info> getData() {
if (!errors.isEmpty()) {
- throw new RuntimeException(CollectionUtilities.join(errors, "\n\t"));
+ throw new RuntimeException(Joiner.on("\n\t").join(errors));
}
return Collections.unmodifiableMap(data);
}
@@ -385,7 +386,7 @@
return data.entrySet();
}
- /**
+ /**
* Specialized scripts
* @return
*/
diff --git a/tools/java/org/unicode/cldr/draft/ShortestCanonicalForm.java b/tools/java/org/unicode/cldr/draft/ShortestCanonicalForm.java
index a3c4eb5..bd77a4c 100644
--- a/tools/java/org/unicode/cldr/draft/ShortestCanonicalForm.java
+++ b/tools/java/org/unicode/cldr/draft/ShortestCanonicalForm.java
@@ -21,10 +21,10 @@
static final UnicodeSet leading = new UnicodeSet();
static final UnicodeSet leading3 = new UnicodeSet();
static StringComparator cpCompare = new UTF16.StringComparator(true, false, 0);
- static final Map<Integer, Set<String>> leadToTrail = new TreeMap<Integer, Set<String>>();
+ static final Map<Integer, Set<String>> leadToTrail = new TreeMap<>();
static UnicodeSet skip = new UnicodeSet(
"[[:hangulsyllabletype=l:][:hangulsyllabletype=v:][:hangulsyllabletype=t:]]");
- static Map<String, String> restoreExclusions = new TreeMap<String, String>();
+ static Map<String, String> restoreExclusions = new TreeMap<>();
static UnicodeSet breakingTrail = new UnicodeSet();
static {
@@ -49,7 +49,7 @@
trailing.addAll(trailingString);
Set<String> trails = leadToTrail.get(first);
if (trails == null) {
- leadToTrail.put(first, trails = new TreeSet<String>(cpCompare));
+ leadToTrail.put(first, trails = new TreeSet<>(cpCompare));
}
trails.add(trailingString);
if (UScript.getScript(i) != UScript.HANGUL
@@ -127,10 +127,12 @@
end = UCharacter.charCount(string.codePointAt(start));
}
+ @Override
public boolean hasNext() {
return start < string.length();
}
+ @Override
public String next() {
String result = string.substring(start, end);
if (end < string.length()) {
@@ -144,6 +146,7 @@
return result;
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
diff --git a/tools/java/org/unicode/cldr/draft/StateMachine.java b/tools/java/org/unicode/cldr/draft/StateMachine.java
index ceb6cd2..061c232 100644
--- a/tools/java/org/unicode/cldr/draft/StateMachine.java
+++ b/tools/java/org/unicode/cldr/draft/StateMachine.java
@@ -39,6 +39,7 @@
short pushState = StateMachine.UNDEFINED;
short action = -1;
+ @Override
public boolean equals(Object other) {
StateAction that = (StateAction) other;
return advanceToNextCodePoint == that.advanceToNextCodePoint
@@ -83,6 +84,7 @@
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder("[");
for (int i = stackSize - 1; i >= 0; --i) {
@@ -125,6 +127,7 @@
return Arrays.asList(actionNames);
}
+ @Override
public String toString() {
StringBuffer output = new StringBuffer();
int i = 0;
diff --git a/tools/java/org/unicode/cldr/draft/StateMachineBuilder.java b/tools/java/org/unicode/cldr/draft/StateMachineBuilder.java
index f5f8484..b8d1e68 100644
--- a/tools/java/org/unicode/cldr/draft/StateMachineBuilder.java
+++ b/tools/java/org/unicode/cldr/draft/StateMachineBuilder.java
@@ -16,22 +16,22 @@
import com.ibm.icu.text.UnicodeSet;
public class StateMachineBuilder<T> {
- private static final UnicodeSet WHITESPACE = (UnicodeSet) new UnicodeSet("[:Pattern_Whitespace:]").freeze();
- private static final UnicodeSet XID_START = (UnicodeSet) new UnicodeSet("[:XID_Start:]").freeze();
- private static final UnicodeSet XID_PART = (UnicodeSet) new UnicodeSet("[-[:XID_Continue:]]").freeze();
+ private static final UnicodeSet WHITESPACE = new UnicodeSet("[:Pattern_Whitespace:]").freeze();
+ private static final UnicodeSet XID_START = new UnicodeSet("[:XID_Start:]").freeze();
+ private static final UnicodeSet XID_PART = new UnicodeSet("[-[:XID_Continue:]]").freeze();
// TODO intern the actions
private short currentState = StateMachine.UNDEFINED;
private UnicodeMap<StateAction> currentMap = null;
- private List<UnicodeMap> stateToData = new ArrayList<UnicodeMap>();
+ private List<UnicodeMap> stateToData = new ArrayList<>();
private ParsePosition parsePosition = new ParsePosition(0);
- private Map<String, UnicodeSet> variables = new LinkedHashMap<String, UnicodeSet>();
+ private Map<String, UnicodeSet> variables = new LinkedHashMap<>();
- private Map<String, Short> stateToNumber = new LinkedHashMap<String, Short>();
- private List<String> numberToState = new ArrayList<String>();
- private Map<String, Short> actionToNumber = new LinkedHashMap<String, Short>();
- private List<String> numberToAction = new ArrayList<String>();
+ private Map<String, Short> stateToNumber = new LinkedHashMap<>();
+ private List<String> numberToState = new ArrayList<>();
+ private Map<String, Short> actionToNumber = new LinkedHashMap<>();
+ private List<String> numberToAction = new ArrayList<>();
private StateAction defaultAction;
@@ -40,7 +40,7 @@
}
public StateMachine<T> build(StateObjectBuilderFactory<T> factory) {
- Set<String> missingStates = new HashSet<String>();
+ Set<String> missingStates = new HashSet<>();
for (int i = 0; i < stateToData.size(); ++i) {
UnicodeMap action = stateToData.get(i);
if (action == null) {
@@ -51,7 +51,7 @@
throw new IllegalArgumentException("Missing states: " + missingStates);
}
fixDefaultAction();
- return new StateMachine<T>(stateToData, factory, numberToState, numberToAction);
+ return new StateMachine<>(stateToData, factory, numberToState, numberToAction);
}
// build state machines with rules on icu4c-trunk/source/common/rbbirpt.txt
@@ -62,8 +62,8 @@
#
#
#StateName:
-# input-char n next-state ^push-state action
-# input-char n next-state ^push-state action
+# input-char n next-state ^push-state action
+# input-char n next-state ^push-state action
# | | | | |
# | | | | |--- action to be performed by state machine
# | | | | See function RBBIRuleScanner::doParseActions()
@@ -83,18 +83,18 @@
# matches, peform the actions and go to the state specified on this line.
# The input character is tested sequentally, in the order written. The characters and
# character classes tested for do not need to be mutually exclusive. The first match wins.
-#
+#
Example:
#
# start state, scan position is at the beginning of the rules file, or in between two rules.
#
start:
- escaped term ^break-rule-end doExprStart
- white_space n start
+ escaped term ^break-rule-end doExprStart
+ white_space n start
'$' scan-var-name ^assign-or-rule doExprStart
- '!' n rev-option
+ '!' n rev-option
';' n start # ignore empty rules.
- eof exit
+ eof exit
default term ^break-rule-end doExprStart
*/
//@formatter:on
@@ -124,7 +124,7 @@
if (stateToData.size() > currentState && stateToData.get(currentState) != null) {
throw new IllegalArgumentException("Cannot define state twice: " + rule);
}
- currentMap = new UnicodeMap<StateAction>();
+ currentMap = new UnicodeMap<>();
while (stateToData.size() <= currentState) {
stateToData.add(null); // TODO make this more efficient
}
diff --git a/tools/java/org/unicode/cldr/draft/StateMachineTest.java b/tools/java/org/unicode/cldr/draft/StateMachineTest.java
index 1055b99..185a258 100644
--- a/tools/java/org/unicode/cldr/draft/StateMachineTest.java
+++ b/tools/java/org/unicode/cldr/draft/StateMachineTest.java
@@ -9,6 +9,7 @@
import java.util.TreeSet;
import org.unicode.cldr.draft.UnicodeSetBuilder.MyActions;
+import org.unicode.cldr.util.PathUtilities;
import com.ibm.icu.text.UnicodeSet;
@@ -19,13 +20,13 @@
private static boolean SHOW_IF_ERROR = true;
public static void main(String[] args) throws Exception {
- System.out.println(new File(".").getCanonicalPath());
+ System.out.println(PathUtilities.getNormalizedPathString("."));
BufferedReader in = FileUtilities.openUTF8Reader("../", "cldr-code/java/org/unicode/cldr/draft/UnicodeSetBuilderTests.txt");
// icu4c-trunk/source/common/rbbirpt.txt
// "icu4c-trunk/source/i18n/regexcst.txt"
- List<String[]> testLines = new ArrayList<String[]>();
+ List<String[]> testLines = new ArrayList<>();
while (true) {
String line = in.readLine();
if (line == null)
@@ -47,9 +48,9 @@
System.out.println(machine);
}
MyActions[] valuesUsed = UnicodeSetBuilder.MyActions.values();
- Set<String> possibleActions = new TreeSet<String>();
- Set<String> actionsUsed = new TreeSet<String>();
- Set<String> errors = new TreeSet<String>();
+ Set<String> possibleActions = new TreeSet<>();
+ Set<String> actionsUsed = new TreeSet<>();
+ Set<String> errors = new TreeSet<>();
for (MyActions valueUsed : valuesUsed) {
final String string = valueUsed.toString();
actionsUsed.add(string);
@@ -63,7 +64,7 @@
}
System.out.println("Errors: " + errors);
- Set<String> temp = new TreeSet<String>();
+ Set<String> temp = new TreeSet<>();
temp.addAll(possibleActions);
temp.removeAll(actionsUsed);
System.out.println("Unused Actions: " + temp);
diff --git a/tools/java/org/unicode/cldr/draft/TestMixedScript.java b/tools/java/org/unicode/cldr/draft/TestMixedScript.java
index 25d01b0..1626a3d 100644
--- a/tools/java/org/unicode/cldr/draft/TestMixedScript.java
+++ b/tools/java/org/unicode/cldr/draft/TestMixedScript.java
@@ -56,7 +56,7 @@
// Note: if UScript were an enum, we could avoid use of bitsets, but...
private final BitSet singleScripts = new BitSet();
- private final HashSet<BitSet> combinations = new HashSet<BitSet>();
+ private final HashSet<BitSet> combinations = new HashSet<>();
private BitSet tempBitSet = new BitSet();
/**
@@ -65,7 +65,7 @@
* described under {@link #MixedScriptLevel}.
* <p>
* <b>Note:</b> thread-safe call
- *
+ *
* @param source
* Input text.
* @return this, for chaining
@@ -285,7 +285,7 @@
/**
* Test numbers to see whether or not they are decimal, and if so, whether from different systems. Returns the first
* error found, or 'ok'.
- *
+ *
* @param text
* @return
*/
diff --git a/tools/java/org/unicode/cldr/draft/Typology.java b/tools/java/org/unicode/cldr/draft/Typology.java
index 98fb60d..be7cf10 100644
--- a/tools/java/org/unicode/cldr/draft/Typology.java
+++ b/tools/java/org/unicode/cldr/draft/Typology.java
@@ -23,12 +23,12 @@
import com.ibm.icu.text.UnicodeSet;
public class Typology {
- private static final Set<String> NOLABELS = Collections.unmodifiableSet(new HashSet<String>(Arrays
+ private static final Set<String> NOLABELS = Collections.unmodifiableSet(new HashSet<>(Arrays
.asList("NOLABEL")));
public static final UnicodeSet SKIP = new UnicodeSet("[[:C:]-[:Cf:]-[:Cc:]]").freeze();
// static UnicodeMap<String> reasons = new UnicodeMap<String>();
- public static Map<String, UnicodeSet> label_to_uset = new TreeMap<String, UnicodeSet>();
- public static UnicodeMap<Set<String>> char2labels = new UnicodeMap<Set<String>>();
+ public static Map<String, UnicodeSet> label_to_uset = new TreeMap<>();
+ public static UnicodeMap<Set<String>> char2labels = new UnicodeMap<>();
// static {
// label_to_uset.put("S", new UnicodeSet("[:S:]").freeze());
// label_to_uset.put("L", new UnicodeSet("[:L:]").freeze());
@@ -38,14 +38,14 @@
// label_to_uset.put("Z", new UnicodeSet("[:Z:]").freeze());
// label_to_uset.put("P", new UnicodeSet("[:P:]").freeze());
// }
- static Set<String> skiplabels = new HashSet<String>(Arrays.asList("", "Symbol", "Punctuation", "Letter", "S", "L", "M",
+ static Set<String> skiplabels = new HashSet<>(Arrays.asList("", "Symbol", "Punctuation", "Letter", "S", "L", "M",
"N", "C", "Z", "P"));
- public static Map<String, UnicodeSet> full_path_to_uset = new TreeMap<String, UnicodeSet>();
- public static Map<String, UnicodeSet> path_to_uset = new TreeMap<String, UnicodeSet>();
+ public static Map<String, UnicodeSet> full_path_to_uset = new TreeMap<>();
+ public static Map<String, UnicodeSet> path_to_uset = new TreeMap<>();
// static Map<List<String>,UnicodeSet> path_to_uset = new TreeMap<List<String>,UnicodeSet>();
public static Relation<String, String> labelToPaths = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- public static Map<String, Map<String, UnicodeSet>> label_parent_uset = new TreeMap<String, Map<String, UnicodeSet>>();
+ public static Map<String, Map<String, UnicodeSet>> label_parent_uset = new TreeMap<>();
// public static Relation<String, String> pathToList = new Relation(new TreeMap(), TreeSet.class);
@@ -54,6 +54,7 @@
public final static Pattern SPLIT = PatternCache.get("\\s*\t\\s*");
public final static Pattern NON_ALPHANUM = PatternCache.get("[^0-9A-Za-z]+");
+ @Override
protected String[] splitLine(String line) {
return SPLIT.split(line);
}
@@ -90,7 +91,7 @@
String[] labels = fullPath.split("/");
String path = "";
- Set<String> labelSet = new TreeSet<String>();
+ Set<String> labelSet = new TreeSet<>();
for (String item : labels) {
if (skiplabels.contains(item)) {
continue;
@@ -116,8 +117,8 @@
return true;
}
- Map<List<String>, List<String>> listCache = new HashMap<List<String>, List<String>>();
- Map<Set<String>, Set<String>> setCache = new HashMap<Set<String>, Set<String>>();
+ Map<List<String>, List<String>> listCache = new HashMap<>();
+ Map<Set<String>, Set<String>> setCache = new HashMap<>();
private <T> T intern(Map<T, T> cache, T list) {
T old = cache.get(list);
@@ -132,7 +133,7 @@
new MyReader().process(Typology.class, "Categories.txt"); // "09421-u52m09xxxx.txt"
// fix the paths
- Map<String, UnicodeSet> temp = new TreeMap<String, UnicodeSet>();
+ Map<String, UnicodeSet> temp = new TreeMap<>();
for (int i = 0; i < UCharacter.CHAR_CATEGORY_COUNT; ++i) {
UnicodeSet same = new UnicodeSet()
.applyIntPropertyValue(UProperty.GENERAL_CATEGORY, i);
@@ -156,7 +157,7 @@
}
Map<String, UnicodeSet> map = label_parent_uset.get(labels[j]);
if (map == null) {
- label_parent_uset.put(labels[j], map = new TreeMap<String, UnicodeSet>());
+ label_parent_uset.put(labels[j], map = new TreeMap<>());
}
UnicodeSet uset2 = map.get(parent);
if (uset2 == null) {
diff --git a/tools/java/org/unicode/cldr/draft/UnicodeMapBuilder.java b/tools/java/org/unicode/cldr/draft/UnicodeMapBuilder.java
index 923982c..e461e0a 100644
--- a/tools/java/org/unicode/cldr/draft/UnicodeMapBuilder.java
+++ b/tools/java/org/unicode/cldr/draft/UnicodeMapBuilder.java
@@ -55,7 +55,7 @@
public UnicodeMapBuilder<T> putFromLines(BufferedReader br) {
if (result == null) {
- result = new UnicodeMap<T>();
+ result = new UnicodeMap<>();
}
UnicodeSet sources = new UnicodeSet();
String line = null;
diff --git a/tools/java/org/unicode/cldr/draft/UnicodeSetBuilder.java b/tools/java/org/unicode/cldr/draft/UnicodeSetBuilder.java
index 041354e..a1b800f 100644
--- a/tools/java/org/unicode/cldr/draft/UnicodeSetBuilder.java
+++ b/tools/java/org/unicode/cldr/draft/UnicodeSetBuilder.java
@@ -15,7 +15,7 @@
/**
* Provides for parsing and formatting UnicodeSet according to different Targets and other settings.
- *
+ *
* @author markdavis
*/
public class UnicodeSetBuilder {
@@ -28,7 +28,7 @@
BufferedReader in = FileUtilities.openUTF8Reader("../", "cldr-code/java/org/unicode/cldr/draft/UnicodeSetStates.txt");
// icu4c-trunk/source/common/rbbirpt.txt
// "icu4c-trunk/source/i18n/regexcst.txt"
- StateMachineBuilder<UnicodeSet> builder = new StateMachineBuilder<UnicodeSet>();
+ StateMachineBuilder<UnicodeSet> builder = new StateMachineBuilder<>();
// builder.add("quoted:=[@]");
// builder.add("rule_char:=[^\\*\\?\\+\\[\\(/)\\{\\}\\^\\$\\|\\\\\\.]");
// builder.add("digit_char:=[0-9]");
@@ -49,6 +49,7 @@
private static final class MyObjectBuilderFactory implements
StateObjectBuilderFactory<UnicodeSet> {
+ @Override
public StateObjectBuilder<UnicodeSet> getInstance() {
return new MyObjectBuilder();
}
@@ -56,13 +57,13 @@
public enum MyActions {
unhandled, doSetLiteral, doSetLiteralEscaped, doHex, doSetRange, doSetNegate, doName, doPropName, doPropRelation, doPropValue, doStartSetProp, doSetBeginUnion, doSetEnd, doSetBeginDifference1, doSetBeginIntersection1, doSetDifference2, doSetIntersection2, doSetBackslash_s, doSetBackslash_S, doSetBackslash_w, doSetBackslash_W, doSetBackslash_d, doSetBackslash_D, doSetAddAmp, doSetAddDash,
- };
+ }
private static final class MyObjectBuilder extends StateObjectBuilder<UnicodeSet> {
private enum Operation {
union, difference, intersection, symmetric
- };
+ }
private static class Info {
UnicodeSet set;
@@ -77,17 +78,17 @@
}
}
- private static final UnicodeSet WHITESPACE = (UnicodeSet) new UnicodeSet("[:whitespace:]").freeze();
+ private static final UnicodeSet WHITESPACE = new UnicodeSet("[:whitespace:]").freeze();
- private static final UnicodeSet NOT_WHITESPACE = (UnicodeSet) new UnicodeSet("[:^whitespace:]").freeze();
+ private static final UnicodeSet NOT_WHITESPACE = new UnicodeSet("[:^whitespace:]").freeze();
- private static final UnicodeSet WORD = (UnicodeSet) new UnicodeSet("[[:alphabetic:][:digit:]]").freeze();
+ private static final UnicodeSet WORD = new UnicodeSet("[[:alphabetic:][:digit:]]").freeze();
- private static final UnicodeSet NOT_WORD = (UnicodeSet) new UnicodeSet("[^[:alphabetic:][:digit:]]").freeze();
+ private static final UnicodeSet NOT_WORD = new UnicodeSet("[^[:alphabetic:][:digit:]]").freeze();
- private static final UnicodeSet DIGIT = (UnicodeSet) new UnicodeSet("[:Nd:]").freeze();
+ private static final UnicodeSet DIGIT = new UnicodeSet("[:Nd:]").freeze();
- private static final UnicodeSet NOT_DIGIT = (UnicodeSet) new UnicodeSet("[:^Nd:]").freeze();
+ private static final UnicodeSet NOT_DIGIT = new UnicodeSet("[:^Nd:]").freeze();
UnicodeSet current = new UnicodeSet();
private Operation operation;
@@ -97,7 +98,7 @@
private String valueName;
private boolean negateProp;
- private List<Info> setStack = new ArrayList<Info>();
+ private List<Info> setStack = new ArrayList<>();
private int lastLiteral = 0;
private int lastPosition;
diff --git a/tools/java/org/unicode/cldr/draft/UnicodeSetFilteredTransform.java b/tools/java/org/unicode/cldr/draft/UnicodeSetFilteredTransform.java
index 3c7b0a8..7ab3568 100644
--- a/tools/java/org/unicode/cldr/draft/UnicodeSetFilteredTransform.java
+++ b/tools/java/org/unicode/cldr/draft/UnicodeSetFilteredTransform.java
@@ -5,7 +5,7 @@
/**
* Immutable StringTransform using a UnicodeSet.
- *
+ *
* @author markdavis
*/
public class UnicodeSetFilteredTransform extends FilteredTransform {
@@ -13,7 +13,7 @@
public UnicodeSetFilteredTransform(UnicodeSet filter, StringTransform result) {
super(result);
- unicodeSet = (UnicodeSet) filter.freeze();
+ unicodeSet = filter.freeze();
}
// TODO optimize scanning, add strings
@@ -51,6 +51,7 @@
return true;
}
+ @Override
public String toString() {
return ":: " + unicodeSet.toPattern(false) + ";\n" + super.toString();
}
diff --git a/tools/java/org/unicode/cldr/draft/UnicodeSetFormat.java b/tools/java/org/unicode/cldr/draft/UnicodeSetFormat.java
index fca9dfa..bd30db1 100644
--- a/tools/java/org/unicode/cldr/draft/UnicodeSetFormat.java
+++ b/tools/java/org/unicode/cldr/draft/UnicodeSetFormat.java
@@ -39,7 +39,7 @@
for (UnicodeSetIterator it = new UnicodeSetIterator((UnicodeSet) obj); it.nextRange();) {
if (it.codepoint == UnicodeSetIterator.IS_STRING) {
if (strings == null) {
- strings = new TreeSet<String>();
+ strings = new TreeSet<>();
}
strings.add(it.string);
continue;
@@ -141,7 +141,7 @@
/**
* Is called every time an unquoted $ is found. Should parse out variables as appropriate
* and return how far we got, and the replacement string. Returns null if doesn't match a variable.
- *
+ *
* @pos on input should be set to the position just before the dollar sign.
* On output should be set to the end of the text to replace.
*/
@@ -158,7 +158,7 @@
* getProperty("bidi_class", "neutral", false, result) <br>
* (for an example of the latter, see {@linkplain http
* ://unicode.org/cldr/utility/list-unicodeset.jsp?a=\p name=/WITH%20DOT%20ABOVE/}
- *
+ *
* @param regex
* Set to true if the property value is a regex "find" expression. In that case,
* the return value should be the set of Unicode characters that match the regex.
@@ -170,7 +170,7 @@
public String formatWithProperties(UnicodeSet original, boolean addOthers, UnicodeSet expandBlockIgnorables,
int... properties) {
UnicodeSet remainder = new UnicodeSet().addAll(original);
- Set<String> propSet = new TreeSet<String>();
+ Set<String> propSet = new TreeSet<>();
BitSet props = new BitSet();
for (int i = 0; i < properties.length; ++i) {
@@ -233,7 +233,7 @@
private Target target;
private int options;
private Extension[] extensions;
- private static final UnicodeSet toQuote = (UnicodeSet) new UnicodeSet(
+ private static final UnicodeSet toQuote = new UnicodeSet(
"[[:Cn:][:Default_Ignorable_Code_Point:][:patternwhitespace:]]").freeze();
}
diff --git a/tools/java/org/unicode/cldr/draft/UnmodifiableBitSet.java b/tools/java/org/unicode/cldr/draft/UnmodifiableBitSet.java
index 5c86c00..cf1049b 100644
--- a/tools/java/org/unicode/cldr/draft/UnmodifiableBitSet.java
+++ b/tools/java/org/unicode/cldr/draft/UnmodifiableBitSet.java
@@ -47,7 +47,7 @@
@Override
public void flip(int bitIndex) {
throw new UnsupportedOperationException("Cannot modify.");
- };
+ }
@Override
public void flip(int fromIndex, int toIndex) {
diff --git a/tools/java/org/unicode/cldr/draft/XLikelySubtags.java b/tools/java/org/unicode/cldr/draft/XLikelySubtags.java
index b869a50..6e020e0 100644
--- a/tools/java/org/unicode/cldr/draft/XLikelySubtags.java
+++ b/tools/java/org/unicode/cldr/draft/XLikelySubtags.java
@@ -50,6 +50,7 @@
}
static final Maker HASHMAP = new Maker() {
+ @Override
@SuppressWarnings("unchecked")
public Map<Object, Object> make() {
return new HashMap<>();
@@ -57,6 +58,7 @@
};
static final Maker TREEMAP = new Maker() {
+ @Override
@SuppressWarnings("unchecked")
public Map<Object, Object> make() {
return new TreeMap<>();
@@ -202,7 +204,7 @@
final LSR value = regionEntry.getValue();
set(result, "und", value.script, value.region, value);
}
- //
+ //
// check that every level has "" (or "und")
if (!result.containsKey("und")) {
throw new IllegalArgumentException("failure: base");
@@ -296,7 +298,7 @@
}
// public static ULocale addLikelySubtags(ULocale loc) {
-//
+//
// }
/**
@@ -376,7 +378,7 @@
if (result.script.equals(value00.script)) { //script is default
if (result.region.equals(value00.region)) {
return result.replace(null, "", "");
- } else if (fieldToFavor == fieldToFavor.FAVOR_REGION) {
+ } else if (fieldToFavor == Minimize.FAVOR_REGION) {
return result.replace(null, "", null);
} else {
favorRegionOk = true;
@@ -456,9 +458,9 @@
// }
// get all the languages, scripts, and regions
- Set<String> languages = new TreeSet<String>();
- Set<String> scripts = new TreeSet<String>();
- Set<String> regions = new TreeSet<String>();
+ Set<String> languages = new TreeSet<>();
+ Set<String> scripts = new TreeSet<>();
+ Set<String> regions = new TreeSet<>();
Counter<String> languageCounter = new Counter<>();
Counter<String> scriptCounter = new Counter<>();
Counter<String> regionCounter = new Counter<>();
diff --git a/tools/java/org/unicode/cldr/draft/XLocaleDistance.java b/tools/java/org/unicode/cldr/draft/XLocaleDistance.java
index 8acd8e4..675965f 100644
--- a/tools/java/org/unicode/cldr/draft/XLocaleDistance.java
+++ b/tools/java/org/unicode/cldr/draft/XLocaleDistance.java
@@ -20,6 +20,7 @@
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.SupplementalDataInfo;
+import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
@@ -30,7 +31,6 @@
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R4;
import com.ibm.icu.util.Output;
@@ -56,7 +56,7 @@
static final SupplementalDataInfo SDI = CONFIG.getSupplementalDataInfo();
private static List<R4<String, String, Integer, Boolean>> xGetLanguageMatcherData() {
- return SDI.getLanguageMatcherData("written");
+ return SDI.getLanguageMatcherData("written_new");
}
static final Multimap<String, String> CONTAINER_TO_CONTAINED;
@@ -69,7 +69,8 @@
for (String container : SDI.getContainers()) {
Set<String> contained = SDI.getContained(container);
- System.out.println(".putAll(\"" + container + "\", \"" + CollectionUtilities.join(contained, "\", \"") + "\")");
+ System.out.println(".putAll(\"" + container + "\", \"" + Joiner.on("\", \"")
+ .join(contained) + "\")");
}
ImmutableMultimap.Builder<String, String> containerToFinalContainedBuilder = new ImmutableMultimap.Builder<>();
@@ -207,9 +208,10 @@
/**
* Return an id, or null if there is none.
*/
+ @Override
public Integer toId(T source) {
return objectToInt.get(source);
-// return value == null ? 0 : value;
+// return value == null ? 0 : value;
}
/**
@@ -304,6 +306,7 @@
}
}
+ @Override
public DistanceTable getDistanceTable() {
return distanceTable;
}
@@ -340,6 +343,7 @@
this(newMap());
}
+ @Override
public boolean isEmpty() {
return subtables.isEmpty();
}
@@ -358,6 +362,7 @@
return subtables.hashCode();
}
+ @Override
public int getDistance(String desired, String supported, Output<DistanceTable> distanceTable, boolean starEquals) {
boolean star = false;
Map<String, DistanceNode> sub2 = subtables.get(desired);
@@ -502,8 +507,9 @@
return toString(false);
}
+ @Override
public String toString(boolean abbreviate) {
- return toString(abbreviate, "", new IdMakerFull<Object>("interner"), new StringBuilder()).toString();
+ return toString(abbreviate, "", new IdMakerFull<>("interner"), new StringBuilder()).toString();
}
public StringBuilder toString(boolean abbreviate, String indent, IdMakerFull<Object> intern, StringBuilder buffer) {
@@ -547,6 +553,7 @@
return buffer;
}
+ @Override
public StringDistanceTable compact() {
return new CompactAndImmutablizer().compact(this);
}
@@ -575,6 +582,7 @@
return dnode == null ? null : dnode.distance;
}
+ @Override
public DistanceNode getInternalNode(String a, String b) {
Map<String, DistanceNode> subsub = subtables.get(a);
if (subsub == null) {
@@ -583,6 +591,7 @@
return subsub.get(b);
}
+ @Override
public Map<String, Set<String>> getInternalMatches() {
Map<String, Set<String>> result = new LinkedHashMap<>();
for (Entry<String, Map<String, DistanceNode>> entry : subtables.entrySet()) {
@@ -642,7 +651,7 @@
* ULocales must be in canonical, addLikelySubtags format. Returns distance
* @param desired
* @param supported
- * @param distanceOption
+ * @param distanceOption
* @return
*/
public int distanceRaw(LSR desired, LSR supported, int threshold, DistanceOption distanceOption) {
@@ -778,7 +787,8 @@
}
if (PRINT_OVERRIDES) {
System.out.println("\t\t<languageMatches type=\"written\" alt=\"enhanced\">");
- System.out.println("\t\t\t<paradigmLocales locales=\"" + CollectionUtilities.join(paradigmRegions, " ")
+ System.out.println("\t\t\t<paradigmLocales locales=\"" + String
+ .join(" ", paradigmRegions)
+ "\"/>");
for (String[] variableRule : variableOverrides) {
System.out.println("\t\t\t<matchVariable id=\"" + variableRule[0]
@@ -879,8 +889,8 @@
private static void printMatchXml(List<String> desired, List<String> supported, Integer distance, Boolean oneway) {
if (PRINT_OVERRIDES) {
- String desiredStr = CollectionUtilities.join(desired, "_");
- String supportedStr = CollectionUtilities.join(supported, "_");
+ String desiredStr = Joiner.on("_").join(desired);
+ String supportedStr = Joiner.on("_").join(supported);
String desiredName = fixedName(desired);
String supportedName = fixedName(supported);
System.out.println("\t\t\t<languageMatch"
@@ -893,7 +903,7 @@
}
private static String fixedName(List<String> match) {
- List<String> alt = new ArrayList<String>(match);
+ List<String> alt = new ArrayList<>(match);
StringBuilder result = new StringBuilder();
switch (alt.size()) {
case 3:
@@ -918,7 +928,7 @@
result.insert(0, english.getName(CLDRFile.TERRITORY_NAME, language));
}
}
- return CollectionUtilities.join(alt, "; ");
+ return Joiner.on("; ").join(alt);
}
static public void add(StringDistanceTable languageDesired2Supported, List<String> desired, List<String> supported, int percentage) {
@@ -999,6 +1009,7 @@
paradigms = ImmutableSet.copyOf(paradigmsIn);
}
+ @Override
public String toId(String region) {
String result = regionToPartition.get(region);
return result == null ? "" : result;
@@ -1114,7 +1125,7 @@
}
/**
- * Parses a string of regions like "US+005-BR" and produces a set of resolved regions.
+ * Parses a string of regions like "US+005-BR" and produces a set of resolved regions.
* All macroregions are fully resolved to sets of non-macro regions.
* <br>Syntax is simple for now:
* <pre>regionSet := region ([-+] region)*</pre>
diff --git a/tools/java/org/unicode/cldr/draft/XLocaleMatcher.java b/tools/java/org/unicode/cldr/draft/XLocaleMatcher.java
index 989aa5e..fd74775 100644
--- a/tools/java/org/unicode/cldr/draft/XLocaleMatcher.java
+++ b/tools/java/org/unicode/cldr/draft/XLocaleMatcher.java
@@ -42,14 +42,14 @@
public static class Builder {
private Set<ULocale> supportedLanguagesList;
private int thresholdDistance = -1;
- private int demotionPerAdditionalDesiredLocale = -1;;
+ private int demotionPerAdditionalDesiredLocale = -1;
private ULocale defaultLanguage;
private XLocaleDistance localeDistance;
private DistanceOption distanceOption;
/**
* @param languagePriorityList the languagePriorityList to set
- * @return
+ * @return
*/
public Builder setSupportedLocales(String languagePriorityList) {
this.supportedLanguagesList = asSet(LocalePriorityList.add(languagePriorityList).build());
@@ -68,7 +68,7 @@
/**
* @param thresholdDistance the thresholdDistance to set, with -1 = default
- * @return
+ * @return
*/
public Builder setThresholdDistance(int thresholdDistance) {
this.thresholdDistance = thresholdDistance;
@@ -77,7 +77,7 @@
/**
* @param demotionPerAdditionalDesiredLocale the demotionPerAdditionalDesiredLocale to set, with -1 = default
- * @return
+ * @return
*/
public Builder setDemotionPerAdditionalDesiredLocale(int demotionPerAdditionalDesiredLocale) {
this.demotionPerAdditionalDesiredLocale = demotionPerAdditionalDesiredLocale;
@@ -86,7 +86,7 @@
/**
* @param localeDistance the localeDistance to set, with default = XLocaleDistance.getDefault().
- * @return
+ * @return
*/
public Builder setLocaleDistance(XLocaleDistance localeDistance) {
this.localeDistance = localeDistance;
@@ -96,7 +96,7 @@
/**
* Set the default language, with null = default = first supported language
* @param defaultLanguage
- * @return
+ * @return
*/
public Builder setDefaultLanguage(ULocale defaultLanguage) {
this.defaultLanguage = defaultLanguage;
@@ -104,10 +104,10 @@
}
/**
- * If true, then the language differences are smaller than than script differences.
+ * If true, then the language differences are smaller than than script differences.
* This is used in situations (such as maps) where it is better to fall back to the same script than a similar language.
* @param distanceOption
- * @return
+ * @return
*/
public Builder setDistanceOption(DistanceOption distanceOption) {
this.distanceOption = distanceOption;
@@ -243,11 +243,10 @@
for (ULocale locale : languageList) {
temp.add(locale);
}
- ;
return temp;
}
- /**
+ /**
* Get the best match between the desired languages and supported languages
* @param desiredLanguages Typically the supplied user's languages, in order of preference, with best first.
* @param outputBestDesired The one of the desired languages that matched best.
@@ -317,7 +316,7 @@
return bestSupportedLocales.iterator().next();
}
- /**
+ /**
* Get the best match between the desired languages and supported languages
* @param desiredLanguages Typically the supplied user's languages, in order of preference, with best first.
* @param outputBestDesired The one of the desired languages that matched best.
@@ -454,6 +453,7 @@
* @return value between 0 and 1, inclusive.
* @deprecated Use the form with 2 parameters instead.
*/
+ @Deprecated
public double match(ULocale desired, ULocale desiredMax, ULocale supported, ULocale supportedMax) {
return match(desired, supported);
}
diff --git a/tools/java/org/unicode/cldr/draft/keyboard/KeyboardId.java b/tools/java/org/unicode/cldr/draft/keyboard/KeyboardId.java
index 22750e0..14d8caf 100644
--- a/tools/java/org/unicode/cldr/draft/keyboard/KeyboardId.java
+++ b/tools/java/org/unicode/cldr/draft/keyboard/KeyboardId.java
@@ -18,10 +18,10 @@
* An object that is used to uniquely identify a particular keyboard. This object can be serialized
* as a string. The string has the following format:
* {@code <locale>-t-k0-<platform>-<attribute0>-<attribute1>-<attributeN>}
- *
+ *
* <p>
* The locale and platform tags are mandatory, the attributes are not.
- *
+ *
* <p>
* The following are all valid keyboard locale strings:
* <ul>
diff --git a/tools/java/org/unicode/cldr/draft/keyboard/KeyboardTool.java b/tools/java/org/unicode/cldr/draft/keyboard/KeyboardTool.java
index ba5adc2..e0275ac 100644
--- a/tools/java/org/unicode/cldr/draft/keyboard/KeyboardTool.java
+++ b/tools/java/org/unicode/cldr/draft/keyboard/KeyboardTool.java
@@ -52,7 +52,7 @@
}
System.out.println(KeylayoutParser.KEYBOARD_ID_MAP.unmatchedIds());
}
-
+
private enum KeylayoutFilenameFilter implements FilenameFilter {
INSTANCE;
@Override public boolean accept(File dir, String name) {
diff --git a/tools/java/org/unicode/cldr/draft/keyboard/out/KeyboardToXml.java b/tools/java/org/unicode/cldr/draft/keyboard/out/KeyboardToXml.java
index 4c526cd..05199f0 100644
--- a/tools/java/org/unicode/cldr/draft/keyboard/out/KeyboardToXml.java
+++ b/tools/java/org/unicode/cldr/draft/keyboard/out/KeyboardToXml.java
@@ -162,7 +162,7 @@
longPressBuilder.append(" ");
}
}
-
+
if (longPressBuilder.length() > 0) {
comment.append(" long=");
comment.append(longPressBuilder.toString());
diff --git a/tools/java/org/unicode/cldr/draft/keyboard/out/XmlWriter.java b/tools/java/org/unicode/cldr/draft/keyboard/out/XmlWriter.java
index 5d966ed..bb26da8 100644
--- a/tools/java/org/unicode/cldr/draft/keyboard/out/XmlWriter.java
+++ b/tools/java/org/unicode/cldr/draft/keyboard/out/XmlWriter.java
@@ -13,7 +13,7 @@
import com.google.common.collect.ImmutableMap;
-/**
+/**
* Object which wraps around an XML stream writer. Automatically adds proper formatting
* (indentation and line breaks) to the written XML elements.
*/
diff --git a/tools/java/org/unicode/cldr/icu/Bcp47Mapper.java b/tools/java/org/unicode/cldr/icu/Bcp47Mapper.java
deleted file mode 100644
index 6cb5cf2..0000000
--- a/tools/java/org/unicode/cldr/icu/Bcp47Mapper.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.google.common.collect.ImmutableSet;
-
-/**
- * A mapper that converts BCP 47 data from CLDR to the ICU data structure.
- *
- * @author jchye
- */
-public class Bcp47Mapper {
-// private static final String[] KEYTYPE_FILES = {
-// "calendar", "collation", "currency", "number", "variant"
-// };
- private String sourceDir;
-
- public Bcp47Mapper(String bcp47Dir) {
- sourceDir = bcp47Dir;
- }
-
- /**
- * Fills an IcuData object with data of the given type.
- */
- public IcuData[] fillFromCldr() {
- IcuData timezoneData = new IcuData("common/bcp47/timezone.xml", "timezoneTypes", false);
- Map<String, String> keyMap = new HashMap<String, String>();
- // Timezone data is put in a different file.
- fillFromFile("timezone", timezoneData, keyMap);
-
- // Process the rest of the data.
- IcuData keyTypeData = new IcuData("common/bcp47/*.xml", "keyTypeData", false);
- for (File file : new File(sourceDir).listFiles()) {
- final String filenameXml = file.getName();
- if (filenameXml.endsWith(".xml") && !filenameXml.equals("timezone.xml")) {
- fillFromFile(filenameXml.substring(0, filenameXml.length() - 4),
- keyTypeData, keyMap);
- }
- }
- // Add all the keyMap values into the IcuData file.
- for (Entry<String, String> kmData : keyMap.entrySet()) {
- String bcpKey = kmData.getKey();
- String key = kmData.getValue();
- if (bcpKey.startsWith("@")) {
- keyTypeData.add("/" + bcpKey.substring(1), key);
- continue;
- }
- if (bcpKey.equals(key)) {
- // empty value to indicate the BCP47 key is same with the legacy key
- bcpKey = "";
- }
- keyTypeData.add("/keyMap/" + key, bcpKey);
- }
- // Add aliases for timezone data.
- keyTypeData.add("/typeAlias/timezone:alias", "/ICUDATA/timezoneTypes/typeAlias/timezone");
- keyTypeData.add("/typeMap/timezone:alias", "/ICUDATA/timezoneTypes/typeMap/timezone");
- keyTypeData.add("/bcpTypeAlias/tz:alias", "/ICUDATA/timezoneTypes/bcpTypeAlias/tz");
- return new IcuData[] { timezoneData, keyTypeData };
- }
-
- private void fillFromFile(String filename, IcuData icuData, Map<String, String> keyMap) {
- KeywordHandler handler = new KeywordHandler(icuData, keyMap);
- MapperUtils.parseFile(new File(sourceDir, filename + ".xml"), handler);
- }
-
- static final Set<String> SKIP_KEY_ATTRIBUTES = ImmutableSet.of(
- "name", "alias", "description", "since", "extension");
- static final Set<String> SKIP_TYPE_ATTRIBUTES = ImmutableSet.of(
- "name", "alias", "description", "since", "preferred");
-
- /**
- * XML parser for BCP47 data.
- */
- private class KeywordHandler extends MapperUtils.EmptyHandler {
- private String typeAliasPrefix;
- private String typeMapPrefix;
- private String bcpTypeAliasPrefix;
- private String lastKeyName;
- private IcuData icuData;
- private Map<String, String> keyMap;
-
- /**
- * KeywordHandler constructor.
- *
- * @param icuData
- * the IcuData object to store the parsed data
- * @param keyMap
- * a mapping of keys to their aliases. These values will
- * not be added to icuData by the handler
- */
- public KeywordHandler(IcuData icuData, Map<String, String> keyMap) {
- this.icuData = icuData;
- this.keyMap = keyMap;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- // Format of BCP47 file:
- // <key name="tz" alias="timezone" description="Time zone key">
- // <type name="adalv" alias="Europe/Andorra" description="Andorra"/>
- // ...
- if (attr == null) {
- return;
- }
-
- if (qName.equals("key")) {
- String keyName = attr.getValue("name");
- if (keyName == null) {
- return;
- }
-
- String keyAlias = attr.getValue("alias");
- if (keyAlias == null) {
- keyAlias = keyName;
-// System.err.println(Bcp47Mapper.class.getSimpleName() + " Info: BCP47 key " + keyName
-// + " didn't have the optional alias= value, mapping " + keyName + "->" + keyName);
- }
-
- keyName = keyName.toLowerCase();
- keyAlias = keyAlias.toLowerCase();
-
- typeAliasPrefix = "/typeAlias/" + keyAlias + '/';
- typeMapPrefix = "/typeMap/" + keyAlias + '/';
- keyMap.put(keyName, keyAlias);
- bcpTypeAliasPrefix = "/bcpTypeAlias/" + keyName + '/';
- lastKeyName = keyName;
- addOtherInfo(qName, attr, keyName, SKIP_KEY_ATTRIBUTES);
- } else if (qName.equals("type")) {
- String typeName = attr.getValue("name");
- if (typeName == null) {
- return;
- }
-
- // BCP47 type alias (maps deprecated type to preferred type)
- String preferredTypeName = attr.getValue("preferred");
- if (preferredTypeName != null) {
- icuData.add(bcpTypeAliasPrefix + typeName, preferredTypeName);
- return;
- }
-
- String alias = attr.getValue("alias");
- if (alias == null) {
- // Generate type map entry using empty value
- // (an empty value indicates same type name
- // is used for both BCP47 and legacy type.
- icuData.add(typeMapPrefix + typeName, "");
- } else {
- String[] aliases = alias.split("\\s+");
- String mainAlias = aliases[0];
- icuData.add(typeMapPrefix + formatName(mainAlias), typeName);
- for (int i = 1; i < aliases.length; i++) {
- icuData.add(typeAliasPrefix + formatName(aliases[i]), mainAlias);
- }
- }
- addOtherInfo(qName, attr, lastKeyName + "/" + typeName, SKIP_KEY_ATTRIBUTES);
- }
- }
-
- private void addOtherInfo(String qName, Attributes attr, String typeName, Set<String> excludedAttributes) {
- for (int i = 0; i < attr.getLength(); ++i) {
- String name = attr.getQName(i);
- String value = attr.getValue(i);
- if (excludedAttributes.contains(name)
- || name.equals("deprecated") && value.equals("false")) {
- continue;
- }
- keyMap.put("@" + qName + "Info/" + name + "/" + typeName, value);
- }
- }
-
- private String formatName(String str) {
- if (str.indexOf('/') > -1) {
- str = '"' + str.replace('/', ':') + '"';
- }
- return str;
- }
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/BreakIteratorMapper.java b/tools/java/org/unicode/cldr/icu/BreakIteratorMapper.java
deleted file mode 100644
index 9cf65f5..0000000
--- a/tools/java/org/unicode/cldr/icu/BreakIteratorMapper.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.XPathParts;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.ibm.icu.impl.Utility;
-import com.ibm.icu.text.MessageFormat;
-
-/**
- * Converts special ICU break iterator files for ICU.
- * @author jchye
- */
-class BreakIteratorMapper extends Mapper {
- private String sourceDir;
- private Factory specialFactory;
- private Set<String> brkSource = new HashSet<String>();
- private Set<String> dictSource = new HashSet<String>();
-
- /**
- * @param specialFactory the factory containing the ICU xml files for break iterators.
- */
- public BreakIteratorMapper(String sourceDir, Factory specialFactory) {
- this.sourceDir = sourceDir;
- this.specialFactory = specialFactory;
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format. (this processes the special data from the ICU side)
- */
- @Override
- public IcuData[] fillFromCldr(String locale) {
- IcuData icuData = new IcuData("common/segments/" + locale + ".xml ../../xml/brkitr/" + locale + ".xml", locale, true);
- CLDRFile specialsFile = specialFactory.make(locale, false);
- BreakIteratorHandler handler = new BreakIteratorHandler(icuData);
- File file = new File(sourceDir, locale + ".xml");
- MapperUtils.parseFile(file, handler);
-
- for (String path : specialsFile) {
- /*
- * example paths:
- //ldml/special/icu:breakIteratorData/icu:boundaries/icu:title[@icu:dependency="title.brk"]
- //ldml/special/icu:breakIteratorData/icu:dictionaries/icu:dictionary[@icu:dependency="laodict.dict"][@type="Laoo"]
- */
- if (!path.startsWith("//ldml/special/icu:breakIteratorData")) continue;
- String fullPath = specialsFile.getFullXPath(path);
- final XPathParts xpp = XPathParts.getFrozenInstance(fullPath);
- final String element = xpp.getElement(-1);
- final String element2 = xpp.getElement(-2);
- Set<String> source = null;
- if (!element.startsWith("icu:") || !element.startsWith("icu:")) {
- System.err.println("WARNING: brkiter: in " + locale + ".xml (ICU specials): Ignoring path: " + fullPath);
- } else {
- final String type;
-
- if (!element.startsWith("icu:") || !element.startsWith("icu:")) {
- System.err.println("WARNING: brkiter: in " + locale + ".xml (ICU specials): Ignoring path (unknown special): " + fullPath);
- continue;
- }
-
- if (element2.equals("icu:boundaries")) {
- type = element.split(":")[1]; // icu:word -> "word"
- source = brkSource;
- } else if (element2.equals("icu:dictionaries")) {
- type = xpp.getAttributeValue(-1, "type"); // [@type="Laoo"] -> "Laoo"
- source = dictSource;
- } else {
- System.err
- .println("WARNING: brkiter: in " + locale + ".xml (ICU specials): Ignoring path (unknown element: " + element2 + "): " + fullPath);
- continue;
- }
- final String filename = xpp.getAttributeValue(-1, "icu:dependency");
- if (filename == null || type == null) {
- System.err.println("WARNING: brkiter: in " + locale + ".xml (ICU specials): Malformed path: " + fullPath);
- } else {
- final String altValue = xpp.getAttributeValue(-1, "alt");
- final String extType = (altValue == null) ? type : type.concat("_").concat(altValue);
- source.add(filename.substring(0, filename.lastIndexOf('.'))); // "title.brk" -> "title"
- icuData.add(
- MessageFormat.format("/{0}/{1}:process(dependency)", element2.split(":")[1], extType), filename); // "Laoo", "laodict.dict"
- }
- }
- }
-
- return new IcuData[] { icuData };
- }
-
- /**
- * The XML handler for break iterator data. (from the CLDR side)
- */
- private class BreakIteratorHandler extends MapperUtils.EmptyHandler {
- private IcuData icuData;
- private String segPath;
- private StringBuilder currentText = new StringBuilder();
- private StringBuilder value = new StringBuilder();
-
- public BreakIteratorHandler(IcuData icuData) {
- this.icuData = icuData;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- if (qName.equals("segmentation")) {
- segPath = "/exceptions/" + attr.getValue("type") + ":array";
- } else if (qName.equals("version")) {
- icuData.add("/Version", CLDRFile.GEN_VERSION);
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (qName.equals("exception") || // deprecated name
- qName.equals("suppression")) { // new name
- value.append(Utility.escape(currentText.toString()));
- icuData.add(segPath, value.toString());
- currentText.setLength(0);
- value.setLength(0);
- }
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- currentText.append(ch, start, length);
- }
- }
-
- @Override
- public Collection<String> getAvailable() {
- return specialFactory.getAvailable();
- }
-
- @Override
- public Makefile generateMakefile(Collection<String> aliases) {
- Makefile makefile = new Makefile("BRK_RES");
- makefile.addSyntheticAlias(aliases);
- makefile.addAliasSource();
- // Add variables for non-XML source files.
- makefile.addEntry("BRK_DICT_SOURCE", "List of dictionary files (dict).", dictSource);
- makefile.addEntry("BRK_SOURCE", "List of break iterator files (brk).", brkSource);
- makefile.addSource(sources);
- return makefile;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/CheckIBMCoverage.java b/tools/java/org/unicode/cldr/icu/CheckIBMCoverage.java
deleted file mode 100644
index 8aa6c68..0000000
--- a/tools/java/org/unicode/cldr/icu/CheckIBMCoverage.java
+++ /dev/null
@@ -1,348 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.unicode.cldr.ant.CLDRConverterTool;
-import org.unicode.cldr.test.CheckCLDR;
-import org.unicode.cldr.test.CheckCLDR.CheckStatus;
-import org.unicode.cldr.test.CheckCoverage;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.LDMLUtilities;
-import org.unicode.cldr.util.Level;
-import org.unicode.cldr.util.StandardCodes;
-import org.w3c.dom.Node;
-
-import com.ibm.icu.dev.tool.UOption;
-import com.ibm.icu.text.Transliterator;
-
-public class CheckIBMCoverage extends CLDRConverterTool {
- /**
- * These must be kept in sync with getOptions().
- */
- private static final int HELP1 = 0;
- private static final int HELP2 = 1;
- private static final int SOURCEDIR = 2;
- private static final int DESTDIR = 3;
- private static final int VERBOSE = 4;
-
- private static final UOption[] options = new UOption[] {
- UOption.HELP_H(),
- UOption.HELP_QUESTION_MARK(),
- UOption.SOURCEDIR(),
- UOption.DESTDIR(),
- UOption.VERBOSE(),
- };
-
- private String sourceDir = null;
- private String destDir = null;
- private boolean verbose = false;
-
- private void usage() {
- System.out.println("\nUsage: CheckIBMCoverage [OPTIONS] [FILES]\nCheckIBMCoverage [OPTIONS] -w [DIRECTORY] \n" +
- "This program is used to convert LDML files to ICU ResourceBundle TXT files.\n" +
- "Please refer to the following options. Options are not case sensitive.\n" +
- "Options:\n" +
- "-s or --sourcedir source directory for files followed by path, default is current directory.\n" +
- "-d or --destdir destination directory, followed by the path, default is current directory.\n" +
- "-h or -? or --help this usage text.\n" +
- "-v or --verbose print out verbose output.\n" +
- "example: org.unicode.cldr.icu.CheckIBMCoverage -s xxx -d yyy en.xml");
- System.exit(-1);
- }
-
- private void printInfo(String message) {
- if (verbose) {
- System.out.println("INFO : " + message);
- }
- }
-
- private void printWarning(String fileName, String message) {
- System.err.println(fileName + ": WARNING : " + message);
- }
-
- private void printError(String fileName, String message) {
- System.err.println(fileName + ": ERROR : " + message);
- }
-
- public static void main(String[] args) {
- CheckIBMCoverage cov = new CheckIBMCoverage();
- cov.processArgs(args);
- }
-
- public void processArgs(String[] args) {
- int remainingArgc = 0;
- // for some reason when
- // Class classDefinition = Class.forName(className);
- // object = classDefinition.newInstance();
- // is done then the options are not reset!!
- for (int i = 0; i < options.length; i++) {
- options[i].doesOccur = false;
- }
- try {
- remainingArgc = UOption.parseArgs(args, options);
- } catch (Exception e) {
- printError("", "(parsing args): " + e.toString());
- e.printStackTrace();
- usage();
- }
- if (args.length == 0 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
- usage();
- }
-
- if (options[SOURCEDIR].doesOccur) {
- sourceDir = options[SOURCEDIR].value;
- }
- if (options[DESTDIR].doesOccur) {
- destDir = options[DESTDIR].value;
- }
- if (options[VERBOSE].doesOccur) {
- verbose = true;
- }
- if (destDir == null) {
- destDir = ".";
- }
-
- try {
- if (getLocalesMap() != null && getLocalesMap().size() > 0) {
- processMap();
- } else if (remainingArgc > 0) {
- for (int i = 0; i < remainingArgc; i++) {
- processFile(args[i], verbose);
- }
- } else if (sourceDir != null) {
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- if (name.matches(".*_.*\\.xml")) {
- return true;
- }
- return false;
- }
- };
- File myDir = new File(sourceDir);
- String[] files = myDir.list(filter);
- if (getLocalesMap() == null) {
- setLocalesMap(new TreeMap<String, String>());
- }
- for (int i = 0; i < files.length; i++) {
- getLocalesMap().put(files[i], "");
- }
- processMap();
- } else {
- printError("", "No files specified for processing. Please check the arguments and try again");
- usage();
- }
- } catch (IOException ex) {
- printError("", ex.getMessage());
- ex.printStackTrace();
- }
- }
-
- private void processMap() throws IOException {
- FileWriter fw = new FileWriter(destDir + File.separator + "IBMCoverage.html");
- fw.write("<html>\n");
- fw.write("\t<body>\n");
- // fw.write("\t\t<br><b><font color=\"FF0000\">Note: Please ignore the POSIX column. The data is not accurate</font></b>\n");
- fw.write("\t\t<table border=\"1\">\n");
- fw.write("\t\t\t<tr>\n");
- fw.write("\t\t\t\t<th>Locale</td>\n");
- fw.write("\t\t\t\t<th>Group</td>\n");
- fw.write("\t\t\t\t<th>Minimum Coverage(POSIX)</td>\n");
- fw.write("\t\t\t\t<th>Minimum Coverage(BASIC)</td>\n");
- fw.write("\t\t\t\t<th>Minimum Coverage(ICU)</td>\n");
- fw.write("\t\t\t</tr>\n");
- int bp = 0, bf = 0, mp = 0, mf = 0;
-
- for (Iterator<String> iter = getLocalesMap().keySet().iterator(); iter.hasNext();) {
- String fileName = iter.next();
- int index = fileName.indexOf(".");
- String locale = fileName.substring(0, index);
- String glf = locale.concat("_group.log");
- String blf = locale.concat("_basic.log");
- String plf = locale.concat("_posix.log");
- StandardCodes sc = StandardCodes.make();
- String group = sc.getGroup(locale, "IBM");
- if (group == null) {
- printWarning(locale, " not required by IBM whitepaper");
- continue;
- }
- Level level = Level.get(group);
-
- fw.write("\t\t\t<tr>\n");
- fw.write("\t\t\t\t<td>" + locale + "</td>\n");
- fw.write("\t\t\t\t<td>" + group + "</td>\n");
-
- // check posix coverage
- int posix = processFile(locale, destDir + File.separator + plf, Level.POSIX, group, true);
- if (posix == 0) {
- fw.write("\t\t\t\t<td><img src=\"blue_check.gif\" border=\"0\" ALT=\"Pass\"></td>\n");
- mp++;
- } else {
- fw.write("\t\t\t\t<td><a href=\"" + plf
- + "\"><img src=\"red_x.gif\" border=\"0\" ALT=\"Fail\"></a></td>\n");
- mf++;
- }
-
- int basic = processFile(locale, destDir + File.separator + blf, Level.BASIC, group, true);
- if (basic == 0) {
- fw.write("\t\t\t\t<td><img src=\"blue_check.gif\" border=\"0\" ALT=\"Pass\"></td>\n");
- bp++;
- } else {
- fw.write("\t\t\t\t<td><a href=\"" + blf
- + "\"><img src=\"red_x.gif\" border=\"0\" ALT=\"Fail\"></a></td>\n");
- bf++;
- }
-
- if (level.equals(Level.POSIX)) {
- if (posix == 0) {
- fw.write("\t\t\t\t<td><img src=\"blue_check.gif\" border=\"0\" ALT=\"Pass\"></td>\n");
- } else {
- fw.write("\t\t\t\t<td><a href=\"" + glf
- + "\"><img src=\"red_x.gif\" border=\"0\" ALT=\"Fail\"></a></td>\n");
- }
- } else if (level.equals(Level.BASIC)) {
- if (basic == 0) {
- fw.write("\t\t\t\t<td><img src=\"blue_check.gif\" border=\"0\" ALT=\"Pass\"></td>\n");
- } else {
- fw.write("\t\t\t\t<td><a href=\"" + glf
- + "\"><img src=\"red_x.gif\" border=\"0\" ALT=\"Fail\"></a></td>\n");
- }
- } else {
- int out = processFile(locale, destDir + File.separator + glf, level, group, true);
-
- if (out == 0) {
- fw.write("\t\t\t\t<td><img src=\"blue_check.gif\" border=\"0\" ALT=\"Pass\"></td>\n");
- } else {
- fw.write("\t\t\t\t<td><a href=\"" + glf
- + "\"><img src=\"red_x.gif\" border=\"0\" ALT=\"Fail\"></a></td>\n");
- }
- }
- fw.write("\t\t\t</tr>\n");
- fw.flush();
- }
- fw.write("\t\t</table>\n");
-
- fw.write("\t\t<br><b><i>Note: </i></b>\n");
- fw.write("\t\t<ol>\n");
- fw.write("\t\t\t<il>POSIX==G4</il>\n");
- fw.write("\t\t\t<il>Basic==G3</il>\n");
- fw.write("\t\t\t<il>Moderate==G2</il>\n");
- fw.write("\t\t\t<il>Modern==G1</il>\n");
- fw.write("\t\t\t<il>Comprehensive==G0</il>\n");
- fw.write("\t\t</ol>\n");
- fw.write("\t\t<br><b>Basic Requirement Passed: " + bp + "</b>\n");
- fw.write("\t\t<br><b>Basic Requirement Failed: " + bf + "</b>\n");
- fw.write("\t\t<br><b>Total: " + (bp + bf) + "</b>\n");
- fw.write("\t\t<br><b>Posix Requirement Passed: " + mp + "</b>\n");
- fw.write("\t\t<br><b>Posix Requirement Failed: " + mf + "</b>\n");
- fw.write("\t\t<br><b>Total: " + (mp + mf) + "</b>\n");
- fw.write("\t</body>\n");
- fw.write("</html>\n");
- fw.flush();
- fw.close();
- }
-
- static Transliterator prettyPath = CheckCLDR.getTransliteratorFromFile("ID", "prettyPath.txt");
-
- private int processFile(String fileName, boolean pretty) throws IOException {
- int index = fileName.indexOf(".");
- String locale = fileName.substring(0, index);
- StandardCodes sc = StandardCodes.make();
- String group = sc.getGroup(locale, "IBM");
- if (group == null) {
- printWarning(locale, " not required by IBM whitepaper");
- return -1;
- }
- Level level = Level.get(group);
- int out = processFile(locale, destDir + File.separator + locale + "_posix.log", Level.POSIX, group, pretty);
- out = processFile(locale, destDir + File.separator + locale + "_basic.log", Level.BASIC, group, pretty);
- out = processFile(locale, destDir + File.separator + locale + "_group.log", level, group, pretty);
- return out;
- }
-
- private static final String RULES = "//ldml/collations/collation[@type=\"standard\"]/rules";
- private static final String COLLATIONS = "//ldml/collations";
-
- private int processFile(String locale, String logFile, Level level, String group, boolean pretty)
- throws IOException {
-
- // Map m = new TreeMap();
- FileWriter fw = new FileWriter(logFile);
- int ret = check(locale, group, level, fw);
- if (level.compareTo(Level.POSIX) == 0) {
- Node node = LDMLUtilities.getFullyResolvedLDML(sourceDir + "/../collation", locale, false, true, false,
- false);
- Node collation = LDMLUtilities.getNode(node, COLLATIONS);
- String validSubLocales = LDMLUtilities.getAttributeValue(collation, LDMLConstants.VALID_SUBLOCALE);
- if (validSubLocales == null || !validSubLocales.matches(".*\\b" + locale + ".*\\b")) {
- fw.write(COLLATIONS + " : Found but not valid according to validSublocales attribute");
- fw.write("\n");
- }
-
- Node rules = LDMLUtilities.getNode(node, RULES);
- if (rules == null) {
- fw.write(RULES + " : Not found. Required for POSIX level coverage");
- fw.write("\n");
- }
- }
- fw.flush();
- fw.close();
- return ret;
- }
-
- private int check(String locale, String group, Level level, FileWriter fw) throws IOException {
-
- Factory cldrFactory = Factory.make(sourceDir, "xml");
- CheckCoverage coverage = new CheckCoverage(cldrFactory);
- CLDRFile file = cldrFactory.make(locale, true);
- List<CheckStatus> result = new ArrayList<CheckStatus>();
- Map<String, String> options = new HashMap<String, String>();
- options.put("CoverageLevel.localeType", group);
- options.put("CheckCoverage.requiredLevel", group);
- options.put("submission", "true");
- printInfo("Processing file " + locale);
- coverage.setCldrFileToCheck(file, options, result);
- CLDRFile resolved = coverage.getResolvedCldrFileToCheck();
- Set<String> paths = new TreeSet<String>(resolved.getComparator());
- com.ibm.icu.dev.util.CollectionUtilities.addAll(resolved.iterator(), paths);
- int ret = 0;
- if (level != null) {
- coverage.setRequiredLevel(level);
- }
- for (Iterator<String> it2 = paths.iterator(); it2.hasNext();) {
-
- String path = (String) it2.next();
- String value = file.getStringValue(path);
- String fullPath = file.getFullXPath(path);
- if (verbose) {
- System.out.println(fullPath);
- }
- result.clear();
- coverage.check(path, fullPath, value, options, result);
- for (Iterator<CheckStatus> it3 = result.iterator(); it3.hasNext();) {
- CheckStatus status = (CheckStatus) it3.next();
- // String statusString = status.toString(); // com.ibm.icu.impl.Utility.escape(
- CheckStatus.Type statusType = status.getType();
-
- if (statusType.equals(CheckStatus.errorType)) {
- fw.write(fullPath + " : Untranslated. " + status.getMessage());
- fw.write("\n");
- ret = -1;
- continue;
- }
- }
- }
- return ret;
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/CollationMapper.java b/tools/java/org/unicode/cldr/icu/CollationMapper.java
deleted file mode 100644
index cd8b552..0000000
--- a/tools/java/org/unicode/cldr/icu/CollationMapper.java
+++ /dev/null
@@ -1,263 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.util.Builder;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CLDRFile.DraftStatus;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.PatternCache;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.ibm.icu.impl.Utility;
-import com.ibm.icu.text.MessageFormat;
-
-/**
- * Converts CLDR collation files to the ICU format.
- * @author jchye
- */
-public class CollationMapper extends Mapper {
- private static Pattern SPECIALS_PATH = PatternCache.get("//ldml/special/icu:([\\w_]++)\\[@icu:([\\w_]++)=\"([^\"]++)\"]");
- private String sourceDir;
- private Factory specialFactory;
- private Set<String> validSubLocales = new HashSet<String>();
-
- // TODO: CLDR 28 ticket #8289 "Move collator CLDR settings into ICU format"
- // deprecated the collation sub-elements
- // import, settings, suppress_contractions, and optimize
- // and changed the data from XML syntax to ICU syntax.
- // Remove conversion of these elements when we do not need to handle old data any more.
-
- // Some settings have to be converted to numbers.
- private Map<String, String> settingsMap = Builder.with(new HashMap<String, String>())
- .put("primary", "1")
- .put("secondary", "2")
- .put("tertiary", "3")
- .put("quarternary", "4")
- .put("identical", "5")
- .put("on", "2")
- .get();
-
- /**
- * @param sourceDir the source dir of the collation files
- * @param specialFactory the factory for any ICU-specific collation info
- */
- public CollationMapper(String sourceDir, Factory specialFactory) {
- this.sourceDir = sourceDir;
- this.specialFactory = specialFactory;
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format
- */
- @Override
- public IcuData[] fillFromCldr(String locale) {
- List<IcuData> dataList = new ArrayList<IcuData>();
- IcuData mainLocale = new IcuData("common/collation/" + locale + ".xml", locale, true);
- CollationHandler handler = new CollationHandler(mainLocale);
- File file = new File(sourceDir, locale + ".xml");
- MapperUtils.parseFile(file, handler);
- dataList.add(mainLocale);
-
- String[] subLocales = handler.getSubLocales();
- if (subLocales != null) {
- for (String subLocale : subLocales) {
- dataList.add(fillSubLocale(locale, subLocale));
- validSubLocales.add(subLocale);
- }
- }
-
- if (hasSpecialFile(locale)) {
- CLDRFile specialFile = specialFactory.make(locale, false);
- mainLocale.setFileComment("ICU <specials> source: <path>/xml/collation/" + locale + ".xml");
- for (String path : specialFile) {
- String fullPath = specialFile.getFullXPath(path);
- Matcher matcher = SPECIALS_PATH.matcher(fullPath);
- if (matcher.matches()) {
- mainLocale.add(
- MessageFormat.format("/{0}:process({1})", matcher.group(1), matcher.group(2)),
- matcher.group(3));
- }
- }
- }
-
- return MapperUtils.toArray(dataList);
- }
-
- /**
- * Creates an IcuData object for the specified sublocale
- * @param locale the parent of the sublocale
- * @param subLocale the sublocale
- * @return
- */
- private IcuData fillSubLocale(String locale, String subLocale) {
- IcuData icuData = new IcuData("icu-config.xml & build.xml", subLocale, true);
- icuData.setFileComment("validSubLocale of \"" + locale + "\"");
- icuData.add("/___", "");
- return icuData;
- }
-
- /**
- * @param filename
- * @return true if a special XML file with the specified filename is available.
- */
- private boolean hasSpecialFile(String filename) {
- return specialFactory != null && specialFactory.getAvailable().contains(filename);
- }
-
- /**
- * The XML handler for collation data.
- */
- private class CollationHandler extends MapperUtils.EmptyHandler {
- private IcuData icuData;
- private StringBuilder currentText = new StringBuilder();
- private String collationType;
- private boolean isShort;
- private List<String> properties = new ArrayList<String>();
- private List<String> rules = new ArrayList<String>();
- private String[] subLocales;
-
- public CollationHandler(IcuData icuData) {
- this.icuData = icuData;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- if (qName.equals("collation")) {
- DraftStatus status = DraftStatus.forString(attr.getValue("draft"));
- collationType = status.compareTo(DraftStatus.contributed) < 0 ? null : attr.getValue("type");
- isShort = attr.getValue("alt") != null;
- properties.clear();
- rules.clear();
- } else if (qName.equals("collations")) {
- String validSubLocales = attr.getValue("validSubLocales");
- if (validSubLocales != null) {
- subLocales = validSubLocales.split("\\s++");
- }
- } else if (qName.equals("version")) {
- icuData.add("/Version", CLDRFile.GEN_VERSION);
- }
- if (collationType == null) return;
-
- // Collation-specific elements.
- if (qName.equals("settings")) {
- for (int i = 0; i < attr.getLength(); i++) {
- String name = attr.getLocalName(i);
- String value = attr.getValue(i);
- if (name.equals("strength") || name.equals("backwards")) {
- value = settingsMap.get(value);
- } else if (name.equals("hiraganaQuaternary")) {
- name = "hiraganaQ";
- }
- properties.add(name + " " + value);
- }
- } else if (qName.equals("import")) {
- String value = attr.getValue("source");
- String type = attr.getValue("type");
- if (type != null) {
- value += "-u-co-" + type;
- }
- properties.add("import " + value);
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- // collationType will only be null if the draft status is insufficient.
- if (qName.equals("defaultCollation")) {
- icuData.add("/collations/default", currentText.toString());
- } else if (collationType == null) {
- currentText.setLength(0);
- return;
- }
-
- if (qName.equals("suppress_contractions")) {
- properties.add("suppressContractions " + currentText.toString());
- } else if (qName.equals("cr")) {
- String[] lines = currentText.toString().split("\n");
- for (String line : lines) {
- int commentPos = Utility.quotedIndexOf(line, 0, line.length(), "#");
- if (commentPos > -1) {
- line = line.substring(0, commentPos);
- }
- line = line.trim();
- if (line.length() > 0) {
- rules.add(line);
- }
- }
- } else if (qName.equals("collation")) {
- // Add attributes before the main rules.
- StringBuilder attrBuffer = new StringBuilder();
- if (properties.size() > 0) {
- for (String property : properties) {
- attrBuffer.append('[').append(property).append(']');
- }
- rules.add(0, attrBuffer.toString());
- }
-
- String[] rulesArray;
- if (rules.size() == 0) {
- rulesArray = new String[] { "" };
- } else {
- rulesArray = new String[rules.size()];
- rules.toArray(rulesArray);
- }
-
- String rbPath = "/collations/" + collationType + "/Sequence";
- // Always prefer the short version.
- if (isShort || !icuData.containsKey(rbPath)) {
- icuData.replace(rbPath, rulesArray);
- icuData.replace("/collations/" + collationType + "/Version", new String[] { CLDRFile.GEN_VERSION });
- }
- }
- currentText.setLength(0);
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- currentText.append(ch, start, length);
- }
-
- public String[] getSubLocales() {
- return subLocales;
- }
- }
-
- @Override
- public Collection<String> getAvailable() {
- return MapperUtils.getNames(sourceDir);
- }
-
- @Override
- public Makefile generateMakefile(Collection<String> aliases) {
- Makefile makefile = new Makefile("COLLATION");
- makefile.addSyntheticAlias(aliases);
- makefile.addAliasSource();
- // Split sources into locales and sublocales.
- List<String> subLocales = new ArrayList<String>();
- List<String> locales = new ArrayList<String>();
- locales.add("$(COLLATION_EMPTY_SOURCE)");
- for (String source : sources) {
- if (validSubLocales.contains(source)) {
- subLocales.add(source);
- } else {
- locales.add(source);
- }
- }
- makefile.addEntry("COLLATION_EMPTY_SOURCE",
- "Empty locales, used for validSubLocale fallback.",
- subLocales);
- makefile.addSource(locales);
- return makefile;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/CompareIcuOutput.java b/tools/java/org/unicode/cldr/icu/CompareIcuOutput.java
deleted file mode 100644
index b66dc78..0000000
--- a/tools/java/org/unicode/cldr/icu/CompareIcuOutput.java
+++ /dev/null
@@ -1,514 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.tool.Option.Options;
-
-import com.ibm.icu.impl.Row;
-import com.ibm.icu.impl.Row.R2;
-import com.ibm.icu.impl.Utility;
-import com.ibm.icu.lang.UCharacter;
-import com.ibm.icu.text.UForwardCharacterIterator;
-import com.ibm.icu.text.UTF16;
-import com.ibm.icu.text.UnicodeSet;
-
-/**
- * Compares the contents of ICU data output while ignoring comments.
- *
- * @author markdavis, jchye
- *
- */
-public class CompareIcuOutput {
- private static final boolean DEBUG = false;
-
- private static final Options options = new Options(
- "Usage: RBChecker [OPTIONS] DIR1 DIR2 FILE_REGEX\n" +
- "This program is used to compare the RB text files in two different directories.\n" +
- " Example: org.unicode.cldr.icu.RBChecker olddatadir newdatadir .*")
- .add("sort", 's', null, null, "Sort values for comparison");
-
- private static final Comparator<String[]> comparator = new Comparator<String[]>() {
- @Override
- public int compare(String[] arg0, String[] arg1) {
- return arg0[0].compareTo(arg1[0]);
- }
- };
-
- private static boolean shouldSort = false;
-
- public static void main(String[] args) throws IOException {
- String dir1 = args[0];
- String dir2 = args[1];
- String regex = args[2];
- System.out.println("dir1 " + dir1);
- System.out.println("dir2 " + dir2);
- System.out.println("regex " + regex);
- shouldSort = options.get("sort").doesOccur();
- long totaltime = System.currentTimeMillis();
- System.out.println("Comparing the contents of text files...");
- compareTextFiles(dir1, dir2, regex);
- System.out.println("Total time taken: " + (System.currentTimeMillis() - totaltime));
- }
-
- /**
- * Parses and compares two ICU textfiles.
- *
- * @param dir1
- * @param dir2
- * @param regex
- * @throws IOException
- */
- private static void compareTextFiles(String dir1, String dir2, String regex) throws IOException {
- File localeDir = new File(dir1);
- if (!localeDir.exists()) localeDir = new File(dir1);
- String[] filenames = localeDir.list();
- int same = 0, different = 0;
- for (String filename : filenames) {
- if (!filename.matches(regex + "\\.txt")) continue;
- String locale = filename.substring(0, filename.length() - 4);
- try {
- IcuData oldData = loadDataFromTextfiles(dir1, locale);
- IcuData newData = loadDataFromTextfiles(dir2, locale);
- StringBuffer messages = new StringBuffer();
- if (analyseMatches(oldData, newData, messages)) {
- System.out.println("=== Differences found for " + locale + " ===");
- System.out.print(messages);
- different++;
- } else {
- same++;
- }
- } catch (FileNotFoundException e) {
- System.err.println(locale + " file not found, skipping");
- }
- }
- System.out.println("Check finished with " + different + " different and " + same + " same locales.");
- }
-
- private static IcuData loadDataFromTextfiles(String icuPath, String locale) throws IOException {
- List<Row.R2<MyTokenizer.Type, String>> comments = new ArrayList<Row.R2<MyTokenizer.Type, String>>();
- IcuData icuData = new IcuData(locale + ".xml", locale, true);
- String filename = icuPath + '/' + locale + ".txt";
- if (new File(filename).exists()) {
- parseRB(filename, icuData, comments);
- } else {
- throw new FileNotFoundException(filename + " does not exist.");
- }
- return icuData;
- }
-
- /**
- * Computes lists of all differences between two sets of IcuData.
- *
- * @param oldData
- * @param newData
- */
- private static boolean analyseMatches(IcuData oldData, IcuData newData, StringBuffer buffer) {
- boolean hasDifferences = false;
- Set<String> missing = new TreeSet<String>(oldData.keySet());
- missing.removeAll(newData.keySet());
- if (missing.size() > 0) {
- buffer.append("Missing paths:\n");
- printAllInSet(oldData, missing, buffer);
- hasDifferences = true;
- }
- Set<String> extra = new TreeSet<String>(newData.keySet());
- extra.removeAll(oldData.keySet());
- if (extra.size() > 0) {
- buffer.append("Extra paths:\n");
- printAllInSet(newData, extra, buffer);
- hasDifferences = true;
- }
- Set<String> common = new TreeSet<String>(oldData.keySet());
- common.retainAll(newData.keySet());
- for (String rbPath : common) {
- if (rbPath.startsWith("/Version")) continue; // skip version
- List<String[]> oldValues = oldData.get(rbPath);
- List<String[]> newValues = newData.get(rbPath);
- if (shouldSort) {
- Collections.sort(oldValues, comparator);
- Collections.sort(newValues, comparator);
- }
- // Print out any value differences.
- if (valuesDiffer(oldValues, newValues)) {
- buffer.append(rbPath + " contains differences:\n");
- buffer.append("\tOld: ");
- printValues(oldValues, buffer);
- buffer.append("\tNew: ");
- printValues(newValues, buffer);
- hasDifferences = true;
- }
- }
- return hasDifferences;
- }
-
- private static void printAllInSet(IcuData icuData, Set<String> paths, StringBuffer buffer) {
- for (String path : paths) {
- buffer.append("\t" + path + " = ");
- printValues(icuData.get(path), buffer);
- }
- }
-
- private static void printValues(List<String[]> values, StringBuffer buffer) {
- // Enclose both numbers and strings in quotes for simplicity.
- for (String[] array : values) {
- if (array.length == 1) {
- buffer.append('"' + array[0] + '"');
- } else {
- buffer.append("[");
- for (String value : array) {
- buffer.append('"' + value + "\", ");
- }
- buffer.append("]");
- }
- buffer.append(", ");
- }
- buffer.append('\n');
- }
-
- /**
- * @param oldValues
- * @param newValues
- * @return true if the contents of the lists are identical
- */
- private static boolean valuesDiffer(List<String[]> oldValues, List<String[]> newValues) {
- if (oldValues.size() != newValues.size()) return true;
- boolean differ = false;
- for (int i = 0; i < oldValues.size(); i++) {
- String[] oldArray = oldValues.get(i);
- String[] newArray = newValues.get(i);
- if (oldArray.length != newArray.length) {
- differ = true;
- break;
- }
- for (int j = 0; j < oldArray.length; j++) {
- // Ignore whitespace.
- if (!oldArray[j].replace(" ", "").equals(newArray[j].replace(" ", ""))) {
- differ = true;
- break;
- }
- }
- }
- return differ;
- }
-
- /**
- * Parse an ICU resource bundle into key,value items
- *
- * @param filename
- * @param output
- * @param comments
- */
- static void parseRB(String filename, IcuData icuData, List<R2<MyTokenizer.Type, String>> comments)
- throws IOException {
- BufferedReader in = null;
- File file = new File(filename);
- String coreFile = file.getName();
- if (!coreFile.endsWith(".txt")) {
- throw new IllegalArgumentException("missing .txt in: " + filename);
- }
- coreFile = coreFile.substring(0, coreFile.length() - 4);
- // redo this later on to use fixed PatternTokenizer
- in = FileUtilities.openUTF8Reader("", filename);
- MyTokenizer tokenIterator = new MyTokenizer(in);
- StringBuffer tokenText = new StringBuffer();
- List<String> oldPaths = new ArrayList<String>();
- List<Integer> indices = new ArrayList<Integer>();
- String lastLabel = null;
- String path = "";
- /*
- * AuxExemplarCharacters{
- * "[á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ"
- * "]" } ExemplarCharacters{
- * "[a b c d e f g h i j k l m n o p q r s t u v w x y z]"}
- * ExemplarCharactersCurrency
- * {"[a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z]"}
- * ExemplarCharactersIndex
- * {"[A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]"}
- * ExemplarCharactersPunctuation{"[\- ‐ – — , ; \: ! ? . … ' ‘ ’ \"
- * “ ” ( ) \[ \] @ * / \& # † ‡ ′ ″ §]"}
- */
- MyTokenizer.Type lastToken = null;
- List<String> arrayValues = null;
- while (true) {
- MyTokenizer.Type nextToken = tokenIterator.next(tokenText);
- if (DEBUG)
- System.out.println(nextToken + "\t" + tokenText);
- switch (nextToken) {
- case BLOCK_COMMENT:
- case LINE_COMMENT:
- if (comments != null) {
- comments.add(Row.of(nextToken, tokenText.toString()));
- }
- continue;
- case DONE:
- if (oldPaths.size() != 0) {
- throw new IllegalArgumentException("missing }");
- }
- in.close();
- return;
- case ID:
- lastLabel = lastLabel == null ? tokenText.toString() : lastLabel + " " + tokenText;
- break;
- case QUOTED:
- if (lastLabel == null) {
- lastLabel = tokenText.toString();
- } else {
- // Remove consecutive quotes.
- lastLabel += tokenText;
- }
- break;
- case OPEN_BRACE:
- // Check for array-type values.
- if (lastToken == MyTokenizer.Type.COMMA) {
- arrayValues = new ArrayList<String>();
- } else {
- oldPaths.add(path);
- indices.add(0);
- if (lastToken == MyTokenizer.Type.OPEN_BRACE || lastToken == MyTokenizer.Type.CLOSE_BRACE) {
- int currentIndexPos = indices.size() - 2;
- int currentIndex = indices.get(currentIndexPos);
- lastLabel = "<" + currentIndex + ">";
- indices.set(currentIndexPos, currentIndex + 1);
- } else if (lastLabel.contains(":") && !lastLabel.contains(":int") && !lastLabel.contains(":alias")
- || path.endsWith("/relative")) {
- lastLabel = '"' + lastLabel + '"';
- }
- path += "/" + lastLabel;
- }
- lastLabel = null;
- break;
- case CLOSE_BRACE:
- if (lastLabel != null) {
- addPath(path, lastLabel, icuData);
- lastLabel = null;
- }
-
- if (arrayValues == null) {
- path = oldPaths.remove(oldPaths.size() - 1);
- indices.remove(indices.size() - 1);
- } else {
- // Value array closed, add it to the path.
- String[] array = new String[0];
- addPath(path, arrayValues.toArray(array), icuData);
- arrayValues = null;
- }
- if (DEBUG)
- System.out.println("POP:\t" + path);
- break;
- case COMMA:
- if (lastToken != MyTokenizer.Type.QUOTED && lastToken != MyTokenizer.Type.ID) {
- throw new IllegalArgumentException(filename + ", " + path + ": Commas can only occur after values ");
- } else if (lastLabel == null) {
- throw new IllegalArgumentException(filename + ": Label missing!");
- }
- if (arrayValues != null) {
- arrayValues.add(lastLabel);
- } else {
- addPath(path, lastLabel, icuData);
- }
- lastLabel = null;
- break;
- default:
- throw new IllegalArgumentException("Illegal type in " + filename + ": " + nextToken + "\t" + tokenText
- + "\t" + Utility.hex(tokenText));
- }
- lastToken = nextToken;
- }
- }
-
- private static void addPath(String path, String value, IcuData icuData) {
- addPath(path, new String[] { value }, icuData);
- }
-
- private static void addPath(String path, String[] values, IcuData icuData) {
- path = path.substring(path.indexOf('/', 1));
- icuData.add(path, values);
- }
-
- /**
- * Reads in tokens from an ICU data file reader.
- * Replace by updated PatternTokenizer someday
- *
- * @author markdavis
- *
- */
- static class MyTokenizer {
- enum Type {
- DONE, ID, QUOTED, OPEN_BRACE, CLOSE_BRACE, COMMA, LINE_COMMENT, BLOCK_COMMENT, BROKEN_QUOTE, BROKEN_BLOCK_COMMENT, UNKNOWN
- }
-
- private final UForwardCharacterIterator source;
- private final UnicodeSet spaceCharacters = new UnicodeSet("[\\u0000\\uFEFF[:pattern_whitespace:]]");
- private final UnicodeSet idCharacters = new UnicodeSet("[-+.():%\"'[:xid_continue:]]");
- private final UnicodeSet quoteCharacters = new UnicodeSet("[\"']");
-
- private int bufferedChar;
-
- /**
- * @param reader
- */
- public MyTokenizer(Reader reader) {
- this.source = new UReaderForwardCharacterIterator(reader);
- }
-
- public Type next(StringBuffer tokenText) {
- int cp = getCodePoint();
- // Skip all spaces not in quotes.
- while (cp >= 0 && spaceCharacters.contains(cp)) {
- cp = getCodePoint();
- }
-
- if (cp == -1) {
- return Type.DONE;
- }
- tokenText.setLength(0);
- if (cp == '/') {
- cp = getCodePoint();
- if (cp == '/') { // line comment
- while (true) {
- cp = getCodePoint();
- if (cp == '\n' || cp < 0) {
- return Type.LINE_COMMENT;
- }
- tokenText.appendCodePoint(cp);
- }
- } else if (cp == '*') { // block comment
- while (true) {
- cp = getCodePoint();
- if (cp < 0) {
- return Type.BROKEN_BLOCK_COMMENT;
- }
- while (cp == '*') {
- int cp2 = getCodePoint();
- if (cp2 < 0) {
- return Type.BROKEN_BLOCK_COMMENT;
- } else if (cp2 == '/') {
- return Type.BLOCK_COMMENT;
- }
- tokenText.appendCodePoint(cp);
- cp = cp2;
- }
- tokenText.appendCodePoint(cp);
- }
- } else {
- throw new IllegalArgumentException("/ can only be in quotes or comments");
- }
- }
- if (quoteCharacters.contains(cp)) {
- // Return the text inside and *excluding* the quotes.
- int oldQuote = cp;
- cp = getCodePoint();
- while (cp != oldQuote) {
- if (cp < 0) {
- return Type.BROKEN_QUOTE;
- } else if (cp == '\\') {
- tokenText.appendCodePoint(cp);
- cp = getCodePoint();
- if (cp < 0) {
- return Type.BROKEN_QUOTE;
- }
- }
- tokenText.appendCodePoint(cp);
- cp = getCodePoint();
- }
- ;
- return Type.QUOTED;
- }
- if (cp == '{') {
- return Type.OPEN_BRACE;
- }
- if (cp == '}') {
- return Type.CLOSE_BRACE;
- }
- if (cp == ',') {
- return Type.COMMA;
- }
- if (idCharacters.contains(cp)) {
- while (true) {
- tokenText.appendCodePoint(cp);
- cp = getCodePoint();
- if (cp < 0 || !idCharacters.contains(cp)) {
- pushCodePoint(cp);
- return Type.ID;
- }
- }
- }
- tokenText.appendCodePoint(cp);
- return Type.UNKNOWN;
- }
-
- int getCodePoint() {
- if (bufferedChar >= 0) {
- int result = bufferedChar;
- bufferedChar = -1;
- return result;
- }
- return source.nextCodePoint();
- }
-
- void pushCodePoint(int codepoint) {
- if (bufferedChar >= 0) {
- throw new IllegalArgumentException("Cannot push twice");
- }
- bufferedChar = codepoint;
- }
- }
-
- public static class UReaderForwardCharacterIterator implements UForwardCharacterIterator {
- private Reader reader;
- private int bufferedChar = -1;
-
- /**
- * @param reader
- */
- public UReaderForwardCharacterIterator(Reader reader) {
- this.reader = reader;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.ibm.icu.text.UForwardCharacterIterator#next()
- */
- public int next() {
- if (bufferedChar >= 0) {
- int temp = bufferedChar;
- bufferedChar = -1;
- return temp;
- }
- try {
- return reader.read();
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.ibm.icu.text.UForwardCharacterIterator#nextCodePoint()
- */
- public int nextCodePoint() {
- int ch1 = next();
- if (UTF16.isLeadSurrogate((char) ch1)) {
- int bufferedChar = next();
- if (UTF16.isTrailSurrogate((char) bufferedChar)) {
- return UCharacter.getCodePoint((char) ch1,
- (char) bufferedChar);
- }
- }
- return ch1;
- }
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/ConvertTransforms.java b/tools/java/org/unicode/cldr/icu/ConvertTransforms.java
deleted file mode 100644
index 9a41a18..0000000
--- a/tools/java/org/unicode/cldr/icu/ConvertTransforms.java
+++ /dev/null
@@ -1,391 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.unicode.cldr.ant.CLDRConverterTool;
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CLDRFile.DraftStatus;
-import org.unicode.cldr.util.CLDRPaths;
-import org.unicode.cldr.util.CldrUtility;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.XPathParts;
-
-import com.ibm.icu.dev.tool.UOption;
-import com.ibm.icu.dev.util.ElapsedTimer;
-import com.ibm.icu.text.Transliterator;
-
-/**
- * Utility to generate the Tansliteration resource bundle files.
- */
-public class ConvertTransforms extends CLDRConverterTool {
-
- private static final int HELP1 = 0,
- HELP2 = 1,
- SOURCEDIR = 2,
- DESTDIR = 3,
- MATCH = 4,
- SKIP_COMMENTS = 5,
- WRITE_INDEX = 6,
- VERBOSE = 7,
- APPROVED_ONLY = 8;
-
- private static final UOption[] options = {
- UOption.HELP_H(),
- UOption.HELP_QUESTION_MARK(),
- UOption.SOURCEDIR().setDefault(CLDRPaths.COMMON_DIRECTORY + "transforms/"),
- UOption.DESTDIR().setDefault(CLDRPaths.GEN_DIRECTORY + "icu-transforms/"),
- UOption.create("match", 'm', UOption.REQUIRES_ARG).setDefault(".*"),
- UOption.create("commentSkip", 'c', UOption.NO_ARG),
- UOption.create("writeIndex", 'x', UOption.NO_ARG),
- UOption.VERBOSE(),
- UOption.create("approvedOnly", 'a', UOption.NO_ARG),
- };
-
- static final String HELP_TEXT1 = "Use the following options" + XPathParts.NEWLINE
- + "-h or -?\t for this message" + XPathParts.NEWLINE
- + "-" + options[SOURCEDIR].shortName + "\t source directory. Default = -s"
- + CldrUtility.getCanonicalName(CLDRPaths.MAIN_DIRECTORY) + XPathParts.NEWLINE
- + "\tExample:-sC:\\Unicode-CVS2\\cldr\\common\\gen\\source\\" + XPathParts.NEWLINE
- + "-" + options[DESTDIR].shortName + "\t destination directory. Default = -d"
- + CldrUtility.getCanonicalName(CLDRPaths.GEN_DIRECTORY + "main/") + XPathParts.NEWLINE
- + "-m<regex>\t to restrict the files to what matches <regex>" + XPathParts.NEWLINE
- + "-a\t to only include transforms with approved/contributed status" + XPathParts.NEWLINE
- // "--writeIndex / -x to write the index (trnsfiles.mk)"+ XPathParts.NEWLINE
- ;
-
- // TODO add options to set input and output directories, matching pattern
- public static void main(String[] args) throws Exception {
- ConvertTransforms ct = new ConvertTransforms();
- ct.processArgs(args);
- }
-
- private boolean skipComments;
- private boolean writeIndex = false;
- private boolean verbose = false;
- private boolean approvedOnly = false;
-
- int fileCount = 0;
-
- public void writeTransforms(String inputDirectory, String matchingPattern, String outputDirectory)
- throws IOException {
- System.out.println(new File(inputDirectory).getCanonicalPath());
- Factory cldrFactory = (approvedOnly) ? Factory.make(inputDirectory, matchingPattern, DraftStatus.contributed)
- : Factory.make(inputDirectory, matchingPattern);
- Set<String> ids = cldrFactory.getAvailable();
- PrintWriter index = FileUtilities.openUTF8Writer(outputDirectory, "root.txt");
- doHeader(index, "//", "root.txt");
- try {
- index.println("root {");
- index.println(" RuleBasedTransliteratorIDs {");
- // addAlias(index, "Latin", "el", "", "Latin", "Greek", "UNGEGN");
- // addAlias(index, "el", "Latin", "", "Greek", "Latin", "UNGEGN");
- // addAlias(index, "Latin", "Jamo", "", "Latin", "ConjoiningJamo", "");
- addAlias(index, "Tone", "Digit", "", "Pinyin", "NumericPinyin", "");
- addAlias(index, "Digit", "Tone", "", "NumericPinyin", "Pinyin", "");
- // addAlias(index, "Simplified", "Traditional", "", "Hans", "Hant", "");
- // addAlias(index, "Traditional", "Simplified", "", "Hant", "Hans", "");
- for (String id : ids) {
- if (id.equals("All")) continue;
- try {
- convertFile(cldrFactory, id, outputDirectory, index);
- } catch (IOException e) {
- System.err.println("Failure in: " + id);
- throw e;
- }
- }
- index.println(" }");
- index.println(" TransliteratorNamePattern {");
- index.println(" // Format for the display name of a Transliterator.");
- index.println(" // This is the language-neutral form of this resource.");
- index.println(" \"{0,choice,0#|1#{1}|2#{1}-{2}}\" // Display name");
- index.println(" }");
- index.println(" // Transliterator display names");
- index.println(" // This is the English form of this resource.");
- index.println(" \"%Translit%Hex\" { \"%Translit%Hex\" }");
- index.println(" \"%Translit%UnicodeName\" { \"%Translit%UnicodeName\" }");
- index.println(" \"%Translit%UnicodeChar\" { \"%Translit%UnicodeChar\" }");
- index.println(" TransliterateLATIN{ ");
- index.println(" \"\",");
- index.println(" \"\"");
- index.println(" }");
- index.println("}");
- } finally {
- index.close();
- }
- }
-
- public static PrintWriter makePrintWriter(ByteArrayOutputStream bytes) {
- try {
- OutputStreamWriter outStream = new OutputStreamWriter(bytes, "UTF-8");
- BufferedWriter buff = new BufferedWriter(outStream, 4 * 1024);
- PrintWriter p = new PrintWriter(buff);
-
- return p;
- } catch (Exception e) {
- System.err.println("Error: Could not create OutputStreamWriter.");
- }
- return null;
- }
-
- private void showComments(PrintWriter toilet, String value) {
- String[] lines = value.trim().split("\\r\\n?|\\n");
- for (String line : lines) {
- if (!line.startsWith("#")) {
- line = "# " + line;
- }
- toilet.println(line);
- }
- }
-
- private void convertFile(Factory cldrFactory, String id, String outputDirectory, PrintWriter index)
- throws IOException {
- PrintWriter output = null;
- String filename = null;
- CLDRFile cldrFile = cldrFactory.make(id, false);
- boolean first = true;
- for (Iterator<String> it = cldrFile.iterator("", cldrFile.getComparator()); it.hasNext();) {
- String path = it.next();
- if (path.indexOf("/version") >= 0 || path.indexOf("/generation") >= 0) {
- continue;
- }
- String value = cldrFile.getStringValue(path);
- if (first) {
- String fullPath = cldrFile.getFullXPath(path);
- filename = addIndexInfo(index, fullPath);
- if (filename == null) {
- return; // not a transform file!
- }
- output = FileUtilities.openUTF8Writer(outputDirectory, filename);
- doHeader(output, "#", filename);
- first = false;
- }
- if (path.indexOf("/comment") >= 0) {
- if (!skipComments) {
- showComments(output, value);
- }
- } else if (path.indexOf("/tRule") >= 0) {
- value = fixup.transliterate(value);
- value = value.replaceAll(CldrUtility.LINE_SEPARATOR, System.lineSeparator());
- output.println(value);
- } else {
- throw new IllegalArgumentException("Unknown element: " + path + "\t " + value);
- }
- }
- if (output != null) { // null for transforms whose draft status is too low
- output.close();
- }
- }
-
- public static final Transliterator fixup = Transliterator.getInstance("[:Mn:]any-hex/java");
-
- public static String replaceUnquoted(String value, String toReplace, String replacement) {
- // quick exit in most cases
- if (value.indexOf(toReplace) < 0)
- return value;
-
- String updatedValue = "";
- int segmentStart = 0;
- boolean inQuotes = false;
- boolean ignoreCharValue = false;
- int length = value.length();
-
- for (int pos = 0; pos < length; ++pos) {
- char curChar = (char) 0;
-
- if (ignoreCharValue) {
- ignoreCharValue = false;
- } else {
- curChar = value.charAt(pos);
- }
-
- if (curChar == '\\') {
- // escape, ignore the value of the next char (actually the next UTF16 code unit, but that works here)
- ignoreCharValue = true;
- }
- boolean isLastChar = (pos + 1 >= length);
- if (curChar == '\'' || isLastChar) {
- // quote, begin or end of a quoted literal (in which no replacement takes place)
- if (inQuotes) {
- // End of a quoted segment; guaranteed to include at least opening quote.
- // Just add the segment (including current char) to updatedValue.
- updatedValue = updatedValue + value.substring(segmentStart, pos + 1);
- segmentStart = pos + 1;
- } else {
- if (isLastChar)
- ++pos;
- if (pos > segmentStart) {
- // End of a nonempty unquoted segment; perform requested replacements and
- // then add segment to updatedValue.
- String currentSegment = value.substring(segmentStart, pos);
- updatedValue = updatedValue + currentSegment.replace(toReplace, replacement);
- segmentStart = pos;
- }
- }
- inQuotes = !inQuotes;
- }
- // else the char just becomes part of the current segment
- }
- return updatedValue;
- }
-
- private String addIndexInfo(PrintWriter index, String path) {
- XPathParts parts = XPathParts.getFrozenInstance(path);
- Map<String, String> attributes = parts.findAttributes("transform");
- if (attributes == null) return null; // error, not a transform file
- String source = attributes.get("source");
- String target = attributes.get("target");
- String variant = attributes.get("variant");
- String direction = attributes.get("direction");
- String alias = attributes.get("alias");
- String backwardAlias = attributes.get("backwardAlias");
- String visibility = attributes.get("visibility");
-
- String status = "internal".equals(visibility) ? "internal" : "file";
-
- fileCount++;
-
- String id = source + "-" + target;
- String rid = target + "-" + source;
- String filename = source + "_" + target;
- if (variant != null) {
- id += "/" + variant;
- rid += "/" + variant;
- filename += "_" + variant;
- }
- filename += ".txt";
-
- if (direction.equals("both") || direction.equals("forward")) {
- if (verbose) {
- System.out.println(" " + id + " " + filename + " " + "FORWARD");
- }
- if (alias != null) {
- for (String ali : alias.trim().split("\\s+")) {
- addAlias(index, ali, id);
- }
- }
- index.println(" " + id + " {");
- index.println(" " + status + " {");
- index.println(" resource:process(transliterator) {\"" + filename + "\"}");
- index.println(" direction {\"FORWARD\"}");
- index.println(" }");
- index.println(" }");
- }
- if (direction.equals("both") || direction.equals("backward")) {
- if (verbose) {
- System.out.println(" " + rid + " " + filename + " " + "REVERSE");
- }
- if (backwardAlias != null) {
- for (String bali : backwardAlias.trim().split("\\s+")) {
- addAlias(index, bali, rid);
- }
- }
- index.println(" " + rid + " {");
- index.println(" " + status + " {");
- index.println(" resource:process(transliterator) {\"" + filename + "\"}");
- index.println(" direction {\"REVERSE\"}");
- index.println(" }");
- index.println(" }");
- }
- index.println();
- return filename;
- }
-
- void addAlias(PrintWriter index, String aliasSource, String aliasTarget, String aliasVariant,
- String originalSource, String originalTarget, String originalVariant) {
- // Spacedhan-Han {
- // alias {"null"}
- // }
- addAlias(index, getName(aliasSource, aliasTarget, aliasVariant),
- getName(originalSource, originalTarget, originalVariant));
- }
-
- private void addAlias(PrintWriter index, String alias, String original) {
- index.println(" " + alias + " {");
- index.println(" alias" + " {\"" + original + "\"}");
- index.println(" }");
- }
-
- String getName(String source, String target, String variant) {
- String id = source + "-" + target;
- if (variant != null && variant.length() != 0) {
- id += "/" + variant;
- }
- return id;
- }
-
- private void doHeader(PrintWriter output, String quoteSymbol, String filename) {
- output.print('\uFEFF');
- output.println(quoteSymbol + " © 2016 and later: Unicode, Inc. and others.");
- output.println(quoteSymbol + " License & terms of use: http://www.unicode.org/copyright.html#License");
- output.println(quoteSymbol);
- output.println(quoteSymbol + " File: " + filename);
- output.println(quoteSymbol + " Generated from CLDR");
- output.println(quoteSymbol);
- }
-
- public void processArgs(String[] args) {
- UOption.parseArgs(args, options);
- if (options[HELP1].doesOccur || options[HELP2].doesOccur) {
- System.out.println(HELP_TEXT1);
- return;
- }
-
- String sourceDir = options[SOURCEDIR].value; // Utility.COMMON_DIRECTORY + "transforms/";
- String targetDir = options[DESTDIR].value; // Utility.GEN_DIRECTORY + "main/";
- String match = options[MATCH].value;
- skipComments = options[SKIP_COMMENTS].doesOccur;
- writeIndex = options[WRITE_INDEX].doesOccur;
- verbose = options[VERBOSE].doesOccur;
- approvedOnly = options[APPROVED_ONLY].doesOccur;
-
- try {
- if (writeIndex) {
- throw new InternalError("writeIndex not implemented.");
- } else {
- ElapsedTimer et = new ElapsedTimer();
- writeTransforms(sourceDir, match, targetDir + File.separator);
- System.out.println("ConvertTransforms: wrote " + fileCount +
- " files in " + et);
- }
- } catch (IOException ex) {
- RuntimeException e = new RuntimeException();
- e.initCause(ex.getCause());
- throw e;
- } finally {
- System.out.println("DONE");
- }
- }
-
- // fixData ONLY NEEDED TO FIX FILE PROBLEM
- /*
- * private void fixData(String inputDirectory, String matchingPattern, String outputDirectory) throws IOException {
- * File dir = new File(inputDirectory);
- * File[] files = dir.listFiles();
- * for (int i = 0; i < files.length; ++i) {
- * if (files[i].isDirectory()) continue;
- * BufferedReader input = FileUtilities.openUTF8Reader("", files[i].getCanonicalPath());
- * PrintWriter output = FileUtilities.openUTF8Writer("", outputDirectory + files[i].getName());
- * while (true) {
- * String line = input.readLine();
- * if (line == null) break;
- * if (line.indexOf("DOCTYPE") >= 0) {
- * line = line.replaceAll(" ldml ", " supplementalData ");
- * }
- * output.println(line);
- * }
- * input.close();
- * output.close();
- * }
- * }
- */
-
-}
diff --git a/tools/java/org/unicode/cldr/icu/DayPeriodsMapper.java b/tools/java/org/unicode/cldr/icu/DayPeriodsMapper.java
deleted file mode 100644
index a30482e..0000000
--- a/tools/java/org/unicode/cldr/icu/DayPeriodsMapper.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-/**
- * Class for converting CLDR dayPeriods data into a format suitable for writing
- * to ICU data. The regex-mapping method can't be used here because the special
- * handling of sets.
- *
- * @author jchye
- */
-public class DayPeriodsMapper {
- private String supplementalDir;
-
- public DayPeriodsMapper(String supplementalDir) {
- this.supplementalDir = supplementalDir;
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format
- */
- public IcuData fillFromCldr() {
- IcuData icuData = new IcuData("dayPeriods.xml", "dayPeriods", false);
- DayPeriodsHandler handler = new DayPeriodsHandler(icuData);
- File inputFile = new File(supplementalDir, "dayPeriods.xml");
- MapperUtils.parseFile(inputFile, handler);
- return icuData;
- }
-
- private class DayPeriodsHandler extends MapperUtils.EmptyHandler {
- private IcuData icuData;
- private int setNum;
- private String selection;
-
- public DayPeriodsHandler(IcuData icuData) {
- this.icuData = icuData;
- setNum = 0;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- // <dayPeriodRuleSet type="selection">
- if (qName.equals("dayPeriodRuleSet")) {
- selection = attr.getValue("type");
- if (selection == null) {
- selection = "";
- } else {
- selection = "_" + selection;
- }
- } else if (qName.equals("dayPeriodRules")) {
- setNum++;
- String[] locales = attr.getValue("locales").split("\\s+");
- for (String locale : locales) {
- icuData.add("/locales" + selection + "/" + locale, "set" + setNum);
- }
- } else if (qName.equals("dayPeriodRule")) {
- String type = attr.getValue("type");
- String prefix = "/rules/set" + setNum + "/" + type + "/";
- // Possible attribute names: type, before, after, at.
- for (int i = 0; i < attr.getLength(); i++) {
- String attrName = attr.getLocalName(i);
- if (!attrName.equals("type")) {
- icuData.add(prefix + attrName, attr.getValue(i));
- }
- }
- }
- }
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/DependencyGraphData.java b/tools/java/org/unicode/cldr/icu/DependencyGraphData.java
deleted file mode 100644
index 9ba684a..0000000
--- a/tools/java/org/unicode/cldr/icu/DependencyGraphData.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// © 2019 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-
-package org.unicode.cldr.icu;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Collection;
-
-import org.unicode.cldr.ant.CLDRConverterTool.Alias;
-import org.unicode.cldr.ant.CLDRConverterTool.AliasDeprecates;
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.SupplementalDataInfo;
-
-class DependencyGraphData {
- SupplementalDataInfo supplementalDataInfo;
- AliasDeprecates aliasDeprecates;
-
- DependencyGraphData(SupplementalDataInfo supplementalDataInfo, AliasDeprecates aliasDeprecates) {
- this.supplementalDataInfo = supplementalDataInfo;
- this.aliasDeprecates = aliasDeprecates;
- }
-
- public void print(String outputDir, String filename) throws IOException {
- PrintWriter out = FileUtilities.openUTF8Writer(outputDir, filename);
- out.append("# -*- coding: utf-8 -*-\n");
- out.append("# © 2019 and later: Unicode, Inc. and others.\n");
- out.append("# License & terms of use: http://www.unicode.org/copyright.html#License\n");
- out.println();
-
- out.append("data = {");
- out.append("\n \"cldrVersion\": \"");
- out.append(CLDRFile.GEN_VERSION);
- out.append('"');
- if (aliasDeprecates.aliasList != null) {
- out.append(",\n \"aliases\": {");
- boolean firstInner = true;
- for (Alias alias : aliasDeprecates.aliasList) {
- if (alias.rbPath != null) {
- continue;
- }
- if (!firstInner) {
- out.append(',');
- }
- firstInner = false;
- out.append("\n \"");
- out.append(alias.from);
- out.append("\": \"");
- out.append(alias.to);
- out.append('"');
- }
- out.append("\n }");
- }
- Collection<String> explicitChildren = supplementalDataInfo.getExplicitChildren();
- if (!explicitChildren.isEmpty()) {
- out.append(",\n \"parents\": {");
- boolean firstInner = true;
- for (String child : explicitChildren) {
- if (!firstInner) {
- out.append(',');
- }
- firstInner = false;
- String parent = supplementalDataInfo.getExplicitParentLocale(child);
- out.append("\n \"");
- out.append(child);
- out.append("\": \"");
- out.append(parent);
- out.append('"');
- }
- out.append("\n }");
- }
- out.append("\n}\n");
- out.close();
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/ExtractICUData.java b/tools/java/org/unicode/cldr/icu/ExtractICUData.java
index cfca726..900b6f9 100644
--- a/tools/java/org/unicode/cldr/icu/ExtractICUData.java
+++ b/tools/java/org/unicode/cldr/icu/ExtractICUData.java
@@ -28,6 +28,7 @@
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
@@ -65,14 +66,14 @@
System.out.println("Done");
}
- static Set<String> skipLines = new HashSet<String>(Arrays.asList(new String[] {
+ static Set<String> skipLines = new HashSet<>(Arrays.asList(new String[] {
"#--------------------------------------------------------------------",
"# Copyright (c) 1999-2005, International Business Machines",
"# Copyright (c) 1999-2004, International Business Machines",
"# Corporation and others. All Rights Reserved.",
"#--------------------------------------------------------------------"
}));
- static Set<String> skipFiles = new HashSet<String>(Arrays.asList(new String[] {
+ static Set<String> skipFiles = new HashSet<>(Arrays.asList(new String[] {
// "Any_Accents",
"el",
"en",
@@ -86,9 +87,9 @@
getTranslitIndex(accumulatedItems);
File translitSource = new File("C:\\cvsdata\\icu\\icu\\source\\data\\translit\\");
- System.out.println("Source: " + translitSource.getCanonicalPath());
+ System.out.println("Source: " + PathUtilities.getNormalizedPathString(translitSource));
File[] fileArray = translitSource.listFiles();
- List<Object> list = new ArrayList<Object>(Arrays.asList(fileArray));
+ List<Object> list = new ArrayList<>(Arrays.asList(fileArray));
// List<String> extras = Arrays.asList(new String[] {
// "Arabic_Latin.txt",
@@ -363,7 +364,7 @@
static Matcher privateFiles = PatternCache.get(".*(Spacedhan|InterIndic|ThaiLogical|ThaiSemi).*").matcher("");
static Matcher allowNames = PatternCache.get("(Fullwidth|Halfwidth|NumericPinyin|Publishing)").matcher("");
- static Set<String> collectedNames = new TreeSet<String>();
+ static Set<String> collectedNames = new TreeSet<>();
private static String fixTransIDPart(String name) {
if (name == null) return name;
@@ -389,14 +390,14 @@
};
Collator col = Collator.getInstance(ULocale.ROOT);
((RuleBasedCollator) col).setNumericCollation(true);
- Map<String, Set<String>> alpha = new TreeMap<String, Set<String>>(col);
+ Map<String, Set<String>> alpha = new TreeMap<>(col);
for (int range = 0; range < ranges.length; ++range) {
for (int propIndex = ranges[range][0]; propIndex < ranges[range][1]; ++propIndex) {
String propName = UCharacter.getPropertyName(propIndex, UProperty.NameChoice.LONG);
String shortPropName = UCharacter.getPropertyName(propIndex, UProperty.NameChoice.SHORT);
propName = getName(propIndex, propName, shortPropName);
- Set<String> valueOrder = new TreeSet<String>(col);
+ Set<String> valueOrder = new TreeSet<>(col);
alpha.put(propName, valueOrder);
switch (range) {
case 0:
@@ -455,4 +456,4 @@
if (valueName.equals(shortValueName)) return valueName;
return valueName + "\u00A0(" + shortValueName + ")";
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/icu/Filter.java b/tools/java/org/unicode/cldr/icu/Filter.java
deleted file mode 100644
index 995c278..0000000
--- a/tools/java/org/unicode/cldr/icu/Filter.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.unicode.cldr.icu;
-
-/**
- * Interface for implementing a filter on a collection of values.
- * @author jchye
- */
-public interface Filter {
- /**
- * @return true if the specified value is allowed through the filter.
- */
- public boolean includes(String value);
-}
diff --git a/tools/java/org/unicode/cldr/icu/ICU2LDMLWriter.java b/tools/java/org/unicode/cldr/icu/ICU2LDMLWriter.java
deleted file mode 100644
index 3ceac1c..0000000
--- a/tools/java/org/unicode/cldr/icu/ICU2LDMLWriter.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- ******************************************************************************
- * Copyright (C) 2004-2008 International Business Machines Corporation and *
- * others. All Rights Reserved. *
- ******************************************************************************
- */
-package org.unicode.cldr.icu;
-
-//CLDR imports
-import org.unicode.cldr.ant.CLDRConverterTool;
-
-import com.ibm.icu.dev.tool.UOption;
-
-/**
- * This class is a user runnable class intended to create LDML documents by
- * calling the appropriate ICU API functions and retrieving the data.
- *
- * @author Brian Rower - IBM - August 2009
- *
- */
-@SuppressWarnings("deprecation")
-public class ICU2LDMLWriter extends CLDRConverterTool {
- private static final UOption[] options = new UOption[] {
- UOption.HELP_H(),
- UOption.HELP_QUESTION_MARK(),
- UOption.DESTDIR(),
- UOption.VERBOSE(),
- UOption.create("main", 'm', UOption.NO_ARG),
- UOption.create("trans", 't', UOption.NO_ARG),
- UOption.create("coll", 'c', UOption.NO_ARG)
- };
-
- // ******************** ENUMS *************************
-
- // For command line options
- private static final int OP_HELP1 = 0;
- private static final int OP_HELP2 = 1;
- private static final int OP_DESTDIR = 2;
- private static final int OP_VERBOSE = 3;
- private static final int OP_MAIN = 4;
- private static final int OP_TRANS = 5;
- private static final int OP_COLL = 6;
-
- private String currentLocaleName = null;
-
- public static void main(String[] args) {
- ICU2LDMLWriter w = new ICU2LDMLWriter();
- w.processArgs(args);
- }
-
- public void processArgs(String[] args) {
- int remainingArgc = 0;
- // for some reason when
- // Class classDefinition = Class.forName(className);
- // object = classDefinition.newInstance();
- // is done then the options are not reset!!
- for (int i = 0; i < options.length; i++) {
- options[i].doesOccur = false;
- }
- try {
- remainingArgc = UOption.parseArgs(args, options);
- } catch (Exception e) {
- printError("(parsing args): " + e.toString());
- e.printStackTrace();
- usage();
- }
-
- if (options[OP_HELP1].doesOccur || options[OP_HELP2].doesOccur || args.length == 0) {
- usage();
- }
-
- printError("** Note: ICU2LDMLWriter is no longer supported or functional. **");
-
- }
-
- private void usage() {
- System.out
- .println("\nUsage: ICU2LDMLWriter [OPTIONS] -d OUTPUTFOLDER [FILES]\n"
- +
- "This program generates LDML documents which represent the data currently inside of your ICU installation\n"
- +
- "If no files are given, a file for each supported locale will be produced.\n"
- +
- "If no destination folder is given, the file structure will be created in the current working directory.\n"
- +
- "Options:\n" +
- "-m or --main Generate the main locale files.\n" +
- "-t or --trans Generate the transliteration locale files.\n" +
- "-c or --coll Generate the collation files.\n" +
- "If none of the above options are given, all three types of files will be generated.\n" +
- "\n" +
- "** Note: ICU2LDMLWriter is no longer supported or functional. **\n");
- System.exit(-1);
- }
-
- // **********************Printing Methods *********************************
-
- private void printError(String message) {
- System.err.println("ERROR : " + currentLocaleName + ": " + message);
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/ICULog.java b/tools/java/org/unicode/cldr/icu/ICULog.java
deleted file mode 100644
index 71a0672..0000000
--- a/tools/java/org/unicode/cldr/icu/ICULog.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.unicode.cldr.icu;
-
-public interface ICULog {
- public enum Level {
- DEBUG, INFO, LOG, WARNING, ERROR;
- }
-
- boolean willOutput(Level level);
-
- void setStatus(String status);
-
- void debug(String msg);
-
- void info(String msg);
-
- void log(String msg);
-
- void warning(String msg);
-
- void error(String msg);
-
- void error(String msg, Throwable t);
-
- /**
- * Outputs and flushes text with no status or level message.
- * Used for 'ticks' during long-running processes and
- * compact output.
- */
- public interface Emitter {
- /** Outputs and flushes text, no newline */
- void emit(String text);
-
- /** Emits a newline */
- void nl();
- }
-
- /**
- * Returns an emitter. If the log will output at this level,
- * the emitter will forward the text, otherwise it will silently
- * ignore it. Use willOutput to see if the emitter will actually
- * emit the text.
- */
- Emitter emitter(Level level);
-}
diff --git a/tools/java/org/unicode/cldr/icu/ICULogImpl.java b/tools/java/org/unicode/cldr/icu/ICULogImpl.java
deleted file mode 100644
index 5a4278b..0000000
--- a/tools/java/org/unicode/cldr/icu/ICULogImpl.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.PrintWriter;
-
-public class ICULogImpl implements ICULog {
- private final Level level;
- private final PrintWriter out;
- private String status;
-
- public ICULogImpl(Level level) {
- this.level = level;
- this.out = new PrintWriter(System.out);
- }
-
- public void debug(String msg) {
- out(Level.DEBUG, msg);
- }
-
- public void error(String msg) {
- out(Level.ERROR, msg);
- }
-
- public void error(String msg, Throwable t) {
- if (t == null) {
- error(msg);
- } else {
- out(Level.ERROR, msg + " '" + t.toString() + "'");
- t.printStackTrace(out);
- }
- out.flush();
- }
-
- public void info(String msg) {
- out(Level.INFO, msg);
- }
-
- public void log(String msg) {
- out(Level.LOG, msg);
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public void warning(String msg) {
- out(Level.WARNING, msg);
- }
-
- protected void out(Level level, String msg) {
- if (willOutput(level)) {
- if (status != null) {
- out.format("%s (%s): %s%n", level, status, msg);
- } else {
- out.format("%s: %s%n", level, msg);
- }
- out.flush();
- }
- }
-
- public boolean willOutput(Level level) {
- return level.ordinal() >= this.level.ordinal();
- }
-
- public Emitter emitter(Level level) {
- return willOutput(level) ? logEmitter : nullEmitter;
- }
-
- // This buffers because ant replaces System.out with an implementation
- // that prepends the name of the running task and appends a newline
- // whenever we flush.
- private final Emitter logEmitter = new Emitter() {
- private final StringBuilder buf = new StringBuilder();
-
- public void emit(String text) {
- buf.append(text);
- }
-
- public void nl() {
- out.println(buf.toString());
- out.flush();
- buf.setLength(0);
- }
- };
-
- private static final Emitter nullEmitter = new Emitter() {
- public void emit(String text) {
- }
-
- public void nl() {
- }
- };
-}
diff --git a/tools/java/org/unicode/cldr/icu/ICUResourceWriter.java b/tools/java/org/unicode/cldr/icu/ICUResourceWriter.java
index ff14fad..8ee418a 100644
--- a/tools/java/org/unicode/cldr/icu/ICUResourceWriter.java
+++ b/tools/java/org/unicode/cldr/icu/ICUResourceWriter.java
@@ -354,6 +354,7 @@
public static class ResourceAlias extends Resource {
String val;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -376,6 +377,7 @@
* @param out
* A File output stream which has already been set up to write to.
*/
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
byte[] valLenBytes;
byte[] valBytes;
@@ -405,6 +407,7 @@
return usedOffset;
}
+ @Override
public void setSize() {
// a pointer + the string
size = SIZE_OF_INT + ((val.length() + 1) * SIZE_OF_CHAR);
@@ -412,6 +415,7 @@
}
public static class ResourceArray extends Resource {
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -437,6 +441,7 @@
write(writer, CLOSEBRACE + LINESEP);
}
+ @Override
public void sort() {
if (noSort == true) {
return;
@@ -448,6 +453,7 @@
}
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
int count = 0;
int[] resources = new int[numChildren];
@@ -529,6 +535,7 @@
/**
* This method will set the size of the resource.
*/
+ @Override
public void setSize() {
// Arrays have children.
int x = 0;
@@ -557,6 +564,7 @@
public static class ResourceInt extends Resource {
String val;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -571,6 +579,7 @@
}
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
return usedOffset;
}
@@ -578,6 +587,7 @@
/**
* This method will set the size of the resource. Overwritten for each child object
*/
+ @Override
public void setSize() {
size = 0;
@@ -587,6 +597,7 @@
public static class ResourceIntVector extends Resource {
public String smallComment = null;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -609,6 +620,7 @@
write(writer, CLOSEBRACE + LINESEP);
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
int count = 0;
int[] numbers = new int[numChildren];
@@ -638,6 +650,7 @@
/**
* This method will set the size of the resource. Overwritten for each child object
*/
+ @Override
public void setSize() {
// has children
int x = 0;
@@ -668,6 +681,7 @@
*/
public String smallComment = null;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -753,6 +767,7 @@
}
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
// clean up quotes if any
@@ -793,6 +808,7 @@
/**
* This method will set the size of the resource. Overwritten for each child object
*/
+ @Override
public void setSize() {
// a pointer to the key + a string
size = SIZE_OF_INT + (SIZE_OF_CHAR * (val.length() + 1));
@@ -803,6 +819,7 @@
public String annotation;
public static final String NO_FALLBACK = "nofallback";
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -824,6 +841,7 @@
// insertion sort of the linked list
// from Algorithms in C++ Sedgewick
+ @Override
public void sort() {
if (noSort == true) {
return;
@@ -880,6 +898,7 @@
return mustBe32;
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
int count = 0;
int pad;
@@ -1013,6 +1032,7 @@
/**
* This method will set the size of the resource. Overwritten for each child object
*/
+ @Override
public void setSize() {
// Tables have children.
int x = 0;
@@ -1049,6 +1069,7 @@
String external;
byte[] data;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -1063,11 +1084,13 @@
}
}
+ @Override
public void setSize() {
// sizeof(int32_t) + sizeof(uint8_t) * length + BIN_ALIGNMENT;
size = SIZE_OF_INT + data.length + BIN_ALIGNMENT;
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
int pad = 0;
int extrapad = pad32(this.size);
@@ -1103,6 +1126,7 @@
String val;
String ext;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -1118,6 +1142,7 @@
}
}
+ @Override
public int writeBinary(FileOutputStream out, int usedOffset) {
if (this.name.equals("depends")) {
@@ -1135,6 +1160,7 @@
public static class ResourceImport extends Resource {
String val;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
@@ -1155,6 +1181,7 @@
public static class ResourceInclude extends Resource {
String val;
+ @Override
public void write(OutputStream writer, int numIndent, boolean bare) {
writeComments(writer, numIndent);
writeIndent(writer, numIndent);
diff --git a/tools/java/org/unicode/cldr/icu/ICUWriter.java b/tools/java/org/unicode/cldr/icu/ICUWriter.java
deleted file mode 100644
index 266b734..0000000
--- a/tools/java/org/unicode/cldr/icu/ICUWriter.java
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2009 Google Inc. All Rights Reserved.
-
-package org.unicode.cldr.icu;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.util.Calendar;
-import java.util.List;
-
-import org.unicode.cldr.icu.ICUResourceWriter.Resource;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceTable;
-import org.unicode.cldr.icu.ResourceSplitter.ResultInfo;
-
-class ICUWriter {
- private static final String LINESEP = System.getProperty("line.separator");
- private static final String BOM = "\uFEFF";
- private static final String CHARSET = "UTF-8";
-
- private final String dstDirName;
- private final ICULog log;
- private final ResourceSplitter splitter;
-
- ICUWriter(String dstDirName, ICULog log, ResourceSplitter splitter) {
- this.dstDirName = dstDirName;
- this.log = log;
- this.splitter = splitter;
- }
-
- // private static final ResourceSplitter debugSplitter;
- // static {
- // List<SplitInfo> splitInfos = new ArrayList<SplitInfo>();
- // splitInfos.add(new SplitInfo("/Languages", "lang"));
- // splitInfos.add(new SplitInfo("/LanguagesShort", "lang"));
- // splitInfos.add(new SplitInfo("/Scripts", "lang"));
- // splitInfos.add(new SplitInfo("/Types", "lang"));
- // splitInfos.add(new SplitInfo("/Variants", "lang"));
- // splitInfos.add(new SplitInfo("/codePatterns", "lang"));
- // splitInfos.add(new SplitInfo("/Countries", "terr", "/Territories"));
- // splitInfos.add(new SplitInfo("/Currencies", "curr"));
- // splitInfos.add(new SplitInfo("/CurrencyPlurals", "curr"));
- // splitInfos.add(new SplitInfo("/CurrencyUnitPatterns", "curr"));
- // splitInfos.add(new SplitInfo("/zoneStrings", "zone"));
- //
- // debugSplitter = new ResourceSplitter("/tmp/ldml", splitInfos);
- // }
-
- public void writeResource(Resource res, String sourceInfo) {
- if (splitter == null) {
- String outputFileName = dstDirName + "/" + res.name + ".txt";
- writeResource(res, sourceInfo, outputFileName);
- } else {
- File rootDir = new File(dstDirName);
- List<ResultInfo> result = splitter.split(rootDir, (ResourceTable) res);
-
- for (ResultInfo info : result) {
- res = info.root;
- String outputFileName = info.directory.getAbsolutePath() + "/" + res.name + ".txt";
- writeResource(res, sourceInfo, outputFileName);
- }
- }
- }
-
- private void writeResource(Resource set, String sourceInfo, String outputFileName) {
- try {
- log.log("Writing " + outputFileName);
- FileOutputStream file = new FileOutputStream(outputFileName);
- BufferedOutputStream writer = new BufferedOutputStream(file);
- writeHeader(writer, sourceInfo);
-
- for (Resource res = set; res != null; res = res.next) {
- res.sort();
- }
-
- for (Resource res = set; res != null; res = res.next) {
- res.write(writer, 0, false);
- }
-
- writer.flush();
- writer.close();
- } catch (Resource.MalformedResourceError mre) {
- String where = set.findResourcePath(mre.offendingResource);
- log.error("Could not write resource " + where + ". " + mre.toString(), mre);
- if (!new File(outputFileName).delete()) {
- log.error("Failed to delete file");
- }
- System.exit(1);
- } catch (Exception ie) {
- log.error("Could not write resource." + ie.toString(), ie);
- if (!new File(outputFileName).delete()) {
- log.error("Failed to delete file");
- }
- System.exit(1);
- }
- }
-
- private void writeLine(OutputStream writer, String line) {
- try {
- byte[] bytes = line.getBytes(CHARSET);
- writer.write(bytes, 0, bytes.length);
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- System.exit(1);
- }
- }
-
- private void writeHeader(OutputStream writer, String fileName) {
- writeBOM(writer);
- Calendar c = Calendar.getInstance();
- StringBuilder buffer = new StringBuilder();
- buffer.append("// ***************************************************************************")
- .append(LINESEP)
- .append("// *")
- .append(LINESEP)
- .append("// * Copyright (C) ")
- .append(c.get(Calendar.YEAR))
- .append(" International Business Machines")
- .append(LINESEP)
- .append("// * Corporation and others. All Rights Reserved.")
- .append(LINESEP)
- .append("// * Tool: com.ibm.icu.dev.tool.cldr.LDML2ICUConverter.java")
- .append(LINESEP);
- // buffer.append("// * Date & Time: ")
- // .append(c.get(Calendar.YEAR))
- // .append("/")
- // .append(c.get(Calendar.MONTH) + 1)
- // .append("/")
- // .append(c.get(Calendar.DAY_OF_MONTH))
- // .append(" ")
- // .append(c.get(Calendar.HOUR_OF_DAY))
- // .append(COLON)
- // .append(c.get(Calendar.MINUTE))
- // .append(LINESEP);
- // String ver = LDMLUtilities.getCVSVersion(fileName);
- // if (ver == null) {
- // ver = "";
- // } else {
- // ver = " v" + ver;
- // }
-
- String tempdir = fileName.replace('\\', '/');
- int index = tempdir.indexOf("/common");
- if (index > -1) {
- tempdir = "<path>" + tempdir.substring(index, tempdir.length());
- } else {
- index = tempdir.indexOf("/xml");
- if (index > -1) {
- tempdir = "<path>" + tempdir.substring(index, tempdir.length());
- } else {
- tempdir = "<path>/" + tempdir;
- }
- }
- buffer.append("// * Source File:" + tempdir)
- .append(LINESEP)
- .append("// *")
- .append(LINESEP)
- .append("// ***************************************************************************")
- .append(LINESEP);
- writeLine(writer, buffer.toString());
- }
-
- private void writeBOM(OutputStream buffer) {
- try {
- byte[] bytes = BOM.getBytes(CHARSET);
- buffer.write(bytes, 0, bytes.length);
- } catch (Exception e) {
- log.error(e.getMessage(), e);
- }
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/IcuData.java b/tools/java/org/unicode/cldr/icu/IcuData.java
deleted file mode 100644
index dfc4baf..0000000
--- a/tools/java/org/unicode/cldr/icu/IcuData.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Wrapper class for converted ICU data which RB paths to values.
- */
-public class IcuData implements Iterable<String> {
- private boolean hasFallback;
- private String sourceFile;
- private String name;
- private Map<String, List<String[]>> rbPathToValues;
- private String comment;
- private Map<String, String> enumMap;
-
- /**
- * IcuData constructor.
- *
- * @param sourceFile
- * the source file of the IcuData object, displayed in
- * comments in the file
- * @param name
- * The name of the IcuData object, also used as the name of the
- * root node in the output file
- * @param hasFallback
- * true if the output file has another ICU file as a
- * fallback
- */
- public IcuData(String sourceFile, String name, boolean hasFallback) {
- this(sourceFile, name, hasFallback, new HashMap<String, String>());
- }
-
- /**
- * IcuData constructor.
- *
- * @param sourceFile
- * the source file of the IcuData object, displayed in
- * comments in the file
- * @param name
- * The name of the IcuData object, also used as the name of the
- * root node in the output file
- * @param hasFallback
- * true if the output file has another ICU file as a
- * fallback
- * @param enumMap
- * a mapping of CLDR string values to their integer values in
- * ICU
- */
- public IcuData(String sourceFile, String name, boolean hasFallback, Map<String, String> enumMap) {
- this.hasFallback = hasFallback;
- this.sourceFile = sourceFile;
- this.name = name;
- rbPathToValues = new HashMap<String, List<String[]>>();
- this.enumMap = enumMap;
- }
-
- /**
- * @return true if data should fallback on data in other files, true by default
- */
- public boolean hasFallback() {
- return hasFallback;
- }
-
- /**
- * Returns the the relative path of the source file used to generate the
- * ICU data. Used when writing the data to file.
- *
- * @return
- */
- public String getSourceFile() {
- return sourceFile;
- }
-
- /**
- * @return the name to be used for the data.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets a comment to be placed above the data structure.
- * @param comment
- */
- public void setFileComment(String comment) {
- this.comment = comment;
- }
-
- public String getFileComment() {
- return comment;
- }
-
- /**
- * The RB path,value pair actually has an array as the value. So when we
- * add to it, add to a list.
- *
- * @param path
- * @param value
- * @return
- */
- public void add(String path, String... values) {
- List<String[]> list = rbPathToValues.get(path);
- if (list == null) {
- rbPathToValues.put(path, list = new ArrayList<String[]>(1));
- }
- list.add(normalizeValues(path, values));
- }
-
- /**
- * The RB path,value pair actually has an array as the value. So when we
- * add to it, add to a list.
- *
- * @param path
- * @param value
- * @return
- */
- void add(String path, String value) {
- add(path, new String[] { value });
- }
-
- void addAll(String path, Collection<String[]> valueList) {
- for (String[] values : valueList) {
- add(path, values);
- }
- }
-
- public void replace(String path, String... values) {
- List<String[]> list = new ArrayList<String[]>(1);
- rbPathToValues.put(path, list);
- list.add(normalizeValues(path, values));
- }
-
- private String[] normalizeValues(String rbPath, String[] values) {
- if (isIntRbPath(rbPath)) {
- List<String> normalizedValues = new ArrayList<String>();
- for (int i = 0; i < values.length; i++) {
- String curValue = values[i];
- String enumValue = enumMap.get(curValue);
- if (enumValue != null) curValue = enumValue;
- normalizedValues.add(curValue);
- }
- return normalizedValues.toArray(values);
- } else {
- return values;
- }
- }
-
- /**
- * Get items
- *
- * @return
- */
- public Set<Entry<String, List<String[]>>> entrySet() {
- return rbPathToValues.entrySet();
- }
-
- /**
- * Get items
- *
- * @return
- */
- public Set<String> keySet() {
- return rbPathToValues.keySet();
- }
-
- @Override
- public Iterator<String> iterator() {
- return rbPathToValues.keySet().iterator();
- }
-
- public int size() {
- return rbPathToValues.size();
- }
-
- public boolean containsKey(String key) {
- return rbPathToValues.containsKey(key);
- }
-
- public List<String[]> get(String path) {
- return rbPathToValues.get(path);
- }
-
- /**
- * @param rbPath
- * @return true if the rbPath is for integer values.
- */
- public static boolean isIntRbPath(String rbPath) {
- return rbPath.endsWith(":int") || rbPath.endsWith(":intvector");
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/IcuDataSplitter.java b/tools/java/org/unicode/cldr/icu/IcuDataSplitter.java
deleted file mode 100644
index c38f6c6..0000000
--- a/tools/java/org/unicode/cldr/icu/IcuDataSplitter.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.unicode.cldr.icu.ResourceSplitter.SplitInfo;
-
-public class IcuDataSplitter {
- private static final String VERSION_PATH = "/Version";
- private static final String PARENT_PATH = "/%%Parent";
-
- private final List<SplitInfo> splitInfos;
- private final Map<String, File> targetDirs;
- private final Map<String, Set<String>> splitSources = new HashMap<String, Set<String>>();
-
- /**
- * Splits the
- *
- * @param splitInfos
- */
- private IcuDataSplitter(List<SplitInfo> splitInfos) {
- this.splitInfos = splitInfos;
- targetDirs = new HashMap<String, File>();
- }
-
- /**
- * Creates a new IcuDataSplitter and creates directories for the split files
- * if they do not already exist.
- *
- * @param mainDirPath
- * the main directory that other directories will be relative to.
- * @param splitInfos
- * @return
- */
- public static IcuDataSplitter make(String mainDirPath, List<SplitInfo> splitInfos) {
- IcuDataSplitter splitter = new IcuDataSplitter(splitInfos);
- // Make sure that all the required directories are present.
- Map<String, File> targetDirs = splitter.targetDirs;
- for (SplitInfo si : splitInfos) {
- String dirPath = si.targetDirPath;
- if (!targetDirs.containsKey(dirPath)) {
- File dir = new File(dirPath);
- if (!dir.isAbsolute()) {
- dir = new File(mainDirPath, "/../" + dirPath);
- }
- if (dir.exists()) {
- if (!dir.isDirectory()) {
- throw new IllegalArgumentException(
- "File \"" + dirPath + "\" exists and is not a directory");
- }
- if (!dir.canWrite()) {
- throw new IllegalArgumentException(
- "Cannot write to directory \"" + dirPath + "\"");
- }
- } else {
- if (!dir.mkdirs()) {
- String canonicalPath;
- try {
- canonicalPath = dir.getCanonicalPath();
- } catch (IOException e) {
- canonicalPath = dirPath;
- }
- throw new IllegalArgumentException(
- "Unable to create directory path \"" + canonicalPath + "\"");
- }
- }
- targetDirs.put(dirPath, dir);
- }
- }
- return splitter;
- }
-
- /**
- * Splits an IcuData object for writing to different directories.
- *
- * @param data
- * @return
- */
- public Map<String, IcuData> split(IcuData icuData, String fallbackDir) {
- Map<String, IcuData> splitData = new HashMap<String, IcuData>();
- String sourceFile = icuData.getSourceFile();
- String name = icuData.getName();
- boolean hasFallback = icuData.hasFallback();
- Set<String> dirs = targetDirs.keySet();
- for (String dir : dirs) {
- splitData.put(dir, new IcuData(sourceFile, name, hasFallback));
- }
- splitData.put(fallbackDir, new IcuData(sourceFile, name, hasFallback));
-
- for (Entry<String, List<String[]>> entry : icuData.entrySet()) {
- String rbPath = entry.getKey();
- List<String[]> values = entry.getValue();
- boolean wasSplit = false;
- // Paths that should be copied to all directories.
- if (rbPath.equals(VERSION_PATH) || rbPath.equals(PARENT_PATH)) {
- for (String dir : dirs) {
- splitData.get(dir).addAll(rbPath, values);
- }
- } else {
- // Split up regular paths.
- for (SplitInfo splitInfo : splitInfos) {
- String checkPath = rbPath.replaceFirst(":alias", "/"); // Handle splitting of a top level alias ( as in root/units )
- if (checkPath.startsWith(splitInfo.srcNodePath)) {
- splitData.get(splitInfo.targetDirPath).addAll(rbPath, values);
- wasSplit = true;
- break;
- }
- }
- }
- // Add any remaining values to the file in fallback dir.
- if (!wasSplit) {
- splitData.get(fallbackDir).addAll(rbPath, values);
- }
- }
- // Remove all files that only contain version info.
- Iterator<Entry<String, IcuData>> iterator = splitData.entrySet().iterator();
- String comment = icuData.getFileComment();
- while (iterator.hasNext()) {
- Entry<String, IcuData> entry = iterator.next();
- IcuData data = entry.getValue();
- data.setFileComment(comment);
- if (entry.getKey().equals(fallbackDir)) continue;
- if (data.size() == 1 && data.containsKey(VERSION_PATH)) {
- // Comment copied from ResourceSplitter:
- // Some locales that use root data rely on the presence of
- // a resource file matching the prefix of the locale to prevent fallback
- // lookup through the default locale. To prevent this error, all resources
- // need at least a language-only stub resource to be present.
- //
- // Arrgh. The icu package tool wants all internal nodes in the tree to be
- // present. Currently, the missing nodes are all lang_Script locales.
- // Maybe change the package tool to fix this.
- String locale = data.getName();
- int underscorePos = locale.indexOf('_');
- if (underscorePos > -1 && locale.length() - underscorePos - 1 != 4) {
- iterator.remove();
- continue;
- }
- }
- add(splitSources, entry.getKey(), data.getName());
- }
- return splitData;
- }
-
- /**
- * Adds a value to the list with the specified key.
- */
- private static void add(Map<String, Set<String>> map, String key, String value) {
- Set<String> set = map.get(key);
- if (set == null) {
- map.put(key, set = new HashSet<String>());
- }
- set.add(value);
- }
-
- /**
- * Returns the set of directories that the splitter splits data into (excluding the main directory).
- */
- public Set<String> getTargetDirs() {
- return targetDirs.keySet();
- }
-
- public Set<String> getDirSources(String dir) {
- return Collections.unmodifiableSet(splitSources.get(dir));
- }
-
- public Makefile generateMakefile(Collection<String> aliases, String dir) {
- String prefix = dir.toUpperCase();
- Makefile makefile = new Makefile(prefix);
- makefile.addSyntheticAlias(aliases);
- makefile.addAliasSource();
- makefile.addSource(splitSources.get(dir));
- return makefile;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/IcuTextWriter.java b/tools/java/org/unicode/cldr/icu/IcuTextWriter.java
deleted file mode 100644
index a147f92..0000000
--- a/tools/java/org/unicode/cldr/icu/IcuTextWriter.java
+++ /dev/null
@@ -1,348 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.util.FileCopier;
-import org.unicode.cldr.util.PatternCache;
-
-import com.ibm.icu.impl.Utility;
-import com.ibm.icu.util.Calendar;
-
-/**
- * Writes an IcuData object to a text file.
- *
- * @author jchye
- */
-public class IcuTextWriter {
- /**
- * The default tab indent (actually spaces)
- */
- private static final String TAB = " ";
- // List of characters to escape in UnicodeSets.
- private static final Pattern UNICODESET_ESCAPE = PatternCache.get("\\\\[\\\\\\[\\]\\{\\}\\-&:^=]");
- // Only escape \ and " from other strings.
- private static final Pattern STRING_ESCAPE = PatternCache.get("(?!')\\\\\\\\(?!')");
- private static final Pattern QUOTE_ESCAPE = PatternCache.get("\\\\?\"");
-
- private static String headerText;
-
- /**
- * ICU paths have a simple comparison, alphabetical within a level. We do
- * have to catch the / so that it is lower than everything.
- */
- public static final Comparator<String> PATH_COMPARATOR = new Comparator<String>() {
- @Override
- public int compare(String arg0, String arg1) {
- int min = Math.min(arg0.length(), arg1.length());
- for (int i = 0; i < min; ++i) {
- int ch0 = arg0.charAt(i);
- int ch1 = arg1.charAt(i);
- int diff = ch0 - ch1;
- if (diff == 0) {
- continue;
- }
- if (ch0 == '/') {
- return -1;
- } else if (ch1 == '/') {
- return 1;
- }
- // make * greater than everything, because of languageMatch
- // while it is a pain to have it be unordered, this fix is sufficient to put all the *'s after anything else
- if (ch0 == '*') {
- return 1;
- } else if (ch1 == '*') {
- return -1;
- }
- return diff;
- }
- return arg0.length() - arg1.length();
- }
- };
-
- private static String getHeader() {
- if (headerText != null) {
- return headerText;
- }
- try (StringWriter stringWriter = new StringWriter();) {
- FileCopier.copy(NewLdml2IcuConverter.class, "ldml2icu_header.txt", stringWriter);
- headerText = stringWriter.toString();
- headerText = headerText.replace("%year%", String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
- return headerText;
- } catch (IOException ioe) {
- throw new IllegalArgumentException(ioe);
- }
- }
-
- /**
- * Write a file in ICU format. LDML2ICUConverter currently has some
- * funny formatting in a few cases; don't try to match everything.
- *
- * @param icuData
- * the icu data structure to be written
- * @param dirPath
- * the directory to write the file to
- * @param hasSpecial
- * true if a special file was used to create the ICU data
- */
- public static void writeToFile(IcuData icuData, String dirPath) throws IOException {
- String name = icuData.getName();
- PrintWriter out = FileUtilities.openUTF8Writer(dirPath, name + ".txt");
- out.write('\uFEFF');
- // Append the header.
- String header = getHeader().replace("%source%", icuData.getSourceFile());
- out.print(header);
- if (icuData.getFileComment() != null) {
- out.println("/**");
- out.append(" * ").append(icuData.getFileComment()).println();
- out.println(" */");
- }
-
- // Write the ICU data to file.
- out.append(name);
- if (!icuData.hasFallback()) out.append(":table(nofallback)");
- List<String> sortedPaths = new ArrayList<String>(icuData.keySet());
- Collections.sort(sortedPaths, PATH_COMPARATOR);
- String[] lastLabels = new String[] {};
- boolean wasSingular = false;
- for (String path : sortedPaths) {
- // Write values to file.
- String[] labels = path.split("/", -1); // Don't discard trailing slashes.
- int common = getCommon(lastLabels, labels);
- for (int i = lastLabels.length - 1; i > common; --i) {
- if (wasSingular) {
- wasSingular = false;
- } else {
- out.append(Utility.repeat(TAB, i));
- }
- out.println("}");
- }
- for (int i = common + 1; i < labels.length; ++i) {
- final String pad = Utility.repeat(TAB, i);
- out.append(pad);
- String label = labels[i];
- if (!label.startsWith("<") && !label.endsWith(">")) {
- out.append(label);
- }
- out.append('{');
- if (i != labels.length - 1) {
- out.println();
- }
- }
- List<String[]> values = icuData.get(path);
- try {
- wasSingular = appendValues(name, path, values, labels.length, out);
- } catch (NullPointerException npe) {
- System.err.println("Null value encountered in " + path);
- }
- out.flush();
- lastLabels = labels;
- }
- // Add last closing braces.
- for (int i = lastLabels.length - 1; i > 0; --i) {
- if (wasSingular) {
- wasSingular = false;
- } else {
- out.append(Utility.repeat(TAB, i));
- }
- out.println("}");
- }
- out.println("}");
- out.close();
- }
-
- /**
- * Inserts padding and values between braces.
- * @param name
- * @param rbPath
- * @param values
- * @param numTabs
- * @param out
- * @return
- */
- private static boolean appendValues(String name, String rbPath, List<String[]> values, int numTabs,
- PrintWriter out) {
- String[] firstArray;
- boolean wasSingular = false;
- boolean quote = !IcuData.isIntRbPath(rbPath);
- boolean isSequence = rbPath.endsWith("/Sequence");
- if (values.size() == 1 && !mustBeArray(true, name, rbPath)) {
- if ((firstArray = values.get(0)).length == 1 && !mustBeArray(false, name, rbPath)) {
- String value = firstArray[0];
- if (quote) {
- value = quoteInside(value);
- }
- int maxWidth = 84 - Math.min(4, numTabs) * TAB.length();
- if (value.length() <= maxWidth) {
- // Single value for path: don't add newlines.
- appendValue(value, quote, out);
- wasSingular = true;
- } else {
- // Value too long to fit in one line, so wrap.
- final String pad = Utility.repeat(TAB, numTabs);
- out.println();
- int end;
- for (int i = 0; i < value.length(); i = end) {
- end = goodBreak(value, i + maxWidth);
- String part = value.substring(i, end);
- out.append(pad);
- appendValue(part, quote, out).println();
- }
- }
- } else {
- // Only one array for the rbPath, so don't add an extra set of braces.
- final String pad = Utility.repeat(TAB, numTabs);
- out.println();
- appendArray(pad, firstArray, quote, isSequence, out);
- }
- } else {
- final String pad = Utility.repeat(TAB, numTabs);
- out.println();
- for (String[] valueArray : values) {
- if (valueArray.length == 1) {
- // Single-value array: print normally.
- appendArray(pad, valueArray, quote, isSequence, out);
- } else {
- // Enclose this array in braces to separate it from other
- // values.
- out.append(pad).println("{");
- appendArray(pad + TAB, valueArray, quote, isSequence, out);
- out.append(pad).println("}");
- }
- }
- }
- return wasSingular;
- }
-
- /**
- * Wrapper for a hack to determine if the given rb path should always
- * present its values as an array. This hack is required for an ICU data test to pass.
- *
- * @param topValues
- * @param name
- * @param rbPath
- * @return
- */
- private static boolean mustBeArray(boolean topValues, String name, String rbPath) {
- // TODO(jchye): Add this as an option to the locale file instead of hardcoding.
- // System.out.println(name + "\t" + rbPath);
- if (topValues) {
- return (rbPath.startsWith("/rules/set")
- && name.equals("pluralRanges"));
- }
- return rbPath.equals("/LocaleScript")
- || (rbPath.contains("/eras/") && !rbPath.endsWith(":alias") && !rbPath.endsWith("/named"))
- || rbPath.startsWith("/calendarPreferenceData")
- || rbPath.startsWith("/metazoneInfo");
- }
-
- private static PrintWriter appendArray(String padding, String[] valueArray,
- boolean quote, boolean isSequence, PrintWriter out) {
- for (String value : valueArray) {
- out.append(padding);
- appendValue(quoteInside(value), quote, out);
- if (!isSequence) {
- out.print(",");
- }
- out.println();
- }
- return out;
- }
-
- private static PrintWriter appendValue(String value, boolean quote, PrintWriter out) {
- if (quote) {
- return out.append('"').append(value).append('"');
- } else {
- return out.append(value);
- }
- }
-
- /**
- * Can a string be broken here? If not, backup until we can.
- *
- * @param quoted
- * @param end
- * @return
- */
- private static int goodBreak(String quoted, int end) {
- if (end > quoted.length()) {
- return quoted.length();
- }
- // Don't break escaped Unicode characters.
- // Need to handle both e.g. \u4E00 and \U00020000
- for (int i = end - 1; i > end - 10;) {
- char current = quoted.charAt(i--);
- if (!Character.toString(current).matches("[0-9A-Fa-f]")) {
- if ((current == 'u' || current == 'U') && i > end - 10 && quoted.charAt(i) == '\\') {
- return i;
- }
- break;
- }
- }
- while (end > 0) {
- char ch = quoted.charAt(end - 1);
- if (ch != '\\' && (ch < '\uD800' || ch > '\uDFFF')) {
- break;
- }
- --end;
- }
- return end;
- }
-
- /**
- * Fix characters inside strings.
- *
- * @param item
- * @return
- */
- private static String quoteInside(String item) {
- // Unicode-escape all quotes.
- item = QUOTE_ESCAPE.matcher(item).replaceAll("\\\\u0022");
- // Double up on backslashes, ignoring Unicode-escaped characters.
- Pattern pattern = item.startsWith("[") && item.endsWith("]") ? UNICODESET_ESCAPE : STRING_ESCAPE;
- Matcher matcher = pattern.matcher(item);
-
- if (!matcher.find()) {
- return item;
- }
- StringBuffer buffer = new StringBuffer();
- int start = 0;
- do {
- buffer.append(item.substring(start, matcher.start()));
- int punctuationChar = item.codePointAt(matcher.end() - 1);
- buffer.append("\\");
- if (punctuationChar == '\\') {
- buffer.append('\\');
- }
- buffer.append(matcher.group());
- start = matcher.end();
- } while (matcher.find());
- buffer.append(item.substring(start));
- return buffer.toString();
- }
-
- /**
- * find the initial labels (from a path) that are identical.
- *
- * @param item
- * @return
- */
- private static int getCommon(String[] lastLabels, String[] labels) {
- int min = Math.min(lastLabels.length, labels.length);
- int i;
- for (i = 0; i < min; ++i) {
- if (!lastLabels[i].equals(labels[i])) {
- return i - 1;
- }
- }
- return i - 1;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/KeyTypeDataConverter.java b/tools/java/org/unicode/cldr/icu/KeyTypeDataConverter.java
deleted file mode 100644
index b273b02..0000000
--- a/tools/java/org/unicode/cldr/icu/KeyTypeDataConverter.java
+++ /dev/null
@@ -1,423 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.unicode.cldr.icu.ICUResourceWriter.Resource;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceAlias;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceString;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceTable;
-import org.unicode.cldr.util.LDMLUtilities;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-public class KeyTypeDataConverter {
- private final ICULog log;
- private final String bcp47Dir;
- private final String[] externalTypeKeys;
- private Collection<Document> documents;
-
- private static final String SOURCE_INFO = "common/bcp47/*.xml";
- private static final String EXTERNAL_TYPES_SUFFIX = "Types";
-
- private static final boolean DEBUG = false;
-
- public KeyTypeDataConverter(ICULog log, String bcp47Dir, String[] externalTypeKeys) {
- this.log = log;
- this.bcp47Dir = bcp47Dir;
- this.externalTypeKeys = (externalTypeKeys == null) ? new String[0] : externalTypeKeys;
- }
-
- public void convert(ICUWriter writer) {
- // creating key mapping data
- Map<String, String> keyMap = new TreeMap<String, String>();
- for (Document doc : getDocuments()) {
- addKeyMap(keyMap, doc);
- }
-
- if (DEBUG) {
- log.log("Key mappings ---------------------------------------------");
- dumpMap(keyMap);
- }
-
- // creating type mapping data
- Map<String, Map<String, String>> typeMaps = new TreeMap<String, Map<String, String>>();
- Map<String, Map<String, String>> typeAliases = new TreeMap<String, Map<String, String>>();
- for (Document doc : getDocuments()) {
- addTypeMaps(typeMaps, typeAliases, doc);
- }
-
- if (DEBUG) {
- for (Map.Entry<String, Map<String, String>> e : typeMaps.entrySet()) {
- log.log("\n\n\nType mappings for " + e.getKey() + " ---------------------------------------------");
- dumpMap(e.getValue());
- }
-
- for (Map.Entry<String, Map<String, String>> e : typeAliases.entrySet()) {
- log.log("\n\n\nAlias mappings for " + e.getKey() + " ---------------------------------------------");
- dumpMap(e.getValue());
- }
- }
-
- // write out keyTypeData.txt
- Resource cur;
-
- ResourceTable keyTypeDataRes = new ResourceTable();
- keyTypeDataRes.name = LDMLBCP47Constants.KEYTYPEDATA;
- keyTypeDataRes.annotation = ResourceTable.NO_FALLBACK;
-
- // keyMap
- ResourceTable keyMapRes = new ResourceTable();
- keyMapRes.name = LDMLBCP47Constants.KEYMAP;
- keyTypeDataRes.first = keyMapRes;
-
- cur = null;
- for (Entry<String, String> keyMapItem : keyMap.entrySet()) {
- ResourceString keyRes = new ResourceString();
- keyRes.name = keyMapItem.getKey();
- keyRes.val = keyMapItem.getValue();
-
- if (cur == null) {
- keyMapRes.first = keyRes;
- } else {
- cur.next = keyRes;
- }
- cur = keyRes;
- }
-
- // typeMap
- Resource typeMapRes = createTypeMapResource(typeMaps, null);
- keyMapRes.next = typeMapRes;
-
- // typeAlias
- Resource typeAliasRes = createTypeAliasResource(typeAliases, null);
- typeMapRes.next = typeAliasRes;
-
- writer.writeResource(keyTypeDataRes, SOURCE_INFO);
-
- // externalized type/alias map data
- for (String key : externalTypeKeys) {
- ResourceTable extTypeDataRes = new ResourceTable();
- extTypeDataRes.name = key + EXTERNAL_TYPES_SUFFIX;
- extTypeDataRes.annotation = ResourceTable.NO_FALLBACK;
-
- // typeMap
- Resource extTypeMapRes = createTypeMapResource(typeMaps, key);
- extTypeDataRes.first = extTypeMapRes;
-
- // typeAlias
- Resource extTypeAliasRes = createTypeAliasResource(typeAliases, key);
- extTypeMapRes.next = extTypeAliasRes;
-
- writer.writeResource(extTypeDataRes, SOURCE_INFO);
- }
-
- }
-
- private Collection<Document> getDocuments() {
- if (documents != null) {
- return documents;
- }
-
- documents = new ArrayList<Document>();
-
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- if (name.endsWith(".xml")) {
- return true;
- }
- return false;
- }
- };
-
- File dir = new File(bcp47Dir);
- String[] files = dir.list(filter);
- if (files == null) {
- String canonicalPath;
- try {
- canonicalPath = dir.getCanonicalPath();
- } catch (IOException e) {
- canonicalPath = e.getMessage();
- }
- log.error("BCP47 files are missing " + canonicalPath);
- System.exit(-1);
- }
-
- String dirPath = dir.getAbsolutePath();
- for (String fileName : files) {
- try {
- log.info("Parsing document " + fileName);
- String filePath = dirPath + File.separator + fileName;
- Document doc = LDMLUtilities.parse(filePath, false);
- documents.add(doc);
- } catch (Throwable se) {
- log.error("Parsing: " + fileName + " " + se.toString(), se);
- System.exit(1);
- }
- }
- return documents;
- }
-
- private static void addKeyMap(Map<String, String> keyMap, Document root) {
- for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
- if (node.getNodeType() != Node.ELEMENT_NODE) {
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.LDMLBCP47)) {
- // Stop iterating over top-level elements, restart iterating over elements
- // under ldmlBCP47.
- node = node.getFirstChild();
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.KEYWORD)) {
- // iterating into elements under keyword
- node = node.getFirstChild();
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.KEY)) {
- String bcpKey = LDMLUtilities.getAttributeValue(node, LDMLBCP47Constants.NAME);
- String key = LDMLUtilities.getAttributeValue(node, LDMLBCP47Constants.ALIAS);
- if (key != null && !bcpKey.equals(key)) {
- /* keys are case-insensitive */
- keyMap.put(escapeKey(key.toLowerCase(Locale.ROOT)), bcpKey);
- }
- }
- }
- }
-
- private static void addTypeMaps(Map<String, Map<String, String>> typeMaps,
- Map<String, Map<String, String>> typeAliases, Document root) {
- for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
- if (node.getNodeType() != Node.ELEMENT_NODE) {
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.LDMLBCP47)) {
- // Stop iterating over top-level elements, restart iterating over elements
- // under ldmlBCP47.
- node = node.getFirstChild();
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.KEYWORD)) {
- // iterating into elements under keyword
- node = node.getFirstChild();
- continue;
- }
-
- if (node.getNodeName().equals(LDMLBCP47Constants.KEY)) {
- String bcpKey = LDMLUtilities.getAttributeValue(node, LDMLBCP47Constants.NAME);
- String key = LDMLUtilities.getAttributeValue(node, LDMLBCP47Constants.ALIAS);
- if (key == null) {
- key = bcpKey;
- }
- key = key.toLowerCase(Locale.ROOT); // keys are case-insensitive
- for (Node node2 = node.getFirstChild(); node2 != null; node2 = node2.getNextSibling()) {
- if (node2.getNodeType() != Node.ELEMENT_NODE) {
- continue;
- }
- if (node2.getNodeName().equals(LDMLBCP47Constants.TYPE)) {
- String bcpType = LDMLUtilities.getAttributeValue(node2, LDMLBCP47Constants.NAME);
- String type = LDMLUtilities.getAttributeValue(node2, LDMLBCP47Constants.ALIAS);
- if (type != null) {
- // type may contain multiple values delimited by space character
- String[] types = type.split(" ");
- if (types.length > 1) {
- type = types[0];
-
- // add 2nd and following type values into the alias map
- Map<String, String> singleTypeAliases = typeAliases.get(key);
- if (singleTypeAliases == null) {
- singleTypeAliases = new TreeMap<String, String>();
- typeAliases.put(key, singleTypeAliases);
- }
- for (int i = 1; i < types.length; i++) {
- singleTypeAliases.put(escapeKey(types[i]), type);
- }
- }
- }
-
- if (type != null && !bcpType.equals(type)) {
- // only populating mapping data when bcp47 representation is different
- Map<String, String> singleTypeMap = typeMaps.get(key);
- if (singleTypeMap == null) {
- singleTypeMap = new TreeMap<String, String>();
- typeMaps.put(key, singleTypeMap);
- }
- singleTypeMap.put(escapeKey(type), bcpType);
- }
- }
- }
- }
- }
- }
-
- private Resource createTypeMapResource(Map<String, Map<String, String>> typeMaps, String key) {
- ResourceTable typeMapRes = new ResourceTable();
- typeMapRes.name = LDMLBCP47Constants.TYPEMAP;
-
- Resource cur = null;
- for (Entry<String, Map<String, String>> typesForKeyItem : typeMaps.entrySet()) {
- String itemKey = typesForKeyItem.getKey();
- if (key != null && !itemKey.equals(key)) {
- // skip this key
- continue;
- }
-
- String aliasName = null;
- if (key == null) {
- for (String extKey : externalTypeKeys) {
- if (extKey.equals(itemKey)) {
- aliasName = "/ICUDATA/" + itemKey + EXTERNAL_TYPES_SUFFIX
- + "/" + LDMLBCP47Constants.TYPEMAP
- + "/" + itemKey;
- break;
- }
- }
- }
-
- Resource res = null;
- if (aliasName != null) {
- // generating alias resource
- ResourceAlias typeMapForKeyResAlias = new ResourceAlias();
- typeMapForKeyResAlias.name = itemKey;
- typeMapForKeyResAlias.val = aliasName;
-
- res = typeMapForKeyResAlias;
- } else {
- // generating type mapping container table per key
- ResourceTable typeMapForKeyRes = new ResourceTable();
- typeMapForKeyRes.name = itemKey;
-
- Resource curTypeRes = null;
- for (Entry<String, String> typeItem : typesForKeyItem.getValue().entrySet()) {
- // generating each type map data
- ResourceString typeRes = new ResourceString();
- typeRes.name = typeItem.getKey();
- typeRes.val = typeItem.getValue();
-
- if (curTypeRes == null) {
- typeMapForKeyRes.first = typeRes;
- } else {
- curTypeRes.next = typeRes;
- }
- curTypeRes = typeRes;
- }
-
- res = typeMapForKeyRes;
- }
-
- if (cur == null) {
- typeMapRes.first = res;
- } else {
- cur.next = res;
- }
- cur = res;
- }
-
- return typeMapRes;
- }
-
- private Resource createTypeAliasResource(Map<String, Map<String, String>> typeAliases, String key) {
- ResourceTable typeAliasRes = new ResourceTable();
- typeAliasRes.name = LDMLBCP47Constants.TYPEALIAS;
-
- Resource cur = null;
- for (Entry<String, Map<String, String>> aliasesForKeyItem : typeAliases.entrySet()) {
- String itemKey = aliasesForKeyItem.getKey();
- if (key != null && !itemKey.equals(key)) {
- // skip this key
- continue;
- }
-
- String aliasName = null;
- if (key == null) {
- for (String extKey : externalTypeKeys) {
- if (extKey.equals(itemKey)) {
- aliasName = "/ICUDATA/" + itemKey + EXTERNAL_TYPES_SUFFIX
- + "/" + LDMLBCP47Constants.TYPEALIAS
- + "/" + itemKey;
- break;
- }
- }
- }
-
- Resource res = null;
-
- if (aliasName != null) {
- // generating alias resource
- ResourceAlias aliasesForKeyResAlias = new ResourceAlias();
- aliasesForKeyResAlias.name = itemKey;
- aliasesForKeyResAlias.val = aliasName;
-
- res = aliasesForKeyResAlias;
- } else {
- // generating alias mapping container table per key
- ResourceTable aliasesForKeyRes = new ResourceTable();
- aliasesForKeyRes.name = itemKey;
-
- Resource curAliasRes = null;
- for (Entry<String, String> aliasItem : aliasesForKeyItem.getValue().entrySet()) {
- // generating each alias map data
- ResourceString aliasRes = new ResourceString();
- aliasRes.name = aliasItem.getKey();
- aliasRes.val = aliasItem.getValue();
-
- if (curAliasRes == null) {
- aliasesForKeyRes.first = aliasRes;
- } else {
- curAliasRes.next = aliasRes;
- }
- curAliasRes = aliasRes;
- }
-
- res = aliasesForKeyRes;
- }
-
- if (cur == null) {
- typeAliasRes.first = res;
- } else {
- cur.next = res;
- }
- cur = res;
- }
-
- return typeAliasRes;
- }
-
- private static String escapeKey(String key) {
- if (key.contains("/")) {
- key = "\"" + key.replace('/', ':') + "\"";
- }
- return key;
- }
-
- private void dumpMap(Map<String, String> map) {
- for (Map.Entry<String, String> e : map.entrySet()) {
- log.log(e.getKey() + " -> " + e.getValue());
- }
- }
-
- private static class LDMLBCP47Constants {
- static final String LDMLBCP47 = "ldmlBCP47";
- static final String KEYWORD = "keyword";
- static final String KEY = "key";
- static final String NAME = "name";
- static final String ALIAS = "alias";
- static final String TYPE = "type";
- static final String KEYTYPEDATA = "keyTypeData";
- static final String KEYMAP = "keyMap";
- static final String TYPEMAP = "typeMap";
- static final String TYPEALIAS = "typeAlias";
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/LDMLComparator.java b/tools/java/org/unicode/cldr/icu/LDMLComparator.java
index b01497f..762d148 100644
--- a/tools/java/org/unicode/cldr/icu/LDMLComparator.java
+++ b/tools/java/org/unicode/cldr/icu/LDMLComparator.java
@@ -122,31 +122,31 @@
return temp;
}
- Hashtable<String, String> optionTable = new Hashtable<String, String>();
+ Hashtable<String, String> optionTable = new Hashtable<>();
private String destFolder = ".";
private String localeStr;
private Calendar cal = Calendar.getInstance();
- private Hashtable<String, String> colorHash = new Hashtable<String, String>();
+ private Hashtable<String, String> colorHash = new Hashtable<>();
private String goldFileName;
private String goldKey;
private int serialNumber = 0;
- private Map<String, Object> compareMap = new TreeMap<String, Object>(getDefaultCollation());
- private Hashtable<String, String> doesNotExist = new Hashtable<String, String>();
- private Hashtable<String, String> requested = new Hashtable<String, String>();
- private Hashtable<String, String> deprecatedLanguageCodes = new Hashtable<String, String>();
- private Hashtable<String, String> deprecatedCountryCodes = new Hashtable<String, String>();
- private Set<String> vettingSet = new TreeSet<String>();
+ private Map<String, Object> compareMap = new TreeMap<>(getDefaultCollation());
+ private Hashtable<String, String> doesNotExist = new Hashtable<>();
+ private Hashtable<String, String> requested = new Hashtable<>();
+ private Hashtable<String, String> deprecatedLanguageCodes = new Hashtable<>();
+ private Hashtable<String, String> deprecatedCountryCodes = new Hashtable<>();
+ private Set<String> vettingSet = new TreeSet<>();
private String encoding = "UTF-8"; // default encoding
// PN added
- private Vector<String> m_PlatformVect = new Vector<String>(); // holds names of platforms
- private Vector<String> m_PlatformFolderVect = new Vector<String>(); // holds names of folders containing locale data
+ private Vector<String> m_PlatformVect = new Vector<>(); // holds names of platforms
+ private Vector<String> m_PlatformFolderVect = new Vector<>(); // holds names of folders containing locale data
// for each platform
private int m_iOptions;
- private Map<String, AccumulatedResults> m_AccumulatedResultsMap = new TreeMap<String, AccumulatedResults>();
+ private Map<String, AccumulatedResults> m_AccumulatedResultsMap = new TreeMap<>();
private int m_iTotalConflictingElements = 0;
private int m_iTotalNonConflictingElements = 0;
- private Map<String, SummaryData> m_LocaleSummaryDataMap = new TreeMap<String, SummaryData>(); // key = localename,
+ private Map<String, SummaryData> m_LocaleSummaryDataMap = new TreeMap<>(); // key = localename,
// data = summary info
private boolean m_Vetting = false;
@@ -158,7 +158,7 @@
String node;
String index;
String parentNode;
- Hashtable<String, String> platformData = new Hashtable<String, String>();
+ Hashtable<String, String> platformData = new Hashtable<>();
String referenceUrl;
}
@@ -172,8 +172,8 @@
String node;
String index;
String parentNode;
- Vector<String> localeVectDiff = new Vector<String>(); // holds locales where a conflict in data was found
- Vector<String> localeVectSame = new Vector<String>(); // holds locales where a no conflict in data was found
+ Vector<String> localeVectDiff = new Vector<>(); // holds locales where a conflict in data was found
+ Vector<String> localeVectSame = new Vector<>(); // holds locales where a no conflict in data was found
}
private class SummaryData {
@@ -235,8 +235,8 @@
addToCompareMap(goldFileName, goldKey);
}
for (; en.hasMoreElements();) {
- String key = (String) en.nextElement();
- String compFile = (String) optionTable.get(key);
+ String key = en.nextElement();
+ String compFile = optionTable.get(key);
if ((m_iOptions & OPT_VETTING) != 0) {
addVettable(goldFileName, goldKey);
} else {
@@ -317,7 +317,7 @@
for (int i = 0; i < USER_OPTIONS.length; i++) {
if (USER_OPTIONS[i].equals(option)) {
- result |= (int) (1 << i); // calculate option bit value
+ result |= 1 << i; // calculate option bit value
optionRecognized = true;
if (USER_OPTIONS[i].equals("-s")) {
} else if (USER_OPTIONS[i].equals("-d")) {
@@ -381,7 +381,7 @@
parent = localeStr.substring(0, index);
}
writer.print(" <th bgcolor=\"" +
- (String) colorHash.get(name) + "\">" +
+ colorHash.get(name) + "\">" +
name.toUpperCase() +
" (<a href=\"../../" + folder + localeStr + ".xml\">" + localeStr + "</a>," +
" <a href=\"../../" + folder + parent + ".xml\">" + parent + "</a>," +
@@ -389,7 +389,7 @@
"</th>\n");
} else {
writer.print(" <th bgcolor=\"" +
- (String) colorHash.get(name) + "\">" +
+ colorHash.get(name) + "\">" +
name.toUpperCase() +
" (<a href=\"../../" + folder + localeStr + ".xml\">" + localeStr + "</a>)" +
"</th>\n");
@@ -412,7 +412,7 @@
" <th width=10%>ID</th>\n");
for (int i = 0; i < m_PlatformVect.size(); i++) {
- String name = (String) m_PlatformVect.elementAt(i);
+ String name = m_PlatformVect.elementAt(i);
String folder;
// Object obj = requested.get(name);
@@ -420,7 +420,7 @@
// {
folder = name + "/xml/";
writer.print(" <th bgcolor=\"" +
- (String) colorHash.get(name) + "\">" +
+ colorHash.get(name) + "\">" +
name.toUpperCase() +
" (<a href=\"../" + folder + localeStr + ".xml\">xml</a>)" +
"</th>\n");
@@ -440,8 +440,8 @@
private boolean printDifferentValues(CompareElement element, PrintWriter writer) {
boolean isEqual = true;
// following don't count
- if ((element.node.compareTo((String) "generation") == 0)
- || (element.node.compareTo((String) "version") == 0)) {
+ if ((element.node.compareTo("generation") == 0)
+ || (element.node.compareTo("version") == 0)) {
return isEqual;
}
@@ -482,7 +482,7 @@
writer.print(" <td>" + element.index + "</td>\n");
for (int i = 0; i < m_PlatformVect.size(); i++) {
- String val = (String) element.platformData.get(m_PlatformVect.elementAt(i));
+ String val = element.platformData.get(m_PlatformVect.elementAt(i));
if (val != null) {
writer.print(" <td>" + val + "</td>\n");
} else {
@@ -503,8 +503,8 @@
private boolean printDifferentValuesWithRef(CompareElement element, PrintWriter writer) {
boolean isEqual = true;
// following don't count
- if ((element.node.compareTo((String) "generation") == 0)
- || (element.node.compareTo((String) "version") == 0)) {
+ if ((element.node.compareTo("generation") == 0)
+ || (element.node.compareTo("version") == 0)) {
return isEqual;
}
@@ -512,11 +512,11 @@
boolean bFoundFirst = false;
for (int i = 0; i < m_PlatformVect.size(); i++) {
// excluding Common from diff
- String platform = (String) m_PlatformVect.elementAt(i);
+ String platform = m_PlatformVect.elementAt(i);
if (platform.compareTo(COMMON) == 0)
continue;
- String value = (String) element.platformData.get(platform);
+ String value = element.platformData.get(platform);
if (value == null)
continue;
@@ -557,7 +557,7 @@
writer.print(" <td>" + element.index + "</td>\n");
for (int i = 0; i < m_PlatformVect.size(); i++) {
- String val = (String) element.platformData.get(m_PlatformVect.elementAt(i));
+ String val = element.platformData.get(m_PlatformVect.elementAt(i));
if (val != null) {
writer.print(" <td>" + val + "</td>\n");
} else {
@@ -583,8 +583,8 @@
serialNumber++;
for (int i = 0; i < PLATFORM_PRINT_ORDER.length; i++) {
- String value = (String) element.platformData.get(PLATFORM_PRINT_ORDER[i]);
- String color = (String) colorHash.get(PLATFORM_PRINT_ORDER[i]);
+ String value = element.platformData.get(PLATFORM_PRINT_ORDER[i]);
+ String color = colorHash.get(PLATFORM_PRINT_ORDER[i]);
boolean caseDiff = false;
boolean isEqual = false;
// the locale exists for the given platform but there is no data
@@ -597,7 +597,7 @@
} else {
// pick the correct color
for (int j = 0; j < i; j++) {
- String compareTo = (String) element.platformData.get(PLATFORM_PRINT_ORDER[j]);
+ String compareTo = element.platformData.get(PLATFORM_PRINT_ORDER[j]);
if (compareTo == null) {
continue;
} else if (value.equals("")) {
@@ -606,17 +606,17 @@
} else if (element.parentNode.indexOf("decimalFormat") > -1
|| element.parentNode.indexOf("currencyFormat") > -1) {
if (comparePatterns(compareTo, value)) {
- color = (String) colorHash.get(PLATFORM_PRINT_ORDER[j]);
+ color = colorHash.get(PLATFORM_PRINT_ORDER[j]);
isEqual = true;
break;
}
} else if (Normalizer.compare(compareTo, value, 0) == 0) {
- color = (String) colorHash.get(PLATFORM_PRINT_ORDER[j]);
+ color = colorHash.get(PLATFORM_PRINT_ORDER[j]);
isEqual = true;
break;
} else if (Normalizer.compare(compareTo, value, Normalizer.COMPARE_IGNORE_CASE) == 0) {
caseDiff = true;
- color = (String) colorHash.get(PLATFORM_PRINT_ORDER[j]);
+ color = colorHash.get(PLATFORM_PRINT_ORDER[j]);
break;
}
}
@@ -624,8 +624,8 @@
value = "=";
} else {
if (i > 0) { // not the first platform
- if ((element.node.compareTo((String) "generation") == 0)
- || (element.node.compareTo((String) "version") == 0)) {
+ if ((element.node.compareTo("generation") == 0)
+ || (element.node.compareTo("version") == 0)) {
// ignored
} else {
m_diffcount++;
@@ -633,7 +633,7 @@
}
}
if (m_Vetting) {
- String altText = (String) element.platformData.get("ALT");
+ String altText = element.platformData.get("ALT");
writer.print("<td>" + value);
String parName = mapToAbbr(element.parentNode);
if ((parName.indexOf("_dateFormat") != -1)
@@ -1187,12 +1187,12 @@
// for country codes and language codes
// replace the deprecated codes with the latest ones
if (childNodeName.equals("language")) {
- String temp = (String) deprecatedLanguageCodes.get(index);
+ String temp = deprecatedLanguageCodes.get(index);
if (temp != null) {
index = temp;
}
} else if (childNodeName.equals("territory")) {
- String temp = (String) deprecatedCountryCodes.get(index);
+ String temp = deprecatedCountryCodes.get(index);
if (temp != null) {
index = temp;
}
@@ -1301,9 +1301,9 @@
// build a HashSet superset
File localeDir = null;
String[] fileList;
- Set<String> localeTreeSet = new TreeSet<String>(); // use TreeSet for locales in alphabetical order
+ Set<String> localeTreeSet = new TreeSet<>(); // use TreeSet for locales in alphabetical order
for (int i = 0; i < m_PlatformFolderVect.size(); i++) {
- localeDir = new File((String) m_PlatformFolderVect.elementAt(i));
+ localeDir = new File(m_PlatformFolderVect.elementAt(i));
fileList = localeDir.list();
for (int j = 0; j < fileList.length; j++) {
if (fileList[j].endsWith(".xml")) {
@@ -1316,7 +1316,7 @@
// as common will only be shown as a reference if there are differences between locales for
// other platforms
if ((m_iOptions & OPT_DIFF_REF_COMMON) != 0) {
- String platform = (String) m_PlatformVect.elementAt(i);
+ String platform = m_PlatformVect.elementAt(i);
if (platform.compareTo(COMMON) == 0)
continue;
}
@@ -1346,12 +1346,12 @@
// add entry to CompareMap for any platforms having an xml file for the locale in question
for (int j = 0; j < m_PlatformFolderVect.size(); j++) {
- localeDir = new File((String) m_PlatformFolderVect.elementAt(j));
+ localeDir = new File(m_PlatformFolderVect.elementAt(j));
fileList = localeDir.list();
for (int k = 0; k < fileList.length; k++) {
if (fileList[k].compareTo(localeFile) == 0) // test for 2 matching xml filenames
{
- String key = (String) m_PlatformVect.elementAt(j); // should use hashtable to link
+ String key = m_PlatformVect.elementAt(j); // should use hashtable to link
// m_PlatformVect and
// m_PlatformFolderVect
String xmlFileName = localeDir + "/" + localeArray[i];
diff --git a/tools/java/org/unicode/cldr/icu/LocaleMapper.java b/tools/java/org/unicode/cldr/icu/LocaleMapper.java
deleted file mode 100644
index 0d8f787..0000000
--- a/tools/java/org/unicode/cldr/icu/LocaleMapper.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.icu.RegexManager.CldrArray;
-import org.unicode.cldr.icu.RegexManager.PathValueInfo;
-import org.unicode.cldr.icu.RegexManager.RegexResult;
-import org.unicode.cldr.test.DisplayAndInputProcessor.NumericType;
-import org.unicode.cldr.tool.FilterFactory;
-import org.unicode.cldr.util.Builder;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.DtdType;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.LanguageTagParser;
-import org.unicode.cldr.util.LocaleIDParser;
-import org.unicode.cldr.util.PatternCache;
-import org.unicode.cldr.util.RegexLookup;
-import org.unicode.cldr.util.RegexLookup.Finder;
-import org.unicode.cldr.util.SupplementalDataInfo;
-//import org.unicode.cldr.util.SupplementalDataInfo.MeasurementType;
-
-import com.ibm.icu.util.Output;
-
-/**
- * A mapper that converts locale data from CLDR to the ICU data structure.
- *
- * @author jchye
- */
-public class LocaleMapper extends Mapper {
- /**
- * Map for converting enums to their integer values.
- */
- private static final Map<String, String> enumMap = Builder.with(new HashMap<String, String>())
- .put("titlecase-firstword", "1")
- .put("no-change", "0")
- .freeze();
-
- private static final Pattern DRAFT_PATTERN = PatternCache.get("\\[@draft=\"\\w+\"]");
- private static final Pattern TERRITORY_XPATH = PatternCache.get(
- "//ldml/localeDisplayNames/territories/territory\\[@type=\"(\\w+)\"]");
- private static final Pattern RB_DATETIMEPATTERN = PatternCache.get(
- "/calendar/(\\w++)/DateTimePatterns");
-
- private SupplementalDataInfo supplementalDataInfo;
- // We may use different factories for resolved or unresolved CLDRFiles depending
- // on whether filtering is required.
- private Factory unresolvedFactory;
- private Factory resolvedFactory;
- private Factory specialFactory;
- private RegexManager manager;
- private String debugXPath;
-
- private Set<String> deprecatedTerritories;
-
- /**
- * Special hack comparator, so that RB strings come out in the right order.
- * This is only important for the order of items in arrays.
- */
- private static Comparator<String> comparator = new Comparator<String>() {
- private final Pattern CURRENCY_FORMAT = PatternCache.get(
- "//ldml/numbers/currencies/currency\\[@type=\"\\w++\"]/(.++)");
- private final Pattern DATE_OR_TIME_FORMAT = PatternCache.get(
- "//ldml/dates/calendars/calendar\\[@type=\"\\w++\"]/(date|time)Formats/.*");
- private final Pattern MONTH_PATTERN = PatternCache
- .get(
- "//ldml/dates/calendars/calendar\\[@type=\"\\w++\"]/months/monthContext\\[@type=\"[\\w\\-]++\"]/monthWidth\\[@type=\"\\w++\"]/month\\[@type=\"\\d++\"](\\[@yeartype=\"leap\"])?");
- private final Pattern CONTEXT_TRANSFORM = PatternCache.get(
- "//ldml/contextTransforms/contextTransformUsage\\[@type=\"([^\"]++)\"]/contextTransform\\[@type=\"([^\"]++)\"]");
-
- private final String[] CURRENCY_ORDER = { "symbol", "displayName",
- "pattern[@type=\"standard\"]", "decimal", "group" };
-
- /**
- * Reverse the ordering of the following:
- * //ldml/numbers/currencies/currency[@type="([^"]*)"]/displayName ; curr ; /Currencies/$1
- * //ldml/numbers/currencies/currency[@type="([^"]*)"]/symbol ; curr ; /Currencies/$1
- * and the following (time/date)
- * //ldml/dates/calendars/calendar[@type="([^"]*)"]/(dateFormats|dateTimeFormats|timeFormats)/(?:[^/\[]*)[@type=
- * "([^"]*)"]/(?:[^/\[]*)[@type="([^"]*)"]/.* ; locales ; /calendar/$1/DateTimePatterns
- */
- @Override
- public int compare(String arg0, String arg1) {
- Matcher[] matchers = new Matcher[2];
- if (RegexManager.matches(CURRENCY_FORMAT, arg0, arg1, matchers)) {
- // Use ldml ordering except that symbol should be first.
- int index0 = getIndexOf(CURRENCY_ORDER, matchers[0].group(1));
- int index1 = getIndexOf(CURRENCY_ORDER, matchers[1].group(1));
- return index0 - index1;
- } else if (RegexManager.matches(DATE_OR_TIME_FORMAT, arg0, arg1, matchers)) {
- int compareValue = matchers[0].group(1).compareTo(matchers[1].group(1));
- if (compareValue != 0) return -compareValue;
- } else if (RegexManager.matches(CONTEXT_TRANSFORM, arg0, arg1, matchers)) {
- // Sort uiListOrMenu before stand-alone.
- if (matchers[0].group(1).equals(matchers[1].group(1))) {
- return -matchers[0].group(2).compareTo(matchers[1].group(2));
- }
- } else if (RegexManager.matches(MONTH_PATTERN, arg0, arg1, matchers)) {
- // Sort leap year types after normal month types.
- String matchGroup0 = matchers[0].group(1);
- String matchGroup1 = matchers[1].group(1);
- if (matchGroup0 != matchGroup1) {
- return matchGroup0 == null && matchGroup1 != null ? -1 : 1;
- }
- }
-
- return CLDRFile.getComparator(DtdType.ldml).compare(arg0, arg1);
- }
- };
-
- /**
- * Looks for a string in an array
- *
- * @param order
- * the array to be searched
- * @param key
- * the string to be searched for
- * @return the index of the string if found, -1 if not found
- */
- private static int getIndexOf(String[] order, String key) {
- for (int i = 0; i < order.length; i++) {
- if (order[i].equals(key)) return i;
- }
- return -1;
- }
-
- /**
- * LocaleMapper constructor.
- *
- * @param factory
- * the factory containing the CLDR data to be converted
- * @param specialFactory
- * a factory containing any additional CLDR data
- * @param supplementalDataInfo
- * SupplementalDataInfo object
- * @param useAltValues
- * true if alt path filtering should be performed
- * @param organization
- * the organization to filter the data by
- * (null if coverage filtering is not needed)
- */
- public LocaleMapper(Factory factory, Factory specialFactory,
- SupplementalDataInfo supplementalDataInfo, boolean useAltValues,
- String organization) {
- manager = new RegexManager("ldml2icu_locale.txt");
- unresolvedFactory = resolvedFactory = factory;
- // If filtering is required, filter all unresolved CLDRFiles for use in
- // fillFromCldr(). We don't filter the resolved CLDRFiles by organization
- // coverage level because
- // some rbPaths (e.g. /calendar/x/DateTimePatterns) have a fixed number
- // of values that must always be present regardless of filtering.
- if (useAltValues || organization != null) {
- unresolvedFactory = FilterFactory.load(factory, organization, useAltValues);
- resolvedFactory = FilterFactory.load(factory, null, useAltValues);
- }
- this.specialFactory = specialFactory;
- this.supplementalDataInfo = supplementalDataInfo;
- }
-
- /**
- * @return the set of locales available for processing by this mapper
- */
- @Override
- public Set<String> getAvailable() {
- return unresolvedFactory.getAvailable();
- }
-
- /**
- * @param filename
- * @return true if a special XML file with the specified filename is available.
- */
- private boolean hasSpecialFile(String filename) {
- return specialFactory != null && specialFactory.getAvailable().contains(filename);
- }
-
- /**
- * @return the set of deprecated territories to be ignored. Remove when no longer
- * present in CLDR data.
- */
- private Set<String> getDeprecatedTerritories() {
- if (deprecatedTerritories == null) {
- deprecatedTerritories = Builder.with(
- supplementalDataInfo.getLocaleAliasInfo().get("territory").keySet())
- .remove("062").remove("172").remove("200").remove("830")
- .remove("AN").remove("CS").remove("QU").get();
- }
- return deprecatedTerritories;
- }
-
- /**
- * Fills an IcuData object using the CLDR data for the specified locale.
- *
- * @param locale
- * @return the filled IcuData object
- */
- @Override
- public IcuData[] fillFromCldr(String locale) {
- Set<String> deprecatedTerritories = getDeprecatedTerritories();
- CLDRFile resolvedCldr = resolvedFactory.make(locale, true);
- RegexLookup<RegexResult> pathConverter = manager.getPathConverter(resolvedCldr);
-
- // First pass through the unresolved CLDRFile to get all icu paths.
- CLDRFile cldr = unresolvedFactory.make(locale, false);
- Map<String, CldrArray> pathValueMap = new HashMap<String, CldrArray>();
- Set<String> validRbPaths = new HashSet<String>();
- for (String xpath : cldr) {
- // Territory hacks to be removed once CLDR data is fixed.
- Matcher matcher = TERRITORY_XPATH.matcher(xpath);
- if (matcher.matches()) {
- String country = matcher.group(1);
- if (deprecatedTerritories.contains(country)) {
- continue;
- }
- }
-
- // Add rb paths.
- Output<Finder> matcherFound = new Output<Finder>();
- Output<String[]> firstInfo = new Output<>();
- RegexResult regexResult = matchXPath(pathConverter, cldr, xpath, matcherFound, firstInfo);
- if (regexResult == null) continue;
-// String[] arguments = matcherFound.value.getInfo();
- String[] arguments = firstInfo.value;
- for (PathValueInfo info : regexResult) {
- String rbPath = info.processRbPath(arguments);
- validRbPaths.add(rbPath);
- // The immediate parent of every path should also exist.
- validRbPaths.add(rbPath.substring(0, rbPath.lastIndexOf('/')));
- }
- }
-
- // Get all values from the resolved CLDRFile.
- for (String xpath : resolvedCldr) {
- // Since the unresolved CLDRFile may have been modified, use it
- // to add values instead of the resolved CLDRFile if possible.
- CLDRFile fileToUse = cldr.getStringValue(xpath) == null ? resolvedCldr : cldr;
- addMatchesForPath(xpath, fileToUse, validRbPaths, pathConverter, pathValueMap);
- }
-
- // Add fallback paths if necessary.
- manager.addFallbackValues(resolvedCldr, pathValueMap);
-
- // Add special values to file.
- boolean hasSpecial = hasSpecialFile(locale);
- if (hasSpecial) {
- CLDRFile specialCldrFile = specialFactory.make(locale, false);
- for (String xpath : specialCldrFile) {
- if (resolvedCldr.isHere(xpath)) continue;
- addMatchesForPath(xpath, specialCldrFile, null, pathConverter, pathValueMap);
- }
- }
-
- for (String rbPath : pathValueMap.keySet()) {
- // HACK: DateTimePatterns needs a duplicate of the medium
- // dateTimeFormat (formerly indicated using dateTimeFormats/default).
- // This hack can be removed when ICU no longer requires it.
- Matcher matcher = RB_DATETIMEPATTERN.matcher(rbPath);
- if (matcher.matches()) {
- String calendar = matcher.group(1);
- CldrArray valueList = RegexManager.getCldrArray(rbPath, pathValueMap);
- // Create a dummy xpath to sort the value in front of the other date time formats.
- String basePath = "//ldml/dates/calendars/calendar[@type=\"" + calendar + "\"]/dateTimeFormats";
- String mediumFormatPath = basePath
- + "/dateTimeFormatLength[@type=\"medium\"]/dateTimeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]";
- valueList.add(basePath,
- getStringValue(resolvedCldr, mediumFormatPath),
- null);
- }
- }
-
- // HACK: Fill missing narrow era values with their abbreviated versions.
- CldrArray narrowEras = pathValueMap.get("/calendar/japanese/eras/narrow");
- CldrArray abbreviatedEras = pathValueMap.get("/calendar/japanese/eras/abbreviated");
- if (narrowEras != null && abbreviatedEras != null) {
- narrowEras.addAll(abbreviatedEras);
- }
-
- IcuData icuData = new IcuData("common/main/" + locale + ".xml", locale, true, enumMap);
- if (hasSpecial) {
- icuData.setFileComment("ICU <specials> source: <path>/common/main/" + locale + ".xml");
- }
- fillIcuData(pathValueMap, comparator, icuData);
-
- // More hacks
- hackAddExtras(resolvedCldr, locale, icuData);
- return new IcuData[] { icuData };
- }
-
- private void fillIcuData(Map<String, CldrArray> pathValueMap,
- Comparator<String> comparator, IcuData icuData) {
- // Convert values to final data structure.
- for (String rbPath : pathValueMap.keySet()) {
- icuData.addAll(rbPath, pathValueMap.get(rbPath).sortValues(comparator));
- }
- }
-
- public static String getFullXPath(String xpath, CLDRFile cldrFile) {
- String fullPath = cldrFile.getFullXPath(xpath);
- return fullPath == null ? xpath : DRAFT_PATTERN.matcher(fullPath).replaceAll("");
- }
-
- /**
- * @param cldr
- * @param path
- * @param matcherFound
- * @param firstInfo
- * @return the result of converting an xpath into an ICU-style path
- */
- private RegexResult matchXPath(RegexLookup<RegexResult> lookup,
- CLDRFile cldr, String path,
- Output<Finder> matcherFound, Output<String[]> firstInfo) {
- String fullPath = cldr.getFullXPath(path);
- fullPath = fullPath == null ? path : DRAFT_PATTERN.matcher(fullPath).replaceAll("");
- List<String> debugResults = isDebugXPath(fullPath) ? new ArrayList<String>() : null;
- Output<String[]> info = new Output<>();
- RegexResult result = lookup.get(fullPath, null, info, matcherFound, debugResults);
- if (debugResults != null) {
- if (result == null) {
- RegexManager.printLookupResults(fullPath, debugResults);
- } else {
- System.out.println(fullPath + " successfully matched");
- }
- }
- if (firstInfo != null && info.value != null) {
- firstInfo.value = info.value;
- }
- return result;
- }
-
- /**
- * Attempts to match an xpath and adds the results of a successful match to
- * the specified map
- *
- * @param xpath
- * the xpath to be matched
- * @param cldrFile
- * the CLDR file to get locale data from
- * @param validRbPaths
- * the set of valid rbPaths that the result must belong
- * to, null if such a requirement does not exist
- * @param pathValueMap
- * the map that the results will be added to
- */
- private void addMatchesForPath(String xpath, CLDRFile cldrFile,
- Set<String> validRbPaths, RegexLookup<RegexResult> pathConverter,
- Map<String, CldrArray> pathValueMap) {
- Output<Finder> matcher = new Output<Finder>();
- Output<String[]> firstInfo = new Output<>();
- RegexResult regexResult = matchXPath(pathConverter,
- cldrFile, xpath, matcher, firstInfo);
- if (regexResult == null) return;
-// String[] arguments = matcher.value.getInfo();
- String[] arguments = firstInfo.value;
- String cldrValue = getStringValue(cldrFile, xpath);
- for (PathValueInfo info : regexResult) {
- String rbPath = info.processRbPath(arguments);
- // Don't add additional paths at this stage.
- if (validRbPaths != null && !validRbPaths.contains(rbPath)) continue;
- CldrArray valueList = RegexManager.getCldrArray(rbPath, pathValueMap);
- List<String> values = info.processValues(arguments, cldrValue);
- String baseXPath = info.processXPath(arguments, xpath);
- String groupKey = info.processGroupKey(arguments);
- valueList.put(baseXPath, values, groupKey);
- }
- }
-
- /**
- * @param cldrFile
- * @param xpath
- * @return the value of the specified xpath (fallback or otherwise)
- */
- private String getStringValue(CLDRFile cldrFile, String xpath) {
- String value = cldrFile.getStringValue(xpath);
- // HACK: DAIP doesn't currently make spaces in currency formats non-breaking.
- // Remove this when fixed.
- if (NumericType.getNumericType(xpath) == NumericType.CURRENCY) {
- value = value.replace(' ', '\u00A0');
- }
- return value;
- }
-
- /**
- * Adds all mappings that couldn't be represented in the ldml2icu.txt file.
- *
- * @param cldrResolved
- * @param locale
- */
- private void hackAddExtras(CLDRFile cldrResolved, String locale, IcuData icuData) {
- // Specify parent of non-language locales.
- String parent = supplementalDataInfo.getExplicitParentLocale(locale);
- if (parent != null) {
- icuData.add("/%%Parent", parent);
- }
-
- // <version number="$Revision: 5806 $"/>
- String version = cldrResolved.getFullXPath("//ldml/identity/version");
- icuData.add("/Version", CLDRFile.GEN_VERSION);
-
- // PaperSize:intvector{ 279, 216, } - now in supplemental
- // MeasurementSystem:int{1} - now in supplemental
-
- // Default calendar.
- String localeID = cldrResolved.getLocaleID();
- String calendar = getCalendarIfDifferent(localeID);
- if (calendar != null) {
- icuData.add("/calendar/default", calendar);
- }
- }
-
- /**
- * Returns the default calendar to be used for a locale. If the default
- * calendar for the parent locale is the same, null is returned.
- */
- private String getCalendarIfDifferent(String localeID) {
- String calendar = getCalendar(localeID);
- if (calendar == null) return null;
- String parent = LocaleIDParser.getParent(localeID);
- String parentCalendar = null;
- while (parentCalendar == null && parent != null) {
- parentCalendar = getCalendar(parent);
- parent = LocaleIDParser.getParent(parent);
- }
- return calendar.equals(parentCalendar) ? null : calendar;
- }
-
- /**
- * Returns the default calendar to be used for a locale, if any.
- */
- private String getCalendar(String localeID) {
- LanguageTagParser parser = new LanguageTagParser().set(localeID);
- String region = localeID.equals("root") ? "001" : parser.getRegion();
- if (region.equals("")) {
- localeID = supplementalDataInfo.getLikelySubtags().get(parser.getLanguage());
- if (localeID == null) {
- throw new RuntimeException("Likely subtag not found for " + parser.getLanguage());
- }
- parser.set(localeID);
- region = parser.getRegion();
- if (region == null) region = "001";
- }
- List<String> calendars = supplementalDataInfo.getCalendars(region);
- return calendars == null ? null : calendars.get(0);
- }
-
- //private String getMeasurementToDisplay(String localeID, MeasurementType measurementType) {...} // deleted
-
- /**
- * @param localeID
- * @param measurementType
- * the type of measurement required
- * @return the measurement of the specified locale
- */
-// private String getMeasurement(String localeID, MeasurementType measurementType) {
-// String region = localeID.equals("root") ? "001" : new LanguageTagParser().set(localeID).getRegion();
-// Map<MeasurementType, Map<String, String>> regionMeasurementData = supplementalDataInfo
-// .getTerritoryMeasurementData();
-// Map<String, String> typeMap = regionMeasurementData.get(measurementType);
-// return typeMap.get(region);
-// } //not used
-
- /**
- * Sets xpath to monitor for debugging purposes.
- * @param debugXPath
- */
- public void setDebugXPath(String debugXPath) {
- this.debugXPath = debugXPath;
- }
-
- /**
- * @param xpath
- * @return true if the xpath is to be debugged
- */
- boolean isDebugXPath(String xpath) {
- return debugXPath == null ? false : xpath.startsWith(debugXPath);
- }
-
- @Override
- public Makefile generateMakefile(Collection<String> aliases) {
- Makefile makefile = new Makefile("GENRB");
- makefile.addSyntheticAlias(aliases);
- makefile.addAliasSource();
- makefile.addSource(sources);
- return makefile;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/Makefile.java b/tools/java/org/unicode/cldr/icu/Makefile.java
deleted file mode 100644
index fa84aaa..0000000
--- a/tools/java/org/unicode/cldr/icu/Makefile.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.FileCopier;
-import org.unicode.cldr.util.PatternCache;
-
-import com.google.common.collect.ImmutableMap;
-import com.ibm.icu.util.Calendar;
-
-/**
- * Stores the content of a makefile and writes it to disk.
- * @author jchye
- */
-class Makefile {
- private static final Pattern VARIABLE = PatternCache.get("\\$\\([\\w_]++\\)");
-
- private String prefix;
- private List<MakefileEntry> entries = new ArrayList<MakefileEntry>();
-
- private static final Comparator<String> valueComparator = new Comparator<String>() {
- @Override
- public int compare(String arg0, String arg1) {
- return arg0.compareTo(arg1);
- }
- };
-
- class MakefileEntry {
- String name;
- String comment;
- List<String> values = new ArrayList<String>();
-
- public MakefileEntry(String name, String comment) {
- this.name = name;
- this.comment = comment;
- }
- }
-
- public Makefile(String prefix) {
- this.prefix = prefix;
- }
-
- public MakefileEntry addEntry(String name, String comment) {
- MakefileEntry entry = new MakefileEntry(name, comment);
- entries.add(entry);
- return entry;
- }
-
- public MakefileEntry addEntry(String name, String comment, Collection<String> values) {
- MakefileEntry entry = addEntry(name, comment);
- entry.values.addAll(values);
- Collections.sort(entry.values, valueComparator);
- return entry;
- }
-
- public void addSyntheticAlias(Collection<String> aliases) {
- addEntry(prefix + "_SYNTHETIC_ALIAS",
- "Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)",
- aliases);
- }
-
- public void addAliasSource() {
- MakefileEntry entry = addEntry(prefix + "_ALIAS_SOURCE",
- "All aliases (to not be included under 'installed'), but not including root.");
- entry.values.add("$(" + prefix + "_SYNTHETIC_ALIAS)");
- }
-
- public void addSource(Collection<String> sources) {
- addEntry(prefix + "_SOURCE", "Ordinary resources", sources);
- }
-
- public void print(String outputDir, String filename) throws IOException {
- PrintWriter out = FileUtilities.openUTF8Writer(outputDir, filename);
- ImmutableMap<String, String> params = ImmutableMap.of(
- "%year%", String.valueOf(Calendar.getInstance().get(Calendar.YEAR)),
- "%prefix%", prefix,
- "%local%", filename.replace("files.mk", "local.mk"),
- "%version%", CLDRFile.GEN_VERSION);
-
- FileCopier.copyAndReplace(NewLdml2IcuConverter.class, "makefile_header.txt",
- Charset.forName("UTF-8"),
- params,
- out);
-
- for (MakefileEntry entry : entries) {
- out.println();
- out.append("# ").append(entry.comment).println();
- out.append(entry.name).append(" =");
- int lineCount = 0;
- for (String value : entry.values) {
- if (value.equals("root")) continue;
- if (lineCount == 4) {
- out.append('\\').println();
- }
- out.append(' ').append(value);
- if (!VARIABLE.matcher(value).matches()) {
- out.append(".txt");
- }
- lineCount = (lineCount + 1) % 5;
- }
- out.println();
- out.println();
- }
- out.close();
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/Mapper.java b/tools/java/org/unicode/cldr/icu/Mapper.java
deleted file mode 100644
index ea33562..0000000
--- a/tools/java/org/unicode/cldr/icu/Mapper.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * Superclass for mappers that convert CLDR data to ICU text files.
- * @author jchye
- */
-public abstract class Mapper {
- // Store list of sources for makefile generation.
- protected Set<String> sources = new HashSet<String>();
-
- /**
- * Converts the specified locale into one or more IcuData objects.
- */
- public abstract IcuData[] fillFromCldr(String locale); // private/protected?
-
- /**
- * Returns an iterator that iterates through all of the CLDR data within the
- * scope of this mapper and matching the specified filter and returns the generated IcuData objects.
- */
- public Iterator<IcuData> iterator(final Filter filter) {
- IcuDataIterator iterator = new IcuDataIterator(filter);
- iterator.init();
- return iterator;
- }
-
- private class IcuDataIterator implements Iterator<IcuData> {
- private Filter filter;
- private Iterator<String> localeIterator = getAvailable().iterator();
- private IcuData[] curArray;
- private int curIndex = -1;
-
- private IcuDataIterator(Filter filter) {
- this.filter = filter;
- }
-
- /**
- * Initializes internal variables before starting iteration.
- */
- private void init() {
- curArray = new IcuData[0];
- loadNextPos();
- }
-
- @Override
- public boolean hasNext() {
- return localeIterator.hasNext() || curIndex < curArray.length;
- }
-
- @Override
- public IcuData next() {
- IcuData icuData = curArray[curIndex];
- sources.add(icuData.getName());
- // Move to next valid position.
- loadNextPos();
- return icuData;
- }
-
- /**
- * Prepares the next item in the iterator.
- */
- private void loadNextPos() {
- do {
- curIndex++;
- if (curIndex == curArray.length) {
- String locale = null;
- do {
- if (!localeIterator.hasNext()) {
- // No more items left in the iterator.
- return;
- }
- locale = localeIterator.next();
- } while (!filter.includes(locale));
- curArray = fillFromCldr(locale);
- curIndex = 0;
- }
- } while (!filter.includes(curArray[curIndex].getName()));
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * @return the set of IcuData objects that were generated by the mapper.
- */
- public Set<String> getGenerated() {
- return sources;
- }
-
- /**
- * Returns the set of all CLDR locales available for conversion.
- */
- public abstract Collection<String> getAvailable();
-
- /**
- * Generates a makefile from the list of locales converted by this mapper.
- * @param aliases any aliases that were created apart from this mapper
- * @return the generated makefile
- */
- public abstract Makefile generateMakefile(Collection<String> aliases);
-}
diff --git a/tools/java/org/unicode/cldr/icu/MapperUtils.java b/tools/java/org/unicode/cldr/icu/MapperUtils.java
deleted file mode 100644
index 756993d..0000000
--- a/tools/java/org/unicode/cldr/icu/MapperUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.unicode.cldr.util.InputStreamFactory;
-import org.unicode.cldr.util.XMLFileReader;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-
-/**
- * Utility class for NewLdml2IcuConverter mappers.
- *
- * @author jchye
- */
-public class MapperUtils {
- /**
- * Parses an XML file.
- *
- * @param inputFile
- * the file to be parsed
- * @param handler
- * the XML parser to be used
- */
- public static void parseFile(File inputFile, ContentHandler handler) {
- XMLReader xmlReader = XMLFileReader.createXMLReader(true);
- xmlReader.setContentHandler(handler);
- if (inputFile == null) {
- System.err.println("Please call with non-null input file");
- return;
- }
- try (InputStream fis = InputStreamFactory.createInputStream(inputFile)) {
-// FileInputStream fis = new FileInputStream(inputFile);
- InputSource is = new InputSource(fis);
- // Set the system ID so the parser knows where to find the dtd.
- is.setSystemId(inputFile.toString());
- xmlReader.parse(is);
-// fis.close();
- } catch (IOException | SAXException e) {
- System.err.println("Error loading " + inputFile.getAbsolutePath());
- e.printStackTrace();
- }
- }
-
- /**
- * Empty convenience superclass for all XML parsers used in mappers.
- *
- * @author jchye
- *
- */
- public static abstract class EmptyHandler implements ContentHandler {
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- }
-
- @Override
- public void startPrefixMapping(String arg0, String arg1) throws SAXException {
- }
-
- @Override
- public void endPrefixMapping(String arg0) throws SAXException {
- }
-
- @Override
- public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
- }
-
- @Override
- public void processingInstruction(String arg0, String arg1) throws SAXException {
- }
-
- @Override
- public void setDocumentLocator(Locator arg0) {
- }
-
- @Override
- public void skippedEntity(String arg0) throws SAXException {
- }
-
- @Override
- public void startDocument() throws SAXException {
- }
-
- @Override
- public void endDocument() throws SAXException {
- }
- }
-
- public static IcuData[] toArray(Collection<IcuData> collection) {
- IcuData[] dataList = new IcuData[collection.size()];
- return collection.toArray(dataList);
- }
-
- /**
- * Returns a list of names of XML files in the specified directory.
- * @param sourceDir
- * @return
- */
- public static List<String> getNames(String sourceDir) {
- return getNames(new File(sourceDir));
- }
-
- /**
- * Returns a list of names of XML files in the specified directory.
- * @param sourceDir
- * @return
- */
- public static List<String> getNames(File sourceDir) {
- List<String> locales = new ArrayList<String>();
- for (String filename : sourceDir.list()) {
- if (!filename.endsWith(".xml")) continue;
- String locale = filename.substring(0, filename.length() - 4);
- locales.add(locale);
- }
- return locales;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/NewLdml2IcuConverter.java b/tools/java/org/unicode/cldr/icu/NewLdml2IcuConverter.java
deleted file mode 100644
index a14dd9f..0000000
--- a/tools/java/org/unicode/cldr/icu/NewLdml2IcuConverter.java
+++ /dev/null
@@ -1,503 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.ant.CLDRConverterTool;
-import org.unicode.cldr.icu.ResourceSplitter.SplitInfo;
-import org.unicode.cldr.tool.Option;
-import org.unicode.cldr.tool.Option.Options;
-import org.unicode.cldr.util.CLDRFile.DraftStatus;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.FileReaders;
-import org.unicode.cldr.util.PatternCache;
-import org.unicode.cldr.util.SupplementalDataInfo;
-
-/**
- * Simpler mechanism for converting CLDR data to ICU Resource Bundles, intended
- * to replace LDML2ICUConverter. The format is almost entirely data-driven
- * instead of having lots of special-case code.
- *
- * The flags used to specify the data to be generated are copied directly from
- * LDML2ICUConverter.
- *
- * Unlike the instructions in CLDRConverterTool, this converter does not invoke
- * computeConvertibleXPaths to check if each xpath is convertible because the
- * xpaths that are convertible have already been filtered out by the regex lookups.
- * It may make more sense down the road to refactor CLDRConverterTool such that
- * this class doesn't inherit unnecessary functionality.
- *
- * A rough overview of the new converter is available at
- * https://sites.google.com/site/cldr/development/coding-cldr-tools/newldml2icuconverter
- *
- * @author jchye
- */
-public class NewLdml2IcuConverter extends CLDRConverterTool {
- private static final String ALIAS_PATH = "/\"%%ALIAS\"";
-
- static final boolean DEBUG = true;
-
- static final Pattern SEMI = PatternCache.get("\\s*+;\\s*+");
-
- /*
- * The type of file to be converted.
- */
- enum Type {
- locales, dayPeriods, genderList, likelySubtags, metadata, metaZones, numberingSystems, plurals, pluralRanges, postalCodeData, rgScope, supplementalData, windowsZones, keyTypeData, brkitr, collation, rbnf;
- }
-
- private static final Options options = new Options(
- "Usage: LDML2ICUConverter [OPTIONS] [FILES]\n" +
- "This program is used to convert LDML files to ICU data text files.\n" +
- "Please refer to the following options. Options are not case sensitive.\n" +
- "\texample: org.unicode.cldr.icu.Ldml2IcuConverter -s xxx -d yyy en")
- .add("sourcedir", ".*", "Source directory for CLDR files")
- .add("destdir", ".*", ".", "Destination directory for output files, defaults to the current directory")
- .add("specialsdir", 'p', ".*", null, "Source directory for files containing special data, if any")
- .add("supplementaldir", 'm', ".*", null, "The supplemental data directory")
- .add("keeptogether", 'k', null, null,
- "Write locale data to one file instead of splitting into separate directories. For debugging")
- .add("type", 't', "\\w+", null, "The type of file to be generated")
- .add("xpath", 'x', ".*", null, "An optional xpath to debug the regexes with")
- .add("filter", 'f', null, null, "Perform filtering on the locale data to be converted.")
- .add("organization", 'o', ".*", null, "The organization to filter the data for")
- .add("makefile", 'g', ".*", null, "If set, generates makefiles and alias files for the specified type. " +
- "The value to set should be the name of the makefile.")
- .add("depgraphfile", 'e', ".*", null, "If set, generates a dependency graph file in JSON form summarizing parent and alias mappings between locale files. Only works when --type=locales.")
- .add("verbose", 'v', null, null, "Debugging aids");
-
- private static final String LOCALES_DIR = "locales";
-
- private boolean keepTogether = false;
- private Map<String, String> dirMapping;
- private Set<String> allDirs;
- private String sourceDir;
- private String destinationDir;
- private String supplementalDir;
- private IcuDataSplitter splitter;
- private Filter filter;
- private boolean verbose = false;
-
- /**
- * Maps ICU paths to the directories they should end up in.
- */
- private Map<String, String> getDirMapping() {
- if (dirMapping == null) {
- dirMapping = loadMapFromFile("ldml2icu_dir_mapping.txt");
- allDirs = new HashSet<String>(dirMapping.values());
- allDirs.remove("*");
- allDirs.add(LOCALES_DIR);
- }
- return dirMapping;
- }
-
- private static Map<String, String> loadMapFromFile(String filename) {
- Map<String, String> map = new HashMap<String, String>();
- BufferedReader reader = FileReaders.openFile(NewLdml2IcuConverter.class, filename);
- String line;
- try {
- int lineNum = 1;
- while ((line = reader.readLine()) != null) {
- if (line.length() == 0 || line.startsWith("#")) continue;
- String[] content = line.split(SEMI.toString());
- if (content.length != 2) {
- throw new IllegalArgumentException("Invalid syntax of " + filename + " at line " + lineNum);
- }
- map.put(content[0], content[1]);
- lineNum++;
- }
- } catch (IOException e) {
- System.err.println("Failed to read fallback file.");
- e.printStackTrace();
- }
- return map;
- }
-
- private List<SplitInfo> loadSplitInfoFromFile() {
- Map<String, String> dirMapping = getDirMapping();
- List<SplitInfo> splitInfos = new ArrayList<SplitInfo>();
- for (Entry<String, String> entry : dirMapping.entrySet()) {
- SplitInfo splitInfo = new SplitInfo(entry.getKey(), entry.getValue());
- splitInfos.add(splitInfo);
- }
- return splitInfos;
- }
-
- @Override
- public void processArgs(String[] args) {
- Set<String> extraArgs = options.parse(args, true);
- // For supplemental output files, the supplemental directory is specified
- // as the source directory and the supplemental directory argument is
- // not required.
- if (!options.get("sourcedir").doesOccur()) {
- throw new IllegalArgumentException("Source directory must be specified.");
- }
- sourceDir = options.get("sourcedir").getValue();
- supplementalDir = options.get("supplementaldir").getValue();
-
- destinationDir = options.get("destdir").getValue();
- if (!options.get("type").doesOccur()) {
- throw new IllegalArgumentException("Type not specified: " + Arrays.asList(Type.values()));
- }
- Type type = Type.valueOf(options.get("type").getValue());
- keepTogether = options.get("keeptogether").doesOccur();
- if (!keepTogether && type == Type.supplementalData || type == Type.locales) {
- if (splitInfos == null) {
- splitInfos = loadSplitInfoFromFile();
- }
- splitter = IcuDataSplitter.make(destinationDir, splitInfos);
- }
-
- verbose = options.get("verbose").doesOccur();
-
- String debugXPath = options.get("xpath").getValue();
- // Quotes are stripped out at the command line so add them back in.
- if (debugXPath != null) {
- debugXPath = debugXPath.replaceAll("=([^\\]\"]++)\\]", "=\"$1\"\\]");
- }
-
- Factory specialFactory = null;
- File specialsDir = null;
- Option option = options.get("specialsdir");
- if (option.doesOccur()) {
- if (type == Type.rbnf) {
- specialsDir = new File(option.getValue());
- } else {
- specialFactory = Factory.make(option.getValue(), ".*");
- }
- } else if (type == Type.brkitr) {
- specialFactory = Factory.make(options.get("specialsdir").getValue(), ".*");
- }
-
- // Get list of locales if defined.
- Set<String> includedLocales = getIncludedLocales();
- Map<String, String> localesMap = getLocalesMap();
- if (includedLocales != null && includedLocales.size() > 0) {
- final Set<String> locales = new HashSet<String>();
- for (String locale : includedLocales) {
- if (localesMap.containsKey(locale + ".xml")) {
- locales.add(locale);
- }
- }
-
- filter = new Filter() {
- @Override
- public boolean includes(String value) {
- return locales.contains(value);
- }
- };
- } else if (extraArgs.size() > 0) {
- final String regex = extraArgs.iterator().next();
- filter = new Filter() {
- @Override
- public boolean includes(String value) {
- return value.matches(regex);
- }
- };
- } else if (type == Type.locales || type == Type.collation) {
- throw new IllegalArgumentException(
- "Missing locale list. Please provide a list of locales or a regex.");
- } else {
- filter = new Filter() {
- @Override
- public boolean includes(String value) {
- return true;
- }
- };
- }
-
- // Process files.
- Mapper mapper = null;
- switch (type) {
- case locales:
- // Generate locale data.
- SupplementalDataInfo supplementalDataInfo = null;
- option = options.get("supplementaldir");
- if (option.doesOccur()) {
- supplementalDataInfo = SupplementalDataInfo.getInstance(supplementalDir);
- } else {
- throw new IllegalArgumentException("Supplemental directory must be specified with -s");
- }
-
- option = options.get("depgraphfile");
- if (option.doesOccur()) {
- DependencyGraphData dependencyGraphData = new DependencyGraphData(
- supplementalDataInfo, aliasDeprecates);
- generateDependencyGraphFile(dependencyGraphData, option.getValue());
- }
-
- Factory factory = Factory.make(sourceDir, ".*", DraftStatus.contributed);
- String organization = options.get("organization").getValue();
- LocaleMapper localeMapper = new LocaleMapper(factory, specialFactory,
- supplementalDataInfo, options.get("filter").doesOccur(), organization);
- localeMapper.setDebugXPath(debugXPath);
- mapper = localeMapper;
- break;
- case keyTypeData:
- processBcp47Data();
- break;
- case brkitr:
- mapper = new BreakIteratorMapper(sourceDir, specialFactory);
- break;
- case collation:
- mapper = new CollationMapper(sourceDir, specialFactory);
- break;
- case rbnf:
- mapper = new RbnfMapper(new File(sourceDir), specialsDir);
- break;
- default: // supplemental data
- processSupplemental(type, debugXPath);
- }
-
- if (mapper != null) {
- convert(mapper);
- option = options.get("makefile");
- generateSynthetics(mapper, option.getValue());
- }
- }
-
- private void processBcp47Data() {
- Bcp47Mapper mapper = new Bcp47Mapper(sourceDir);
- IcuData[] icuData = mapper.fillFromCldr();
- for (IcuData data : icuData) {
- writeIcuData(data, destinationDir);
- }
- }
-
- private void processSupplemental(Type type, String debugXPath) {
- IcuData icuData;
- // Use the supplementaldir if explicitly specified , otherwise the source dir.
- String dir = options.get("supplementaldir").doesOccur() ? supplementalDir : sourceDir;
- switch (type) {
- case plurals: {
- PluralsMapper mapper = new PluralsMapper(dir);
- icuData = mapper.fillFromCldr();
- break;
- }
- case pluralRanges: {
- PluralRangesMapper mapper = new PluralRangesMapper(dir);
- icuData = mapper.fillFromCldr();
- break;
- }
- case dayPeriods: {
- DayPeriodsMapper mapper = new DayPeriodsMapper(dir);
- icuData = mapper.fillFromCldr();
- break;
- }
- default: {
- SupplementalMapper mapper = SupplementalMapper.create(dir);
- if (debugXPath != null) {
- mapper.setDebugXPath(debugXPath);
- }
- icuData = mapper.fillFromCldr(type.toString());
- }
- }
- writeIcuData(icuData, destinationDir);
- }
-
- /**
- * Writes the given IcuData object to file.
- *
- * @param icuData
- * the IcuData object to be written
- * @param outputDir
- * the destination directory of the output file
- */
- private void writeIcuData(IcuData icuData, String outputDir) {
- if (icuData.keySet().size() == 0) {
- throw new RuntimeException(icuData.getName() + " was not written because no data was generated.");
- }
- try {
- // Split data into different directories if necessary.
- // splitInfos is filled from the <remap> element in ICU's build.xml.
- if (splitter == null) {
- IcuTextWriter.writeToFile(icuData, outputDir);
- } else {
- String fallbackDir = new File(outputDir).getName();
- Map<String, IcuData> splitData = splitter.split(icuData, fallbackDir);
- for (String dir : splitData.keySet()) {
- IcuTextWriter.writeToFile(splitData.get(dir), outputDir + "/../" + dir);
- }
- }
- } catch (IOException e) {
- System.err.println("Error while converting " + icuData.getSourceFile());
- e.printStackTrace();
- }
- }
-
- /**
- * Converts CLDR XML files using the specified mapper.
- */
- private void convert(Mapper mapper) {
- IcuData icuData;
- Iterator<IcuData> iterator = mapper.iterator(filter);
- final Type type = Type.valueOf(options.get("type").getValue());
- while (iterator.hasNext()) {
- long time = System.currentTimeMillis();
- icuData = iterator.next();
- writeIcuData(icuData, destinationDir);
- System.out.println("Converted " + type + ": " + icuData.getName() + ".xml in " +
- (System.currentTimeMillis() - time) + "ms");
- }
- }
-
- /**
- * Generates makefiles for files generated from the specified mapper.
- * @param mapper
- * @param makefileName If non-null, print Makefile data to this file.
- */
- private void generateSynthetics(Mapper mapper, String makefileName) {
- // Generate aliases and makefiles for main directory.
- Set<String> aliases = writeSyntheticFiles(mapper.getGenerated(), destinationDir);
- if (makefileName != null) {
- Makefile makefile = mapper.generateMakefile(aliases);
- writeMakefile(makefile, destinationDir, makefileName);
- }
- if (splitter == null) return;
-
- // Generate aliases and locales for remaining directories if a splitter was used.
- for (String dir : splitter.getTargetDirs()) {
- File outputDir = new File(destinationDir, "../" + dir);
- aliases = writeSyntheticFiles(splitter.getDirSources(dir), outputDir.getAbsolutePath());
- if (makefileName != null) {
- Makefile makefile = splitter.generateMakefile(aliases, outputDir.getName());
- writeMakefile(makefile, outputDir.getAbsolutePath(), makefileName);
- }
- }
- }
-
- /**
- * Generates dependency graph files (usually named _dependencies.py).
- */
- private void generateDependencyGraphFile(DependencyGraphData dependencyGraphData, String filename) {
- try {
- dependencyGraphData.print(destinationDir, filename);
- } catch (IOException e) {
- System.err.println("Unable to write " + filename + ": " + e);
- System.exit(-1);
- }
- }
-
- /**
- * Creates all synthetic files needed by the makefile in the specified output directory.
- * @param sources the set of source files that have already been generated
- * @param outputDir
- * @return
- */
- private Set<String> writeSyntheticFiles(Set<String> sources, String outputDir) {
- Set<String> targets = new HashSet<String>();
- if (aliasDeprecates != null) {
- if (aliasDeprecates.emptyLocaleList != null) {
- for (String locale : aliasDeprecates.emptyLocaleList) {
- IcuData icuData = createEmptyFile(locale);
- System.out.println("Empty locale created: " + locale);
- targets.add(locale);
- writeIcuData(icuData, outputDir);
- }
- }
- if (aliasDeprecates.aliasList != null) {
- for (Alias alias : aliasDeprecates.aliasList) {
- try {
- writeAlias(alias, outputDir, sources, targets);
- } catch (IOException e) {
- System.err.println("Error writing alias " + alias.from + "-" + alias.to);
- System.exit(-1);
- }
- }
- }
- }
- return targets;
- }
-
- /**
- * Writes a makefile to the specified directory and filename.
- */
- private void writeMakefile(Makefile makefile, String outputDir, String makefileName) {
- try {
- new File(outputDir + File.separator + makefileName).createNewFile();
- makefile.print(outputDir, makefileName);
- } catch (IOException e) {
- System.err.println("Error while writing makefile for " + outputDir + "/" + makefileName);
- }
- }
-
- /**
- * Creates an empty IcuData object to act as a placeholder for the specified alias target locale.
- */
- public IcuData createEmptyFile(String locale) {
- IcuData icuData = new IcuData("icu-locale-deprecates.xml & build.xml", locale, true);
- icuData.setFileComment("generated alias target");
- icuData.add("/___", "");
- return icuData;
- }
-
- /**
- * Creates any synthetic files required for the specified alias.
- * @param alias
- * @param outputDir
- * @param sources the set of sources in the output directory
- * @param aliasTargets the alias targets already created in the output directory
- * @throws IOException
- */
- private void writeAlias(Alias alias, String outputDir,
- Set<String> sources, Set<String> aliasTargets) throws IOException {
- String from = alias.from;
- String to = alias.to;
- // Add synthetic destination file for alias if necessary.
- if (!sources.contains(to) && !aliasTargets.contains(to) && new File(outputDir + File.separator + alias.to + ".txt").createNewFile()) {
- System.out.println(to + " not found, creating empty file in " + outputDir);
- IcuTextWriter.writeToFile(createEmptyFile(alias.to), outputDir);
- aliasTargets.add(to);
- }
-
- if (from == null || to == null) {
- throw new IllegalArgumentException("Malformed alias - no 'from' or 'to': from=\"" +
- from + "\" to=\"" + to + "\"");
- }
-
- if (sources.contains(from)) {
- throw new IllegalArgumentException(
- "Can't be both a synthetic alias locale and a real xml file - "
- + "consider using <aliasLocale locale=\"" + from + "\"/> instead. ");
- }
-
- String rbPath = alias.rbPath;
- String value = alias.value;
- if ((rbPath == null) != (value == null)) {
- throw new IllegalArgumentException("Incomplete alias specification for " +
- from + "-" + to + ": both rbPath (" +
- rbPath + ") and value (" + value + ") must be specified");
- }
-
- IcuData icuData = new IcuData("icu-locale-deprecates.xml & build.xml", from, true);
- if (rbPath == null) {
- icuData.add(ALIAS_PATH, to);
- } else {
- icuData.add(rbPath, value);
- }
-
- if (new File(outputDir + File.separator + from + ".txt").createNewFile()) {
- IcuTextWriter.writeToFile(icuData, outputDir);
- aliasTargets.add(alias.from);
- System.out.println("Created alias from " + from + " to " + to + " in " + outputDir + ".");
- }
- }
-
- public static void main(String[] args) throws IOException {
- long totalTime = System.currentTimeMillis();
- NewLdml2IcuConverter converter = new NewLdml2IcuConverter();
- converter.processArgs(args);
- System.out.println("Total time taken: " + (System.currentTimeMillis() - totalTime) + "ms");
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/PluralRangesMapper.java b/tools/java/org/unicode/cldr/icu/PluralRangesMapper.java
deleted file mode 100644
index 5f1fa75..0000000
--- a/tools/java/org/unicode/cldr/icu/PluralRangesMapper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import org.unicode.cldr.util.PluralRanges;
-import org.unicode.cldr.util.SupplementalDataInfo;
-import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
-
-/**
- * Class for converting CLDR plurals files to a format suitable for outputting
- * ICU data with. It might be possible for PluralsMapper and LdmlLocaleMapper to
- * share a parent class, but there isn't currently a need for that so they're
- * kept separate for the time being.
- *
- * @author markdavis
- * Based on PluralsMapper
- */
-public class PluralRangesMapper {
- private static final boolean DO_NUMBER = false;
- private static final boolean DO_INT_VECTOR = DO_NUMBER && true;
-
- private String supplementalDir;
-
- /**
- * Constructor. A SupplementalDataInfo object is used rather than the
- * supplemental directory because the supplemental data parsing is already
- * done for us. The RegexLookup method used by LdmlLocaleMapper wouldn't
- * work well, since there would only be one regex.
- *
- * @param supplementalDataInfo
- */
- public PluralRangesMapper(String supplementalDir) {
- this.supplementalDir = supplementalDir;
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format
- */
- public IcuData fillFromCldr() {
- IcuData icuData = new IcuData("pluralRanges.xml", "pluralRanges", false);
- SupplementalDataInfo sdi = SupplementalDataInfo.getInstance(supplementalDir);
- Map<PluralRanges, Integer> rulesToSet = new TreeMap<>();
- for (String locale : sdi.getPluralRangesLocales()) {
- PluralRanges ranges = sdi.getPluralRanges(locale);
- Integer number = rulesToSet.get(ranges);
- if (number == null) {
- rulesToSet.put(ranges, number = rulesToSet.size());
- }
- icuData.add("/locales/" + locale, format(number));
- }
- String intStyle = DO_INT_VECTOR ? ":intvector" : "";
-
- for (Entry<PluralRanges, Integer> rulesAndSet : rulesToSet.entrySet()) {
- PluralRanges ranges = rulesAndSet.getKey();
- Integer setNumber = rulesAndSet.getValue();
- int numberWritten = 0;
- for (Count start : Count.VALUES) {
- for (Count end : Count.VALUES) {
- Count value = ranges.getExplicit(start, end);
- if (value != null) {
- ++numberWritten;
- icuData.add("/rules/" + format(setNumber) + intStyle,
- getString(start),
- getString(end),
- getString(value));
- }
- }
- }
- }
- return icuData;
- }
-
- private String format(int number) {
- return "set" + (number < 10 ? "0" + number : String.valueOf(number));
- }
-
- public String getString(Count start) {
- return DO_NUMBER ? String.valueOf(start.ordinal()) : start.toString();
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/PluralsMapper.java b/tools/java/org/unicode/cldr/icu/PluralsMapper.java
deleted file mode 100644
index 7c9840f..0000000
--- a/tools/java/org/unicode/cldr/icu/PluralsMapper.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.ibm.icu.impl.Row.R2;
-
-/**
- * Class for converting CLDR plurals files to a format suitable for outputting
- * ICU data with. It might be possible for PluralsMapper and LdmlLocaleMapper to
- * share a parent class, but there isn't currently a need for that so they're
- * kept separate for the time being.
- *
- * @author jchye
- */
-public class PluralsMapper {
- private int numRuleSets = 0;
- private String supplementalDir;
- private Map<String, Integer> ruleOrder;
-
- /**
- * Constructor. A SupplementalDataInfo object is used rather than the
- * supplemental directory because the supplemental data parsing is already
- * done for us. The RegexLookup method used by LdmlLocaleMapper wouldn't
- * work well, since there would only be one regex.
- *
- * @param supplementalDataInfo
- */
- public PluralsMapper(String supplementalDir) {
- this.supplementalDir = supplementalDir;
- ruleOrder = new HashMap<String, Integer>();
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format
- */
- public IcuData fillFromCldr() {
- IcuData icuData = new IcuData("plurals.xml, ordinals.xml", "plurals", false);
- fillType(PluralType.cardinal, icuData);
- fillType(PluralType.ordinal, icuData);
- return icuData;
- }
-
- private void fillType(PluralType type, IcuData icuData) {
- PluralsHandler handler = new PluralsHandler(type, icuData);
- String filename = type == PluralType.cardinal ? "plurals.xml" : "ordinals.xml";
- File inputFile = new File(supplementalDir, filename); // handle ordinals too.
- MapperUtils.parseFile(inputFile, handler);
- }
-
- private class PluralsHandler extends MapperUtils.EmptyHandler {
- private StringBuffer currentText;
- private String currentCount;
- private String[] currentLocales;
- // List of plural counts and corresponding rules.
- private List<R2<String, String>> currentRules;
- private IcuData icuData;
- String prefix;
-
- public PluralsHandler(PluralType type, IcuData icuData) {
- this.icuData = icuData;
- prefix = type == PluralType.cardinal ? "/locales/" : "/locales_ordinals/";
- currentText = new StringBuffer();
- currentRules = new ArrayList<R2<String, String>>();
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- currentText.append(ch, start, length);
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- if (qName.equals("pluralRules")) {
- currentLocales = attr.getValue("locales").split("\\s+");
- } else if (qName.equals("pluralRule")) {
- currentCount = attr.getValue("count");
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (qName.equals("pluralRules")) {
- // add locale path to ICU data
- StringBuffer ruleBuffer = new StringBuffer();
- for (R2<String, String> rule : currentRules) {
- ruleBuffer.append(rule.toString() + '\n');
- }
- Integer setNum = ruleOrder.get(ruleBuffer.toString());
- // Only add the rules to the ICU file if they aren't a duplicate
- // of an earlier rule set.
- if (setNum == null) {
- setNum = numRuleSets;
- ruleOrder.put(ruleBuffer.toString(), setNum);
- for (R2<String, String> rule : currentRules) {
- icuData.add("/rules/set" + numRuleSets + '/' + rule.get0(), rule.get1());
- }
- numRuleSets++;
- }
- String setName = currentRules.size() == 0 ? "" : "set" + setNum;
- for (String locale : currentLocales) {
- icuData.add(prefix + locale, setName);
- }
- currentRules.clear();
- } else if (qName.equals("pluralRule")) {
- currentRules.add(new R2<String, String>(currentCount,
- currentText.toString()));
- currentText.setLength(0);
- }
- }
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/RbnfMapper.java b/tools/java/org/unicode/cldr/icu/RbnfMapper.java
deleted file mode 100644
index 617275b..0000000
--- a/tools/java/org/unicode/cldr/icu/RbnfMapper.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.Collection;
-
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.SupplementalDataInfo;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.ibm.icu.impl.Utility;
-
-public class RbnfMapper extends Mapper {
- private File sourceDir;
- private File specialsDir;
- private SupplementalDataInfo sdi;
-
- public RbnfMapper(File sourceDir, File specialsDir) {
- this.sourceDir = sourceDir;
- this.specialsDir = specialsDir;
- }
-
- /**
- * @return CLDR data converted to an ICU-friendly format
- */
- @Override
- public IcuData[] fillFromCldr(String locale) {
- IcuData icuData = new IcuData("common/rbnf/" + locale + ".xml", locale, true);
- RbnfHandler handler = new RbnfHandler(icuData);
- // Parse the specials first.
- File specialsFile = getSpecialsFile(locale);
- if (specialsFile != null) {
- icuData.setFileComment("ICU <specials> source: <path>/xml/rbnf/" + locale + ".xml");
- MapperUtils.parseFile(specialsFile, handler);
- }
-
- File file = new File(sourceDir, locale + ".xml");
- MapperUtils.parseFile(file, handler);
-
- if (sdi == null) {
- sdi = SupplementalDataInfo.getInstance();
- }
- String parent = sdi.getExplicitParentLocale(locale);
- if (parent != null) { // Empty except for version
- icuData.add("/%%Parent", parent);
- }
- return new IcuData[] { icuData };
- }
-
- /**
- * @param filename
- * @return true if a special XML file with the specified filename is available.
- */
- private File getSpecialsFile(String filename) {
- if (specialsDir == null) return null;
- File file = new File(specialsDir, filename + ".xml");
- return file.exists() ? file : null;
- }
-
- /**
- * The XML handler for collation data.
- */
- private class RbnfHandler extends MapperUtils.EmptyHandler {
- private IcuData icuData;
- private String rbPath;
- private StringBuilder currentText = new StringBuilder();
- private StringBuilder value = new StringBuilder();
- private boolean isLenient;
-
- public RbnfHandler(IcuData icuData) {
- this.icuData = icuData;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
- if (qName.equals("rulesetGrouping")) {
- rbPath = "/RBNFRules/" + attr.getValue("type");
- } else if (qName.equals("ruleset")) {
- String access = attr.getValue("access");
- String value = access != null && access.equals("private") ? "%%" : "%";
- String type = attr.getValue("type");
- value += type + ":";
- icuData.add(rbPath, value);
- isLenient = type.equals("lenient-parse");
- } else if (qName.equals("rbnfrule")) {
- if (isLenient) return;
- value.append(attr.getValue("value"));
- String radix = attr.getValue("radix");
- if (radix != null) {
- value.append('/').append(radix);
- }
- value.append(": ");
- } else if (qName.equals("version")) {
- icuData.replace("/Version", CLDRFile.GEN_VERSION);
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (qName.equals("rbnfrule")) {
- // TODO(jchye): Utility.escape unicode-escapes all non-ASCII chars.
- // Find out what non-ASCII chars really need to be escaped.
- value.append(Utility.escape(currentText.toString()
- .replace('→', '>')
- .replace('←', '<')));
- icuData.add(rbPath, value.toString());
- currentText.setLength(0);
- value.setLength(0);
- }
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- currentText.append(ch, start, length);
- }
- }
-
- @Override
- public Collection<String> getAvailable() {
- return MapperUtils.getNames(sourceDir);
- }
-
- @Override
- public Makefile generateMakefile(Collection<String> aliases) {
- Makefile makefile = new Makefile("RBNF");
- makefile.addSyntheticAlias(aliases);
- makefile.addAliasSource();
- makefile.addSource(sources);
- return makefile;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/RegexManager.java b/tools/java/org/unicode/cldr/icu/RegexManager.java
deleted file mode 100644
index 2ad7c4a..0000000
--- a/tools/java/org/unicode/cldr/icu/RegexManager.java
+++ /dev/null
@@ -1,742 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.BufferedReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CldrUtility.VariableReplacer;
-import org.unicode.cldr.util.FileReaders;
-import org.unicode.cldr.util.PatternCache;
-import org.unicode.cldr.util.RegexLookup;
-import org.unicode.cldr.util.RegexLookup.Finder;
-import org.unicode.cldr.util.RegexLookup.Merger;
-import org.unicode.cldr.util.RegexLookup.RegexFinder;
-
-import com.ibm.icu.impl.Row.R2;
-import com.ibm.icu.impl.Row.R3;
-import com.ibm.icu.text.Transform;
-import com.ibm.icu.text.UnicodeSet;
-import com.ibm.icu.util.Output;
-
-/**
- * A class for loading and managing the xpath converters used to map CLDR data
- * to ICU.
- * @author jchye
- */
-class RegexManager {
- private static final Pattern SEMI = PatternCache.get("\\s*+;\\s*+");
- private static final Pattern FUNCTION_PATTERN = PatternCache.get("\\&(\\w++)\\(([^\\)]++)\\)");
- private static final Pattern QUOTES = PatternCache.get("\"([^\"]++)\"");
- private static final UnicodeSet SPACE_CHARACTERS = new UnicodeSet(
- "[\\u0000\\uFEFF[:pattern_whitespace:]]");
- // Matches arguments with or without enclosing quotes.
- private static final Pattern ARGUMENT = PatternCache.get("[<\"]?\\$(\\d)[\">]?");
-
- private static Map<String, Function> functionMap = new HashMap<String, Function>();
-
- private String converterFile;
- private Map<String, RegexResult> unprocessedMatchers;
- private Map<String, String> xpathVariables;
- private VariableReplacer cldrVariables;
-
- /**
- * Wrapper class for functions that need to be performed on CLDR values as
- * part of the ICU conversion,
- */
- static abstract class Function {
- int maxArgs;
-
- /**
- * @param maxArgs
- * the maximum number of args that can be passed to this function,
- * or a negative number if there is no limit.
- */
- Function(int maxArgs) {
- this.maxArgs = maxArgs;
- }
-
- /**
- * Processes a comma-delimited list of arguments.
- *
- * @param arg
- * @return
- */
- public String process(String arg) {
- String[] args = arg.split(",");
- if (maxArgs > -1 && args.length > maxArgs) {
- throw new IllegalArgumentException("Function has too many args: expected "
- + maxArgs + " but got (" + arg + ")");
- }
- return run(args);
- }
-
- /**
- * Runs the function on a list of arguments.
- *
- * @return the resultant string
- */
- abstract String run(String... args);
- }
-
- /**
- * A wrapper class for storing and working with the unprocessed path-value pairs of a RegexResult.
- */
- static class PathValueInfo {
- private String rbPath;
- private String valueArg;
- private String groupKey;
- private String baseXPath;
- private int splitRbPathArg;
-
- /**
- * @param rbPath
- * the rbPath expression to be used for this set of path-value pairs.
- * @param instructions
- * any special instructions to be carried out on this set of path-value pairs
- * @param splitRbPathArg
- * if applicable, the number of the argument in the rbPath
- * expression that needs to be split to create multiple rbPaths, each with the same value
- */
- public PathValueInfo(String rbPath, Map<String, String> instructions, int splitRbPathArg) {
- this.rbPath = rbPath;
- this.valueArg = instructions.get("values");
- this.groupKey = instructions.get("group");
- this.baseXPath = instructions.get("base_xpath");
- this.splitRbPathArg = splitRbPathArg;
- }
-
- /**
- * @param arguments
- * the arguments retrieved from the regex corresponding to this PathValueInfo
- * @return the processed rb path
- */
- public String processRbPath(String[] arguments) {
- String path = processString(rbPath, arguments);
- // Replace slashes in metazone names,
- // e.g. "America/Argentina/La_Rioja"
- Matcher matcher = QUOTES.matcher(path);
- if (matcher.find()) {
- path = path.substring(0, matcher.start(1))
- + matcher.group(1).replace('/', ':')
- + path.substring(matcher.end(1));
- }
- return path;
- }
-
- public String processGroupKey(String[] arguments) {
- return processString(groupKey, arguments);
- }
-
- public List<String> processValues(String[] arguments, String cldrValue) {
- if (valueArg == null) {
- List<String> values = new ArrayList<String>();
- values.add(cldrValue);
- return values;
- }
- // Split single args using spaces.
- String processedValue = processValue(valueArg, cldrValue, arguments);
- return splitValues(processedValue);
- }
-
- public String processXPath(String[] arguments, String xpath) {
- if (baseXPath != null) {
- return processString(baseXPath, arguments);
- } else {
- return xpath;
- }
- }
-
- private List<String> splitValues(String unsplitValues) {
- // Split up values using spaces unless enclosed by non-escaped quotes,
- // e.g. a "b \" c" would become {"a", "b \" c"}
- List<String> args = new ArrayList<String>();
- StringBuffer valueBuffer = new StringBuffer();
- boolean shouldSplit = true;
- char lastChar = ' ';
- for (char c : unsplitValues.toCharArray()) {
- // Normalize whitespace input.
- if (SPACE_CHARACTERS.contains(c)) {
- c = ' ';
- }
- if (c == '"' && lastChar != '\\') {
- shouldSplit = !shouldSplit;
- } else if (c == ' ') {
- if (lastChar == ' ') {
- // Do nothing.
- } else if (shouldSplit) {
- args.add(valueBuffer.toString());
- valueBuffer.setLength(0);
- } else {
- valueBuffer.append(c);
- }
- } else {
- valueBuffer.append(c);
- }
- lastChar = c;
- }
- if (valueBuffer.length() > 0) {
- args.add(valueBuffer.toString());
- }
- return args;
- }
-
- private String processValue(String value, String cldrValue, String[] arguments) {
- value = processString(value, arguments);
- Matcher matcher = FUNCTION_PATTERN.matcher(value);
- if (matcher.find()) {
- int index = 0;
- StringBuffer buffer = new StringBuffer();
- do {
- buffer.append(value.substring(index, matcher.start()));
- String fnName = matcher.group(1);
- String fnArgs = matcher.group(2);
- String result = functionMap.get(fnName).process(fnArgs);
- buffer.append(result);
- index = matcher.end();
- } while (matcher.find());
- buffer.append(value.substring(index));
- // System.out.println(value + " to " + buffer.toString());
- value = buffer.toString();
- }
- if (value.contains("{value}")) {
- value = value.replace("{value}", cldrValue);
- }
- return value;
- }
-
- @Override
- public String toString() {
- return rbPath + "=" + valueArg;
- }
-
- public int getSplitRbPathArg() {
- return splitRbPathArg;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof PathValueInfo) {
- PathValueInfo otherInfo = (PathValueInfo) o;
- return rbPath.equals(otherInfo.rbPath)
- && valueArg.equals(otherInfo.valueArg);
- } else {
- return false;
- }
- }
- }
-
- static String processString(String value, String[] arguments) {
- if (value == null) {
- return null;
- }
- try {
- return RegexLookup.replace(value, arguments);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new RuntimeException("Error while filling out arguments in " + value + " with "
- + Arrays.asList(arguments), e);
- }
- }
-
- static class RegexResult implements Iterable<PathValueInfo> {
-
- private Set<PathValueInfo> unprocessed;
-
- public RegexResult() {
- unprocessed = new HashSet<PathValueInfo>();
- }
-
- public void add(String rbPath, Map<String, String> instructions,
- int splitRbPathArg) {
- unprocessed.add(new PathValueInfo(rbPath, instructions, splitRbPathArg));
- }
-
- @Override
- public Iterator<PathValueInfo> iterator() {
- return unprocessed.iterator();
- }
- }
-
- static class CldrArray {
- // Map of xpaths to values and group key.
- private Map<String, R2<List<String>, String>> map;
-
- public CldrArray() {
- map = new HashMap<String, R2<List<String>, String>>();
- }
-
- public void put(String key, List<String> values, String groupKey) {
- map.put(key, new R2<List<String>, String>(values, groupKey));
- }
-
- public void add(String key, String[] values, String groupKey) {
- List<String> list = new ArrayList<String>();
- for (String value : values) {
- list.add(value);
- }
- put(key, list, groupKey);
- }
-
- public void add(String key, String value, String groupKey) {
- List<String> list = new ArrayList<String>();
- list.add(value);
- put(key, list, groupKey);
- }
-
- public void addAll(CldrArray otherArray) {
- // HACK: narrow alias to abbreviated. Remove after CLDR data fixed.
- for (String otherKey : otherArray.map.keySet()) {
- String narrowPath = otherKey.replace("eraAbbr", "eraNarrow");
- if (!map.containsKey(narrowPath)) {
- map.put(narrowPath, otherArray.map.get(otherKey));
- }
-
- }
- }
-
- public boolean findKey(Finder finder) {
- for (String key : map.keySet()) {
- if (finder.find(key, null, null)) {
- return true;
- }
- }
- return false;
- }
-
- public List<String[]> sortValues(Comparator<String> comparator) {
- List<String> sortedKeys = new ArrayList<String>(map.keySet());
- Collections.sort(sortedKeys, comparator);
- List<String[]> sortedValues = new ArrayList<String[]>();
- // Group isArray for the same xpath together.
- List<String> arrayValues = new ArrayList<String>();
- for (int i = 0, len = sortedKeys.size(); i < len; i++) {
- String key = sortedKeys.get(i);
- R2<List<String>, String> currentEntry = map.get(key);
- List<String> values = currentEntry.get0();
- String groupKey = currentEntry.get1();
- if (groupKey == null) {
- for (String value : values) {
- sortedValues.add(new String[] { value });
- }
- } else {
- arrayValues.addAll(values);
- String nextKey = null;
- if (i < len - 1) {
- nextKey = map.get(sortedKeys.get(i + 1)).get1();
- }
- if (!groupKey.equals(nextKey)) {
- sortedValues.add(toArray(arrayValues));
- arrayValues.clear();
- }
- }
- }
- return sortedValues;
- }
- }
-
- /**
- * Converts a list into an Array.
- */
- static String[] toArray(List<String> list) {
- String[] array = new String[list.size()];
- list.toArray(array);
- return array;
- }
-
- private static Transform<String, Finder> regexTransform = new Transform<String, Finder>() {
- @Override
- public Finder transform(String source) {
- return new RegexFinder(source);
- }
- };
-
- Map<String, Function> addFunction(String fnName, Function function) {
- functionMap.put(fnName, function);
- return functionMap;
- }
-
- /**
- * Checks if two strings match a specified pattern.
- *
- * @param pattern
- * the pattern to be matched against
- * @param arg0
- * @param arg1
- * @param matchers
- * a 2-element array to contain the two matchers. The
- * array is not guaranteed to be filled if matches() returns false
- * @return true if both strings successfully matched the pattern
- */
- static boolean matches(Pattern pattern, String arg0, String arg1, Matcher[] matchers) {
- return (matchers[0] = pattern.matcher(arg0)).matches()
- && (matchers[1] = pattern.matcher(arg1)).matches();
- }
-
- /**
- * Outputs the list of debugging results returned from a RegexLookup.
- * Only the matches most similar to the specified xpath will be returned.
- * @param xpath
- * @param results
- */
- static void printLookupResults(String xpath, List<String> results) {
- if (results == null) return;
- System.out.println("Debugging " + xpath + ":");
- int[] haltPos = new int[results.size()];
- int furthestPos = 0;
- for (int i = 0; i < haltPos.length; i++) {
- int pos = results.get(i).indexOf('\u2639'); // ☹
- haltPos[i] = pos;
- if (pos > furthestPos) furthestPos = pos;
- }
- for (int i = 0; i < haltPos.length; i++) {
- if (haltPos[i] < furthestPos) continue;
- System.out.println(results.get(i));
- }
- }
-
- RegexLookup<FallbackInfo> fallbackConverter;
- RegexLookup<RegexResult> xpathConverter;
-
- // One FallbackInfo object for every type of rbPath.
- class FallbackInfo implements Iterable<R3<Finder, String, List<String>>> {
- // Fallback info in the order: xpath matcher, fallback xpath, fallback values.
- private List<R3<Finder, String, List<String>>> fallbackItems;
- private List<Integer> argsUsed; // list of args used by the rb pattern
- private int numXpathArgs; // Number of args in the xpath
-
- public FallbackInfo(List<Integer> argsUsed, int numXpathArgs) {
- fallbackItems = new ArrayList<R3<Finder, String, List<String>>>();
- this.argsUsed = argsUsed;
- this.numXpathArgs = numXpathArgs;
- }
-
- public void addItem(Finder xpathMatcher, String fallbackXpath, String[] fallbackValues) {
- List<String> values = new ArrayList<String>();
- for (String fallbackValue : fallbackValues) {
- values.add(fallbackValue);
- }
- fallbackItems.add(new R3<Finder, String, List<String>>(xpathMatcher, fallbackXpath, values));
- }
-
- /**
- * Takes in arguments obtained from a RegexLookup on a RB path and fleshes
- * it out for the corresponding xpath.
- *
- * @param arguments
- * @return
- */
- public String[] getArgumentsForXpath(String[] arguments) {
- String[] output = new String[numXpathArgs + 1];
- output[0] = arguments[0];
- for (int i = 0; i < argsUsed.size(); i++) {
- output[argsUsed.get(i)] = arguments[i + 1];
- }
- for (int i = 0; i < output.length; i++) {
- if (output[i] == null) output[i] = "x"; // dummy value
- }
- return output;
- }
-
- private R3<Finder, String, List<String>> getItem(Finder finder) {
- for (R3<Finder, String, List<String>> item : fallbackItems) {
- if (item.get0().equals(finder)) return item;
- }
- return null;
- }
-
- public FallbackInfo merge(FallbackInfo newInfo) {
- for (R3<Finder, String, List<String>> newItem : newInfo.fallbackItems) {
- R3<Finder, String, List<String>> item = getItem(newItem.get0());
- if (item == null) {
- fallbackItems.add(newItem);
- } else {
- item.get2().addAll(newItem.get2());
- }
- }
- return this;
- }
-
- @Override
- public Iterator<R3<Finder, String, List<String>>> iterator() {
- return fallbackItems.iterator();
- }
- }
-
- /**
- * All child classes should call this constructor.
- *
- * @param converterFile
- */
- RegexManager(String converterFile) {
- this.converterFile = converterFile;
- unprocessedMatchers = new HashMap<String, RegexResult>();
- }
-
- /**
- * @return a RegexLookup for matching rb paths that may require fallback
- * values.
- */
- RegexLookup<FallbackInfo> getFallbackConverter() {
- if (fallbackConverter == null) {
- loadConverters();
- }
- return fallbackConverter;
- }
-
- /**
- * @return a RegexLookup for matching xpaths
- */
- RegexLookup<RegexResult> getPathConverter() {
- if (xpathConverter == null) {
- loadConverters();
- }
- return xpathConverter;
- }
-
- RegexLookup<RegexResult> getPathConverter(CLDRFile cldrFile) {
- RegexLookup<RegexResult> basePathConverter = getPathConverter();
-
- RegexLookup<RegexResult> processedPathConverter = new RegexLookup<RegexResult>()
- .setPatternTransform(regexTransform);
- cldrVariables = new VariableReplacer();
- for (Entry<String, String> entry : xpathVariables.entrySet()) {
- cldrVariables.add(entry.getKey(), cldrFile.getStringValue(entry.getValue()));
- }
- for (Map.Entry<Finder, RegexResult> entry : basePathConverter) {
- processedPathConverter.add(entry.getKey(), entry.getValue());
- }
- for (Entry<String, RegexResult> entry : unprocessedMatchers.entrySet()) {
- processedPathConverter.add(cldrVariables.replace(entry.getKey()),
- entry.getValue());
- }
- return processedPathConverter;
- }
-
- private void loadConverters() {
- xpathConverter = new RegexLookup<RegexResult>()
- .setPatternTransform(regexTransform);
- fallbackConverter = new RegexLookup<FallbackInfo>()
- .setValueMerger(new Merger<FallbackInfo>() {
- @Override
- public FallbackInfo merge(FallbackInfo a, FallbackInfo into) {
- return into.merge(a);
- }
- });
- xpathVariables = new HashMap<String, String>();
- BufferedReader reader = FileReaders.openFile(NewLdml2IcuConverter.class, converterFile);
- VariableReplacer variables = new VariableReplacer();
- Finder xpathMatcher = null;
- RegexResult regexResult = null;
- String line = null;
- int lineNum = 0;
- try {
- while ((line = reader.readLine()) != null) {
- lineNum++;
- line = line.trim();
- // Skip comments.
- if (line.length() == 0 || line.startsWith("#")) continue;
- // Read variables.
- if (line.charAt(0) == '%') {
- int pos = line.indexOf("=");
- if (pos < 0) {
- throw new IllegalArgumentException();
- }
- String varName = line.substring(0, pos).trim();
- String varValue = line.substring(pos + 1).trim();
- // Variables representing xpaths should be replaced later on.
- if (varValue.startsWith("//")) {
- xpathVariables.put(varName, varValue);
- } else {
- variables.add(varName, varValue);
- }
- continue;
- }
- if (line.contains("%")) {
- line = variables.replace(line);
- }
- // if line still contains "%", still unprocessed
- // Process a line in the input file for xpath conversion.
- String[] content = line.split(SEMI.toString());
- // xpath ; rbPath ; value
- // Create a reverse lookup for rbPaths to xpaths.
- if (!line.startsWith(";")) {
- if (regexResult != null) {
- if (xpathMatcher.toString().contains("%")) {
- unprocessedMatchers.put(xpathMatcher.toString(), regexResult);
- } else {
- xpathConverter.add(xpathMatcher, regexResult);
- }
- }
- xpathMatcher = new RegexFinder(content[0].replace("[@", "\\[@"));
- regexResult = new RegexResult();
- }
- if (content.length > 1) {
- addConverterEntry(xpathMatcher, content, regexResult);
- }
- }
- xpathConverter.add(xpathMatcher, regexResult);
- } catch (Exception e) {
- System.err.println("Error reading " + converterFile + " at line " + lineNum + ": " + line);
- e.printStackTrace();
- }
- }
-
- private void addConverterEntry(Finder xpathMatcher, String[] content,
- RegexResult regexResult) {
- String rbPath = content[1];
- // Find arguments in rbPath.
- Matcher matcher = ARGUMENT.matcher(rbPath);
- int splitRbPathArg = -1;
- while (matcher.find()) {
- char startChar = rbPath.charAt(matcher.start());
- char endChar = rbPath.charAt(matcher.end() - 1);
- boolean shouldSplit = !(startChar == '"' && endChar == '"' ||
- startChar == '<' && endChar == '>');
- if (shouldSplit) {
- splitRbPathArg = Integer.parseInt(matcher.group(1));
- break;
- }
- }
-
- // Parse remaining special instructions.
- Map<String, String> instructions = new HashMap<String, String>();
- for (int i = 2; i < content.length; i++) {
- String[] instruction = content[i].split("=", 2);
- if (instruction[0].equals("fallback")) {
- // WARNING: fallback might backfire if more than one type of xpath for the same rbpath
- addFallback(xpathMatcher, rbPath, instruction[1]);
- } else {
- instructions.put(instruction[0], instruction[1]);
- }
- }
- regexResult.add(rbPath, instructions, splitRbPathArg);
- }
-
- /**
- * Adds an entry to the fallback converter.
- *
- * @param xpathMatcher
- * the xpath matcher that determines if a fallback value
- * is necessary
- * @param rbPath
- * the rb path that the fallback value is for
- * @param fallbackValue
- * the fallback value
- */
- private void addFallback(Finder xpathMatcher, String rbPath, String fallbackValue) {
- ArrayList<StringBuffer> args = new ArrayList<StringBuffer>();
- int numBraces = 0;
- int argNum = 0;
- // Create RB path matcher and xpath replacement.
- // WARNING: doesn't currently take lookaround groups into account.
- StringBuffer xpathReplacement = new StringBuffer();
- for (char c : xpathMatcher.toString().toCharArray()) {
- boolean isBrace = false;
- if (c == '(') {
- numBraces++;
- argNum++;
- args.add(new StringBuffer());
- isBrace = true;
- if (numBraces == 1) {
- xpathReplacement.append('$').append(argNum);
- }
- }
- if (numBraces > 0) {
- for (int i = args.size() - numBraces; i < args.size(); i++) {
- args.get(i).append(c);
- }
- }
- if (c == ')') {
- numBraces--;
- isBrace = true;
- }
- if (!isBrace && numBraces == 0) {
- xpathReplacement.append(c);
- }
- }
- String fallbackXpath = xpathReplacement.toString().replaceAll("\\\\\\[", "[");
- if (fallbackXpath.contains("(")) {
- System.err.println("Warning: malformed xpath " + fallbackXpath);
- }
-
- // Create rb matcher.
- Matcher matcher = ARGUMENT.matcher(rbPath);
- StringBuffer rbPattern = new StringBuffer();
- int lastIndex = 0;
- List<Integer> argsUsed = new ArrayList<Integer>();
- while (matcher.find()) {
- rbPattern.append(rbPath.substring(lastIndex, matcher.start()));
- argNum = Integer.parseInt(matcher.group(1));
- rbPattern.append(args.get(argNum - 1));
- argsUsed.add(argNum);
- lastIndex = matcher.end();
- }
- rbPattern.append(rbPath.substring(lastIndex));
- FallbackInfo info = new FallbackInfo(argsUsed, args.size());
- info.addItem(xpathMatcher, fallbackXpath, fallbackValue.split("\\s"));
- fallbackConverter.add(new RegexFinder(rbPattern.toString()), info);
- }
-
- void addFallbackValues(Map<String, CldrArray> pathValueMap) {
- addFallbackValues(null, pathValueMap);
- }
-
- /**
- * Checks if any fallback values are required and adds them to the specified
- * map.
- *
- * @param pathValueMap
- */
- void addFallbackValues(CLDRFile cldrFile, Map<String, CldrArray> pathValueMap) {
- RegexLookup<FallbackInfo> fallbackConverter = getFallbackConverter();
- for (String rbPath : pathValueMap.keySet()) {
- Output<String[]> arguments = new Output<String[]>();
- FallbackInfo fallbackInfo = fallbackConverter.get(rbPath, null, arguments);
- if (fallbackInfo == null) continue;
- CldrArray values = pathValueMap.get(rbPath);
- for (R3<Finder, String, List<String>> info : fallbackInfo) {
- if (!values.findKey(info.get0())) {
- // The fallback xpath is just for sorting purposes.
- String fallbackXpath = processString(info.get1(),
- fallbackInfo.getArgumentsForXpath(arguments.value));
- // Sanity check.
- if (fallbackXpath.contains("$")) {
- System.err.println("Warning: " + fallbackXpath + " for " + rbPath +
- " still contains unreplaced arguments.");
- }
- List<String> fallbackValues = info.get2();
- List<String> valueList = new ArrayList<String>();
- for (String value : fallbackValues) {
- value = processString(value, arguments.value);
- // Value is an xpath, so get real value from CLDRFile.
- if (value.startsWith("//") && cldrFile != null) {
- value = cldrFile.getStringValue(cldrVariables.replace(value));
- }
- valueList.add(value);
- }
- values.put(fallbackXpath, valueList, null);
- }
- }
- }
- }
-
- static CldrArray getCldrArray(String key, Map<String, CldrArray> pathValueMap) {
- CldrArray cldrArray = pathValueMap.get(key);
- if (cldrArray == null) {
- cldrArray = new CldrArray();
- pathValueMap.put(key, cldrArray);
- }
- return cldrArray;
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/ResourceSplitter.java b/tools/java/org/unicode/cldr/icu/ResourceSplitter.java
deleted file mode 100644
index e5379fe..0000000
--- a/tools/java/org/unicode/cldr/icu/ResourceSplitter.java
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2009 Google Inc. All Rights Reserved.
-
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.unicode.cldr.icu.ICUResourceWriter.Resource;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceInt;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceString;
-import org.unicode.cldr.icu.ICUResourceWriter.ResourceTable;
-
-public class ResourceSplitter {
- private final ICULog log;
- private final List<SplitInfo> splitInfos;
- private final Map<String, File> targetDirs;
-
- public static class SplitInfo {
- final String srcNodePath;
- final String targetNodePath;
- final String targetDirPath;
-
- public SplitInfo(String srcNodePath, String targetDirPath) {
- this(srcNodePath, targetDirPath, null);
- }
-
- public SplitInfo(String srcNodePath, String targetDirPath, String targetNodePath) {
- // normalize
- if (!srcNodePath.endsWith("/")) {
- srcNodePath += "/";
- }
-
- if (targetNodePath == null) {
- targetNodePath = srcNodePath;
- } else if (!targetNodePath.endsWith("/")) {
- targetNodePath += "/";
- }
-
- this.srcNodePath = srcNodePath;
- this.targetNodePath = targetNodePath;
- this.targetDirPath = targetDirPath;
- }
- }
-
- static class ResultInfo {
- final File directory;
- final ResourceTable root;
-
- public ResultInfo(File directory, ResourceTable root) {
- this.directory = directory;
- this.root = root;
- }
- }
-
- static class Path {
- private StringBuilder sb = new StringBuilder();
- private int[] indices = new int[10]; // default length should be enough
- private int depth;
-
- Path(String s) {
- sb.append(s);
- }
-
- String fullPath() {
- return sb.toString();
- }
-
- void push(String pathSegment) {
- if (depth == indices.length) {
- int[] temp = new int[depth * 2];
- System.arraycopy(indices, 0, temp, 0, depth);
- indices = temp;
- }
-
- indices[depth++] = sb.length();
- sb.append(pathSegment).append("/");
- }
-
- void pop() {
- if (depth == 0) {
- throw new IndexOutOfBoundsException("can't pop past start of path");
- }
- sb.setLength(indices[--depth]);
- }
- }
-
- ResourceSplitter(ICULog log, String baseDirPath, List<SplitInfo> splitInfos) {
- this.log = log;
- this.splitInfos = splitInfos;
- this.targetDirs = new HashMap<String, File>();
-
- File baseDir = new File(baseDirPath);
-
- for (SplitInfo si : splitInfos) {
- String dirPath = si.targetDirPath;
- if (!targetDirs.containsKey(dirPath)) {
- File dir = new File(dirPath);
- if (!dir.isAbsolute()) {
- dir = new File(baseDir, dirPath);
- }
- if (dir.exists()) {
- if (!dir.isDirectory()) {
- throw new IllegalArgumentException(
- "File \"" + dirPath + "\" exists and is not a directory");
- }
- if (!dir.canWrite()) {
- throw new IllegalArgumentException(
- "Cannot write to directory \"" + dirPath + "\"");
- }
- } else {
- if (!dir.mkdirs()) {
- throw new IllegalArgumentException(
- "Unable to create directory path \"" + dirPath + "\"");
- }
- }
- targetDirs.put(dirPath, dir);
- }
- }
- }
-
- public List<ResultInfo> split(File targetDir, ResourceTable root) {
- return new SplitProcessor(new ResultInfo(targetDir, root)).split();
- }
-
- // Does the actual work of splitting the resource, based on the ResourceSplitter's specs.
- private class SplitProcessor {
- private final ResultInfo source;
-
- private final Path path;
- private final Map<String, ResourceTable> resultMap;
- private final Map<String, ResourceTable> aliasMap;
- private final List<SplitInfo> remainingInfos;
-
- private SplitProcessor(ResultInfo source) {
- this.source = source;
-
- this.path = new Path("/");
- this.resultMap = new HashMap<String, ResourceTable>();
- this.aliasMap = new HashMap<String, ResourceTable>();
- this.remainingInfos = new ArrayList<SplitInfo>();
- this.remainingInfos.addAll(splitInfos);
- }
-
- private List<ResultInfo> split() {
- // start split below the root, so we don't match against the locale name
- if (!handleAlias()) {
- process(source.root, source.root.first);
- }
-
- // All trees need a root resource. Add one to any tree that didn't get one.
- // Not only that, but some locales that use root data rely on the presence of
- // a resource file matching the prefix of the locale to prevent fallback
- // lookup through the default locale. To prevent this error, all resources
- // need at least a language-only stub resource to be present.
- //
- // If the locale string does not contain an underscore, we assume that it's
- // either the 'root' locale or a language-only locale, so we always generate
- // the resource.
- //
- // Arrgh. The icu package tool wants all internal nodes in the tree to be
- // present. Currently, the missing nodes are all lang_Script locales.
- // Maybe change the package tool to fix this.
- int x = source.root.name.indexOf('_');
- if (x == -1 || source.root.name.length() - x == 5) {
- for (String targetDirPath : targetDirs.keySet()) {
- ResourceTable root = resultMap.get(targetDirPath);
- if (root == null) {
- log.log("Generate stub '" + source.root.name + ".txt' in '" + targetDirPath + "'");
- getResultRoot(targetDirPath);
- }
- }
- }
-
- List<ResultInfo> results = new ArrayList<ResultInfo>();
- results.add(source); // write out what's left of the original
-
- for (Map.Entry<String, ResourceTable> e : resultMap.entrySet()) {
- File dir = targetDirs.get(e.getKey());
- results.add(new ResultInfo(dir, e.getValue()));
- }
-
- for (Map.Entry<String, ResourceTable> e : aliasMap.entrySet()) {
- File dir = targetDirs.get(e.getKey());
- results.add(new ResultInfo(dir, e.getValue()));
- }
-
- return results;
- }
-
- // if there is an "%%ALIAS" resource at the top level, copy the file to
- // all target directories. We're done.
- // Well, maybe not. We need to ensure that all aliases have their targets in
- // their directories.
- //
- // It's probably ok to generate them. if they were created already, we'll
- // not bother. If we generate one, and there is real data later, we'll
- // just overwrite it.
- private boolean handleAlias() {
- for (Resource res = source.root.first; res != null; res = res.next) {
- if ("\"%%ALIAS\"".equals(res.name)) {
- // it's an alias, create for all targets
- for (String targetDirPath : targetDirs.keySet()) {
- log.log("Generate alias '" + source.root.name + "' in '" + targetDirPath + "'");
- getResultRoot(targetDirPath);
- generateTargetIfNeeded(((ResourceString) res).val, targetDirPath);
- }
- return true;
- }
- }
- return false;
- }
-
- private void generateTargetIfNeeded(String resName, String dirPath) {
- File targetDir = targetDirs.get(dirPath);
- String fileName = resName + ".txt";
- if (!new File(targetDir, fileName).exists()) {
- log.log("Generating alias target '" + resName + "' in '" + dirPath + "'");
-
- ResourceTable res = new ResourceTable();
- res.name = resName;
- ResourceString str = new ResourceString();
- str.name = "___";
- str.val = "";
- str.comment = "empty target resource";
- res.first = str;
-
- aliasMap.put(dirPath, res);
- }
- }
-
- private void process(Resource parent, Resource res) {
- while (true) {
- Resource next = res.next;
-
- path.push(res.name);
- String fullPath = path.fullPath();
- for (Iterator<SplitInfo> iter = remainingInfos.iterator(); iter.hasNext();) {
- SplitInfo si = iter.next();
- if (si.srcNodePath.startsWith(fullPath)) {
- if (si.srcNodePath.equals(fullPath)) {
- handleSplit(parent, res, si);
- iter.remove(); // don't need to look for this path anymore
- } else {
- if (res.first != null) {
- process(res, res.first);
- }
- }
- break;
- }
- }
- path.pop();
-
- if (next == null) {
- break;
- }
-
- res = next;
- }
- }
-
- private void handleSplit(Resource parent, Resource res, SplitInfo si) {
- ResourceTable root = getResultRoot(si.targetDirPath);
-
- removeChildFromParent(res, parent);
-
- placeResourceAtPath(root, si.targetNodePath, res);
- }
-
- private ResourceTable getResultRoot(String targetDirPath) {
- ResourceTable root = resultMap.get(targetDirPath);
- if (root == null) {
- root = createRoot();
- resultMap.put(targetDirPath, root);
- }
- return root;
- }
-
- /**
- * Creates a new ResourceTable root. It is a copy of the top of the source resource.
- * It includes the Version and %%ParentIsRoot resources from the source resource, if present.
- */
- private ResourceTable createRoot() {
- ResourceTable src = source.root;
- ResourceTable root = new ResourceTable();
- root.annotation = src.annotation;
- root.comment = src.comment;
- root.name = src.name;
-
- // if the src contains a version element, copy that element
- final String versionKey = "Version";
- final String parentRootKey = "%%ParentIsRoot";
- final String aliasKey = "\"%%ALIAS\"";
-
- for (Resource child = src.first; child != null; child = child.next) {
- if (versionKey.equals(child.name)) {
- String value = ((ResourceString) child).val;
- root.appendContents(ICUResourceWriter.createString(versionKey, value));
- } else if (parentRootKey.equals(child.name)) {
- ResourceInt parentIsRoot = new ResourceInt();
- parentIsRoot.name = parentRootKey;
- parentIsRoot.val = ((ResourceInt) child).val;
- root.appendContents(parentIsRoot);
- } else if (aliasKey.equals(child.name)) {
- String value = ((ResourceString) child).val;
- root.appendContents(ICUResourceWriter.createString(aliasKey, value));
- }
- }
-
- return root;
- }
-
- /**
- * Ensures that targetNodePath exists rooted at res, and returns the resource at that
- * path.
- */
- private void placeResourceAtPath(Resource root, String targetNodePath, Resource res) {
- String[] nodeNames = targetNodePath.split("/");
-
- // rename the resource with the last name in the path, and shorten the path
- int len = nodeNames.length;
- res.name = nodeNames[--len];
-
- // find or build nodes corresponding to remaining path
- // Skip initial empty node name (because of leading slash in target path)
- for (int i = 1; i < len; ++i) {
- root = findOrCreateNode(root, nodeNames[i]);
- }
-
- // put the renamed node at the end of the new parent
- root.appendContents(res);
- }
-
- private Resource findOrCreateNode(Resource parent, String nodeName) {
- // if no children, just create one, set it as the first child, and return it
- if (parent.first == null) {
- ResourceTable newNode = new ResourceTable();
- newNode.name = nodeName;
- parent.first = newNode;
- return newNode;
- }
-
- // if the first child is the one we want, return it
- if (nodeName.equals(parent.first.name)) {
- return parent.first;
- }
-
- // search for the node we want, remembering its 'elder' sibling, and if we find the
- // one we want, return it
- Resource child = parent.first;
- for (; child.next != null; child = child.next) {
- if (nodeName.equals(child.next.name)) {
- return child.next;
- }
- }
-
- // didn't find it, so create the node, make it the sibling of the youngest child,
- // and return it
- ResourceTable newNode = new ResourceTable();
- newNode.name = nodeName;
- child.next = newNode;
- return newNode;
- }
-
- /**
- * Removes this single child resource from parent, leaving other children
- * of parent undisturbed.
- *
- * @return the child resource (with no siblings)
- */
- private Resource removeChildFromParent(Resource child, Resource parent) {
- Resource first = parent.first;
- if (first == child) {
- parent.first = child.next;
- } else {
- while (first.next != null && first.next != child) {
- first = first.next;
- }
- if (first.next == null) {
- throw new IllegalArgumentException("Resource " + child + " is not a child of " +
- parent);
- }
- first.next = child.next;
- }
- child.next = null;
-
- return child;
- }
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/SupplementalMapper.java b/tools/java/org/unicode/cldr/icu/SupplementalMapper.java
deleted file mode 100644
index 1213f60..0000000
--- a/tools/java/org/unicode/cldr/icu/SupplementalMapper.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package org.unicode.cldr.icu;
-
-import java.io.File;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.unicode.cldr.icu.RegexManager.CldrArray;
-import org.unicode.cldr.icu.RegexManager.Function;
-import org.unicode.cldr.icu.RegexManager.PathValueInfo;
-import org.unicode.cldr.icu.RegexManager.RegexResult;
-import org.unicode.cldr.util.Builder;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.DtdType;
-import org.unicode.cldr.util.Pair;
-import org.unicode.cldr.util.PatternCache;
-import org.unicode.cldr.util.RegexLookup;
-import org.unicode.cldr.util.RegexLookup.Finder;
-import org.unicode.cldr.util.XMLFileReader;
-import org.unicode.cldr.util.XPathParts;
-
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.text.SimpleDateFormat;
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.GregorianCalendar;
-import com.ibm.icu.util.Output;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-/**
- * A mapper that converts supplemental LDML data from CLDR to the ICU data
- * structure.
- */
-public class SupplementalMapper {
- private static final Pattern ARRAY_INDEX = PatternCache.get("(/[^\\[]++)(?:\\[(\\d++)\\])?$");
- private static final Map<String, String> enumMap = Builder.with(new HashMap<String, String>())
- .put("sun", "1").put("mon", "2").put("tues", "3").put("wed", "4")
- .put("thu", "5").put("fri", "6").put("sat", "7").get();
- private static final NumberFormat numberFormat = NumberFormat.getInstance();
- static {
- numberFormat.setMinimumIntegerDigits(4);
- }
-
- private int fifoCounter;
- private String inputDir;
- private RegexManager regexMapper;
- private String debugXPath;
-
- private enum DateFieldType {
- from, to;
-
- public static DateFieldType toEnum(String value) {
- value = value.toLowerCase();
- if (value.equals("from") || value.equals("start")) {
- return from;
- } else if (value.equals("to") || value.equals("end")) {
- return to;
- } else {
- throw new IllegalArgumentException(value + " is not a valid date field type");
- }
- }
- };
-
- /**
- * Comparator for sorting LDML supplementalData xpaths.
- */
- private static Comparator<String> supplementalComparator = new Comparator<String>() {
- private final Pattern FROM_ATTRIBUTE = PatternCache.get("\\[@from=\"([^\"]++)\"]");
- private final Pattern WEEKDATA = PatternCache.get(
- "//supplementalData/weekData/(minDays|firstDay|weekendStart|weekendEnd).*");
-
- @Override
- public int compare(String arg0, String arg1) {
- Matcher[] matchers = new Matcher[2];
- String metazone = "//supplementalData/metaZones/metazoneInfo/timezone";
- if (arg0.startsWith(metazone) && arg1.startsWith(metazone)) {
- int startPos = metazone.length();
- boolean from0 = FROM_ATTRIBUTE.matcher(arg0).find(startPos);
- boolean from1 = FROM_ATTRIBUTE.matcher(arg1).find(startPos);
- if (from0 != from1) {
- return from0 ? 1 : -1;
- } else {
- // CLDRFile.ldmlComparator doesn't always order the from
- // dates correctly, so use a regular string comparison.
- return arg0.compareTo(arg1);
- }
- } else if (RegexManager.matches(WEEKDATA, arg0, arg1, matchers)) {
- // Sort weekData elements ourselves because ldmlComparator
- // sorts firstDay after minDays.
- String elem0 = matchers[0].group(1);
- String elem1 = matchers[1].group(1);
- int compareElem = elem0.compareTo(elem1);
- if (compareElem == 0) return compareElem;
- if (elem0.equals("weekendEnd")) {
- return 1;
- } else if (elem1.equals("weekendEnd")) {
- return -1;
- }
- return compareElem;
- }
- return CLDRFile.getComparator(DtdType.supplementalData).compare(arg0, arg1);
- }
- };
-
- /**
- * SupplementalMapper constructor.
- *
- * @param inputDir
- * the directory that the input files are in
- */
- private SupplementalMapper(String inputDir) {
- this.inputDir = inputDir;
- }
-
- public static SupplementalMapper create(String inputDir) {
- SupplementalMapper mapper = new SupplementalMapper(inputDir);
- // Handlers for functions in regex file.
- RegexManager manager = new RegexManager("ldml2icu_supplemental.txt");
- manager.addFunction("date", new Function(2) {
- /**
- * args[0] = value
- * args[1] = type (i.e. from/to)
- */
- @Override
- protected String run(String... args) {
- DateFieldType dft = DateFieldType.toEnum(args[1].trim());
- return getSeconds(args[0], dft);
- }
- });
- manager.addFunction("algorithm", new Function(1) {
- @Override
- protected String run(String... args) {
- // Insert % into numberingSystems descriptions.
- String value = args[0];
- int percentPos = value.lastIndexOf('/') + 1;
- return value.substring(0, percentPos) + '%' + value.substring(percentPos);
- }
- });
- // Converts a number into a special integer that represents the number in
- // normalized scientific notation for ICU's RB parser.
- // Resultant integers are in the form -?xxyyyyyy, where xx is the exponent
- // offset by 50 and yyyyyy is the coefficient to 5 decimal places, e.g.
- // 14660000000000 -> 1.466E13 -> 63146600
- // 0.0001 -> 1E-4 -> 46100000
- // -123.456 -> -1.23456E-2 -> -48123456
- // args[0] = number to be converted
- // args[2] = an (optional) additional exponent offset,
- // e.g. -2 for converting percentages into fractions.
- manager.addFunction("exp", new Function(2) {
- @Override
- protected String run(String... args) {
- double value = Double.parseDouble(args[0]);
- if (value == 0) {
- return "0";
- }
- int exponent = 50;
- if (args.length == 2) {
- exponent += Integer.parseInt(args[1]);
- }
- String sign = value >= 0 ? "" : "-";
- value = Math.abs(value);
- while (value >= 10) {
- value /= 10;
- exponent++;
- }
- while (value < 1) {
- value *= 10;
- exponent--;
- }
- if (exponent < 0 || exponent > 99) {
- throw new IllegalArgumentException("Exponent out of bounds: " + exponent);
- }
- return sign + exponent + Math.round(value * 100000);
- }
- });
- manager.addFunction("ymd", new Function(1) {
- /**
- * "Y-M-D" to "Y M D". Year value might be negative.
- * Also leading zeros are removed.
- *
- * Month value is 1-base unlike month
- * field in ICU calendar implementation.
- */
- @Override
- protected String run(String... args) {
- // Extracts fields separated by "-"
- String[] fields = args[0].replaceAll("([^-]+)-", "$1 ").split(" ");
- if (fields.length != 3) {
- throw new IllegalArgumentException("Not Y-M-D: " + args[0]);
- }
- StringBuilder buf = new StringBuilder();
- for (int i = 0; i < 3; i++) {
- // Validate each field as a numeric value,
- // emit the value as text without leading zeros.
- int val = Integer.parseInt(fields[i]);
- if (i != 0) {
- buf.append(" ");
- }
- buf.append(val);
- }
- return buf.toString();
- }
- });
- mapper.regexMapper = manager;
- return mapper;
- }
-
- /**
- * Loads an IcuData object of the specified type.
- *
- * @param outputName
- * the type of data to be converted
- * @return an IcuData object
- */
- public IcuData fillFromCldr(String outputName) {
- Map<String, CldrArray> pathValueMap = new HashMap<String, CldrArray>();
- String category = outputName;
- if (outputName.equals("supplementalData")) {
- String[] categories = {
- // "characters", explicitly skipped
-// "coverageLevels", explicitly skipped
-// "dayPeriods", done in processSupplemental
-// "genderList", done elsewhere??
- "languageInfo",
- // "likelySubtags", done elsewhere??
-// "metaZones", done elsewhere??
-// "numberingSystems", done elsewhere??
-// "ordinals", done in processSupplemental
-// "pluralRanges", done in processSupplemental
-// "plurals", done in processSupplemental
-// "postalCodeData", deprecated
- "supplementalData",
- "subdivisions",
-// "telephoneCodeData",
- "/../validity/"
- // "windowsZones", done elsewhere??
- };
- for (String cat : categories) {
- loadValues(cat, pathValueMap);
- }
- } else {
- if (outputName.equals("metadata")) category = "supplementalMetadata";
- loadValues(category, pathValueMap);
- }
- regexMapper.addFallbackValues(pathValueMap);
- IcuData icuData = new IcuData(category + ".xml", outputName, false, enumMap);
- for (String rbPath : pathValueMap.keySet()) {
- CldrArray values = pathValueMap.get(rbPath);
- icuData.addAll(rbPath, values.sortValues(supplementalComparator));
- }
- // Final pass through IcuData object to clean up any fallback rbpaths
- // in the values.
- // Assume one value per fallback path.
- for (String rbPath : icuData) {
- List<String[]> values = icuData.get(rbPath);
- for (int i = 0, len = values.size(); i < len; i++) {
- String[] valueArray = values.get(i);
- if (valueArray.length != 1) continue;
- String value = valueArray[0];
- Matcher matcher = ARRAY_INDEX.matcher(value);
- if (!matcher.matches()) continue;
- String replacePath = matcher.group(1);
- List<String[]> replaceValues = icuData.get(replacePath);
- if (replaceValues == null) {
- throw new RuntimeException(replacePath + " is missing from IcuData object.");
- }
- int replaceIndex = matcher.groupCount() > 1 ? Integer.valueOf(matcher.group(2)) : 0;
- if (replaceIndex >= replaceValues.size()) {
- throw new RuntimeException(replaceIndex + " out of range of values in " + replacePath);
- }
- values.set(i, replaceValues.get(replaceIndex));
- }
- }
- // Hack to add the CLDR version
- if (outputName.equals("supplementalData")) {
- icuData.add("/cldrVersion", CLDRFile.GEN_VERSION);
- }
- return icuData;
- }
-
- /**
- * Loads values for the specified category from CLDR.
- *
- * @param category
- * @param pathValueMap
- * the output map
- */
- private void loadValues(String category, Map<String, CldrArray> pathValueMap) {
- if (category.endsWith("/")) {
- File dir = new File(inputDir + category);
- for (File subfile : dir.listFiles()) {
- String name = subfile.getName();
- if (name.endsWith(".xml")) {
- name = name.substring(0, name.length() - 4);
- loadValues(category + name, pathValueMap);
- }
- }
- return;
- }
- String inputFile = new File(inputDir, category + ".xml").getAbsolutePath();
- List<Pair<String, String>> contents = new ArrayList<Pair<String, String>>();
- XMLFileReader.loadPathValues(inputFile, contents, true);
- RegexLookup<RegexResult> pathConverter = regexMapper.getPathConverter();
- fifoCounter = 0; // Helps to keep unsorted rb paths in order.
- for (Pair<String, String> pair : contents) {
- Output<Finder> matcher = new Output<Finder>();
- XPathParts parts = XPathParts.getFrozenInstance(pair.getFirst());
- String fullPath = parts.toString();
- // Only convert contributed or higher data
- if (parts.containsAttributeValue("draft", "provisional") ||
- parts.containsAttributeValue("draft", "unconfirmed")) {
- continue;
- }
- List<String> debugResults = isDebugXPath(fullPath) ? new ArrayList<String>() : null;
- Output<String[]> argInfo = new Output<>();
- RegexResult regexResult = pathConverter.get(fullPath, null, argInfo, matcher, debugResults);
- if (regexResult == null) {
- RegexManager.printLookupResults(fullPath, debugResults);
- continue;
- }
- if (debugResults != null) {
- System.out.println(fullPath + " successfully matched");
- }
- // String[] arguments = matcher.value.getInfo();
- String[] arguments = argInfo.value;
- String cldrValue = pair.getSecond();
- for (PathValueInfo info : regexResult) {
- List<String> values = info.processValues(arguments, cldrValue);
- // Check if there are any arguments that need splitting for the rbPath.
- String groupKey = info.processGroupKey(arguments);
- String baseXPath = info.processXPath(arguments, fullPath);
- boolean splitNeeded = false;
- int argIndex = info.getSplitRbPathArg();
- if (argIndex != -1) {
- String[] splitArgs = arguments[argIndex].split("\\s++");
- // Only split the first splittable argument needed for each rbPath.
- if (splitArgs.length > 1) {
- String[] newArgs = arguments.clone();
- for (String splitArg : splitArgs) {
- newArgs[argIndex] = splitArg;
- String rbPath = info.processRbPath(newArgs);
- processValues(baseXPath, rbPath, values, groupKey, pathValueMap);
- }
- splitNeeded = true;
- }
- }
- // No splitting required, process as per normal.
- if (!splitNeeded) {
- String rbPath = info.processRbPath(arguments);
- processValues(baseXPath, rbPath, values, groupKey, pathValueMap);
- }
- }
- fifoCounter++;
- }
- }
-
- /**
- * Processes values to be added to the ICU data structure
- *
- * @param xpath
- * the CLDR path that the values came from
- * @param rbPath
- * the rbPath that the values belong to
- * @param values
- * the values
- * @param groupKey
- * the key that the values should be grouped by
- * @param pathValueMap
- * the output map
- */
- private void processValues(String xpath, String rbPath, List<String> values,
- String groupKey, Map<String, CldrArray> pathValueMap) {
- // The fifo counter needs to be formatted with leading zeros for sorting.
- if (rbPath.contains("<FIFO>")) {
- rbPath = rbPath.replace("<FIFO>", '<' + numberFormat.format(fifoCounter) + '>');
- }
- CldrArray cldrArray = RegexManager.getCldrArray(rbPath, pathValueMap);
- cldrArray.put(xpath, values, groupKey);
- }
-
- /**
- * Converts a date string to a pair of millisecond values.
- *
- * @param dateStr
- * @return
- */
- private static String getSeconds(String dateStr, DateFieldType type) {
- long millis;
- try {
- millis = getMilliSeconds(dateStr, type);
- } catch (ParseException ex) {
- throw new IllegalArgumentException("Could not parse date: " + dateStr, ex);
- }
-
- int top = (int) ((millis & 0xFFFFFFFF00000000L) >>> 32); // top
- int bottom = (int) ((millis & 0x00000000FFFFFFFFL)); // bottom
-
- if (NewLdml2IcuConverter.DEBUG) {
- long bot = 0xffffffffL & bottom;
- long full = ((long) (top) << 32);
- full += bot;
- if (full != millis) {
- System.err.println("Error when converting " + millis + ": " +
- top + ", " + bottom + " was converted back into " + full);
- }
- }
-
- return top + " " + bottom;
- }
-
- /**
- * Parses a string date and normalizes it depending on what type of date it
- * is.
- *
- * @param dateStr
- * @param type
- * whether the date is a from or a to
- * @return
- * @throws ParseException
- */
- private static long getMilliSeconds(String dateStr, DateFieldType type)
- throws ParseException {
- int count = countHyphens(dateStr);
- if (count != 2) {
- throw new RuntimeException("Tried to parse invalid date: " + dateStr);
- }
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", ULocale.ROOT);
- TimeZone timezone = TimeZone.getTimeZone("GMT");
- format.setTimeZone(timezone);
- Date date = format.parse(dateStr);
- Calendar calendar = new GregorianCalendar();
- calendar.setTimeZone(timezone);
- calendar.setTime(date);
- switch (type) {
- case from: {
- // Set the times for to fields to the beginning of the day.
- calendar.set(Calendar.HOUR_OF_DAY, 0);
- calendar.set(Calendar.MINUTE, 0);
- calendar.set(Calendar.SECOND, 0);
- calendar.set(Calendar.MILLISECOND, 0);
- break;
- }
- case to: {
- // Set the times for to fields to the end of the day.
- calendar.set(Calendar.HOUR_OF_DAY, 23);
- calendar.set(Calendar.MINUTE, 59);
- calendar.set(Calendar.SECOND, 59);
- calendar.set(Calendar.MILLISECOND, 999);
- break;
- }
- }
- return calendar.getTimeInMillis();
- }
-
- /**
- * Counts the number of hyphens in a string.
- *
- * @param str
- * @return
- */
- private static int countHyphens(String str) {
- // Hyphens in front are actually minus signs.
- int lastPos = 0;
- int numHyphens = 0;
- while ((lastPos = str.indexOf('-', lastPos + 1)) > -1) {
- numHyphens++;
- }
- return numHyphens;
- }
-
- /**
- * Sets xpath to monitor for debugging purposes.
- * @param debugXPath
- */
- public void setDebugXPath(String debugXPath) {
- this.debugXPath = debugXPath;
- }
-
- /**
- * @param xpath
- * @return true if the xpath is to be debugged
- */
- boolean isDebugXPath(String xpath) {
- return debugXPath == null ? false : xpath.startsWith(debugXPath);
- }
-}
diff --git a/tools/java/org/unicode/cldr/icu/TestCldr.java b/tools/java/org/unicode/cldr/icu/TestCldr.java
index 8502d5f..9908dd8 100644
--- a/tools/java/org/unicode/cldr/icu/TestCldr.java
+++ b/tools/java/org/unicode/cldr/icu/TestCldr.java
@@ -35,6 +35,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.LanguageTagParser;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@@ -82,7 +83,7 @@
String directory;
- Set<String> allLocales = new TreeSet<String>();
+ Set<String> allLocales = new TreeSet<>();
public void TestScripts() {
Factory cldrFactory = Factory.make(
@@ -92,7 +93,7 @@
ULocale locale = locales[i];
logln(locale.toString());
int[] scriptNumbers = UScript.getCode(locale);
- Set<String> ICUScripts = new TreeSet<String>();
+ Set<String> ICUScripts = new TreeSet<>();
for (int j = 0; j < scriptNumbers.length; ++j) {
ICUScripts.add(UScript.getShortName(scriptNumbers[j]));
}
@@ -128,7 +129,7 @@
}
scriptBits.clear(UScript.COMMON);
scriptBits.clear(UScript.INHERITED);
- Set<String> scripts = new TreeSet<String>();
+ Set<String> scripts = new TreeSet<>();
for (int j = 0; j < scriptBits.size(); ++j) {
if (scriptBits.get(j)) {
scripts.add(UScript.getShortName(j));
@@ -156,7 +157,7 @@
* }
*/
// only get ICU's locales
- Set<String> s = new TreeSet<String>();
+ Set<String> s = new TreeSet<>();
addLocales(NumberFormat.getAvailableULocales(), s);
addLocales(DateFormat.getAvailableULocales(), s);
addLocales(Collator.getAvailableULocales(), s);
@@ -183,7 +184,7 @@
// oLocale = uLocale.toLocale();
File f = new File(directory, localeName + ".xml");
- logln("Testing " + f.getCanonicalPath());
+ logln("Testing " + PathUtilities.getNormalizedPathString(f));
SAX.parse(f, DEFAULT_HANDLER);
}
@@ -196,15 +197,15 @@
// ============ SAX Handler Infrastructure ============
enum AttributeName {
numberType, dateType, timeType, date, field, zone, parse, input, draft
- };
+ }
abstract public class Handler {
- Map<AttributeName, String> settings = new TreeMap<AttributeName, String>();
+ Map<AttributeName, String> settings = new TreeMap<>();
String name;
- List<ULocale> currentLocales = new ArrayList<ULocale>();
+ List<ULocale> currentLocales = new ArrayList<>();
int failures = 0;
@@ -247,7 +248,7 @@
for (Iterator<AttributeName> it = settings.keySet().iterator(); it
.hasNext();) {
AttributeName attributeName = it.next();
- String attributeValue = (String) settings.get(attributeName);
+ String attributeValue = settings.get(attributeName);
temp += " " + attributeName + "=<" + attributeValue + ">";
}
logln(temp + "]");
@@ -290,7 +291,7 @@
public Handler getHandler(String name, Attributes attributes) {
if (DEBUG)
logln("Creating Handler: " + name);
- Handler result = (Handler) RegisteredHandlers.get(name);
+ Handler result = RegisteredHandlers.get(name);
if (result == null)
logln("Unexpected test type: " + name);
else {
@@ -304,7 +305,7 @@
RegisteredHandlers.put(name, handler);
}
- Map<String, Handler> RegisteredHandlers = new HashMap<String, Handler>();
+ Map<String, Handler> RegisteredHandlers = new HashMap<>();
// ============ Statics for Date/Number Support ============
@@ -339,6 +340,7 @@
{
addHandler("collation", new Handler() {
+ @Override
public void handleResult(ULocale currentLocale, String value) {
Collator col = Collator.getInstance(currentLocale);
String lastLine = "";
@@ -370,6 +372,7 @@
addHandler("number", new Handler() {
String numberType = null;
+ @Override
public void handleResult(ULocale locale, String result) {
NumberFormat nf = null;
double v = Double.NaN;
@@ -435,6 +438,7 @@
int timeFormat = 0;
+ @Override
public void handleResult(ULocale locale, String result)
throws ParseException {
Date date = new Date();
@@ -515,6 +519,7 @@
String pattern = "";
+ @Override
public void handleResult(ULocale locale, String result)
throws ParseException {
for (Iterator<AttributeName> it = settings.keySet().iterator(); it
@@ -575,6 +580,7 @@
Handler handler;
+ @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// data.put(new ContextStack(contextStack), lastChars);
@@ -598,6 +604,7 @@
}
}
+ @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
try {
@@ -615,6 +622,7 @@
}
// Have to hack around the fact that the character data might be in pieces
+ @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
@@ -630,20 +638,24 @@
// just for debugging
+ @Override
public void notationDecl(String name, String publicId, String systemId)
throws SAXException {
logln("notationDecl: " + name + ", " + publicId + ", " + systemId);
}
+ @Override
public void processingInstruction(String target, String data)
throws SAXException {
logln("processingInstruction: " + target + ", " + data);
}
+ @Override
public void skippedEntity(String name) throws SAXException {
logln("skippedEntity: " + name);
}
+ @Override
public void unparsedEntityDecl(String name, String publicId,
String systemId, String notationName) throws SAXException {
logln("unparsedEntityDecl: " + name + ", " + publicId + ", " + systemId
@@ -651,4 +663,4 @@
}
};
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/icu/ldml2icu_dir_mapping.txt b/tools/java/org/unicode/cldr/icu/ldml2icu_dir_mapping.txt
deleted file mode 100644
index 4c32723..0000000
--- a/tools/java/org/unicode/cldr/icu/ldml2icu_dir_mapping.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-# Mapping of ICU paths to their respective folders.
-# Any leftover paths will be written to the locales folder.
-# '*' means that the path will be written to all folders.
-# Used by LDMLConverter.
-
-/Keys/ ; lang
-/Languages/ ; lang
-/LanguagesShort/ ; lang
-/Scripts/ ; lang
-/Scripts%stand-alone/ ; lang
-/Types/ ; lang
-/Variants/ ; lang
-/codePatterns/ ; lang
-/annotationPatterns/ ; lang
-/localeDisplayPattern/ ; lang
-/Countries/ ; region
-/Currencies/ ; curr
-/CurrencyPlurals/ ; curr
-/CurrencyUnitPatterns/ ; curr
-/currencySpacing/ ; curr
-/zoneStrings/ ; zone
-/CurrencyMap/ ; curr
-/CurrencyMeta/ ; curr
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/ldml2icu_header.txt b/tools/java/org/unicode/cldr/icu/ldml2icu_header.txt
deleted file mode 100644
index a9bd38f..0000000
--- a/tools/java/org/unicode/cldr/icu/ldml2icu_header.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/icu/ldml2icu_locale.txt b/tools/java/org/unicode/cldr/icu/ldml2icu_locale.txt
deleted file mode 100644
index 61d87f5..0000000
--- a/tools/java/org/unicode/cldr/icu/ldml2icu_locale.txt
+++ /dev/null
@@ -1,285 +0,0 @@
-# ldml2icu_locale.txt
-#
-# Copyright © 2011-2016 Unicode, Inc.
-# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
-# For terms of use, see http://www.unicode.org/copyright.html
-#
-# Used by LdmlLocaleMapper.
-# Data-driven file for mapping LDML locale paths to ICU paths.
-# See ldml2icu_readme.txt for a detailed explanation of this file.
-
-# Variables
-# Attribute value
-%A=[^"']++
-# Word
-%W=[\w\-]++
-# Greedy word match
-%G=[\w\-]+
-# Number match
-%N=\d++
-# The default numbering system to be used.
-%D=//ldml/numbers/defaultNumberingSystem
-
-# Main locale data
-
-# Aliases
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/alias[@source="locale"][@path="../calendar[@type='(%A)']"] ; /calendar/$1lo ; values=/LOCALE/calendar/$2
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/alias[@source="locale"][@path="../../calendar[@type='(%A)']/dayPeriods"] ; /calendar/$1/AmPmMarkers:alias ; values=/LOCALE/calendar/$2/AmPmMarkers
- ; /calendar/$1/AmPmMarkersNarrow:alias ; values=/LOCALE/calendar/$2/AmPmMarkersNarrow
- ; /calendar/$1/NoonMarker:alias ; values=/LOCALE/calendar/$2/NoonMarker
- ; /calendar/$1/NoonMarkerNarrow:alias ; values=/LOCALE/calendar/$2/NoonMarkerNarrow
-
-//ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="wide"]/alias[@source="locale"][@path="../dayPeriodWidth[@type='abbreviated']"] ; /calendar/gregorian/AmPmMarkers:alias ; values=/LOCALE/calendar/gregorian/AmPmMarkersAbbr
-//ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="narrow"]/alias[@source="locale"][@path="../dayPeriodWidth[@type='abbreviated']"] ; /calendar/gregorian/AmPmMarkersNarrow:alias ; values=/LOCALE/calendar/gregorian/AmPmMarkersAbbr
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(eras|quarters|cyclicNameSets|monthPatterns)/alias[@source="locale"][@path="../../%W[@type='(%A)']/%W"] ; /calendar/$1/$2:alias ; values=/LOCALE/calendar/$3/$2
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNarrow/alias[@source="locale"][@path="../eraAbbr"] ; /calendar/$1/eras/narrow:alias ; values=/LOCALE/calendar/$1/eras/abbreviated
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNames/alias[@source="locale"][@path="../eraAbbr"] ; /calendar/$1/eras/wide:alias ; values=/LOCALE/calendar/$1/eras/abbreviated
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(cyclicNameSet)s/\2[@type="(%W)"]/alias[@source="locale"][@path="../\2[@type='(%A)']"] ; /calendar/$1/$2s/$3:alias ; values=/LOCALE/calendar/$1/$2s/$4
-//ldml/dates/calendars/calendar[@type="(%A)"]/(cyclicNameSet)s/\2[@type="(%W)"]/(cyclicName)Context[@type="(%W)"]/\4Width[@type="(%W)"]/alias[@source="locale"][@path="../../../\4Set[@type='(%A)']/\4Context[@type='(%A)']/\4Width[@type='(%A)']"] ; /calendar/$1/$2s/$3/$5/$6:alias ; values=/LOCALE/calendar/$1/$2s/$7/$8/$9
-//ldml/dates/calendars/calendar[@type="(%A)"]/(cyclicNameSet)s/\2[@type="(%W)"]/(cyclicName)Context[@type="(%W)"]/\4Width[@type="(%W)"]/alias[@source="locale"][@path="../\4Width[@type='(%A)']"] ; /calendar/$1/$2s/$3/$5/$6:alias ; values=/LOCALE/calendar/$1/$2s/$3/$5/$7
-//ldml/dates/calendars/calendar[@type="(%A)"]/(cyclicNameSet|monthPattern|quarter)s/\2Context[@type="(%W)"]/\2Width[@type="(%W)"]/alias[@source="locale"][@path="../../\2Context[@type='(%W)']/\2Width[@type='(%A)']"] ; /calendar/$1/$2s/$3/$4:alias ; values=/LOCALE/calendar/$1/$2s/$5/$6
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(day|month)s/alias[@source="locale"][@path="../../%W[@type='(%A)']/%W"] ; /calendar/$1/$2Names:alias ; values=/LOCALE/calendar/$3/$2Names
-//ldml/dates/calendars/calendar[@type="(%A)"]/(day|month)s/\2Context[@type="(%W)"]/\2Width[@type="(%W)"]/alias[@source="locale"][@path="../\2Width[@type='(%A)']"] ; /calendar/$1/$2Names/$3/$4:alias ; values=/LOCALE/calendar/$1/$2Names/$3/$5
-//ldml/dates/calendars/calendar[@type="(%A)"]/(day|month)s/\2Context[@type="(%W)"]/\2Width[@type="(%W)"]/alias[@source="locale"][@path="../../\2Context[@type='(%W)']/\2Width[@type='(%A)']"] ; /calendar/$1/$2Names/$3/$4:alias ; values=/LOCALE/calendar/$1/$2Names/$5/$6
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(monthPattern|quarter)s/\2Context[@type="(%W)"]/\2Width[@type="(%W)"]/alias[@source="locale"][@path="../\2Width[@type='(%A)']"] ; /calendar/$1/$2s/$3/$4:alias ; values=/LOCALE/calendar/$1/$2s/$3/$5
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateFormats/alias[@source="locale"][@path="../../calendar[@type='(%A)']/dateFormats"] ; /calendar/$1/DateTimePatterns:alias ; values=/LOCALE/calendar/$2/DateTimePatterns
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/alias[@source="locale"][@path="../../calendar[@type='(%A)']/dateTimeFormats"]
- ; /calendar/$1/availableFormats:alias ; values=/LOCALE/calendar/$2/availableFormats
- ; /calendar/$1/appendItems:alias ; values=/LOCALE/calendar/$2/appendItems
- ; /calendar/$1/intervalFormats:alias ; values=/LOCALE/calendar/$2/intervalFormats
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/(availableFormats|appendItems|intervalFormats)/alias[@source="locale"][@path="../../../calendar[@type='(%A)']/dateTimeFormats/\2"] ; /calendar/$1/$2:alias ; values=/LOCALE/calendar/$3/$2
-
-//ldml/units/unitLength[@type="long"]/alias[@source="locale"][@path="../unitLength[@type='short']"] ; /units:alias ; values=/LOCALE/unitsShort
-//ldml/units/unitLength[@type="narrow"]/alias[@source="locale"][@path="../unitLength[@type='short']"] ; /unitsNarrow:alias ; values=/LOCALE/unitsShort
-
-//ldml/listPatterns/listPattern[@type="(%A)"]/alias[@source="locale"][@path="../listPattern"]
- ; /listPattern/$1/start:alias ; values=/LOCALE/listPattern/standard/start
- ; /listPattern/$1/middle:alias ; values=/LOCALE/listPattern/standard/middle
- ; /listPattern/$1/end:alias ; values=/LOCALE/listPattern/standard/end
- ; /listPattern/$1/2:alias ; values=/LOCALE/listPattern/standard/2
-//ldml/listPatterns/listPattern[@type="(%A)"]/alias[@source="locale"][@path="../listPattern[@type='(%A)']"]
- ; /listPattern/$1/start:alias ; values=/LOCALE/listPattern/$2/start
- ; /listPattern/$1/middle:alias ; values=/LOCALE/listPattern/$2/middle
- ; /listPattern/$1/end:alias ; values=/LOCALE/listPattern/$2/end
- ; /listPattern/$1/2:alias ; values=/LOCALE/listPattern/$2/2
-
-//ldml/numbers/currencyFormats[@numberSystem="(%A)"]/currencyFormatLength/currencyFormat[@type="accounting"]/alias[@source="locale"][@path="../(%W)[@type='standard']"] ; /NumberElements/$1/patterns/accountingFormat:alias ; values=/LOCALE/NumberElements/$1/patterns/$2
-
-# Characters
-
-//ldml/characters/exemplarCharacters[@type="auxiliary"] ; /AuxExemplarCharacters
-//ldml/characters/exemplarCharacters[@type="currencySymbol"] ; /ExemplarCharactersCurrency
-//ldml/characters/exemplarCharacters[@type="index"] ; /ExemplarCharactersIndex
-//ldml/characters/exemplarCharacters[@type="punctuation"] ; /ExemplarCharactersPunctuation
-//ldml/characters/exemplarCharacters[@type="numbers"] ; /ExemplarCharactersNumbers
-//ldml/characters/exemplarCharacters ; /ExemplarCharacters
-
-//ldml/characters/ellipsis[@type="(%A)"] ; /Ellipsis/$1
-//ldml/characters/moreInformation ; /MoreInformation
-//ldml/characters/special/icu:scripts/icu:script[@type="%N"] ; /LocaleScript
-
-//ldml/characters/parseLenients[@scope="(%A)"][@level="(%A)"]/parseLenient[@sample="(%A)"] ; /parse/$1/$2
-
-characters/parseLenients/parseLenient[@sample='%anyAttribute'][@scope='%anyAttribute']"/>
-characters/parseLenients/parseLenient[@sample='%anyAttribute'][@level='%anyAttribute']"/>
-characters/parseLenients/parseLenient[@sample='%anyAttribute'][@scope='%anyAttribute'][@level='%anyAttribute']"/>
-
-
-# Defaults
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(monthPattern)s/\2Context[@type="(%W)"]/\2Width[@type="(%W)"]/\2[@type="(%W)"] ; /calendar/$1/$2s/$3/$4/$5
-
-# Dates
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/cyclicNameSets/cyclicNameSet[@type="(%A)"]/cyclicNameContext[@type="(%A)"]/cyclicNameWidth[@type="(%A)"]/cyclicName[@type="(%A)"] ; /calendar/$1/cyclicNameSets/$2/$3/$4 ;
-# This is a weird edge case. When the number attribute is present in the xpath,
-# its value needs to be grouped together with the xpath value in its own special
-# array, which is treated like just another value in /DateTimePatterns.
-# The group keyword is used here to specify that values from the same xpath
-# should be grouped into their own separate array.
-# So far (Jan 2014), this only happens in the Chinese calendar for ja/zh/zh_Hant
-# and the Hebrew calendar for he, and all calendars for haw (which has numbers="M=romanlow").
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateFormats/dateFormatLength[@type="(%A)"]/dateFormat[@type="%A"]/pattern[@type="%A"][@numbers="(%A)"] ; /calendar/$1/DateTimePatterns ; values="{value}" $3 ; group=$2
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/((date|time|dateTime)Format)s/\2Length[@type="(%A)"]/\2[@type="%A"]/pattern[@type="%A"]$ ; /calendar/$1/DateTimePatterns
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/appendItems/appendItem[@request="(%A)"] ; /calendar/$1/appendItems/$2
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/availableFormats/dateFormatItem[@id="(%A)"]$ ; /calendar/$1/availableFormats/$2
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/availableFormats/dateFormatItem[@id="(%A)"][@count="(%A)"]$ ; /calendar/$1/availableFormats/$2/$3
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/intervalFormats/intervalFormatItem[@id="(%A)"]/greatestDifference[@id="(%A)"]$ ; /calendar/$1/intervalFormats/$2/$3
-//ldml/dates/calendars/calendar[@type="(%A)"]/dateTimeFormats/intervalFormats/intervalFormatFallback ; /calendar/$1/intervalFormats/fallback
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="wide"]/dayPeriod[@type="(am|pm)"][@alt="(%A)"] ; /calendar/$1/AmPmMarkers%$3
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="narrow"]/dayPeriod[@type="(am|pm)"][@alt="(%A)"] ; /calendar/$1/AmPmMarkersNarrow%$3
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="abbreviated"]/dayPeriod[@type="(am|pm)"][@alt="(%A)"] ; /calendar/$1/AmPmMarkersAbbr%$3
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="wide"]/dayPeriod[@type="(am|pm)"] ; /calendar/$1/AmPmMarkers
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="abbreviated"]/dayPeriod[@type="(am|pm)"] ; /calendar/$1/AmPmMarkersAbbr
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="format"]/dayPeriodWidth[@type="narrow"]/dayPeriod[@type="(am|pm)"] ; /calendar/$1/AmPmMarkersNarrow
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="(stand-alone)"]/dayPeriodWidth[@type="(%A)"]/dayPeriod[@type="(am|pm)"][@alt="(%A)"] ; /calendar/$1/dayPeriod/$2/$3/$4%$5
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="(stand-alone)"]/dayPeriodWidth[@type="(%A)"]/dayPeriod[@type="(am|pm)"] ; /calendar/$1/dayPeriod/$2/$3/$4
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="(%A)"]/dayPeriodWidth[@type="(%A)"]/dayPeriod[@type="(?!am|pm)(%A)"][@alt="(%A)"] ; /calendar/$1/dayPeriod/$2/$3/$4%$5
-//ldml/dates/calendars/calendar[@type="(%A)"]/dayPeriods/dayPeriodContext[@type="(%A)"]/dayPeriodWidth[@type="(%A)"]/dayPeriod[@type="(?!am|pm)(%A)"] ; /calendar/$1/dayPeriod/$2/$3/$4
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNarrow/era[@type="(%A)"][@alt="(%A)"] ; /calendar/$1/eras/narrow%$3
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraAbbr/era[@type="(%A)"][@alt="(%A)"] ; /calendar/$1/eras/abbreviated%$3
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNames/era[@type="(%A)"][@alt="(%A)"] ; /calendar/$1/eras/wide%$3
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNarrow/era[@type="(%A)"] ; /calendar/$1/eras/narrow
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraAbbr/era[@type="(%A)"] ; /calendar/$1/eras/abbreviated
-//ldml/dates/calendars/calendar[@type="(%A)"]/eras/eraNames/era[@type="(%A)"] ; /calendar/$1/eras/wide
-
-//ldml/dates/calendars/calendar[@type="(%A)"]/(day|month)s/%W[@type="(%A)"]/%W[@type="(%A)"]/%W[@type="(%A)"]([@yeartype="(%A)"])? ; /calendar/$1/$2Names/$3/$4
-//ldml/dates/calendars/calendar[@type="(%A)"]/(quarters)/%W[@type="(%A)"]/%W[@type="(%A)"]/%W[@type="(?:%A)"] ; /calendar/$1/$2/$3/$4
-
-//ldml/dates/fields/field[@type="(%A)"]/displayName[@alt="(%A)"] ; /fields/$1/dn%$2
-//ldml/dates/fields/field[@type="(%A)"]/displayName ; /fields/$1/dn
-//ldml/dates/fields/field[@type="(%A)"]/relative[@type="(%A)"] ; /fields/$1/relative/"$2"
-//ldml/dates/fields/field[@type="(%A)"]/relativePeriod ; /fields/$1/relativePeriod
-//ldml/dates/fields/field[@type="(%A)"]/relativeTime[@type="(%A)"]/relativeTimePattern[@count="(%A)"] ; /fields/$1/relativeTime/$2/$3
-
-//ldml/dates/fields/field[@type="(%A)"]/alias[@source="locale"][@path="../field[@type='(%A)']"]
- ; /fields/$1:alias ; values=/LOCALE/fields/$2
-
-//ldml/dates/timeZoneNames/regionFormat[@type="daylight"] ; /zoneStrings/regionFormatDaylight
-//ldml/dates/timeZoneNames/regionFormat[@type="standard"] ; /zoneStrings/regionFormatStandard
-//ldml/dates/timeZoneNames/(%GFormat) ; /zoneStrings/$1
-
-//ldml/dates/timeZoneNames/metazone[@type="(%A)"]/(\w)%W/(\w)%W ; /zoneStrings/"meta:$1"/$2$3
-
-//ldml/dates/timeZoneNames/zone[@type="(%W)/(%W)"]/exemplarCity[@alt="(%A)"] ; /zoneStrings/"$1:$2"/ec%$3
-//ldml/dates/timeZoneNames/zone[@type="(%W)/(%W)"]/exemplarCity ; /zoneStrings/"$1:$2"/ec
-//ldml/dates/timeZoneNames/zone[@type="(%W)/(%W)"]/(\w)%W/(\w)%W ; /zoneStrings/"$1:$2"/$3$4
-//ldml/dates/timeZoneNames/zone[@type="(%W)/(%W)/(%W)"]/exemplarCity[@alt="(%A)"] ; /zoneStrings/"$1:$2:$3"/ec%$4
-//ldml/dates/timeZoneNames/zone[@type="(%W)/(%W)/(%W)"]/exemplarCity ; /zoneStrings/"$1:$2:$3"/ec
-
-# Locale Display Names
-
-//ldml/localeDisplayNames/codePatterns/codePattern[@type="(%A)"] ; /codePatterns/$1
-//ldml/localeDisplayNames/annotationPatterns/annotationPattern[@type="(%A)"] ; /codePatterns/$1
-
-//ldml/localeDisplayNames/keys/key[@type="(%A)"] ; /Keys/$1
-
-//ldml/localeDisplayNames/languages/language[@type="(%A)"][@alt="(%A)"] ; /Languages%$2/$1
-//ldml/localeDisplayNames/languages/language[@type="(%A)"] ; /Languages/$1
-
-//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern ; /localeDisplayPattern/keyTypePattern
-//ldml/localeDisplayNames/localeDisplayPattern/localePattern ; /localeDisplayPattern/pattern
-//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator ; /localeDisplayPattern/separator
-
-//ldml/localeDisplayNames/measurementSystemNames/measurementSystemName[@type="(%A)"] ; /measurementSystemNames/$1
-
-//ldml/localeDisplayNames/scripts/script[@type="(%A)"][@alt="(%A)"] ; /Scripts%$2/$1
-//ldml/localeDisplayNames/scripts/script[@type="(%A)"] ; /Scripts/$1
-
-//ldml/localeDisplayNames/territories/territory[@type="(%A)"][@alt="(%A)"] ; /Countries%$2/$1
-//ldml/localeDisplayNames/territories/territory[@type="(%A)"] ; /Countries/$1
-
-//ldml/localeDisplayNames/transformNames/transformName[@type="(%W)"] ; /transformNames/$1
-
-//ldml/localeDisplayNames/types/type[@key="(%A)"][@type="(%A)"][@alt="(%A)"] ; /Types%$3/$1/$2
-//ldml/localeDisplayNames/types/type[@key="(%A)"][@type="(%A)"] ; /Types/$1/$2
-
-//ldml/localeDisplayNames/variants/variant[@type="(%A)"][@alt="(%A)"] ; /Variants%$2/$1
-//ldml/localeDisplayNames/variants/variant[@type="(%A)"] ; /Variants/$1
-
-# Numbers
-
-//ldml/numbers/currencies/currency[@type="(%A)"]/displayName[@count="(%A)"] ; /CurrencyPlurals/$1/$2
-
-//ldml/numbers/currencies/currency[@type="(%W)"]/symbol[@alt="(%A)"] ; /Currencies%$2/$1
-//ldml/numbers/currencies/currency[@type="(%W)"]/pattern[@type="standard"]; /Currencies/$1/ ; fallback=//ldml/numbers/currencyFormats[@numberSystem="%D"]/currencyFormatLength/currencyFormat[@type="standard"]/pattern[@type="standard"]
-//ldml/numbers/currencies/currency[@type="(%W)"]/decimal ; /Currencies/$1/ ; fallback=//ldml/numbers/symbols[@numberSystem="%D"]/decimal
-//ldml/numbers/currencies/currency[@type="(%W)"]/group ; /Currencies/$1/ ; fallback=//ldml/numbers/symbols[@numberSystem="%D"]/group
-//ldml/numbers/currencies/currency[@type="(%W)"]/symbol ; /Currencies/$1 ; fallback=$1
-//ldml/numbers/currencies/currency[@type="(%W)"]/displayName ; /Currencies/$1 ; fallback=$1
-
-
-//ldml/numbers/currencyFormats[@numberSystem="%D"]/currencySpacing/(%W)/(%W) ; /currencySpacing/$1/$2
-//ldml/numbers/currencyFormats[@numberSystem="%D"]/unitPattern[@count="(%W)"] ; /CurrencyUnitPatterns/$1
-
-//ldml/numbers/defaultNumberingSystem[@alt="(%A)"] ; /NumberElements/default_$1
-//ldml/numbers/defaultNumberingSystem ; /NumberElements/default
-//ldml/numbers/minimumGroupingDigits ; /NumberElements/minimumGroupingDigits
-//ldml/numbers/otherNumberingSystems/(%W) ; /NumberElements/$1
-
-//ldml/numbers/symbols[@numberSystem="(%A)"]/(%W)$ ; /NumberElements/$1/symbols/$2
-//ldml/numbers/(%GFormat)s[@numberSystem="(%W)"]/\1Length/\1[@type="standard"]/pattern[@type="standard"] ; /NumberElements/$2/patterns/$1
-//ldml/numbers/currencyFormats[@numberSystem="(%W)"]/currencyFormatLength/currencyFormat[@type="accounting"]/pattern[@type="standard"] ; /NumberElements/$1/patterns/accountingFormat
-//ldml/numbers/currencyFormats[@numberSystem="(%W)"]/currencyFormatLength[@type="short"]/currencyFormat[@type="standard"]/pattern[@type="(%N)"][@count="(%W)"] ; /NumberElements/$1/patternsShort/currencyFormat/$2/$3
-//ldml/numbers/decimalFormats[@numberSystem="(%W)"]/decimalFormatLength[@type="short"]/decimalFormat[@type="standard"]/pattern[@type="(%N)"][@count="(%W)"] ; /NumberElements/$1/patternsShort/decimalFormat/$2/$3
-//ldml/numbers/decimalFormats[@numberSystem="(%W)"]/decimalFormatLength[@type="long"]/decimalFormat[@type="standard"]/pattern[@type="(%N)"][@count="(%W)"] ; /NumberElements/$1/patternsLong/decimalFormat/$2/$3
-
-//ldml/numbers/miscPatterns[@numberSystem="(%W)"]/pattern[@type="(%W)"] ; /NumberElements/$1/miscPatterns/$2
-//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal="(%A)"] ; /NumberElements/minimalPairs/ordinal/$1
-//ldml/numbers/minimalPairs/pluralMinimalPairs[@count="(%A)"] ; /NumberElements/minimalPairs/plural/$1
-
-# Misc
-
-//ldml/contextTransforms/contextTransformUsage[@type="(%W)"]/contextTransform[@type="uiListOrMenu"] ; /contextTransforms/$1:intvector ; fallback=0
-//ldml/contextTransforms/contextTransformUsage[@type="(%W)"]/contextTransform[@type="stand-alone"] ; /contextTransforms/$1:intvector ; fallback=0
-
-//ldml/delimiters/(%W) ; /delimiters/$1
-
-//ldml/layout/orientation/(%G)Order ; /layout/$1s
-
-//ldml/listPatterns/listPattern/listPatternPart[@type="(%A)"] ; /listPattern/standard/$1
-//ldml/listPatterns/listPattern[@type="(%A)"]/listPatternPart[@type="(%A)"] ; /listPattern/$1/$2
-
-//ldml/units/unitLength[@type="narrow"]/unit[@type="(\w++)-(%A)"]/displayName ; /unitsNarrow/$1/$2/dnam
-//ldml/units/unitLength[@type="short"]/unit[@type="(\w++)-(%A)"]/displayName ; /unitsShort/$1/$2/dnam
-//ldml/units/unitLength[@type="long"]/unit[@type="(\w++)-(%A)"]/displayName ; /units/$1/$2/dnam
-
-//ldml/units/unitLength[@type="narrow"]/unit[@type="(\w++)-(%A)"]/unitPattern[@count="(%A)"] ; /unitsNarrow/$1/$2/$3
-//ldml/units/unitLength[@type="short"]/unit[@type="(\w++)-(%A)"]/unitPattern[@count="(%A)"] ; /unitsShort/$1/$2/$3
-//ldml/units/unitLength[@type="long"]/unit[@type="(\w++)-(%A)"]/unitPattern[@count="(%A)"] ; /units/$1/$2/$3
-
-//ldml/units/unitLength[@type="narrow"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1 ; /unitsNarrow/compound1/$1
-//ldml/units/unitLength[@type="short"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1 ; /unitsShort/compound1/$1
-//ldml/units/unitLength[@type="long"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1 ; /units/compound1/$1
-
-//ldml/units/unitLength[@type="narrow"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1[@count="(%A)"] ; /unitsNarrow/compoundPlurals/$1/$2
-//ldml/units/unitLength[@type="short"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1[@count="(%A)"] ; /unitsShort/compoundPlurals/$1/$2
-//ldml/units/unitLength[@type="long"]/compoundUnit[@type="(%A)"]/compoundUnitPattern1[@count="(%A)"] ; /units/compoundPlurals/$1/$2
-
-//ldml/units/unitLength[@type="narrow"]/compoundUnit[@type="(%A)"]/compoundUnitPattern ; /unitsNarrow/compound/$1
-//ldml/units/unitLength[@type="short"]/compoundUnit[@type="(%A)"]/compoundUnitPattern ; /unitsShort/compound/$1
-//ldml/units/unitLength[@type="long"]/compoundUnit[@type="(%A)"]/compoundUnitPattern ; /units/compound/$1
-
-//ldml/units/unitLength[@type="narrow"]/compoundUnit[@type="(%A)"]/unitPrefixPattern ; /unitsNarrow/prefix/$1
-//ldml/units/unitLength[@type="short"]/compoundUnit[@type="(%A)"]/unitPrefixPattern ; /unitsShort/prefix/$1
-//ldml/units/unitLength[@type="long"]/compoundUnit[@type="(%A)"]/unitPrefixPattern ; /units/prefix/$1
-
-//ldml/units/unitLength[@type="narrow"]/coordinateUnit/displayName ; /unitsNarrow/coordinate/dnam
-//ldml/units/unitLength[@type="short"]/coordinateUnit/displayName ; /unitsShort/coordinate/dnam
-//ldml/units/unitLength[@type="long"]/coordinateUnit/displayName ; /units/coordinate/dnam
-
-//ldml/units/unitLength[@type="narrow"]/coordinateUnit/coordinateUnitPattern[@type="(%A)"] ; /unitsNarrow/coordinate/$1
-//ldml/units/unitLength[@type="short"]/coordinateUnit/coordinateUnitPattern[@type="(%A)"] ; /unitsShort/coordinate/$1
-//ldml/units/unitLength[@type="long"]/coordinateUnit/coordinateUnitPattern[@type="(%A)"] ; /units/coordinate/$1
-
-//ldml/units/unitLength[@type="narrow"]/unit[@type="(\w++)-(%A)"]/perUnitPattern ; /unitsNarrow/$1/$2/per
-//ldml/units/unitLength[@type="short"]/unit[@type="(\w++)-(%A)"]/perUnitPattern ; /unitsShort/$1/$2/per
-//ldml/units/unitLength[@type="long"]/unit[@type="(\w++)-(%A)"]/perUnitPattern ; /units/$1/$2/per
-
-//ldml/units/durationUnit[@type="(%A)"]/durationUnitPattern$ ; /durationUnits/$1
-
-//ldml/units/unitLength[@type="narrow"]/unit[@type="(\w++)-(%A)"]/alias[@source="locale"][@path="../unit[@type='(\w++)-(%A)']"] ; /unitsNarrow/$1/$2:alias ; values=/LOCALE/unitsNarrow/$3/$4
-//ldml/units/unitLength[@type="short"]/unit[@type="(\w++)-(%A)"]/alias[@source="locale"][@path="../unit[@type='(\w++)-(%A)']"] ; /unitsShort/$1/$2:alias ; values=/LOCALE/unitsShort/$3/$4
-//ldml/units/unitLength[@type="long"]/unit[@type="(\w++)-(%A)"]/alias[@source="locale"][@path="../unit[@type='(\w++)-(%A)']"] ; /units/$1/$2:alias ; values=/LOCALE/units/$3/$4
-
-//ldml/characterLabels/characterLabelPattern[@type="(%A)"][@count="(%A)"] ; /characterLabelPattern/$1/$2
-//ldml/characterLabels/characterLabelPattern[@type="(%A)"] ; /characterLabelPattern/$1
-//ldml/characterLabels/characterLabel[@type="(%A)"] ; /characterLabel/$1
-
diff --git a/tools/java/org/unicode/cldr/icu/ldml2icu_readme.txt b/tools/java/org/unicode/cldr/icu/ldml2icu_readme.txt
deleted file mode 100644
index bd95389..0000000
--- a/tools/java/org/unicode/cldr/icu/ldml2icu_readme.txt
+++ /dev/null
@@ -1,182 +0,0 @@
-# README.txt for regex files used by org.unicode.cldr.icu.NewLdml2IcuConverter.
-#
-# Copyright © 2012-2014 Unicode, Inc.
-# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
-# For terms of use, see http://www.unicode.org/copyright.html
-
-======
-Basics
-======
-
-NewLdml2IcuConverter maps CLDR XPaths to ICU Resource Bundle paths based on
-regexes in special text files (ldml2icu.txt for locale data and
-ldml2icu_supplemental.txt for supplemental data). A Resource Bundle path is
-comprised of the ordered list of labels that appear for a value, e.g. the
-following ICU text file would have the paths /a/b/c and a/b/d:
-
-rootLabel{
- a{
- b{
- c{
- "x",
- "y"
- }
- d{3}
- }
- }
-}
-
-Root labels are not included in Resource Bundle paths for brevity.
-
-The format of a line in the regex file is:
- ldmlRegex ; icuPath (; specialInstructions)*
-
-All regexes in a file are assumed to be mutually exclusive and unique, so order
-is not important and the lines can be grouped logically.
-NOTE: The above is no longer true in CLDR 26 !!
-
-If an LDML xpath results in two or more ICU paths, they should be split into
-multiple lines, like this:
- ldmlRegex
- ; rbPath1 (; specialInstructions)*
- ; rbPath2 (; specialInstructions)*
- ...
-
-rbPath is a ICU path replacement expression that is filled out with arguments
-from ldmlRegex, e.g. given the line:
- //ldml/(.*)/b ; /x/$1
-matching //ldml/a/b would result in the ICU path /x/a.
-
-Each regex pattern must match an xpath completely to have a successful match.
-Square brackets that are part of the xpath will be preceded by a backslash
-during processing, so there's no need to do it here.
-
-When an xpath is matched, the value of the mapped ICU path will be the
-unsplit value in the CLDRFile. This can be overridden by using the special
-instruction "values=".
-
-All values written to ICU files are treated as strings and enclosed with quotes
-in the output by default. To force values to be written without quotes, the
-corresponding RB path should have :int (for single values) or :intvector
-(for arrays) appended to it, e.g. /contextTransforms/$1:intvector.
-
-There may be zero or more semicolon-delimited specialInstructions per line. See
-the section "Special Instructions" for details.
-
-
-=========
-Variables
-=========
-
-Variables are substituted into all the regexes in a file and should be declared
-at the top of the file. The value of the variable can either be a regex or a
-CLDR XPath that is present in the file being converted.
-All variable names should start with '%' and be one character long.
-Any regex being used that contains square brackets should be made a variable,
-since the converter will automatically escape all brackets that occur in the
-XPath regex unless they are represented by variables.
-
-
-====================
-Special Instructions
-====================
-
-There may be one or more semicolon-separated special instructions per line, each
-of which are performed whenever the regex in that line is matched.
-Each instruction may be one of the following:
-
-* values=<space-delimited-values>
-The values instruction explicitly specifies the values to be mapped to the
-generated rbPath instead of using the default values in CLDR.
-
-<space-delimited-values> may contain hardcoded values, replacement arguments
-from the xpath regex, or the keyword {value} which represents the value of the
-xpath in the CLDR data file.
-
-* fallback=<space-delimited-values>
-This instruction specifies that if the generated rbPath does not contain a value
-from an xpath that matches the current regex, the specified fallback values
-will be added to the rbPath instead.
-
-<space-delimited-values> may contain hardcoded values, replacement arguments
-from the xpath regex, or the XPath of another value in the CLDR file currently
-being converted.
-
-* group (no arguments)
-If present, this instruction indicates that the values created using this xpath
-should be grouped together in their own sub-array in the ICU data file. This
-instruction should be used instead of hidden labels if the array is in an array
-of values, e.g. the example below is generated by putting "EEEE, d בMMMM y" and
-"hebr" in the same group:
- DateTimePatterns {
- "HH:mm",
- {
- "EEEE, d בMMMM y",
- "hebr",
- }
- ...
-
-
-==========
-Functions
-==========
-
-Values sometimes need some further processing to be suitable for ICU. In such
-cases, functions can be written to process these values and their use is
-specified in the regex file like this:
- value=&date($1)
-
-This helps to put the special-case code in one place to minimize hackiness.
-
-Currently available functions:
-
-* &date(<arg>)
-Converts a formatted date to a pair of integers.
-
-* &algorithm(<arg>)
-Converts aliases for algorithmic numbering system descriptions to an
-ICU-compatible format.
-
-
-================
-Space Delimiting
-================
-
-All matched arguments from xpaths in the rbPath or specialInstructions will be
-split by whitespace, e.g. if the special instruction value=$1 is given an
-argument of "New York", it will be split into "New" and "York" in the output.
-In the case of rbPaths, multiple ICU paths will be created from the split argument,
-each containing one part of the argument.
-
-To prevent splitting, enclose the the corresponding argument in the replacement
-string with quotes, e.g. "$1" or "1999-01-01 9:00" will not be split.
-
-This trick can be used to split default values; the instruction values={value}
-will cause the CLDR value to be split by whitespace, while values="{value}" has
-the same effect as not including the instruction at all.
-
-
-=============
-Hidden Labels
-=============
-
-Some ICU paths will contain labels which are enclosed in angle brackets,
-e.g. /telephoneCodeData/$1/<$2>/code. They are processed and sorted like any
-any other ICU path, except that labels enclosed in angle brackets will not be
-written to the ICU file. This is used to create arrays without labels where
-necessary, e.g. the RB path mentioned earlier would result in the following
-output:
- telephoneCodeData{
- 001{
- {
- code{"388"}
- }
- {
- code{"800"}
- }
- ...
-
-<FIFO> is a special hidden label for ldml2icu_supplemental.txt only: using this
-label will cause the values from a single xpath to be grouped together in the
-same array, and the arrays will be written in the same order that they were read
-from the CLDR file.
diff --git a/tools/java/org/unicode/cldr/icu/ldml2icu_supplemental.txt b/tools/java/org/unicode/cldr/icu/ldml2icu_supplemental.txt
deleted file mode 100644
index ab714bd..0000000
--- a/tools/java/org/unicode/cldr/icu/ldml2icu_supplemental.txt
+++ /dev/null
@@ -1,208 +0,0 @@
-# ldml2icu_supplemental.txt
-#
-# Copyright © 2012-2015 Unicode, Inc.
-# CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
-# For terms of use, see http://www.unicode.org/copyright.html
-#
-# Used by SupplementalMapper.
-# Data-driven file for mapping supplemental LDML paths to ICU paths.
-# See ldml2icu_readme.txt for a detailed explanation of this file.
-
-# Attribute value
-%A=[^"']++
-# Attribute value, no underscore
-%B=[^"'_]++
-# Word/Zone match
-%W=[\s\w\-/]++
-# Greedy word match
-%G=[\s\w\-]+
-# Number match
-%N=[\d\.]++
-
-# supplementalData.xml
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@iso4217="(%W)"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$2
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@iso4217="(%W)"][@tender="false"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$2
- ; /CurrencyMap/$1/<FIFO>/tender ; values=false
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@from="(%W)"][@iso4217="(%W)"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$3
- ; /CurrencyMap/$1/<FIFO>/from:intvector ; values=&date($2, from)
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@from="(%W)"][@iso4217="(%W)"][@tender="false"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$3
- ; /CurrencyMap/$1/<FIFO>/from:intvector ; values=&date($2, from)
- ; /CurrencyMap/$1/<FIFO>/tender ; values=false
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@from="(%W)"][@to="(%W)"][@iso4217="(%W)"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$4
- ; /CurrencyMap/$1/<FIFO>/from:intvector ; values=&date($2, from)
- ; /CurrencyMap/$1/<FIFO>/to:intvector ; values=&date($3, to)
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@from="(%W)"][@to="(%W)"][@iso4217="(%W)"][@tender="false"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$4
- ; /CurrencyMap/$1/<FIFO>/from:intvector ; values=&date($2, from)
- ; /CurrencyMap/$1/<FIFO>/to:intvector ; values=&date($3, to)
- ; /CurrencyMap/$1/<FIFO>/tender ; values=false
-//supplementalData/currencyData/region[@iso3166="(%W)"]/currency[@to="(%W)"][@iso4217="(%W)"][@tender="false"]
- ; /CurrencyMap/$1/<FIFO>/id ; values=$3
- ; /CurrencyMap/$1/<FIFO>/to:intvector ; values=&date($2, to)
- ; /CurrencyMap/$1/<FIFO>/tender ; values=false
-//supplementalData/currencyData/fractions/info[@iso4217="(%W)"][@digits="(%N)"][@rounding="(%N)"][@cashDigits="(%N)"][@cashRounding="(%N)"] ; /CurrencyMeta/$1:intvector ; values=$2 $3 $4 $5
-//supplementalData/currencyData/fractions/info[@iso4217="(%W)"][@digits="(%N)"][@rounding="(%N)"][@cashRounding="(%N)"] ; /CurrencyMeta/$1:intvector ; values=$2 $3 $2 $4
-//supplementalData/currencyData/fractions/info[@iso4217="(%W)"][@digits="(%N)"][@rounding="(%N)"] ; /CurrencyMeta/$1:intvector ; values=$2 $3 $2 $3
-
-//supplementalData/calendarPreferenceData/calendarPreference[@territories="(%A)"][@ordering="(%A)"] ; /calendarPreferenceData/$1 ; values=$2
-//supplementalData/codeMappings/territoryCodes[@type="(%W)"][@numeric="(%N)"][@alpha3="(%W)"].* ; /codeMappings/<$1> ; values=$1 $2 $3
-
-//supplementalData/codeMappings/currencyCodes[@type="(%W)"][@numeric="(%N)"].* ; /codeMappingsCurrency/<$1> ; values=$1 $2
-
-//supplementalData/languageData/language[@type="(%W)"][@scripts="(%W)"][@territories="(%W)"][@alt="secondary"]
- ; /languageData/$1/secondary/scripts ; values=$2
- ; /languageData/$1/secondary/territories ; values=$3
-//supplementalData/languageData/language[@type="(%W)"][@scripts="(%W)"][@alt="secondary"] ; /languageData/$1/secondary/scripts ; values=$2
-//supplementalData/languageData/language[@type="(%W)"][@territories="(%G)"][@alt="secondary"] ; /languageData/$1/secondary/territories ; values=$2
-
-//supplementalData/languageData/language[@type="(%W)"][@scripts="(%W)"][@territories="(%W)"]
- ; /languageData/$1/primary/scripts ; values=$2
- ; /languageData/$1/primary/territories; values=$3
-//supplementalData/languageData/language[@type="(%W)"][@scripts="(%W)"] ; /languageData/$1/primary/scripts ; values=$2
-//supplementalData/languageData/language[@type="(%W)"][@territories="(%W)"] ; /languageData/$1/primary/territories ; values=$2
-
-//supplementalData/territoryContainment/group[@type="(%W)"][@contains="(%A)"][@status="deprecated"] ; /territoryContainment/deprecated/$1 ; values=$2
-//supplementalData/territoryContainment/group[@type="(%W)"][@contains="(%A)"][@status="grouping"] ; /territoryContainment/containedGroupings/$1 ; values=$2
-//supplementalData/territoryContainment/group[@type="(%W)"][@contains="(%A)"][@grouping="true"] ; /territoryContainment/grouping/$1 ; values=$2
-//supplementalData/territoryContainment/group[@type="(%W)"][@contains="(%A)"]; /territoryContainment/$1 ; values=$2
-
-//supplementalData/subdivisionContainment/subgroup[@type="(%W)"][@contains="(%A)"]; /subdivisionContainment/$1 ; values=$2
-//supplementalData/subdivisionContainment/subgroup[@type="(%W)"][@subtype="(%W)"][@contains="(%A)"]; /subdivisionContainment/$1-$2 ; values=$3
-
-//supplementalData/weekData/firstDay[@day="(%W)"][@territories="(%W)"]([@references="(%A)"])?[@alt="(%A)"] ; /weekData%$5/$2:intvector ; values=$1 ; fallback=/weekData/001:intvector[0]
-
-//supplementalData/weekData/firstDay[@day="(%W)"][@territories="(%W)"] ; /weekData/$2:intvector ; values=$1 ; fallback=/weekData/001:intvector[0]
-//supplementalData/weekData/minDays[@count="(%N)"][@territories="(%W)"] ; /weekData/$2:intvector ; values=$1 ; fallback=/weekData/001:intvector[1]
-//supplementalData/weekData/weekendStart[@day="(%W)"][@territories="(%W)"] ; /weekData/$2:intvector ; values=$1 0 ; fallback=/weekData/001:intvector[2] /weekData/001:intvector[3]
-//supplementalData/weekData/weekendEnd[@day="(%W)"][@territories="(%W)"] ; /weekData/$2:intvector ; values=$1 86400000 ; fallback=/weekData/001:intvector[4] /weekData/001:intvector[5]
-
-# <weekOfPreference ordering="weekOfYear" locales="und"/>
-//supplementalData/weekData/weekOfPreference[@locales="(%A)"][@ordering="(%A)"] ; /weekOfPreference/$1 ; values=$2
-
-//supplementalData/timeData/hours[@allowed="(%W)"][@preferred="(%W)"][@regions="(%W)"]
- ; /timeData/$3/allowed ; values=$1
- ; /timeData/$3/preferred ; values=$2
-
-//supplementalData/measurementData/measurementSystem[@type="metric"][@category="(%W)"][@territories="(%W)"] ; /measurementData/$2/MeasurementSystemCategory/$1:int ; values=0
-//supplementalData/measurementData/measurementSystem[@type="US"][@category="(%W)"][@territories="(%W)"] ; /measurementData/$2/MeasurementSystemCategory/$1:int ; values=1
-//supplementalData/measurementData/measurementSystem[@type="UK"][@category="(%W)"][@territories="(%W)"] ; /measurementData/$2/MeasurementSystemCategory/$1:int ; values=2
-
-//supplementalData/measurementData/measurementSystem[@type="metric"][@territories="(%W)"] ; /measurementData/$1/MeasurementSystem:int ; values=0
-//supplementalData/measurementData/measurementSystem[@type="US"][@territories="(%W)"] ; /measurementData/$1/MeasurementSystem:int ; values=1
-//supplementalData/measurementData/measurementSystem[@type="UK"][@territories="(%W)"] ; /measurementData/$1/MeasurementSystem:int ; values=2
-//supplementalData/measurementData/paperSize[@type="A4"][@territories="(%W)"] ; /measurementData/$1/PaperSize:intvector ; values=297 210
-//supplementalData/measurementData/paperSize[@type="US-Letter"][@territories="(%W)"] ; /measurementData/$1/PaperSize:intvector ; values=279 216
-
-//supplementalData/unitPreferenceData/unitPreferences[@category="(%W)"][@usage="(%A)"][@scope="small"]/unitPreference[@regions="(%A)"][@alt="informal"] ; /unitPreferenceData/$3/$1-$2-small-informal
-//supplementalData/unitPreferenceData/unitPreferences[@category="(%W)"][@usage="(%A)"][@scope="small"]/unitPreference[@regions="(%A)"] ; /unitPreferenceData/$3/$1-$2-small
-//supplementalData/unitPreferenceData/unitPreferences[@category="(%W)"][@usage="(%A)"]/unitPreference[@regions="(%A)"][@alt="informal"] ; /unitPreferenceData/$3/$1-$2-informal
-//supplementalData/unitPreferenceData/unitPreferences[@category="(%W)"][@usage="(%A)"]/unitPreference[@regions="(%A)"] ; /unitPreferenceData/$3/$1-$2
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@writingPercent="(%N)"][@populationPercent="(%N)"][@officialStatus="(%W)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/writingShareF:int ; values=&exp($6,-2)
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($7,-2)
- ; /territoryInfo/$1/$5/officialStatus ; values=$8
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@writingPercent="(%N)"][@populationPercent="(%N)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/writingShareF:int ; values=&exp($6,-2)
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($7,-2)
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@literacyPercent="(%N)"][@populationPercent="(%N)"][@officialStatus="(%W)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/literacyShareF:int ; values=&exp($6,-2)
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($7,-2)
- ; /territoryInfo/$1/$5/officialStatus ; values=$8
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@literacyPercent="(%N)"][@populationPercent="(%N)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/literacyShareF:int ; values=&exp($6,-2)
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($7,-2)
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@populationPercent="(%N)"][@officialStatus="(%W)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($6,-2)
- ; /territoryInfo/$1/$5/officialStatus ; values=$7
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]/languagePopulation[@type="(%W)"][@populationPercent="(%N)"]([@references="%W"])?
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
- ; /territoryInfo/$1/$5/populationShareF:int ; values=&exp($6,-2)
-
-//supplementalData/territoryInfo/territory[@type="(%W)"][@gdp="(%N)"][@literacyPercent="(%N)"][@population="(%N)"]
- ; /territoryInfo/$1/territoryF:intvector ; values=&exp($2) &exp($3,-2) &exp($4) ; base_xpath=//supplementalData/territoryInfo/territory[@type="$1"]
-
-//supplementalData/calendarData/calendar[@type="(%W)"]/calendarSystem[@type="(%W)"] ; /calendarData/$1/system ; values=$2
-//supplementalData/calendarData/calendar[@type="(%W)"]/eras/era[@type="(%W)"][@(start|end)="(%A)"][@named="(%W)"]
- ; /calendarData/$1/eras/$2/$3:intvector ; values=&ymd($4)
- ; /calendarData/$1/eras/$2/named ; values=$5
-//supplementalData/calendarData/calendar[@type="(%W)"]/eras/era[@type="(%W)"][@(start|end)="(%A)"]
- ; /calendarData/$1/eras/$2/$3:intvector ; values=&ymd($4)
-
-# telephoneCodeData.xml
-#//supplementalData/telephoneCodeData/codesByTerritory[@territory="(%W)"]/telephoneCountryCode[@code="(%N)"][@alt="(%A)"] ; /telephoneCodeData/$1/<$2>/code%$3 ; values=$2
-#//supplementalData/telephoneCodeData/codesByTerritory[@territory="(%W)"]/telephoneCountryCode[@code="(%N)"] ; /telephoneCodeData/$1/<$2>/code ; values=$2
-
-# languageInfo.xml
-
-//supplementalData/languageMatching/languageMatches[@type="(%B)_new"]/paradigmLocales[@locales="(%A)"] ; /languageMatchingInfo/$1/paradigmLocales ; values=$2
-//supplementalData/languageMatching/languageMatches[@type="(%B)_new"]/matchVariable[@id="\$(%A)"][@value="(%A)"] ; /languageMatchingInfo/$1/matchVariable/$2 ; values=$3
-
-//supplementalData/languageMatching/languageMatches[@type="(%B)_new"]/languageMatch[@desired="(%A)"][@supported="(%A)"][@distance="(%N)"][@oneway="true"] ; /languageMatchingNew/$1/<FIFO> ; values=$2 $3 $4 1
-//supplementalData/languageMatching/languageMatches[@type="(%B)_new"]/languageMatch[@desired="(%A)"][@supported="(%A)"][@distance="(%N)"] ; /languageMatchingNew/$1/<FIFO> ; values=$2 $3 $4 0
-
-//supplementalData/languageMatching/languageMatches[@type="(%B)"]/languageMatch[@desired="(%A)"][@supported="(%A)"][@percent="(%N)"][@oneway="true"] ; /languageMatching/$1/<FIFO> ; values=$2 $3 $4 1
-//supplementalData/languageMatching/languageMatches[@type="(%B)"]/languageMatch[@desired="(%A)"][@supported="(%A)"][@percent="(%N)"] ; /languageMatching/$1/<FIFO> ; values=$2 $3 $4 0
-
-# likelySubtags.xml
-//supplementalData/likelySubtags/likelySubtag[@from="(%A)"][@to="(%A)"] ; /$1 ; values=$2
-
-# metaZones.xml - metaZones.txt
-//supplementalData/metaZones/mapTimezones[@type="metazones"][@typeVersion="%A"]/mapZone[@type="(%A)"][@other="(%W)"][@territory="(%W)"] ; /mapTimezones/$2/$3 ; values=$1
-//supplementalData/metaZones/metazoneInfo/timezone[@type="(%W)"]/usesMetazone[@mzone="(%W)"] ; /metazoneInfo/"$1"/<$2> ; values=$2
-//supplementalData/metaZones/metazoneInfo/timezone[@type="(%W)"]/usesMetazone[@from="(%A)"][@mzone="(%W)"] ; /metazoneInfo/"$1"/<$2> ; values=$3 "$2" "9999-12-31 23:59"
-//supplementalData/metaZones/metazoneInfo/timezone[@type="(%W)"]/usesMetazone[@from="(%A)"][@to="(%A)"][@mzone="(%W)"] ; /metazoneInfo/"$1"/<$2> ; values=$4 "$2" "$3"
-//supplementalData/metaZones/metazoneInfo/timezone[@type="(%W)"]/usesMetazone[@to="(%A)"][@mzone="(%W)"] ; /metazoneInfo/"$1"/<1970-01-01 00:00> ; values=$3 "1970-01-01 00:00" "$2"
-
-//supplementalData/primaryZones/primaryZone[@iso3166="(%W)"] ; /primaryZones/$1 ; values={value}
-
-# numberingSystems.txt
-//supplementalData/numberingSystems/numberingSystem[@type="algorithmic"][@id="(%W)"][@rules="(%A)"]
- ; /numberingSystems/$1/algorithmic:int ; values=1
- ; /numberingSystems/$1/desc ; values=&algorithm($2)
- ; /numberingSystems/$1/radix:int ; values=10
-
-//supplementalData/numberingSystems/numberingSystem[@type="numeric"][@id="(%W)"][@digits="(%A)"]
- ; /numberingSystems/$1/algorithmic:int ; values=0
- ; /numberingSystems/$1/desc ; values=$2
- ; /numberingSystems/$1/radix:int ; values=10
-
-# windowsZones.txt
-//supplementalData/windowsZones/mapTimezones[@otherVersion="%W"][@typeVersion="%W"]/mapZone[@type="(%A)"][@other="(%A)"][@territory="(%W)"] ; /mapTimezones/"$2"/$3 ; values="$1"
-
-# genderList.txt
-//supplementalData/gender/personList[@type="(%W)"][@locales="(%W)"] ; /genderList/$2 ; values=$1
-
-# postalCodeData.xml
-//supplementalData/postalCodeData/postCodeRegex[@territoryId="(%W)"] ; /$1
-
-# locale info
-//supplementalData/parentLocales/parentLocale[@parent="(%A)"][@locales="(%A)"] ; /parentLocales/$1 ; values=$2
-//supplementalData/metadata/defaultContent[@locales="(%A)"] ; /defaultContent ; values=$1
-
-# supplementalMetadata.xml (metadata.txt)
-//supplementalData/metadata/alias/(language|script|territory|subdivision|variant)Alias[@type="(%A)"][@replacement="(%A)"][@reason="(%A)"]
- ; /alias/$1/$2/reason ; values="$4"
- ; /alias/$1/$2/replacement ; values="$3"
-
-# Region codes used by ICU's Region class
-# Specify the value explicitly so that the LDMLConverter will split it.
-//supplementalData/metadata/validity/variable[@type="choice"][@id="\$territory"] ; /regionCodes ; values={value}
-
-# validity
-//supplementalData/idValidity/id[@type="(%A)"][@idStatus="(%A)"] ; /idValidity/$1/$2 ; values={value}
diff --git a/tools/java/org/unicode/cldr/json/CldrItem.java b/tools/java/org/unicode/cldr/json/CldrItem.java
index f74ef31..092f408 100644
--- a/tools/java/org/unicode/cldr/json/CldrItem.java
+++ b/tools/java/org/unicode/cldr/json/CldrItem.java
@@ -30,7 +30,7 @@
}
int start = 0;
- ArrayList<String> segments = new ArrayList<String>();
+ ArrayList<String> segments = new ArrayList<>();
boolean inBracket = false;
boolean inBracketQuote = false;
for (int pos = start; pos < path.length(); ++pos) {
@@ -94,7 +94,7 @@
*/
private String value;
- CldrItem(String path, String fullPath, String untransformedPath, String untransformedFullPath, String value) {
+ CldrItem(final String path, String fullPath, String untransformedPath, String untransformedFullPath, String value) {
if (DEBUG) {
System.out.println("---");
@@ -104,6 +104,11 @@
System.out.println("---");
}
+ if(path.isEmpty()) {
+ // Should not happen
+ throw new IllegalArgumentException("empty path with " + fullPath+"|"+untransformedPath+"|"+untransformedFullPath+ " = " + value );
+ }
+
this.path = path;
this.fullPath = fullPath;
this.untransformedPath = untransformedPath;
@@ -163,7 +168,7 @@
String[] pathSegments = splitPathToSegments(path);
String[] fullPathSegments = splitPathToSegments(fullPath);
assert (pathSegments.length == fullPathSegments.length);
- ArrayList<CldrNode> nodesInPath = new ArrayList<CldrNode>();
+ ArrayList<CldrNode> nodesInPath = new ArrayList<>();
String parent = "";
for (int i = 0; i < pathSegments.length; i++) {
@@ -203,6 +208,9 @@
}
public void setPath(String path) {
+ if(path.isEmpty()) {
+ throw new IllegalArgumentException("empty path");
+ }
this.path = path;
}
@@ -224,15 +232,15 @@
for (SplittableAttributeSpec s : LdmlConvertRules.SPLITTABLE_ATTRS) {
if (fullxpp.containsElement(s.element) && fullxpp.containsAttribute(s.attribute)) {
- ArrayList<CldrItem> list = new ArrayList<CldrItem>();
+ ArrayList<CldrItem> list = new ArrayList<>();
String wordString = fullxpp.findAttributeValue(s.element, s.attribute);
String[] words = null;
words = wordString.trim().split("\\s+");
for (String word : words) {
- XPathParts newxpp = XPathParts.getInstance(xpp.toString());
- XPathParts newfullxpp = XPathParts.getInstance(fullxpp.toString());
- XPathParts untransformednewxpp = XPathParts.getInstance(untransformedxpp.toString());
- XPathParts untransformednewfullxpp = XPathParts.getInstance(untransformedfullxpp.toString());
+ XPathParts newxpp = xpp.cloneAsThawed();
+ XPathParts newfullxpp = fullxpp.cloneAsThawed();
+ XPathParts untransformednewxpp = untransformedxpp.cloneAsThawed();
+ XPathParts untransformednewfullxpp = untransformedfullxpp.cloneAsThawed();
newxpp.setAttribute(s.element, s.attribute, word);
newfullxpp.setAttribute(s.element, s.attribute, word);
diff --git a/tools/java/org/unicode/cldr/json/CldrNode.java b/tools/java/org/unicode/cldr/json/CldrNode.java
index f000c24..a4559eb 100644
--- a/tools/java/org/unicode/cldr/json/CldrNode.java
+++ b/tools/java/org/unicode/cldr/json/CldrNode.java
@@ -130,8 +130,8 @@
private String uniqueNodeName;
private CldrNode() {
- distinguishingAttributes = new HashMap<String, String>();
- nondistinguishingAttributes = new HashMap<String, String>();
+ distinguishingAttributes = new HashMap<>();
+ nondistinguishingAttributes = new HashMap<>();
}
/**
@@ -140,7 +140,7 @@
* @return String map.
*/
public Map<String, String> getAttrAsValueMap() {
- Map<String, String> attributesAsValues = new HashMap<String, String>();
+ Map<String, String> attributesAsValues = new HashMap<>();
for (String key : distinguishingAttributes.keySet()) {
String keyStr = parent + ":" + name + ":" + key;
if (LdmlConvertRules.ATTR_AS_VALUE_SET.contains(keyStr)) {
diff --git a/tools/java/org/unicode/cldr/json/JSON_config.txt b/tools/java/org/unicode/cldr/json/JSON_config.txt
index ba63a5e..2f9274b 100644
--- a/tools/java/org/unicode/cldr/json/JSON_config.txt
+++ b/tools/java/org/unicode/cldr/json/JSON_config.txt
@@ -8,6 +8,8 @@
section=contextTransforms ; path=//cldr/main/[^/]++/contextTransforms/.* ; package=misc
section=layout ; path=//cldr/main/[^/]++/layout/.* ; package=misc
section=characters ; path=//cldr/main/[^/]++/characters/.* ; package=misc
+section=typographic ; path=//cldr/main/[^/]++/typographicNames/.* ; package=misc
+section=characterLabels ; path=//cldr/main/[^/]++/characterLabel.*/.* ; package=misc
section=delimiters ; path=//cldr/main/[^/]++/delimiters/.* ; package=misc
section=ca-buddhist ; path=//cldr/main/[^/]++/dates/calendars/buddhist/.* ; package=cal-buddhist
section=ca-chinese ; path=//cldr/main/[^/]++/dates/calendars/chinese/.* ; package=cal-chinese
diff --git a/tools/java/org/unicode/cldr/json/JSON_config_annotations.txt b/tools/java/org/unicode/cldr/json/JSON_config_annotations.txt
new file mode 100644
index 0000000..0dc61d6
--- /dev/null
+++ b/tools/java/org/unicode/cldr/json/JSON_config_annotations.txt
@@ -0,0 +1 @@
+section=annotations ; path=//cldr/annotation.* ; package=annotations
diff --git a/tools/java/org/unicode/cldr/json/JSON_config_annotationsDerived.txt b/tools/java/org/unicode/cldr/json/JSON_config_annotationsDerived.txt
new file mode 100644
index 0000000..316a34d
--- /dev/null
+++ b/tools/java/org/unicode/cldr/json/JSON_config_annotationsDerived.txt
@@ -0,0 +1 @@
+section=annotations ; path=//cldr/annotation.* ; package=annotations-derived
diff --git a/tools/java/org/unicode/cldr/json/JSON_config_supplemental.txt b/tools/java/org/unicode/cldr/json/JSON_config_supplemental.txt
index 6cd5b55..ad29616 100644
--- a/tools/java/org/unicode/cldr/json/JSON_config_supplemental.txt
+++ b/tools/java/org/unicode/cldr/json/JSON_config_supplemental.txt
@@ -8,6 +8,7 @@
section=numberingSystems ; path=//cldr/supplemental/numberingSystems/.* ; package=core
section=ordinals ; path=//cldr/supplemental/plurals\[@type="ordinal"\]/.* ; package=core
section=plurals ; path=//cldr/supplemental/plurals\[@type="cardinal"\]/.* ; package=core
+section=pluralRanges ; path=//cldr/supplemental/plurals/.* ; package=core
section=postalCodeData ; path=//cldr/supplemental/postalCodeData/.* ; package=core
section=currencyData ; path=//cldr/supplemental/currencyData/.* ; package=core
section=territoryContainment ; path=//cldr/supplemental/territoryContainment/.* ; package=core
diff --git a/tools/java/org/unicode/cldr/json/Ldml2JsonConverter.java b/tools/java/org/unicode/cldr/json/Ldml2JsonConverter.java
index 7e3f64d..8086035 100644
--- a/tools/java/org/unicode/cldr/json/Ldml2JsonConverter.java
+++ b/tools/java/org/unicode/cldr/json/Ldml2JsonConverter.java
@@ -13,6 +13,7 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -20,6 +21,7 @@
import org.unicode.cldr.draft.ScriptMetadata;
import org.unicode.cldr.draft.ScriptMetadata.Info;
import org.unicode.cldr.tool.Option.Options;
+import org.unicode.cldr.util.Annotations;
import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRFile.DraftStatus;
@@ -38,13 +40,13 @@
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonWriter;
-import com.ibm.icu.dev.util.CollectionUtilities;
/**
* Utility methods to extract data from CLDR repository and export it in JSON
@@ -57,16 +59,16 @@
private static boolean DEBUG = false;
private enum RunType {
- main, supplemental, segments, rbnf
- };
+ main, supplemental, segments, rbnf, annotations, annotationsDerived
+ }
private static final StandardCodes sc = StandardCodes.make();
private Set<String> defaultContentLocales = SupplementalDataInfo.getInstance().getDefaultContentLocales();
- private Set<String> skippedDefaultContentLocales = new TreeSet<String>();
+ private Set<String> skippedDefaultContentLocales = new TreeSet<>();
private class availableLocales {
- Set<String> modern = new TreeSet<String>();
- Set<String> full = new TreeSet<String>();
+ Set<String> modern = new TreeSet<>();
+ Set<String> full = new TreeSet<>();
}
private availableLocales avl = new availableLocales();
@@ -82,7 +84,7 @@
"Destination directory for output files, defaults to CldrUtility.GEN_DIRECTORY")
.add("match", 'm', ".*", ".*",
"Regular expression to define only specific locales or files to be generated")
- .add("type", 't', "(main|supplemental|segments|rbnf)", "main",
+ .add("type", 't', "(main|supplemental|segments|rbnf|annotations|annotationsDerived)", "main",
"Type of CLDR data being generated, main, supplemental, or segments.")
.add("resolved", 'r', "(true|false)", "false",
"Whether the output JSON for the main directory should be based on resolved or unresolved data")
@@ -140,17 +142,16 @@
private class JSONSection implements Comparable<JSONSection> {
public String section;
- public Matcher matcher;
+ public Pattern pattern;
public String packageName;
+ @Override
public int compareTo(JSONSection other) {
return section.compareTo(other.section);
}
}
- private Map<JSONSection, List<CldrItem>> sectionItems = new TreeMap<JSONSection, List<CldrItem>>();
-
private Map<String, String> dependencies;
private List<JSONSection> sections;
private Set<String> packages;
@@ -166,9 +167,9 @@
this.writePackages = writePackages;
this.coverageValue = Level.get(coverage).getLevel();
- sections = new ArrayList<JSONSection>();
- packages = new TreeSet<String>();
- dependencies = new HashMap<String, String>();
+ sections = new ArrayList<>();
+ packages = new TreeSet<>();
+ dependencies = new HashMap<>();
FileProcessor myReader = new FileProcessor() {
@Override
@@ -203,7 +204,7 @@
if (hasSection && hasPath) {
JSONSection j = new JSONSection();
j.section = section;
- j.matcher = PatternCache.get(path).matcher("");
+ j.pattern = PatternCache.get(path);
if (hasPackage) {
j.packageName = packageName;
}
@@ -232,34 +233,56 @@
case rbnf:
myReader.process(Ldml2JsonConverter.class, "JSON_config_rbnf.txt");
break;
-
+ default:
+ myReader.process(Ldml2JsonConverter.class, "JSON_config_"+type.name()+".txt");
}
}
// Add a section at the end of the list that will match anything not already matched.
JSONSection j = new JSONSection();
j.section = "other";
- j.matcher = PatternCache.get(".*").matcher("");
+ j.pattern = PatternCache.get(".*");
sections.add(j);
}
/**
+ * @see XPathParts#addInternal
+ */
+ static final Pattern ANNOTATION_CP_REMAP = PatternCache.get("^(.*)\\[@cp=\"(\\[|\\]|'|\"|@|/|=)\"\\](.*)$");
+ /**
* Transform the path by applying PATH_TRANSFORMATIONS rules.
*
* @param pathStr
* The path string being transformed.
* @return The transformed path.
*/
- private String transformPath(String pathStr, String pathPrefix) {
+ private String transformPath(final String pathStr, final String pathPrefix) {
String result = pathStr;
+ // handle annotation cp value
+ Matcher cpm = ANNOTATION_CP_REMAP.matcher(result);
+ if( cpm.matches() ) {
+ // We need to avoid breaking the syntax not just of JSON, but of XPATH.
+ final String badCodepointRange = cpm.group(2);
+ StringBuilder sb = new StringBuilder(cpm.group(1))
+ .append("[@cp=\"");
+ // JSON would handle a wide range of things if escaped, but XPATH will not.
+ if(badCodepointRange.codePointCount(0, badCodepointRange.length()) != 1) {
+ // forbid more than one U+ (because we will have to unescape it.)
+ throw new IllegalArgumentException("Need exactly one codepoint in the @cp string, but got " + badCodepointRange + " in xpath " + pathStr);
+ }
+ badCodepointRange.codePoints().forEach(cp -> sb.append("U+").append(Integer.toHexString(cp).toUpperCase()));
+ sb.append("\"]").append(cpm.group(3));
+ result = sb.toString();
+ }
+
if (DEBUG) {
System.out.println(" IN pathStr : " + result);
}
Matcher m;
for (int i = 0; i < LdmlConvertRules.PATH_TRANSFORMATIONS.length; i++) {
- m = LdmlConvertRules.PATH_TRANSFORMATIONS[i].pattern.matcher(pathStr);
+ m = LdmlConvertRules.PATH_TRANSFORMATIONS[i].pattern.matcher(result);
if (m.matches()) {
if (DEBUG) {
System.out.println(LdmlConvertRules.PATH_TRANSFORMATIONS[i].pattern);
@@ -289,14 +312,16 @@
return result;
}
- private void mapPathsToSections(CLDRFile file, String pathPrefix, SupplementalDataInfo sdi)
+ private Map<JSONSection, List<CldrItem>> mapPathsToSections(AtomicInteger readCount, int totalCount,
+ CLDRFile file, String pathPrefix, SupplementalDataInfo sdi)
throws IOException, ParseException {
+ final Map<JSONSection, List<CldrItem>> sectionItems = new TreeMap<>();
String locID = file.getLocaleID();
Matcher noNumberingSystemMatcher = LdmlConvertRules.NO_NUMBERING_SYSTEM_PATTERN.matcher("");
Matcher numberingSystemMatcher = LdmlConvertRules.NUMBERING_SYSTEM_PATTERN.matcher("");
Matcher rootIdentityMatcher = LdmlConvertRules.ROOT_IDENTITY_PATTERN.matcher("");
- Set<String> activeNumberingSystems = new TreeSet<String>();
+ Set<String> activeNumberingSystems = new TreeSet<>();
activeNumberingSystems.add("latn"); // Always include latin script numbers
for (String np : LdmlConvertRules.ACTIVE_NUMBERING_SYSTEM_XPATHS) {
String ns = file.getWinningValue(np);
@@ -313,7 +338,7 @@
CoverageInfo covInfo = CLDRConfig.getInstance().getCoverageInfo();
for (Iterator<String> it = file.iterator("", DtdData.getInstance(fileDtdType).getDtdComparator(null)); it.hasNext();) {
int cv = Level.UNDETERMINED.getLevel();
- String path = it.next();
+ final String path = it.next();
String fullPath = file.getFullXPath(path);
String value = file.getWinningValue(path);
if (path.startsWith("//ldml/localeDisplayNames/languages") &&
@@ -361,14 +386,17 @@
String transformedPath = transformPath(path, pathPrefix);
String transformedFullPath = transformPath(fullPath, pathPrefix);
+ if(transformedPath.isEmpty()) {
+ continue; // skip this path
+ }
+
for (JSONSection js : sections) {
- js.matcher.reset(transformedPath);
- if (js.matcher.matches()) {
+ if (js.pattern.matcher(transformedPath).matches()) {
CldrItem item = new CldrItem(transformedPath, transformedFullPath, path, fullPath, value);
List<CldrItem> cldrItems = sectionItems.get(js);
if (cldrItems == null) {
- cldrItems = new ArrayList<CldrItem>();
+ cldrItems = new ArrayList<>();
}
cldrItems.add(item);
sectionItems.put(js, cldrItems);
@@ -382,9 +410,9 @@
JSONSection otherSection = sections.get(sections.size() - 1);
List<CldrItem> others = sectionItems.get(otherSection);
if (others == null) {
- return;
+ return sectionItems;
}
- List<CldrItem> otherSectionItems = new ArrayList<CldrItem>(others);
+ List<CldrItem> otherSectionItems = new ArrayList<>(others);
int addedItemCount = 0;
boolean copyIdentityInfo = Boolean.parseBoolean(options.get("identity").getValue());
@@ -407,6 +435,7 @@
addedItemCount++;
}
}
+ return sectionItems;
}
/**
@@ -419,7 +448,9 @@
* @throws IOException
* @throws ParseException
*/
- private void convertCldrItems(String dirName, String filename, String pathPrefix)
+ private void convertCldrItems(AtomicInteger readCount, int totalCount,
+ String dirName, String filename, String pathPrefix,
+ final Map<JSONSection, List<CldrItem>> sectionItems)
throws IOException, ParseException {
// zone and timezone items are queued for sorting first before they are
// processed.
@@ -478,6 +509,8 @@
System.out.println("pack: " + js.packageName);
System.out.println("dir: " + dirName);
}
+ } else {
+ outputDirname.append("/" + filename);
}
File dir = new File(outputDirname.toString());
@@ -485,7 +518,7 @@
dir.mkdirs();
}
- List<String> outputDirs = new ArrayList<String>();
+ List<String> outputDirs = new ArrayList<>();
outputDirs.add(outputDirname.toString());
if (writePackages && type == RunType.main && tier.equals("-modern")) {
outputDirs.add(outputDirname.toString().replaceFirst("-modern", "-full"));
@@ -494,22 +527,27 @@
for (String outputDir : outputDirs) {
List<CldrItem> theItems = sectionItems.get(js);
if (theItems == null || theItems.size() == 0) {
+ System.out.println(">"+progressPrefix(readCount, totalCount) +
+ outputDir + " - no items to write");
continue;
}
+ System.out.println("?"+progressPrefix(readCount, totalCount) + outputDir + " - " + theItems.size() + " item(s) to write.");
PrintWriter outf = FileUtilities.openUTF8Writer(outputDir, outFilename);
JsonWriter out = new JsonWriter(outf);
out.setIndent(" ");
- ArrayList<CldrItem> sortingItems = new ArrayList<CldrItem>();
- ArrayList<CldrItem> arrayItems = new ArrayList<CldrItem>();
+ ArrayList<CldrItem> sortingItems = new ArrayList<>();
+ ArrayList<CldrItem> arrayItems = new ArrayList<>();
- ArrayList<CldrNode> nodesForLastItem = new ArrayList<CldrNode>();
+ ArrayList<CldrNode> nodesForLastItem = new ArrayList<>();
String lastLeadingArrayItemPath = null;
String leadingArrayItemPath = "";
int valueCount = 0;
String previousIdentityPath = null;
for (CldrItem item : theItems) {
-
+ if(item.getPath().isEmpty()) {
+ throw new IllegalArgumentException("empty xpath in " + filename + " section " + js.packageName+"/"+js.section);
+ }
if (type == RunType.rbnf) {
item.setValue(item.getValue().replace('→', '>'));
item.setValue(item.getValue().replace('←', '<'));
@@ -627,7 +665,8 @@
resolveSortingItems(out, nodesForLastItem, sortingItems);
resolveArrayItems(out, nodesForLastItem, arrayItems);
- System.out.println(String.format(" %s = %d values", outFilename, valueCount));
+ System.out.println(">"+progressPrefix(readCount, totalCount) + String.format(".../%s/%s\t= %d values",
+ dir.getPath().substring(this.outputDir.length()+1), outFilename, valueCount));
closeNodes(out, nodesForLastItem.size() - 2, 0);
outf.println();
out.close();
@@ -683,9 +722,7 @@
JsonObject obj = new JsonObject();
writeBasicInfo(obj, packageName, true);
- JsonArray licenses = new JsonArray();
JsonArray maintainers = new JsonArray();
- JsonObject UnicodeLicense = new JsonObject();
JsonObject primaryMaintainer = new JsonObject();
obj.addProperty("homepage", "http://cldr.unicode.org");
@@ -702,10 +739,7 @@
repository.addProperty("url", "git://github.com/unicode-cldr/" + packageName + ".git");
obj.add("repository", repository);
- UnicodeLicense.addProperty("type", "Unicode-TOU");
- UnicodeLicense.addProperty("url", "http://www.unicode.org/copyright.html");
- licenses.add(UnicodeLicense);
- obj.add("licenses", licenses);
+ obj.addProperty("license", "Unicode-DFS-2016");
obj.addProperty("bugs", "https://unicode-org.atlassian.net/projects/CLDR/issues");
@@ -761,13 +795,13 @@
public void writeScriptMetadata(String outputDir) throws IOException {
PrintWriter outf = FileUtilities.openUTF8Writer(outputDir + "/cldr-core", "scriptMetadata.json");
System.out.println("Creating script metadata file => " + outputDir + File.separator + "cldr-core" + File.separator + "scriptMetadata.json");
- Map<String, Info> scriptInfo = new TreeMap<String, Info>();
+ Map<String, Info> scriptInfo = new TreeMap<>();
for (String script : ScriptMetadata.getScripts()) {
Info i = ScriptMetadata.getInfo(script);
scriptInfo.put(script, i);
}
if (ScriptMetadata.errors.size() > 0) {
- System.err.println(CollectionUtilities.join(ScriptMetadata.errors, "\n\t"));
+ System.err.println(Joiner.on("\n\t").join(ScriptMetadata.errors));
//throw new IllegalArgumentException();
}
@@ -793,7 +827,7 @@
ArrayList<CldrNode> nodesForLastItem,
ArrayList<CldrItem> sortingItems)
throws IOException, ParseException {
- ArrayList<CldrItem> arrayItems = new ArrayList<CldrItem>();
+ ArrayList<CldrItem> arrayItems = new ArrayList<>();
String lastLeadingArrayItemPath = null;
if (!sortingItems.isEmpty()) {
@@ -1029,7 +1063,17 @@
Map<String, String> attrAsValueMap = node.getAttrAsValueMap();
- out.name(objName);
+ if( type == RunType.annotations || type == RunType.annotationsDerived ) {
+ if(objName.startsWith("U+")) {
+ // parse U+22 -> " etc
+ out.name(com.ibm.icu.text.UTF16.valueOf(Integer.parseInt(objName.substring(2), 16)));
+ } else {
+ out.name(objName);
+ }
+ } else {
+ out.name(objName);
+ }
+
out.beginObject();
for (String key : attrAsValueMap.keySet()) {
String value = escapeValue(attrAsValueMap.get(key));
@@ -1189,6 +1233,14 @@
return i;
}
+ private final String progressPrefix(AtomicInteger readCount, int totalCount) {
+ return progressPrefix(readCount.get(), totalCount);
+ }
+
+ private final String progressPrefix(int readCount, int totalCount) {
+ return String.format("[%d/%d]:\t", readCount, totalCount);
+ }
+
/**
* Process files in a directory of CLDR file tree.
*
@@ -1205,28 +1257,63 @@
Factory cldrFactory = Factory.make(
cldrCommonDir + dirName + "/", ".*");
Set<String> files = cldrFactory.getAvailable();
- for (String filename : files) {
- if (LdmlConvertRules.IGNORE_FILE_SET.contains(filename)) {
- continue;
+ final int total = files.size();
+ AtomicInteger readCount = new AtomicInteger(0);
+ Map<String, Throwable> errs = new TreeMap<>();
+ files
+ .parallelStream()
+ .unordered()
+ .forEach(filename -> {
+
+ if (LdmlConvertRules.IGNORE_FILE_SET.contains(filename)) {
+ return;
+ }
+ if (!filename.matches(match)) {
+ return;
+ }
+
+ String pathPrefix;
+ CLDRFile file = cldrFactory.make(filename, resolve && type == RunType.main, minimalDraftStatus);
+ // Print 'reading' after the make, to stagger the output a little bit.
+ // Otherwise, the printout happens before any work happens, and is easily out of order.
+ System.out.println("<"+progressPrefix(readCount.incrementAndGet(), total) +
+ "Reading " + dirName + "/" + filename);
+
+ if (type == RunType.main) {
+ pathPrefix = "/cldr/" + dirName + "/" + filename.replaceAll("_", "-") + "/";
+ } else {
+ pathPrefix = "/cldr/" + dirName + "/";
+ }
+
+ try {
+ convertCldrItems(readCount, total, dirName, filename, pathPrefix,
+ mapPathsToSections(readCount, total, file, pathPrefix, sdi));
+ } catch(IOException | ParseException t) {
+ t.printStackTrace();
+ System.err.println("!"+progressPrefix(readCount.incrementAndGet(), total)+filename + " - err - " + t);
+ errs.put(filename, t);
+ } finally {
+ System.out.println("."+progressPrefix(readCount, total) +
+ "Completing " + dirName + "/" + filename);
+ }
+ });
+
+ if(!errs.isEmpty()) {
+ System.err.println("Errors in these files:");
+ for(Map.Entry<String,Throwable> e : errs.entrySet()) {
+ System.err.println(e.getKey() + " - " + e.getValue());
}
- if (!filename.matches(match)) {
- continue;
+ // rethrow
+ for(Map.Entry<String,Throwable> e : errs.entrySet()) {
+ if(e.getValue() instanceof IOException ) {
+ throw (IOException)e.getValue(); // throw the first one
+ } else if(e.getValue() instanceof ParseException ) {
+ throw (ParseException)e.getValue(); // throw the first one
+ } else {
+ throw new RuntimeException("Other exception thrown: " + e.getValue());
+ }
+ /* NOTREACHED */
}
-
- System.out.println("Processing file " + dirName + "/" + filename);
- String pathPrefix;
- CLDRFile file = cldrFactory.make(filename, resolve && type == RunType.main, minimalDraftStatus);
-
- sectionItems.clear();
- if (type == RunType.main) {
- pathPrefix = "/cldr/" + dirName + "/" + filename.replaceAll("_", "-") + "/";
- } else {
- pathPrefix = "/cldr/" + dirName + "/";
- }
- mapPathsToSections(file, pathPrefix, sdi);
-
- convertCldrItems(dirName, filename, pathPrefix);
-
}
if (writePackages) {
@@ -1310,12 +1397,21 @@
value = escapeValue(value);
if (attrAsValueMap.isEmpty()) {
+ out.name(objName);
if (value.isEmpty()) {
- out.name(objName);
out.beginObject();
out.endObject();
+ } else if (type == RunType.annotations ||
+ type == RunType.annotationsDerived) {
+ out.beginArray();
+ // split this, so "a | b | c" becomes ["a","b","c"]
+ for (final String s : Annotations.splitter.split(value.trim())) {
+ out.value(s);
+ }
+ out.endArray();
} else {
- out.name(objName).value(value);
+ // normal value
+ out.value(value);
}
return;
}
@@ -1351,13 +1447,10 @@
out.value(s);
}
out.endArray();
- } else {
- if (type != RunType.rbnf) {
+ } else if (type != RunType.rbnf) {
out.name("_" + key).value(attrValue);
- } else {
- out.name(key).value(attrValue);
- }
-
+ } else {
+ out.name(key).value(attrValue);
}
}
if (!objName.equals("rbnfrule")) {
diff --git a/tools/java/org/unicode/cldr/json/LdmlConvertRules.java b/tools/java/org/unicode/cldr/json/LdmlConvertRules.java
index 932b74f..b45185a 100644
--- a/tools/java/org/unicode/cldr/json/LdmlConvertRules.java
+++ b/tools/java/org/unicode/cldr/json/LdmlConvertRules.java
@@ -13,7 +13,7 @@
class LdmlConvertRules {
/** File sets that will not be processed in JSON transformation. */
- public static final ImmutableSet<String> IGNORE_FILE_SET = ImmutableSet.of("attributeValueValidity", "coverageLevels", "grammaticalFeatures", "postalCodeData", "pluralRanges",
+ public static final ImmutableSet<String> IGNORE_FILE_SET = ImmutableSet.of("attributeValueValidity", "coverageLevels", "grammaticalFeatures", "postalCodeData",
"subdivisions", "units");
/**
@@ -26,6 +26,7 @@
"monthWidth:month:yeartype",
"characters:parseLenients:scope",
"dateFormat:pattern:numbers",
+ "characterLabelPatterns:characterLabelPattern:count", // originally under characterLabels
"currencyFormats:unitPattern:count",
"currency:displayName:count",
"numbers:symbols:numberSystem",
@@ -39,6 +40,10 @@
"decimalFormat:pattern:count",
"currencyFormat:pattern:count",
"unit:unitPattern:count",
+ // compound units
+ "compoundUnit:compoundUnitPattern1:count",
+ "compoundUnit:compoundUnitPattern1:gender",
+ "compoundUnit:compoundUnitPattern1:case",
"field:relative:type",
"field:relativeTime:type",
"relativeTime:relativeTimePattern:count",
@@ -53,8 +58,12 @@
"unitPreferenceDataData:unitPreferences:category",
"measurementData:measurementSystem:category",
"supplemental:plurals:type",
+ "pluralRanges:pluralRange:start",
+ "pluralRanges:pluralRange:end",
"pluralRules:pluralRule:count",
- "languageMatches:languageMatch:desired");
+ "languageMatches:languageMatch:desired",
+ "styleNames:styleName:subtype",
+ "styleNames:styleName:alt");
/**
* The set of attributes that should become part of the name in form of
@@ -171,6 +180,9 @@
// common/collation
"collations:default:choice",
+ // common/supplemental/pluralRanges.xml
+ "pluralRanges:pluralRange:result",
+
// identity elements
"identity:language:type",
"identity:script:type",
@@ -255,6 +267,7 @@
*/
public static final SplittableAttributeSpec[] SPLITTABLE_ATTRS = {
new SplittableAttributeSpec("calendarPreference", "territories", null),
+ new SplittableAttributeSpec("pluralRanges", "locales", null),
new SplittableAttributeSpec("pluralRules", "locales", null),
new SplittableAttributeSpec("minDays", "territories", "count"),
new SplittableAttributeSpec("firstDay", "territories", "day"),
@@ -293,7 +306,7 @@
* multiple items, and items for each locale should be grouped together.
*/
public static final String[] ELEMENT_NEED_SORT = {
- "zone", "timezone", "zoneItem", "typeMap", "dayPeriodRule",
+ "zone", "timezone", "zoneItem", "typeMap", "dayPeriodRule", "pluralRanges",
"pluralRules", "personList", "calendarPreferenceData", "character-fallback", "types", "timeData", "minDays",
"firstDay", "weekendStart", "weekendEnd", "measurementData", "measurementSystem"
};
@@ -362,7 +375,7 @@
* done by transforming the path. Following rules covers these kind of
* transformation.
* Note: It is important to keep the order for these rules. Whenever a
- * rule matches, further rule won't be applied.
+ * rule matches, further rules won't be applied.
*/
public static final PathTransformSpec PATH_TRANSFORMATIONS[] = {
// Add "standard" as type attribute to exemplarCharacter element if there
@@ -401,6 +414,16 @@
new PathTransformSpec("(.*)/types/type\\[@key=\"([^\"]*)\"\\]\\[@type=\"([^\"]*)\"\\](.*)$",
"$1/types/$2/$3$4"),
+ // Typographic
+ new PathTransformSpec("(.*)/(typographicNames)/(axisName|featureName)\\[@type=\"([^\"]*)\"\\](.*)$",
+ "$1/$2/$3s/$4$5"),
+ new PathTransformSpec("(.*)/(typographicNames)/(styleName)(.*)$",
+ "$1/$2/$3s/$3$4"),
+
+ // put CharacterLabelPatterns under CharacterLabelPatterns
+ new PathTransformSpec("(.*)/(characterLabels)/(characterLabelPattern)(.*)$",
+ "$1/characterLabelPatterns/$3$4"),
+
new PathTransformSpec(
"(.*/numbers/(decimal|scientific|percent|currency)Formats\\[@numberSystem=\"([^\"]*)\"\\])/(decimal|scientific|percent|currency)FormatLength/(decimal|scientific|percent|currency)Format\\[@type=\"standard\"]/pattern.*$",
"$1/standard"),
@@ -438,5 +461,12 @@
new PathTransformSpec("(.*)/weekData/(.*)\\[@alt=\"variant\"\\](.*)", "$1/weekData/$2$3"),
new PathTransformSpec("(.*)/unitPreferenceData/unitPreferences\\[@category=\"([^\"]*)\"\\]\\[@usage=\"([^\"]*)\"\\](.*)",
"$1/unitPreferenceData/unitPreferences/$2/$3$4"),
+
+ // Annotations
+ // If there is a type, move that into a sibling value
+ new PathTransformSpec("(.*)/(annotations)/(annotation)\\[@cp=\"([^\"]*)\"\\]\\[@type=\"([^\"]*)\"\\](.*)$",
+ "$1/$2/$4/$5$6"),
+ new PathTransformSpec("(.*)/(annotations)/(annotation)\\[@cp=\"([^\"]*)\"\\](.*)$",
+ "$1/$2/$4/default$5"),
};
}
diff --git a/tools/java/org/unicode/cldr/posix/GenerateCharmap.java b/tools/java/org/unicode/cldr/posix/GenerateCharmap.java
index ca3be9b..ebb2637 100644
--- a/tools/java/org/unicode/cldr/posix/GenerateCharmap.java
+++ b/tools/java/org/unicode/cldr/posix/GenerateCharmap.java
@@ -69,6 +69,7 @@
CharacterAltName = "";
}
+ @Override
public int compareTo(Object o) {
CharmapLine c = (CharmapLine) o;
return (CharacterValue.compareTo(c.CharacterValue));
@@ -136,7 +137,7 @@
int LongestCharNameLength = 0;
int LongestCharValueLength = 0;
UnicodeSet us = new UnicodeSet("[^[:Noncharacter_Code_Point:][:Cn:][:Cs:]]").retainAll(chars);
- List<CharmapLine> cml = new ArrayList<CharmapLine>();
+ List<CharmapLine> cml = new ArrayList<>();
CharmapLine current;
for (UnicodeSetIterator it = new UnicodeSetIterator(us); it.next();) {
String Name = POSIXUtilities.POSIXCharFullName(it.getString());
diff --git a/tools/java/org/unicode/cldr/posix/POSIXUtilities.java b/tools/java/org/unicode/cldr/posix/POSIXUtilities.java
index 048df43..de67258 100644
--- a/tools/java/org/unicode/cldr/posix/POSIXUtilities.java
+++ b/tools/java/org/unicode/cldr/posix/POSIXUtilities.java
@@ -23,7 +23,7 @@
private static UnicodeSet repertoire = new UnicodeSet(0x0000, 0x10FFFF);
private static CLDRFile char_fallbk;
- private static Map<Integer, String> controlCodeNames = new HashMap<Integer, String>();
+ private static Map<Integer, String> controlCodeNames = new HashMap<>();
// Since UCharacter.getExtendedName() in ICU doesn't provide the names for control characters
// we have to force the issue here. Required elements for the POSIX portable character set will be
diff --git a/tools/java/org/unicode/cldr/posix/POSIX_LCCollate.java b/tools/java/org/unicode/cldr/posix/POSIX_LCCollate.java
index 7bb7d91..3fbcdc8 100644
--- a/tools/java/org/unicode/cldr/posix/POSIX_LCCollate.java
+++ b/tools/java/org/unicode/cldr/posix/POSIX_LCCollate.java
@@ -173,9 +173,9 @@
}
}
- Set<Weights> nonUniqueWeights = new HashSet<Weights>();
- Set<Weights> allWeights = new HashSet<Weights>();
- Map<String, Weights> stringToWeights = new HashMap<String, Weights>();
+ Set<Weights> nonUniqueWeights = new HashSet<>();
+ Set<Weights> allWeights = new HashSet<>();
+ Map<String, Weights> stringToWeights = new HashMap<>();
private void writeList(PrintWriter out) {
// BitSet alreadySeen = new BitSet();
@@ -287,6 +287,7 @@
}
}
+ @Override
public boolean equals(Object other) {
Weights that = (Weights) other;
return primaries.equals(that.primaries)
@@ -294,6 +295,7 @@
&& tertiaries.equals(that.tertiaries);
}
+ @Override
public int hashCode() {
return (primaries.hashCode() * 37
+ secondaries.hashCode()) * 37
@@ -320,6 +322,7 @@
s.set(weights[j]);
}
+ @Override
public String toString() {
if (count == 0) return "IGNORE";
if (count == 1) return getID('X', weights[0]);
@@ -330,6 +333,7 @@
return result + "\"";
}
+ @Override
public boolean equals(Object other) {
WeightList that = (WeightList) other;
for (int j = 0; j < count; ++j) {
@@ -338,6 +342,7 @@
return true;
}
+ @Override
public int hashCode() {
int result = count;
for (int j = 0; j < count; ++j)
diff --git a/tools/java/org/unicode/cldr/test/BuildIcuCompactDecimalFormat.java b/tools/java/org/unicode/cldr/test/BuildIcuCompactDecimalFormat.java
index afa5c9f..eef66c1 100644
--- a/tools/java/org/unicode/cldr/test/BuildIcuCompactDecimalFormat.java
+++ b/tools/java/org/unicode/cldr/test/BuildIcuCompactDecimalFormat.java
@@ -57,8 +57,8 @@
}
public static Map<String, Map<String, String>> buildCustomData(CLDRFile resolvedCldrFile, CompactStyle style, CurrencyStyle currencyStyle) {
-
- final Map<String, Map<String, String>> customData = new TreeMap<String, Map<String, String>>();
+
+ final Map<String, Map<String, String>> customData = new TreeMap<>();
String prefix = currencyStyle == CurrencyStyle.PLAIN ? "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength"
: "//ldml/numbers/currencyFormats[@numberSystem=\"latn\"]/currencyFormatLength";
@@ -116,6 +116,6 @@
String currencySymbol = cldrFile.getWinningValue(prefix + "symbol");
return currencySymbol != null ? currencySymbol : currencyCode;
}
- };
+ }
}
diff --git a/tools/java/org/unicode/cldr/test/CLDRTest.java b/tools/java/org/unicode/cldr/test/CLDRTest.java
index ea1c261..bf0b452 100644
--- a/tools/java/org/unicode/cldr/test/CLDRTest.java
+++ b/tools/java/org/unicode/cldr/test/CLDRTest.java
@@ -6,6 +6,8 @@
*/
package org.unicode.cldr.test;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPath;
+
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@@ -30,6 +32,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.LanguageTagParser;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.TimezoneFormatter;
@@ -75,10 +78,10 @@
"[[:script=common:][:script=inherited:][:alphabetic=false:]]");
private static final String[] WIDTHS = { "narrow", "wide", "abbreviated", "short" };
private static final String[] MONTHORDAYS = { "day", "month" };
- private Map<String, String> localeNameCache = new HashMap<String, String>();
+ private Map<String, String> localeNameCache = new HashMap<>();
private CLDRFile english = null;
- private Set<String> surveyInfo = new TreeSet<String>();
+ private Set<String> surveyInfo = new TreeSet<>();
/**
* TestFmwk boilerplate
@@ -172,8 +175,8 @@
public void TestCommonChildren() {
if (disableUntilLater("TestCommonChildren")) return;
- Map<String, ValueCount> currentValues = new TreeMap<String, ValueCount>();
- Set<String> okValues = new TreeSet<String>();
+ Map<String, ValueCount> currentValues = new TreeMap<>();
+ Set<String> okValues = new TreeSet<>();
for (String parent : languageLocales) {
logln("Testing: " + parent);
@@ -236,7 +239,7 @@
public void TestThatExemplarsContainAll() {
UnicodeSet allExemplars = new UnicodeSet();
if (disableUntilLater("TestThatExemplarsContainAll")) return;
- Set<String> counts = new TreeSet<String>();
+ Set<String> counts = new TreeSet<>();
int totalCount = 0;
UnicodeSet localeMissing = new UnicodeSet();
for (String locale : locales) {
@@ -421,8 +424,8 @@
*/
public void TestForIllegalAttributeValues() {
// check for illegal attribute values that are not in the DTD
- Map<String, Set<String>> result = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> totalResult = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> result = new TreeMap<>();
+ Map<String, Set<String>> totalResult = new TreeMap<>();
for (String locale : locales) {
logln("Testing: " + locale);
CLDRFile item = cldrFactory.make(locale, false);
@@ -442,7 +445,7 @@
Set<String> avalues = result.get(code);
errln(getLocaleAndName(locale) + "\tillegal attribute value for " + code + ", value:\t" + show(avalues));
Set<String> totalvalues = totalResult.get(code);
- if (totalvalues == null) totalResult.put(code, totalvalues = new TreeSet<String>());
+ if (totalvalues == null) totalResult.put(code, totalvalues = new TreeSet<>());
totalvalues.addAll(avalues);
}
}
@@ -463,9 +466,9 @@
Map<String, String>[] maps = new HashMap[CLDRFile.LIMIT_TYPES];
for (int i = 0; i < maps.length; ++i) {
- maps[i] = new HashMap<String, String>();
+ maps[i] = new HashMap<>();
}
- Set<String> collisions = new TreeSet<String>();
+ Set<String> collisions = new TreeSet<>();
for (Iterator<String> it = locales.iterator(); it.hasNext();) {
String locale = it.next();
CLDRFile item = cldrFactory.make(locale, true);
@@ -575,7 +578,7 @@
if (results == null) return;
Set<String> s = results.get(code);
if (s == null) {
- s = new TreeSet<String>();
+ s = new TreeSet<>();
results.put(code, s);
}
s.add(avalue);
@@ -616,8 +619,8 @@
private void checkTranslatedCode(CLDRFile cldrfile, StandardCodes codes, String type, String prefix, String postfix) {
// TODO, expand to other languages
- Map<String, Set<String>> completionExceptions = new HashMap<String, Set<String>>();
- Set<String> scriptExceptions = new HashSet<String>();
+ Map<String, Set<String>> completionExceptions = new HashMap<>();
+ Set<String> scriptExceptions = new HashSet<>();
scriptExceptions.add("Cham");
scriptExceptions.add("Thai");
completionExceptions.put("script", scriptExceptions);
@@ -710,7 +713,7 @@
if (scripts == null)
language_scripts.put(language, new TreeSet<String>());
else {
- language_scripts.put(language, new TreeSet<String>(CldrUtility.splitList(scripts, ' ', true)));
+ language_scripts.put(language, new TreeSet<>(CldrUtility.splitList(scripts, ' ', true)));
if (SHOW)
System.out.println(getIDAndLocalization(language) + "\t\t"
+ getIDAndLocalization(language_scripts.get(language)));
@@ -719,7 +722,7 @@
if (territories == null)
language_territories.put(language, new TreeSet<String>());
else {
- language_territories.put(language, new TreeSet<String>(CldrUtility.splitList(territories, ' ', true)));
+ language_territories.put(language, new TreeSet<>(CldrUtility.splitList(territories, ' ', true)));
if (SHOW)
System.out.println(getIDAndLocalization(language) + "\t\t"
+ getIDAndLocalization(language_territories.get(language)));
@@ -737,8 +740,8 @@
if (disableUntilLater("TestMinimalLocalization")) return;
boolean testDraft = false;
- Map<String, Set<String>> language_scripts = new HashMap<String, Set<String>>();
- Map<String, Set<String>> language_territories = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> language_scripts = new HashMap<>();
+ Map<String, Set<String>> language_territories = new HashMap<>();
getSupplementalData(language_scripts, language_territories, null, null, null);
LanguageTagParser localIDParser = new LanguageTagParser();
// see http://oss.software.ibm.com/cvs/icu/~checkout~/locale/docs/design/minimal_requirements.htm
@@ -762,7 +765,7 @@
String language = localIDParser.getLanguage();
logln("Testing: " + locale);
// languages
- Set<String> languages = new TreeSet<String>(CldrUtility.MINIMUM_LANGUAGES);
+ Set<String> languages = new TreeSet<>(CldrUtility.MINIMUM_LANGUAGES);
languages.add(language);
// LANGUAGE_NAME = 0, SCRIPT_NAME = 1, TERRITORY_NAME = 2, VARIANT_NAME = 3,
// CURRENCY_NAME = 4, CURRENCY_SYMBOL = 5, TZID = 6
@@ -775,18 +778,18 @@
* checkTranslatedCode(cldrfile, codes, "variant", "//ldml/localeDisplayNames/variants/variant");
*/
- Set<String> scripts = new TreeSet<String>();
+ Set<String> scripts = new TreeSet<>();
scripts.add("Latn");
Set<String> others = language_scripts.get(language);
if (others != null) scripts.addAll(others);
checkForItems(item, scripts, CLDRFile.SCRIPT_NAME, missing, failureCount, null);
- Set<String> countries = new TreeSet<String>(CldrUtility.MINIMUM_TERRITORIES);
+ Set<String> countries = new TreeSet<>(CldrUtility.MINIMUM_TERRITORIES);
others = language_territories.get(language);
if (others != null) countries.addAll(others);
checkForItems(item, countries, CLDRFile.TERRITORY_NAME, missing, failureCount, null);
- Set<String> currencies = new TreeSet<String>();
+ Set<String> currencies = new TreeSet<>();
StandardCodes sc = StandardCodes.make();
for (Iterator<String> it2 = countries.iterator(); it2.hasNext();) {
String country = it2.next();
@@ -801,10 +804,10 @@
checkForItems(item, currencies, CLDRFile.CURRENCY_SYMBOL, missing, failureCount, exemplars);
// context=format and width=wide; context=stand-alone & width=abbreviated
- Set<String> months = new TreeSet<String>();
+ Set<String> months = new TreeSet<>();
for (int i = 1; i <= 12; ++i)
months.add(i + "");
- Set<String> days = new TreeSet<String>(Arrays.asList(new String[] { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }));
+ Set<String> days = new TreeSet<>(Arrays.asList(new String[] { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }));
for (int i = -7; i < 0; ++i) {
checkForItems(item, (i < -4 ? months : days), i, missing, failureCount, null);
}
@@ -816,7 +819,7 @@
out.close();
// String s = getIDAndLocalization(missing);
String message = "missing localizations, creating file"
- + new File(CLDRPaths.GEN_DIRECTORY + "missing/", filename).getCanonicalPath();
+ + getNormalizedPath(CLDRPaths.GEN_DIRECTORY, "missing", filename);
if (failureCount[0] > 0)
warnln(getLocaleAndName(locale) + "\t" + message);
else
@@ -906,6 +909,7 @@
*/
CldrUtility.CollectionTransform EnglishName = new CldrUtility.CollectionTransform() {
+ @Override
public Object transform(Object source) {
// TODO Auto-generated method stub
return getLocalization(source.toString()) + " (" + source + ")";
@@ -913,6 +917,7 @@
};
CldrUtility.CollectionTransform EnglishCurrencyName = new CldrUtility.CollectionTransform() {
+ @Override
public Object transform(Object source) {
if (english == null) english = cldrFactory.make("en", true);
return english.getName("currency", source.toString()) + " (" + source + ")";
@@ -924,13 +929,13 @@
*
*/
public void TestSupplementalData() {
- Map<String, Set<String>> language_scripts = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> language_territories = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> groups = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> territory_currencies = new TreeMap<String, Set<String>>();
- Map<String, Map<String, String>> aliases = new TreeMap<String, Map<String, String>>();
+ Map<String, Set<String>> language_scripts = new TreeMap<>();
+ Map<String, Set<String>> language_territories = new TreeMap<>();
+ Map<String, Set<String>> groups = new TreeMap<>();
+ Map<String, Set<String>> territory_currencies = new TreeMap<>();
+ Map<String, Map<String, String>> aliases = new TreeMap<>();
getSupplementalData(language_scripts, language_territories, groups, territory_currencies, aliases);
- Set<String> sTerritories = new TreeSet<String>();
+ Set<String> sTerritories = new TreeSet<>();
for (Iterator<Set<String>> it = language_territories.values().iterator(); it.hasNext();) {
sTerritories.addAll(it.next());
}
@@ -938,7 +943,7 @@
Set<String> fullTerritories = sc.getAvailableCodes("territory");
Set<String> fullLanguages = sc.getAvailableCodes("language");
- Set<String> allLanguages = new TreeSet<String>(language_scripts.keySet());
+ Set<String> allLanguages = new TreeSet<>(language_scripts.keySet());
allLanguages.addAll(language_territories.keySet());
for (Iterator<String> it = allLanguages.iterator(); it.hasNext();) {
Object language = it.next();
@@ -949,7 +954,7 @@
+ " territories: " + EnglishName.transform(territories));
}
- Map<String, String> changedLanguage = new TreeMap<String, String>();
+ Map<String, String> changedLanguage = new TreeMap<>();
for (Iterator<String> it = fullLanguages.iterator(); it.hasNext();) {
String code = it.next();
List<String> data = sc.getFullData("language", code);
@@ -965,8 +970,8 @@
}
// remove private use, deprecated, groups
- Set<String> standardTerritories = new TreeSet<String>();
- Map<String, String> changedTerritory = new TreeMap<String, String>();
+ Set<String> standardTerritories = new TreeSet<>();
+ Map<String, String> changedTerritory = new TreeMap<>();
for (Iterator<String> it = fullTerritories.iterator(); it.hasNext();) {
String code = it.next();
if (code.equals("200")) continue; // || code.equals("YU") || code.equals("PZ")
@@ -981,12 +986,12 @@
standardTerritories.removeAll(groups.keySet());
if (!standardTerritories.containsAll(sTerritories)) {
- TreeSet<String> extras = new TreeSet<String>(sTerritories);
+ TreeSet<String> extras = new TreeSet<>(sTerritories);
extras.removeAll(standardTerritories);
errln("Supplemental Language Territories contain illegal values: " + EnglishName.transform(extras));
}
if (!sTerritories.containsAll(standardTerritories)) {
- TreeSet<String> extras = new TreeSet<String>(standardTerritories);
+ TreeSet<String> extras = new TreeSet<>(standardTerritories);
extras.removeAll(sTerritories);
warnln("Missing Language Territories: " + EnglishName.transform(extras));
}
@@ -994,26 +999,26 @@
// now test currencies
logln("Check that no illegal territories are used");
if (!standardTerritories.containsAll(territory_currencies.keySet())) {
- TreeSet<String> extras = new TreeSet<String>(territory_currencies.keySet());
+ TreeSet<String> extras = new TreeSet<>(territory_currencies.keySet());
extras.removeAll(fullTerritories);
if (extras.size() != 0) errln("Currency info -- Illegal Territories: " + EnglishName.transform(extras));
- extras = new TreeSet<String>(territory_currencies.keySet());
+ extras = new TreeSet<>(territory_currencies.keySet());
extras.retainAll(fullTerritories);
extras.removeAll(standardTerritories);
if (extras.size() != 0) warnln("Currency info -- Archaic Territories: " + EnglishName.transform(extras));
}
logln("Check that no territories are missing");
if (!territory_currencies.keySet().containsAll(standardTerritories)) {
- TreeSet<String> extras = new TreeSet<String>(standardTerritories);
+ TreeSet<String> extras = new TreeSet<>(standardTerritories);
extras.removeAll(territory_currencies.keySet());
errln("Currency info -- Missing Territories: " + EnglishName.transform(extras));
}
- Set<String> currencies = new TreeSet<String>();
+ Set<String> currencies = new TreeSet<>();
for (Iterator<Set<String>> it = territory_currencies.values().iterator(); it.hasNext();) {
currencies.addAll(it.next());
}
logln("Check that no illegal currencies are used");
- Set<String> legalCurrencies = new TreeSet<String>(sc.getAvailableCodes("currency"));
+ Set<String> legalCurrencies = new TreeSet<>(sc.getAvailableCodes("currency"));
// first remove non-ISO
for (Iterator<String> it = legalCurrencies.iterator(); it.hasNext();) {
String code = it.next();
@@ -1021,22 +1026,22 @@
if ("X".equals(data.get(3))) it.remove();
}
if (!legalCurrencies.containsAll(currencies)) {
- TreeSet<String> extras = new TreeSet<String>(currencies);
+ TreeSet<String> extras = new TreeSet<>(currencies);
extras.removeAll(legalCurrencies);
errln("Currency info -- Illegal Currencies: " + EnglishCurrencyName.transform(extras));
}
logln("Check that there are no missing currencies");
if (!currencies.containsAll(legalCurrencies)) {
- TreeSet<String> extras = new TreeSet<String>(legalCurrencies);
+ TreeSet<String> extras = new TreeSet<>(legalCurrencies);
extras.removeAll(currencies);
- Map<String, Set<String>> failures = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> failures = new TreeMap<>();
for (Iterator<String> it = extras.iterator(); it.hasNext();) {
String code = it.next();
List<String> data = sc.getFullData("currency", code);
if (data.get(1).equals("ZZ")) continue;
String type = data.get(3) + "/" + data.get(1);
Set<String> s = failures.get(type);
- if (s == null) failures.put(type, s = new TreeSet<String>());
+ if (s == null) failures.put(type, s = new TreeSet<>());
s.add(code);
}
for (Iterator<String> it = failures.keySet().iterator(); it.hasNext();) {
@@ -1118,14 +1123,14 @@
}
logln("Checking that all links are TO canonical zones");
- Set<String> s = new TreeSet<String>(old_new.values());
+ Set<String> s = new TreeSet<>(old_new.values());
s.removeAll(core);
if (s.size() != 0) {
errln("Links go TO zones that are not canonical! " + s);
}
logln("Checking that no links are FROM canonical zones");
- s = new TreeSet<String>(core);
+ s = new TreeSet<>(core);
s.retainAll(old_new.keySet());
if (s.size() != 0) {
errln("Links go FROM zones that are canonical! " + s);
@@ -1149,7 +1154,7 @@
String oldItem = it.next();
logln("old: " + oldItem + "\tnew: " + old_new.get(oldItem));
}
- Map<String, Set<String>> new_old = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> new_old = new TreeMap<>();
for (Iterator<String> it = core.iterator(); it.hasNext();) {
new_old.put(it.next(), new TreeSet<String>());
}
diff --git a/tools/java/org/unicode/cldr/test/CasingInfo.java b/tools/java/org/unicode/cldr/test/CasingInfo.java
index 1dd0098..22c0435 100644
--- a/tools/java/org/unicode/cldr/test/CasingInfo.java
+++ b/tools/java/org/unicode/cldr/test/CasingInfo.java
@@ -50,7 +50,7 @@
private List<File> casingDirs;
public CasingInfo(Factory factory) {
- casingDirs = new ArrayList<File>();
+ casingDirs = new ArrayList<>();
for (File f : factory.getSourceDirectories()) {
this.casingDirs.add(new File(f.getAbsolutePath() + "/../casing"));
}
@@ -61,7 +61,7 @@
* ONLY usable in command line tests.
*/
public CasingInfo() {
- casingDirs = new ArrayList<File>();
+ casingDirs = new ArrayList<>();
this.casingDirs.add(new File(CLDRPaths.CASING_DIRECTORY));
casing = CldrUtility.newConcurrentHashMap();
}
@@ -122,10 +122,10 @@
Set<String> defaultContentLocales = supplementalDataInfo.getDefaultContentLocales();
String sourceDirectory = CldrUtility.checkValidDirectory(CLDRPaths.MAIN_DIRECTORY);
Factory cldrFactory = Factory.make(sourceDirectory, localePattern);
- Set<String> locales = new LinkedHashSet<String>(cldrFactory.getAvailable());
+ Set<String> locales = new LinkedHashSet<>(cldrFactory.getAvailable());
locales.removeAll(defaultContentLocales); // Skip all default content locales
UnicodeSet allCaps = new UnicodeSet("[:Lu:]");
- Map<String, Boolean> localeUsesCasing = new HashMap<String, Boolean>();
+ Map<String, Boolean> localeUsesCasing = new HashMap<>();
LocaleIDParser parser = new LocaleIDParser();
for (String localeID : locales) {
@@ -199,7 +199,7 @@
private void createCasingXml(String localeID, Map<Category, CasingType> localeCasing) {
// Load any existing overrides over casing info.
CasingHandler handler = loadFromXml(localeID);
- Map<Category, CasingType> overrides = handler == null ? new EnumMap<Category, CasingType>(Category.class) : handler.getOverrides();
+ Map<Category, CasingType> overrides = handler == null ? new EnumMap<>(Category.class) : handler.getOverrides();
localeCasing.putAll(overrides);
XMLSource source = new SimpleXMLSource(localeID);
@@ -247,8 +247,8 @@
private class CasingHandler extends XMLFileReader.SimpleHandler {
private Pattern localePattern = PatternCache.get("//ldml/identity/language\\[@type=\"(\\w+)\"\\]");
private String localeID;
- private Map<Category, CasingTypeAndErrFlag> caseMap = new EnumMap<Category, CasingTypeAndErrFlag>(Category.class);
- private Map<Category, CasingType> overrideMap = new EnumMap<Category, CasingType>(Category.class);
+ private Map<Category, CasingTypeAndErrFlag> caseMap = new EnumMap<>(Category.class);
+ private Map<Category, CasingType> overrideMap = new EnumMap<>(Category.class);
@Override
public void handlePathValue(String path, String value) {
diff --git a/tools/java/org/unicode/cldr/test/CheckAlt.java b/tools/java/org/unicode/cldr/test/CheckAlt.java
index 581fb20..23c3707 100644
--- a/tools/java/org/unicode/cldr/test/CheckAlt.java
+++ b/tools/java/org/unicode/cldr/test/CheckAlt.java
@@ -9,10 +9,11 @@
public class CheckAlt extends CheckCLDR {
- Set<String> seenSoFar = new HashSet<String>();
+ Set<String> seenSoFar = new HashSet<>();
// determine if we have an alt=...proposed
// if we have one, and there is not a non-proposed version -- in this same file, unaliased, there's a problem.
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
if (fullPath == null) return this; // skip paths that we don't have
diff --git a/tools/java/org/unicode/cldr/test/CheckAttributeValues.java b/tools/java/org/unicode/cldr/test/CheckAttributeValues.java
index bd15a32..209b0fb 100644
--- a/tools/java/org/unicode/cldr/test/CheckAttributeValues.java
+++ b/tools/java/org/unicode/cldr/test/CheckAttributeValues.java
@@ -13,6 +13,7 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
@@ -33,7 +34,6 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities.ObjectMatcher;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -41,21 +41,21 @@
public class CheckAttributeValues extends FactoryCheckCLDR {
- private static final ObjectMatcher<String> NOT_DONE_YET = new RegexMatcher().set(".*", Pattern.COMMENTS);
+ private static final Predicate<String> NOT_DONE_YET = new RegexMatcher().set(".*", Pattern.COMMENTS);
private static final boolean FIND_MISSING = CldrUtility.getProperty("FIND_MISSING_ATTRIBUTE_TESTS", false); // turn on to show <attributeValues> that are missing.
private static final boolean SHOW_UNNECESSARY = false; // turn on to show <attributeValues> we should delete.
- static LinkedHashSet<String> elementOrder = new LinkedHashSet<String>();
- static LinkedHashSet<String> attributeOrder = new LinkedHashSet<String>();
- static LinkedHashSet<String> serialElements = new LinkedHashSet<String>();
- static Map<String, Map<String, MatcherPattern>> element_attribute_validity = new HashMap<String, Map<String, MatcherPattern>>();
- static Map<String, MatcherPattern> common_attribute_validity = new HashMap<String, MatcherPattern>();
- static Map<String, MatcherPattern> variables = new HashMap<String, MatcherPattern>();
+ static LinkedHashSet<String> elementOrder = new LinkedHashSet<>();
+ static LinkedHashSet<String> attributeOrder = new LinkedHashSet<>();
+ static LinkedHashSet<String> serialElements = new LinkedHashSet<>();
+ static Map<String, Map<String, MatcherPattern>> element_attribute_validity = new HashMap<>();
+ static Map<String, MatcherPattern> common_attribute_validity = new HashMap<>();
+ static Map<String, MatcherPattern> variables = new HashMap<>();
// static VariableReplacer variableReplacer = new VariableReplacer(); // note: this can be coalesced with the above
// -- to do later.
static boolean initialized = false;
static LocaleMatcher localeMatcher;
- static Map<String, Map<String, String>> code_type_replacement = new TreeMap<String, Map<String, String>>();
+ static Map<String, Map<String, String>> code_type_replacement = new TreeMap<>();
static final SupplementalDataInfo supplementalData = CLDRConfig.getInstance().getSupplementalDataInfo();
static DtdData ldmlDtdData = DtdData.getInstance(DtdType.ldml);
@@ -69,12 +69,14 @@
super(factory);
}
+ @Override
public void handleFinish() {
for (Entry<String, Set<String>> entry : missingTests.keyValuesSet()) {
System.out.println("Missing element: " + entry.getKey() + ", attributes: " + entry.getValue());
}
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
if (fullPath == null) return this; // skip paths that we don't have
@@ -191,7 +193,7 @@
if (matcherPattern == null) {
return false; // no test
}
- if (matcherPattern.matcher.matches(attributeValue)) {
+ if (matcherPattern.matcher.test(attributeValue)) {
return true;
}
// special check for deprecated codes
@@ -261,7 +263,7 @@
localeMatcher = LocaleMatcher.make();
}
}
- if (!localeMatcher.matches(cldrFileToCheck.getLocaleID())) {
+ if (!localeMatcher.test(cldrFileToCheck.getLocaleID())) {
possibleErrors.add(new CheckStatus()
.setCause(this).setMainType(CheckStatus.errorType).setSubtype(Subtype.invalidLocale)
.setMessage("Invalid Locale {0}",
@@ -333,7 +335,7 @@
// System.out.println("\t" + element);
Map<String, MatcherPattern> attribute_validity = element_attribute_validity.get(element);
if (attribute_validity == null) {
- element_attribute_validity.put(element, attribute_validity = new TreeMap<String, MatcherPattern>());
+ element_attribute_validity.put(element, attribute_validity = new TreeMap<>());
}
addAttributes(attributeList, attribute_validity, mp);
}
@@ -420,7 +422,7 @@
result.value = value;
if ("choice".equals(typeAttribute)) {
result.matcher = new CollectionMatcher()
- .set(new HashSet<String>(Arrays.asList(value.trim().split("\\s+"))));
+ .set(new HashSet<>(Arrays.asList(value.trim().split("\\s+"))));
} else if ("bcp47".equals(typeAttribute)) {
result = getBcp47MatcherPattern(value);
} else if ("regex".equals(typeAttribute)) {
@@ -449,74 +451,79 @@
private static class MatcherPattern {
public String value;
- ObjectMatcher<String> matcher;
+ Predicate<String> matcher;
String pattern;
+ @Override
public String toString() {
return matcher.getClass().getName() + "\t" + pattern;
}
}
- public static class RegexMatcher implements ObjectMatcher<String> {
+ public static class RegexMatcher implements Predicate<String> {
private java.util.regex.Matcher matcher;
- public ObjectMatcher<String> set(String pattern) {
+ public Predicate<String> set(String pattern) {
matcher = PatternCache.get(pattern).matcher("");
return this;
}
- public ObjectMatcher<String> set(String pattern, int flags) {
+ public Predicate<String> set(String pattern, int flags) {
matcher = Pattern.compile(pattern, flags).matcher("");
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
matcher.reset(value.toString());
return matcher.matches();
}
}
- public static class CollectionMatcher implements ObjectMatcher<String> {
+ public static class CollectionMatcher implements Predicate<String> {
private Collection<String> collection;
- public ObjectMatcher<String> set(Collection<String> collection) {
+ public Predicate<String> set(Collection<String> collection) {
this.collection = collection;
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
return collection.contains(value);
}
}
- public static class OrMatcher implements ObjectMatcher<String> {
- private ObjectMatcher<String> a;
- private ObjectMatcher<String> b;
+ public static class OrMatcher implements Predicate<String> {
+ private Predicate<String> a;
+ private Predicate<String> b;
- public ObjectMatcher<String> set(ObjectMatcher<String> a, ObjectMatcher<String> b) {
+ public Predicate<String> set(Predicate<String> a, Predicate<String> b) {
this.a = a;
this.b = b;
return this;
}
- public boolean matches(String value) {
- return a.matches(value) || b.matches(value);
+ @Override
+ public boolean test(String value) {
+ return a.test(value) || b.test(value);
}
}
- public static class ListMatcher implements ObjectMatcher<String> {
- private ObjectMatcher<String> other;
+ public static class ListMatcher implements Predicate<String> {
+ private Predicate<String> other;
- public ObjectMatcher<String> set(ObjectMatcher<String> other) {
+ public Predicate<String> set(Predicate<String> other) {
this.other = other;
return this;
}
- public boolean matches(String value) {
+ @Override
+ public boolean test(String value) {
String[] values = value.trim().split("\\s+");
if (values.length == 1 && values[0].length() == 0) return true;
for (int i = 0; i < values.length; ++i) {
- if (!other.matches(values[i])) {
+ if (!other.test(values[i])) {
return false;
}
}
@@ -524,12 +531,12 @@
}
}
- public static class LocaleMatcher implements ObjectMatcher<String> {
- ObjectMatcher<String> grandfathered = variables.get("$grandfathered").matcher;
- ObjectMatcher<String> language = variables.get("$language").matcher;
- ObjectMatcher<String> script = variables.get("$script").matcher;
- ObjectMatcher<String> territory = variables.get("$territory").matcher;
- ObjectMatcher<String> variant = variables.get("$variant").matcher;
+ public static class LocaleMatcher implements Predicate<String> {
+ Predicate<String> legacy = variables.get("$grandfathered").matcher;
+ Predicate<String> language = variables.get("$language").matcher;
+ Predicate<String> script = variables.get("$script").matcher;
+ Predicate<String> territory = variables.get("$territory").matcher;
+ Predicate<String> variant = variables.get("$variant").matcher;
LocaleIDParser lip = new LocaleIDParser();
static LocaleMatcher singleton = null;
static Object sync = new Object();
@@ -546,21 +553,22 @@
return singleton;
}
- public boolean matches(String value) {
- if (grandfathered.matches(value)) return true;
+ @Override
+ public boolean test(String value) {
+ if (legacy.test(value)) return true;
lip.set((String) value);
String field = lip.getLanguage();
- if (!language.matches(field)) return false;
+ if (!language.test(field)) return false;
field = lip.getScript();
- if (field.length() != 0 && !script.matches(field)) return false;
+ if (field.length() != 0 && !script.test(field)) return false;
field = lip.getRegion();
- if (field.length() != 0 && !territory.matches(field)) return false;
+ if (field.length() != 0 && !territory.test(field)) return false;
String[] fields = lip.getVariants();
for (int i = 0; i < fields.length; ++i) {
- if (!variant.matches(fields[i])) return false;
+ if (!variant.test(fields[i])) return false;
}
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/test/CheckCLDR.java b/tools/java/org/unicode/cldr/test/CheckCLDR.java
index e6ee4cc..4bbf23b 100644
--- a/tools/java/org/unicode/cldr/test/CheckCLDR.java
+++ b/tools/java/org/unicode/cldr/test/CheckCLDR.java
@@ -12,7 +12,6 @@
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -43,6 +42,7 @@
import org.unicode.cldr.util.VoteResolver;
import org.unicode.cldr.util.VoteResolver.Status;
+import com.google.common.collect.ImmutableSet;
import com.ibm.icu.dev.util.ElapsedTimer;
import com.ibm.icu.impl.Row.R3;
import com.ibm.icu.text.ListFormatter;
@@ -78,7 +78,7 @@
private boolean skipTest = false;
private Phase phase;
- private Map<Subtype, List<Pattern>> filtersForLocale = new HashMap<Subtype, List<Pattern>>();
+ private Map<Subtype, List<Pattern>> filtersForLocale = new HashMap<>();
public enum InputMethod {
DIRECT, BULK
@@ -104,11 +104,12 @@
/**
* Disallow (for various reasons)
*/
- FORBID_ERRORS(true),
- FORBID_READONLY(true),
- FORBID_UNLESS_DATA_SUBMISSION(true),
+ FORBID_ERRORS(true),
+ FORBID_READONLY(true),
+ FORBID_UNLESS_DATA_SUBMISSION(true),
FORBID_NULL(true),
FORBID_ROOT(true),
+ FORBID_CODE(true),
FORBID_PERMANENT_WITHOUT_FORUM(true);
private final boolean isForbidden;
@@ -130,7 +131,7 @@
}
}
- private static final HashMap<String, Phase> PHASE_NAMES = new HashMap<String, Phase>();
+ private static final HashMap<String, Phase> PHASE_NAMES = new HashMap<>();
public enum Phase {
BUILD, SUBMISSION, VETTING, FINAL_TESTING("RESOLUTION");
@@ -340,7 +341,7 @@
Option() {
this.key = name();
}
- };
+ }
private static StandardCodes sc = StandardCodes.make();
@@ -383,7 +384,7 @@
}
private static String getValidKeys() {
- Set<String> allkeys = new TreeSet<String>();
+ Set<String> allkeys = new TreeSet<>();
for (Option o : Option.values()) {
allkeys.add(o.getKey());
}
@@ -542,7 +543,7 @@
}
return sb.toString();
}
- };
+ }
public boolean isSkipTest() {
return skipTest;
@@ -668,7 +669,7 @@
Subtype subtype = filter.get1();
List<Pattern> xpaths = filtersForLocale.get(subtype);
if (xpaths == null) {
- filtersForLocale.put(subtype, xpaths = new ArrayList<Pattern>());
+ filtersForLocale.put(subtype, xpaths = new ArrayList<>());
}
xpaths.add(filter.get2());
}
@@ -687,47 +688,50 @@
public enum Type {
Comment, Warning, Error, Example, Demo
- };
+ }
public enum Subtype {
- none, noUnproposedVariant, deprecatedAttribute, illegalPlural, invalidLocale, incorrectCasing,
+ none, noUnproposedVariant, deprecatedAttribute, illegalPlural, invalidLocale, incorrectCasing,
valueMustBeOverridden,
- valueAlwaysOverridden, nullChildFile, internalError, coverageLevel, missingPluralInfo,
- currencySymbolTooWide, incorrectDatePattern, abbreviatedDateFieldTooWide, displayCollision,
- illegalExemplarSet, missingAuxiliaryExemplars, extraPlaceholders, missingPlaceholders,
- shouldntHavePlaceholders, couldNotAccessExemplars, noExemplarCharacters, modifiedEnglishValue,
- invalidCurrencyMatchSet, multipleMetazoneMappings, noMetazoneMapping, noMetazoneMappingAfter1970,
- noMetazoneMappingBeforeNow, cannotCreateZoneFormatter, insufficientCoverage, missingLanguageTerritoryInfo,
- missingEuroCountryInfo, deprecatedAttributeWithReplacement, missingOrExtraDateField, internalUnicodeSetFormattingError,
+ valueAlwaysOverridden, nullChildFile, internalError, coverageLevel, missingPluralInfo,
+ currencySymbolTooWide, incorrectDatePattern, abbreviatedDateFieldTooWide, displayCollision,
+ illegalExemplarSet, missingAuxiliaryExemplars, extraPlaceholders, missingPlaceholders,
+ shouldntHavePlaceholders, couldNotAccessExemplars, noExemplarCharacters, modifiedEnglishValue,
+ invalidCurrencyMatchSet, multipleMetazoneMappings, noMetazoneMapping, noMetazoneMappingAfter1970,
+ noMetazoneMappingBeforeNow, cannotCreateZoneFormatter, insufficientCoverage, missingLanguageTerritoryInfo,
+ missingEuroCountryInfo, deprecatedAttributeWithReplacement, missingOrExtraDateField, internalUnicodeSetFormattingError,
auxiliaryExemplarsOverlap, missingPunctuationCharacters,
- charactersNotInCurrencyExemplars, asciiCharactersNotInCurrencyExemplars,
+ charactersNotInCurrencyExemplars, asciiCharactersNotInCurrencyExemplars,
charactersNotInMainOrAuxiliaryExemplars, asciiCharactersNotInMainOrAuxiliaryExemplars,
narrowDateFieldTooWide, illegalCharactersInExemplars, orientationDisagreesWithExemplars,
- inconsistentDatePattern, inconsistentTimePattern, missingDatePattern, illegalDatePattern,
- missingMainExemplars, mustNotStartOrEndWithSpace, illegalCharactersInNumberPattern,
- numberPatternNotCanonical, currencyPatternMissingCurrencySymbol, missingMinusSign,
- badNumericType, percentPatternMissingPercentSymbol, illegalNumberFormat, unexpectedAttributeValue,
- metazoneContainsDigit, tooManyGroupingSeparators, inconsistentPluralFormat, sameAsEnglish, sameAsCode,
- dateSymbolCollision, incompleteLogicalGroup, extraMetazoneString, inconsistentDraftStatus,
- errorOrWarningInLogicalGroup, valueTooWide, valueTooNarrow, nameContainsYear, patternCannotContainDigits,
- patternContainsInvalidCharacters, parenthesesNotAllowed, illegalNumberingSystem, unexpectedOrderOfEraYear,
- invalidPlaceHolder, asciiQuotesNotAllowed, badMinimumGroupingDigits, inconsistentPeriods,
+ inconsistentDatePattern, inconsistentTimePattern, missingDatePattern, illegalDatePattern,
+ missingMainExemplars, mustNotStartOrEndWithSpace, illegalCharactersInNumberPattern,
+ numberPatternNotCanonical, currencyPatternMissingCurrencySymbol, missingMinusSign,
+ badNumericType, percentPatternMissingPercentSymbol, illegalNumberFormat, unexpectedAttributeValue,
+ metazoneContainsDigit, tooManyGroupingSeparators, inconsistentPluralFormat, missingZeros, sameAsEnglish, sameAsCode,
+ dateSymbolCollision, incompleteLogicalGroup, extraMetazoneString, inconsistentDraftStatus,
+ errorOrWarningInLogicalGroup, valueTooWide, valueTooNarrow, nameContainsYear, patternCannotContainDigits,
+ patternContainsInvalidCharacters, parenthesesNotAllowed, illegalNumberingSystem, unexpectedOrderOfEraYear,
+ invalidPlaceHolder, asciiQuotesNotAllowed, badMinimumGroupingDigits, inconsistentPeriods,
inheritanceMarkerNotAllowed, invalidDurationUnitPattern, invalidDelimiter, illegalCharactersInPattern,
- badParseLenient, tooManyValues, invalidSymbol;
+ badParseLenient, tooManyValues, invalidSymbol, invalidGenderCode,
+ mismatchedUnitComponent, longPowerWithSubscripts, gapsInPlaceholderNumbers, duplicatePlaceholders, largerDifferences
+ ;
+ @Override
public String toString() {
return TO_STRING.matcher(name()).replaceAll(" $1").toLowerCase();
}
static Pattern TO_STRING = PatternCache.get("([A-Z])");
- };
+ }
- /**
+ /**
* These error don't prevent entry during submission, since they become valid if a different row is changed.
*/
- public static EnumSet<Subtype> crossCheckSubtypes = EnumSet.of(
+ public static Set<Subtype> crossCheckSubtypes = ImmutableSet.of(
Subtype.dateSymbolCollision,
Subtype.displayCollision,
Subtype.inconsistentDraftStatus,
@@ -737,6 +741,15 @@
Subtype.narrowDateFieldTooWide,
Subtype.coverageLevel);
+ public static Set<Subtype> errorCodesPath = ImmutableSet.of(
+ Subtype.duplicatePlaceholders,
+ Subtype.extraPlaceholders,
+ Subtype.gapsInPlaceholderNumbers,
+ Subtype.invalidPlaceHolder,
+ Subtype.missingPlaceholders,
+ Subtype.shouldntHavePlaceholders);
+
+
private Type type;
private Subtype subtype = Subtype.none;
private String messageFormat;
@@ -774,6 +787,9 @@
String fixedApos = MessageFormat.autoQuoteApostrophe(messageFormat);
MessageFormat format = new MessageFormat(fixedApos);
message = format.format(parameters);
+ if (errorCodesPath.contains(subtype)) {
+ message += "; see <a href='http://cldr.unicode.org/translation/error-codes#" + subtype.name() + "' target='cldr_error_codes'>" + subtype + "</a>.";
+ }
} catch (Exception e) {
message = messageFormat;
System.err.println("MessageFormat Failure: " + subtype + "; " + messageFormat + "; "
@@ -797,6 +813,7 @@
/**
* @deprecated
*/
+ @Deprecated
public String getHTMLMessage() {
return htmlMessage;
}
@@ -804,6 +821,7 @@
/**
* @deprecated
*/
+ @Deprecated
public CheckStatus setHTMLMessage(String message) {
htmlMessage = message;
return this;
@@ -830,6 +848,7 @@
return this;
}
+ @Override
public String toString() {
return getType() + ": " + getMessage();
}
@@ -851,7 +870,7 @@
return null;
}
- List<Exception> errors = new ArrayList<Exception>();
+ List<Exception> errors = new ArrayList<>();
for (Object o : parameters) {
if (o instanceof Exception) {
errors.add((Exception) o);
@@ -926,7 +945,7 @@
}
public static abstract class SimpleDemo {
- Map<String, String> internalPostArguments = new HashMap<String, String>();
+ Map<String, String> internalPostArguments = new HashMap<>();
/**
* @param postArguments
@@ -969,6 +988,7 @@
protected abstract void getArguments(Map<String, String> postArguments);
+ @Override
public String getHTML(Map<String, String> postArguments) throws Exception {
getArguments(postArguments);
StringBuffer htmlMessage = new StringBuffer();
@@ -1086,10 +1106,11 @@
*/
// if (value == cldrFileToCheck.getBaileyValue(path, null, null) && value != cldrFileToCheck.getWinningValue(path)) {
if (value != null
- && value.equals(cldrFileToCheck.getBaileyValue(path, null, null))
- && !value.equals(cldrFileToCheck.getWinningValue(path))) {
- return this;
+ && !value.equals(cldrFileToCheck.getWinningValue(path))
+ && cldrFileToCheck.getUnresolved().getStringValue(path) == null) {
+ return this;
}
+
// If we're being asked to run tests for an inheritance marker, then we need to change it
// to the "real" value first before running tests. Testing the value CldrUtility.INHERITANCE_MARKER ("↑↑↑") doesn't make sense.
if (CldrUtility.INHERITANCE_MARKER.equals(value)) {
@@ -1167,8 +1188,8 @@
*/
static class CompoundCheckCLDR extends CheckCLDR {
private Matcher filter;
- private List<CheckCLDR> checkList = new ArrayList<CheckCLDR>();
- private List<CheckCLDR> filteredCheckList = new ArrayList<CheckCLDR>();
+ private List<CheckCLDR> checkList = new ArrayList<>();
+ private List<CheckCLDR> filteredCheckList = new ArrayList<>();
public CompoundCheckCLDR add(CheckCLDR item) {
checkList.add(item);
@@ -1183,6 +1204,7 @@
return this;
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
result.clear();
@@ -1219,6 +1241,7 @@
}
}
+ @Override
protected CheckCLDR handleGetExamples(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
result.clear();
@@ -1245,6 +1268,7 @@
}));
}
+ @Override
public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options,
List<CheckStatus> possibleErrors) {
ElapsedTimer testTime = null, testOverallTime = null;
@@ -1256,7 +1280,7 @@
possibleErrors.clear();
for (Iterator<CheckCLDR> it = filteredCheckList.iterator(); it.hasNext();) {
- CheckCLDR item = (CheckCLDR) it.next();
+ CheckCLDR item = it.next();
if (SHOW_TIMES)
testTime = new ElapsedTimer("Test setup time for " + item.getClass().toString() + ": {0}");
try {
@@ -1339,7 +1363,7 @@
*/
private void loadFilters() {
if (allFilters != null) return;
- allFilters = new ArrayList<R3<Pattern, Subtype, Pattern>>();
+ allFilters = new ArrayList<>();
RegexFileParser fileParser = new RegexFileParser();
fileParser.setLineParser(new RegexLineParser() {
@Override
@@ -1348,7 +1372,7 @@
Subtype subtype = Subtype.valueOf(fields[0]);
Pattern locale = PatternCache.get(fields[1]);
Pattern xpathRegex = PatternCache.get(fields[2].replaceAll("\\[@", "\\\\[@"));
- allFilters.add(new R3<Pattern, Subtype, Pattern>(locale, subtype, xpathRegex));
+ allFilters.add(new R3<>(locale, subtype, xpathRegex));
}
});
fileParser.parse(CheckCLDR.class, "/org/unicode/cldr/util/data/CheckCLDR-exceptions.txt");
@@ -1381,4 +1405,8 @@
public void setEnglishFile(CLDRFile englishFile) {
this.englishFile = englishFile;
}
+
+ public CharSequence fixedValueIfInherited(String value, String path) {
+ return !CldrUtility.INHERITANCE_MARKER.equals(value) ? value: getCldrFileToCheck().getStringValueWithBailey(path);
+ }
}
diff --git a/tools/java/org/unicode/cldr/test/CheckCasing.java b/tools/java/org/unicode/cldr/test/CheckCasing.java
index 4a16768..067b35b 100644
--- a/tools/java/org/unicode/cldr/test/CheckCasing.java
+++ b/tools/java/org/unicode/cldr/test/CheckCasing.java
@@ -16,7 +16,7 @@
public static Case forString(String input) {
return valueOf(input.replace('-', '_'));
}
- };
+ }
// remember to add this class to the list in CheckCLDR.getCheckAll
// to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*Currencies.*
@@ -35,6 +35,7 @@
}
// If you don't need any file initialization or postprocessing, you only need this one routine
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
// it helps performance to have a quick reject of most paths
diff --git a/tools/java/org/unicode/cldr/test/CheckChildren.java b/tools/java/org/unicode/cldr/test/CheckChildren.java
index 94010c4..41a1a86 100644
--- a/tools/java/org/unicode/cldr/test/CheckChildren.java
+++ b/tools/java/org/unicode/cldr/test/CheckChildren.java
@@ -14,12 +14,13 @@
public class CheckChildren extends FactoryCheckCLDR {
CLDRFile[] immediateChildren;
- Map<String, String> tempSet = new HashMap<String, String>();
+ Map<String, String> tempSet = new HashMap<>();
public CheckChildren(Factory factory) {
super(factory);
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
if (immediateChildren == null) return this; // skip - test isn't even relevant
@@ -71,7 +72,7 @@
return this;
}
- List<CLDRFile> iChildren = new ArrayList<CLDRFile>();
+ List<CLDRFile> iChildren = new ArrayList<>();
super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
CLDRLocale myLocale = CLDRLocale.getInstance(cldrFileToCheck.getLocaleID());
if (myLocale.getCountry() != null && myLocale.getCountry().length() == 2) {
@@ -95,7 +96,7 @@
immediateChildren = null;
else {
immediateChildren = new CLDRFile[iChildren.size()];
- immediateChildren = (CLDRFile[]) iChildren.toArray(immediateChildren);
+ immediateChildren = iChildren.toArray(immediateChildren);
}
return this;
}
diff --git a/tools/java/org/unicode/cldr/test/CheckConsistentCasing.java b/tools/java/org/unicode/cldr/test/CheckConsistentCasing.java
index ff8a5dc..c5d9964 100644
--- a/tools/java/org/unicode/cldr/test/CheckConsistentCasing.java
+++ b/tools/java/org/unicode/cldr/test/CheckConsistentCasing.java
@@ -21,7 +21,7 @@
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.RegexLookup;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.util.ULocale;
@@ -81,6 +81,7 @@
}
// If you don't need any file initialization or postprocessing, you only need this one routine
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
// it helps performance to have a quick reject of most paths
@@ -212,7 +213,7 @@
// ldml/localeDisplayNames/transformNames/transformName[@type=".*"]
;
- Map<Category, CasingTypeAndErrFlag> types = new EnumMap<Category, CasingTypeAndErrFlag>(Category.class);
+ Map<Category, CasingTypeAndErrFlag> types = new EnumMap<>(Category.class);
public enum Category {
language, script, territory, variant, keyValue, month_narrow, month_format_except_narrow, month_standalone_except_narrow, day_narrow, day_format_except_narrow, day_standalone_except_narrow, era_narrow, era_abbr, era_name, quarter_narrow, quarter_abbreviated, quarter_format_wide, quarter_standalone_wide, calendar_field, zone_exemplarCity, zone_short, zone_long, NOT_USED, metazone_short, metazone_long, symbol, currencyName_count, currencyName, relative, unit_pattern, key;
@@ -235,14 +236,14 @@
*/
public static Map<Category, CasingType> getSamples(CLDRFile resolved) {
// Use EnumMap instead of an array for type safety.
- Map<Category, Counter<CasingType>> counters = new EnumMap<Category, Counter<CasingType>>(Category.class);
+ Map<Category, Counter<CasingType>> counters = new EnumMap<>(Category.class);
for (Category category : Category.values()) {
counters.put(category, new Counter<CasingType>());
}
PathStarrer starrer = new PathStarrer();
boolean isRoot = "root".equals(resolved.getLocaleID());
- Set<String> missing = !DEBUG ? null : new TreeSet<String>();
+ Set<String> missing = !DEBUG ? null : new TreeSet<>();
for (String path : resolved) {
if (!isRoot) {
@@ -267,7 +268,7 @@
}
}
- Map<Category, CasingType> info = new EnumMap<Category, CasingType>(Category.class);
+ Map<Category, CasingType> info = new EnumMap<>(Category.class);
for (Category category : Category.values()) {
if (category == Category.NOT_USED) continue;
Counter<CasingType> counter = counters.get(category);
@@ -287,7 +288,7 @@
info.put(category, type);
}
if (DEBUG && missing.size() != 0) {
- System.out.println("Paths skipped:\n" + CollectionUtilities.join(missing, "\n"));
+ System.out.println("Paths skipped:\n" + Joiner.on("\n").join(missing));
}
return info;
}
diff --git a/tools/java/org/unicode/cldr/test/CheckCoverage.java b/tools/java/org/unicode/cldr/test/CheckCoverage.java
index 39fbd94..03b2a9b 100644
--- a/tools/java/org/unicode/cldr/test/CheckCoverage.java
+++ b/tools/java/org/unicode/cldr/test/CheckCoverage.java
@@ -50,6 +50,7 @@
super(factory);
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
@@ -68,11 +69,11 @@
}
Status status = new Status();
-
+
/*
* Need skipInheritanceMarker false for getSourceLocaleIdExtended here.
* Reference: https://unicode.org/cldr/trac/ticket/11720
- *
+ *
* Compare same change in getMissingStatus for https://unicode.org/cldr/trac/ticket/11765
*/
String source = resolvedCldrFileToCheck.getSourceLocaleIdExtended(path, status, false /* skipInheritanceMarker */);
diff --git a/tools/java/org/unicode/cldr/test/CheckCurrencies.java b/tools/java/org/unicode/cldr/test/CheckCurrencies.java
index 42ac069..382a51b 100644
--- a/tools/java/org/unicode/cldr/test/CheckCurrencies.java
+++ b/tools/java/org/unicode/cldr/test/CheckCurrencies.java
@@ -11,6 +11,7 @@
// to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*Currencies.*
// If you don't need any file initialization or postprocessing, you only need this one routine
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
// it helps performance to have a quick reject of most paths
diff --git a/tools/java/org/unicode/cldr/test/CheckDates.java b/tools/java/org/unicode/cldr/test/CheckDates.java
index eaa984d..0f1efc3 100644
--- a/tools/java/org/unicode/cldr/test/CheckDates.java
+++ b/tools/java/org/unicode/cldr/test/CheckDates.java
@@ -43,7 +43,7 @@
import org.unicode.cldr.util.XPathParts;
import org.unicode.cldr.util.props.UnicodeProperty.PatternMatcher;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.DateTimePatternGenerator;
@@ -222,6 +222,9 @@
// possibleErrors.add(flexInfo.getFailurePath(path));
}
redundants.clear();
+ /*
+ * TODO: NullPointerException may be thrown in ICU here during cldr-unittest TestAll
+ */
flexInfo.getRedundants(redundants);
// Set baseSkeletons = flexInfo.gen.getBaseSkeletons(new TreeSet());
// Set notCovered = new TreeSet(neededFormats);
@@ -276,7 +279,7 @@
*/
BreakIterator bi;
FlexibleDateFromCLDR flexInfo;
- Collection<String> redundants = new HashSet<String>();
+ Collection<String> redundants = new HashSet<>();
Status status = new Status();
PathStarrer pathStarrer = new PathStarrer();
@@ -293,6 +296,7 @@
return s;
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
@@ -439,7 +443,7 @@
boolean endsWithDisplayName = path.endsWith("displayName"); // special hack, these shouldn't be in
// calendar.
- Set<String> retrievedPaths = new HashSet<String>();
+ Set<String> retrievedPaths = new HashSet<>();
getResolvedCldrFileToCheck().getPathsWithValue(value, calendarPrefix, null, retrievedPaths);
if (retrievedPaths.size() < 2) {
break main;
@@ -458,7 +462,7 @@
// TODO redo above and below in terms of parts instead of searching strings
- Set<String> filteredPaths = new HashSet<String>();
+ Set<String> filteredPaths = new HashSet<>();
Output<Integer> sampleError = new Output<>();
for (String item : retrievedPaths) {
@@ -491,7 +495,7 @@
if (filteredPaths.size() == 0) {
break main;
}
- Set<String> others = new TreeSet<String>();
+ Set<String> others = new TreeSet<>();
for (String path2 : filteredPaths) {
PathHeader pathHeader = getPathHeaderFactory().fromPath(path2);
others.add(pathHeader.getHeaderCode());
@@ -567,7 +571,8 @@
} catch (Exception e) {
// e.printStackTrace();
// HACK
- if (!HACK_CONFLICTING.matcher(e.getMessage()).find()) {
+ String msg = e.getMessage();
+ if (msg == null || !HACK_CONFLICTING.matcher(msg).find()) {
CheckStatus item = new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
.setSubtype(Subtype.illegalDatePattern)
.setMessage("Error in creating date format {0}", new Object[] { e });
@@ -651,18 +656,19 @@
}
private String getValues(CLDRFile resolvedCldrFileToCheck, Collection<String> values) {
- Set<String> results = new TreeSet<String>();
+ Set<String> results = new TreeSet<>();
for (String path : values) {
final String stringValue = resolvedCldrFileToCheck.getStringValue(path);
if (stringValue != null) {
results.add(stringValue);
}
}
- return "{" + CollectionUtilities.join(results, "},{") + "}";
+ return "{" + Joiner.on("},{").join(results) + "}";
}
static final Pattern HACK_CONFLICTING = PatternCache.get("Conflicting fields:\\s+M+,\\s+l");
+ @Override
public CheckCLDR handleGetExamples(String path, String fullPath, String value, Options options, List<CheckStatus> result) {
if (path.indexOf("/dates") < 0 || path.indexOf("gregorian") < 0) return this;
try {
@@ -845,7 +851,7 @@
date, time, dateTime
}
- static final Map<DateOrTime, Relation<DateTimeLengths, String>> STOCK_PATTERNS = new EnumMap<DateOrTime, Relation<DateTimeLengths, String>>(
+ static final Map<DateOrTime, Relation<DateTimeLengths, String>> STOCK_PATTERNS = new EnumMap<>(
DateOrTime.class);
//
@@ -927,7 +933,7 @@
int countMismatches = 0;
boolean errorOnMissing = false;
String timezonePattern = null;
- Set<String> bases = new LinkedHashSet<String>();
+ Set<String> bases = new LinkedHashSet<>();
for (String key : keys) {
int star = key.indexOf('*');
boolean hasStar = star >= 0;
@@ -977,7 +983,7 @@
result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType)
.setSubtype(Subtype.missingDatePattern)
.setMessage(msg,
- dateTimeLength, dateOrTime, value, CollectionUtilities.join(bases, ", ")));
+ dateTimeLength, dateOrTime, value, Joiner.on(", ").join(bases)));
}
}
}
@@ -1000,7 +1006,7 @@
return false;
}
- List<Object> items1 = new ArrayList<Object>(formatParser.set(value1).getItems()); // clone
+ List<Object> items1 = new ArrayList<>(formatParser.set(value1).getItems()); // clone
List<Object> items2 = formatParser.set(value2).getItems();
if (items1.size() != items2.size()) {
return false;
@@ -1022,7 +1028,7 @@
return true;
}
- static final Set<String> YgLanguages = new HashSet<String>(Arrays.asList(
+ static final Set<String> YgLanguages = new HashSet<>(Arrays.asList(
"ar", "cs", "da", "de", "en", "es", "fa", "fi", "fr", "he", "hr", "id", "it", "nb", "nl", "pt", "ru", "sv", "tr"));
private GyState getExpectedGy(String localeID) {
@@ -1056,7 +1062,7 @@
enum DateTimeLengths {
SHORT, MEDIUM, LONG, FULL
- };
+ }
// The patterns below should only use the *canonical* characters for each field type:
// y (not Y, u, U)
@@ -1125,6 +1131,7 @@
return this;
}
+ @Override
public SimpleDemo getDemo() {
return new MyDemo().setFormat(df);
}
@@ -1133,10 +1140,12 @@
static class MyDemo extends FormatDemo {
private SimpleDateFormat df;
+ @Override
protected String getPattern() {
return df.toPattern();
}
+ @Override
protected String getSampleInput() {
return neutralFormat.format(ExampleGenerator.DATE_SAMPLE);
}
@@ -1146,6 +1155,7 @@
return this;
}
+ @Override
protected void getArguments(Map<String, String> inout) {
currentPattern = currentInput = currentFormatted = currentReparsed = "?";
Date d;
@@ -1160,7 +1170,7 @@
return;
}
try {
- currentInput = (String) inout.get("input");
+ currentInput = inout.get("input");
if (currentInput == null) {
currentInput = getSampleInput();
}
diff --git a/tools/java/org/unicode/cldr/test/CheckDisplayCollisions.java b/tools/java/org/unicode/cldr/test/CheckDisplayCollisions.java
index 6ee2f81..e897ace 100644
--- a/tools/java/org/unicode/cldr/test/CheckDisplayCollisions.java
+++ b/tools/java/org/unicode/cldr/test/CheckDisplayCollisions.java
@@ -1,10 +1,11 @@
package org.unicode.cldr.test;
+import java.util.Arrays;
import java.util.Calendar;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -22,13 +23,16 @@
import org.unicode.cldr.util.XMLSource;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
public class CheckDisplayCollisions extends FactoryCheckCLDR {
private static final String DEBUG_PATH_PART = "-mass"; // example: "//ldml/dates/fields/field[@type=\"sun-narrow\"]/relative[@type=\"-1\"]";
/**
* Set to true to get verbose logging of path removals
*/
private static final boolean LOG_PATH_REMOVALS = false;
-
+
/**
* Set to true to prevent "Turkey" from being used for both 🇹🇷 -name and 🦃 -name.
* (Means clients need to use the "flag: Turkey" format.)
@@ -69,15 +73,15 @@
UNITS_COMPOUND_SHORT("//ldml/units/unitLength[@type=\"short\"]/compoundUnit", MatchType.PREFIX),
UNITS_COORDINATE( "//ldml/units/unitLength\\[@type=\".*\"\\]/coordinateUnit/", MatchType.REGEX),
UNITS_IGNORE("//ldml/units/unitLength[@type=\"narrow\"]", MatchType.PREFIX),
- UNITS("//ldml/units/unitLength", MatchType.PREFIX),
+ UNITS("//ldml/units/unitLength.*/(displayName|unitPattern|perUnitPattern)", MatchType.REGEX),
FIELDS_NARROW("//ldml/dates/fields/field\\[@type=\"(sun|mon|tue|wed|thu|fri|sat)-narrow\"\\]/relative", MatchType.REGEX),
FIELDS_RELATIVE("//ldml/dates/fields/field\\[@type=\".*\"\\]/relative\\[@type=\"(-1|0|1)\"\\]", MatchType.REGEX),
ANNOTATIONS("//ldml/annotations/annotation\\[@cp=\".*\"\\]\\[@type=\"tts\"\\]", MatchType.REGEX),
CARDINAL_MINIMAL("//ldml/numbers/minimalPairs/pluralMinimalPairs", MatchType.PREFIX),
- ORDINAL_MINIMAL("//ldml/numbers/minimalPairs/ordinalMinimalPairs", MatchType.PREFIX),
- TYPOGRAPHIC_AXIS("//ldml/typographicNames/axisName", MatchType.PREFIX),
- TYPOGRAPHIC_FEATURE("//ldml/typographicNames/featureName", MatchType.PREFIX),
- TYPOGRAPHIC_STYLE("//ldml/typographicNames/styleName", MatchType.PREFIX),
+ ORDINAL_MINIMAL("//ldml/numbers/minimalPairs/ordinalMinimalPairs", MatchType.PREFIX),
+ TYPOGRAPHIC_AXIS("//ldml/typographicNames/axisName", MatchType.PREFIX),
+ TYPOGRAPHIC_FEATURE("//ldml/typographicNames/featureName", MatchType.PREFIX),
+ TYPOGRAPHIC_STYLE("//ldml/typographicNames/styleName", MatchType.PREFIX),
;
private MatchType matchType;
@@ -131,7 +135,7 @@
private final Matcher exclusions = PatternCache.get("=\"narrow\"]").matcher(""); // no matches
private final Matcher typePattern = PatternCache.get("\\[@type=\"([^\"]*+)\"]").matcher("");
- private final Matcher ignoreAltAndCountAttributes = PatternCache.get("\\[@(?:count|alt)=\"[^\"]*+\"]").matcher("");
+ private final Matcher ignoreAltAndCountAttributes = PatternCache.get("\\[@(?:count|alt|gender|case)=\"[^\"]*+\"]").matcher("");
private final Matcher ignoreAltAttributes = PatternCache.get("\\[@(?:alt)=\"[^\"]*+\"]").matcher("");
private final Matcher ignoreAltShortOrVariantAttributes = PatternCache.get("\\[@(?:alt)=\"(?:short|variant)\"]").matcher("");
private final Matcher compoundUnitPatterns = PatternCache.get("compoundUnitPattern").matcher("");
@@ -141,123 +145,140 @@
private static final Map<String, Set<String>> mapPathPartsToSetsForDupOK = createMapPathPartsToSets();
private static Map<String, Set<String>> createMapPathPartsToSets() {
- Map<String, Set<String>> mapPathPartsToSets = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> mapPathPartsToSets = new HashMap<>();
// Add OK collisions for /unit[@type=\"energy-calorie\"]
- Set<String> set1 = new HashSet<String>();
+ Set<String> set1 = new HashSet<>();
set1.add("/unit[@type=\"energy-foodcalorie\"]");
set1.add("/unit[@type=\"length-inch\"]"); // #11292
mapPathPartsToSets.put("/unit[@type=\"energy-calorie\"]", set1);
// Add OK collisions for /unit[@type=\"energy-foodcalorie\"]
- Set<String> set2 = new HashSet<String>();
+ Set<String> set2 = new HashSet<>();
set2.add("/unit[@type=\"energy-calorie\"]");
set2.add("/unit[@type=\"energy-kilocalorie\"]");
set2.add("/unit[@type=\"length-inch\"]"); // #11292
mapPathPartsToSets.put("/unit[@type=\"energy-foodcalorie\"]", set2);
// Add OK collisions for /unit[@type=\"energy-kilocalorie\"]
- Set<String> set3 = new HashSet<String>();
+ Set<String> set3 = new HashSet<>();
set3.add("/unit[@type=\"energy-foodcalorie\"]");
mapPathPartsToSets.put("/unit[@type=\"energy-kilocalorie\"]", set3);
// Add OK collisions for /unit[@type=\"mass-carat\"]
- Set<String> set4 = new HashSet<String>();
+ Set<String> set4 = new HashSet<>();
set4.add("/unit[@type=\"concentr-karat\"]");
mapPathPartsToSets.put("/unit[@type=\"mass-carat\"]", set4);
// Add OK collisions for /unit[@type=\"concentr-karat\"]
- Set<String> set5 = new HashSet<String>();
+ Set<String> set5 = new HashSet<>();
set5.add("/unit[@type=\"mass-carat\"]");
set5.add("/unit[@type=\"temperature-kelvin\"]");
mapPathPartsToSets.put("/unit[@type=\"concentr-karat\"]", set5);
// Add OK collisions for /unit[@type=\"digital-byte\"]
- Set<String> set6 = new HashSet<String>();
+ Set<String> set6 = new HashSet<>();
set6.add("/unit[@type=\"mass-metric-ton\"]");
mapPathPartsToSets.put("/unit[@type=\"digital-byte\"]", set6);
// Add OK collisions for /unit[@type=\"mass-metric-ton\"]
- Set<String> set7 = new HashSet<String>();
+ Set<String> set7 = new HashSet<>();
set7.add("/unit[@type=\"digital-byte\"]");
mapPathPartsToSets.put("/unit[@type=\"mass-metric-ton\"]", set7);
// delete the exceptions allowing acceleration-g-force and mass-gram to have the same symbol, see #7561
// Add OK collisions for /unit[@type=\"length-inch\"]
- Set<String> set9 = new HashSet<String>();
+ Set<String> set9 = new HashSet<>();
set9.add("/unit[@type=\"energy-calorie\"]");
set9.add("/unit[@type=\"energy-foodcalorie\"]");
mapPathPartsToSets.put("/unit[@type=\"length-inch\"]", set9);
// Add OK collisions for /unit[@type=\"length-foot\"]
- Set<String> set10 = new HashSet<String>();
+ Set<String> set10 = new HashSet<>();
set10.add("/unit[@type=\"angle-arc-minute\"]");
mapPathPartsToSets.put("/unit[@type=\"length-foot\"]", set10);
// Add OK collisions for /unit[@type=\"angle-arc-minute\"]
- Set<String> set11 = new HashSet<String>();
+ Set<String> set11 = new HashSet<>();
set11.add("/unit[@type=\"length-foot\"]");
mapPathPartsToSets.put("/unit[@type=\"angle-arc-minute\"]", set11);
// Add OK collisions for /unit[@type=\"temperature-kelvin\"]
- Set<String> set12 = new HashSet<String>();
+ Set<String> set12 = new HashSet<>();
set12.add("/unit[@type=\"concentr-karat\"]");
mapPathPartsToSets.put("/unit[@type=\"temperature-kelvin\"]", set12);
// Add OK collisions for /unit[@type=\"temperature-generic\"]
- Set<String> set13 = new HashSet<String>();
+ Set<String> set13 = new HashSet<>();
set13.add("/unit[@type=\"angle-degree\"]");
mapPathPartsToSets.put("/unit[@type=\"temperature-generic\"]", set13);
// Add OK collisions for /unit[@type=\"angle-degree\"]
- Set<String> set14 = new HashSet<String>();
+ Set<String> set14 = new HashSet<>();
set14.add("/unit[@type=\"temperature-generic\"]");
mapPathPartsToSets.put("/unit[@type=\"angle-degree\"]", set14);
// Add OK collisions for /unit[@type=\"length-point\"]
- Set<String> set15 = new HashSet<String>();
+ Set<String> set15 = new HashSet<>();
set15.add("/unit[@type=\"volume-pint\"]");
set15.add("/unit[@type=\"mass-pound\"]");
mapPathPartsToSets.put("/unit[@type=\"length-point\"]", set15);
// Add OK collisions for /unit[@type=\"volume-pint\"]
- Set<String> set16 = new HashSet<String>();
+ Set<String> set16 = new HashSet<>();
set16.add("/unit[@type=\"length-point\"]");
mapPathPartsToSets.put("/unit[@type=\"volume-pint\"]", set16);
// Add OK collisions for /unit[@type=\"pressure-hectopascal\"]
- Set<String> set17 = new HashSet<String>();
+ Set<String> set17 = new HashSet<>();
set17.add("/unit[@type=\"pressure-millibar\"]");
mapPathPartsToSets.put("/unit[@type=\"pressure-hectopascal\"]", set17);
// Add OK collisions for /unit[@type=\"pressure-millibar\"]
- Set<String> set18 = new HashSet<String>();
+ Set<String> set18 = new HashSet<>();
set18.add("/unit[@type=\"pressure-hectopascal\"]");
mapPathPartsToSets.put("/unit[@type=\"pressure-millibar\"]", set18);
// Add OK collisions for /unit[@type=\"mass-pound\"]
- Set<String> set19 = new HashSet<String>();
+ Set<String> set19 = new HashSet<>();
set19.add("/unit[@type=\"length-point\"]");
mapPathPartsToSets.put("/unit[@type=\"mass-pound\"]", set19);
// Add OK collisions for /unit[@type=\"duration-century\"]
- Set<String> set20 = new HashSet<String>();
+ Set<String> set20 = new HashSet<>();
set20.add("/unitLength[@type=\"short\"]/unit[@type=\"duration-second\"]");
mapPathPartsToSets.put("/unitLength[@type=\"short\"]/unit[@type=\"duration-century\"]", set20);
// Add OK collisions for /unit[@type=\"duration-second\"]
- Set<String> set21 = new HashSet<String>();
+ Set<String> set21 = new HashSet<>();
set21.add("/unitLength[@type=\"short\"]/unit[@type=\"duration-century\"]");
mapPathPartsToSets.put("/unitLength[@type=\"short\"]/unit[@type=\"duration-second\"]", set21);
+ // Add OK collisions for dot and pixel
+ addNonColliding(mapPathPartsToSets, "[@type=\"graphics-pixel\"]", "[@type=\"graphics-dot\"]");
+ addNonColliding(mapPathPartsToSets, "[@type=\"graphics-pixel-per-inch\"]", "[@type=\"graphics-dot-per-inch\"]");
+ addNonColliding(mapPathPartsToSets, "[@type=\"graphics-dot-per-centimeter\"]", "[@type=\"graphics-pixel-per-centimeter\"]");
+
// all done, return immutable version
- return Collections.unmodifiableMap(mapPathPartsToSets);
+ return ImmutableMap.copyOf(mapPathPartsToSets);
+ }
+
+ // TODO Clean up the mapPathPartsToSets; clumsy to build and probably not speedy to use.
+
+ public static void addNonColliding(Map<String, Set<String>> mapPathPartsToSets, String... alternatives) {
+ LinkedHashSet<String> items = new LinkedHashSet<>(Arrays.asList(alternatives));
+ for (String item : items) {
+ LinkedHashSet<String> others = new LinkedHashSet<>(items);
+ others.remove(item);
+ mapPathPartsToSets.put(item, ImmutableSet.copyOf(others));
+ }
}
public CheckDisplayCollisions(Factory factory) {
super(factory);
}
+ @Override
@SuppressWarnings("unused")
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
@@ -293,7 +314,7 @@
if (!path.contains("[@count=") || "0".equals(value)) {
return this;
}
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for removeElement
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); // not frozen, for removeElement
String type = parts.getAttributeValue(-1, "type");
myPrefix = parts.removeElement(-1).toString();
matcher = PatternCache.get(myPrefix.replaceAll("\\[", "\\\\[") +
@@ -302,6 +323,7 @@
message = "Can't have same number pattern as {0}";
paths = getPathsWithValue(getResolvedCldrFileToCheck(), path, value, myType, myPrefix, matcher, currentAttributesToIgnore, Equivalence.exact);
} else if (myType == Type.UNITS || myType == Type.UNIT_PREFIX) {
+ currentAttributesToIgnore = ignoreAltAttributes;
paths = getPathsWithValue(getResolvedCldrFileToCheck(), path, value, myType, myPrefix, matcher, currentAttributesToIgnore, Equivalence.unit);
} else if (myType == Type.CARDINAL_MINIMAL || myType == Type.ORDINAL_MINIMAL) {
if (value.equals("{0}?")) {
@@ -338,7 +360,7 @@
// paths.add(subdivisionPath);
// }
paths.addAll(duplicatePaths);
- } else if (CHECK_FLAG_AND_EMOJI && myType == Type.ANNOTATIONS) {
+ } else if (CHECK_FLAG_AND_EMOJI && myType == Type.ANNOTATIONS) {
// make sure that annotations don't have same value as regions, eg “日本” for 🇯🇵 & 🗾
// NOTE: this is an asymmetric test; we presume the name of the region is ok.
Set<String> duplicatePaths = getPathsWithValue(
@@ -373,7 +395,7 @@
}
}
}
-
+
// Collisions between different lengths and counts of the same unit are allowed
// Collisions between 'narrow' forms are allowed (the current is filtered by UNITS_IGNORE)
//ldml/units/unitLength[@type="narrow"]/unit[@type="duration-day-future"]/unitPattern[@count="one"]
@@ -440,7 +462,7 @@
}
}
}
-
+
// removeMatches(myType);
// check again on size
if (paths.isEmpty()) {
@@ -448,7 +470,7 @@
}
// ok, we probably have a collision! Extract the types
- Set<String> collidingTypes = new TreeSet<String>();
+ Set<String> collidingTypes = new TreeSet<>();
if (SKIP_TYPE_CHECK) {
for (String pathName : paths) {
@@ -532,7 +554,7 @@
log("Ignore a collision between exemplarCity and another name for Etc/* zones");
return this;
}
- Set<String> collidingZoneTypes = new TreeSet<String>();
+ Set<String> collidingZoneTypes = new TreeSet<>();
collidingZoneTypes.add(thisZoneType);
collidingZoneTypes.add(collidingZoneType);
if (collidingZoneTypes.size() == 2 &&
@@ -579,7 +601,7 @@
int debug = 0;
}
- Set<String> retrievedPaths = new HashSet<String>();
+ Set<String> retrievedPaths = new HashSet<>();
if (myType.matchType == MatchType.PREFIX) {
file.getPathsWithValue(value, myPrefix, matcher, retrievedPaths);
} else {
@@ -596,8 +618,8 @@
}
// Do first cleanup
- // remove paths with "alt/count"; they can be duplicates
- Set<String> paths = new HashSet<String>();
+ // remove paths with "alt/count" per currentAttributesToIgnore; they can be duplicates
+ Set<String> paths = new HashSet<>();
for (String pathName : retrievedPaths) {
Type thisPathType = Type.getType(pathName);
// If the colliding path is of a different type than the original,
@@ -605,7 +627,6 @@
if (myType != thisPathType) {
continue;
}
- ;
if (exclusions.reset(pathName).find() && thisPathType != Type.UNITS_COORDINATE) {
continue;
}
@@ -691,7 +712,7 @@
CLDRFile english = getEnglishFile();
// Pick up all instances in English where the exemplarCity and territory match
// and include them as exceptions.
- exceptions = new HashMap<String, String>();
+ exceptions = new HashMap<>();
for (Iterator<String> it = english.iterator(Type.ZONE.getPrefix()); it.hasNext();) {
String xpath = it.next();
if (!xpath.endsWith("/exemplarCity")) continue;
diff --git a/tools/java/org/unicode/cldr/test/CheckExemplars.java b/tools/java/org/unicode/cldr/test/CheckExemplars.java
index 3166f70..306c940 100644
--- a/tools/java/org/unicode/cldr/test/CheckExemplars.java
+++ b/tools/java/org/unicode/cldr/test/CheckExemplars.java
@@ -146,6 +146,7 @@
return this;
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
if (fullPath == null) return this; // skip paths that we don't have
@@ -275,7 +276,14 @@
.setMessage("ParseLenient sample not in value: {0} ∌ {1}", us, sampleValue);
result.add(message);
}
- } catch (Exception e) {
+ } catch (IllegalArgumentException e) {
+ /*
+ * new UnicodeSet(value) throws IllegalArgumentException if, for example, value is null or value = "?".
+ * This can happen during cldr-unittest TestAll.
+ * path = //ldml/characters/parseLenients[@scope="general"][@level="lenient"]/parseLenient[@sample="’"]
+ * or
+ * path = //ldml/characters/parseLenients[@scope="date"][@level="lenient"]/parseLenient[@sample="-"]
+ */
CheckStatus message = new CheckStatus().setCause(this)
.setMainType(CheckStatus.errorType)
.setSubtype(Subtype.badParseLenient)
@@ -349,7 +357,7 @@
} catch (Exception e) {
result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
.setSubtype(Subtype.illegalExemplarSet)
- .setMessage("This field must be a set of the form [a b c-d ...]: ", new Object[] { e.getMessage() }));
+ .setMessage("This field must be a set of the form [a b c-d ...]: {0}", new Object[] { e.getMessage() }));
return;
}
diff --git a/tools/java/org/unicode/cldr/test/CheckForCopy.java b/tools/java/org/unicode/cldr/test/CheckForCopy.java
index 540294b..b201d3e 100644
--- a/tools/java/org/unicode/cldr/test/CheckForCopy.java
+++ b/tools/java/org/unicode/cldr/test/CheckForCopy.java
@@ -9,11 +9,11 @@
import org.unicode.cldr.util.CLDRFile.Status;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.InternalCldrException;
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.RegexLookup;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.lang.CharSequences;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.ICUException;
@@ -37,7 +37,6 @@
"|dayPeriod" +
"|(monthWidth|dayWidth|quarterWidth)\\[@type=\"(narrow|abbreviated)\"]" +
"|exemplarCity" +
- // "|localeDisplayNames/(scripts|territories)" +
"|currency\\[@type=\"[A-Z]+\"]/symbol" +
"|pattern" +
"|field\\[@type=\"dayperiod\"]" +
@@ -55,170 +54,152 @@
private static final RegexLookup<Boolean> SKIP_CODE_CHECK = new RegexLookup<Boolean>()
.add("^//ldml/characterLabels/characterLabel", true)
.add("^//ldml/dates/fields/field\\[@type=\"(era|week|minute|quarter|second)\"]/displayName", true)
- .add("^//ldml/localeDisplayNames/scripts/script\\[@type=\"(Jamo|Thai|Ahom|Loma|Moon|Newa|Arab|Lisu|Bali|Cham|Modi)\"]", true)
- .add("^//ldml/localeDisplayNames/languages/language\\[@type=\"(fon|gan|luo|tiv|yao|vai)\"]", true)
- .add("^//ldml/dates/timeZoneNames/metazone\\[@type=\"GMT\"]", true)
- .add("^//ldml/localeDisplayNames/territories/territory\\[@type=\"[^\"]*+\"]\\[@alt=\"short\"]", true)
- .add("^//ldml/localeDisplayNames/measurementSystemNames/measurementSystemName", true)
- .add("^//ldml/localeDisplayNames/types/type\\[@key=\"collation\"]\\[@type=\"standard\"]", true)
+ .add("^//ldml/localeDisplayNames/scripts/script\\[@type=\"(Jamo|Thai|Ahom|Loma|Moon|Newa|Arab|Lisu|Bali|Cham|Modi)\"]", true)
+ .add("^//ldml/localeDisplayNames/languages/language\\[@type=\"(fon|gan|luo|tiv|yao|vai)\"]", true)
+ .add("^//ldml/dates/timeZoneNames/metazone\\[@type=\"GMT\"]", true)
+ .add("^//ldml/localeDisplayNames/territories/territory\\[@type=\"[^\"]*+\"]\\[@alt=\"short\"]", true)
+ .add("^//ldml/localeDisplayNames/measurementSystemNames/measurementSystemName", true)
+ .add("^//ldml/localeDisplayNames/types/type\\[@key=\"collation\"]\\[@type=\"standard\"]", true)
;
-// private static final Set<String> SKIP_TYPES = ImmutableSet.of(
-// "CHF", "EUR", "XPD",
-// "Vaii", "Yiii", "Thai",
-// "SAAHO", "BOONT", "SCOUSE",
-// "fon", "ijo", "luo", "tiv", "yao", "zu", "zza", "tw", "ur", "vo", "ha", "hi", "ig", "yo", "ak", "vai",
-// "eo", "af",
-// "Cuba",
-// // languages that are the same in English as in themselves
-// // and countries that have the same name as English in one of their official languages.
-// "af", // Afrikaans
-// "ak", // Akan
-// "AD", // Andorra
-// "LI", // Liechtenstein
-// "NA", // Namibia
-// "AR", // Argentina
-// "CO", // Colombia
-// "VE", // Venezuela
-// "CL", // Chile
-// "CU", // Cuba
-// "EC", // Ecuador
-// "GT", // Guatemala
-// "BO", // Bolivia
-// "HN", // Honduras
-// "SV", // El Salvador
-// "CR", // Costa Rica
-// "PR", // Puerto Rico
-// "NI", // Nicaragua
-// "UY", // Uruguay
-// "PY", // Paraguay
-// "fil", // Filipino
-// "FR", // France
-// "MG", // Madagascar
-// "CA", // Canada
-// "CI", // Côte d’Ivoire
-// "BI", // Burundi
-// "ML", // Mali
-// "TG", // Togo
-// "NE", // Niger
-// "BF", // Burkina Faso
-// "RE", // Réunion
-// "GA", // Gabon
-// "LU", // Luxembourg
-// "MQ", // Martinique
-// "GP", // Guadeloupe
-// "YT", // Mayotte
-// "VU", // Vanuatu
-// "SC", // Seychelles
-// "MC", // Monaco
-// "DJ", // Djibouti
-// "RW", // Rwanda
-// "ha", // Hausa
-// "ID", // Indonesia
-// "ig", // Igbo
-// "NG", // Nigeria
-// "SM", // San Marino
-// "kln", // Kalenjin
-// "mg", // Malagasy
-// "MY", // Malaysia
-// "BN", // Brunei
-// "MT", // Malta
-// "ZW", // Zimbabwe
-// "SR", // Suriname
-// "AW", // Aruba
-// "PT", // Portugal
-// "AO", // Angola
-// "TL", // Timor-Leste
-// "RS", // Serbia
-// "rw", // Kinyarwanda
-// "RW", // Rwanda
-// "ZW", // Zimbabwe
-// "FI", // Finland
-// "TZ", // Tanzania
-// "KE", // Kenya
-// "UG", // Uganda
-// "TO", // Tonga
-// "wae", // Walser
-// "metric");
-
static UnicodeSet ASCII_LETTER = new UnicodeSet("[a-zA-Z]").freeze();
enum Failure {
ok, same_as_english, same_as_code
}
+ @Override
+ @SuppressWarnings("unused")
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
- if (fullPath == null || value == null) {
+ if (fullPath == null || path == null || value == null) {
return this; // skip root, and paths that we don't have
}
- if (value.contentEquals("Hanb")) {
- int debug = 0;
- }
+ Failure failure = sameAsCodeOrEnglish(value, path, getCldrFileToCheck(), false);
+ addFailure(result, failure);
+ return this;
+ }
+
+ /**
+ * Check the given path and value, and return true if it has a same_as_code failure
+
+ * @param value the value
+ * @param path the path
+ * @param cldrFile the CLDRFile
+ * @return true or false
+ */
+ public static boolean sameAsCode(String value, String path, CLDRFile cldrFile) {
+ return sameAsCodeOrEnglish(value, path, cldrFile, true) == Failure.same_as_code;
+ }
+
+ /**
+ * Check the given path and value for same_as_code and same_as_english failures
+ *
+ * @param value the value
+ * @param path the path
+ * @param cldrFile the CLDRFile
+ * @param contextIsVoteSubmission true when a new or imported vote is in question, else false
+ * @return the Failure object
+ */
+ private static Failure sameAsCodeOrEnglish(String value, String path, CLDRFile cldrFile, boolean contextIsVoteSubmission) {
Status status = new Status();
- // don't check inherited values unless they are from ^^^
- String topStringValue = getCldrFileToCheck().getUnresolved().getStringValue(path);
+ /*
+ * Don't check inherited values unless they are from ^^^
+ *
+ * In the context of vote submission, we must check inherited values,
+ * otherwise nothing prevents voting to inherit the code value.
+ *
+ * TODO: clarify the purpose of using topStringValue and getConstructedValue here;
+ * cf. getConstructedBaileyValue. This code is confusing and warrants explanation.
+ * The meaning of "explicit" here seems to be the opposite of its meaning elsewhere.
+ */
+ String topStringValue = cldrFile.getUnresolved().getStringValue(path);
final boolean isExplicitBailey = CldrUtility.INHERITANCE_MARKER.equals(topStringValue);
- if (!isExplicitBailey) {
- String loc = getCldrFileToCheck().getSourceLocaleID(path, status);
- if (!getCldrFileToCheck().getLocaleID().equals(loc)
+ String loc = cldrFile.getSourceLocaleID(path, status);
+ if (!contextIsVoteSubmission && !isExplicitBailey) {
+ if (!cldrFile.getLocaleID().equals(loc)
|| !path.equals(status.pathWhereFound)) {
- return this;
+ return Failure.ok;
}
- }
+ }
-
+ /*
+ * Since get() may return null here, comparison with Boolean.TRUE prevents NullPointerException.
+ */
if (Boolean.TRUE == skip.get(path)) {
- return this;
+ return Failure.ok;
}
Failure failure = Failure.ok;
- String english = getDisplayInformation().getStringValue(path);
- if (CharSequences.equals(english, value)) {
+ CLDRFile di = getDisplayInformation();
+ if (di == null) {
+ throw new InternalCldrException("CheckForCopy.sameAsCodeOrEnglish error: getDisplayInformation is null");
+ }
+ String english = di.getStringValue(path);
+ if (value.equals(english)) {
if (ASCII_LETTER.containsSome(english)) {
failure = Failure.same_as_english;
}
}
- // Check for attributes.
- // May override English test
- if (Boolean.TRUE != SKIP_CODE_CHECK.get(path)) {
- String value2 = value;
- if (isExplicitBailey) {
- value2 = getCldrFileToCheck().getConstructedValue(path);
- if (value2 == null) { // no special constucted value
- value2 = value;
- }
+ /*
+ * Check for attributes. May override English test.
+ * Since get() may return null here, comparison with Boolean.TRUE prevents NullPointerException.
+ */
+ if (Boolean.TRUE == SKIP_CODE_CHECK.get(path)) {
+ return Failure.ok;
+ }
+ if (CldrUtility.INHERITANCE_MARKER.equals(value)) {
+ value = cldrFile.getConstructedBaileyValue(path, null, null);
+ }
+ if (value == null) {
+ return Failure.ok;
+ }
+ if ("en".equals(loc) || loc.startsWith("en_")) {
+ if ("year".equals(value) || "month".equals(value) || "day".equals(value) || "hour".equals(value)) {
+ return Failure.ok;
}
-
- XPathParts parts = XPathParts.getFrozenInstance(path);
-
- int elementCount = parts.size();
- for (int i = 2; i < elementCount; ++i) {
- Map<String, String> attributes = parts.getAttributes(i);
- for (Entry<String, String> attributeEntry : attributes.entrySet()) {
- final String attributeValue = attributeEntry.getValue();
- // if (SKIP_TYPES.contains(attributeValue)) {
- // failure = Failure.ok; // override English test
- // break;
- // }
- try {
- if (value2.equals(attributeValue)) {
- failure = Failure.same_as_code;
- break;
- }
- } catch (NullPointerException e) {
- throw new ICUException("Value: " + value + "\nattributeValue: " + attributeValue
- + "\nPath: " + path, e);
- }
- }
+ }
+ String value2 = value;
+ if (isExplicitBailey) {
+ value2 = cldrFile.getConstructedValue(path);
+ if (value2 == null) { // no special constructed value
+ value2 = value;
}
}
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+
+ int elementCount = parts.size();
+ for (int i = 2; i < elementCount; ++i) {
+ Map<String, String> attributes = parts.getAttributes(i);
+ for (Entry<String, String> attributeEntry : attributes.entrySet()) {
+ final String attributeValue = attributeEntry.getValue();
+ try {
+ if (value2.equals(attributeValue)) {
+ failure = Failure.same_as_code;
+ break;
+ }
+ } catch (NullPointerException e) {
+ throw new ICUException("Value: " + value + "\nattributeValue: " + attributeValue
+ + "\nPath: " + path, e);
+ }
+ }
+ }
+ return failure;
+ }
+
+ /**
+ * If there is a failure, add it to the list
+ *
+ * @param result the list of CheckStatus objects
+ * @param failure the Failure object
+ */
+ private void addFailure(List<CheckStatus> result, Failure failure) {
switch (failure) {
case same_as_english:
result
@@ -244,21 +225,22 @@
break;
default:
}
- return this;
}
@Override
public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options,
List<CheckStatus> possibleErrors) {
-
- if (cldrFileToCheck == null) return this;
+
+ if (cldrFileToCheck == null) {
+ return this;
+ }
final String localeID = cldrFileToCheck.getLocaleID();
-
+
LanguageTagParser ltp = new LanguageTagParser().set(localeID);
String lang = ltp.getLanguage();
- setSkipTest(false);
+ setSkipTest(false);
if (lang.equals("en") || localeID.equals("root")) {// || exemplars != null && ASCII_LETTER.containsNone(exemplars)) {
setSkipTest(true);
if (DEBUG) {
diff --git a/tools/java/org/unicode/cldr/test/CheckForExemplars.java b/tools/java/org/unicode/cldr/test/CheckForExemplars.java
index 645b1c0..f06341e 100644
--- a/tools/java/org/unicode/cldr/test/CheckForExemplars.java
+++ b/tools/java/org/unicode/cldr/test/CheckForExemplars.java
@@ -12,6 +12,7 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -24,6 +25,7 @@
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.PatternPlaceholders;
+import org.unicode.cldr.util.PatternPlaceholders.PlaceholderInfo;
import org.unicode.cldr.util.PatternPlaceholders.PlaceholderStatus;
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.BasicLanguageData;
@@ -33,6 +35,10 @@
import org.unicode.cldr.util.XMLSource;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Multiset.Entry;
+import com.google.common.collect.TreeMultiset;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Collator;
@@ -134,7 +140,7 @@
")");
private Matcher leadOrTrailWhitespaceOk = LEAD_OR_TRAIL_WHITESPACE_OK.matcher("");
- private static UnicodeSet ASCII = (UnicodeSet) new UnicodeSet("[\\u0020-\\u007F]").freeze();
+ private static UnicodeSet ASCII = new UnicodeSet("[\\u0020-\\u007F]").freeze();
private PatternPlaceholders patternPlaceholders = PatternPlaceholders.getInstance();
private SupplementalDataInfo sdi;
@@ -156,7 +162,7 @@
static class PlaceholderTransform implements Transform<String, Set<String>> {
@Override
public Set<String> transform(String source) {
- Set<String> placeholders = new LinkedHashSet<String>();
+ Set<String> placeholders = new LinkedHashSet<>();
String[] parts = source.split(";\\s+");
for (String part : parts) {
int equalsPos = part.indexOf('=');
@@ -257,6 +263,7 @@
return result;
}
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
if (fullPath == null) return this; // skip paths that we don't have
@@ -294,13 +301,13 @@
if (path.startsWith("//ldml/numbers/miscPatterns") && path.contains("[@type=\"range\"]")) {
if (DISALLOWED_IN_RANGE.containsSome(value)) {
result
- .add(new CheckStatus()
- .setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.illegalCharactersInPattern)
- .setMessage(
- "Range patterns should not have letters.",
- new Object[] {}));
+ .add(new CheckStatus()
+ .setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.illegalCharactersInPattern)
+ .setMessage(
+ "Range patterns should not have letters.",
+ new Object[] {}));
}
}
// Now handle date patterns.
@@ -413,7 +420,7 @@
if (localeID == null) {
throw new IllegalArgumentException(
"A likely subtag for " + parser.getLanguage() +
- " is required to get its script.");
+ " is required to get its script.");
}
}
script = parser.set(localeID).getScript();
@@ -462,88 +469,89 @@
}
private String checkAndReplacePlaceholders(String path, String value, List<CheckStatus> result) {
- // add checks for patterns. Make sure that all and only the message format patterns have {n}
- Matcher matcher = patternMatcher.reset(value);
- Set<String> matchList = new HashSet<String>();
- StringBuffer placeholderBuffer = new StringBuffer();
- while (matcher.find()) {
- // Look for duplicate values.
- if (!matchList.add(matcher.group())) {
- placeholderBuffer.append(", ").append(matcher.group());
- }
- }
- Set<String> placeholders = null;
+ CheckStatus.Type statusType = getPhase() == Phase.BUILD ? CheckStatus.warningType : CheckStatus.errorType; // new errors, so get past the tests.
+
+ // Get information about what should be there
PlaceholderStatus placeholderStatus = patternPlaceholders.getStatus(path);
- if (placeholderStatus != PlaceholderStatus.DISALLOWED) {
- placeholders = patternPlaceholders.get(path).keySet();
- }
+ Map<String, PlaceholderInfo> placeholderInfo = patternPlaceholders.get(path);
- boolean supposedToHaveMessageFormatFields =
- // supposedToBeMessageFormat.reset(path).find()
- placeholders != null;
+ int minimum = placeholderInfo.size();
+ int maximum = placeholderInfo.size();
- if (supposedToHaveMessageFormatFields) {
- if (placeholderBuffer.length() > 0) {
- if (placeholderStatus != PlaceholderStatus.MULTIPLE) {
- result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.extraPlaceholders)
- .setMessage("Remove duplicates of{0}",
- new Object[] { placeholderBuffer.substring(1) }));
+ if (placeholderStatus == PlaceholderStatus.LOCALE_DEPENDENT || placeholderStatus == PlaceholderStatus.MULTIPLE) {
+ // if locale dependent, it is because of count= or ordinal=. Figure out what the values are, and whether we are allowed to have none or one
+ PluralRules rules = PluralRules.forLocale(new ULocale(getCldrFileToCheck().getLocaleID()));
+ if (rules != null) {
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ String keyword = parts.getAttributeValue(-1, "count");
+ if (keyword == null) {
+ keyword = parts.getAttributeValue(-1, "ordinal");
}
- }
- placeholderBuffer.setLength(0);
- // Check that the needed placeholders are there.
- if (placeholders == null) placeholders = new HashSet<String>();
- for (String placeholder : placeholders) {
- if (!matchList.contains(placeholder)) {
- placeholderBuffer.append(", ").append(placeholder);
- }
- }
- boolean placeholdersMissing = false;
- if (placeholderBuffer.length() > 0) {
- // Check
- if (placeholderStatus == PlaceholderStatus.LOCALE_DEPENDENT && (path.contains("[@count=") || path.contains("[@ordinal="))) {
- PluralRules rules = PluralRules.forLocale(new ULocale(getCldrFileToCheck().getLocaleID()));
- XPathParts parts = XPathParts.getFrozenInstance(path);
- String keyword = parts.getAttributeValue(-1, "count");
- if (keyword == null) {
- keyword = parts.getAttributeValue(-1, "ordinal");
+ try {
+ if (rules.getUniqueKeywordValue(keyword) != PluralRules.NO_UNIQUE_VALUE) {
+ minimum = 0;
}
- placeholdersMissing = rules.getUniqueKeywordValue(keyword) == PluralRules.NO_UNIQUE_VALUE;
- } else {
- placeholdersMissing = placeholderStatus == PlaceholderStatus.REQUIRED;
+ } catch (Exception e) {
+ // internal error, skip
}
}
- if (placeholdersMissing) {
- result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.missingPlaceholders)
- .setMessage("This message pattern is missing placeholder(s){0}. See the English for an example.",
- new Object[] { placeholderBuffer.substring(1) }));
- }
- // Check for extra placeholders.
- matchList.removeAll(placeholders);
- if (matchList.size() > 0) {
- String list = matchList.toString();
- list = list.substring(1, list.length() - 1);
- result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.extraPlaceholders)
- .setMessage("Extra placeholders {0} should be removed.",
- new Object[] { list }));
- }
- // check the other characters in the message format patterns
- value = patternMatcher.replaceAll(STAND_IN);
- } else if (matchList.size() > 0 && placeholderStatus == PlaceholderStatus.DISALLOWED) { // non-message field has
- // placeholder values
- result.add(new CheckStatus()
- .setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.shouldntHavePlaceholders)
- .setMessage(
- "This field is not a message pattern, and should not have '{0}, {1},' etc. See the English for an example.",
- new Object[] {}));
- // end checks for patterns
}
- return value;
+
+ // TODO: move these tests to CheckPlaceholder
+
+ // Now see what is there, and see if they match
+ Matcher matcher = patternMatcher.reset(value);
+ Multiset<String> matchList = TreeMultiset.create(); // Look for duplicate values.
+ while (matcher.find()) {
+ matchList.add(matcher.group());
+ }
+ final Set<String> distinctPlaceholders = matchList.elementSet();
+ int countDistinctPlaceholders = distinctPlaceholders.size();
+
+ if (countDistinctPlaceholders > 0) {
+ // Verify that all placeholders are monotonically increasing from zero.
+ int expected = 0;
+ for (String element : distinctPlaceholders) {
+ // int elementValue = Integer.parseInt(element, 1, element.length()-1, 10);
+ int elementValue = Integer.parseInt(element.substring(1, element.length()-1), 10);
+ if (elementValue != expected) {
+ result.add(new CheckStatus().setCause(this).setMainType(statusType)
+ .setSubtype(Subtype.gapsInPlaceholderNumbers)
+ .setMessage("Placeholders {0} should be strictly increasing, starting at zero.", distinctPlaceholders));
+ break;
+ }
+ ++expected;
+ }
+ }
+
+ // Check if duplicates are allowed
+ if (matchList.size() > countDistinctPlaceholders && placeholderStatus != PlaceholderStatus.MULTIPLE) {
+ Set<String> errors = new LinkedHashSet<>();
+ for (Entry<String> entry : matchList.entrySet()) {
+ if (entry.getCount() > 1) {
+ errors.add(entry.getElement());
+ }
+ }
+ result.add(new CheckStatus().setCause(this).setMainType(statusType)
+ .setSubtype(Subtype.duplicatePlaceholders)
+ .setMessage("Duplicate placeholders: {0}.", Joiner.on(", ").join(errors)));
+ }
+
+ // Now see if the number we have is within bounds
+
+ if (countDistinctPlaceholders < minimum) {
+ result.add(new CheckStatus().setCause(this).setMainType(statusType)
+ .setSubtype(Subtype.missingPlaceholders)
+ .setMessage("Need at least {0} placeholder(s), but only have {1}. Placeholders are: {2}", minimum, countDistinctPlaceholders, placeholderInfo));
+ } else {
+ if (countDistinctPlaceholders > maximum) {
+ result.add(new CheckStatus().setCause(this).setMainType(statusType)
+ .setSubtype(Subtype.extraPlaceholders)
+ .setMessage("Need no more than {0} placeholders, but have too many with {1}.", countDistinctPlaceholders, minimum));
+ }
+ }
+ // Return the pattern with placeholders replaced
+ return matchList.isEmpty() ? value : patternMatcher.replaceAll(STAND_IN);
}
/**
@@ -570,7 +578,7 @@
if (localeID == null) {
throw new IllegalArgumentException(
"A likely subtag for " + parser.getLanguage() +
- " is required to get its script.");
+ " is required to get its script.");
}
}
script = parser.set(localeID).getScript();
@@ -608,7 +616,7 @@
scriptToCurrencies = new Relation(new HashMap<String, Set<String>>(), HashSet.class);
for (Object curScript : scriptToTerritories.keySet()) {
Set<String> territories = scriptToTerritories.get(curScript);
- Set<String> currencies = new HashSet<String>();
+ Set<String> currencies = new HashSet<>();
for (String territory : territories) {
Set<CurrencyDateInfo> currencyInfo = sdi.getCurrencyDateInfo(territory);
for (CurrencyDateInfo info : currencyInfo) {
@@ -684,14 +692,14 @@
scriptString.append("}");
}
result
- .add(new CheckStatus()
- .setCause(this)
- .setMainType(warningVsError)
- .setSubtype(ASCII.containsAll(missing) ? subtypeAscii : subtype)
- .setMessage(
- "The characters \u200E{0}\u200E {1} {2}. "
- +
- "For what to do, see <i>Handling Warnings</i> in <a target='CLDR-ST-DOCS' href='http://cldr.org/translation/characters#TOC-Handing-Warnings'>Characters</a>.",
+ .add(new CheckStatus()
+ .setCause(this)
+ .setMainType(warningVsError)
+ .setSubtype(ASCII.containsAll(missing) ? subtypeAscii : subtype)
+ .setMessage(
+ "The characters \u200E{0}\u200E {1} {2}. "
+ +
+ "For what to do, see <i>Handling Warnings</i> in <a target='CLDR-ST-DOCS' href='http://cldr.org/translation/characters#TOC-Handing-Warnings'>Characters</a>.",
new Object[] { fixedMissing, scriptString, qualifier }));
}
diff --git a/tools/java/org/unicode/cldr/test/CheckLogicalGroupings.java b/tools/java/org/unicode/cldr/test/CheckLogicalGroupings.java
index 8b6b871..af96eb4 100644
--- a/tools/java/org/unicode/cldr/test/CheckLogicalGroupings.java
+++ b/tools/java/org/unicode/cldr/test/CheckLogicalGroupings.java
@@ -3,6 +3,8 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
@@ -12,10 +14,21 @@
import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.LogicalGrouping;
+import org.unicode.cldr.util.LogicalGrouping.PathType;
+import org.unicode.cldr.util.With;
import org.unicode.cldr.util.XMLSource;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Multiset.Entry;
+import com.google.common.collect.TreeMultiset;
+import com.ibm.icu.dev.util.UnicodeMap;
+import com.ibm.icu.text.Transliterator;
+import com.ibm.icu.text.UnicodeSet;
+import com.ibm.icu.util.Output;
public class CheckLogicalGroupings extends FactoryCheckCLDR {
// Change MINIMUM_DRAFT_STATUS to DraftStatus.contributed if you only care about
@@ -26,7 +39,7 @@
private boolean phaseCausesError;
private CoverageLevel2 coverageLevel;
-
+
public CheckLogicalGroupings(Factory factory) {
super(factory);
}
@@ -36,18 +49,18 @@
List<CheckStatus> possibleErrors) {
super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
- // skip the test unless we are at the top level, eg
+ // skip the test unless we are at the top level, eg
// test root, fr, sr_Latn, ...
// but skip fr_CA, sr_Latn_RS, etc.
// TODO: could simplify some of the code later, since non-topLevel locales are skipped
- // NOTE: we could have a weaker test.
+ // NOTE: we could have a weaker test.
// Skip if all of the items are either inherited, or aliased *including votes for inherited (3 up arrows)*
String parent = LocaleIDParser.getParent(cldrFileToCheck.getLocaleID());
boolean isTopLevel = parent == null || parent.equals("root");
setSkipTest(!isTopLevel);
phaseCausesError = PHASES_CAUSE_ERROR.contains(getPhase());
-
+
coverageLevel = CoverageLevel2.getInstance(cldrFileToCheck.getLocaleID());
return this;
@@ -58,7 +71,7 @@
// to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*LogicalGroupings.*
/**
- * We are not as strict with sublocales (where the parent is neither root nor code_fallback).
+ * We are not as strict with sublocales (where the parent is neither root nor code_fallback).
* @param path
* @return
*/
@@ -79,6 +92,9 @@
return !source.equals(XMLSource.ROOT_ID) && !source.equals(XMLSource.CODE_FALLBACK_ID);
}
+ static final int LIMIT_DISTANCE = 5;
+
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
@@ -87,11 +103,34 @@
return this;
}
- Set<String> paths = LogicalGrouping.getPaths(getCldrFileToCheck(), path);
+ Output<PathType> pathType = new Output<>();
+ Set<String> paths = LogicalGrouping.getPaths(getCldrFileToCheck(), path, pathType);
if (paths == null || paths.size() < 2) return this; // skip if not part of a logical grouping
- // TODO
- Set<String> paths2 = new HashSet<String>(paths);
+ // check the edit distances for count, gender, case
+ switch(pathType.value) {
+ case COUNT_CASE:
+ case COUNT:
+ case COUNT_CASE_GENDER:
+ // only check the first path
+ TreeSet<String> sorted = new TreeSet<>(paths);
+ if (path.equals(sorted.iterator().next())) {
+ Multiset<String> values = TreeMultiset.create();
+ int maxDistance = getMaxDistance(path, value, sorted, values);
+ if (maxDistance >= LIMIT_DISTANCE) {
+ maxDistance = getMaxDistance(path, value, paths, values);
+ result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType)
+ .setSubtype(Subtype.largerDifferences) // typically warningType or errorType
+ .setMessage("{0} different characters within {1}; {2}", maxDistance, showInvisibles(values), pathType.value));
+ }
+ }
+ break;
+ default: break;
+ }
+
+
+ // TODO make this more efficient
+ Set<String> paths2 = new HashSet<>(paths);
for (String p : paths2) {
if (LogicalGrouping.isOptional(getCldrFileToCheck(), p)) {
paths.remove(p);
@@ -99,7 +138,8 @@
}
if (paths.size() < 2) return this; // skip if not part of a logical grouping
- Set<String> missingPaths = new HashSet<String>();
+
+ Set<String> missingPaths = new HashSet<>();
boolean havePath = false;
String firstPath = null;
for (String apath : paths) {
@@ -111,7 +151,7 @@
}
missingPaths.add(apath);
}
- }
+ }
if (havePath && !missingPaths.isEmpty()) {
if (path.equals(firstPath)) {
@@ -120,7 +160,7 @@
.map(x -> getPathReferenceForMessage(x, true))
.collect(Collectors.toSet());
Level cLevel = coverageLevel.getLevel(path);
-
+
CheckStatus.Type showError = phaseCausesError ? CheckStatus.errorType : CheckStatus.warningType;
result.add(new CheckStatus().setCause(this).setMainType(showError)
.setSubtype(Subtype.incompleteLogicalGroup)
@@ -177,7 +217,7 @@
return this; // bail if we are ok
}
- // If some other path in the LG has a higher draft status, then cause error on this path.
+ // If some other path in the LG has a higher draft status, then cause error on this path.
// NOTE: changed to show in Vetting, not just Resolution
for (String apath : paths) {
@@ -197,11 +237,115 @@
CheckStatus.Type showError = phaseCausesError ? CheckStatus.errorType : CheckStatus.warningType;
result.add(new CheckStatus().setCause(this).setMainType(showError)
.setSubtype(Subtype.inconsistentDraftStatus) // typically warningType or errorType
- .setMessage("This item has a lower draft status (in its logical group) than {0}.",
+ .setMessage("This item has a lower draft status (in its logical group) than {0}.",
getPathReferenceForMessage(apath, true))); // the
break; // no need to continue
}
}
return this;
}
+
+ static final Transliterator SHOW_INVISIBLES = Transliterator.createFromRules(
+ "show",
+ "([[:C:][:Z:][:whitespace:][:Default_Ignorable_Code_Point:]-[\\u0020]]) > &hex/perl($1);",
+ Transliterator.FORWARD);
+
+ public static String showInvisibles(String value) {
+ return SHOW_INVISIBLES.transform(value);
+ }
+
+ public static String showInvisibles(int codePoint) {
+ return showInvisibles(With.fromCodePoint(codePoint));
+ }
+
+ public static String showInvisibles(Multiset<?> codePointCounts) {
+ StringBuilder b = new StringBuilder().append('{');
+ for (Entry<?> entry : codePointCounts.entrySet()) {
+ if (b.length() > 1) {
+ b.append(", ");
+ }
+ Object element = entry.getElement();
+ b.append(element instanceof Integer ? showInvisibles((int) element) : showInvisibles(element.toString()));
+ if (entry.getCount() > 1) {
+ b.append('⨱').append(entry.getCount());
+ }
+ }
+ return b.append('}').toString();
+ }
+
+ private int getMaxDistance(String path, String value, Set<String> paths, Multiset<String> values) {
+ values.clear();
+ final CLDRFile cldrFileToCheck = getCldrFileToCheck();
+ Set<Fingerprint> fingerprints = new HashSet<>();
+ for (String path1 : paths) {
+ final String pathValue = cleanSpaces(path.contentEquals(path1) ? value : cldrFileToCheck.getWinningValue(path1));
+ values.add(pathValue);
+ fingerprints.add(Fingerprint.make(pathValue));
+ }
+ return Fingerprint.maxDistanceBetween(fingerprints);
+ }
+
+ private static final UnicodeMap<String> OTHER_SPACES = new UnicodeMap<String>().putAll(new UnicodeSet("[[:Z:][:S:][:whitespace:]]"), " ").freeze();
+ public static String cleanSpaces(String pathValue) {
+ return OTHER_SPACES.transform(pathValue);
+ }
+
+ // Later
+ private static ConcurrentHashMap<String, Fingerprint> FINGERPRINT_CACHE = new ConcurrentHashMap<>();
+
+ /**
+ * Use cheap distance metric for testing differences; just the number of characters of each kind.
+ */
+ public static class Fingerprint {
+ private final Multiset<Integer> codePointCounts;
+
+ private Fingerprint(String value) {
+ Multiset<Integer> result = TreeMultiset.create();
+ for (int cp : With.codePointArray(value)) {
+ result.add(cp);
+ }
+ codePointCounts = ImmutableMultiset.copyOf(result);
+ }
+
+ public static int maxDistanceBetween(Set<Fingerprint> fingerprintsIn) {
+ int distance = 0;
+ List<Fingerprint> fingerprints = ImmutableList.copyOf(fingerprintsIn); // The set removes duplicates
+ // get the n x n comparisons (but skipping inverses, so (n x (n-1))/2). Quadratic, but most sets are small.
+ for (int i = fingerprints.size()-1; i > 0; --i) { // note the lower bound is different for i and j
+ final Fingerprint fingerprint_i = fingerprints.get(i);
+ for (int j = i-1; j >= 0; --j) {
+ final Fingerprint fingerprints_j = fingerprints.get(j);
+ final int currentDistance = fingerprint_i.getDistanceTo(fingerprints_j);
+ distance = Math.max(distance, currentDistance);
+ }
+ }
+ return distance;
+ }
+
+ public int getDistanceTo(Fingerprint that) {
+ int distance = 0;
+ Set<Integer> allChars = new HashSet<>(that.codePointCounts.elementSet());
+ allChars.addAll(codePointCounts.elementSet());
+
+ for (Integer element :allChars) {
+ final int count = codePointCounts.count(element);
+ final int otherCount = that.codePointCounts.count(element);
+ distance += Math.abs(count - otherCount);
+ }
+ return distance;
+ }
+
+ public int size() {
+ return codePointCounts.size();
+ }
+
+ public static Fingerprint make(String value) {
+ return FINGERPRINT_CACHE.computeIfAbsent(value, v -> new Fingerprint(v));
+ }
+
+ @Override
+ public String toString() {
+ return showInvisibles(codePointCounts);
+ }
+ }
}
diff --git a/tools/java/org/unicode/cldr/test/CheckMetazones.java b/tools/java/org/unicode/cldr/test/CheckMetazones.java
index 5ad88f7..24d7afd 100644
--- a/tools/java/org/unicode/cldr/test/CheckMetazones.java
+++ b/tools/java/org/unicode/cldr/test/CheckMetazones.java
@@ -11,6 +11,7 @@
// to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*Metazones.*
// If you don't need any file initialization or postprocessing, you only need this one routine
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
// it helps performance to have a quick reject of most paths
diff --git a/tools/java/org/unicode/cldr/test/CheckNew.java b/tools/java/org/unicode/cldr/test/CheckNew.java
index 6a17f47..6a75c81 100644
--- a/tools/java/org/unicode/cldr/test/CheckNew.java
+++ b/tools/java/org/unicode/cldr/test/CheckNew.java
@@ -2,16 +2,16 @@
import java.util.Date;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
-import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CLDRFile.Status;
import org.unicode.cldr.util.Factory;
public class CheckNew extends FactoryCheckCLDR {
private OutdatedPaths outdatedPaths;
- private CLDRFile annotationsRoot;
+ boolean isRoot;
public CheckNew(Factory factory) {
super(factory);
@@ -24,41 +24,30 @@
if (cldrFileToCheck == null) {
return this;
}
- // if (Phase.VETTING == getPhase()) {
- // setSkipTest(false); // ok
- // } else {
- // setSkipTest(true);
- // return this;
- // }
-
super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
- annotationsRoot = CLDRConfig.getInstance().getAnnotationsFactory().make("root", false);
+ isRoot = "root".equals(cldrFileToCheck.getLocaleID());
+
return this;
}
+ static final Pattern BAD_EMOJI = Pattern.compile("E\\d+(\\.\\d+)?-\\d+");
+
@Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
CLDRFile cldrFileToCheck = getCldrFileToCheck();
- if (path.startsWith("//ldml/annotations/annotation") && value != null) {
+ if (!isRoot
+ && value != null
+ && path.startsWith("//ldml/annotations/annotation")
+ && cldrFileToCheck.getUnresolved().getStringValue(path) != null) { // don't check inherited values
// first see if the value is inherited or not
- boolean skip = false;
- if (cldrFileToCheck.isResolved()) {
- Status status = new Status();
- String localeFound = cldrFileToCheck.getSourceLocaleID(path, status);
- if ("root".equals(localeFound)) {
- skip = true;
- }
- }
- if (!skip) {
- String rootValue = annotationsRoot.getStringValueWithBailey(path);
- if (value.equals(rootValue)) {
- result.add(new CheckStatus().setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.valueMustBeOverridden)
- .setMessage("This value must be a real translation, NOT the name/keyword placeholder."));
- }
+ Matcher matcher = BAD_EMOJI.matcher(value);
+ if (matcher.matches()) {
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.valueMustBeOverridden)
+ .setMessage("This value must be a real translation, NOT the name/keyword placeholder."));
}
}
diff --git a/tools/java/org/unicode/cldr/test/CheckNumbers.java b/tools/java/org/unicode/cldr/test/CheckNumbers.java
index cbc815f..76203cc 100644
--- a/tools/java/org/unicode/cldr/test/CheckNumbers.java
+++ b/tools/java/org/unicode/cldr/test/CheckNumbers.java
@@ -33,7 +33,7 @@
public class CheckNumbers extends FactoryCheckCLDR {
private static final Splitter SEMI_SPLITTER = Splitter.on(';');
-
+
private static final Set<String> SKIP_TIME_SEPARATOR = ImmutableSet.of("nds", "fr_CA");
private static final UnicodeSet FORBIDDEN_NUMERIC_PATTERN_CHARS = new UnicodeSet("[[:n:]-[0]]");
@@ -188,11 +188,11 @@
if (patternForHm != null && !patternForHm.contains(value)) {
// Should be fixed to not require hack, see #11833
if (!SKIP_TIME_SEPARATOR.contains(getCldrFileToCheck().getLocaleID())) {
- result.add(new CheckStatus()
- .setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.invalidSymbol)
- .setMessage("Invalid timeSeparator: " + value + "; must match what is used in Hm time pattern: " + patternForHm));
+ result.add(new CheckStatus()
+ .setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.invalidSymbol)
+ .setMessage("Invalid timeSeparator: " + value + "; must match what is used in Hm time pattern: " + patternForHm));
}
}
}
@@ -202,7 +202,7 @@
if (type == NumericType.NOT_NUMERIC) {
return this; // skip
}
- XPathParts parts = XPathParts.getInstance(path); // can't be frozen because some of the following code modifies it!
+ XPathParts parts = XPathParts.getFrozenInstance(path);
boolean isPositive = true;
for (String patternPart : SEMI_SPLITTER.split(value)) {
@@ -280,6 +280,7 @@
// Tests that assume that the value is a valid number pattern.
// Notice that we pick up any exceptions, so that we can
// give a reasonable error message.
+ parts = parts.cloneAsThawed();
try {
if (type == NumericType.DECIMAL_ABBREVIATED || type == NumericType.CURRENCY_ABBREVIATED) {
// Check for consistency in short/long decimal formats.
@@ -373,6 +374,10 @@
return this;
}
+ /**
+ * Only called when we are looking at compact decimals. Make sure that we have a consistent number of 0's at each level, and check for missing 0's.
+ * (The latter are only allowed for "singular" plural forms).
+ */
private void checkDecimalFormatConsistency(XPathParts parts, String path, String value,
List<CheckStatus> result, NumericType type) {
// Look for duplicates of decimal formats with the same number
@@ -389,15 +394,36 @@
// can happen if count is numeric literal, like "1"
}
CLDRFile resolvedFile = getResolvedCldrFileToCheck();
- Set<String> inconsistentItems = new TreeSet<String>();
- Set<Count> otherCounts = new HashSet<Count>(pluralTypes);
+ Set<String> inconsistentItems = new TreeSet<>();
+ Set<Count> otherCounts = new HashSet<>(pluralTypes);
if (thisCount != null) {
- if (pluralExamples.get(thisCount).size() == 1 && numIntegerDigits <= 0) {
- // If a plural case corresponds to a single double value, the format is
- // allowed to not include a numeric value and in this way be inconsistent
- // with the numeric formats used for other plural cases.
+ Set<Double> pe = pluralExamples.get(thisCount);
+ if (pe == null) {
+ /*
+ * This can happen for unknown reasons when path =
+ * //ldml/numbers/currencyFormats[@numberSystem="latn"]/currencyFormatLength[@type="short"]/currencyFormat[@type="standard"]/pattern[@type="1000"][@count="one"]
+ * TODO: something? At least don't throw NullPointerException, as happened when the code
+ * was "... pluralExamples.get(thisCount).size() ..."; never assume get() returns non-null
+ */
return;
}
+ if (!value.contains("0")) {
+ switch (pe.size()) {
+ case 0: // do nothing, shouldn't ever happen
+ break;
+ case 1:
+ // If a plural case corresponds to a single double value, the format is
+ // allowed to not include a numeric value and in this way be inconsistent
+ // with the numeric formats used for other plural cases.
+ return;
+ default: // we have too many digits
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.missingZeros)
+ .setMessage("Values without a zero must only be used where there is only one possible numeric form, but this has multiple: {0} ",
+ pe.toString()));
+ }
+ }
otherCounts.remove(thisCount);
}
for (Count count : otherCounts) {
@@ -537,6 +563,7 @@
/**
* Produce a canonical pattern, which will vary according to type and whether it is posix or not.
+ * @param count
*
* @param path
*/
@@ -552,7 +579,10 @@
df.setMaximumFractionDigits(digits[2]);
pattern = df.toPattern();
} else { // of form 1000. Result must be 0+(.0+)?
- if (type == NumericType.CURRENCY_ABBREVIATED) {
+ if (type == NumericType.CURRENCY_ABBREVIATED || type == NumericType.DECIMAL_ABBREVIATED) {
+ if (!inpattern.contains("0")) {
+ return inpattern; // we check in checkDecimalFormatConsistency to make sure that the "no number" case is allowed.
+ }
if (!inpattern.contains("0.0")) {
df.setMinimumFractionDigits(0); // correct the current rewrite
}
@@ -582,6 +612,7 @@
return this;
}
+ @Override
public SimpleDemo getDemo() {
return new MyDemo().setFormat(df);
}
@@ -594,10 +625,12 @@
static class MyDemo extends FormatDemo {
private DecimalFormat df;
+ @Override
protected String getPattern() {
return df.toPattern();
}
+ @Override
protected String getSampleInput() {
return String.valueOf(ExampleGenerator.NUMBER_SAMPLE);
}
@@ -607,6 +640,7 @@
return this;
}
+ @Override
protected void getArguments(Map<String, String> inout) {
currentPattern = currentInput = currentFormatted = currentReparsed = "?";
double d;
diff --git a/tools/java/org/unicode/cldr/test/CheckUnits.java b/tools/java/org/unicode/cldr/test/CheckUnits.java
index d3f728e..e32da4e 100644
--- a/tools/java/org/unicode/cldr/test/CheckUnits.java
+++ b/tools/java/org/unicode/cldr/test/CheckUnits.java
@@ -1,45 +1,90 @@
package org.unicode.cldr.test;
+import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;
import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
+import org.unicode.cldr.util.CLDRConfig;
+import org.unicode.cldr.util.CLDRFile;
+import org.unicode.cldr.util.GrammarInfo;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
import org.unicode.cldr.util.PatternCache;
+import org.unicode.cldr.util.UnitConverter;
+import org.unicode.cldr.util.UnitConverter.UnitId;
+import org.unicode.cldr.util.UnitPathType;
import org.unicode.cldr.util.XPathParts;
import com.ibm.icu.text.SimpleFormatter;
+import com.ibm.icu.text.UnicodeSet;
public class CheckUnits extends CheckCLDR {
private static final Pattern HOUR_SYMBOL = PatternCache.get("h{1,2}");
private static final Pattern MINUTE_SYMBOL = PatternCache.get("m{1,2}");
private static final Pattern SECONDS_SYMBOL = PatternCache.get("ss");
+ private static final UnicodeSet DISALLOW_LONG_POWER = new UnicodeSet("[²³]").freeze();
+
+ static final UnitConverter unitConverter = CLDRConfig.getInstance().getSupplementalDataInfo().getUnitConverter();
+
+ private Collection<String> genders = null;
+
+ @Override
+ public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options, List<CheckStatus> possibleErrors) {
+ super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
+
+ GrammarInfo grammarInfo = CLDRConfig.getInstance().getSupplementalDataInfo().getGrammarInfo(cldrFileToCheck.getLocaleID());
+ genders = grammarInfo == null ? null : grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+
+ return this;
+ }
@Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
List<CheckStatus> result) {
- if (!path.startsWith("//ldml/units")) {
+ if (value == null || !path.startsWith("//ldml/units")) {
return this;
}
+ final XPathParts parts = XPathParts.getFrozenInstance(path);
+ String finalElement = parts.getElement(-1);
+
+ if (genders != null && !genders.isEmpty() && finalElement.equals("gender")) {
+ if (!genders.contains(value)) {
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.invalidGenderCode)
+ .setMessage("The gender value for this locale must be one of: {0}", genders));
+ }
+ }
+
// Note, the following test has some overlaps with the checkAndReplacePlaceholders
// test in CheckForExamplars (why there?). That is probably OK, they check in
// different ways, but some errors will produce two somewhat different error messages.
- if (path.startsWith("//ldml/units/unitLength")) {
+ UnitPathType pathType = UnitPathType.getPathType(parts);
+ if (pathType != null) {
int min = 0;
int max = 0;
- if (path.contains("/compoundUnitPattern1") || path.contains("/unitPrefixPattern")) {
+ switch(pathType) {
+ case power: case prefix:
min = 1;
max = 1;
- } else if (path.contains("/compoundUnitPattern")) {
+ break;
+ case times: case per:
min = 2;
max = 2;
- } else if (path.contains("/perUnitPattern") || path.contains("/coordinateUnitPattern")) {
+ break;
+ case perUnit: case coordinate: // coordinateUnitPattern
min = 1;
max = 1;
- } else if (path.contains("/unitPattern")) {
+ break;
+ case unit:
min = 0;
max = 1;
- } // else we have displayName, with min/max = 0
+ break;
+ default: // 0, 0
+ }
if (max > 0) {
try {
SimpleFormatter sf = SimpleFormatter.compileMinMaxArguments(value, min, max);
@@ -49,37 +94,77 @@
.setMessage("Invalid unit pattern, must have min " + min + " and max " + max + " distinct placeholders of the form {n}"));
}
}
+ String idType;
+ switch(pathType) {
+ case power: {
+ final String width = parts.getAttributeValue(-3, "type");
+ if (value != null && "long".contentEquals(width)) {
+ if (DISALLOW_LONG_POWER.containsSome(fixedValueIfInherited(value, path))) {
+ String unresolvedValue = getCldrFileToCheck().getUnresolved().getStringValue(path);
+ if (unresolvedValue != null) {
+ final String message = genders == null
+ ? "Long value for power can’t use superscripts; it must be spelled out."
+ : "Long value for power can’t use superscripts; it must be spelled out. [NOTE: values can vary by gender.]";
+ result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.longPowerWithSubscripts)
+ .setMessage(message));
+ }
+ }
+ }
+ }
+ // fall through
+ case prefix:
+ idType = parts.getAttributeValue(-2, "type");
+ for (String shortUnitId : pathType.sampleComposedShortUnitIds.get(idType)) {
+ final UnitId unitId = unitConverter.createUnitId(shortUnitId);
+ final String width = parts.getAttributeValue(-3, "type");
+ String count = parts.getAttributeValue(-1, "count");
+ String caseVariant = parts.getAttributeValue(-1, "case");
+ final CLDRFile cldrFile = getCldrFileToCheck();
+ String explicitPattern = UnitPathType.unit.getTrans(cldrFile, width, shortUnitId, count, caseVariant, null, null);
+ if (explicitPattern != null) {
+ String composedPattern = unitId.toString(cldrFile, width, count, caseVariant, null, false);
+ if (composedPattern != null && !explicitPattern.equals(composedPattern)) {
+ unitId.toString(cldrFile, width, count, caseVariant, null, false); // for debugging
+ result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType)
+ .setSubtype(Subtype.mismatchedUnitComponent)
+ .setMessage("Mismatched component: «{0}» produces «{1}», but the explicit translation is «{2}». See http://cldr.unicode.org/translation/units-1/units#TOC-Compound-Units", value, composedPattern, explicitPattern));
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
- if (!path.contains("durationUnitPattern")) {
- return this;
- }
+ if (pathType == UnitPathType.duration) {
+ XPathParts xpp = parts;
+ String durationUnitType = xpp.findAttributeValue("durationUnit", "type");
+ boolean hasHourSymbol = HOUR_SYMBOL.matcher(value).find();
+ boolean hasMinuteSymbol = MINUTE_SYMBOL.matcher(value).find();
+ boolean hasSecondsSymbol = SECONDS_SYMBOL.matcher(value).find();
- XPathParts xpp = XPathParts.getFrozenInstance(path);
- String durationUnitType = xpp.findAttributeValue("durationUnit", "type");
- boolean hasHourSymbol = HOUR_SYMBOL.matcher(value).find();
- boolean hasMinuteSymbol = MINUTE_SYMBOL.matcher(value).find();
- boolean hasSecondsSymbol = SECONDS_SYMBOL.matcher(value).find();
-
- if (durationUnitType.contains("h") && !hasHourSymbol) {
- /* Changed message from "The hour symbol (h or hh) is missing"
- * to "The hour indicator should be either h or hh for duration"
- * per http://unicode.org/cldr/trac/ticket/10999
- */
- result.add(new CheckStatus().setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.invalidDurationUnitPattern)
- .setMessage("The hour indicator should be either h or hh for duration."));
- } else if (durationUnitType.contains("m") && !hasMinuteSymbol) {
- result.add(new CheckStatus().setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.invalidDurationUnitPattern)
- .setMessage("The minutes symbol (m or mm) is missing."));
- } else if (durationUnitType.contains("s") && !hasSecondsSymbol) {
- result.add(new CheckStatus().setCause(this)
- .setMainType(CheckStatus.errorType)
- .setSubtype(Subtype.invalidDurationUnitPattern)
- .setMessage("The seconds symbol (ss) is missing."));
+ if (durationUnitType.contains("h") && !hasHourSymbol) {
+ /* Changed message from "The hour symbol (h or hh) is missing"
+ * to "The hour indicator should be either h or hh for duration"
+ * per http://unicode.org/cldr/trac/ticket/10999
+ */
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.invalidDurationUnitPattern)
+ .setMessage("The hour indicator should be either h or hh for duration."));
+ } else if (durationUnitType.contains("m") && !hasMinuteSymbol) {
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.invalidDurationUnitPattern)
+ .setMessage("The minutes symbol (m or mm) is missing."));
+ } else if (durationUnitType.contains("s") && !hasSecondsSymbol) {
+ result.add(new CheckStatus().setCause(this)
+ .setMainType(CheckStatus.errorType)
+ .setSubtype(Subtype.invalidDurationUnitPattern)
+ .setMessage("The seconds symbol (ss) is missing."));
+ }
}
return this;
}
diff --git a/tools/java/org/unicode/cldr/test/CheckWidths.java b/tools/java/org/unicode/cldr/test/CheckWidths.java
index 76a0a94..d508d52 100644
--- a/tools/java/org/unicode/cldr/test/CheckWidths.java
+++ b/tools/java/org/unicode/cldr/test/CheckWidths.java
@@ -20,11 +20,11 @@
private Level requiredLevel;
/**
- * Controls for the warning about too many components, and for when to cause error.
+ * Controls for the warning about too many components, and for when to cause error.
*/
public static final int WARN_COMPONENTS_PER_ANNOTATION = 7;
public static final int MAX_COMPONENTS_PER_ANNOTATION = 16;
-
+
SupplementalDataInfo supplementalData;
private static final double EM = ApproximateWidth.getWidth("月");
@@ -86,7 +86,7 @@
this.message = "Too wide by about {2}% (with common fonts).";
this.subtype = Subtype.valueTooWide;
break;
- case SET_ELEMENTS:
+ case SET_ELEMENTS:
this.message = "Expected no more than {0} items(s), but was {1}.";
this.subtype = Subtype.tooManyValues;
break;
@@ -321,7 +321,7 @@
System.out.println("EMs: " + ApproximateWidth.getWidth("grinning cat face with smiling eyes"));
}
- Set<Limit> found = new LinkedHashSet<Limit>();
+ Set<Limit> found = new LinkedHashSet<>();
@Override
public CheckCLDR handleCheck(String path, String fullPath, String value, Options options, List<CheckStatus> result) {
@@ -358,6 +358,7 @@
return this;
}
+ @Override
public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options,
List<CheckStatus> possibleErrors) {
final String localeID = cldrFileToCheck.getLocaleID();
diff --git a/tools/java/org/unicode/cldr/test/CheckZones.java b/tools/java/org/unicode/cldr/test/CheckZones.java
index f697fe7..1f5d7f6 100644
--- a/tools/java/org/unicode/cldr/test/CheckZones.java
+++ b/tools/java/org/unicode/cldr/test/CheckZones.java
@@ -52,6 +52,7 @@
String previousFrom = new String("1970-01-01");
String previousTo = new String("present");
+ @Override
public CheckCLDR handleCheck(String path, String fullPath, String value,
Options options, List<CheckStatus> result) {
if (fullPath == null) return this; // skip paths that we don't have
@@ -114,7 +115,7 @@
public static String exampleTextForXpath(TimezoneFormatter timezoneFormatter, String path) {
XPathParts parts = XPathParts.getFrozenInstance(path);
if (parts.containsElement("zone")) {
- String id = (String) parts.getAttributeValue(3, "type");
+ String id = parts.getAttributeValue(3, "type");
TimeZone tz = TimeZone.getTimeZone(id);
String pat = "vvvv";
if (parts.containsElement("exemplarCity")) {
diff --git a/tools/java/org/unicode/cldr/test/ConsoleCheckCLDR.java b/tools/java/org/unicode/cldr/test/ConsoleCheckCLDR.java
index 677ba9e..8465b76 100644
--- a/tools/java/org/unicode/cldr/test/ConsoleCheckCLDR.java
+++ b/tools/java/org/unicode/cldr/test/ConsoleCheckCLDR.java
@@ -49,6 +49,7 @@
import org.unicode.cldr.util.Pair;
import org.unicode.cldr.util.PathDescription;
import org.unicode.cldr.util.PathHeader;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StandardCodes;
@@ -84,8 +85,10 @@
*
*/
@CLDRTool(alias = "check",
- description = "Run CheckCLDR against CLDR data")
+description = "Run CheckCLDR against CLDR data")
public class ConsoleCheckCLDR {
+ private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance();
+ private static final PathHeader.Factory PATH_HEADER_FACTORY = PathHeader.getFactory();
public static boolean showStackTrace = false;
public static boolean errorsOnly = false;
static boolean SHOW_LOCALE = true;
@@ -114,8 +117,8 @@
SUBTYPE_FILTER = 19,
SOURCE_ALL = 20,
BAILEY = 21
- // VOTE_RESOLVE2 = 21
- ;
+ // VOTE_RESOLVE2 = 21
+ ;
static final String SOURCE_DIRS = CLDRPaths.MAIN_DIRECTORY + "," + CLDRPaths.ANNOTATIONS_DIRECTORY + "," + CLDRPaths.SEED_DIRECTORY;
@@ -208,6 +211,7 @@
LanguageTagParser languageTagParser1 = new LanguageTagParser();
LanguageTagParser languageTagParser2 = new LanguageTagParser();
+ @Override
public int compare(String o1, String o2) {
String ls1 = languageTagParser1.set(o1).getLanguageScript();
String ls2 = languageTagParser2.set(o2).getLanguageScript();
@@ -240,8 +244,8 @@
"-b \t check bailey values (" + CldrUtility.INHERITANCE_MARKER + ")",
};
- static Counter<ErrorType> subtotalCount = new Counter<ErrorType>(true); // new ErrorCount();
- static Counter<ErrorType> totalCount = new Counter<ErrorType>(true);
+ static Counter<ErrorType> subtotalCount = new Counter<>(true); // new ErrorCount();
+ static Counter<ErrorType> totalCount = new Counter<>(true);
/**
* This will be the test framework way of using these tests. It is preliminary for now.
@@ -319,7 +323,7 @@
+ organizations);
}
}
- final CLDRConfig cldrConf = CLDRConfig.getInstance();
+ final CLDRConfig cldrConf = CLDR_CONFIG;
// set the envronment to UNITTEST as suggested
cldrConf.setEnvironment(Environment.UNITTEST);
// get the Phase from CLDRConfig object
@@ -396,7 +400,7 @@
true, null);
VoteResolver.setVoterToInfo(CldrUtility.checkValidFile(CLDRPaths.BASE_DIRECTORY
+ "incoming/vetted/usersa/usersa.xml", false, null));
- voteResolver = new VoteResolver<String>();
+ voteResolver = new VoteResolver<>();
}
// check stuff
@@ -409,7 +413,7 @@
System.out.println("Source directories:\n");
for (File f : sourceDirectories) {
System.out.println(" " + f.getPath() + "\t("
- + f.getCanonicalPath() + ")");
+ + PathUtilities.getNormalizedPathString(f) + ")");
}
// System.out.println("factoryFilter: " + factoryFilter);
// System.out.println("test filter: " + checkFilter);
@@ -441,24 +445,24 @@
.setSupplementalDirectory(new File(CLDRPaths.SUPPLEMENTAL_DIRECTORY));
english = backCldrFactory.make("en", true);
- checkCldr.setDisplayInformation(english);
+ CheckCLDR.setDisplayInformation(english);
checkCldr.setEnglishFile(english);
setExampleGenerator(new ExampleGenerator(english, english, CLDRPaths.SUPPLEMENTAL_DIRECTORY));
PathShower pathShower = new PathShower();
// call on the files
- Set<String> locales = new TreeSet<String>(baseFirstCollator);
+ Set<String> locales = new TreeSet<>(baseFirstCollator);
locales.addAll(cldrFactory.getAvailable());
- List<CheckStatus> result = new ArrayList<CheckStatus>();
- Set<PathHeader> paths = new TreeSet<PathHeader>(); // CLDRFile.ldmlComparator);
+ List<CheckStatus> result = new ArrayList<>();
+ Set<PathHeader> paths = new TreeSet<>(); // CLDRFile.ldmlComparator);
Map m = new TreeMap();
// double testNumber = 0;
- Map<String, String> options = new HashMap<String, String>();
+ Map<String, String> options = new HashMap<>();
FlexibleDateFromCLDR fset = new FlexibleDateFromCLDR();
Set<String> englishPaths = null;
- Set<String> fatalErrors = new TreeSet<String>();
+ Set<String> fatalErrors = new TreeSet<>();
showHeaderLine();
@@ -468,7 +472,7 @@
String lastBaseLanguage = "";
PathHeader.Factory pathHeaderFactory = PathHeader.getFactory(english);
- final List<String> specialPurposeLocales = new ArrayList<String>(Arrays.asList("en_US_POSIX", "en_ZZ", "und", "und_ZZ"));
+ final List<String> specialPurposeLocales = new ArrayList<>(Arrays.asList("en_US_POSIX", "en_ZZ", "und", "und_ZZ"));
for (String localeID : locales) {
if (CLDRFile.isSupplementalName(localeID)) continue;
if (supplementalDataInfo.getDefaultContentLocales().contains(localeID)) {
@@ -578,7 +582,7 @@
showValue(file, null, localeID, null, null, null, null, statusString, status.getSubtype());
}
paths.clear();
- // CollectionUtilities.addAll(file.iterator(pathFilter), paths);
+
CoverageInfo covInfo = cldrConf.getCoverageInfo();
for (String path : file.fullIterable()) {
if (pathFilter != null && !pathFilter.reset(path).find()) {
@@ -596,10 +600,9 @@
// addPrettyPaths(file, file.getExtraPaths(), pathFilter, prettyPathMaker, noaliases, false, paths);
// also add the English paths
- // CollectionUtilities.addAll(checkCldr.getDisplayInformation().iterator(pathFilter), paths);
// initialize the first time in.
if (englishPaths == null) {
- englishPaths = new HashSet<String>();
+ englishPaths = new HashSet<>();
final CLDRFile displayFile = CheckCLDR.getDisplayInformation();
addPrettyPaths(displayFile, pathFilter, pathHeaderFactory, noaliases, true, englishPaths);
addPrettyPaths(displayFile, displayFile.getExtraPaths(), pathFilter, pathHeaderFactory, noaliases,
@@ -684,7 +687,25 @@
CheckStatus status = it3.next();
String statusString = status.toString(); // com.ibm.icu.impl.Utility.escape(
CheckStatus.Type statusType = status.getType();
- if (errorsOnly && !statusType.equals(CheckStatus.errorType)) continue;
+ Object[] parameters = status.getParameters();
+
+ if (parameters != null) {
+ if (parameters.length >= 1 && status.getCause().getClass() == CheckForExemplars.class) {
+ try {
+ UnicodeSet set = new UnicodeSet(parameters[0].toString());
+ if (status.getMessage().contains("currency")) {
+ missingCurrencyExemplars.addAll(set);
+ } else {
+ missingExemplars.addAll(set);
+ }
+ } catch (RuntimeException e) {
+ } // skip if not parseable as set
+ }
+ }
+
+ if (errorsOnly && !statusType.equals(CheckStatus.errorType)) {
+ continue;
+ }
if (subtypeFilter != null) {
if (!subtypeFilter.contains(status.getSubtype())) {
@@ -692,7 +713,7 @@
}
}
if (checkOnSubmit) {
- if (!status.isCheckOnSubmit() || !statusType.equals(status.errorType)) continue;
+ if (!status.isCheckOnSubmit() || !statusType.equals(CheckStatus.errorType)) continue;
}
// System.out.print("Locale:\t" + getLocaleAndName(localeID) + "\t");
@@ -707,29 +728,19 @@
}
continue;
}
- showValue(file, prettyPath, localeID, example, path, value, fullPath, statusString,
- status.getSubtype());
- showedOne = true;
- Object[] parameters = status.getParameters();
if (parameters != null) {
- if (parameters.length >= 1 && status.getCause().getClass() == CheckForExemplars.class) {
- try {
- UnicodeSet set = new UnicodeSet(parameters[0].toString());
- if (status.getMessage().contains("currency")) {
- missingCurrencyExemplars.addAll(set);
- } else {
- missingExemplars.addAll(set);
- }
- } catch (RuntimeException e) {
- } // skip if not parseable as set
- }
for (int i = 0; i < parameters.length; ++i) {
if (showStackTrace && parameters[i] instanceof Throwable) {
((Throwable) parameters[i]).printStackTrace();
}
}
}
+
+ showValue(file, prettyPath, localeID, example, path, value, fullPath, statusString,
+ status.getSubtype());
+ showedOne = true;
+
// survey tool will use: if (status.hasHTMLMessage())
// System.out.println(status.getHTMLMessage());
}
@@ -752,23 +763,25 @@
missingExemplars.removeAll(new UnicodeSet("[[:Uppercase:]-[İ]]")); // remove uppercase #4670
if (missingExemplars.size() != 0) {
Collator col = Collator.getInstance(new ULocale(localeID));
- showSummary(localeID, level, "Total missing from general exemplars:\t" + new UnicodeSetPrettyPrinter()
- .setOrdering(col != null ? col : Collator.getInstance(ULocale.ROOT))
- .setSpaceComparator(col != null ? col : Collator.getInstance(ULocale.ROOT)
- .setStrength2(Collator.PRIMARY))
- .setCompressRanges(true)
- .format(missingExemplars));
+ showSummary(localeID, level, "Total missing from general exemplars:\t" +
+ missingExemplars.size()
+ + "\t" + new UnicodeSetPrettyPrinter()
+ .setOrdering(col != null ? col : Collator.getInstance(ULocale.ROOT))
+ .setSpaceComparator(col != null ? col : Collator.getInstance(ULocale.ROOT)
+ .setStrength2(Collator.PRIMARY))
+ .setCompressRanges(false)
+ .format(missingExemplars));
}
}
if (missingCurrencyExemplars.size() != 0) {
Collator col = Collator.getInstance(new ULocale(localeID));
showSummary(localeID, level, "Total missing from currency exemplars:\t"
+ new UnicodeSetPrettyPrinter()
- .setOrdering(col != null ? col : Collator.getInstance(ULocale.ROOT))
- .setSpaceComparator(col != null ? col : Collator.getInstance(ULocale.ROOT)
- .setStrength2(Collator.PRIMARY))
- .setCompressRanges(true)
- .format(missingCurrencyExemplars));
+ .setOrdering(col != null ? col : Collator.getInstance(ULocale.ROOT))
+ .setSpaceComparator(col != null ? col : Collator.getInstance(ULocale.ROOT)
+ .setStrength2(Collator.PRIMARY))
+ .setCompressRanges(true)
+ .format(missingCurrencyExemplars));
}
for (ErrorType type : subtotalCount.keySet()) {
showSummary(localeID, level, "Subtotal " + type + ":\t" + subtotalCount.getCount(type));
@@ -839,12 +852,12 @@
static class LocaleVotingData {
private int disputedCount = 0;
- Counter<Organization> missingOrganizationCounter = new Counter<Organization>(true);
- Counter<Organization> goodOrganizationCounter = new Counter<Organization>(true);
- Counter<Organization> conflictedOrganizations = new Counter<Organization>(true);
- Counter<VoteResolver.Status> winningStatusCounter = new Counter<VoteResolver.Status>(true);
+ Counter<Organization> missingOrganizationCounter = new Counter<>(true);
+ Counter<Organization> goodOrganizationCounter = new Counter<>(true);
+ Counter<Organization> conflictedOrganizations = new Counter<>(true);
+ Counter<VoteResolver.Status> winningStatusCounter = new Counter<>(true);
- static Map<String, LocaleVotingData> localeToErrors = new HashMap<String, LocaleVotingData>();
+ static Map<String, LocaleVotingData> localeToErrors = new HashMap<>();
private static Map<Integer, String> idToPath;
public static void resolveErrors(String locale) {
@@ -858,7 +871,7 @@
Map<Integer, Map<Integer, CandidateInfo>> info = VoteResolver
.getBaseToAlternateToInfo(resolveVotesDirectory + locale + ".xml");
- Map<String, Integer> valueToItem = new HashMap<String, Integer>();
+ Map<String, Integer> valueToItem = new HashMap<>();
for (int basePath : info.keySet()) {
final Map<Integer, CandidateInfo> itemInfo = info.get(basePath);
@@ -936,7 +949,7 @@
if (missingOrganizationCounter.size() > 0) {
System.out.println(getLocaleAndName(locale) + "\tMIA organizations:\t" + missingOrganizationCounter);
System.out
- .println(getLocaleAndName(locale) + "\tConflicted organizations:\t" + conflictedOrganizations);
+ .println(getLocaleAndName(locale) + "\tConflicted organizations:\t" + conflictedOrganizations);
System.out.println(getLocaleAndName(locale) + "\tCool organizations!:\t" + goodOrganizationCounter);
}
System.out.println(getLocaleAndName(locale) + "\tOptimal Status:\t" + winningStatusCounter);
@@ -999,7 +1012,7 @@
}
return shortStatus;
}
- };
+ }
/*
* static class ErrorCount implements Comparable<ErrorCount> {
@@ -1041,45 +1054,43 @@
ErrorFile.errorFileTable = new TablePrinter();
errorFileCounter.clear();
ErrorFile.errorFileTable.setCaption("Problem Details")
- .addColumn("Problem").setCellAttributes("align=\"left\" class=\"{0}\"").setSortPriority(0)
- .setSpanRows(true)
- .setBreakSpans(true).setRepeatHeader(true).setHeaderCell(true)
- .addColumn("Subtype").setCellAttributes("align=\"left\" class=\"{1}\"").setSortPriority(1)
- .setSpanRows(true)
- .setBreakSpans(true).setRepeatHeader(true).setHeaderCell(true)
- .addColumn("Locale").setCellAttributes("class=\"{1}\"")
- .setCellPattern("<a href=\"http://unicode.org/cldr/apps/survey?_={0}\">{0}</a>").setSortPriority(2)
- .setSpanRows(true).setBreakSpans(true)//.setRepeatDivider(true)
- .addColumn("Name").setCellAttributes("class=\"{1}\"").setSpanRows(true)
- .setBreakSpans(true)
- .addColumn("Section").setCellAttributes("class=\"{1}\"").setSortPriority(3)
- .setCellPattern("<a href=\"http://unicode.org/cldr/apps/survey?_={3}&x={0}\">{0}</a>")
- .setSpanRows(true)
- .addColumn("Count").setCellAttributes("class=\"{1}\" align=\"right\"");
+ .addColumn("Problem").setCellAttributes("align=\"left\" class=\"{0}\"").setSortPriority(0)
+ .setSpanRows(true)
+ .setBreakSpans(true).setRepeatHeader(true).setHeaderCell(true)
+ .addColumn("Subtype").setCellAttributes("align=\"left\" class=\"{1}\"").setSortPriority(1)
+ .setSpanRows(true)
+ .setBreakSpans(true).setRepeatHeader(true).setHeaderCell(true)
+ .addColumn("Locale").setCellAttributes("class=\"{1}\"")
+ .setCellPattern("<a href=\"http://unicode.org/cldr/apps/survey?_={0}\">{0}</a>").setSortPriority(2)
+ .setSpanRows(true).setBreakSpans(true)//.setRepeatDivider(true)
+ .addColumn("Name").setCellAttributes("class=\"{1}\"").setSpanRows(true)
+ .setBreakSpans(true)
+ .addColumn("Section").setCellAttributes("class=\"{1}\"").setSortPriority(3)
+ .setCellPattern("<a href=\"http://unicode.org/cldr/apps/survey?_={3}&x={0}\">{0}</a>")
+ .setSpanRows(true)
+ .addColumn("Count").setCellAttributes("class=\"{1}\" align=\"right\"");
showIndexHead("", localeID, ErrorFile.errorFileWriter);
}
static TablePrinter errorFileTable = new TablePrinter();
- static Counter<Row.R4<String, String, ErrorType, Subtype>> errorFileCounter = new Counter<Row.R4<String, String, ErrorType, Subtype>>(
+ static Counter<Row.R4<String, String, ErrorType, Subtype>> errorFileCounter = new Counter<>(
true);
private static void addDataToErrorFile(String localeID, String path, ErrorType shortStatus,
Subtype subType) {
- String section = path == null
- ? null
- : org.unicode.cldr.util.PathUtilities.xpathToMenu(path);
+ String section = path == null ? null : XPathToMenu.xpathToMenu(path);
if (section == null) {
section = "general";
}
errorFileCounter.add(
- new Row.R4<String, String, ErrorType, Subtype>(localeID, section, shortStatus, subType), 1);
+ new Row.R4<>(localeID, section, shortStatus, subType), 1);
ErrorFile.sectionToProblemsToLocaleToCount.add(
- new Row.R4<String, ErrorType, Subtype, String>(section, shortStatus, subType, localeID), 1);
+ new Row.R4<>(section, shortStatus, subType, localeID), 1);
}
private static void closeErrorFile() {
- Set<String> locales = new TreeSet<String>();
+ Set<String> locales = new TreeSet<>();
for (Row.R4<String, String, ErrorType, Subtype> item : errorFileCounter.keySet()) {
String localeID = item.get0();
locales.add(localeID);
@@ -1089,17 +1100,17 @@
// final String prettyPath = path == null ? "general" : prettyPathMaker.getPrettyPath(path, true);
// final String outputForm = path == null ? "general" : prettyPathMaker.getOutputForm(prettyPath);
errorFileTable.addRow()
- .addCell(shortStatus)
- .addCell(subtype)
- .addCell(localeID)
- .addCell(ConsoleCheckCLDR.getLocaleName(localeID))
- // .addCell(prettyPath) // menuPath == null ? "" : "<a href='" + link + "'>" + menuPath + "</a>"
- .addCell(section) // menuPath == null ? "" : "<a href='" + link + "'>" + menuPath + "</a>"
- .addCell(errorFileCounter.getCount(item))
- // .addCell(ConsoleCheckCLDR.safeForHtml(path == null ? null :
- // ConsoleCheckCLDR.getEnglishPathValue(path)))
- // .addCell(ConsoleCheckCLDR.safeForHtml(value))
- .finishRow();
+ .addCell(shortStatus)
+ .addCell(subtype)
+ .addCell(localeID)
+ .addCell(ConsoleCheckCLDR.getLocaleName(localeID))
+ // .addCell(prettyPath) // menuPath == null ? "" : "<a href='" + link + "'>" + menuPath + "</a>"
+ .addCell(section) // menuPath == null ? "" : "<a href='" + link + "'>" + menuPath + "</a>"
+ .addCell(errorFileCounter.getCount(item))
+ // .addCell(ConsoleCheckCLDR.safeForHtml(path == null ? null :
+ // ConsoleCheckCLDR.getEnglishPathValue(path)))
+ // .addCell(ConsoleCheckCLDR.safeForHtml(value))
+ .finishRow();
}
if (SHOW_VOTING_INFO) {
@@ -1109,8 +1120,8 @@
.addColumn("Organization")
.addColumn("Missing")
.addColumn("Conflicted")
- // .addColumn("Good")
- ;
+ // .addColumn("Good")
+ ;
for (String localeID : locales) {
// now the voting info
LocaleVotingData localeVotingData = LocaleVotingData.localeToErrors.get(localeID);
@@ -1122,13 +1133,13 @@
orgs.addAll(localeVotingData.goodOrganizationCounter.keySet());
for (Organization org : orgs) {
data.addRow()
- .addCell(ConsoleCheckCLDR.getLinkedLocale(localeID))
- .addCell(ConsoleCheckCLDR.getLocaleName(localeID))
- .addCell(org)
- .addCell(localeVotingData.missingOrganizationCounter.getCount(org))
- .addCell(localeVotingData.conflictedOrganizations.getCount(org))
- // .addCell(localeVotingData.goodOrganizationCounter.getCount(org))
- .finishRow();
+ .addCell(ConsoleCheckCLDR.getLinkedLocale(localeID))
+ .addCell(ConsoleCheckCLDR.getLocaleName(localeID))
+ .addCell(org)
+ .addCell(localeVotingData.missingOrganizationCounter.getCount(org))
+ .addCell(localeVotingData.conflictedOrganizations.getCount(org))
+ // .addCell(localeVotingData.goodOrganizationCounter.getCount(org))
+ .finishRow();
}
}
}
@@ -1163,15 +1174,15 @@
.addColumn("Name");
if (SHOW_VOTING_INFO) {
indexTablePrinter.addColumn("Summary")
- .addColumn("Missing");
+ .addColumn("Missing");
}
for (Organization org : orgToLocales.keySet()) {
indexTablePrinter.addColumn(org.toString().substring(0, 2));
}
indexTablePrinter
- .addColumn("Disputed").setHeaderAttributes("class='disputed'").setCellAttributes("class='disputed'")
- .addColumn("Conflicted").setHeaderAttributes("class='conflicted'")
- .setCellAttributes("class='conflicted'");
+ .addColumn("Disputed").setHeaderAttributes("class='disputed'").setCellAttributes("class='disputed'")
+ .addColumn("Conflicted").setHeaderAttributes("class='conflicted'")
+ .setCellAttributes("class='conflicted'");
for (ConsoleCheckCLDR.ErrorType type : ConsoleCheckCLDR.ErrorType.showInSummary) {
String columnTitle = UCharacter.toTitleCase(type.toString(), null);
@@ -1182,7 +1193,7 @@
columnTitle = "MV: " + columnTitle;
}
indexTablePrinter.addColumn(columnTitle).setHeaderAttributes("class='" + type + "'")
- .setCellAttributes("class='" + type + "'");
+ .setCellAttributes("class='" + type + "'");
}
// now fill in the data
@@ -1197,20 +1208,20 @@
}
final String baseLanguage = ltp.set(htmlOpenedFileLanguage).getLanguage();
indexTablePrinter.addRow()
- .addCell(baseLanguage)
- .addCell(htmlOpenedFileLanguage)
- .addCell(ConsoleCheckCLDR.getLocaleName(htmlOpenedFileLanguage));
+ .addCell(baseLanguage)
+ .addCell(htmlOpenedFileLanguage)
+ .addCell(ConsoleCheckCLDR.getLocaleName(htmlOpenedFileLanguage));
if (SHOW_VOTING_INFO) {
indexTablePrinter.addCell(votingData == null ? "" : votingData.winningStatusCounter.toString())
- .addCell(votingData == null ? "" : votingData.missingOrganizationCounter.toString());
+ .addCell(votingData == null ? "" : votingData.missingOrganizationCounter.toString());
}
for (Organization org : orgToLocales.keySet()) {
indexTablePrinter.addCell(orgToLocales.getAll(org).contains(htmlOpenedFileLanguage) ? org.toString()
.substring(0, 2) : "");
}
indexTablePrinter
- .addCell(votingData == null ? "" : formatSkippingZero(votingData.getDisputedCount()))
- .addCell(votingData == null ? "" : votingData.getConflictedHTML());
+ .addCell(votingData == null ? "" : formatSkippingZero(votingData.getDisputedCount()))
+ .addCell(votingData == null ? "" : votingData.getConflictedHTML());
for (ConsoleCheckCLDR.ErrorType type : ConsoleCheckCLDR.ErrorType.showInSummary) {
indexTablePrinter.addCell(formatSkippingZero(counts.getCount(type)));
}
@@ -1269,12 +1280,12 @@
long count = ErrorFile.sectionToProblemsToLocaleToCount.getCount(sectionAndProblemsAndLocale);
final String section = sectionAndProblemsAndLocale.get0();
indexTablePrinter.addRow()
- .addCell(section)
- .addCell(problem)
- .addCell(subtype)
- .addCell(ConsoleCheckCLDR.getLocaleName(locale))
- .addCell(locale)
- .addCell(count);
+ .addCell(section)
+ .addCell(problem)
+ .addCell(subtype)
+ .addCell(ConsoleCheckCLDR.getLocaleName(locale))
+ .addCell(locale)
+ .addCell(count);
for (Organization org : orgToLocales.keySet()) {
indexTablePrinter.addCell(orgToLocales.getAll(org).contains(locale) ? org.toString().substring(0, 2) : "");
}
@@ -1302,53 +1313,53 @@
title = "Errors in " + ConsoleCheckCLDR.getNameAndLocale(localeID, false);
}
generated_html_index
- .println("<html>" +
- "<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"
- + CldrUtility.LINE_SEPARATOR
- +
- "<title>"
- + title
- + "</title>"
- + CldrUtility.LINE_SEPARATOR
- +
- "<link rel='stylesheet' href='errors.css' type='text/css'>"
- + CldrUtility.LINE_SEPARATOR
- +
- "<base target='_blank'>"
- + CldrUtility.LINE_SEPARATOR
- +
- "</head><body>"
- + CldrUtility.LINE_SEPARATOR
- +
- "<h1>"
- + title
- + "</h1>"
- + CldrUtility.LINE_SEPARATOR
- +
- "<p>"
- +
- "<a href='index.html"
- + (notLocaleSpecific ? "" : "#" + localeID)
- + "'>Index</a>"
- +
- " | "
- +
- "<a href='sections.html"
- + (notLocaleSpecific ? "" : "#" + localeID)
- + "'>Index by Section</a>"
- +
- " | "
- +
- "<a href='http://unicode.org/cldr/data/docs/survey/vetting.html'><b style='background-color: yellow;'><i>Help: How to Vet</i></b></a>"
- +
- "</p>"
- +
- "<p>The following errors have been detected in the locale"
- +
- (notLocaleSpecific
- ? "s. " + org.unicode.cldr.test.HelpMessages.getChartMessages("error_index_header")
- : " " + ConsoleCheckCLDR.getNameAndLocale(localeID, false) + ". "
- + ErrorFile.ERROR_CHART_HEADER));
+ .println("<html>" +
+ "<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "<title>"
+ + title
+ + "</title>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "<link rel='stylesheet' href='errors.css' type='text/css'>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "<base target='_blank'>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "</head><body>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "<h1>"
+ + title
+ + "</h1>"
+ + CldrUtility.LINE_SEPARATOR
+ +
+ "<p>"
+ +
+ "<a href='index.html"
+ + (notLocaleSpecific ? "" : "#" + localeID)
+ + "'>Index</a>"
+ +
+ " | "
+ +
+ "<a href='sections.html"
+ + (notLocaleSpecific ? "" : "#" + localeID)
+ + "'>Index by Section</a>"
+ +
+ " | "
+ +
+ "<a href='http://unicode.org/cldr/data/docs/survey/vetting.html'><b style='background-color: yellow;'><i>Help: How to Vet</i></b></a>"
+ +
+ "</p>"
+ +
+ "<p>The following errors have been detected in the locale"
+ +
+ (notLocaleSpecific
+ ? "s. " + org.unicode.cldr.test.HelpMessages.getChartMessages("error_index_header")
+ : " " + ConsoleCheckCLDR.getNameAndLocale(localeID, false) + ". "
+ + ErrorFile.ERROR_CHART_HEADER));
}
private static void writeErrorFileIndex() throws IOException {
@@ -1372,8 +1383,8 @@
// now store the data for the index
ErrorFile.errorFileIndexData.put(ConsoleCheckCLDR.lastHtmlLocaleID,
- new Pair<String, Counter<ErrorType>>(ConsoleCheckCLDR.lastHtmlLocaleID, ErrorFile.htmlErrorsPerLocale));
- ErrorFile.htmlErrorsPerLocale = new Counter<ErrorType>();
+ new Pair<>(ConsoleCheckCLDR.lastHtmlLocaleID, ErrorFile.htmlErrorsPerLocale));
+ ErrorFile.htmlErrorsPerLocale = new Counter<>();
// }
}
@@ -1384,9 +1395,9 @@
* static Counter<VoteResolver.Status> winningStatusCounter = new Counter<VoteResolver.Status>(true);
*/
- static Counter<ErrorType> htmlErrorsPerLocale = new Counter<ErrorType>(); // ConsoleCheckCLDR.ErrorCount();
+ static Counter<ErrorType> htmlErrorsPerLocale = new Counter<>(); // ConsoleCheckCLDR.ErrorCount();
static PrintWriter generated_html_count = null;
- private static TreeMap<String, Pair<String, Counter<ErrorType>>> errorFileIndexData = new TreeMap<String, Pair<String, Counter<ErrorType>>>();
+ private static TreeMap<String, Pair<String, Counter<ErrorType>>> errorFileIndexData = new TreeMap<>();
// private static ConsoleCheckCLDR.ErrorCount htmlErrorsPerBaseLanguage = new ConsoleCheckCLDR.ErrorCount();
static PrintWriter errorFileWriter = null;
@@ -1401,7 +1412,7 @@
// "<p>Coverage depends on your organizations goals: the highest tier languages should include up through all Modern values.</p>"
// + Utility.LINE_SEPARATOR;
static String generated_html_directory = null;
- public static Counter<Row.R4<String, ErrorType, Subtype, String>> sectionToProblemsToLocaleToCount = new Counter<Row.R4<String, ErrorType, Subtype, String>>();
+ public static Counter<Row.R4<String, ErrorType, Subtype, String>> sectionToProblemsToLocaleToCount = new Counter<>();
}
private static void showSummary(String localeID, Level level, String value) {
@@ -1484,11 +1495,11 @@
if (SHOW_LOCALE) {
if (idView) {
System.out
- .println("Locale\tID\tDesc.\t〈Eng.Value〉\t【Eng.Ex.】\t〈Loc.Value〉\t【Loc.Ex】\t⁅error/warning type⁆\t❮Error/Warning Msg❯");
+ .println("Locale\tID\tDesc.\t〈Eng.Value〉\t【Eng.Ex.】\t〈Loc.Value〉\t【Loc.Ex】\t⁅error/warning type⁆\t❮Error/Warning Msg❯");
} else {
System.out
- .println(
- "Locale\tStatus\t▸PPath◂\t〈Eng.Value〉\t【Eng.Ex.】\t〈Loc.Value〉\t«fill-in»\t【Loc.Ex】\t⁅error/warning type⁆\t❮Error/Warning Msg❯\tFull Path\tAliasedSource/Path?");
+ .println(
+ "Locale\tStatus\t▸PPath◂\t〈Eng.Value〉\t【Eng.Ex.】\t〈Loc.Value〉\t«fill-in»\t【Loc.Ex】\t⁅error/warning type⁆\t❮Error/Warning Msg❯\tFull Path\tAliasedSource/Path?");
}
}
}
@@ -1527,6 +1538,8 @@
String fillinValue = path == null ? null : cldrFile.getFillInValue(path);
fillinValue = fillinValue == null ? "" : fillinValue.equals(value) ? "=" : fillinValue;
+ String pathLink = CLDR_CONFIG.urls().forXpath(localeID, path);
+
final String otherSource = path == null ? null
: (sourceLocaleID.equals(localeID) ? ""
: "\t" + sourceLocaleID);
@@ -1537,27 +1550,27 @@
String idViewString = idView ? (path == null ? "\tNO_ID" : getIdString(path, value)) : "";
System.out.println(
getLocaleAndName(localeID)
- + (idViewString.isEmpty() ?
+ + (idViewString.isEmpty() ?
// + "\t" + subtotalCount.getCount(shortStatus)
- "\t" + shortStatus
- + "\t▸" + cleanPrettyPath + "◂"
- + "\t〈" + englishPathValue + "〉"
- + "\t【" + englishExample + "】"
- + "\t〈" + value + "〉"
- + "\t«" + fillinValue + "»"
- + "\t【" + example + "】"
- + "\t⁅" + subType + "⁆"
- + "\t❮" + statusString + "❯"
- + "\t" + fullPath
- + otherSource
- + otherPath
- : idViewString
- + "\t〈" + englishPathValue + "〉"
- + "\t【" + englishExample + "】"
- + "\t" + value + "〉"
- + "\t【" + example + "】"
- + "\t⁅" + subType + "⁆"
- + "\t❮" + statusString + "❯"));
+ "\t" + shortStatus
+ + "\t▸" + cleanPrettyPath + "◂"
+ + "\t〈" + englishPathValue + "〉"
+ + "\t【" + englishExample + "】"
+ + "\t〈" + value + "〉"
+ + "\t«" + fillinValue + "»"
+ + "\t【" + example + "】"
+ + "\t⁅" + subType + "⁆"
+ + "\t❮" + statusString + "❯"
+ + "\t" + pathLink
+ + otherSource
+ + otherPath
+ : idViewString
+ + "\t〈" + englishPathValue + "〉"
+ + "\t【" + englishExample + "】"
+ + "\t" + value + "〉"
+ + "\t【" + example + "】"
+ + "\t⁅" + subType + "⁆"
+ + "\t❮" + statusString + "❯"));
} else if (ErrorFile.errorFileWriter != null) {
if (shortStatus == ErrorType.contributed) {
return;
@@ -1673,4 +1686,6 @@
public static String getLinkedLocale(String locale) {
return "<a href='http://unicode.org/cldr/apps/survey?_=" + locale + "'>" + locale + "</a>";
}
+
+
}
diff --git a/tools/java/org/unicode/cldr/test/CoverageLevel2.java b/tools/java/org/unicode/cldr/test/CoverageLevel2.java
index d1072f9..dae3262 100644
--- a/tools/java/org/unicode/cldr/test/CoverageLevel2.java
+++ b/tools/java/org/unicode/cldr/test/CoverageLevel2.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.test;
+import static java.util.Collections.disjoint;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -20,7 +22,6 @@
import org.unicode.cldr.util.SupplementalDataInfo.CoverageVariableInfo;
import org.unicode.cldr.util.Timer;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.ULocale;
@@ -61,8 +62,10 @@
public MyRegexFinder(String pattern, String additionalMatch, CoverageLevelInfo ci) {
super(pattern);
// remove the ${ and the }, and change - to _.
- this.additionalMatch = additionalMatch == null ? null : SetMatchType.valueOf(additionalMatch.substring(2,
- additionalMatch.length() - 1).replace('-', '_'));
+ this.additionalMatch = additionalMatch == null
+ ? null
+ : SetMatchType.valueOf(
+ additionalMatch.substring(2, additionalMatch.length() - 1).replace('-', '_'));
this.ci = ci;
}
@@ -78,10 +81,10 @@
&& ci.inLanguage.matcher(localeSpecificInfo.targetLanguage).matches()) {
lstOK = true;
} else if (ci.inScriptSet != null
- && CollectionUtilities.containsSome(ci.inScriptSet, localeSpecificInfo.cvi.targetScripts)) {
+ && !disjoint(ci.inScriptSet, localeSpecificInfo.cvi.targetScripts)) {
lstOK = true;
} else if (ci.inTerritorySet != null
- && CollectionUtilities.containsSome(ci.inTerritorySet, localeSpecificInfo.cvi.targetTerritories)) {
+ && !disjoint(ci.inTerritorySet, localeSpecificInfo.cvi.targetTerritories)) {
lstOK = true;
}
@@ -142,6 +145,7 @@
* @see #getInstance(SupplementalDataInfo, String)
* @see CLDRPaths#SUPPLEMENTAL_DIRECTORY
*/
+ @Deprecated
public static CoverageLevel2 getInstance(String locale) {
return new CoverageLevel2(SupplementalDataInfo.getInstance(), locale);
}
@@ -157,9 +161,9 @@
synchronized (lookup) { // synchronize on the class, since the Matchers are changed during the matching process
Level result;
if (DEBUG_LOOKUP) { // for testing
- Output<String[]> checkItems = new Output<String[]>();
- Output<Finder> matcherFound = new Output<Finder>();
- List<String> failures = new ArrayList<String>();
+ Output<String[]> checkItems = new Output<>();
+ Output<Finder> matcherFound = new Output<>();
+ List<String> failures = new ArrayList<>();
result = lookup.get(path, myInfo, checkItems, matcherFound, failures);
for (String s : failures) {
System.out.println(s);
diff --git a/tools/java/org/unicode/cldr/test/DateOrder.java b/tools/java/org/unicode/cldr/test/DateOrder.java
index 30275d2..5d8398c 100644
--- a/tools/java/org/unicode/cldr/test/DateOrder.java
+++ b/tools/java/org/unicode/cldr/test/DateOrder.java
@@ -65,10 +65,10 @@
public static Map<String, Map<DateOrder, String>> getOrderingInfo(CLDRFile plain, CLDRFile resolved,
DateTimePatternGenerator.FormatParser fp) {
- Map<String, Map<DateOrder, String>> pathsWithConflictingOrder2sample = new HashMap<String, Map<DateOrder, String>>();
+ Map<String, Map<DateOrder, String>> pathsWithConflictingOrder2sample = new HashMap<>();
Status status = new Status();
try {
- Map<String, Map<DateOrder, Set<String>>> type2order2set = new HashMap<String, Map<DateOrder, Set<String>>>();
+ Map<String, Map<DateOrder, Set<String>>> type2order2set = new HashMap<>();
Matcher typeMatcher = PatternCache.get("\\[@type=\"([^\"]*)\"]").matcher("");
int[] soFar = new int[50];
int lenSoFar = 0;
@@ -84,7 +84,7 @@
String type = typeMatcher.group(1);
Map<DateOrder, Set<String>> pairCount = type2order2set.get(type);
if (pairCount == null) {
- type2order2set.put(type, pairCount = new HashMap<DateOrder, Set<String>>());
+ type2order2set.put(type, pairCount = new HashMap<>());
}
boolean isInterval = path.contains("intervalFormatItem");
lenSoFar = 0;
@@ -103,7 +103,7 @@
DateOrder order = new DateOrder(soFar[i], eType);
Set<String> paths = pairCount.get(order);
if (paths == null) {
- pairCount.put(order, paths = new HashSet<String>());
+ pairCount.put(order, paths = new HashSet<>());
}
paths.add(path);
}
@@ -115,7 +115,7 @@
// determine conflicts, and mark
for (Entry<String, Map<DateOrder, Set<String>>> typeAndOrder2set : type2order2set.entrySet()) {
Map<DateOrder, Set<String>> pairCount = typeAndOrder2set.getValue();
- HashSet<DateOrder> alreadySeen = new HashSet<DateOrder>();
+ HashSet<DateOrder> alreadySeen = new HashSet<>();
for (Entry<DateOrder, Set<String>> entry : pairCount.entrySet()) {
DateOrder thisOrder = entry.getKey();
if (alreadySeen.contains(thisOrder)) {
@@ -200,7 +200,7 @@
}
Map<DateOrder, String> order2path = pathsWithConflictingOrder2sample.get(path);
if (order2path == null) {
- pathsWithConflictingOrder2sample.put(path, order2path = new TreeMap<DateOrder, String>());
+ pathsWithConflictingOrder2sample.put(path, order2path = new TreeMap<>());
}
order2path.put(sample, conflictingPath);
}
diff --git a/tools/java/org/unicode/cldr/test/DisplayAndInputProcessor.java b/tools/java/org/unicode/cldr/test/DisplayAndInputProcessor.java
index 2a70024..e35bac4 100644
--- a/tools/java/org/unicode/cldr/test/DisplayAndInputProcessor.java
+++ b/tools/java/org/unicode/cldr/test/DisplayAndInputProcessor.java
@@ -56,7 +56,7 @@
public static final UnicodeSet RTL = new UnicodeSet("[[:Bidi_Class=Arabic_Letter:][:Bidi_Class=Right_To_Left:]]")
.freeze();
- public static final UnicodeSet TO_QUOTE = (UnicodeSet) new UnicodeSet(
+ public static final UnicodeSet TO_QUOTE = new UnicodeSet(
"[[:Cn:]" +
"[:Default_Ignorable_Code_Point:]" +
"[:patternwhitespace:]" +
@@ -105,7 +105,7 @@
private static final CLDRLocale GERMAN_SWITZERLAND = CLDRLocale.getInstance("de_CH");
private static final CLDRLocale SWISS_GERMAN = CLDRLocale.getInstance("gsw");
private static final CLDRLocale FF_ADLAM = CLDRLocale.getInstance("ff_Adlm");
- public static final Set<String> LANGUAGES_USING_MODIFIER_APOSTROPHE = new HashSet<String>(
+ public static final Set<String> LANGUAGES_USING_MODIFIER_APOSTROPHE = new HashSet<>(
Arrays.asList("br", "bss", "cad", "cic", "cch", "gn", "ha", "ha_Latn", "lkt", "mgo", "moh", "mus", "nnh", "qu", "quc", "uk", "uz", "uz_Latn"));
// Ş ş Ţ ţ => Ș ș Ț ț
@@ -314,6 +314,7 @@
*/
public synchronized String processInput(String path, String value, Exception[] internalException) {
String original = value;
+ value = stripProblematicControlCharacters(value);
value = Normalizer.compose(value, false); // Always normalize all input to NFC.
if (internalException != null) {
internalException[0] = null;
@@ -473,11 +474,28 @@
}
}
+ /**
+ * Strip out all code points less than U+0020 except for U+0009 tab,
+ * U+000A line feed, and U+000D carriage return.
+ *
+ * @param s the string
+ * @return the resulting string
+ */
+ private String stripProblematicControlCharacters(String s) {
+ if (s == null || s.isEmpty()) {
+ return s;
+ }
+ return s.codePoints()
+ .filter(c -> (c >= 0x20 || c == 9 || c == 0xA || c == 0xD))
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+ .toString();
+ }
+
private static final boolean REMOVE_COVERED_KEYWORDS = true;
/**
* Produce a modification of the given annotation by sorting its components and filtering covered keywords.
- *
+ *
* Examples: Given "b | a", return "a | b". Given "bear | panda | panda bear", return "bear | panda".
*
* @param value the string
@@ -496,7 +514,7 @@
/**
* Filter from the given set some keywords that include spaces, if they duplicate,
* or are "covered by", other keywords in the set.
- *
+ *
* For example, if the set is {"bear", "panda", "panda bear"} (annotation was "bear | panda | panda bear"),
* then remove "panda bear", treating it as "covered" since the set already includes "panda" and "bear".
*
@@ -862,10 +880,10 @@
switch (string) {
case "\u2011": toAdd.add("-"); break; // nobreak hyphen
case "-": toAdd.add("\u2011"); break; // nobreak hyphen
-
+
case " ": toAdd.add("\u00a0"); break; // nobreak space
case "\u00a0": toAdd.add(" "); break; // nobreak space
-
+
case "\u202F": toAdd.add("\u2009"); break; // nobreak narrow space
case "\u2009": toAdd.add("\u202F"); break; // nobreak narrow space
}
@@ -952,7 +970,7 @@
private int[] posixDigitCount;
private NumericType() {
- };
+ }
private NumericType(int[] digitCount, int[] posixDigitCount) {
this.digitCount = digitCount;
@@ -994,5 +1012,5 @@
public int[] getPosixDigitCount() {
return posixDigitCount;
}
- };
+ }
}
diff --git a/tools/java/org/unicode/cldr/test/EmojiSubdivisionNames.java b/tools/java/org/unicode/cldr/test/EmojiSubdivisionNames.java
index b678c85..5060bbb 100644
--- a/tools/java/org/unicode/cldr/test/EmojiSubdivisionNames.java
+++ b/tools/java/org/unicode/cldr/test/EmojiSubdivisionNames.java
@@ -82,18 +82,31 @@
_subdivisionIdToName.put(m.group(1), m.group(2));
}
}
- _nameToSubdivisionId = _nameToSubdivisionId.isEmpty() ? Collections.emptyMap()
+ _nameToSubdivisionId = _nameToSubdivisionId.isEmpty() ? Collections.emptyMap()
: ImmutableMap.copyOf(_nameToSubdivisionId);
- _subdivisionIdToName = _subdivisionIdToName.isEmpty() ? Collections.emptyMap()
+ _subdivisionIdToName = _subdivisionIdToName.isEmpty() ? Collections.emptyMap()
: ImmutableMap.copyOf(_subdivisionIdToName);
} else {
String parentLocaleId = LocaleIDParser.getParent(localeID);
_nameToSubdivisionId = getNameToSubdivisionPath(parentLocaleId);
_subdivisionIdToName = localeToSubdivisionIdToName.get(parentLocaleId);
}
- localeToNameToSubdivisionId.put(localeID, _nameToSubdivisionId);
- localeToSubdivisionIdToName.put(localeID, _subdivisionIdToName);
- } catch (Exception e) {}
+ /*
+ * In practice _subdivisionIdToName == null actually happens here.
+ * Check for null rather than triggering NullPointerException.
+ */
+ if (_nameToSubdivisionId != null) {
+ localeToNameToSubdivisionId.put(localeID, _nameToSubdivisionId);
+ }
+ if (_subdivisionIdToName != null) {
+ localeToSubdivisionIdToName.put(localeID, _subdivisionIdToName);
+ }
+ } catch (Exception e) {
+ /*
+ * TODO: If there is a valid rationale for catching and ignoring all exceptions here,
+ * document it. Otherwise it should be avoided since it tends to hide programming errors.
+ */
+ }
}
static Set<String> SUBDIVISIONS = ImmutableSet.of("gbeng", "gbsct", "gbwls");
diff --git a/tools/java/org/unicode/cldr/test/ExampleCache.java b/tools/java/org/unicode/cldr/test/ExampleCache.java
new file mode 100644
index 0000000..5af14fb
--- /dev/null
+++ b/tools/java/org/unicode/cldr/test/ExampleCache.java
@@ -0,0 +1,187 @@
+package org.unicode.cldr.test;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.unicode.cldr.util.PathStarrer;
+
+/**
+ * Cache example html strings for ExampleGenerator.
+ *
+ * Essentially, the cache simply maps from xpath+value to html.
+ *
+ * The complexity of this class is mostly for the sake of handling dependencies where the
+ * example for pathB+valueB depends not only on pathB and valueB, but also on the current
+ * <em>winning</em> values of pathA1, pathA2, ...
+ *
+ * Some examples in the cache must get cleared when a changed winning value for a path makes
+ * the cached examples for other paths possibly no longer correct.
+
+ * For example, let pathA = "//ldml/localeDisplayNames/languages/language[@type=\"aa\"]"
+ * and pathB = "//ldml/localeDisplayNames/territories/territory[@type=\"DJ\"]". The values,
+ * in locale fr, might be "afar" for pathA and "Djibouti" for pathB. The example for pathB
+ * might include "afar (Djibouti)", which depends on the values of both pathA and pathB.
+ *
+ * Each ExampleGenerator object, which is for one locale, has its own ExampleCache object.
+ *
+ * This cache is internal to each ExampleGenerator. Compare TestCache.exampleGeneratorCache,
+ * which is at a higher level, caching entire ExampleGenerator objects, one for each locale.
+ *
+ * Unlike TestCache.exampleGeneratorCache, this cache doesn't get cleared to conserve memory,
+ * only to adapt to changed winning values.
+ */
+class ExampleCache {
+ /**
+ * An ExampleCacheItem is a temporary container for the info
+ * needed to get and/or put one item in the cache.
+ */
+ class ExampleCacheItem {
+ private String xpath;
+ private String value;
+
+ /**
+ * starredPath, the "starred" version of xpath, is the key for the highest level
+ * of the cache, which is nested.
+ *
+ * Compare starred "//ldml/localeDisplayNames/languages/language[@type=\"*\"]"
+ * with starless "//ldml/localeDisplayNames/languages/language[@type=\"aa\"]".
+ * There are fewer starred paths than starless paths.
+ * ExampleDependencies.dependencies has starred paths for that reason.
+ */
+ private String starredPath = null;
+
+ /**
+ * The cache maps each starredPath to a pathMap, which in turn maps each starless path
+ * to a valueMap.
+ */
+ private Map<String, Map<String, String>> pathMap = null;
+
+ /**
+ * Finally the valueMap maps the value to the example html.
+ */
+ private Map<String, String> valueMap = null;
+
+ ExampleCacheItem(String xpath, String value) {
+ this.xpath = xpath;
+ this.value = value;
+ }
+
+ /**
+ * Get the cached example html for this item, based on its xpath and value
+ *
+ * The HTML string shows example(s) using that value for that path, for the locale
+ * of the ExampleGenerator we're connected to.
+ *
+ * @return the example html or null
+ */
+ String getExample() {
+ if (!cachingIsEnabled) {
+ return null;
+ }
+ String result = null;
+ starredPath = pathStarrer.set(xpath);
+ pathMap = cache.get(starredPath);
+ if (pathMap != null) {
+ valueMap = pathMap.get(xpath);
+ if (valueMap != null) {
+ result = valueMap.get(value);
+ }
+ }
+ if (cacheOnly && result == NONE) {
+ throw new InternalError("getExampleHtml cacheOnly not found: " + xpath + ", " + value);
+ }
+ return (result == NONE) ? null : result;
+ }
+
+ void putExample(String result) {
+ if (cachingIsEnabled) {
+ if (pathMap == null) {
+ pathMap = new ConcurrentHashMap<>();
+ cache.put(starredPath, pathMap);
+ }
+ if (valueMap == null) {
+ valueMap = new ConcurrentHashMap<>();
+ pathMap.put(xpath, valueMap);
+ }
+ valueMap.put(value, (result == null) ? NONE : result);
+ }
+ }
+ }
+
+ /**
+ * AVOID_CLEARING_CACHE: a performance optimization. Should be true except for testing.
+ * Only remove keys for which the examples may be affected by this change.
+ *
+ * All paths of type “A” (i.e., all that have dependencies) have keys in ExampleDependencies.dependencies.
+ * For any other path given as the argument to this function, there should be no need to clear the cache.
+ * When there are dependencies, only remove the keys for paths that are dependent on this path.
+ *
+ * Reference: https://unicode-org.atlassian.net/browse/CLDR-13636
+ */
+ private static final boolean AVOID_CLEARING_CACHE = true;
+
+ /**
+ * Avoid storing null in the cache, but do store NONE as a way to remember
+ * there is no example html for the given xpath and value. This is probably
+ * faster than calling constructExampleHtml again and again to get null every
+ * time, if nothing at all were stored in the cache.
+ */
+ private static final String NONE = "\uFFFF";
+
+ /**
+ * The nested cache mapping is: starredPath → (starlessPath → (value → html)).
+ */
+ private final Map<String, Map<String, Map<String, String>>> cache = new ConcurrentHashMap<>();
+
+ /**
+ * The PathStarrer is for getting starredPath from an ordinary (starless) path.
+ * Inclusion of starred paths enables performance improvement with AVOID_CLEARING_CACHE.
+ */
+ private final PathStarrer pathStarrer = new PathStarrer().setSubstitutionPattern("*");
+
+ /**
+ * For testing, caching can be disabled for some ExampleCaches while still
+ * enabled for others.
+ */
+ private boolean cachingIsEnabled = true;
+
+ void setCachingEnabled(boolean enabled) {
+ cachingIsEnabled = enabled;
+ }
+
+ /**
+ * For testing, we can switch some ExampleCaches into a special "cache only"
+ * mode, where they will throw an exception if queried for a path+value that isn't
+ * already in the cache. See TestExampleGeneratorDependencies.
+ */
+ private boolean cacheOnly = false;
+
+ void setCacheOnly(boolean only) {
+ this.cacheOnly = only;
+ }
+
+ /**
+ * Clear the cached examples for any paths whose examples might depend on the
+ * winning value of the given path, since the winning value of the given path has changed.
+ *
+ * There is no need to update the example(s) for the given path itself, since
+ * the cache key includes path+value and therefore each path+value has its own
+ * example, regardless of which value is winning. There is a need to update
+ * the examples for OTHER paths whose examples depend on the winning value
+ * of the given path.
+ *
+ * @param xpath the path whose winning value has changed
+ *
+ * Called by ExampleGenerator.updateCache
+ */
+ void update(String xpath) {
+ if (AVOID_CLEARING_CACHE) {
+ String starredA = pathStarrer.set(xpath);
+ for (String starredB : ExampleDependencies.dependencies.get(starredA)) {
+ cache.remove(starredB);
+ }
+ } else {
+ cache.clear();
+ }
+ }
+}
diff --git a/tools/java/org/unicode/cldr/test/ExampleDependencies.java b/tools/java/org/unicode/cldr/test/ExampleDependencies.java
new file mode 100644
index 0000000..529b35b
--- /dev/null
+++ b/tools/java/org/unicode/cldr/test/ExampleDependencies.java
@@ -0,0 +1,265 @@
+package org.unicode.cldr.test;
+import com.google.common.collect.ImmutableSetMultimap;
+public class ExampleDependencies {
+ public static ImmutableSetMultimap<String, String> dependencies
+ = new ImmutableSetMultimap.Builder<String, String>()
+ .put("//ldml/characterLabels/characterLabelPattern[@type=\"*\"]", "//ldml/characterLabels/characterLabel[@type=\"*\"]")
+ .put("//ldml/characterLabels/characterLabel[@type=\"*\"]", "//ldml/characterLabels/characterLabelPattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/dateTimeFormatLength[@type=\"*\"]/dateTimeFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/days/dayContext[@type=\"*\"]/dayWidth[@type=\"*\"]/day[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/days/dayContext[@type=\"*\"]/dayWidth[@type=\"*\"]/day[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/days/dayContext[@type=\"*\"]/dayWidth[@type=\"*\"]/day[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/days/dayContext[@type=\"*\"]/dayWidth[@type=\"*\"]/day[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/days/dayContext[@type=\"*\"]/dayWidth[@type=\"*\"]/day[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraAbbr/era[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraAbbr/era[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraAbbr/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraAbbr/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraAbbr/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraNames/era[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraNames/era[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraNames/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraNames/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/eras/eraNames/era[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/monthPatterns/monthPatternContext[@type=\"*\"]/monthPatternWidth[@type=\"*\"]/monthPattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/months/monthContext[@type=\"*\"]/monthWidth[@type=\"*\"]/month[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/quarters/quarterContext[@type=\"*\"]/quarterWidth[@type=\"*\"]/quarter[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/quarters/quarterContext[@type=\"*\"]/quarterWidth[@type=\"*\"]/quarter[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dayPeriods/dayPeriodContext[@type=\"*\"]/dayPeriodWidth[@type=\"*\"]/dayPeriod[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/quarters/quarterContext[@type=\"*\"]/quarterWidth[@type=\"*\"]/quarter[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/quarters/quarterContext[@type=\"*\"]/quarterWidth[@type=\"*\"]/quarter[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/quarters/quarterContext[@type=\"*\"]/quarterWidth[@type=\"*\"]/quarter[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/appendItems/appendItem[@request=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/dateTimeFormatLength[@type=\"*\"]/dateTimeFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/long/daylight")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/long/generic")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/long/standard")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/short/daylight")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/short/generic")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/short/standard")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/fallbackFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/timeZoneNames/fallbackFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/timeZoneNames/fallbackFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/gmtFormat", "//ldml/dates/timeZoneNames/hourFormat")
+ .put("//ldml/dates/timeZoneNames/gmtFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/timeZoneNames/gmtFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/timeZoneNames/gmtFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/gmtZeroFormat", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/appendItems/appendItem[@request=\"*\"]")
+ .put("//ldml/dates/timeZoneNames/hourFormat", "//ldml/dates/timeZoneNames/gmtFormat")
+ .put("//ldml/dates/timeZoneNames/hourFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/timeZoneNames/hourFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/timeZoneNames/hourFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/metazone[@type=\"*\"]/long/generic", "//ldml/dates/timeZoneNames/fallbackFormat")
+ .put("//ldml/dates/timeZoneNames/regionFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/timeZoneNames/regionFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/timeZoneNames/regionFormat", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/regionFormat[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/dates/timeZoneNames/regionFormat[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/dates/timeZoneNames/regionFormat[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/dates/timeZoneNames/zone[@type=\"*\"]/exemplarCity", "//ldml/dates/timeZoneNames/fallbackFormat")
+ .put("//ldml/dates/timeZoneNames/zone[@type=\"*\"]/exemplarCity", "//ldml/dates/timeZoneNames/regionFormat")
+ .put("//ldml/dates/timeZoneNames/zone[@type=\"*\"]/exemplarCity", "//ldml/dates/timeZoneNames/regionFormat[@type=\"*\"]")
+ .put("//ldml/delimiters/alternateQuotationEnd", "//ldml/delimiters/alternateQuotationStart")
+ .put("//ldml/delimiters/alternateQuotationEnd", "//ldml/delimiters/quotationEnd")
+ .put("//ldml/delimiters/alternateQuotationEnd", "//ldml/delimiters/quotationStart")
+ .put("//ldml/delimiters/alternateQuotationStart", "//ldml/delimiters/alternateQuotationEnd")
+ .put("//ldml/delimiters/alternateQuotationStart", "//ldml/delimiters/quotationEnd")
+ .put("//ldml/delimiters/alternateQuotationStart", "//ldml/delimiters/quotationStart")
+ .put("//ldml/delimiters/quotationEnd", "//ldml/delimiters/alternateQuotationEnd")
+ .put("//ldml/delimiters/quotationEnd", "//ldml/delimiters/alternateQuotationStart")
+ .put("//ldml/delimiters/quotationEnd", "//ldml/delimiters/quotationStart")
+ .put("//ldml/delimiters/quotationStart", "//ldml/delimiters/alternateQuotationEnd")
+ .put("//ldml/delimiters/quotationStart", "//ldml/delimiters/alternateQuotationStart")
+ .put("//ldml/delimiters/quotationStart", "//ldml/delimiters/quotationEnd")
+ .put("//ldml/listPatterns/listPattern/listPatternPart[@type=\"*\"]", "//ldml/listPatterns/listPattern/listPatternPart[@type=\"*\"]")
+ .put("//ldml/listPatterns/listPattern[@type=\"*\"]/listPatternPart[@type=\"*\"]", "//ldml/listPatterns/listPattern[@type=\"*\"]/listPatternPart[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/codePatterns/codePattern[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/keys/key[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/keys/key[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/keys/key[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localePattern", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/characterLabels/characterLabelPattern[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/characterLabels/characterLabel[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/characters/ellipsis[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/dates/timeZoneNames/regionFormat")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/dates/timeZoneNames/regionFormat[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/listPatterns/listPattern/listPatternPart[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/listPatterns/listPattern[@type=\"*\"]/listPatternPart[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"]", "//ldml/localeDisplayNames/scripts/script[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/languages/language[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"]")
+ .put("//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]", "//ldml/localeDisplayNames/territories/territory[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/delimiters/alternateQuotationEnd")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/delimiters/alternateQuotationStart")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/delimiters/quotationEnd")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/delimiters/quotationStart")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localePattern")
+ .put("//ldml/localeDisplayNames/types/type[@key=\"*\"][@type=\"*\"]", "//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol[@alt=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/decimal", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol[@alt=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol[@alt=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/grouping", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol[@alt=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/pattern", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencyFormats/currencyFormatLength[@type=\"*\"]/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"][@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencies/currency[@type=\"*\"]/symbol", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength[@type=\"*\"]/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"][@count=\"*\"]")
+ .put("//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol")
+ .put("//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/currencies/currency[@type=\"*\"]/symbol[@alt=\"*\"]")
+ .put("//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]")
+ .put("//ldml/numbers/currencyFormats/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/currencyFormats[@numberSystem=\"*\"]/currencyFormatLength/currencyFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/currencyMatch", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/currencyMatch", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/insertBetween", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/insertBetween", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/surroundingMatch", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/afterCurrency/surroundingMatch", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/currencyMatch", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/currencyMatch", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/insertBetween", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/insertBetween", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/surroundingMatch", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/currencyFormats/currencySpacing/beforeCurrency/surroundingMatch", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/currencyFormats/unitPattern[@count=\"*\"]", "//ldml/numbers/currencies/currency[@type=\"*\"]/displayName[@count=\"*\"]")
+ .put("//ldml/numbers/decimalFormats/decimalFormatLength/decimalFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/miscPatterns[@numberSystem=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/decimalFormats/decimalFormatLength/decimalFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/decimalFormats/decimalFormatLength/decimalFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"][@alt=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"][@count=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/numbers/defaultNumberingSystem", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/percentFormats/percentFormatLength/percentFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols/percentSign")
+ .put("//ldml/numbers/percentFormats/percentFormatLength/percentFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols[@numberSystem=\"*\"]/percentSign")
+ .put("//ldml/numbers/scientificFormats/scientificFormatLength/scientificFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols/plusSign")
+ .put("//ldml/numbers/scientificFormats/scientificFormatLength/scientificFormat[@type=\"*\"]/pattern[@type=\"*\"]", "//ldml/numbers/symbols[@numberSystem=\"*\"]/plusSign")
+ .put("//ldml/numbers/symbols/percentSign", "//ldml/numbers/symbols/perMille")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/currencyDecimal", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/currencyDecimal", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/currencyGroup", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/currencyGroup", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/exponential", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/exponential", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/group", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/group", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/infinity", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/infinity", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/list", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/list", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/minusSign", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/minusSign", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/nan", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/nan", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/perMille", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/perMille", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/percentSign", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/percentSign", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/percentSign", "//ldml/numbers/symbols[@numberSystem=\"*\"]/perMille")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/plusSign", "//ldml/numbers/symbols/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/plusSign", "//ldml/numbers/symbols[@numberSystem=\"*\"]/decimal")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateFormats/dateFormatLength[@type=\"*\"]/dateFormat[@type=\"*\"]/pattern[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"][@alt=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"*\"][@count=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"]")
+ .put("//ldml/numbers/symbols[@numberSystem=\"*\"]/timeSeparator", "//ldml/dates/calendars/calendar[@type=\"*\"]/timeFormats/timeFormatLength[@type=\"*\"]/timeFormat[@type=\"*\"]/pattern[@type=\"*\"][@alt=\"*\"]")
+ .put("//ldml/units/unitLength[@type=\"*\"]/unit[@type=\"*\"]/displayName", "//ldml/units/unitLength[@type=\"*\"]/compoundUnit[@type=\"*\"]/compoundUnitPattern1")
+ .put("//ldml/units/unitLength[@type=\"*\"]/unit[@type=\"*\"]/displayName", "//ldml/units/unitLength[@type=\"*\"]/compoundUnit[@type=\"*\"]/unitPrefixPattern")
+ .put("//ldml/units/unitLength[@type=\"*\"]/unit[@type=\"*\"]/unitPattern[@count=\"*\"]", "//ldml/listPatterns/listPattern[@type=\"*\"]/listPatternPart[@type=\"*\"]")
+ .put("//ldml/units/unitLength[@type=\"*\"]/unit[@type=\"*\"]/unitPattern[@count=\"*\"]", "//ldml/units/unitLength[@type=\"*\"]/compoundUnit[@type=\"*\"]/compoundUnitPattern")
+ .put("//ldml/units/unitLength[@type=\"*\"]/unit[@type=\"*\"]/unitPattern[@count=\"*\"]", "//ldml/units/unitLength[@type=\"*\"]/compoundUnit[@type=\"*\"]/compoundUnitPattern1[@count=\"*\"]")
+ .build();
+}
diff --git a/tools/java/org/unicode/cldr/test/ExampleGenerator.java b/tools/java/org/unicode/cldr/test/ExampleGenerator.java
index ba62b29..50db46b 100644
--- a/tools/java/org/unicode/cldr/test/ExampleGenerator.java
+++ b/tools/java/org/unicode/cldr/test/ExampleGenerator.java
@@ -15,7 +15,6 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -43,6 +42,8 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
import org.unicode.cldr.util.TimezoneFormatter;
import org.unicode.cldr.util.TransliteratorUtilities;
+import org.unicode.cldr.util.UnitConverter;
+import org.unicode.cldr.util.UnitConverter.UnitId;
import org.unicode.cldr.util.Units;
import org.unicode.cldr.util.XListFormatter.ListTypeLength;
import org.unicode.cldr.util.XPathParts;
@@ -84,8 +85,6 @@
private static final String EXEMPLAR_CITY_LOS_ANGELES = "//ldml/dates/timeZoneNames/zone[@type=\"America/Los_Angeles\"]/exemplarCity";
- private static final boolean SHOW_ERROR = false;
-
private static final Pattern URL_PATTERN = Pattern
.compile("http://[\\-a-zA-Z0-9]+(\\.[\\-a-zA-Z0-9]+)*([/#][\\-a-zA-Z0-9]+)*");
@@ -94,25 +93,12 @@
private static SupplementalDataInfo supplementalDataInfo;
private PathDescription pathDescription;
- /*
- * For testing, caching can be disabled for some ExampleGenerators while still
- * enabled for others.
- */
- private boolean cachingIsEnabled = true;
-
- public void disableCaching() {
- cachingIsEnabled = false;
+ public void setCachingEnabled(boolean enabled) {
+ exCache.setCachingEnabled(enabled);
}
- /*
- * For testing, we can switch some ExampleGenerators into a special "cache only"
- * mode, where they will throw an exception if queried for a path+value that isn't
- * already in the cache. See TestExampleGeneratorDependencies.
- */
- private boolean cacheOnly = false;
-
- public void makeCacheOnly() {
- cacheOnly = true;
+ public void setCacheOnly(boolean cacheOnly) {
+ exCache.setCacheOnly(cacheOnly);
}
public final static double NUMBER_SAMPLE = 123456.789;
@@ -178,159 +164,21 @@
private CLDRFile englishFile;
Matcher URLMatcher = URL_PATTERN.matcher("");
- /**
- * The cache is accessed only by getExampleHtml and updateCache.
- * Its key is built from an xpath, and a value for that xpath.
- * Its value is an HTML string showing example(s) using that value for that path, for the locale of this ExampleGenerator.
- *
- * Note that this cache is internal to each ExampleGenerator. Compare TestCache.exampleGeneratorCache,
- * which is at a higher level, caching entire ExampleGenerator objects, one for each locale.
- */
- private Map<String, String> cache = new ConcurrentHashMap<String, String>();
-
- /**
- * AVOID_CLEARING_CACHE: work in progress, keep false until it becomes beneficial and reliable.
- * Reference: https://unicode-org.atlassian.net/browse/CLDR-13331
- */
- private static final boolean AVOID_CLEARING_CACHE = false;
+ private ExampleCache exCache = new ExampleCache();
/**
* For this (locale-specific) ExampleGenerator, clear the cached examples for
* any paths whose examples might depend on the winning value of the given path,
- * since the winning value of the given path has (or may have?) changed.
+ * since the winning value of the given path has changed.
*
- * There is no need to update the example(s) for the given path itself, since
- * the cache key includes path+value and therefore each path+value has its own
- * example, regardless of which value is winning. There is a need to update
- * the examples for OTHER paths whose examples depend on the winning value
- * of the given path.
- *
- * For example, let pathA = "//ldml/localeDisplayNames/languages/language[@type=\"aa\"]"
- * and pathB = "//ldml/localeDisplayNames/territories/territory[@type=\"DJ\"]". The values,
- * in locale fr, might be "afar" for pathA and "Djibouti" for pathB. The example for pathB
- * might include "afar (Djibouti)", which depends on the values of both pathA and pathB.
- *
- * @param xpath the path whose winning value has (may have?) changed
- *
- * TODO: make sure we're only called if the winning value really HAS changed.
- * Looking at the callers, it's not obvious if that's the case, or if this
- * function may sometimes be called when a vote has been made without actually
- * changing the winning value.
+ * @param xpath the path whose winning value has changed
*
* Called by TestCache.updateExampleGeneratorCache
*/
- public void updateCache(@SuppressWarnings("unused") String xpath) {
- /*
- * TODO: instead of removing ALL keys, only remove keys for which the examples
- * may be affected by this change.
- *
- * It appears (based on incomplete evidence), that all paths of type “A”
- * (i.e., all that have dependencies) start with one of these seven strings:
- * //ldml/characterLabels
- * //ldml/dates
- * //ldml/delimiters
- * //ldml/listPatterns
- * //ldml/localeDisplayNames
- * //ldml/numbers
- * //ldml/units
- *
- * Problem: that's something like 98% of all paths! Need to narrow it down much further.
- *
- * For any other path given as the argument to this function, there should be no need to clear the cache.
- * Also, when there are dependencies, ideally only the keys for paths that are dependent on this path
- * should be removed. It might be slow to loop through the cache testing each path to see if it's affected.
- * Ideally we might maintain a complete mapping of dependencies, so given pathA we could quickly loop
- * through the pre-existing set of paths B that depend on pathA.
- *
- * Reference: https://unicode-org.atlassian.net/browse/CLDR-13331
- */
- if (AVOID_CLEARING_CACHE) {
- if (!pathMightBeTypeA(xpath)) {
- return;
- }
- }
- cache.clear();
+ public void updateCache(String xpath) {
+ exCache.update(xpath);
}
- static long typeACount = 0, notTypeACount = 0;
-
- /**
- * Does changing the winning value for the given path potentially have side-effect of changing the example
- * html for other paths? In other words, might this be a path of type "A"?
- *
- * We say "might be", since this function is meant to be fast rather than exact. It should never return
- * false for a path that really is type "A", but it may return true for some paths that aren't really type "A".
- *
- * @param xpath
- * @return true or false
- *
- * Called locally (only if AVOID_CLEARING_CACHE is true), and also by TestExampleGeneratorDependencies.
- */
- static public boolean pathMightBeTypeA(String xpath) {
- final String pathAStarts[] = {
- "//ldml/characterLabels/characterLabelPattern",
- "//ldml/characterLabels/characterLabel",
- "//ldml/dates/calendars",
- "//ldml/dates/fields",
- "//ldml/dates/timeZoneNames",
- "//ldml/delimiters/alternateQuotationEnd",
- "//ldml/delimiters/alternateQuotationStart",
- "//ldml/delimiters/quotationEnd",
- "//ldml/delimiters/quotationStart",
- "//ldml/listPatterns/listPattern",
- "//ldml/localeDisplayNames/codePatterns",
- "//ldml/localeDisplayNames/keys",
- "//ldml/localeDisplayNames/languages",
- "//ldml/localeDisplayNames/localeDisplayPattern",
- "//ldml/localeDisplayNames/scripts",
- "//ldml/localeDisplayNames/territories",
- "//ldml/localeDisplayNames/types",
- "//ldml/numbers/currencies",
- "//ldml/numbers/currencyFormats",
- "//ldml/numbers/decimalFormats",
- "//ldml/numbers/defaultNumberingSystem",
- "//ldml/numbers/minimalPairs",
- "//ldml/numbers/minimumGroupingDigits",
- "//ldml/numbers/miscPatterns",
- "//ldml/numbers/otherNumberingSystems",
- "//ldml/numbers/percentFormats",
- "//ldml/numbers/scientificFormats",
- "//ldml/numbers/symbols",
- "//ldml/posix/messages",
- "//ldml/typographicNames",
- "//ldml/units/durationUnit",
- "//ldml/units/unitLength",
- };
- /***
- final String pathAStartsShorter[] = {
- "//ldml/characterLabels",
- "//ldml/dates",
- "//ldml/delimiters",
- "//ldml/listPatterns",
- "//ldml/localeDisplayNames",
- "//ldml/numbers",
- "//ldml/units"
- };
- ***/
- boolean maybeTypeA = false;
- for (String s : pathAStarts) {
- if (xpath.startsWith(s)) {
- maybeTypeA = true;
- break;
- }
- }
- if (maybeTypeA) {
- ++typeACount;
- } else {
- ++notTypeACount; // e.g., //ldml/localeDisplayNames/subdivisions/subdivision[@type="gbeng"] or //ldml/localeDisplayNames/variants/variant[@type="1901"] or //ldml/localeDisplayNames/measurementSystemNames/measurementSystemName[@type="US"]
- }
- // System.out.println("type A percent = " + ((100 * typeACount) / (typeACount + notTypeACount))
- // + " [" + typeACount + ", " + notTypeACount + "]");
- return maybeTypeA;
- }
-
- private static final String NONE = "\uFFFF";
-
private ICUServiceBuilder icuServiceBuilder = new ICUServiceBuilder();
private PluralInfo pluralInfo;
@@ -442,127 +290,123 @@
* example. <br>
* The result is valid HTML.
*
+ * If generating examples for an inheritance marker, use the "real" inherited value
+ * to generate from. Do this BEFORE accessing the cache, which doesn't use INHERITANCE_MARKER.
+ *
* @param xpath the path; e.g., "//ldml/dates/timeZoneNames/fallbackFormat"
* @param value the value; e.g., "{1} [{0}]"; not necessarily the winning value
* @return the example HTML, or null
*/
public String getExampleHtml(String xpath, String value) {
- if (value == null) {
+ if (value == null || xpath == null || xpath.endsWith("/alias")) {
return null;
}
- String cacheKey = null;
String result = null;
try {
- if (cachingIsEnabled) {
- cacheKey = xpath + "," + value;
- result = cache.get(cacheKey);
- if (result != null) {
- if (result == NONE) {
- return null;
- }
- return result;
- }
- } else if (cacheOnly ) {
- throw new InternalError("getExampleHtml cacheOnly not found: " + cacheKey);
- }
- // If generating examples for an inheritance marker, then we need to find the
- // "real" value to generate from.
if (CldrUtility.INHERITANCE_MARKER.equals(value)) {
value = cldrFile.getConstructedBaileyValue(xpath, null, null);
- }
-
- /*
- * result is null at this point. Get the real value if we can.
- *
- * Need getInstance, not getFrozenInstance here: some functions such as handleNumberSymbol
- * expect to call functions like parts.addRelative which throw exceptions if parts is frozen.
- */
- XPathParts parts = XPathParts.getInstance(xpath);
- if (parts.contains("dateRangePattern")) { // {0} - {1}
- result = handleDateRangePattern(value);
- } else if (parts.contains("timeZoneNames")) {
- result = handleTimeZoneName(parts, value);
- } else if (parts.contains("localeDisplayNames")) {
- result = handleDisplayNames(xpath, parts, value);
- } else if (parts.contains("currency")) {
- result = handleCurrency(xpath, parts, value);
- } else if (parts.contains("dayPeriods")) {
- result = handleDayPeriod(parts, value);
- } else if (parts.contains("pattern") || parts.contains("dateFormatItem")) {
- if (parts.contains("calendar")) {
- result = handleDateFormatItem(xpath, value);
- } else if (parts.contains("miscPatterns")) {
- result = handleMiscPatterns(parts, value);
- } else if (parts.contains("numbers")) {
- if (parts.contains("currencyFormat")) {
- result = handleCurrencyFormat(parts, value);
- } else {
- result = handleDecimalFormat(parts, value);
- }
+ if (value == null) {
+ /*
+ * This can happen for some paths, such as
+ * //ldml/dates/timeZoneNames/metazone[@type="Mawson"]/short/daylight
+ */
+ return null;
}
- } else if (parts.getElement(2).contains("symbols")) {
- result = handleNumberSymbol(parts, value);
- } else if (parts.contains("defaultNumberingSystem") || parts.contains("otherNumberingSystems")) {
- result = handleNumberingSystem(value);
- } else if (parts.contains("currencyFormats") && parts.contains("unitPattern")) {
- result = formatCountValue(xpath, parts, value);
- } else if (parts.getElement(-1).equals("compoundUnitPattern")) {
- result = handleCompoundUnit(parts);
- } else if (parts.getElement(-1).equals("compoundUnitPattern1")
- || parts.getElement(-1).equals("unitPrefixPattern")) {
- result = handleCompoundUnit1(parts, value);
- } else if (parts.getElement(-1).equals("unitPattern")) {
- String count = parts.getAttributeValue(-1, "count");
- result = handleFormatUnit(Count.valueOf(count), value);
- } else if (parts.getElement(-1).equals("durationUnitPattern")) {
- result = handleDurationUnit(value);
- } else if (parts.contains("intervalFormats")) {
- result = handleIntervalFormats(parts, value);
- } else if (parts.getElement(1).equals("delimiters")) {
- result = handleDelimiters(parts, xpath, value);
- } else if (parts.getElement(1).equals("listPatterns")) {
- result = handleListPatterns(parts, value);
- } else if (parts.getElement(2).equals("ellipsis")) {
- result = handleEllipsis(parts.getAttributeValue(-1, "type"), value);
- } else if (parts.getElement(-1).equals("monthPattern")) {
- result = handleMonthPatterns(parts, value);
- } else if (parts.getElement(-1).equals("appendItem")) {
- result = handleAppendItems(parts, value);
- } else if (parts.getElement(-1).equals("annotation")) {
- result = handleAnnotationName(parts, value);
- } else if (parts.getElement(-1).equals("characterLabel")) {
- result = handleLabel(parts, value);
- } else if (parts.getElement(-1).equals("characterLabelPattern")) {
- result = handleLabelPattern(parts, value);
- } else {
- // didn't detect anything
- result = null;
}
- } catch (NullPointerException e) {
- if (SHOW_ERROR) {
- e.printStackTrace();
+ ExampleCache.ExampleCacheItem cacheItem = exCache.new ExampleCacheItem(xpath, value);
+ result = cacheItem.getExample();
+ if (result != null) {
+ return result;
}
- result = null;
+ result = constructExampleHtml(xpath, value);
+ cacheItem.putExample(result);
} catch (RuntimeException e) {
+ e.printStackTrace();
String unchained = verboseErrors ? ("<br>" + finalizeBackground(unchainException(e))) : "";
result = "<i>Parsing error. " + finalizeBackground(e.getMessage()) + "</i>" + unchained;
}
+ return result;
+ }
+ /**
+ * Do the main work of getExampleHtml given that the result was not
+ * found in the cache.
+ *
+ * @param xpath the path; e.g., "//ldml/dates/timeZoneNames/fallbackFormat"
+ * @param value the value; e.g., "{1} [{0}]"; not necessarily the winning value
+ * @return the example HTML, or null
+ */
+ private String constructExampleHtml(String xpath, String value) {
+ String result = null;
+ /*
+ * Need getInstance, not getFrozenInstance here: some functions such as handleNumberSymbol
+ * expect to call functions like parts.addRelative which throw exceptions if parts is frozen.
+ */
+ XPathParts parts = XPathParts.getFrozenInstance(xpath).cloneAsThawed();
+ if (parts.contains("dateRangePattern")) { // {0} - {1}
+ result = handleDateRangePattern(value);
+ } else if (parts.contains("timeZoneNames")) {
+ result = handleTimeZoneName(parts, value);
+ } else if (parts.contains("localeDisplayNames")) {
+ result = handleDisplayNames(xpath, parts, value);
+ } else if (parts.contains("currency")) {
+ result = handleCurrency(xpath, parts, value);
+ } else if (parts.contains("dayPeriods")) {
+ result = handleDayPeriod(parts, value);
+ } else if (parts.contains("pattern") || parts.contains("dateFormatItem")) {
+ if (parts.contains("calendar")) {
+ result = handleDateFormatItem(xpath, value);
+ } else if (parts.contains("miscPatterns")) {
+ result = handleMiscPatterns(parts, value);
+ } else if (parts.contains("numbers")) {
+ if (parts.contains("currencyFormat")) {
+ result = handleCurrencyFormat(parts, value);
+ } else {
+ result = handleDecimalFormat(parts, value);
+ }
+ }
+ } else if (parts.getElement(2).contains("symbols")) {
+ result = handleNumberSymbol(parts, value);
+ } else if (parts.contains("defaultNumberingSystem") || parts.contains("otherNumberingSystems")) {
+ result = handleNumberingSystem(value);
+ } else if (parts.contains("currencyFormats") && parts.contains("unitPattern")) {
+ result = formatCountValue(xpath, parts, value);
+ } else if (parts.getElement(-1).equals("compoundUnitPattern")) {
+ result = handleCompoundUnit(parts);
+ } else if (parts.getElement(-1).equals("compoundUnitPattern1")
+ || parts.getElement(-1).equals("unitPrefixPattern")) {
+ result = handleCompoundUnit1(parts, value);
+ } else if (parts.getElement(-1).equals("unitPattern")) {
+ result = handleFormatUnit(parts, value);
+ } else if (parts.getElement(-1).equals("perUnitPattern")) {
+ result = handleFormatPerUnit(parts, value);
+ } else if (parts.getElement(-1).equals("durationUnitPattern")) {
+ result = handleDurationUnit(value);
+ } else if (parts.contains("intervalFormats")) {
+ result = handleIntervalFormats(parts, value);
+ } else if (parts.getElement(1).equals("delimiters")) {
+ result = handleDelimiters(parts, xpath, value);
+ } else if (parts.getElement(1).equals("listPatterns")) {
+ result = handleListPatterns(parts, value);
+ } else if (parts.getElement(2).equals("ellipsis")) {
+ result = handleEllipsis(parts.getAttributeValue(-1, "type"), value);
+ } else if (parts.getElement(-1).equals("monthPattern")) {
+ result = handleMonthPatterns(parts, value);
+ } else if (parts.getElement(-1).equals("appendItem")) {
+ result = handleAppendItems(parts, value);
+ } else if (parts.getElement(-1).equals("annotation")) {
+ result = handleAnnotationName(parts, value);
+ } else if (parts.getElement(-1).equals("characterLabel")) {
+ result = handleLabel(parts, value);
+ } else if (parts.getElement(-1).equals("characterLabelPattern")) {
+ result = handleLabelPattern(parts, value);
+ }
if (result != null) {
- // add transliteration if one exists
if (!typeIsEnglish) {
result = addTransliteration(result, value);
}
result = finalizeBackground(result);
}
-
- if (cachingIsEnabled) {
- if (result == null) {
- cache.put(cacheKey, NONE);
- } else {
- cache.put(cacheKey, result);
- }
- }
return result;
}
@@ -721,10 +565,15 @@
//ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="stand-alone"]/dayPeriodWidth[@type="wide"]/dayPeriod[@type="morning1"]
List<String> examples = new ArrayList<>();
final String dayPeriodType = parts.getAttributeValue(5, "type");
+ if (dayPeriodType == null) {
+ return null; // formerly happened for some "/alias" paths
+ }
org.unicode.cldr.util.DayPeriodInfo.Type aType = dayPeriodType.equals("format") ? DayPeriodInfo.Type.format : DayPeriodInfo.Type.selection;
DayPeriodInfo dayPeriodInfo = supplementalDataInfo.getDayPeriods(aType, cldrFile.getLocaleID());
String periodString = parts.getAttributeValue(-1, "type");
-
+ if (periodString == null) {
+ return null; // formerly happened for some "/alias" paths
+ }
DayPeriod dayPeriod = DayPeriod.valueOf(periodString);
String periods = dayPeriodInfo.toString(dayPeriod);
examples.add(periods);
@@ -733,10 +582,11 @@
value = "�";
}
R3<Integer, Integer, Boolean> info = dayPeriodInfo.getFirstDayPeriodInfo(dayPeriod);
- int time = (((info.get0() + info.get1()) % DayPeriodInfo.DAY_LIMIT) / 2);
- //String calendar = parts.getAttributeValue(3, "type");
- String timeFormatString = icuServiceBuilder.formatDayPeriod(time, backgroundStartSymbol + value + backgroundEndSymbol);
- examples.add(invertBackground(timeFormatString));
+ if (info != null) {
+ int time = (((info.get0() + info.get1()) % DayPeriodInfo.DAY_LIMIT) / 2);
+ String timeFormatString = icuServiceBuilder.formatDayPeriod(time, backgroundStartSymbol + value + backgroundEndSymbol);
+ examples.add(invertBackground(timeFormatString));
+ }
}
return formatExampleList(examples.toArray(new String[examples.size()]));
}
@@ -745,13 +595,39 @@
return UnitLength.valueOf(parts.getAttributeValue(-3, "type").toUpperCase(Locale.ENGLISH));
}
- private String handleFormatUnit(Count count, String value) {
- FixedDecimal amount = getBest(count);
- if (amount == null) {
- return "n/a";
+ private String handleFormatUnit(XPathParts parts, String value) {
+ String count = parts.getAttributeValue(-1, "count");
+ List<String> examples = new ArrayList<>();
+ /*
+ * PluralRules.FixedDecimal is deprecated, but deprecated in ICU is
+ * also used to mark internal methods (which are OK for us to use in CLDR).
+ */
+ @SuppressWarnings("deprecation")
+ FixedDecimal amount = getBest(Count.valueOf(count));
+ if (amount != null) {
+ DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
+ examples.add(format(value, backgroundStartSymbol + numberFormat.format(amount) + backgroundEndSymbol));
}
+ if (parts.getElement(-2).equals("unit")) {
+ String longUnitId = parts.getAttributeValue(-2, "type");
+ UnitConverter uc = supplementalDataInfo.getUnitConverter();
+ final String shortUnitId = uc.getShortId(longUnitId);
+ if (UnitConverter.HACK_SKIP_UNIT_NAMES.contains(shortUnitId)) {
+ return null;
+ }
+ final UnitId unitId = uc.createUnitId(shortUnitId);
+ String width = parts.getAttributeValue(2, "type");
+ String pattern = unitId.toString(getCldrFile(), width, count, "nominative", null, false);
+ if (pattern != null && !value.contentEquals(pattern)) {
+ examples.add(pattern);
+ }
+ }
+ return formatExampleList(examples);
+ }
+
+ private String handleFormatPerUnit(XPathParts parts, String value) {
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
- return format(value, backgroundStartSymbol + numberFormat.format(amount) + backgroundEndSymbol);
+ return format(value, backgroundStartSymbol + numberFormat.format(1) + backgroundEndSymbol);
}
public String handleCompoundUnit(XPathParts parts) {
@@ -761,6 +637,7 @@
return handleCompoundUnit(unitLength, compoundType, count);
}
+ @SuppressWarnings("deprecation")
public String handleCompoundUnit(UnitLength unitLength, String compoundType, Count count) {
/**
* <units>
@@ -807,13 +684,12 @@
String unit1 = backgroundStartSymbol + unit1mid.trim() + backgroundEndSymbol;
String unit2 = backgroundStartSymbol + unit2mid.trim() + backgroundEndSymbol;
- // TODO fix hack
String form = this.pluralInfo.getPluralRules().select(amount);
// we rebuild a path, because we may have changed it.
String perPath = makeCompoundUnitPath(unitLength, compoundType, "compoundUnitPattern");
return format(getValueFromFormat(perPath, form), unit1, unit2);
}
-
+
public String handleCompoundUnit1(XPathParts parts, String compoundPattern) {
UnitLength unitLength = getUnitLength(parts);
String pathCount = parts.getAttributeValue(-1, "count");
@@ -828,7 +704,7 @@
String pathFormat = "//ldml/units/unitLength" + unitLength.typeString + "/unit[@type=\"{0}\"]/displayName";
String meterFormat = getValueFromFormat(pathFormat, "length-meter");
-
+
String modFormat = combinePrefix(meterFormat, compoundPattern, unitLength == UnitLength.LONG);
return removeEmptyRuns(modFormat);
@@ -837,21 +713,23 @@
public String handleCompoundUnit1(UnitLength unitLength, Count count, String compoundPattern) {
// we want to get a number that works for the count passed in.
+ @SuppressWarnings("deprecation")
FixedDecimal amount = getBest(count);
if (amount == null) {
return "n/a";
}
- FixedDecimal oneValue = new FixedDecimal(1d, 0);
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
+
+ @SuppressWarnings("deprecation")
String form1 = this.pluralInfo.getPluralRules().select(amount);
-
+
String pathFormat = "//ldml/units/unitLength" + unitLength.typeString
+ "/unit[@type=\"{0}\"]/unitPattern[@count=\"{1}\"]";
-
+
// now pick up the meter pattern
String meterFormat = getValueFromFormat(pathFormat, "length-meter", form1);
-
+
// now combine them
String modFormat = combinePrefix(meterFormat, compoundPattern, unitLength == UnitLength.LONG);
@@ -860,7 +738,7 @@
}
// TODO, pass in unitLength instead of last parameter, and do work in Units.combinePattern.
-
+
public String combinePrefix(String unitFormat, String inCompoundPattern, boolean lowercaseUnitIfNoSpaceInCompound) {
// mark the part except for the {0} as foreground
String compoundPattern = backgroundEndSymbol
@@ -868,7 +746,7 @@
+ backgroundStartSymbol;
String modFormat = Units.combinePattern(unitFormat, compoundPattern, lowercaseUnitIfNoSpaceInCompound);
-
+
return backgroundStartSymbol + modFormat + backgroundEndSymbol;
}
@@ -879,6 +757,7 @@
+ "/" + patternType;
}
+ @SuppressWarnings("deprecation")
private FixedDecimal getBest(Count count) {
FixedDecimalSamples samples = pluralInfo.getPluralRules().getDecimalSamples(count.name(), SampleType.DECIMAL);
if (samples == null) {
@@ -903,9 +782,9 @@
}
}
- IntervalFormat intervalFormat = new IntervalFormat();
+ private IntervalFormat intervalFormat = new IntervalFormat();
- static Calendar generatingCalendar = Calendar.getInstance(ULocale.US);
+ private static Calendar generatingCalendar = Calendar.getInstance(ULocale.US);
private static Date getDate(int year, int month, int date, int hour, int minute, int second) {
synchronized (generatingCalendar) {
@@ -915,8 +794,9 @@
}
}
- static Date FIRST_INTERVAL = getDate(2008, 1, 13, 5, 7, 9);
- static Map<String, Date> SECOND_INTERVAL = CldrUtility.asMap(new Object[][] {
+ private static Date FIRST_INTERVAL = getDate(2008, 1, 13, 5, 7, 9);
+ private static Map<String, Date> SECOND_INTERVAL = CldrUtility.asMap(new Object[][] {
+ { "G", getDate(1009, 2, 14, 17, 8, 10) }, // "G" mostly useful for calendars that have short eras, like Japanese
{ "y", getDate(2009, 2, 14, 17, 8, 10) },
{ "M", getDate(2008, 2, 14, 17, 8, 10) },
{ "d", getDate(2008, 1, 14, 17, 8, 10) },
@@ -936,12 +816,32 @@
dateFormat.format(SECOND_INTERVAL.get("y")));
}
String greatestDifference = parts.getAttributeValue(-1, "id");
- if (greatestDifference.equals("H")) greatestDifference = "h";
+ /*
+ * Choose an example interval suitable for the symbol. If testing years, use an interval
+ * of more than one year, and so forth. For the purpose of choosing the interval,
+ * "H" is equivalent to "h", and so forth; map to a symbol that occurs in SECOND_INTERVAL.
+ */
+ if (greatestDifference.equals("H")) { // Hour [0-23]
+ greatestDifference = "h"; // Hour [1-12]
+ } else if (greatestDifference.equals("B") // flexible day periods
+ || greatestDifference.equals("b")) { // am, pm, noon, midnight
+ greatestDifference = "a"; // AM, PM
+ }
// intervalFormatFallback
// //ldml/dates/calendars/calendar[@type="gregorian"]/dateTimeFormats/intervalFormats/intervalFormatItem[@id="yMd"]/greatestDifference[@id="y"]
// find where to split the value
intervalFormat.setPattern(parts, value);
- return intervalFormat.format(FIRST_INTERVAL, SECOND_INTERVAL.get(greatestDifference));
+ Date later = SECOND_INTERVAL.get(greatestDifference);
+ if (later == null) {
+ /*
+ * This may still happen for some less-frequently used symbols such as "Q" (Quarter),
+ * if they ever occur in the data.
+ * Reference: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
+ * For now, such paths do not get examples.
+ */
+ return null;
+ }
+ return intervalFormat.format(FIRST_INTERVAL, later);
}
private String handleDelimiters(XPathParts parts, String xpath, String value) {
@@ -978,6 +878,9 @@
private String handleRegularListPatterns(XPathParts parts, String value, ListTypeLength listTypeLength) {
String patternType = parts.getAttributeValue(-1, "type");
+ if (patternType == null) {
+ return null; // formerly happened for some "/alias" paths
+ }
String pathFormat = "//ldml/localeDisplayNames/territories/territory[@type=\"{0}\"]";
String territory1 = getValueFromFormat(pathFormat, "CH");
String territory2 = getValueFromFormat(pathFormat, "JP");
@@ -992,6 +895,9 @@
private String handleDurationListPatterns(XPathParts parts, String value, UnitLength unitWidth) {
String patternType = parts.getAttributeValue(-1, "type");
+ if (patternType == null) {
+ return null; // formerly happened for some "/alias" paths
+ }
String duration1 = getFormattedUnit("duration-day", unitWidth, 4);
String duration2 = getFormattedUnit("duration-hour", unitWidth, 2);
if (patternType.equals("2")) {
@@ -1026,15 +932,18 @@
}
}
+ @SuppressWarnings("deprecation")
private String getFormattedUnit(String unitType, UnitLength unitWidth, FixedDecimal unitAmount) {
DecimalFormat numberFormat = icuServiceBuilder.getNumberFormat(1);
return getFormattedUnit(unitType, unitWidth, unitAmount, numberFormat.format(unitAmount));
}
+ @SuppressWarnings("deprecation")
private String getFormattedUnit(String unitType, UnitLength unitWidth, double unitAmount) {
return getFormattedUnit(unitType, unitWidth, new FixedDecimal(unitAmount));
}
+ @SuppressWarnings("deprecation")
private String getFormattedUnit(String unitType, UnitLength unitWidth, FixedDecimal unitAmount, String formattedUnitAmount) {
String form = this.pluralInfo.getPluralRules().select(unitAmount);
String pathFormat = "//ldml/units/unitLength" + unitWidth.typeString
@@ -1054,12 +963,16 @@
String startPattern = getPattern(listPathFormat, "start", patternType, value);
String middlePattern = getPattern(listPathFormat, "middle", patternType, value);
String endPattern = getPattern(listPathFormat, "end", patternType, value);
+ /*
+ * DateTimePatternGenerator.FormatParser is deprecated, but deprecated in ICU is
+ * also used to mark internal methods (which are OK for us to use in CLDR).
+ */
+ @SuppressWarnings("deprecation")
ListFormatter listFormatter = new ListFormatter(doublePattern, startPattern, middlePattern, endPattern);
- String example = listFormatter.format(items);
+ String example = listFormatter.format((Object[]) items);
return invertBackground(example);
}
-
/**
* Helper method for handleListPatterns. Returns the pattern to be used for
* a specified pattern type.
@@ -1143,7 +1056,8 @@
return result;
}
- class IntervalFormat {
+ private class IntervalFormat {
+ @SuppressWarnings("deprecation")
DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser();
SimpleDateFormat firstFormat = new SimpleDateFormat();
SimpleDateFormat secondFormat = new SimpleDateFormat();
@@ -1152,11 +1066,36 @@
BitSet letters = new BitSet();
public String format(Date earlier, Date later) {
+ if (earlier == null || later == null) {
+ return null;
+ }
+ if (later.compareTo(earlier) < 0) {
+ /*
+ * Swap so earlier is earlier than later.
+ * This is necessary for "G" (Era) given the current FIRST_INTERVAL, SECOND_INTERVAL
+ */
+ Date tmp = earlier;
+ earlier = later;
+ later = tmp;
+ }
return firstFormat.format(earlier) + secondFormat.format(later);
}
+ @SuppressWarnings("deprecation")
public IntervalFormat setPattern(XPathParts parts, String pattern) {
- formatParser.set(pattern);
+ if (formatParser == null || pattern == null) {
+ return this;
+ }
+ try {
+ formatParser.set(pattern);
+ } catch (NullPointerException e) {
+ /*
+ * This has been observed to occur, within ICU, for unknown reasons.
+ */
+ System.err.println("Caught NullPointerException in IntervalFormat.setPattern, pattern = " + pattern);
+ e.printStackTrace();
+ return null;
+ }
first.setLength(0);
second.setLength(0);
boolean doFirst = true;
@@ -1194,14 +1133,18 @@
}
private String handleDurationUnit(String value) {
- // ULocale locale = new ULocale(this.icuServiceBuilder.getCldrFile().getLocaleID());
- // SimpleDateFormat df = new SimpleDateFormat(value.replace('h', 'H'), locale);
DateFormat df = this.icuServiceBuilder.getDateFormat("gregorian", value.replace('h', 'H'));
df.setTimeZone(TimeZone.GMT_ZONE);
long time = ((5 * 60 + 37) * 60 + 23) * 1000;
- return df.format(new Date(time));
+ try {
+ return df.format(new Date(time));
+ } catch (IllegalArgumentException e) {
+ // e.g., Illegal pattern character 'o' in "aɖabaƒoƒo m:ss"
+ return null;
+ }
}
+ @SuppressWarnings("deprecation")
static final List<FixedDecimal> CURRENCY_SAMPLES = Arrays.asList(
new FixedDecimal(1.23),
new FixedDecimal(0),
@@ -1210,6 +1153,7 @@
new FixedDecimal(5.67),
new FixedDecimal(1));
+ @SuppressWarnings("deprecation")
private String formatCountValue(String xpath, XPathParts parts, String value) {
if (!parts.containsAttribute("count")) { // no examples for items that don't format
return null;
@@ -1225,7 +1169,7 @@
final boolean isCurrency = !parts.contains("units");
Count count = null;
- final LinkedHashSet<FixedDecimal> exampleCount = new LinkedHashSet();
+ final LinkedHashSet<FixedDecimal> exampleCount = new LinkedHashSet<>();
exampleCount.addAll(CURRENCY_SAMPLES);
String countString = parts.getAttributeValue(-1, "count");
if (countString == null) {
@@ -1248,7 +1192,7 @@
int decimalCount = currencyFormat.getMinimumFractionDigits();
// we will cycle until we have (at most) two examples.
- Set<FixedDecimal> examplesSeen = new HashSet<FixedDecimal>();
+ Set<FixedDecimal> examplesSeen = new HashSet<>();
int maxCount = 2;
main:
// If we are a currency, we will try to see if we can set the decimals to match.
@@ -1301,6 +1245,7 @@
return result.isEmpty() ? null : result;
}
+ @SuppressWarnings("deprecation")
static public void getStartEndSamples(PluralRules.FixedDecimalSamples samples, Set<FixedDecimal> target) {
if (samples != null) {
for (FixedDecimalRange item : samples.getSamples()) {
@@ -1310,6 +1255,7 @@
}
}
+ @SuppressWarnings("deprecation")
private String formatCurrency(String value, String unitType, final boolean isPattern, final boolean isCurrency, Count count,
FixedDecimal example) {
String resultItem;
@@ -1363,21 +1309,19 @@
}
private String getUnitPattern(String unitType, final boolean isCurrency, Count count) {
- String unitPattern;
- String unitPatternPath = cldrFile.getCountPathWithFallback(isCurrency
- ? "//ldml/numbers/currencyFormats/unitPattern"
- : "//ldml/units/unit[@type=\"" + unitType + "\"]/unitPattern",
- count, true);
- unitPattern = cldrFile.getWinningValue(unitPatternPath);
- return unitPattern;
+ return cldrFile.getStringValue(isCurrency
+ ? "//ldml/numbers/currencyFormats/unitPattern" + countAttribute(count)
+ : "//ldml/units/unit[@type=\"" + unitType + "\"]/unitPattern" + countAttribute(count));
}
private String getUnitName(String unitType, final boolean isCurrency, Count count) {
- String unitNamePath = cldrFile.getCountPathWithFallback(isCurrency
- ? "//ldml/numbers/currencies/currency[@type=\"" + unitType + "\"]/displayName"
- : "//ldml/units/unit[@type=\"" + unitType + "\"]/unitPattern",
- count, true);
- return unitNamePath == null ? unitType : cldrFile.getWinningValue(unitNamePath);
+ return cldrFile.getStringValue(isCurrency
+ ? "//ldml/numbers/currencies/currency[@type=\"" + unitType + "\"]/displayName" + countAttribute(count)
+ : "//ldml/units/unit[@type=\"" + unitType + "\"]/unitPattern" + countAttribute(count));
+ }
+
+ public String countAttribute(Count count) {
+ return "[@count=\"" + count + "\"]";
}
private String handleNumberSymbol(XPathParts parts, String value) {
@@ -1401,6 +1345,11 @@
index = 2;
numberSample = 0.023;
originalValue = cldrFile.getWinningValue(parts.addRelative("../percentSign").toString());
+ } else if (symbolType.equals("approximatelySign")) {
+ // Substitute the approximately symbol in for the minus sign.
+ index = 1;
+ numberSample = -numberSample;
+ originalValue = cldrFile.getWinningValue(parts.addRelative("../minusSign").toString());
} else if (symbolType.equals("exponential") || symbolType.equals("plusSign")) {
index = 3;
} else if (symbolType.equals("superscriptingExponent")) {
@@ -1551,6 +1500,7 @@
return result;
}
+ @SuppressWarnings("deprecation")
private String handleDateFormatItem(String xpath, String value) {
String fullpath = cldrFile.getFullXPath(xpath);
@@ -1591,7 +1541,7 @@
if (id == null || id.indexOf('B') < 0) {
return sdf.format(DATE_SAMPLE);
} else {
- List<String> examples = new ArrayList<String>();
+ List<String> examples = new ArrayList<>();
examples.add(sdf.format(DATE_SAMPLE3));
examples.add(sdf.format(DATE_SAMPLE));
examples.add(sdf.format(DATE_SAMPLE4));
@@ -1639,9 +1589,11 @@
territory = loc.getCountry();
if (territory == null || territory.length() == 0) {
loc = supplementalDataInfo.getDefaultContentFromBase(loc);
- territory = loc.getCountry();
- if (territory.equals("001") && loc.getLanguage().equals("ar")) {
- territory = "EG"; // Use Egypt as territory for examples in ar locale, since its default content is ar_001.
+ if (loc != null) {
+ territory = loc.getCountry();
+ if (territory.equals("001") && loc.getLanguage().equals("ar")) {
+ territory = "EG"; // Use Egypt as territory for examples in ar locale, since its default content is ar_001.
+ }
}
}
if (territory == null || territory.length() == 0) {
@@ -1678,7 +1630,14 @@
}
private String formatCountDecimal(DecimalFormat numberFormat, String countValue) {
- Count count = Count.valueOf(countValue);
+ Count count;
+ try {
+ count = Count.valueOf(countValue);
+ } catch (Exception e) {
+ String locale = getCldrFile().getLocaleID();
+ PluralInfo pluralInfo = supplementalDataInfo.getPlurals(locale);
+ count = pluralInfo.getCount(new FixedDecimal(countValue));
+ }
Double numberSample = getExampleForPattern(numberFormat, count);
if (numberSample == null) {
// Ideally, we would suppress the value in the survey tool.
@@ -1704,7 +1663,7 @@
/**
* Calculates a numerical example to use for the specified pattern using
- * brute force (TODO: there should be a more elegant way to do this).
+ * brute force (there should be a more elegant way to do this).
*
* @param format
* @param count
@@ -1716,26 +1675,9 @@
}
int numDigits = format.getMinimumIntegerDigits();
Map<Count, Double> samples = patternExamples.getSamples(numDigits);
- // int min = (int) Math.pow(10, numDigits - 1);
- // int max = min * 10;
- // Map<Count, Integer> examples = patternExamples.get(numDigits);
- // if (examples == null) {
- // patternExamples.put(numDigits, examples = new HashMap<Count, Integer>());
- // Set<Count> typesLeft = new HashSet<Count>(pluralInfo.getCountToExamplesMap().keySet());
- // // Add at most one example of each type.
- // for (int i = min; i < max; ++i) {
- // if (typesLeft.isEmpty()) break;
- // Count type = Count.valueOf(pluralInfo.getPluralRules().select(i));
- // if (!typesLeft.contains(type)) continue;
- // examples.put(type, i);
- // typesLeft.remove(type);
- // }
- // // Add zero as an example only if there is no other option.
- // if (min == 1) {
- // Count type = Count.valueOf(pluralInfo.getPluralRules().select(0));
- // if (!examples.containsKey(type)) examples.put(type, 0);
- // }
- // }
+ if (samples == null) {
+ return null;
+ }
return samples.get(count);
}
@@ -1802,7 +1744,7 @@
String localePattern = getLocaleDisplayPattern("localePattern", element, value);
String localeSeparator = getLocaleDisplayPattern("localeSeparator", element, value);
- List<String> locales = new ArrayList<String>();
+ List<String> locales = new ArrayList<>();
if (element.equals("localePattern")) {
locales.add("uz-AF");
}
@@ -1827,7 +1769,7 @@
}
} else {
value = setBackground(value);
- List<String> examples = new ArrayList<String>();
+ List<String> examples = new ArrayList<>();
String nameType = parts.getElement(3);
Map<String, String> likely = supplementalDataInfo.getLikelySubtags();
@@ -1894,7 +1836,7 @@
examples.add(invertBackground(format(localePattern, languageName, scriptTerritory)));
}
Output<String> pathWhereFound = null;
- if (isStandAloneValue
+ if (isStandAloneValue
|| cldrFile.getStringValueWithBailey(xpath + ALT_STAND_ALONE, pathWhereFound = new Output<>(), null) == null
|| !pathWhereFound.value.contains(ALT_STAND_ALONE)) {
// only do this if either it is a stand-alone form,
@@ -1962,6 +1904,9 @@
* @return
*/
private String setBackground(String inputPattern) {
+ if (inputPattern == null) {
+ return "?";
+ }
Matcher m = PARAMETER.matcher(inputPattern);
return backgroundStartSymbol + m.replaceAll(backgroundEndSymbol + "$1" + backgroundStartSymbol)
+ backgroundEndSymbol;
@@ -1970,9 +1915,7 @@
/**
* Put a background on an item, skipping enclosed patterns, except for {0}
* @param patternToEmbed
- * TODO
* @param sampleTerritory
- *
* @return
*/
private String setBackgroundExceptMatch(String input, Pattern patternToEmbed) {
@@ -2030,10 +1973,8 @@
/**
* This is called just before we return a result. It fixes the special characters that were added by setBackground.
*
- * @param input
- * string with special characters from setBackground.
+ * @param input string with special characters from setBackground.
* @param invert
- * TODO
* @return string with HTML for the background.
*/
private String finalizeBackground(String input) {
@@ -2056,11 +1997,11 @@
}
private String invertBackground(String input) {
- return input == null ? null
- : backgroundStartSymbol
+ return input == null ? null
+ : backgroundStartSymbol
+ input.replace(backgroundStartSymbol, backgroundTempSymbol)
.replace(backgroundEndSymbol, backgroundStartSymbol)
- .replace(backgroundTempSymbol, backgroundEndSymbol)
+ .replace(backgroundTempSymbol, backgroundEndSymbol)
+ backgroundEndSymbol;
}
@@ -2069,8 +2010,8 @@
.replace(backgroundEndSymbol + backgroundStartSymbol, "");
}
- public static final Pattern PARAMETER = PatternCache.get("(\\{[0-9]\\})");
- public static final Pattern PARAMETER_SKIP0 = PatternCache.get("(\\{[1-9]\\})");
+ public static final Pattern PARAMETER = PatternCache.get("(\\{(?:0|[1-9][0-9]*)\\})");
+ public static final Pattern PARAMETER_SKIP0 = PatternCache.get("(\\{[1-9][0-9]*\\})");
public static final Pattern ALL_DIGITS = PatternCache.get("(\\p{Nd}+(.\\p{Nd}+)?)");
/**
@@ -2146,14 +2087,12 @@
// lazy initialization
if (pathDescription == null) {
- Map<String, List<Set<String>>> starredPaths = new HashMap<String, List<Set<String>>>();
- Map<String, String> extras = new HashMap<String, String>();
+ Map<String, List<Set<String>>> starredPaths = new HashMap<>();
+ Map<String, String> extras = new HashMap<>();
this.pathDescription = new PathDescription(supplementalDataInfo, englishFile, extras, starredPaths,
PathDescription.ErrorHandling.CONTINUE);
- this.pathDescription = new PathDescription(supplementalDataInfo, englishFile, extras, starredPaths,
- PathDescription.ErrorHandling.CONTINUE);
if (helpMessages == null) {
helpMessages = new HelpMessages("test_help_messages.html");
}
@@ -2193,13 +2132,6 @@
}
return buffer.toString();
- // return helpMessages.find(xpath);
- // if (xpath.contains("/exemplarCharacters")) {
- // result = "The standard exemplar characters are those used in customary writing ([a-z] for English; "
- // + "the auxiliary characters are used in foreign words found in typical magazines, newspapers, &c.; "
- // + "currency auxilliary characters are those used in currency symbols, like 'US$ 1,234'. ";
- // }
- // return result == null ? null : TransliteratorUtilities.toHTML.transliterate(result);
}
public synchronized String getHelpHtml(String xpath, String value) {
diff --git a/tools/java/org/unicode/cldr/test/FactoryCheckCLDR.java b/tools/java/org/unicode/cldr/test/FactoryCheckCLDR.java
index 205e752..5159db4 100644
--- a/tools/java/org/unicode/cldr/test/FactoryCheckCLDR.java
+++ b/tools/java/org/unicode/cldr/test/FactoryCheckCLDR.java
@@ -17,6 +17,7 @@
private CLDRFile resolvedCldrFileToCheck;
private PathHeader.Factory pathHeaderFactory;
+ @Override
public synchronized CLDRFile getEnglishFile() {
if (super.getEnglishFile() != null) {
return super.getEnglishFile();
@@ -58,7 +59,7 @@
public Factory getFactory() {
return factory;
}
-
+
public String getPathReferenceForMessage(String path, boolean codeOnly) {
PathHeader pathHeader = getPathHeaderFactory().fromPath(path);
String referenceToOther;
diff --git a/tools/java/org/unicode/cldr/test/FlexibleDateFromCLDR.java b/tools/java/org/unicode/cldr/test/FlexibleDateFromCLDR.java
index 4cbc15d..09e749c 100644
--- a/tools/java/org/unicode/cldr/test/FlexibleDateFromCLDR.java
+++ b/tools/java/org/unicode/cldr/test/FlexibleDateFromCLDR.java
@@ -130,7 +130,7 @@
System.out.println("END");
}
- Map<String, String> failureMap = new TreeMap<String, String>();
+ Map<String, String> failureMap = new TreeMap<>();
/**
* @param path
diff --git a/tools/java/org/unicode/cldr/test/FlexibleDateTime.java b/tools/java/org/unicode/cldr/test/FlexibleDateTime.java
index 8b65c23..620bf13 100644
--- a/tools/java/org/unicode/cldr/test/FlexibleDateTime.java
+++ b/tools/java/org/unicode/cldr/test/FlexibleDateTime.java
@@ -81,20 +81,20 @@
static class LocaleIDFixer {
LocaleIDParser lip = new LocaleIDParser();
- static final Set<String> mainLocales = new HashSet<String>(
+ static final Set<String> mainLocales = new HashSet<>(
Arrays.asList(new String[] { "ar_EG", "bn_IN", "de_DE", "en_US", "es_ES", "fr_FR", "it_IT", "nl_NL", "pt_BR", "sv_SE", "zh_TW" }));
DeprecatedCodeFixer dcf = new DeprecatedCodeFixer();
Map<String, String> fixLocales(Collection<String> available, Map<String, String> result) {
// find the multi-country locales
- Map<String, Set<String>> language_locales = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> language_locales = new HashMap<>();
for (String locale : available) {
String fixedLocale = dcf.fixLocale(locale);
result.put(locale, fixedLocale);
String language = lip.set(fixedLocale).getLanguageScript();
Set<String> locales = language_locales.get(language);
if (locales == null) {
- language_locales.put(language, locales = new HashSet<String>());
+ language_locales.put(language, locales = new HashSet<>());
}
locales.add(locale);
}
@@ -106,7 +106,7 @@
result.put(locales.iterator().next(), language);
continue;
}
- Set<String> intersect = new HashSet<String>(mainLocales);
+ Set<String> intersect = new HashSet<>(mainLocales);
intersect.retainAll(locales);
if (intersect.size() == 1) {
// the intersection is the parent, so overwrite it
@@ -124,8 +124,8 @@
}
static class DeprecatedCodeFixer {
- Map<String, String> languageAlias = new HashMap<String, String>();
- Map<String, String> territoryAlias = new HashMap<String, String>();
+ Map<String, String> languageAlias = new HashMap<>();
+ Map<String, String> territoryAlias = new HashMap<>();
{
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile supp = cldrFactory.make(CLDRFile.SUPPLEMENTAL_NAME, false);
@@ -139,7 +139,7 @@
} else if (parts.getElement(3).equals("territoryAlias")) {
territoryAlias.put(type, replacement);
} else {
- throw new IllegalArgumentException("Unexpected type: " + path);
+ throw new IllegalArgumentException("Unexpected type: " + path);
}
}
// special hack for OpenOffice
@@ -151,7 +151,7 @@
String fixLocale(String locale) {
lip.set(locale);
String territory = lip.getRegion();
- String replacement = (String) territoryAlias.get(territory);
+ String replacement = territoryAlias.get(territory);
if (replacement != null) {
lip.setRegion(replacement);
}
@@ -349,6 +349,7 @@
static Date TEST_DATE = new Date(104, 8, 13, 23, 58, 59);
static Comparator<Collection<String>> VariableFieldComparator = new Comparator<Collection<String>>() {
+ @Override
public int compare(Collection<String> a, Collection<String> b) {
if (a.size() != b.size()) {
if (a.size() < b.size()) return 1;
@@ -369,7 +370,7 @@
"[A a c D d E e F G g h H K k L m M q Q s S u v W w Y y z Z]");
static Collection<String> getOOData(Factory cldrFactory, String locale) {
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
OOConverter ooConverter = new OOConverter();
{
if (SHOW_OO) {
diff --git a/tools/java/org/unicode/cldr/test/HelpMessages.java b/tools/java/org/unicode/cldr/test/HelpMessages.java
index 735e2ee..adca8ed 100644
--- a/tools/java/org/unicode/cldr/test/HelpMessages.java
+++ b/tools/java/org/unicode/cldr/test/HelpMessages.java
@@ -26,13 +26,13 @@
private static final Matcher HEADER_HTML = PatternCache.get("<h[0-9]>(.*)</h[0-9]>").matcher("");
- List<Matcher> keys = new ArrayList<Matcher>();
+ List<Matcher> keys = new ArrayList<>();
- List<String> values = new ArrayList<String>();
+ List<String> values = new ArrayList<>();
enum Status {
BASE, BEFORE_CELL, IN_CELL, IN_INSIDE_TABLE
- };
+ }
StringBuilder[] currentColumn = new StringBuilder[2];
diff --git a/tools/java/org/unicode/cldr/test/OutdatedPaths.java b/tools/java/org/unicode/cldr/test/OutdatedPaths.java
index 1a63d42..065e238 100644
--- a/tools/java/org/unicode/cldr/test/OutdatedPaths.java
+++ b/tools/java/org/unicode/cldr/test/OutdatedPaths.java
@@ -70,8 +70,8 @@
* @param directory
*/
public OutdatedPaths(String directory) {
- Map<Long, PathHeader> id2header = new HashMap<Long, PathHeader>(); // for debugging
-
+ Map<Long, PathHeader> id2header = new HashMap<>(); // for debugging
+
readLocaleToPaths(directory, id2header);
// now previous English
@@ -98,7 +98,7 @@
if (DEBUG) {
System.out.println("OutdatedPaths: Locale: " + locale);
}
- final HashSet<Long> data = new HashSet<Long>();
+ final HashSet<Long> data = new HashSet<>();
int size = dataIn.readInt();
for (int i = 0; i < size; ++i) {
long item = dataIn.readLong();
@@ -115,7 +115,7 @@
}
}
- public static void readBirthValues(String outdatedDirectory, Map<Long, PathHeader> id2header,
+ public static void readBirthValues(String outdatedDirectory, Map<Long, PathHeader> id2header,
Map<Long, Pair<CldrVersion, String>> pathToBirthNPrevious2) {
try {
DataInputStream dataIn = openDataInput(outdatedDirectory, OUTDATED_ENGLISH_DATA);
@@ -134,7 +134,7 @@
CldrVersion birth = CldrVersion.from(dataIn.readUTF());
if (DEBUG) {
- System.out.println("en\t(" + previous + ")"
+ System.out.println("en\t(" + previous + ")"
+ (id2header == null ? "" : "\t" + id2header.get(pathId)));
}
pathToBirthNPrevious2.put(pathId, Pair.of(birth,previous).freeze());
@@ -150,7 +150,7 @@
}
public Map<Long, PathHeader> getIdToPath(Factory factory) {
- Map<Long, PathHeader> result = new HashMap<Long, PathHeader>();
+ Map<Long, PathHeader> result = new HashMap<>();
CLDRFile english = factory.make("en", true);
PathHeader.Factory pathHeaders = PathHeader.getFactory(english);
for (String s : english) {
@@ -268,10 +268,10 @@
OutdatedPaths outdatedPaths = SINGLETON.get();
if (outdatedPaths == null) {
outdatedPaths = new OutdatedPaths();
- SINGLETON = new SoftReference<OutdatedPaths>(outdatedPaths);
+ SINGLETON = new SoftReference<>(outdatedPaths);
}
return outdatedPaths;
}
- private static Reference<OutdatedPaths> SINGLETON = new SoftReference<OutdatedPaths>(null);
+ private static Reference<OutdatedPaths> SINGLETON = new SoftReference<>(null);
}
diff --git a/tools/java/org/unicode/cldr/test/QuickCheck.java b/tools/java/org/unicode/cldr/test/QuickCheck.java
index e83fc20..002ff3f 100644
--- a/tools/java/org/unicode/cldr/test/QuickCheck.java
+++ b/tools/java/org/unicode/cldr/test/QuickCheck.java
@@ -26,6 +26,7 @@
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.Organization;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.PrettyPath;
import org.unicode.cldr.util.StandardCodes;
@@ -49,7 +50,7 @@
* @author markdavis
*/
public class QuickCheck {
- private static final Set<String> skipAttributes = new HashSet<String>(Arrays.asList(new String[] {
+ private static final Set<String> skipAttributes = new HashSet<>(Arrays.asList(new String[] {
"alt", "draft", "references" }));
private static String localeRegex;
@@ -117,11 +118,11 @@
private static void checkDtds(String directory) throws IOException {
File directoryFile = new File(directory);
File[] listFiles = directoryFile.listFiles();
- String canonicalPath = directoryFile.getCanonicalPath();
+ String normalizedPath = PathUtilities.getNormalizedPathString(directoryFile);
if (listFiles == null) {
- throw new IllegalArgumentException("Empty directory: " + canonicalPath);
+ throw new IllegalArgumentException("Empty directory: " + normalizedPath);
}
- System.out.println("Checking files for DTD errors in: " + canonicalPath);
+ System.out.println("Checking files for DTD errors in: " + normalizedPath);
for (File fileName : listFiles) {
if (!fileName.toString().endsWith(".xml")) {
continue;
@@ -131,16 +132,19 @@
}
static class MyErrorHandler implements ErrorHandler {
+ @Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("\nerror: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("\nfatalError: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("\nwarning: " + XMLFileReader.showSAX(exception));
throw exception;
@@ -276,7 +280,7 @@
+ CldrUtility.LINE_SEPARATOR);
}
PrettyPath prettyPath = new PrettyPath().setShowErrors(true);
- Set<String> badPaths = new TreeSet<String>();
+ Set<String> badPaths = new TreeSet<>();
for (String path : pathToLocale.keySet()) {
String prettied = prettyPath.getPrettyPath(path, false);
if (showInfo) System.out.println(prettied + "\t\t" + path);
@@ -368,4 +372,4 @@
return areSame ? 0 : 1;
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/test/SubmissionLocales.java b/tools/java/org/unicode/cldr/test/SubmissionLocales.java
index c0256df..a4f991a 100644
--- a/tools/java/org/unicode/cldr/test/SubmissionLocales.java
+++ b/tools/java/org/unicode/cldr/test/SubmissionLocales.java
@@ -17,21 +17,21 @@
"mni", // Manipuri (Bengali script)-Apple as well
"sat", // Santali -(Apple use Olck script)
"kok", // Konkani -(Note: this is already covered by a MS vetter at Modern level)
- "sd_Deva", // Sindhi (Devanagari)
+ "sd_Deva", // Sindhi (Devanagari)
"su", // Sundanese (script TBD)
- "cad", // Caddo
- "pcm", // Nigerian Pidgin
- "gn" // Guarani
+ "pcm" // Nigerian Pidgin
+// "cad", // Caddo
+// "gn" // Guarani
);
-
+
public static Set<String> HIGH_LEVEL_LOCALES = ImmutableSet.of(
"chr", // Cherokee
"gd", // Scottish Gaelic, Gaelic
"fo" // Faroese
);
-
+
// have to have a lazy eval because otherwise CLDRConfig is called too early in the boot process
- static Set<String> CLDR_LOCALES = ImmutableSet.<String>builder()
+ public static Set<String> CLDR_LOCALES = ImmutableSet.<String>builder()
.addAll(HIGH_LEVEL_LOCALES)
.addAll(NEW_CLDR_LOCALES)
.addAll(StandardCodes.make().getLocaleToLevel(Organization.cldr).keySet()).build();
@@ -44,10 +44,10 @@
// }
// }
- public static final Pattern ALLOWED_IN_LIMITED_PATHS =
+ public static final Pattern ALLOWED_IN_LIMITED_PATHS =
Pattern.compile("//ldml/annotations/annotation.*[🤵👰⬆➡⬇⬅♾✖➕➖➗]");
-
+
/* Example of special paths
* Pattern.compile(
"//ldml/"
@@ -64,7 +64,7 @@
+ ")"
);
*/
-
+
//ldml/dates/timeZoneNames/metazone[@type="Macau"]/long/daylight, old: Macau Summer Time, new: Macao Summer Time
//ldml/dates/timeZoneNames/metazone[@type="Macau"]/long/standard, old: Macau Standard Time, new: Macao Standard Time
//ldml/localeDisplayNames/territories/territory[@type="SZ"][@alt="variant"], old: SZ, new: Swaziland
@@ -86,7 +86,7 @@
// don't limit new locales or errors
if (SubmissionLocales.NEW_CLDR_LOCALES.contains(localeString) || isError) {
- return true;
+ return true;
} else {
int debug = 0; // for debugging
}
diff --git a/tools/java/org/unicode/cldr/test/TestCLDRTests.java b/tools/java/org/unicode/cldr/test/TestCLDRTests.java
index e3d1268..c03ac10 100644
--- a/tools/java/org/unicode/cldr/test/TestCLDRTests.java
+++ b/tools/java/org/unicode/cldr/test/TestCLDRTests.java
@@ -53,7 +53,7 @@
Locale oLocale = Locale.ENGLISH; // TODO Drop once ICU4J has ULocale everywhere
PrintWriter log;
SAXParser SAX;
- TreeMap<String, MutableInteger> results = new TreeMap<String, MutableInteger>();
+ TreeMap<String, MutableInteger> results = new TreeMap<>();
public static void main(String[] args) throws Exception {
double deltaTime = System.currentTimeMillis();
@@ -84,6 +84,7 @@
languagesToTest = (Set<String>) new CldrUtility.CollectionTransform() {
LocaleIDParser lip = new LocaleIDParser();
+ @Override
public Object transform(Object source) {
return lip.set(source.toString()).getLanguageScript();
}
@@ -118,7 +119,7 @@
// ============ SAX Handler Infrastructure ============
abstract public class Handler {
- Map<String, String> settings = new TreeMap<String, String>();
+ Map<String, String> settings = new TreeMap<>();
String name;
String attributes;
@@ -169,6 +170,7 @@
static class MutableInteger {
int value;
+ @Override
public String toString() {
return String.valueOf(value);
}
@@ -194,7 +196,7 @@
RegisteredHandlers.put(name, handler);
}
- Map<String, Handler> RegisteredHandlers = new HashMap<String, Handler>();
+ Map<String, Handler> RegisteredHandlers = new HashMap<>();
// ============ Statics for Date/Number Support ============
@@ -211,6 +213,7 @@
// ============ Handler for Collation ============
{
addHandler("collation", new Handler() {
+ @Override
public void handleResult(String value) {
Collator col = Collator.getInstance(uLocale.toLocale());
boolean showedAttributes = false;
@@ -239,6 +242,7 @@
// ============ Handler for Numbers ============
addHandler("number", new Handler() {
+ @Override
public void handleResult(String result) {
NumberFormat nf = null;
double v = Double.NaN;
@@ -281,6 +285,7 @@
// ============ Handler for Dates ============
addHandler("date", new Handler() {
+ @Override
public void handleResult(String result) throws ParseException {
int dateFormat = DateFormat.DEFAULT;
int timeFormat = DateFormat.DEFAULT;
@@ -333,6 +338,7 @@
StringBuffer lastChars = new StringBuffer();
Handler handler;
+ @Override
public void startElement(
String uri,
String localName,
@@ -360,6 +366,7 @@
}
}
+ @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
try {
@@ -377,6 +384,7 @@
}
// Have to hack around the fact that the character data might be in pieces
+ @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
@@ -391,6 +399,7 @@
// just for debugging
+ @Override
public void notationDecl(String name, String publicId, String systemId)
throws SAXException {
System.out.println("notationDecl: " + name
@@ -398,16 +407,19 @@
+ ", " + systemId);
}
+ @Override
public void processingInstruction(String target, String data)
throws SAXException {
System.out.println("processingInstruction: " + target + ", " + data);
}
+ @Override
public void skippedEntity(String name)
throws SAXException {
System.out.println("skippedEntity: " + name);
}
+ @Override
public void unparsedEntityDecl(String name, String publicId,
String systemId, String notationName)
throws SAXException {
diff --git a/tools/java/org/unicode/cldr/test/TestCache.java b/tools/java/org/unicode/cldr/test/TestCache.java
index c4cbe5d..3f874de 100644
--- a/tools/java/org/unicode/cldr/test/TestCache.java
+++ b/tools/java/org/unicode/cldr/test/TestCache.java
@@ -32,11 +32,11 @@
final CLDRFile file;
final private CheckCLDR.Options options;
final private ConcurrentHashMap<Pair<String, String>, List<CheckStatus>> pathCache;
- final protected List<CheckStatus> possibleProblems = new ArrayList<CheckStatus>();
-
+ final protected List<CheckStatus> possibleProblems = new ArrayList<>();
+
protected TestResultBundle(CheckCLDR.Options cldrOptions) {
options = cldrOptions;
- pathCache = new ConcurrentHashMap<Pair<String, String>, List<CheckStatus>>();
+ pathCache = new ConcurrentHashMap<>();
file = getFactory().make(options.getLocale().getBaseName(), true);
cc.setCldrFileToCheck(file, options, possibleProblems);
}
@@ -44,7 +44,7 @@
/**
* Check the given value for the given path, using this TestResultBundle for
* options, pathCache and cc (CheckCLDR).
- *
+ *
* @param path the path
* @param result the list to which CheckStatus objects may be added; this function
* clears any objects that might already be in it
@@ -58,7 +58,7 @@
* currently redundant here. Clear it here unconditionally to be sure.
*/
result.clear();
- Pair<String, String> key = new Pair<String, String>(path, value);
+ Pair<String, String> key = new Pair<>(path, value);
List<CheckStatus> cachedResult = pathCache.get(key);
if (cachedResult != null) {
result.addAll(cachedResult);
@@ -133,7 +133,7 @@
/**
* Convert this TestCache to a string
- *
+ *
* Used only for debugging?
*/
@Override
@@ -171,18 +171,12 @@
/**
* Update the caches as needed, given that the value has changed for this xpath and locale.
- *
+ *
* Called by valueChanged(String xpath, XMLSource source),
* and also calls itself recursively for sublocales
*
* @param xpath the xpath
* @param locale the CLDRLocale
- *
- * There is room for improvement of performance. Currently we invalidate all paths for any affected locale.
- * Ideally, cache invalidation should only be done for each locale+path whose test results or examples potentially
- * depend on the given locale+path, due to inheritance, aliasing, logical groups, etc. That could be done using a mapping
- * between paths that are related by such dependencies; that mapping would be constant for as long as the paths and tests
- * (or example-generation methods) don't change.
*/
private void valueChangedInvalidateRecursively(String xpath, final CLDRLocale locale) {
if (DEBUG) {
diff --git a/tools/java/org/unicode/cldr/test/TestMetadata.java b/tools/java/org/unicode/cldr/test/TestMetadata.java
index fdaa260..7353bba 100644
--- a/tools/java/org/unicode/cldr/test/TestMetadata.java
+++ b/tools/java/org/unicode/cldr/test/TestMetadata.java
@@ -22,8 +22,7 @@
public static void main(String[] args) {
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile metadata = cldrFactory.make("supplementalMetadata", false);
- // Set allKeys = new TreeSet();
- // CollectionUtilities.addAll(metadata.iterator(), allKeys);
+ // Set allKeys = new TreeSet(metadata);
// System.out.println("Keys: " + allKeys);
// attribute order
@@ -94,7 +93,7 @@
private static void sublistCheck(Set<LinkedHashSet<String>> elementOrderingLists, List<String> elementOrder) {
for (Iterator<LinkedHashSet<String>> it = elementOrderingLists.iterator(); it.hasNext();) {
- LinkedHashSet<String> sublist = (LinkedHashSet<String>) it.next();
+ LinkedHashSet<String> sublist = it.next();
// verify that the elements are in the list in the right order.
int lastPosition = -1;
for (Iterator<String> it2 = sublist.iterator(); it2.hasNext();) {
@@ -111,7 +110,7 @@
private static boolean showSetDifferences(String name1, Collection<String> set1, String name2, Collection<String> set2) {
boolean hasDifference = false;
- TreeSet<String> temp = new TreeSet<String>();
+ TreeSet<String> temp = new TreeSet<>();
temp.addAll(set1);
temp.removeAll(set2);
if (temp.size() != 0) {
@@ -148,7 +147,7 @@
public static <T> String showDifference(Iterable<T> a, Iterable<T> b, String separator,
Transform<T, String> aDisplay,
Transform<T, String> bDisplay) {
- Differ<T> differ = new Differ<T>(300, 10);
+ Differ<T> differ = new Differ<>(300, 10);
StringBuilder out = new StringBuilder();
Iterator<T> ai = a.iterator();
Iterator<T> bi = b.iterator();
@@ -203,18 +202,18 @@
}
String[] zones = zoneList.split("\\s+");
- Set<String> metaZoneSet = new TreeSet<String>();
+ Set<String> metaZoneSet = new TreeSet<>();
metaZoneSet.addAll(Arrays.asList(zones));
StandardCodes sc = StandardCodes.make();
Map<String, List<String>> new_oldZones = sc.getZoneData();
- Set<String> stdZoneSet = new TreeSet<String>();
+ Set<String> stdZoneSet = new TreeSet<>();
stdZoneSet.addAll(new_oldZones.keySet());
if (metaZoneSet.equals(stdZoneSet)) {
System.out.println("Zone Set is up-to-date");
} else {
- Set<String> diff = new TreeSet<String>();
+ Set<String> diff = new TreeSet<>();
diff.addAll(metaZoneSet);
diff.removeAll(stdZoneSet);
System.out.println("Meta Zones - Std Zones: " + diff);
@@ -240,6 +239,7 @@
this.elementOrderingLists = elementOrderingLists;
}
+ @Override
public void handleAttributeDecl(String eName, String aName, String type, String mode, String value) {
attributes.add(aName);
// System.out.println(
@@ -251,9 +251,10 @@
// );
}
+ @Override
public void handleElementDecl(String name, String model) {
elements.add(name);
- LinkedHashSet<String> ordering = new LinkedHashSet<String>(Arrays.asList(model.split("[^-_a-zA-Z0-9]+")));
+ LinkedHashSet<String> ordering = new LinkedHashSet<>(Arrays.asList(model.split("[^-_a-zA-Z0-9]+")));
ordering.remove("");
ordering.remove("PCDATA");
ordering.remove("EMPTY");
diff --git a/tools/java/org/unicode/cldr/test/TestMetazones.java b/tools/java/org/unicode/cldr/test/TestMetazones.java
index 8ac40fe..de8eb1a 100644
--- a/tools/java/org/unicode/cldr/test/TestMetazones.java
+++ b/tools/java/org/unicode/cldr/test/TestMetazones.java
@@ -272,12 +272,12 @@
* @return
*/
private List<Pair<Long, Long>> getDifferencesOverRange(OlsonTimeZone zone1, OlsonTimeZone zone2, DateRange overlap) {
- Set<Long> list1 = new TreeSet<Long>();
+ Set<Long> list1 = new TreeSet<>();
addTransitions(zone1, overlap, list1);
addTransitions(zone2, overlap, list1);
// Remove any transition points that keep the same delta relationship
- List<Long> list = new ArrayList<Long>();
+ List<Long> list = new ArrayList<>();
int lastDelta = 0;
for (long point : list1) {
int offset1 = getOffset(zone1, point);
@@ -290,7 +290,7 @@
}
// now combine into a list of start/end pairs
- List<Pair<Long, Long>> result = new ArrayList<Pair<Long, Long>>();
+ List<Pair<Long, Long>> result = new ArrayList<>();
long lastPoint = Long.MIN_VALUE;
for (long point : list) {
if (lastPoint != Long.MIN_VALUE) {
@@ -318,7 +318,7 @@
if (skipPartialDays && end - start < DAY) {
// do nothing
} else {
- result.add(new Pair<Long, Long>(start, end)); // back up 1 minute
+ result.add(new Pair<>(start, end)); // back up 1 minute
}
}
}
@@ -419,7 +419,7 @@
}
Set<DateRangeAndZone> values = mzoneToData.getAll(mzone);
- Map<String, DateRanges> zoneToRanges = new TreeMap<String, DateRanges>();
+ Map<String, DateRanges> zoneToRanges = new TreeMap<>();
DateRanges mzoneRanges = new DateRanges();
// first determine what the max and min dates are
@@ -482,7 +482,7 @@
errorLog.println("*** Verify coverage of canonical zones");
errorLog.println();
Set<String> canonicalZones = supplementalData.getCanonicalZones();
- Set<String> missing = new TreeSet<String>(canonicalZones);
+ Set<String> missing = new TreeSet<>(canonicalZones);
missing.removeAll(zoneToDateRanges.keySet());
for (Iterator<String> it = missing.iterator(); it.hasNext();) {
String value = it.next();
@@ -493,7 +493,7 @@
if (missing.size() != 0) {
errln("Missing canonical zones: " + missing);
}
- Set<String> extras = new TreeSet<String>(zoneToDateRanges.keySet());
+ Set<String> extras = new TreeSet<>(zoneToDateRanges.keySet());
extras.removeAll(canonicalZones);
if (extras.size() != 0) {
errln("Superfluous zones (not canonical): " + extras);
@@ -542,6 +542,7 @@
this.zone = zone;
}
+ @Override
public int compareTo(DateRangeAndZone other) {
int result = range.compareTo(other.range);
if (result != 0)
@@ -549,13 +550,14 @@
return zone.compareTo(other.zone);
}
+ @Override
public String toString() {
return "{" + range + " => " + zone + "}";
}
}
static class DateRanges {
- Set<DateRange> contents = new TreeSet<DateRange>();
+ Set<DateRange> contents = new TreeSet<>();
public void add(DateRange o) {
contents.add(o);
@@ -596,14 +598,17 @@
return true;
}
+ @Override
public boolean equals(Object other) {
return contents.equals(((DateRanges) other).contents);
}
+ @Override
public int hashCode() {
return contents.hashCode();
}
+ @Override
public String toString() {
return contents.toString();
}
@@ -701,6 +706,7 @@
static DateFormat iso2 = new SimpleDateFormat("yyyy-MM-dd");
+ @Override
public int compareTo(DateRange other) {
if (startDate < other.startDate)
return -1;
@@ -724,6 +730,7 @@
static long MAX_DATE = getDateTimeinMillis(110, 0, 1, 0, 0, 0);
+ @Override
public String toString() {
return "{" + format(startDate) + " to " + format(endDate) + "}";
}
diff --git a/tools/java/org/unicode/cldr/test/TestMisc.java b/tools/java/org/unicode/cldr/test/TestMisc.java
index 55ba623..391e66b 100644
--- a/tools/java/org/unicode/cldr/test/TestMisc.java
+++ b/tools/java/org/unicode/cldr/test/TestMisc.java
@@ -8,7 +8,6 @@
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -58,7 +57,7 @@
static class Lists {
public static <E extends Comparable> List<E> sortedCopy(Collection<E> iterable) {
- List<E> list = new ArrayList<E>();
+ List<E> list = new ArrayList<>();
list.addAll(iterable);
Collections.sort(list);
return list;
@@ -67,7 +66,7 @@
enum Foo {
A, M, Z
- };
+ }
public static void main(String[] args) {
@@ -178,10 +177,10 @@
System.out.println(eg.getHelpHtml("/calendar/pattern", ""));
if (true) return;
- Set<String> s = new HashSet<String>(Arrays.asList("a", "A", "c"));
+ Set<String> s = new HashSet<>(Arrays.asList("a", "A", "c"));
Collator caselessCompare = Collator.getInstance(Locale.ENGLISH);
caselessCompare.setStrength(Collator.PRIMARY);
- Set<String> t = new TreeSet<String>((Comparator) caselessCompare);
+ Set<String> t = new TreeSet<>(caselessCompare);
t.addAll(Arrays.asList("a", "b", "c"));
System.out.println("s equals t: " + s.equals(t));
System.out.println("t equals s: " + t.equals(s));
@@ -190,7 +189,7 @@
System.out.println("s==t " + (s.equals(t)));
System.out.println("s==u " + (s.equals(u)));
UnicodeSet x = new UnicodeSet("[a-z]");
- UnicodeSet y = (UnicodeSet) new UnicodeSet("[a-z]").freeze();
+ UnicodeSet y = new UnicodeSet("[a-z]").freeze();
System.out.println("x==y " + (x.equals(y)));
// showEnglish();
// checkPrivateUse();
@@ -226,10 +225,10 @@
private static void testWeights() {
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile english = cldrFactory.make("en", true);
- Set<Pair<Integer, String>> rel = new TreeSet<Pair<Integer, String>>();
+ Set<Pair<Integer, String>> rel = new TreeSet<>();
for (String desiredLocale : cldrFactory.getAvailable()) {
int vote = Level.getDefaultWeight("google", desiredLocale);
- rel.add(new Pair<Integer, String>(vote, desiredLocale));
+ rel.add(new Pair<>(vote, desiredLocale));
}
for (Pair<Integer, String> p : rel) {
System.out.println(p + "\t" + english.getName(p.getSecond()));
@@ -253,14 +252,14 @@
caseFolded.freeze();
simpleCaseFolded.freeze();
- UnicodeSet functionalExceptCase = (UnicodeSet) new UnicodeSet("[" +
+ UnicodeSet functionalExceptCase = new UnicodeSet("[" +
"[:L:][:Mc:][:Mn:][:Nd:]" +
"&[:^NFKC_QuickCheck=No:]" +
"&[:^default_ignorable_code_point:]]").freeze();
- UnicodeSet asciiIdn = (UnicodeSet) new UnicodeSet("[-A-Z0-9]").freeze();
+ UnicodeSet asciiIdn = new UnicodeSet("[-A-Z0-9]").freeze();
- UnicodeSet archaic = (UnicodeSet) new UnicodeSet("[" +
+ UnicodeSet archaic = new UnicodeSet("[" +
"[:script=Bugi:]" +
"[:script=Copt:]" +
"[:script=Cprt:]" +
@@ -301,9 +300,9 @@
.retainAll(functionalExceptCase)
.removeAll(archaic).removeAll(asciiIdn)));
- UnicodeSet functional = (UnicodeSet) new UnicodeSet(functionalExceptCase).retainAll(caseFolded).freeze();
+ UnicodeSet functional = new UnicodeSet(functionalExceptCase).retainAll(caseFolded).freeze();
System.out.println("functional: " + functional.size());
- UnicodeSet functionalAndNotArchaic = (UnicodeSet) new UnicodeSet(functional).removeAll(archaic).freeze();
+ UnicodeSet functionalAndNotArchaic = new UnicodeSet(functional).removeAll(archaic).freeze();
System.out.println("archaic: " + archaic.size());
System.out.println("functionalAndNotArchaic: " + functionalAndNotArchaic.size());
@@ -348,7 +347,7 @@
}
scripts.set(script);
}
- Set<String> toPrint = new TreeSet<String>();
+ Set<String> toPrint = new TreeSet<>();
for (int script = 0; script < scripts.size(); ++script) {
if (!scripts.get(script)) continue;
String code = UScript.getShortName(script);
@@ -367,6 +366,7 @@
private static void checkCollections() {
System.out.println("Collections");
new org.unicode.cldr.util.CldrUtility.Apply<String>() {
+ @Override
public void apply(String item) {
if (Iso639Data.getScope(item.toString()) != Scope.Collection) return;
System.out.println(item + "\t" + CldrUtility.join(Iso639Data.getNames(item), ", "));
@@ -374,6 +374,7 @@
}.applyTo(Iso639Data.getAvailable());
System.out.println(CldrUtility.LINE_SEPARATOR + "Macrolanguages");
new org.unicode.cldr.util.CldrUtility.Apply<String>() {
+ @Override
public void apply(String item) {
if (Iso639Data.getScope(item.toString()) != Scope.Macrolanguage) return;
System.out.println(item + "\t" + CldrUtility.join(Iso639Data.getNames(item), ", "));
@@ -413,8 +414,8 @@
}
static void checkEastAsianWidth() {
- UnicodeSet dontCares = (UnicodeSet) new UnicodeSet("[[:surrogate:][:unassigned:][:control:]]").freeze();
- UnicodeSet dontCares2 = (UnicodeSet) new UnicodeSet("[:^letter:]").freeze();
+ UnicodeSet dontCares = new UnicodeSet("[[:surrogate:][:unassigned:][:control:]]").freeze();
+ UnicodeSet dontCares2 = new UnicodeSet("[:^letter:]").freeze();
// UnicodeSet wide = new UnicodeSet("[[:East_Asian_Width=wide:][:East_Asian_Width=fullwidth:][:Co:]]"); //
// remove supplementaries
@@ -429,15 +430,15 @@
// Utility.addDontCareSpans(zeroWidth, dontCares));
// P2. In each paragraph, find the first character of type L, AL, or R.
- UnicodeSet strongL = (UnicodeSet) new UnicodeSet("[[:BidiClass=L:]-[:unassigned:]]").freeze(); //
+ UnicodeSet strongL = new UnicodeSet("[[:BidiClass=L:]-[:unassigned:]]").freeze(); //
showSpans("Bidi L", strongL, dontCares);
showSpans("Bidi L*", strongL, dontCares2);
- UnicodeSet strongRAL = (UnicodeSet) new UnicodeSet("[[:BidiClass=R:][:BidiClass=AL:]-[:unassigned:]]").freeze();
+ UnicodeSet strongRAL = new UnicodeSet("[[:BidiClass=R:][:BidiClass=AL:]-[:unassigned:]]").freeze();
showSpans("Bidi R,AL", strongRAL, dontCares);
showSpans("Bidi R,AL*", strongRAL, dontCares2);
- UnicodeSet strong = (UnicodeSet) new UnicodeSet(
+ UnicodeSet strong = new UnicodeSet(
"[[:BidiClass=L:][:BidiClass=R:][:BidiClass=AL:]-[:unassigned:]]").freeze();
showSpans("Strong", strong, dontCares);
showSpans("Strong*", strong, dontCares2);
@@ -500,8 +501,8 @@
private static void checkDistinguishing() {
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
Set<String> cldrFiles = cldrFactory.getAvailableLanguages();
- Set<String> distinguishing = new TreeSet<String>();
- Set<String> nondistinguishing = new TreeSet<String>();
+ Set<String> distinguishing = new TreeSet<>();
+ Set<String> nondistinguishing = new TreeSet<>();
for (Iterator<String> it = cldrFiles.iterator(); it.hasNext();) {
CLDRFile cldrFile = cldrFactory.make(it.next(), false);
DtdType dtdType = null;
@@ -569,9 +570,9 @@
String requestedLocale = "en";
CLDRFile cldrFile = cldrFactory.make(requestedLocale, true);
StandardCodes sc = StandardCodes.make();
- Set<String> careAbout = new HashSet<String>(Arrays.asList(new String[] { "language", "script", "territory", "variant" }));
- HashMap<String, Set<String>> foundItems = new HashMap<String, Set<String>>();
- TreeSet<String> problems = new TreeSet<String>();
+ Set<String> careAbout = new HashSet<>(Arrays.asList(new String[] { "language", "script", "territory", "variant" }));
+ HashMap<String, Set<String>> foundItems = new HashMap<>();
+ TreeSet<String> problems = new TreeSet<>();
for (Iterator<String> it = cldrFile.iterator("", new UTF16.StringComparator(true, false, 0)); it.hasNext();) {
String requestedPath = it.next();
XPathParts parts = XPathParts.getFrozenInstance(requestedPath);
@@ -583,9 +584,9 @@
if (type == null) {
continue;
}
- Set<String> foundSet = (Set<String>) foundItems.get(element);
+ Set<String> foundSet = foundItems.get(element);
if (foundSet == null) {
- foundItems.put(element, foundSet = new TreeSet<String>());
+ foundItems.put(element, foundSet = new TreeSet<>());
}
foundSet.add(type);
@@ -605,10 +606,10 @@
System.out.println(it.next());
}
for (Iterator<String> it = careAbout.iterator(); it.hasNext();) {
- String element = (String) it.next();
+ String element = it.next();
Set<String> real = sc.getAvailableCodes(element);
- Set<String> notFound = new TreeSet<String>(real);
- notFound.removeAll((Set<String>) foundItems.get(element));
+ Set<String> notFound = new TreeSet<>(real);
+ notFound.removeAll(foundItems.get(element));
for (Iterator<String> it2 = notFound.iterator(); it2.hasNext();) {
String type = it2.next();
List<String> data = sc.getFullData(element, type);
@@ -639,10 +640,11 @@
String path = it.next();
String value = supp.getStringValue(path);
String fullPath = supp.getFullXPath(path);
- XPathParts parts = XPathParts.getInstance(fullPath); // not frozen, for putAttributeValue
+ XPathParts parts = XPathParts.getFrozenInstance(fullPath);
String type = parts.getAttributeValue(-1, "type");
- String pop = (String) language_territory_hack_map.get(type);
+ String pop = language_territory_hack_map.get(type);
if (pop != null) {
+ parts = parts.cloneAsThawed();
parts.putAttributeValue(-1, "mostPopulousTerritory", pop);
fullPath = parts.toString();
}
@@ -653,7 +655,7 @@
pw.close();
}
- private static final Map<String, String> language_territory_hack_map = new HashMap<String, String>();
+ private static final Map<String, String> language_territory_hack_map = new HashMap<>();
private static final String[][] language_territory_hack = {
{ "af", "ZA" },
{ "am", "ET" },
@@ -820,6 +822,7 @@
static VariantFolder canonicalFolder = new VariantFolder(new CanonicalFolder());
static VariantFolder compatibilityFolder = new VariantFolder(new CompatibilityFolder());
+ @Override
public boolean applyPropertyAlias(String propertyName, String propertyValue, UnicodeSet result) {
if (propertyName.equalsIgnoreCase("close")) {
if (propertyValue.equalsIgnoreCase("case")) {
diff --git a/tools/java/org/unicode/cldr/test/TestSupplementalData.java b/tools/java/org/unicode/cldr/test/TestSupplementalData.java
index 03d80c5..38cf1ef 100644
--- a/tools/java/org/unicode/cldr/test/TestSupplementalData.java
+++ b/tools/java/org/unicode/cldr/test/TestSupplementalData.java
@@ -61,7 +61,7 @@
}
// gather the data
// this could be slightly simpler using supplementalData.get
- Set<String> singulars = new TreeSet<String>();
+ Set<String> singulars = new TreeSet<>();
for (String region : territoryToZones.keySet()) {
final Set<String> zones = territoryToZones.getAll(region);
if (zones.size() == 1 || region.equals("001")) {
@@ -92,7 +92,7 @@
private static void checkPlurals() {
Relation<PluralInfo, String> pluralsToLocale = Relation.<PluralInfo, String> of(new HashMap<PluralInfo, Set<String>>(), TreeSet.class);
- for (String locale : new TreeSet<String>(supplementalData.getPluralLocales())) {
+ for (String locale : new TreeSet<>(supplementalData.getPluralLocales())) {
PluralInfo pluralInfo = supplementalData.getPlurals(locale);
System.out.println(locale + ":\t" + pluralInfo);
pluralsToLocale.put(pluralInfo, locale);
@@ -128,7 +128,7 @@
private static void checkTerritoryMapping() {
Relation<String, String> alpha3 = supplementalData.getAlpha3TerritoryMapping();
- Set<String> temp = new TreeSet<String>(sc.getAvailableCodes("territory"));
+ Set<String> temp = new TreeSet<>(sc.getAvailableCodes("territory"));
for (Iterator<String> it = temp.iterator(); it.hasNext();) {
String code = it.next();
if (numericTerritory.reset(code).matches()) {
@@ -158,7 +158,7 @@
}
private static Set<String> getFirstMinusSecond(Set<String> name, Set<String> availableCodes) {
- Set<String> temp = new TreeSet<String>(name);
+ Set<String> temp = new TreeSet<>(name);
temp.removeAll(availableCodes);
return temp;
}
@@ -170,10 +170,10 @@
Set<BasicLanguageData> newLanguageData = supplementalData.getBasicLanguageData(language);
if (newLanguageData != null) {
for (BasicLanguageData languageData : newLanguageData) {
- Set<String> territories = new TreeSet<String>(languageData.getTerritories());
+ Set<String> territories = new TreeSet<>(languageData.getTerritories());
territories.addAll(languageData.getTerritories());
if (territories != null) {
- Set<String> scripts = new TreeSet<String>(languageData.getScripts());
+ Set<String> scripts = new TreeSet<>(languageData.getScripts());
scripts.addAll(languageData.getScripts());
if (scripts == null || scripts.size() < 2) {
otherTerritoryToLanguages.putAll(territories, language);
@@ -192,9 +192,9 @@
Set<String> otherLanguages = otherTerritoryToLanguages.getAll(territory);
if (otherLanguages == null) otherLanguages = Collections.emptySet();
if (!Objects.equals(languages, otherLanguages)) {
- Set<String> languagesLeftover = new TreeSet<String>(languages);
+ Set<String> languagesLeftover = new TreeSet<>(languages);
languagesLeftover.removeAll(otherLanguages);
- Set<String> otherLanguagesLeftover = new TreeSet<String>(otherLanguages);
+ Set<String> otherLanguagesLeftover = new TreeSet<>(otherLanguages);
otherLanguagesLeftover.removeAll(languages);
String territoryString = english.getName(CLDRFile.TERRITORY_NAME, territory);
if (otherLanguagesLeftover.size() != 0) {
@@ -214,7 +214,7 @@
*/
public static void genData() throws IOException {
BufferedReader codes = CldrUtility.getUTF8Data("territory_codes.txt");
- Set<Pair> sorted = new TreeSet<Pair>();
+ Set<Pair> sorted = new TreeSet<>();
while (true) {
String line = codes.readLine();
if (line == null)
diff --git a/tools/java/org/unicode/cldr/test/XPathToMenu.java b/tools/java/org/unicode/cldr/test/XPathToMenu.java
new file mode 100644
index 0000000..594b844
--- /dev/null
+++ b/tools/java/org/unicode/cldr/test/XPathToMenu.java
@@ -0,0 +1,319 @@
+package org.unicode.cldr.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.unicode.cldr.icu.LDMLConstants;
+import org.unicode.cldr.util.XPathParts;
+
+/**
+ * Deprecated utility class only used by ConsoleCheckCLDR.
+ *
+ * @deprecated Do not use.
+ */
+@Deprecated
+final class XPathToMenu {
+ // ===== types of data and menu names
+ private static final String LOCALEDISPLAYNAMES = "//ldml/localeDisplayNames/";
+ private static final String OTHER_CALENDARS_XPATH = "//ldml/dates/calendars/calendar";
+
+ private static final String CURRENCIES = "currencies";
+ private static final String TIMEZONES = "timezones";
+ private static final String METAZONES = "metazones";
+ private static final String MISC = "misc";
+ private static final String CODEPATTERNS = "codePatterns";
+ private static final String MEASNAMES = "measurementSystemNames";
+
+ private static final String LOCALEDISPLAYPATTERN_XPATH =
+ LOCALEDISPLAYNAMES + LDMLConstants.LOCALEDISPLAYPATTERN;
+ private static final String NUMBERSCURRENCIES =
+ LDMLConstants.NUMBERS + "/" + CURRENCIES;
+
+ /**
+ * All of the data items under LOCALEDISPLAYNAMES (menu items)
+ */
+ private static final String[] LOCALEDISPLAYNAMES_ITEMS = { LDMLConstants.LANGUAGES,
+ LDMLConstants.SCRIPTS, LDMLConstants.TERRITORIES, LDMLConstants.VARIANTS, LDMLConstants.KEYS,
+ LDMLConstants.TYPES, CURRENCIES, TIMEZONES, CODEPATTERNS, MEASNAMES };
+
+ public static String xpathToMenu(String path) {
+ String theMenu = null;
+ if (path.startsWith(LOCALEDISPLAYNAMES)) {
+ for (int i = 0; i < LOCALEDISPLAYNAMES_ITEMS.length; i++) {
+ if (path.startsWith(LOCALEDISPLAYNAMES
+ + LOCALEDISPLAYNAMES_ITEMS[i])) {
+ theMenu = LOCALEDISPLAYNAMES_ITEMS[i];
+ }
+ }
+ if (path.startsWith(LOCALEDISPLAYPATTERN_XPATH)) {
+ theMenu = LDMLConstants.LOCALEDISPLAYPATTERN;
+ }
+ } else if (path.startsWith(OTHER_CALENDARS_XPATH)) {
+ String items[] = getCalendarsItems();
+ for (String which : items) {
+ String CAL_XPATH = "//ldml/dates/calendars/calendar[@type=\"" + which + "\"]";
+ if (path.startsWith(CAL_XPATH)) {
+ theMenu = which;
+ break;
+ }
+ }
+ } else if (path.startsWith(LOCALEDISPLAYPATTERN_XPATH)) {
+ theMenu = LDMLConstants.LOCALEDISPLAYPATTERN;
+ } else if (path.startsWith("//ldml/" + NUMBERSCURRENCIES)) {
+ theMenu = CURRENCIES;
+ } else if (path.startsWith("//ldml/" + "dates/timeZoneNames/zone")) {
+ theMenu = TIMEZONES;
+ } else if (path.startsWith("//ldml/" + "units")) {
+ theMenu = "units";
+ } else if (path.startsWith("//ldml/" + "dates/timeZoneNames/metazone")) {
+ theMenu = getMetazoneContinent(path);
+ if (theMenu == null) {
+ theMenu = METAZONES;
+ }
+ } else if (path.startsWith("//ldml/" + LDMLConstants.CHARACTERS + "/" + LDMLConstants.EXEMPLAR_CHARACTERS)) {
+ theMenu = LDMLConstants.CHARACTERS;
+ } else if (path.startsWith("//ldml/" + LDMLConstants.NUMBERS)) {
+ theMenu = LDMLConstants.NUMBERS;
+ } else if (path.startsWith("//ldml/" + LDMLConstants.REFERENCES)) {
+ theMenu = LDMLConstants.REFERENCES;
+ } else {
+ theMenu = MISC;
+ // other?
+ }
+ return theMenu;
+ }
+
+ private static String[] getCalendarsItems() {
+ // TODO : Make this data driven from supplementalMetaData ;
+ // I couldn't get the xpath right....
+ // CLDRFile mySupp = getFactory().make("supplementalMetaData",false);
+ // String xpath =
+ // "//supplementalData/metadata/validity/variable[@id=\"$calendar\"][@type=\"choice\"]";
+ // String items = mySupp.getStringValue(xpath);
+ // if ( items != null ) {
+ // return (items.split(" "));
+ // }
+ // else {
+
+ String defaultCalendarsItems = "gregorian buddhist coptic ethiopic chinese hebrew indian islamic japanese persian roc";
+ return (defaultCalendarsItems.split(" "));
+
+ // }
+ }
+
+ private static String getMetazoneContinent(String xpath) {
+ XPathParts parts = XPathParts.getFrozenInstance(xpath);
+ String thisMetazone = parts.getAttributeValue(3, "type");
+ return getMetazoneToContinentMap().get(thisMetazone);
+ }
+
+ private static Map<String, String> mzToContinentMap = null;
+
+ private static Map<String, String> getMetazoneToContinentMap() {
+ if (mzToContinentMap == null) {
+ System.err
+ .println(
+ "PathUtilities.java getMetazoneToContinentMap(): TODO: Get this data from supplemental data! http://unicode.org/cldr/trac/ticket/3761");
+ HashMap<String, String> newMap = new HashMap<>();
+ for (int i = 0; i < mzToContinentStatic.length; i += 2) {
+ newMap.put(mzToContinentStatic[i + 0], mzToContinentStatic[i + 1]);
+ }
+ mzToContinentMap = newMap;
+ }
+ return mzToContinentMap;
+ }
+
+ private static final String mzToContinentStatic[] = {
+ "Philippines", "Asia",
+ "Gambier", "Pacific",
+ "Ecuador", "America",
+ "Kuybyshev", "Europe",
+ "Europe_Western", "Atlantic",
+ "Chile", "America",
+ "Afghanistan", "Asia",
+ "Pierre_Miquelon", "America",
+ "Solomon", "Pacific",
+ "Arabian", "Asia",
+ "Krasnoyarsk", "Asia",
+ "Vladivostok", "Asia",
+ "Fiji", "Pacific",
+ "Niue", "Pacific",
+ "Marquesas", "Pacific",
+ "Karachi", "Asia",
+ "Aqtobe", "Asia",
+ "Irish", "Europe",
+ "Yakutsk", "Asia",
+ "Galapagos", "Pacific",
+ "Bangladesh", "Asia",
+ "America_Pacific", "America",
+ "Urumqi", "Asia",
+ "Tahiti", "Pacific",
+ "Samoa", "Pacific",
+ "Uzbekistan", "Asia",
+ "Turkey", "Europe",
+ "Kyrgystan", "Asia",
+ "Europe_Eastern", "Europe",
+ "Casey", "Antarctica",
+ "Lord_Howe", "Australia",
+ "Kizilorda", "Asia",
+ "Kashgar", "Asia",
+ "Africa_Western", "Africa",
+ "Macquarie", "Antarctica",
+ "Wake", "Pacific",
+ "Australia_Eastern", "Australia",
+ "Guyana", "America",
+ "Taipei", "Asia",
+ "Samarkand", "Asia",
+ "Mawson", "Antarctica",
+ "Africa_Eastern", "Africa",
+ "Guam", "Pacific",
+ "Kazakhstan_Western", "Asia",
+ "Aqtau", "Asia",
+ "Cook", "Pacific",
+ "Wallis", "Pacific",
+ "Irkutsk", "Asia",
+ "Africa_Southern", "Africa",
+ "French_Guiana", "America",
+ "Chatham", "Pacific",
+ "Oral", "Asia",
+ "Noronha", "America",
+ "Paraguay", "America",
+ "Moscow", "Europe",
+ "Hong_Kong", "Asia",
+ "Yerevan", "Asia",
+ "Vostok", "Antarctica",
+ "Rothera", "Antarctica",
+ "Colombia", "America",
+ "Newfoundland", "America",
+ "Hawaii_Aleutian", "Pacific",
+ "East_Timor", "Asia",
+ "GMT", "Atlantic",
+ "Indian_Ocean", "Indian",
+ "Reunion", "Indian",
+ "Vanuatu", "Pacific",
+ "Malaysia", "Asia",
+ "Kwajalein", "Pacific",
+ "Line_Islands", "Pacific",
+ "Shevchenko", "Asia",
+ "Azores", "Atlantic",
+ "Frunze", "Asia",
+ "Greenland_Eastern", "America",
+ "Hovd", "Asia",
+ "Lanka", "Asia",
+ "Almaty", "Asia",
+ "Macau", "Asia",
+ "Mongolia", "Asia",
+ "Easter", "Pacific",
+ "British", "Europe",
+ "Korea", "Asia",
+ "Papua_New_Guinea", "Pacific",
+ "Bering", "America",
+ "Cocos", "Indian",
+ "Mauritius", "Indian",
+ "Argentina", "America",
+ "Tokelau", "Pacific",
+ "America_Central", "America",
+ "Alaska", "America",
+ "Georgia", "Asia",
+ "Choibalsan", "Asia",
+ "Sakhalin", "Asia",
+ "Anadyr", "Asia",
+ "Dushanbe", "Asia",
+ "Indonesia_Eastern", "Asia",
+ "Japan", "Asia",
+ "Omsk", "Asia",
+ "Nauru", "Pacific",
+ "Cuba", "America",
+ "Iran", "Asia",
+ "Sverdlovsk", "Asia",
+ "Maldives", "Indian",
+ "Europe_Central", "Europe",
+ "Kamchatka", "Asia",
+ "Tajikistan", "Asia",
+ "Pitcairn", "Pacific",
+ "Gilbert_Islands", "Pacific",
+ "Novosibirsk", "Asia",
+ "Brunei", "Asia",
+ "Tonga", "Pacific",
+ "Changbai", "Asia",
+ "India", "Asia",
+ "Indonesia_Western", "Asia",
+ "Malaya", "Asia",
+ "Dacca", "Asia",
+ "Tashkent", "Asia",
+ "New_Zealand", "Pacific",
+ "Indonesia_Central", "Asia",
+ "Myanmar", "Asia",
+ "South_Georgia", "Atlantic",
+ "Truk", "Pacific",
+ "Pakistan", "Asia",
+ "Borneo", "Asia",
+ "DumontDUrville", "Antarctica",
+ "Argentina_Western", "America",
+ "Uruguay", "America",
+ "Dutch_Guiana", "America",
+ "Ponape", "Pacific",
+ "Gulf", "Asia",
+ "Aktyubinsk", "Asia",
+ "America_Mountain", "America",
+ "Dominican", "America",
+ "North_Mariana", "Pacific",
+ "Yukon", "America",
+ "Armenia", "Asia",
+ "Falkland", "Atlantic",
+ "Tbilisi", "Asia",
+ "Baku", "Asia",
+ "Venezuela", "America",
+ "Ashkhabad", "Asia",
+ "Cape_Verde", "Atlantic",
+ "Phoenix_Islands", "Pacific",
+ "Brasilia", "America",
+ "Marshall_Islands", "Pacific",
+ "Volgograd", "Europe",
+ "Yekaterinburg", "Asia",
+ "Kosrae", "Pacific",
+ "Tuvalu", "Pacific",
+ "Africa_Central", "Africa",
+ "Palau", "Pacific",
+ "Alaska_Hawaii", "America",
+ "Qyzylorda", "Asia",
+ "Bhutan", "Asia",
+ "Israel", "Asia",
+ "America_Eastern", "America",
+ "Nepal", "Asia",
+ "Azerbaijan", "Asia",
+ "Uralsk", "Asia",
+ "Bolivia", "America",
+ "Liberia", "Africa",
+ "Turkmenistan", "Asia",
+ "Davis", "Antarctica",
+ "Norfolk", "Pacific",
+ "Indochina", "Asia",
+ "Peru", "America",
+ "Acre", "America",
+ "China", "Asia",
+ "Chamorro", "Pacific",
+ "Atlantic", "America",
+ "Syowa", "Antarctica",
+ "Africa_FarWestern", "Africa",
+ "New_Caledonia", "Pacific",
+ "Greenland_Western", "America",
+ "Suriname", "America",
+ "Seychelles", "Indian",
+ "Christmas", "Indian",
+ "Australia_CentralWestern", "Australia",
+ "Greenland_Central", "America",
+ "French_Southern", "Indian",
+ "Australia_Central", "Australia",
+ "Australia_Western", "Australia",
+ "Magadan", "Asia",
+ "Kazakhstan_Eastern", "Asia",
+ "Goose_Bay", "America",
+ "Singapore", "Asia",
+ "Amazon", "America",
+ "Long_Shu", "Asia",
+ "Samara", "Europe",
+ };
+
+ private XPathToMenu() {}
+}
diff --git a/tools/java/org/unicode/cldr/tool/AddPopulationData.java b/tools/java/org/unicode/cldr/tool/AddPopulationData.java
index 80ef59d..6ca6764 100644
--- a/tools/java/org/unicode/cldr/tool/AddPopulationData.java
+++ b/tools/java/org/unicode/cldr/tool/AddPopulationData.java
@@ -25,7 +25,7 @@
enum WBLine {
// "Afghanistan","AFG","GNI, PPP (current international $)","NY.GNP.MKTP.PP.CD","..","..","13144920451.3325","16509662130.816","18932631964.8727","22408872945.1924","25820670505.2627","30783369469.7509","32116190092.1429","..",
- Country_Name, Country_Code, Series_Name, Series_Code, YR2000, YR2001, YR2002, YR2003, YR2004, YR2005, YR2006, YR2007, YR2008, YR2009, YR2010, YR2011, YR2012, YR2013, YR2014, YR2015, YR2016, YR2017, YR2018;
+ Country_Name, Country_Code, Series_Name, Series_Code, YR2000, YR2001, YR2002, YR2003, YR2004, YR2005, YR2006, YR2007, YR2008, YR2009, YR2010, YR2011, YR2012, YR2013, YR2014, YR2015, YR2016, YR2017, YR2018, YR2019;
String get(String[] pieces) {
return ordinal() < pieces.length ? pieces[ordinal()] : EMPTY;
}
@@ -48,20 +48,20 @@
private static final String GCP = "NY.GNP.MKTP.PP.CD";
private static final String POP = "SP.POP.TOTL";
private static final String EMPTY = "..";
- private static Counter2<String> worldbank_gdp = new Counter2<String>();
- private static Counter2<String> worldbank_population = new Counter2<String>();
- private static Counter2<String> un_literacy = new Counter2<String>();
+ private static Counter2<String> worldbank_gdp = new Counter2<>();
+ private static Counter2<String> worldbank_population = new Counter2<>();
+ private static Counter2<String> un_literacy = new Counter2<>();
- private static Counter2<String> factbook_gdp = new Counter2<String>();
- private static Counter2<String> factbook_population = new Counter2<String>();
- private static Counter2<String> factbook_literacy = new Counter2<String>();
+ private static Counter2<String> factbook_gdp = new Counter2<>();
+ private static Counter2<String> factbook_population = new Counter2<>();
+ private static Counter2<String> factbook_literacy = new Counter2<>();
private static CountryData other = new CountryData();
static class CountryData {
- private static Counter2<String> population = new Counter2<String>();
- private static Counter2<String> gdp = new Counter2<String>();
- private static Counter2<String> literacy = new Counter2<String>();
+ private static Counter2<String> population = new Counter2<>();
+ private static Counter2<String> gdp = new Counter2<>();
+ private static Counter2<String> literacy = new Counter2<>();
}
public static void main(String[] args) throws IOException {
@@ -75,7 +75,7 @@
for (String country : StandardCodes.make().getGoodCountries()) {
showCountryData(country);
}
- Set<String> outliers = new TreeSet<String>();
+ Set<String> outliers = new TreeSet<>();
outliers.addAll(factbook_population.keySet());
outliers.addAll(worldbank_population.keySet());
outliers.addAll(factbook_gdp.keySet());
@@ -94,10 +94,10 @@
}
throw new IllegalArgumentException("Mistakes: data for non-country codes");
}
- Set<String> altNames = new TreeSet<String>();
+ Set<String> altNames = new TreeSet<>();
String oldCode = "";
for (String display : CountryCodeConverter.names()) {
- String code = CountryCodeConverter.getCodeFromName(display);
+ String code = CountryCodeConverter.getCodeFromName(display, true);
String icu = ULocale.getDisplayCountry("und-" + code, "en");
if (!display.equalsIgnoreCase(icu)) {
altNames.add(code + "\t" + display + "\t" + icu);
@@ -161,7 +161,7 @@
// each item is of the form abc...
// or "..." (required if a comma or quote is contained)
// " in a field is represented by ""
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
StringBuilder item = new StringBuilder();
boolean inQuote = false;
for (int i = 0; i < line.length(); ++i) {
@@ -195,13 +195,14 @@
private static void loadFactbookInfo(String filename, final Counter2<String> factbookGdp) throws IOException {
CldrUtility.handleFile(filename, new LineHandler() {
+ @Override
public boolean handle(String line) {
if (line.length() == 0 || line.startsWith("This tab") || line.startsWith("Rank")
|| line.startsWith(" This file")) {
return false;
}
String[] pieces = line.split("\\s{2,}");
- String code = CountryCodeConverter.getCodeFromName(FBLine.Country.get(pieces));
+ String code = CountryCodeConverter.getCodeFromName(FBLine.Country.get(pieces), true);
if (code == null) {
return false;
}
@@ -239,6 +240,7 @@
this.countryData = countryData;
}
+ @Override
public boolean handle(String line) throws ParseException {
if (line.startsWith("#")) return true;
if (line.length() == 0) {
@@ -286,14 +288,15 @@
}
}
- static final UnicodeSet DIGITS = (UnicodeSet) new UnicodeSet("[:Nd:]").freeze();
+ static final UnicodeSet DIGITS = new UnicodeSet("[:Nd:]").freeze();
private static void loadFactbookLiteracy() throws IOException {
final String filename = "external/factbook_literacy.txt";
CldrUtility.handleFile(filename, new LineHandler() {
+ @Override
public boolean handle(String line) {
String[] pieces = line.split("\\t");
- String code = CountryCodeConverter.getCodeFromName(FBLiteracy.Country.get(pieces));
+ String code = CountryCodeConverter.getCodeFromName(FBLiteracy.Country.get(pieces), true);
if (code == null) {
return false;
}
@@ -322,6 +325,7 @@
// List<List<String>> data = SpreadSheet.convert(CldrUtility.getUTF8Data(filename));
CldrUtility.handleFile(filename, new LineHandler() {
+ @Override
public boolean handle(String line) {
if (line.contains("Series Code")) {
return false;
@@ -344,7 +348,7 @@
if (last == null) {
return false;
}
- String country = CountryCodeConverter.getCodeFromName(WBLine.Country_Name.get(pieces));
+ String country = CountryCodeConverter.getCodeFromName(WBLine.Country_Name.get(pieces), true);
if (country == null) {
return false;
}
@@ -374,6 +378,7 @@
private static void loadUnLiteracy() throws IOException {
CldrUtility.handleFile("external/un_literacy.csv", new CldrUtility.LineHandler() {
+ @Override
public boolean handle(String line) {
// Afghanistan,2000, ,28,43,13,,34,51,18
// "Country or area","Year",,"Adult (15+) literacy rate",,,,,," Youth (15-24) literacy rate",,,,
@@ -383,7 +388,7 @@
if (pieces.length != 14 || pieces[1].length() == 0 || !DIGITS.containsAll(pieces[1])) {
return false;
}
- String code = CountryCodeConverter.getCodeFromName(pieces[0]);
+ String code = CountryCodeConverter.getCodeFromName(pieces[0], true);
if (code == null) {
return false;
}
@@ -437,7 +442,7 @@
}
if (myErrors.length() != 0) {
throw new IllegalArgumentException(
- "Missing Country values, the following and add to external/other_country_data to fix:"
+ "Missing Country values, the following and add to external/other_country_data to fix, chaning the 0 to the real value:"
+ myErrors);
}
} catch (IOException e) {
diff --git a/tools/java/org/unicode/cldr/tool/CLDRCompare.java b/tools/java/org/unicode/cldr/tool/CLDRCompare.java
index 85b22cf..d0d8524 100644
--- a/tools/java/org/unicode/cldr/tool/CLDRCompare.java
+++ b/tools/java/org/unicode/cldr/tool/CLDRCompare.java
@@ -9,16 +9,15 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
-import com.ibm.icu.dev.util.CollectionUtilities;
-
public class CLDRCompare {
public static void main(String[] args) throws Exception {
String filter = CldrUtility.getProperty("filter", ".*");
Matcher matcher = PatternCache.get(filter).matcher("");
- File oldVersion = new File(CldrUtility.getProperty("old", new File(CLDRPaths.COMMON_DIRECTORY
- + "../../../common-cldr1.6").getCanonicalPath()));
+ File oldVersion = new File(CldrUtility.getProperty("old", PathUtilities.getNormalizedPathString(CLDRPaths.COMMON_DIRECTORY
+ + "../../../common-cldr1.6")));
if (!oldVersion.exists()) {
throw new IllegalArgumentException("Directory not found");
}
@@ -34,13 +33,13 @@
for (String subDir : newVersion.list()) {
if (subDir.equals("CVS") || subDir.equals("posix") || subDir.equals("test")) continue;
- final String newSubDir = newVersion.getCanonicalPath() + "/" + subDir;
+ final String newSubDir = PathUtilities.getNormalizedPathString(newVersion) + "/" + subDir;
final File srcDir = new File(newSubDir);
if (!srcDir.isDirectory()) continue;
- final String oldSubDir = oldVersion.getCanonicalPath() + "/" + subDir;
+ final String oldSubDir = PathUtilities.getNormalizedPathString(oldVersion) + "/" + subDir;
- TreeSet<String> files = new TreeSet<String>();
+ TreeSet<String> files = new TreeSet<>();
Factory cldrFactory = Factory.make(newSubDir, ".*");
files.addAll(cldrFactory.getAvailable());
@@ -58,17 +57,17 @@
continue;
}
- HashSet<String> paths = new HashSet<String>();
+ HashSet<String> paths = new HashSet<>();
CLDRFile newCldrFile = null;
try {
newCldrFile = cldrFactory.make(file, false);
- CollectionUtilities.addAll(newCldrFile.iterator(), paths);
+ newCldrFile.forEach(paths::add);
} catch (Exception e) {
}
CLDRFile oldCldrFile = null;
try {
oldCldrFile = oldFactory.make(file, false);
- CollectionUtilities.addAll(oldCldrFile.iterator(), paths);
+ oldCldrFile.forEach(paths::add);
} catch (Exception e1) {
}
diff --git a/tools/java/org/unicode/cldr/tool/CLDRFilePseudolocalizer.java b/tools/java/org/unicode/cldr/tool/CLDRFilePseudolocalizer.java
index ba3efa9..329add5 100644
--- a/tools/java/org/unicode/cldr/tool/CLDRFilePseudolocalizer.java
+++ b/tools/java/org/unicode/cldr/tool/CLDRFilePseudolocalizer.java
@@ -78,7 +78,7 @@
private int charCount = 0;
private static Map<Integer, String> buildReplacementsTable() {
- Map<Integer, String> table = new HashMap<Integer, String>();
+ Map<Integer, String> table = new HashMap<>();
table.put((int) ' ', "\u2003");
table.put((int) '!', "\u00a1");
table.put((int) '"', "\u2033");
@@ -172,11 +172,13 @@
return table;
}
+ @Override
public String start() {
charCount = 0;
return "[";
}
+ @Override
public String end() {
StringBuilder expansionText = new StringBuilder();
int expansion = (charCount + 1) / 2;
@@ -198,6 +200,7 @@
return expansionText.toString();
}
+ @Override
public String fragment(String text) {
StringBuilder buf = new StringBuilder();
int index = 0;
@@ -228,6 +231,7 @@
/** Postfix to add after each LTR word */
private static final String BIDI_POSTFIX = PDF + RLM;
+ @Override
public String fragment(String text) {
StringBuilder output = new StringBuilder();
boolean wrapping = false;
diff --git a/tools/java/org/unicode/cldr/tool/CLDRFileTransformer.java b/tools/java/org/unicode/cldr/tool/CLDRFileTransformer.java
index baf3e9b..0a12fff 100644
--- a/tools/java/org/unicode/cldr/tool/CLDRFileTransformer.java
+++ b/tools/java/org/unicode/cldr/tool/CLDRFileTransformer.java
@@ -29,15 +29,17 @@
* @author jchye
*/
public class CLDRFileTransformer {
+ public enum PolicyIfExisting {
+ RETAIN, // Do not transliterate if existing output has locale content
+ DISCARD, // Replace existing output locale content
+ MINIMIZE // RETAIN, plus drop values if translit is a no-op.
+ }
+
/**
* Contains all supported locale-to-locale conversions along with information
* needed to convert each locale. Each enum value is named after the locale that results
* from the conversion.
*/
- enum PolicyIfExisting {
- RETAIN, DISCARD, MINIMIZE
- }
-
public enum LocaleTransform {
sr_Latn("sr", "Serbian-Latin-BGN.xml", Transliterator.FORWARD, "[:script=Cyrl:]", PolicyIfExisting.DISCARD), //
sr_Latn_BA("sr_Cyrl_BA", "Serbian-Latin-BGN.xml", Transliterator.FORWARD, "[:script=Cyrl:]", PolicyIfExisting.DISCARD), //
@@ -47,7 +49,7 @@
yo_BJ("yo", "yo-yo_BJ.xml", Transliterator.FORWARD, "[ẹ ọ ṣ Ẹ Ọ Ṣ]", PolicyIfExisting.DISCARD), //
de_CH("de", "[ß] Casefold", Transliterator.FORWARD, "[ß]", PolicyIfExisting.MINIMIZE), //
yue_Hans("yue", "Simplified-Traditional.xml", Transliterator.REVERSE, "[:script=Hant:]", PolicyIfExisting.RETAIN), //
- // en_NZ("en_AU", "null", Transliterator.FORWARD, "[]", PolicyIfExisting.DISCARD),
+ // en_NZ("en_AU", "null", Transliterator.FORWARD, "[]", PolicyIfExisting.DISCARD),
// Needs work to fix currency symbols, handle Maori. See http://unicode.org/cldr/trac/ticket/9516#comment:6
;
@@ -60,6 +62,7 @@
/**
* @deprecated Use {@link #LocaleTransform(String,String,int,String,PolicyIfExisting)} instead
*/
+ @Deprecated
private LocaleTransform(String inputLocale, String transformFilename, int direction, String inputCharPattern) {
this(inputLocale, transformFilename, direction, inputCharPattern, PolicyIfExisting.DISCARD);
}
@@ -73,6 +76,13 @@
}
/**
+ * @return the policy for existing content
+ */
+ public PolicyIfExisting getPolicyIfExisting() {
+ return policy;
+ }
+
+ /**
* @return the locale that used for conversion
*/
public String getInputLocale() {
@@ -118,7 +128,7 @@
* Use ConcurrentHashMap rather than HashMap to avoid concurrency problems.
* Reference: https://unicode.org/cldr/trac/ticket/11657
*/
- private static Map<LocaleTransform, Transliterator> transliterators = new ConcurrentHashMap<LocaleTransform, Transliterator>();
+ private static Map<LocaleTransform, Transliterator> transliterators = new ConcurrentHashMap<>();
private String transformDir;
/**
@@ -204,7 +214,7 @@
/**
* Transforms a CLDRFile value into another form.
- * @param parentValue
+ * @param parentValue
*/
private String transformValue(Transliterator transliterator, LocaleTransform localeTransform, String path, String value,
String oldValue, String parentValue) {
@@ -269,7 +279,7 @@
}
String outputDir = CLDRPaths.GEN_DIRECTORY + "common/" + dir + File.separator;
String outputFile = output.getLocaleID() + ".xml";
-
+
try (PrintWriter out = FileUtilities.openUTF8Writer(outputDir, outputFile)) {
System.out.println("Generating locale file: " + outputDir + outputFile);
if (!transformer.unconverted.isEmpty()) {
diff --git a/tools/java/org/unicode/cldr/tool/CLDRFormat.java b/tools/java/org/unicode/cldr/tool/CLDRFormat.java
index fd72113..d0aef05 100644
--- a/tools/java/org/unicode/cldr/tool/CLDRFormat.java
+++ b/tools/java/org/unicode/cldr/tool/CLDRFormat.java
@@ -12,12 +12,11 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
//import org.unicode.cldr.util.XPathParts.Comments;
-import com.ibm.icu.dev.util.CollectionUtilities;
-
public class CLDRFormat {
public static void main(String[] args) throws Exception {
// TODO - make these parameters
@@ -28,7 +27,7 @@
File dtd = new File(dest + "/main/" + "../../common/dtd/ldmlSupplemental.dtd");
if (!dtd.exists()) {
throw new IllegalArgumentException("Can't access DTD\nas is: " + dtd + "\ncanonical: "
- + dtd.getCanonicalPath());
+ + PathUtilities.getNormalizedPathString(dtd));
}
// Log.setLog(Utility.GEN_DIRECTORY + "logCldr.txt");
for (String subDir : src.list()) {
@@ -77,18 +76,18 @@
}
}
- static Set<String> keys1 = new TreeSet<String>();
- static Set<String> keys2 = new TreeSet<String>();
+ static Set<String> keys1 = new TreeSet<>();
+ static Set<String> keys2 = new TreeSet<>();
private static String findFirstDifference(CLDRFile cldrFile, CLDRFile regenFile) {
keys1.clear();
keys2.clear();
- CollectionUtilities.addAll(cldrFile.iterator(), keys1);
- CollectionUtilities.addAll(regenFile.iterator(), keys2);
+ cldrFile.forEach(keys1::add);
+ regenFile.forEach(keys2::add);
if (!keys1.equals(keys2)) {
- Set<String> missing = new TreeSet<String>(keys1);
+ Set<String> missing = new TreeSet<>(keys1);
missing.removeAll(keys2);
- Set<String> extras = new TreeSet<String>(keys2);
+ Set<String> extras = new TreeSet<>(keys2);
extras.removeAll(keys1);
return "\tMissing: " + missing.toString().replace(", ", ",\n") + ";\n\tExtras: "
+ extras.toString().replace(", ", ",\n");
diff --git a/tools/java/org/unicode/cldr/tool/CLDRModify.java b/tools/java/org/unicode/cldr/tool/CLDRModify.java
index 3c7857a..9713254 100644
--- a/tools/java/org/unicode/cldr/tool/CLDRModify.java
+++ b/tools/java/org/unicode/cldr/tool/CLDRModify.java
@@ -49,8 +49,9 @@
import org.unicode.cldr.util.FileProcessor;
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.Level;
-import org.unicode.cldr.util.Log;
+// import org.unicode.cldr.util.Log;
import org.unicode.cldr.util.LogicalGrouping;
+import org.unicode.cldr.util.PathChecker;
import org.unicode.cldr.util.PathHeader;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.RegexLookup;
@@ -65,9 +66,9 @@
import org.unicode.cldr.util.XPathParts.Comments;
import org.unicode.cldr.util.XPathParts.Comments.CommentType;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.ibm.icu.dev.tool.UOption;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.DateTimePatternGenerator;
@@ -162,6 +163,7 @@
}
}
+ @Override
public String toString() {
return action != null ? action.toString()
: exactMatch == null ? regexMatch.toString()
@@ -335,7 +337,7 @@
System.out.format("Source:\t%s\n", sourceDirBase);
System.out.format("Target:\t%s\n", targetDirBase);
- Set<String> dirSet = new TreeSet<String>();
+ Set<String> dirSet = new TreeSet<>();
if (recurseOnDirectories == null) {
dirSet.add("");
} else {
@@ -350,7 +352,7 @@
String sourceDir = sourceDirBase + dir;
if (!new File(sourceDir).isDirectory()) continue;
String targetDir = targetDirBase + dir;
- Log.setLog(targetDir + "/diff", "log.txt");
+ // Log.setLog(targetDir + "/diff", "log.txt");
try {
Factory cldrFactory = Factory.make(sourceDir, ".*");
@@ -389,10 +391,10 @@
* testSet = new TreeSet(Arrays.asList(quicktest));
* }
*/
- Set<String> locales = new TreeSet<String>(cldrFactory.getAvailable());
+ Set<String> locales = new TreeSet<>(cldrFactory.getAvailable());
if (mergeFactory != null) {
- Set<String> temp = new TreeSet<String>(mergeFactory.getAvailable());
- Set<String> locales3 = new TreeSet<String>();
+ Set<String> temp = new TreeSet<>(mergeFactory.getAvailable());
+ Set<String> locales3 = new TreeSet<>();
for (String locale : temp) {
if (!locale.startsWith(join_prefix) || !locale.endsWith(join_postfix)) continue;
locales3.add(locale.substring(join_prefix.length(), locale.length() - join_postfix.length()));
@@ -523,13 +525,13 @@
testPath = "//ldml/dates/calendars/calendar[@type=\"persian\"]/months/monthContext[@type=\"format\"]/monthWidth[@type=\"abbreviated\"]/alias";
System.out.println(k.getStringValue(testPath));
// System.out.println(k.getFullXPath(testPath));
- Iterator it4 = k.iterator();
- Set s = CollectionUtilities.addAll(it4, new TreeSet());
+ TreeSet s = new TreeSet();
+ k.forEach(s::add);
System.out.println(k.getStringValue(testPath));
// if (true) return;
Set orderedSet = new TreeSet(k.getComparator());
- CollectionUtilities.addAll(k.iterator(), orderedSet);
+ k.forEach(orderedSet::add);
for (Iterator it3 = orderedSet.iterator(); it3.hasNext();) {
String path = (String) it3.next();
// System.out.println(path);
@@ -575,7 +577,7 @@
}
} finally {
fixList.handleCleanup();
- Log.close();
+ // Log.close();
System.out.println("Done -- Elapsed time: " + ((System.currentTimeMillis() - startTime) / 60000.0)
+ " minutes");
}
@@ -624,7 +626,7 @@
}
return Retention.RETAIN_IF_DIFFERENT;
}
- };
+ }
static final Splitter COMMA_SEMI = Splitter.on(Pattern.compile("[,;|]")).trimResults().omitEmptyStrings();
protected static final boolean NUMBER_SYSTEM_HACK = true;
@@ -646,7 +648,7 @@
*
*/
private static void removePosix(CLDRFile toMergeIn) {
- Set<String> toRemove = new HashSet<String>();
+ Set<String> toRemove = new HashSet<>();
for (String xpath : toMergeIn) {
if (xpath.startsWith("//ldml/posix")) toRemove.add(xpath);
}
@@ -704,6 +706,9 @@
// }
// }
+ static PathChecker pathChecker = new PathChecker();
+
+
abstract static class CLDRFilter {
protected CLDRFile cldrFileToFilter;
protected CLDRFile cldrFileToFilterResolved;
@@ -810,6 +815,10 @@
}
boolean pathSame = oldFullPath.equals(newFullPath);
+ if (!pathChecker.checkPath(newFullPath)) {
+ throw new IllegalArgumentException("Bad path: " + newFullPath);
+ }
+
if (pathSame) {
if (newValue == null) {
remove(oldFullPath, reason);
@@ -975,9 +984,9 @@
}
}
- static Set<String> totalSkeletons = new HashSet<String>();
+ static Set<String> totalSkeletons = new HashSet<>();
- static Map<String, String> rootUnitMap = new HashMap<String, String>();
+ static Map<String, String> rootUnitMap = new HashMap<>();
static {
rootUnitMap.put("second", "s");
@@ -1035,6 +1044,7 @@
});
fixList.add('e', "fix Interindic", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
if (xpath.indexOf("=\"InterIndic\"") < 0) return;
String v = cldrFileToFilter.getStringValue(xpath);
@@ -1070,6 +1080,7 @@
// TODO add simpler way to skip file entirely
}
+ @Override
public void handlePath(String xpath) {
if (skip) {
return;
@@ -1101,7 +1112,7 @@
}
String oldFullXPath = cldrFileToFilter.getFullXPath(xpath);
String value = cldrFileToFilter.getStringValue(xpath);
- XPathParts fullparts = XPathParts.getInstance(oldFullXPath); // not frozen, for removeAttribute
+ XPathParts fullparts = XPathParts.getFrozenInstance(oldFullXPath).cloneAsThawed(); // not frozen, for removeAttribute
fullparts.removeAttribute("pattern", "alt");
fullparts.setAttribute("currencyFormat", "type", "accounting");
String newFullXPath = fullparts.toString();
@@ -1138,6 +1149,7 @@
fixList.add('x', "retain paths", new CLDRFilter() {
Matcher m = null;
+ @Override
public void handlePath(String xpath) {
if (m == null) {
m = PatternCache.get(options[PATH].value).matcher("");
@@ -1181,20 +1193,23 @@
fixList.add('l', "change language code", new CLDRFilter() {
private CLDRFile resolved;
+ @Override
public void handleStart() {
resolved = factory.make(cldrFileToFilter.getLocaleID(), true);
}
+ @Override
public void handlePath(String xpath) {
if (!xpath.contains("/language")) {
return;
}
- XPathParts parts = XPathParts.getInstance(xpath); // not frozen, for setAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(xpath);
String languageCode = parts.findAttributeValue("language", "type");
String v = resolved.getStringValue(xpath);
if (!languageCode.equals("swc")) {
return;
}
+ parts = parts.cloneAsThawed();
parts.setAttribute("language", "type", "sw_CD");
replace(xpath, parts.toString(), v);
}
@@ -1221,9 +1236,11 @@
fixList.add('g', "Swap alt/non-alt values for Czechia", new CLDRFilter() {
+ @Override
public void handleStart() {
}
+ @Override
public void handlePath(String xpath) {
XPathParts parts = XPathParts.getFrozenInstance(xpath);
if (!parts.containsAttributeValue("alt", "variant") || !parts.containsAttributeValue("type", "CZ")) {
@@ -1239,6 +1256,7 @@
fixList.add('u', "fix duration unit patterns", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
if (!xpath.contains("/units")) {
return;
@@ -1274,7 +1292,7 @@
return;
}
String fullpath = cldrFileToFilter.getFullXPath(xpath);
- XPathParts parts = XPathParts.getInstance(fullpath); // not frozen, for setAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(fullpath).cloneAsThawed(); // not frozen, for setAttribute
String countValue = parts.getAttributeValue(-1, "count");
if (!DIGITS.containsAll(countValue)) {
return;
@@ -1303,6 +1321,7 @@
fixList.add('b', "Prep for bulk import", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
if (!options[USER].doesOccur) {
return;
@@ -1310,7 +1329,7 @@
String userID = options[USER].value;
String fullpath = cldrFileToFilter.getFullXPath(xpath);
String value = cldrFileToFilter.getStringValue(xpath);
- XPathParts parts = XPathParts.getInstance(fullpath); // not frozen, for addAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(fullpath).cloneAsThawed(); // not frozen, for addAttribute
parts.addAttribute("draft", "unconfirmed");
parts.addAttribute("alt", "proposed-u" + userID + "-implicit1.8");
String newPath = parts.toString();
@@ -1319,6 +1338,7 @@
});
fixList.add('c', "Fix transiton from an old currency code to a new one", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
String oldCurrencyCode = "VEF";
String newCurrencyCode = "VES";
@@ -1367,14 +1387,17 @@
fixList.add('p', "input-processor", new CLDRFilter() {
private DisplayAndInputProcessor inputProcessor;
+ @Override
public void handleStart() {
inputProcessor = new DisplayAndInputProcessor(cldrFileToFilter, true);
}
+ @Override
public void handleEnd() {
inputProcessor = null; // clean up, just in case
}
+ @Override
public void handlePath(String xpath) {
String value = cldrFileToFilter.getStringValue(xpath);
if (!value.equals(value.trim())) {
@@ -1391,6 +1414,7 @@
fixList.add('t', "Fix missing count values groups", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
if (xpath.indexOf("@count=\"other\"") < 0) {
return;
@@ -1410,6 +1434,7 @@
});
fixList.add('f', "NFC (all but transforms, exemplarCharacters, pc, sc, tc, qc, ic)", new CLDRFilter() {
+ @Override
public void handlePath(String xpath) {
if (xpath.indexOf("/segmentation") >= 0
|| xpath.indexOf("/transforms") >= 0
@@ -1446,6 +1471,7 @@
StandardCodes sc = StandardCodes.make();
String[] codeTypes = { "language", "script", "territory", "currency" };
+ @Override
public void handlePath(String xpath) {
if (xpath.indexOf("/currency") < 0
&& xpath.indexOf("/timeZoneNames") < 0
@@ -1468,12 +1494,13 @@
});
fixList.add('w', "fix alt='...proposed' when there is no alternative", new CLDRFilter() {
- private Set<String> newFullXPathSoFar = new HashSet<String>();
+ private Set<String> newFullXPathSoFar = new HashSet<>();
+ @Override
public void handlePath(String xpath) {
if (xpath.indexOf("proposed") < 0) return;
String fullXPath = cldrFileToFilter.getFullXPath(xpath);
- XPathParts parts = XPathParts.getInstance(fullXPath); // not frozen, for removeProposed
+ XPathParts parts = XPathParts.getFrozenInstance(fullXPath).cloneAsThawed(); // not frozen, for removeProposed
String newFullXPath = parts.removeProposed().toString();
// now see if there is an uninherited value
String value = cldrFileToFilter.getStringValue(xpath);
@@ -1510,12 +1537,14 @@
fixList.add('d', "fix dates", new CLDRFilter() {
DateTimePatternGenerator dateTimePatternGenerator = DateTimePatternGenerator.getEmptyInstance();
DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser();
- Map<String, Set<String>> seenSoFar = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> seenSoFar = new HashMap<>();
+ @Override
public void handleStart() {
seenSoFar.clear();
}
+ @Override
public void handlePath(String xpath) {
// timeFormatLength type="full"
if (xpath.contains("timeFormatLength") && xpath.contains("full")) {
@@ -1591,12 +1620,14 @@
DateTimePatternGenerator dateTimePatternGenerator = DateTimePatternGenerator.getEmptyInstance();
DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser();
- Map<String, Set<String>> seenSoFar = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> seenSoFar = new HashMap<>();
+ @Override
public void handleStart() {
seenSoFar.clear();
}
+ @Override
public void handlePath(String xpath) {
DateTimePatternType datetimePatternType = DateTimePatternType.fromPath(xpath);
@@ -1628,10 +1659,12 @@
fixList.add('j', "add year ranges from root to Japanese calendar eras", new CLDRFilter() {
private CLDRFile rootFile;
+ @Override
public void handleStart() {
rootFile = factory.make("root", false);
}
+ @Override
public void handlePath(String xpath) {
// Skip paths we don't care about
if (xpath.indexOf("/calendar[@type=\"japanese\"]/eras/era") < 0) return;
@@ -1668,7 +1701,7 @@
fixList.add('r', "fix references and standards", new CLDRFilter() {
int currentRef = 500;
- Map<String, TreeMap<String, String>> locale_oldref_newref = new TreeMap<String, TreeMap<String, String>>();
+ Map<String, TreeMap<String, String>> locale_oldref_newref = new TreeMap<>();
TreeMap<String, String> oldref_newref;
//LanguageTagParser ltp = new LanguageTagParser();
@@ -1676,11 +1709,12 @@
// References standards = new References(true);
// References references = new References(false);
+ @Override
public void handleStart() {
String locale = cldrFileToFilter.getLocaleID();
oldref_newref = locale_oldref_newref.get(locale);
if (oldref_newref == null) {
- oldref_newref = new TreeMap<String, String>();
+ oldref_newref = new TreeMap<>();
locale_oldref_newref.put(locale, oldref_newref);
}
}
@@ -1688,12 +1722,13 @@
// // Samples:
// // <language type="ain" references="RP1">阿伊努文</language>
// // <reference type="R1" uri="http://www.info.gov.hk/info/holiday_c.htm">二零零五年公眾假期刊登憲報</reference>
+ @Override
public void handlePath(String xpath) {
// must be minimised for this to work.
String fullpath = cldrFileToFilter.getFullXPath(xpath);
if (!fullpath.contains("reference")) return;
String value = cldrFileToFilter.getStringValue(xpath);
- XPathParts fullparts = XPathParts.getInstance(fullpath); // can't be frozen
+ XPathParts fullparts = XPathParts.getFrozenInstance(fullpath).cloneAsThawed(); // can't be frozen
if ("reference".equals(fullparts.getElement(-1))) {
fixType(value, "type", fullpath, fullparts);
} else if (fullparts.getAttributeValue(-1, "references") != null) {
@@ -1738,13 +1773,14 @@
return;
}
String fullpath = cldrFileToFilter.getFullXPath(xpath);
- XPathParts parts = XPathParts.getInstance(fullpath); // not frozen, for putAttributeValue
+ XPathParts parts = XPathParts.getFrozenInstance(fullpath);
String cp = parts.getAttributeValue(2, "cp");
String tts = parts.getAttributeValue(2, "tts");
String type = parts.getAttributeValue(2, "type");
if ("tts".equals(type)) {
return; // ok, skip
}
+ parts = parts.cloneAsThawed();
String hex = "1F600";
if (cp.startsWith("[")) {
UnicodeSet us = new UnicodeSet(cp);
@@ -1787,7 +1823,6 @@
if (!available.contains(localeID)) {
throw new IllegalArgumentException("no annotations available, probably wrong directory");
}
- ;
resolved = factory.make(localeID, true);
}
@@ -1805,7 +1840,7 @@
if (type == null) {
return; // no TTS, so keywords, skip
}
-
+
XPathParts keywordParts = parts.cloneAsThawed().removeAttribute(2, "type");
String keywordPath = keywordParts.toString();
String rawKeywordValue = cldrFileToFilter.getStringValue(keywordPath);
@@ -1817,13 +1852,13 @@
return;
}
}
-
+
// skip if the name is not above root
String nameSourceLocale = resolved.getSourceLocaleID(xpath, null);
if ("root".equals(nameSourceLocale) || XMLSource.CODE_FALLBACK_ID.equals(nameSourceLocale)) {
return;
}
-
+
String name = resolved.getStringValue(xpath);
String keywordValue = resolved.getStringValue(keywordPath);
String sourceLocaleId = resolved.getSourceLocaleID(keywordPath, null);
@@ -1837,7 +1872,7 @@
int debug = 0;
}
DisplayAndInputProcessor.filterCoveredKeywords(sorted);
- String newKeywordValue = CollectionUtilities.join(sorted, " | ");
+ String newKeywordValue = Joiner.on(" | ").join(sorted);
if (!newKeywordValue.equals(keywordValue)) {
replace(keywordPath, keywordPath, newKeywordValue);
}
@@ -1919,7 +1954,7 @@
"fix according to -k config file. Details on http://cldr.unicode.org/development/cldr-big-red-switch/cldrmodify-passes/cldrmodify-config",
new CLDRFilter() {
private Map<ConfigMatch, LinkedHashSet<Map<ConfigKeys, ConfigMatch>>> locale2keyValues;
- private LinkedHashSet<Map<ConfigKeys, ConfigMatch>> keyValues = new LinkedHashSet<Map<ConfigKeys, ConfigMatch>>();
+ private LinkedHashSet<Map<ConfigKeys, ConfigMatch>> keyValues = new LinkedHashSet<>();
private Matcher draftMatcher = Pattern.compile("\\[@draft=\"[^\"]+\"]").matcher("");
@Override
@@ -1955,8 +1990,9 @@
case add:
if (pathMatch != null || valueMatch != null || newPath == null || newValue == null) {
throw new IllegalArgumentException(
- "Bad arguments, must have " +
- "path==null, value=null, new_path!=null, new_value!=null:\n\t"
+ "Bad arguments, must have non-null for one of:" +
+ "path, value, new_path, new_value "
+ + ":\n\t"
+ entry);
}
String newPathString = newPath.getPath(getResolved());
@@ -1989,7 +2025,7 @@
}
private void fillCache() {
- locale2keyValues = new LinkedHashMap<ConfigMatch, LinkedHashSet<Map<ConfigKeys, ConfigMatch>>>();
+ locale2keyValues = new LinkedHashMap<>();
String configFileName = options[KONFIG].value;
FileProcessor myReader = new FileProcessor() {
{
@@ -2003,7 +2039,7 @@
// return true;
// }
String[] lineParts = line.split("\\s*;\\s*");
- Map<ConfigKeys, ConfigMatch> keyValue = new EnumMap<ConfigKeys, ConfigMatch>(
+ Map<ConfigKeys, ConfigMatch> keyValue = new EnumMap<>(
ConfigKeys.class);
for (String linePart : lineParts) {
int pos = linePart.indexOf('=');
@@ -2022,11 +2058,12 @@
throw new IllegalArgumentException();
}
+ // validate new path
LinkedHashSet<Map<ConfigKeys, ConfigMatch>> keyValues = locale2keyValues
.get(locale);
if (keyValues == null) {
locale2keyValues.put(locale,
- keyValues = new LinkedHashSet<Map<ConfigKeys, ConfigMatch>>());
+ keyValues = new LinkedHashSet<>());
}
keyValues.add(keyValue);
return true;
@@ -2181,8 +2218,8 @@
}
@Override
public void handlePath(String xpath) {
- if (skip
- || seen.contains(xpath)
+ if (skip
+ || seen.contains(xpath)
|| coverageLeveler.getLevel(xpath) == Level.COMPREHENSIVE) {
return;
}
@@ -2229,12 +2266,12 @@
for (String path2 : paths) {
String fullPath = resolved.getFullXPath(path2);
String value = resolved.getStringValue(path2);
- if (LogicalGrouping.isOptional(cldrFileToFilter, path2)
+ if (LogicalGrouping.isOptional(cldrFileToFilter, path2)
&& !cldrFileToFilter.isHere(path2)) {
continue;
}
- XPathParts fullparts = XPathParts.getInstance(fullPath); // not frozen, for setAttribute
+ XPathParts fullparts = XPathParts.getFrozenInstance(fullPath).cloneAsThawed(); // not frozen, for setAttribute
fullparts.setAttribute(-1, "draft", worstStatus.toString());
replace(fullPath, fullparts.toString(), value, "Fleshing out bailey to " + worstStatus);
}
@@ -2268,11 +2305,11 @@
if (key.equals("root")) return;
Set<String> availableChildren = cldrFactory.getAvailableWithParent(key, true);
if (availableChildren.size() == 0) return;
- Set<String> skipPaths = new HashSet<String>();
- Map<String, ValuePair> haveSameValues = new TreeMap<String, ValuePair>();
+ Set<String> skipPaths = new HashSet<>();
+ Map<String, ValuePair> haveSameValues = new TreeMap<>();
CLDRFile resolvedFile = cldrFactory.make(key, true);
// get only those paths that are not in "root"
- CollectionUtilities.addAll(resolvedFile.iterator(), skipPaths);
+ resolvedFile.forEach(skipPaths::add);
// first, collect all the paths
for (String locale : availableChildren) {
@@ -2350,7 +2387,7 @@
// TODO before modifying, make sure that it is fully resolved.
// then minimize against the NEW parents
- Set<String> removal = new TreeSet<String>(k.getComparator());
+ Set<String> removal = new TreeSet<>(k.getComparator());
CLDRFile replacements = SimpleFactory.makeFile("temp");
fixList.setFile(k, inputOptions, cldrFactory, removal, replacements);
@@ -2399,9 +2436,9 @@
public static void testJavaSemantics() {
Collator caseInsensitive = Collator.getInstance(ULocale.ROOT);
caseInsensitive.setStrength(Collator.SECONDARY);
- Set<String> setWithCaseInsensitive = new TreeSet<String>(caseInsensitive);
+ Set<String> setWithCaseInsensitive = new TreeSet<>(caseInsensitive);
setWithCaseInsensitive.addAll(Arrays.asList(new String[] { "a", "b", "c" }));
- Set<String> plainSet = new TreeSet<String>();
+ Set<String> plainSet = new TreeSet<>();
plainSet.addAll(Arrays.asList(new String[] { "a", "b", "B" }));
System.out.println("S1 equals S2?\t" + setWithCaseInsensitive.equals(plainSet));
System.out.println("S2 equals S1?\t" + plainSet.equals(setWithCaseInsensitive));
diff --git a/tools/java/org/unicode/cldr/tool/Chart.java b/tools/java/org/unicode/cldr/tool/Chart.java
index 882af23..752b064 100644
--- a/tools/java/org/unicode/cldr/tool/Chart.java
+++ b/tools/java/org/unicode/cldr/tool/Chart.java
@@ -23,7 +23,7 @@
public static final SupplementalDataInfo SDI = CONFIG.getSupplementalDataInfo();
public static final CLDRFile ENGLISH = CONFIG.getEnglish();
public static final String LS = System.lineSeparator();
-
+
public static final String PREV_CHART_VERSION_DIRECTORY = ToolConstants.getBaseDirectory(ToolConstants.PREV_CHART_VERSION);
public static final String CHART_VERSION_DIRECTORY = ToolConstants.getBaseDirectory(ToolConstants.CHART_VERSION);
@@ -31,7 +31,7 @@
private static final String LDML_SPEC = "https://unicode.org/reports/tr35/";
public static String dataScrapeMessage(String specPart, String testFile, String... dataFiles) {
- final String dataFileList = dataFiles.length == 0 ? null :
+ final String dataFileList = dataFiles.length == 0 ? null :
ListFormatter.getInstance(ULocale.ENGLISH).format(
Arrays.asList(dataFiles).stream()
.map(dataFile -> Chart.dataFileLink(dataFile))
@@ -59,7 +59,7 @@
*/
public String getFileName() {
return null;
- };
+ }
/**
* Show Date?
@@ -100,7 +100,7 @@
standardFooter(pw, AnalyticsID.CLDR);
}
- enum AnalyticsID {
+ private enum AnalyticsID {
CLDR("UA-7672775-1"), ICU("UA-7670213-1"), ICU_GUIDE("UA-7670256-1"), UNICODE("UA-7670213-1"), UNICODE_UTILITY("UA-8314904-1");
public final String id;
@@ -109,7 +109,7 @@
}
}
- public static void standardFooter(FormattedFileWriter pw, AnalyticsID analytics) throws IOException {
+ private static void standardFooter(FormattedFileWriter pw, AnalyticsID analytics) throws IOException {
pw.write("<div style='text-align: center; margin-top:2em; margin-bottom: 60em;'><br>\n"
+ "<a href='http://www.unicode.org/unicode/copyright.html'>\n"
+ "<img src='http://www.unicode.org/img/hb_notice.gif' style='border-style: none; width: 216px; height=50px;' alt='Access to Copyright and terms of use'>"
diff --git a/tools/java/org/unicode/cldr/tool/ChartAnnotations.java b/tools/java/org/unicode/cldr/tool/ChartAnnotations.java
index 14a97e7..7bb9dcb 100644
--- a/tools/java/org/unicode/cldr/tool/ChartAnnotations.java
+++ b/tools/java/org/unicode/cldr/tool/ChartAnnotations.java
@@ -16,6 +16,7 @@
import org.unicode.cldr.util.Annotations.AnnotationSet;
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRPaths;
+import org.unicode.cldr.util.CLDRURLS;
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.FileCopier;
@@ -23,9 +24,9 @@
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.LocaleIDParser;
+import com.google.common.base.Joiner;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R3;
@@ -39,7 +40,9 @@
private static final String LDML_ANNOTATIONS = "<a href='http://unicode.org/repos/cldr/trunk/specs/ldml/tr35-general.html#Annotations'>LDML Annotations</a>";
private static final String MAIN_HEADER = "<p>Annotations provide names and keywords for Unicode characters, currently focusing on emoji. "
- + "If you see any problems, please <a target='_blank' href='http://unicode.org/cldr/trac/newticket'>file a ticket</a> with the corrected values for the locale. "
+ + "If you see any problems, please <a target='_blank' href='"
+ + CLDRURLS.CLDR_NEWTICKET_URL
+ + "'>file a ticket</a> with the corrected values for the locale. "
+ "For the XML data used for these charts, see "
+ "<a href='http://unicode.org/repos/cldr/tags/latest/common/annotations/'>latest-release annotations </a> "
+ "or <a href='http://unicode.org/repos/cldr/tags/latest/common/annotations/'>beta annotations</a>. "
@@ -71,6 +74,7 @@
return MAIN_HEADER + "<p>The charts are presented in groups of related languages, for easier comparison.<p>";
}
+ @Override
public void writeContents(FormattedFileWriter pw) throws IOException {
FileCopier.ensureDirectoryExists(DIR);
FileCopier.copy(Chart.class, "index.css", DIR);
@@ -108,7 +112,7 @@
// set up right order for columns
- Map<String, String> nameToCode = new LinkedHashMap<String, String>();
+ Map<String, String> nameToCode = new LinkedHashMap<>();
Relation<LanguageGroup, R3<Integer, String, String>> groupToNameAndCodeSorted = Relation.of(
new EnumMap<LanguageGroup, Set<R3<Integer, String, String>>>(LanguageGroup.class),
TreeSet.class);
@@ -212,7 +216,7 @@
}
}
for (Entry<String, Collection<String>> entry : valueToSub.asMap().entrySet()) {
- baseAnnotation += "<hr><i>" + CollectionUtilities.join(entry.getValue(), ", ") + "</i>: " + entry.getKey();
+ baseAnnotation += "<hr><i>" + Joiner.on(", ").join(entry.getValue()) + "</i>: " + entry.getKey();
}
}
tablePrinter.addCell(baseAnnotation);
@@ -333,7 +337,7 @@
+ "The keywords plus the words in the short name are typically used for search and predictive typing.<p>\n"
+ "<p>Most short names and keywords that can be constructed with the mechanism in " + LDML_ANNOTATIONS + " are omitted. "
+ "However, a few are included for comparison: "
- + CollectionUtilities.join(EXTRAS.addAllTo(new TreeSet<>()), ", ") + ". "
+ + Joiner.on(", ").join(EXTRAS.addAllTo(new TreeSet<>())) + ". "
+ "In this chart, missing items are marked with “" + Annotations.MISSING_MARKER + "”, "
+ "‘fallback’ constructed items with “" + Annotations.BAD_MARKER + "”, "
+ "substituted English values with “" + Annotations.ENGLISH_MARKER + "”, and "
diff --git a/tools/java/org/unicode/cldr/tool/ChartCollation.java b/tools/java/org/unicode/cldr/tool/ChartCollation.java
index 20bd229..9a67264 100644
--- a/tools/java/org/unicode/cldr/tool/ChartCollation.java
+++ b/tools/java/org/unicode/cldr/tool/ChartCollation.java
@@ -29,8 +29,8 @@
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.RuleBasedCollator;
import com.ibm.icu.text.Transliterator;
@@ -41,7 +41,7 @@
static final String NOT_TAILORED = "notTailored";
static final String NOT_EXEMPLARS = "notExemplars";
- private static final String KNOWN_PROBLEMS =
+ private static final String KNOWN_PROBLEMS =
"<ul>" + LS
+ "<li>The characters used in the illustration are:" + LS
+ "<ol>" + LS
@@ -90,6 +90,7 @@
+ dataScrapeMessage("/tr35-collation.html", "common/testData/units/unitsTest.txt", "common/collation")+ LS;
}
+ @Override
public void writeContents(FormattedFileWriter pw) throws IOException {
FileCopier.ensureDirectoryExists(DIR);
FileCopier.copy(Chart.class, "index.css", DIR);
@@ -210,7 +211,7 @@
if (dataItem == null) {
data.put(type, dataItem = new Data());
}
- dataItem.settings.add(leaf + ":" + CollectionUtilities.join(settings, ";"));
+ dataItem.settings.add(leaf + ":" + Joiner.on(";").join(settings));
}
private void addCollator(Map<String, Data> data, String type, RuleBasedCollator col) {
@@ -311,7 +312,7 @@
Set<String> settings = entry.getValue().settings;
StringBuilder list = new StringBuilder();
if (!settings.isEmpty()) {
- list.append(CollectionUtilities.join(settings, "<br>"));
+ list.append(Joiner.on("<br>").join(settings));
list.append("<br><b><i>plus</i></b><br>");
}
if (col == null) {
diff --git a/tools/java/org/unicode/cldr/tool/ChartDelta.java b/tools/java/org/unicode/cldr/tool/ChartDelta.java
index 4acfb65..a478a8f 100644
--- a/tools/java/org/unicode/cldr/tool/ChartDelta.java
+++ b/tools/java/org/unicode/cldr/tool/ChartDelta.java
@@ -19,6 +19,7 @@
import java.util.regex.Pattern;
import org.unicode.cldr.draft.FileUtilities;
+import org.unicode.cldr.test.SubmissionLocales;
import org.unicode.cldr.tool.FormattedFileWriter.Anchors;
import org.unicode.cldr.tool.Option.Options;
import org.unicode.cldr.tool.Option.Params;
@@ -43,14 +44,15 @@
import org.unicode.cldr.util.SimpleXMLSource;
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.SupplementalDataInfo;
+import org.unicode.cldr.util.SupplementalDataInfo.CoverageVariableInfo;
import org.unicode.cldr.util.TransliteratorUtilities;
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.impl.Row.R3;
@@ -62,24 +64,23 @@
public class ChartDelta extends Chart {
private static final boolean verbose_skipping = false;
- private static final String DIR_NAME = "delta";
+ private static final String DEFAULT_DELTA_DIR_NAME = "delta";
+ private static final String DEFAULT_CHURN_DIR_NAME = "churn";
private static final boolean SKIP_REFORMAT_ANNOTATIONS = ToolConstants.PREV_CHART_VERSION.compareTo("30") >= 0;
private static final PageId DEBUG_PAGE_ID = PageId.DayPeriod;
private static final SupplementalDataInfo SUPPLEMENTAL_DATA_INFO = CLDRConfig.getInstance().getSupplementalDataInfo();
- private static final String LAST_ARCHIVE_DIRECTORY = CLDRPaths.LAST_RELEASE_DIRECTORY;
- private static final String CURRENT_DIRECTORY = CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + ToolConstants.PREV_CHART_VERSION_WITH0 + "/";
- private static final String LOG_DIR = CLDRPaths.GEN_DIRECTORY + "charts/";
- enum MyOptions {
+ private enum MyOptions {
fileFilter(new Params().setHelp("filter files by dir/locale, eg: ^main/en$ or .*/en").setMatch(".*")),
orgFilter(new Params().setHelp("filter files by organization").setMatch(".*")),
Vxml(new Params().setHelp("use cldr-aux for the base directory")),
coverageFilter(new Params().setHelp("filter files by coverage").setMatch(".*")),
- directory(new Params().setHelp("Set the output directory name").setDefault(DIR_NAME).setMatch(".*")),
+ directory(new Params().setHelp("Set the output directory name").setDefault(DEFAULT_DELTA_DIR_NAME).setMatch(".*")),
verbose(new Params().setHelp("verbose debugging messages")),
+ highLevelOnly(new Params().setHelp("check high-level paths (churn) only").setFlag('H')),
;
// BOILERPLATE TO COPY
@@ -96,20 +97,31 @@
}
}
- private static Set<String> parse(String[] args, boolean showArguments) {
+ private static Set<String> parse(String[] args) {
return myOptions.parse(MyOptions.values()[0], args, true);
}
}
private final Matcher fileFilter;
- private final String DIR;
+ private final String dirName; // "delta" or "churn" or set as option
+ private final String chartNameCap; // capitalized, e.g., "Delta" or "Churn"
+ private final String DIR; // full path of output folder
private final Level minimumPathCoverage;
- private final boolean vxml;
private final boolean verbose;
+ /**
+ * If true, check only high-level paths, i.e., paths for which any changes
+ * have high potential to cause disruptive "churn"
+ */
+ private final boolean highLevelOnly;
+
public static void main(String[] args) {
+ main(args, false);
+ }
+
+ public static void main(String[] args, boolean highLevelOnly) {
System.out.println("use -DCHART_VERSION=36.0 -DPREV_CHART_VERSION=34.0 to generate the differences between v36 and v34.");
- MyOptions.parse(args, true);
+ MyOptions.parse(args);
Matcher fileFilter = !MyOptions.fileFilter.option.doesOccur() ? null : PatternCache.get(MyOptions.fileFilter.option.getValue()).matcher("");
if (MyOptions.orgFilter.option.doesOccur()) {
if (MyOptions.fileFilter.option.doesOccur()) {
@@ -118,23 +130,38 @@
String rawOrg = MyOptions.orgFilter.option.getValue();
Organization org = Organization.fromString(rawOrg);
Set<String> locales = StandardCodes.make().getLocaleCoverageLocales(org);
- fileFilter = PatternCache.get("^(main|annotations)/(" + CollectionUtilities.join(locales, "|") + ")$").matcher("");
+ fileFilter = PatternCache.get("^(main|annotations)/(" + Joiner.on("|").join(locales) + ")$").matcher("");
}
Level coverage = !MyOptions.coverageFilter.option.doesOccur() ? null : Level.fromString(MyOptions.coverageFilter.option.getValue());
boolean verbose = MyOptions.verbose.option.doesOccur();
- boolean vxml = MyOptions.Vxml.option.doesOccur();
- String DIR = CLDRPaths.CHART_DIRECTORY + MyOptions.directory.option.getValue();
- ChartDelta temp = new ChartDelta(fileFilter, coverage, DIR, verbose, vxml);
+ if (MyOptions.highLevelOnly.option.doesOccur()) {
+ highLevelOnly = true;
+ }
+ String dirName = MyOptions.directory.option.getValue();
+ if (highLevelOnly && DEFAULT_DELTA_DIR_NAME.equals(dirName)) {
+ System.out.println("For highLevelOnly, changing directory from " + DEFAULT_DELTA_DIR_NAME
+ + " to " + DEFAULT_CHURN_DIR_NAME);
+ dirName = DEFAULT_CHURN_DIR_NAME;
+ }
+ ChartDelta temp = new ChartDelta(fileFilter, coverage, dirName, verbose, highLevelOnly);
temp.writeChart(null);
temp.showTotals();
+ if (highLevelOnly) {
+ HighLevelPaths.reportHighLevelPathUsage();
+ }
+ System.out.println("Finished. Files may have been created in these directories:");
+ System.out.println(temp.DIR);
+ System.out.println(getTsvDir(temp.DIR, temp.dirName));
}
- public ChartDelta(Matcher fileFilter, Level coverage, String dir, boolean verbose, boolean vxml) {
+ private ChartDelta(Matcher fileFilter, Level coverage, String dirName, boolean verbose, boolean highLevelOnly) {
this.fileFilter = fileFilter;
this.verbose = verbose;
- this.DIR = dir;
+ this.highLevelOnly = highLevelOnly;
+ this.dirName = dirName;
+ this.chartNameCap = dirName.substring(0, 1).toUpperCase() + dirName.substring(1);
+ this.DIR = CLDRPaths.CHART_DIRECTORY + dirName;
this.minimumPathCoverage = coverage;
- this.vxml = vxml;
}
private static final String SEP = "\u0001";
@@ -152,7 +179,7 @@
@Override
public String getTitle() {
- return "Delta Charts";
+ return chartNameCap + " Charts";
}
@Override
@@ -180,21 +207,23 @@
pw.write(anchors.toString());
}
- static class PathHeaderSegment extends R3<PathHeader, Integer, String> {
+ private static class PathHeaderSegment extends R3<PathHeader, Integer, String> {
public PathHeaderSegment(PathHeader b, int elementIndex, String attribute) {
super(b, elementIndex, attribute);
}
}
- static class PathDiff extends R4<PathHeaderSegment, String, String, String> {
+ private static class PathDiff extends R4<PathHeaderSegment, String, String, String> {
public PathDiff(String locale, PathHeaderSegment pathHeaderSegment, String oldValue, String newValue) {
super(pathHeaderSegment, locale, oldValue, newValue);
}
}
- static final CLDRFile EMPTY_CLDR = new CLDRFile(new SimpleXMLSource("und").freeze());
+ private static final CLDRFile EMPTY_CLDR = new CLDRFile(new SimpleXMLSource("und").freeze());
- enum ChangeType {
+ private static final File CLDR_BASE_DIR = CLDRConfig.getInstance().getCldrBaseDirectory();
+
+ private enum ChangeType {
added, deleted, changed, same;
public static ChangeType get(String oldValue, String currentValue) {
return oldValue == null ? added
@@ -204,9 +233,9 @@
}
}
- Counter<ChangeType> counter = new Counter<>();
- Map<String, Counter<ChangeType>> fileCounters = new TreeMap<>();
- Set<String> badHeaders = new TreeSet<>();
+ private Counter<ChangeType> counter = new Counter<>();
+ private Map<String, Counter<ChangeType>> fileCounters = new TreeMap<>();
+ private Set<String> badHeaders = new TreeSet<>();
private void addChange(String file, ChangeType changeType, int count) {
counter.add(changeType, count); // unified add
@@ -218,8 +247,8 @@
}
private void showTotals() {
- try (PrintWriter pw = FileUtilities.openUTF8Writer(getTsvDir(DIR, DIR_NAME), DIR_NAME + "_summary.tsv")) {
- pw.println("# percentages are of *new* total");
+ try (PrintWriter pw = FileUtilities.openUTF8Writer(getTsvDir(DIR, dirName), dirName + "_summary.tsv")) {
+ // pw.println("# percentages are of *new* total");
pw.print("# dir\tfile");
for (ChangeType item : ChangeType.values()) {
pw.print("\t" + (item == ChangeType.same ? "total" : item.toString()));
@@ -233,7 +262,7 @@
for (String s : badHeaders) {
pw.println(s);
}
- pw.println("# EOF");
+ // pw.println("# EOF");
} catch (IOException e) {
throw new ICUUncheckedIOException(e);
}
@@ -256,39 +285,27 @@
pw.println();
}
- public void writeSubcharts(Anchors anchors) throws IOException {
- FileUtilities.copyFile(ChartDelta.class, "index.css", getDirectory());
- counter.clear();
- fileCounters.clear();
- writeNonLdmlPlain(anchors);
- writeLdml(anchors);
- }
-
- private static final File[] PATHS = {
- new File(CLDRPaths.MAIN_DIRECTORY),
- new File(CLDRPaths.ANNOTATIONS_DIRECTORY),
- };
-
+ /**
+ *
+ * @param anchors
+ * @throws IOException
+ *
+ * TODO: shorten the function using subroutines
+ */
private void writeLdml(Anchors anchors) throws IOException {
-
- try (PrintWriter tsvFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, DIR_NAME), DIR_NAME + ".tsv");
- PrintWriter tsvCountFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, DIR_NAME), DIR_NAME + "_count.tsv");
+ try (PrintWriter tsvFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, dirName), dirName + ".tsv");
+ PrintWriter tsvCountFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, dirName), dirName + "_count.tsv");
) {
tsvFile.println("# Section\tPage\tHeader\tCode\tLocale\tOld\tNew\tLevel");
// set up factories
List<Factory> factories = new ArrayList<>();
List<Factory> oldFactories = new ArrayList<>();
-// factories.add(Factory.make(CLDRPaths.BASE_DIRECTORY + "common/" + "main", ".*"));
-// oldFactories.add(Factory.make(LAST_ARCHIVE_DIRECTORY + "common/" + "main", ".*"));
Counter<PathHeader> counts = new Counter<>();
String dirBase = ToolConstants.getBaseDirectory(ToolConstants.CHART_VERSION);
String prevDirBase = ToolConstants.getBaseDirectory(ToolConstants.PREV_CHART_VERSION);
-// ToolConstants.CLDR_RELEASE_VERSION_SET.contains(ToolConstants.PREV_CHART_VERSION) ? CURRENT_DIRECTORY
-// : vxml ? CLDRPaths.SVN_DIRECTORY + "cldr-aux/" + "voting/36/vxml/" // TODO fix version to be variable
-// : CLDRPaths.BASE_DIRECTORY;
for (String dir : DtdType.ldml.directories) {
if (dir.equals("annotationsDerived") || dir.equals("casing")) {
@@ -312,7 +329,7 @@
System.out.println("Will compare: " + dir + "\t\t" + current + "\t\t" + past);
}
if (factories.isEmpty()) {
- throw new IllegalArgumentException("No factories found for "
+ throw new IllegalArgumentException("No factories found for "
+ dirBase + ": " + DtdType.ldml.directories);
}
// get a list of all the locales to cycle over
@@ -321,7 +338,7 @@
Matcher m = fileMatcher.matcher("");
Set<String> defaultContents = SDI.getDefaultContentLocales();
LanguageTagParser ltp = new LanguageTagParser();
- LikelySubtags ls = new LikelySubtags(SDI);
+ LikelySubtags ls = new LikelySubtags();
for (String file : factories.get(0).getAvailable()) {
if (defaultContents.contains(file)) {
continue;
@@ -343,7 +360,6 @@
Relation<PathHeader, String> diffAll = Relation.of(new TreeMap<PathHeader, Set<String>>(), TreeSet.class);
for (Entry<String, Set<String>> baseNLocale : baseToLocales.keyValuesSet()) {
String base = baseNLocale.getKey();
-// int qCount = 0;
for (int i = 0; i < factories.size(); ++i) {
Factory factory = factories.get(i);
Factory oldFactory = oldFactories.get(i);
@@ -353,12 +369,10 @@
}
File sourceDir = sourceDirs.get(0);
String sourceDirLeaf = sourceDir.getName();
- //System.out.println(sourceDirLeaf);
boolean resolving = !sourceDirLeaf.contains("subdivisions")
&& !sourceDirLeaf.contains("transforms");
for (String locale : baseNLocale.getValue()) {
- //System.out.println("\t" + locale);
String nameAndLocale = sourceDirLeaf + "/" + locale;
if (fileFilter != null && !fileFilter.reset(nameAndLocale).find()) {
if (verbose && verbose_skipping) {
@@ -366,7 +380,6 @@
}
continue;
}
-// boolean isBase = locale.equals(base);
if (verbose) {
System.out.println(nameAndLocale);
}
@@ -378,6 +391,9 @@
if (old == EMPTY_CLDR && current == EMPTY_CLDR) {
continue;
}
+ if (highLevelOnly && !HighLevelPaths.localeIsHighLevel(locale)) {
+ continue;
+ }
paths.clear();
for (String path : current.fullIterable()) {
if (allowPath(locale, path)) {
@@ -390,10 +406,13 @@
}
}
- Output<String> reformattedValue = new Output<String>();
- Output<Boolean> hasReformattedValue = new Output<Boolean>();
+ Output<String> reformattedValue = new Output<>();
+ Output<Boolean> hasReformattedValue = new Output<>();
for (String path : paths) {
+ if (highLevelOnly && !HighLevelPaths.pathIsHighLevel(path, locale)) {
+ continue;
+ }
if (path.startsWith("//ldml/identity")
|| path.endsWith("/alias")
|| path.startsWith("//ldml/segmentations") // do later
@@ -401,9 +420,6 @@
) {
continue;
}
- if (path.contains("/tRule")) {
- int debug = 0;
- }
PathHeader ph = getPathHeader(path);
if (ph == null) {
continue;
@@ -446,13 +462,12 @@
writeDiffs(anchors, base, diff, tsvFile, counts);
diff.clear();
}
- writeDiffs(anchors, diffAll);
+ writeDiffs(diffAll);
writeCounter(tsvCountFile, "Count", counts);
- tsvFile.println("# EOF");
- tsvCountFile.println("# EOF");
+ //tsvFile.println("# EOF");
+ //tsvCountFile.println("# EOF");
}
-
}
private boolean allowPath(String locale, String path) {
@@ -461,7 +476,6 @@
if (minimumPathCoverage.compareTo(pathLevel) < 0) {
return false;
}
- int debug = 0;
}
return true;
}
@@ -475,7 +489,7 @@
// NEW: <annotation cp="😀">face | grin</annotation>
// <annotation cp="😀" type="tts">grinning face</annotation>
// from the NEW paths, get the OLD values
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for removeAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); // not frozen, for removeAttribute
boolean isTts = parts.getAttributeValue(-1, "type") != null;
if (isTts) {
parts.removeAttribute(-1, "type");
@@ -558,7 +572,7 @@
continue;
}
if (fullAttributes == null) {
- fullAttributes = new TreeSet<String>();
+ fullAttributes = new TreeSet<>();
} else {
fullAttributes.clear();
}
@@ -710,7 +724,7 @@
writeTable(anchors, file, tablePrinter, title, tsvFile);
}
- private void writeDiffs(Anchors anchors, Relation<PathHeader, String> diffAll) {
+ private void writeDiffs(Relation<PathHeader, String> diffAll) {
TablePrinter tablePrinter = new TablePrinter()
.addColumn("Section", "class='source'", CldrUtility.getDoubleLinkMsg(), "class='source'", true)
.addColumn("Page", "class='source'", CldrUtility.getDoubleLinkMsg(), "class='source'", true)
@@ -725,7 +739,7 @@
.addCell(ph.getPageId())
.addCell(ph.getHeader())
.addCell(ph.getCode())
- .addCell(CollectionUtilities.join(locales, " "))
+ .addCell(Joiner.on(" ").join(locales))
.finishRow();
}
}
@@ -763,9 +777,6 @@
}
}
Level coverageLevel = SUPPLEMENTAL_DATA_INFO.getCoverageLevel(ph.getOriginalPath(), locale);
- if (coverageLevel != Level.BASIC && coverageLevel != Level.CORE) {
- int debug = 0;
- }
String fixedOldValue = oldValue == null ? "▷missing◁" : TransliteratorUtilities.toHTML.transform(oldValue);
String fixedNewValue = currentValue == null ? "▷removed◁" : TransliteratorUtilities.toHTML.transform(currentValue);
@@ -781,18 +792,19 @@
.finishRow();
}
- writeTable(anchors, file, tablePrinter, ENGLISH.getName(file) + " Delta", tsvFile);
+ String title = ENGLISH.getName(file) + " " + chartNameCap;
+ writeTable(anchors, file, tablePrinter, title, tsvFile);
diff.clear();
}
private class ChartDeltaSub extends Chart {
- String title;
- String file;
+ private String title;
+ private String file;
private TablePrinter tablePrinter;
private PrintWriter tsvFile;
- public ChartDeltaSub(String title, String file, TablePrinter tablePrinter, PrintWriter tsvFile) {
+ private ChartDeltaSub(String title, String file, TablePrinter tablePrinter, PrintWriter tsvFile) {
super();
this.title = title;
this.file = file;
@@ -824,8 +836,6 @@
public String getExplanation() {
return "<p>Lists data fields that differ from the last major version (see versions above)."
+ " Inherited differences in locales are suppressed, except where the source locales are different. "
-// + " The collations and metadata still have a raw format."
-// + " The rbnf, segmentations, and annotations are not yet included."
+ "<p>";
}
@@ -841,9 +851,9 @@
chartDeltaSub.writeChart(anchors);
}
- public void writeNonLdmlPlain(Anchors anchors) throws IOException {
- try (PrintWriter tsvFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, DIR_NAME), DIR_NAME + "_supp.tsv");
- PrintWriter tsvCountFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, DIR_NAME), DIR_NAME + "_supp_count.tsv");
+ private void writeNonLdmlPlain(Anchors anchors) throws IOException {
+ try (PrintWriter tsvFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, dirName), dirName + "_supp.tsv");
+ PrintWriter tsvCountFile = FileUtilities.openUTF8Writer(getTsvDir(DIR, dirName), dirName + "_supp_count.tsv");
) {
tsvFile.println("# Section\tPage\tHeader\tCode\tOld\tNew");
@@ -854,8 +864,6 @@
Counter<PathHeader> countSame = new Counter<>();
Counter<PathHeader> countAdded = new Counter<>();
Counter<PathHeader> countDeleted = new Counter<>();
-
-
for (String dir : new File(CLDRPaths.BASE_DIRECTORY + "common/").list()) {
if (DtdType.ldml.directories.contains(dir)
@@ -883,20 +891,22 @@
}
continue;
}
-
+ if (highLevelOnly && !HighLevelPaths.localeIsHighLevel(base)) {
+ continue;
+ }
if (verbose) {
System.out.println(file);
}
- Relation<PathHeader, String> contentsOld = fillData(dirOld.toString() + "/", file);
- Relation<PathHeader, String> contents2 = fillData(dir2.toString() + "/", file);
+ Relation<PathHeader, String> contentsOld = fillData(dirOld.toString() + "/", file, base);
+ Relation<PathHeader, String> contents2 = fillData(dir2.toString() + "/", file, base);
- Set<PathHeader> keys = new TreeSet<PathHeader>(CldrUtility.ifNull(contentsOld.keySet(), Collections.<PathHeader> emptySet()));
+ Set<PathHeader> keys = new TreeSet<>(CldrUtility.ifNull(contentsOld.keySet(), Collections.<PathHeader> emptySet()));
keys.addAll(CldrUtility.ifNull(contents2.keySet(), Collections.<PathHeader> emptySet()));
DtdType dtdType = null;
for (PathHeader key : keys) {
String originalPath = key.getOriginalPath();
- if (originalPath.contains("/paradigmLocales")) {
- int debug = 0;
+ if (highLevelOnly && !HighLevelPaths.pathIsHighLevel(originalPath, base)) {
+ continue;
}
boolean isTransform = originalPath.contains("/tRule");
if (dtdType == null) {
@@ -931,16 +941,12 @@
} else {
Set<String> s1MOld = setOld;
Set<String> s2M1 = set2;
-// Set<String> s1M2 = new LinkedHashSet<>(set1);
-// s1M2.removeAll(set2);
-// Set<String> s2M1 = new LinkedHashSet<>(set2);
-// s2M1.removeAll(set1);
if (s1MOld.isEmpty()) {
- addRow(target, key, "▷missing◁", CollectionUtilities.join(s2M1, ", "));
+ addRow(target, key, "▷missing◁", Joiner.on(", ").join(s2M1));
addChange(parentAndFile, ChangeType.added, s2M1.size());
countAdded.add(key, 1);
} else if (s2M1.isEmpty()) {
- addRow(target, key, CollectionUtilities.join(s1MOld, ", "), "▷removed◁");
+ addRow(target, key, Joiner.on(", ").join(s1MOld), "▷removed◁");
addChange(parentAndFile, ChangeType.deleted, s1MOld.size());
countDeleted.add(key, 1);
} else {
@@ -963,11 +969,9 @@
}
}
}
- // private void writeDiffs(Anchors anchors, String file, String title, Relation<PathHeader, String> bcp) {
-
- writeDiffs(anchors, "bcp47", "¤¤BCP47 Delta", bcp, tsvFile);
- writeDiffs(anchors, "supplemental-data", "¤¤Supplemental Delta", supplemental, tsvFile);
- writeDiffs(anchors, "transforms", "¤¤Transforms Delta", transforms, tsvFile);
+ writeDiffs(anchors, "bcp47", "¤¤BCP47 " + chartNameCap, bcp, tsvFile);
+ writeDiffs(anchors, "supplemental-data", "¤¤Supplemental " + chartNameCap, supplemental, tsvFile);
+ writeDiffs(anchors, "transforms", "¤¤Transforms " + chartNameCap, transforms, tsvFile);
writeCounter(tsvCountFile, "CountSame", countSame);
tsvCountFile.println();
@@ -975,15 +979,15 @@
tsvCountFile.println();
writeCounter(tsvCountFile, "CountDeleted", countDeleted);
- tsvFile.println("# EOF");
- tsvCountFile.println("# EOF");
+ //tsvFile.println("# EOF");
+ //tsvCountFile.println("# EOF");
}
}
private void writeCounter(PrintWriter tsvFile, String title, Counter<PathHeader> countDeleted) {
tsvFile.append("# "
+ title
- + "\tPathHeader\n\n");
+ + "\tSection\tPage\tSubhead\tCode\n\n");
for (R2<Long, PathHeader> entry : countDeleted.getEntrySetSortedByCount(false, null)) {
tsvFile.println(entry.get0() + "\t" + entry.get1());
}
@@ -996,13 +1000,24 @@
target.put(key, oldItem + SEP + newItem);
}
- public Relation<PathHeader, String> fillData(String directory, String file) {
+ /**
+ * Fill in the chart data for the specified file
+ *
+ * @param directory
+ * @param file like "xx.xml" where "xx" may be a locale name
+ * @param fileBase like "xx", same as file without ".xml"
+ * @return the Relation
+ */
+ private Relation<PathHeader, String> fillData(String directory, String file, String fileBase) {
Relation<PathHeader, String> results = Relation.of(new TreeMap<PathHeader, Set<String>>(), TreeSet.class);
List<Pair<String, String>> contents1;
try {
contents1 = XMLFileReader.loadPathValues(directory + file, new ArrayList<Pair<String, String>>(), true);
} catch (Exception e) {
+ /*
+ * This happens with e = ICUException, file = grammaticalFeatures.xml in cldr-36.0
+ */
return results;
}
DtdType dtdType = null;
@@ -1011,24 +1026,40 @@
for (Pair<String, String> s : contents1) {
String path = s.getFirst();
- if (path.contains("/collat")) {
- int debug = 0;
+ if (highLevelOnly && !HighLevelPaths.pathIsHighLevel(path, fileBase /* locale, or not */)) {
+ continue;
}
-
String value = s.getSecond();
if (dtdType == null) {
+ /*
+ * Note: although dtdType and dtdData depend on path, they are the same for all paths
+ * in the same file, so they only need to be set the first time through this loop.
+ *
+ * Note: the current DTD in CLDR_BASE_DIR is supposed to be backward-compatible, that is, to support
+ * paths from all archived versions. Any exception to that rule (e.g., for "grammaticalState") is a bug.
+ */
dtdType = DtdType.fromPath(path);
- dtdData = DtdData.getInstance(dtdType);
+ dtdData = DtdData.getInstance(dtdType, CLDR_BASE_DIR);
}
XPathParts pathPlain = XPathParts.getFrozenInstance(path);
- if (dtdData.isMetadata(pathPlain)) {
+ try {
+ if (dtdData.isMetadata(pathPlain)) {
+ continue;
+ }
+ } catch (NullPointerException e) {
+ /*
+ * TODO: this happens for "grammaticalState" in this path from version 37:
+ * //supplementalData/grammaticalData/grammaticalFeatures[@targets="nominal"][@locales="he"]/grammaticalState[@values="definite indefinite construct"]
+ * Reference: https://unicode-org.atlassian.net/browse/CLDR-13306
+ */
+ System.out.println("Caught NullPointerException in fillData calling isMetadata, path = " + path);
continue;
}
Set<String> pathForValues = dtdData.getRegularizedPaths(pathPlain, extras);
if (pathForValues != null) {
for (String pathForValue : pathForValues) {
PathHeader pathHeader = phf.fromPath(pathForValue);
- Splitter splitter = getValueSplitter(pathPlain);
+ Splitter splitter = DtdData.getValueSplitter(pathPlain);
for (String line : splitter.split(value)) {
// special case # in transforms
if (isComment(pathPlain, line)) {
@@ -1064,11 +1095,7 @@
return false;
}
- public Splitter getValueSplitter(XPathParts pathPlain) {
- return DtdData.getValueSplitter(pathPlain);
- }
-
- public static boolean isComment(XPathParts pathPlain, String line) {
+ private static boolean isComment(XPathParts pathPlain, String line) {
if (pathPlain.contains("transform")) {
if (line.startsWith("#")) {
return true;
@@ -1077,154 +1104,357 @@
return false;
}
-// private static final Set<String> SKIP_ATTRIBUTE = new HashSet<String>(Arrays.asList("references"));
-//
-// private static void checkedPut(Map<String, String> contentsA, String path2, String value) {
-// String old = contentsA.get(path2);
-// if (old != null) {
-// if (old.equals(value)) {
-// return;
-// }
-// value = old + "\n" + value;
-// }
-// contentsA.put(path2, value);
-// }
-//
-// static final ChainedMap.M4<DtdType, String, String, Boolean> FIXED_DISTINGUISHING = ChainedMap.of(
-// new HashMap<DtdType, Object>(),
-// new HashMap<String, Object>(),
-// new HashMap<String, Object>(),
-// Boolean.class);
-//
-// static final ChainedMap.M3<DtdType, String, Boolean> FIXED_ORDERING = ChainedMap.of(
-// new HashMap<DtdType, Object>(),
-// new HashMap<String, Object>(),
-// Boolean.class);
-//
-// static {
-// //<key name="ca" description="Calendar algorithm key" alias="calendar">
-// //<type name="buddhist" description="Thai Buddhist calendar"/>
-// FIXED_DISTINGUISHING.put(DtdType.ldmlBCP47, "key", "alias", false);
-//
-// FIXED_ORDERING.put(DtdType.supplementalData, "substitute", true);
-//
-// //<approvalRequirement votes="20" locales="Cldr:modern" paths="//ldml/numbers/symbols[^/]++/(decimal|group|(plus|minus)Sign)"/>
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "approvalRequirement", "locales", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "approvalRequirement", "paths", true);
-// // approvalRequirement should be ordered, but for our comparison, simpler to override
-//
-// //<coverageVariable key="%acctPattern" value="[@type='accounting']/pattern[@type='standard']"/>
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "coverageVariable", "key", true);
-// FIXED_ORDERING.put(DtdType.supplementalData, "coverageVariable", false);
-//
-// //<coverageLevel inLanguage="%phonebookCollationLanguages" value="minimal" match="localeDisplayNames/types/type[@type='phonebook'][@key='collation']"/>
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "coverageLevel", "inLanguage", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "coverageLevel", "inScript", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "coverageLevel", "inTerritory", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "coverageLevel", "match", true);
-// FIXED_ORDERING.put(DtdType.supplementalData, "coverageLevel", false); // this should be true, but for our comparison, simpler to override
-//
-//// <!ATTLIST dayPeriodRule type NMTOKEN #REQUIRED >
-//// <!ATTLIST dayPeriodRule at NMTOKEN #IMPLIED >
-//// <!ATTLIST dayPeriodRule after NMTOKEN #IMPLIED >
-//// <!ATTLIST dayPeriodRule before NMTOKEN #IMPLIED >
-//// <!ATTLIST dayPeriodRule from NMTOKEN #IMPLIED >
-//// <!ATTLIST dayPeriodRule to NMTOKEN #IMPLIED >
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "type", false);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "at", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "after", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "before", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "from", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "dayPeriodRule", "to", true);
-//
-//// <personList type="neutral" locales="af bn bg da de en et eu fa fil fi gu hu id ja kn ko ml ms no sv sw ta te th tr vi zu" />
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "personList", "type", false);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "personList", "locales", true);
-//
-// // <languageMatch desired="am_*_*" supported="en_GB" percent="90" oneway="true" /> <!-- fix ICU for en_GB -->
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "languageMatch", "desired", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "languageMatch", "supported", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "languageMatch", "oneway", true);
-// FIXED_ORDERING.put(DtdType.supplementalData, "languageMatch", false); // this should be true, but for our comparison, simpler to override
-//
-// // <usesMetazone to="1979-10-25 23:00" from="1977-10-20 23:00" mzone="Europe_Central"/>
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "usesMetazone", "from", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "usesMetazone", "to", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "usesMetazone", "mzone", false);
-//
-//// <!ATTLIST numberingSystem type ( numeric | algorithmic ) #REQUIRED >
-//// <!ATTLIST numberingSystem id NMTOKEN #REQUIRED >
-//// <!ATTLIST numberingSystem radix NMTOKEN #IMPLIED >
-//// <!ATTLIST numberingSystem digits CDATA #IMPLIED >
-//// <!ATTLIST numberingSystem rules CDATA #IMPLIED >
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "numberingSystem", "type", false);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "numberingSystem", "radix", false);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "numberingSystem", "digits", false);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "numberingSystem", "rules", false);
-//
-// FIXED_ORDERING.put(DtdType.supplementalData, "pluralRule", false); // this should be true, but for our comparison, simpler to override
-//
-// //pluralRanges locales
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "pluralRanges", "locales", true);
-//
-// // <pluralRange start="one" end="one" result="one"/>
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "pluralRange", "start", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "pluralRange", "end", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "pluralRange", "result", false);
-//
-//// <territory type="AC" gdp="35200000" literacyPercent="99" population="940"> <!--Ascension Island-->
-//// <languagePopulation type="en" populationPercent="99" references="R1020"/> <!--English-->
-//
-// FIXED_DISTINGUISHING.put(DtdType.ldml, "rbnfrule", "value", false);
-// FIXED_ORDERING.put(DtdType.ldml, "ruleset", false); // this should be true, but for our comparison, simpler to override
-// FIXED_ORDERING.put(DtdType.ldml, "rbnfrule", false); // this should be true, but for our comparison, simpler to override
-//
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "transform", "source", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "transform", "target", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "transform", "direction", true);
-// FIXED_DISTINGUISHING.put(DtdType.supplementalData, "transform", "variant", true);
-// FIXED_ORDERING.put(DtdType.supplementalData, "tRule", false);
-//
-// System.out.println("Current Overrides for Distinguishing");
-// for (R4<DtdType, String, String, Boolean> entry : FIXED_DISTINGUISHING.rows()){
-// DtdData dtdData = DtdData.getInstance(entry.get0());
-// boolean actual = dtdData.isDistinguishing(entry.get1(), entry.get2());
-// boolean fixed = entry.get3();
-// if (actual != fixed) {
-// System.out.println("\tOverride to\t" + entry);
-// } else {
-// System.out.println("\tUnnecessary\t" + entry);
-// }
-// }
-// System.out.println("Current Overrides for Ordering");
-// for (R3<DtdType, String, Boolean> entry : FIXED_ORDERING.rows()){
-// DtdData dtdData = DtdData.getInstance(entry.get0());
-// boolean actual = dtdData.isOrdered(entry.get1());
-// boolean fixed = entry.get2();
-// if (actual != fixed) {
-// System.out.println("\tOverride to\t" + entry);
-// } else {
-// System.out.println("\tUnnecessary\t" + entry);
-// }
-// }
-//
-// // FIXED_ORDERING.freeze(); Add to ChainedMap?
-// }
+ /**
+ * Determine which paths are considered "high-level" paths, i.e.,
+ * paths for which any changes have high potential to cause disruptive "churn".
+ * Whether a path is high-level sometimes depends on the locale or xml file in
+ * which it occurs.
+ * Some paths are high-level regardless of the locale in which they are located.
+ * Other paths are high-level for some locales but not others. For example,
+ * //ldml/localeDisplayNames/languages/language[@type="xx"]
+ * is high level in locale "xx", and maybe "en", but not for all locales.
+ */
+ private static class HighLevelPaths {
+ /**
+ * A set of paths to be treated as "high-level".
+ * These are complete paths to be matched exactly.
+ * (Other paths are recognized by special functions like isHighLevelTerritoryName.)
+ *
+ * The ordering and comments for are based on the design spec.
+ *
+ * Possibilities for improvement: read from file; maybe use RegexLookup;
+ * distinguish these types:
+ * (1) complete paths to be matched exactly;
+ * (2) paths recognized by special functions like isHighLevelTerritoryName
+ * (3) prefixes that could match with startsWith();
+ * (4) RegexLookup or other regex
+ * (5) "starred" paths
+ * Currently we only have type (1) in this array, and all others are of type (2).
+ */
+ final private static Set<String> highLevelPaths = new HashSet<>(Arrays.asList(
+ /*
+ * Core data
+ */
+ "//ldml/characters/exemplarCharacters",
+ "//ldml/numbers/defaultNumberingSystem",
+ "//ldml/numbers/otherNumberingSystems/native",
+ /*
+ * Territory and Language names
+ * Country/Region names (English and Native names) -- see isHighLevelTerritoryName
+ * //ldml/localeDisplayName/territories/territory/...
+ * Language names (English and Native) -- see isHighLevelLangName
+ * //ldml/localeDisplayNames/languages/language/...
+ */
+ /*
+ * Date
+ * Note: "year", "month", etc., below, form a subset (eight) of all possible values for type,
+ * excluding, for example, "fri" and "zone". If we use starred paths, we would need further complication
+ * to filter out "fri", "zone", etc.
+ */
+ "//ldml/dates/fields/field[@type=\"year\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"month\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"week\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"day\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"hour\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"era\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"minute\"]/displayName",
+ "//ldml/dates/fields/field[@type=\"second\"]/displayName",
+ /*
+ * TODO: First day of week: /supplemental.xml firstDay
+ * TODO: First week of year: /supplementalData/weekData/firstDay[not(\@alt)
+ */
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateFormats/dateFormatLength[@type=\"full\"]/dateFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateFormats/dateFormatLength[@type=\"long\"]/dateFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateFormats/dateFormatLength[@type=\"medium\"]/dateFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateFormats/dateFormatLength[@type=\"short\"]/dateFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"MMMEd\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dateTimeFormats/availableFormats/dateFormatItem[@id=\"MEd\"]",
+ /*
+ * Time
+ */
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/timeFormats/timeFormatLength[@type=\"full\"]/timeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/timeFormats/timeFormatLength[@type=\"long\"]/timeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/timeFormats/timeFormatLength[@type=\"medium\"]/timeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/timeFormats/timeFormatLength[@type=\"short\"]/timeFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"am\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"abbreviated\"]/dayPeriod[@type=\"am\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"wide\"]/dayPeriod[@type=\"pm\"]",
+ "//ldml/dates/calendars/calendar[@type=\"gregorian\"]/dayPeriods/dayPeriodContext[@type=\"format\"]/dayPeriodWidth[@type=\"abbreviated\"]/dayPeriod[@type=\"pm\"]",
+ /*
+ * Currency (English and Native) -- see isHighLevelCurrencyName
+ * E.g., //ldml/numbers/currencies/currency[@type=\"KRW\"]/displayName"
+ *
+ * TODO: per design spec, "ISO Currency Code: SupplementalData.xml match <region iso3166>"
+ */
+ /*
+ * Currency Formats
+ * a. Currency thousand separator
+ * TODO: See pt_CV.xml example <numbers><currencies><currency><symbol>
+ * b. Currency decimal separator
+ * TODO: See pt_CV.xml example <numbers><currencies><currency><decimal>
+ * c. Currency Symbol//ldml/numbers/currencies/currency[@type="CNY"]/symbol
+ * d. Currency Symbol Narrow
+ */
+ "//ldml/numbers/currencyFormats[@numberSystem=\"latn\"]/currencyFormatLength/currencyFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/numbers/currencyFormats[@numberSystem=\"arab\"]/currencyFormatLength/currencyFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ /*
+ * Currency symbols
+ */
+ "//ldml/numbers/currencies/currency[@type=\"CNY\"]/symbol",
+ "//ldml/numbers/currencies/currency[@type=\"CNY\"]/symbol[@alt=\"narrow\"]",
+ /*
+ * Number Symbols
+ */
+ "//ldml/numbers/minimumGroupingDigits",
+ "//ldml/numbers/symbols[@numberSystem=\"latn\"]/decimal",
+ "//ldml/numbers/symbols[@numberSystem=\"latn\"]/group",
+ "//ldml/numbers/symbols[@numberSystem=\"arab\"]/decimal",
+ "//ldml/numbers/symbols[@numberSystem=\"arab\"]/group",
+ /*
+ * Number formats
+ */
+ "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength/decimalFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/numbers/percentFormats[@numberSystem=\"latn\"]/percentFormatLength/percentFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/numbers/currencyFormats[@numberSystem=\"latn\"]/currencyFormatLength/currencyFormat[@type=\"accounting\"]/pattern[@type=\"standard\"]",
+ "//ldml/numbers/decimalFormats[@numberSystem=\"arab\"]/decimalFormatLength/decimalFormat[@type=\"standard\"]/pattern[@type=\"standard\"]",
+ "//ldml/numbers/percentFormats[@numberSystem=\"arab\"]/percentFormatLength/percentFormat[@type=\"standard\"]/pattern[@type=\"standard\"]"
+ /*
+ * "Complementary Observations"
+ */
+ /*
+ * Changes to language aliases (supplementalMetaData) -- see isHighLevelLangAlias
+ * E.g., //supplementalData/metadata/alias/languageAlias[@type="aar"]
+ */
+ /*
+ * Changes in the containment graph -- see isHighLevelTerritoryContainment
+ * Data mostly (or entirely?) from M49 standard, thus CLDR has limited control.
+ * Users use the containment graph in a variety of ways.
+ * E.g., //supplementalData/territoryContainment/group[@type="003"][@contains="013 021 029"]
+ */
+ /*
+ * TODO: per design doc, "Format changes: second to none on the disruptiveness scale are changes involving spaces such as SPACE -> NBSP
+ * or NBSP -> Narrow NBSP. Or adding a space somewhere in the format where previously there was none."
+ * TODO: per design doc, "Adding a timezone"
+ * TODO: per design doc, "Changes of symbols or codes that are cross-locale in some way such as the unknown
+ * currency symbol change '???' -> '¤'."
+ * TODO: per design doc, "Change in character properties (not a CLDR but a Unicode change), and here especially
+ * newly adding or removing punctuation. Frequently irritates parsers."
+ */
+ ));
-// private static boolean isFixedDistinguishing(DtdType dtdType, String element, String key) {
-// Boolean override = FIXED_DISTINGUISHING.get(dtdType, element, key);
-// if (override != null) {
-// return override;
-// }
-// return CLDRFile.isDistinguishing(dtdType, element, key);
-// }
-//
-// private static boolean shouldBeOrdered(DtdType dtdType, String element) {
-// Boolean override = FIXED_ORDERING.get(dtdType, element);
-// if (override != null) {
-// return override;
-// }
-// return CLDRFile.isOrdered(element, dtdType);
-// }
+ /**
+ * Should the given path be taken into account for generating "churn" reports?
+ *
+ * @param path the path of interest
+ * @param locale the locale in which the path was found, or null, or possibly
+ * the base file name without extension, like "xx" if the file name is "xx.xml",
+ * where "xx" may or may not be a locale
+ * @return true if it counts, else false to ignore
+ */
+ private static boolean pathIsHighLevel(String path, String locale) {
+ if (path == null || locale == null) {
+ return false;
+ }
+ if (!localeIsHighLevel(locale)) { // this should normally be caught at a higher level
+ System.out.println("locale [" + locale + "] failed localeIsHighLevel in pathIsHighLevel; path = " + path);
+ return false;
+ }
+ if (highLevelPaths.contains(path)) {
+ recordHighLevelMatch(path);
+ return true;
+ } else if (isHighLevelTerritoryName(path, locale)) {
+ if (verboseHighLevelReporting) {
+ recordHighLevelMatch(path);
+ }
+ return true;
+ } else if (isHighLevelLangName(path, locale)) {
+ if (verboseHighLevelReporting) {
+ recordHighLevelMatch(path);
+ }
+ return true;
+ } else if (isHighLevelCurrencyName(path, locale)) {
+ if (verboseHighLevelReporting) {
+ recordHighLevelMatch(path);
+ }
+ return true;
+ } else if (isHighLevelLangAlias(path, locale)) {
+ // if (verboseHighLevelReporting) {
+ recordHighLevelMatch(path);
+ // }
+ return true;
+ } else if (isHighLevelTerritoryContainment(path, locale)) {
+ // if (verboseHighLevelReporting) {
+ recordHighLevelMatch(path);
+ // }
+ return true;
+ }
+ return false;
+ }
+ private static boolean localeIsHighLevel(String locale) {
+ return SubmissionLocales.CLDR_LOCALES.contains(locale);
+ }
+
+ /**
+ * Changes to language aliases (supplementalMetaData)
+ * E.g., //supplementalData/metadata/alias/languageAlias[@type="aar"]
+ *
+ * @param path
+ * @param locale
+ * @return true or false
+ */
+ private static boolean isHighLevelLangAlias(String path, String locale) {
+ // TODO Implement isHighLevelLangAlias
+ return false;
+ }
+
+ /**
+ * Changes in the containment graph -- see isHighLevelTerritoryContainment
+ * Data mostly (or entirely?) from M49 standard, thus CLDR has limited control.
+ * Users use the containment graph in a variety of ways.
+ * E.g., //supplementalData/territoryContainment/group[@type="003"][@contains="013 021 029"]
+ *
+ * @param path
+ * @param locale
+ * @return true or false
+ */
+ private static boolean isHighLevelTerritoryContainment(String path, String locale) {
+ // TODO Implement isHighLevelTerritoryContainment
+ if (path.startsWith("//supplementalData/territoryContainment")) {
+ System.out.println("isHighLevelTerritoryContainment got " + path);
+ }
+ return false;
+ }
+
+ /**
+ * Is the given path a high-level territory name path in the given locale?
+ *
+ * E.g., //ldml/localeDisplayNames/territories/territory[@type="NNN"]
+ * if type "NNN" CORRESPONDS TO the locale or the locale is "en"
+ *
+ * English names (en.xml): match all types
+ * Native: check each territory type NNN corresponding to the given locale
+ *
+ * Exclude "alt"
+ *
+ * @param path
+ * @param locale
+ * @return true or false
+ */
+ private static boolean isHighLevelTerritoryName(String path, String locale) {
+ if (path.startsWith("//ldml/localeDisplayNames/territories/territory")
+ && !path.contains("[@alt=")) {
+ if ("en".equals(locale)) {
+ return true;
+ }
+ CoverageVariableInfo cvi = SUPPLEMENTAL_DATA_INFO.getCoverageVariableInfo(locale);
+ if (cvi != null) {
+ for (String type: cvi.targetTerritories) {
+ if (path.contains("[@type=\"" + type + "\"]")) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is the given path a high-level language name path in the given locale?
+ *
+ * E.g., //ldml/localeDisplayNames/languages/language[@type="xx"]
+ * if type "xx" matches the locale or the locale is "en"
+ *
+ * Exclude "alt"
+ *
+ * @param path
+ * @param locale
+ * @return true or false
+ */
+ private static boolean isHighLevelLangName(String path, String locale) {
+ if (path.startsWith("//ldml/localeDisplayNames/languages/language")
+ && !path.contains("[@alt=")) {
+ if ("en".equals(locale)) {
+ /*
+ * English names (en.xml): match all types
+ */
+ return true;
+ } else if (path.contains("[@type=\"" + locale + "\"]")) {
+ /*
+ * Native names: match the type=”xx” of each xml file to identify the Native. E.g., type=ko if ko.xml
+ */
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is the given path a high-level currency name path in the given locale?
+ *
+ * E.g., //ldml/numbers/currencies/currency[@type=\"AAA\"]/displayName
+ * if type "AAA" CORRESPONDS TO the locale or the locale is "en"
+ *
+ * English names (en.xml): match all types
+ * Native: check each currency type AAA corresponding to the given locale
+ *
+ * Do NOT exclude "alt"; e.g.,
+ * //ldml/numbers/currencies/currency[@type="KRW"]/symbol[@alt="narrow"]
+ *
+ * @param path
+ * @param locale
+ * @return true or false
+ */
+ private static boolean isHighLevelCurrencyName(String path, String locale) {
+ if (path.startsWith("//ldml/numbers/currencies/currency")) {
+ if ("en".equals(locale)) {
+ return true;
+ }
+ CoverageVariableInfo cvi = SUPPLEMENTAL_DATA_INFO.getCoverageVariableInfo(locale);
+ if (cvi != null) {
+ for (String type: cvi.targetCurrencies) {
+ if (path.contains("[@type=\"" + type + "\"]")) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * For debugging, testing
+ */
+ private static Set<String> highLevelPathMatched = null;
+ private static boolean verboseHighLevelReporting = false;
+
+ private static void recordHighLevelMatch(String path) {
+ if (highLevelPathMatched == null) {
+ highLevelPathMatched = new HashSet<>();
+ }
+ highLevelPathMatched.add(path);
+ }
+
+ /**
+ * For debugging, report on any paths in highLevelPaths that never matched
+ */
+ private static void reportHighLevelPathUsage() {
+ if (highLevelPathMatched == null) {
+ System.out.println("Zero high-level paths were matched!");
+ return;
+ }
+ for (String path: highLevelPaths) {
+ if (!highLevelPathMatched.contains(path)) {
+ System.out.println("Unmatched high-level path: " + path);
+ }
+ }
+ if (verboseHighLevelReporting || true) {
+ for (String path: highLevelPathMatched) {
+ if (!highLevelPaths.contains(path)) {
+ System.out.println("Special matched high-level path: " + path);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/tools/java/org/unicode/cldr/tool/ChartDtdDelta.java b/tools/java/org/unicode/cldr/tool/ChartDtdDelta.java
index 2030ff0..31162c6 100644
--- a/tools/java/org/unicode/cldr/tool/ChartDtdDelta.java
+++ b/tools/java/org/unicode/cldr/tool/ChartDtdDelta.java
@@ -11,6 +11,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CldrUtility;
@@ -21,11 +22,12 @@
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.SupplementalDataInfo;
+import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.VersionInfo;
@@ -35,9 +37,14 @@
*/
public class ChartDtdDelta extends Chart {
+ private static final Splitter SPLITTER_SPACE = Splitter.on(' ');
+
private static final String DEPRECATED_PREFIX = "⊖";
private static final String NEW_PREFIX = "+";
+ private static final String ORDERED_SIGN = "⇣";
+ private static final String UNORDERED_SIGN = "⇟";
+
private static final Set<String> OMITTED_ATTRIBUTES = Collections.singleton("⊕");
@@ -63,16 +70,17 @@
+ "<li>Element attributes are abbreviated as ⊕ where is no change to them, "
+ "but the element is newly the child of another.</li>\n"
+ "<li>LDML DTDs have augmented data:\n"
- + "<ul><li>Attribute status is marked by: "
+ + "<ul><li>Attribute status is marked by: "
+ AttributeStatus.distinguished.shortName + "=" + AttributeStatus.distinguished + ", "
+ AttributeStatus.value.shortName + "=" + AttributeStatus.value + ", or "
+ AttributeStatus.metadata.shortName + "=" + AttributeStatus.metadata + ".</li>\n"
+ "<li>Attribute value constraints are marked with ⟨…⟩ (for DTD constraints) and ⟪…⟫ (for augmented constraints, added in v35.0).</li>\n"
- + "<li>Changes in status or constraints are shown with ➠.</li>\n"
+ + "<li>Changes in status or constraints are shown with ➠, with identical sections shown with ….</li>\n"
+ + "<li>Newly ordered elements are indicated with " + ORDERED_SIGN + "; newly unordered with " + UNORDERED_SIGN + ".</li>\n"
+ "</ul></li></ul>\n"
+ "<p>For more information, see the LDML spec.</p>";
}
-
+
@Override
public void writeContents(FormattedFileWriter pw) throws IOException {
TablePrinter tablePrinter = new TablePrinter()
@@ -92,7 +100,7 @@
.setSpanRows(false);
String last = null;
-
+
for (String current : ToolConstants.CLDR_RELEASE_AND_DEV_VERSION_SET) {
System.out.println("DTD delta: " + current);
final boolean finalVersion = current.equals(ToolConstants.DEV_VERSION);
@@ -105,9 +113,9 @@
DtdData dtdCurrent = null;
try {
dtdCurrent = DtdData.getInstance(type,
- finalVersion
- // && ToolConstants.CHART_STATUS != ToolConstants.ChartStatus.release
- ? null
+ finalVersion
+ // && ToolConstants.CHART_STATUS != ToolConstants.ChartStatus.release
+ ? null
: current);
} catch (Exception e) {
if (!(e.getCause() instanceof FileNotFoundException)) {
@@ -173,7 +181,7 @@
static final boolean SHOW = false;
@SuppressWarnings("unused")
- private void checkNames(String version, DtdData dtdCurrent, DtdData dtdLast, Map<String, Element> oldNameToElement, String path, Element element,
+ private void checkNames(String version, DtdData dtdCurrent, DtdData dtdLast, Map<String, Element> oldNameToElement, String path, Element element,
HashSet<Element> seen, boolean showAnyway) {
String name = element.getName();
@@ -204,21 +212,24 @@
Element oldElement = null;
+ boolean ordered = element.isOrdered();
if (!oldNameToElement.containsKey(name)) {
Set<String> attributeNames = getAttributeNames(dtdCurrent, dtdLast, name, Collections.emptyMap(), element.getAttributes());
- addData(dtdCurrent, NEW_PREFIX + name, version, newPath, attributeNames);
+ addData(dtdCurrent, NEW_PREFIX + name + (ordered ? ORDERED_SIGN : ""), version, newPath, attributeNames);
} else {
oldElement = oldNameToElement.get(name);
+ boolean oldOrdered = oldElement.isOrdered();
Set<String> attributeNames = getAttributeNames(dtdCurrent, dtdLast, name, oldElement.getAttributes(), element.getAttributes());
boolean currentDeprecated = element.isDeprecated();
boolean lastDeprecated = dtdLast == null ? false : oldElement.isDeprecated(); // + (currentDeprecated ? "ⓓ" : "")
boolean newlyDeprecated = currentDeprecated && !lastDeprecated;
+ String orderingStatus = (ordered == oldOrdered || currentDeprecated) ? "" : ordered ? ORDERED_SIGN : UNORDERED_SIGN;
if (newlyDeprecated) {
- addData(dtdCurrent, DEPRECATED_PREFIX + name, version, newPath, Collections.emptySet());
+ addData(dtdCurrent, DEPRECATED_PREFIX + name + orderingStatus, version, newPath, Collections.emptySet());
}
if (!attributeNames.isEmpty()) {
- addData(dtdCurrent, (newlyDeprecated ? DEPRECATED_PREFIX : "") + name, version, newPath, attributeNames);
+ addData(dtdCurrent, (newlyDeprecated ? DEPRECATED_PREFIX : "") + name + orderingStatus, version, newPath, attributeNames);
}
}
if (element.getName().equals("coordinateUnit")) {
@@ -262,8 +273,8 @@
}
dtdType = dtdCurrent.dtdType;
this.newPath = fix(newPath);
- this.attributeNames = attributeNames2.isEmpty() ? NONE :
- START_ATTR + CollectionUtilities.join(attributeNames2, END_ATTR + START_ATTR) + END_ATTR;
+ this.attributeNames = attributeNames2.isEmpty() ? NONE :
+ START_ATTR + Joiner.on(END_ATTR + START_ATTR).join(attributeNames2) + END_ATTR;
this.newElement = newElement;
}
@@ -305,7 +316,7 @@
static final Set<String> SKIP_ATTRIBUTES = ImmutableSet.of("references", "standard", "draft", "alt");
- private static Set<String> getAttributeNames(DtdData dtdCurrent, DtdData dtdLast, String elementName,
+ private static Set<String> getAttributeNames(DtdData dtdCurrent, DtdData dtdLast, String elementName,
Map<Attribute, Integer> attributesOld,
Map<Attribute, Integer> attributes) {
Set<String> names = new LinkedHashSet<>();
@@ -313,7 +324,7 @@
int debug = 0;
}
- main:
+ main:
// we want to add a name that is new or that becomes deprecated
for (Attribute attribute : attributes.keySet()) {
String name = attribute.getName();
@@ -326,11 +337,11 @@
// if (isDeprecated(dtdCurrent, elementName, name)) { // SDI.isDeprecated(dtdCurrent, elementName, name, "*")) {
// continue;
// }
- String oldMatch = "?";
+ String oldMatch = "?";
String pre, post;
Attribute attributeOld = attribute.getMatchingName(attributesOld);
if (attributeOld == null) {
- display += " " + AttributeStatus.getShortName(status) + " " + match;
+ display = NEW_PREFIX + name + " " + AttributeStatus.getShortName(status) + " " + match;
} else if (attribute.isDeprecated() && !attributeOld.isDeprecated()) {
display = DEPRECATED_PREFIX + name;
} else {
@@ -340,7 +351,7 @@
boolean matchEquals = match.equals(oldMatch);
if (status != oldStatus) {
pre = AttributeStatus.getShortName(oldStatus);
- post = AttributeStatus.getShortName(status);
+ post = AttributeStatus.getShortName(status);
if (!matchEquals) {
pre += " " + oldMatch;
post += " " + match;
@@ -351,13 +362,45 @@
} else {
continue main; // skip attribute entirely;
}
- display += " " + pre + "➠" + post;
+ display = name + " " + diff(pre, post);
}
names.add(display);
}
return names;
}
+ public static String diff(String pre, String post) {
+ Matcher matcherPre = Attribute.LEAD_TRAIL.matcher(pre);
+ Matcher matcherPost = Attribute.LEAD_TRAIL.matcher(post);
+ if (matcherPre.matches() && matcherPost.matches()) {
+ List<String> preParts = SPLITTER_SPACE.splitToList(matcherPre.group(2));
+ List<String> postParts = SPLITTER_SPACE.splitToList(matcherPost.group(2));
+ pre = matcherPre.group(1) + remove(preParts, postParts) + matcherPre.group(3);
+ post = matcherPost.group(1) + remove(postParts, preParts) + matcherPost.group(3);
+ }
+ return pre + "➠" + post;
+ }
+
+ private static String remove(List<String> main, List<String> toRemove) {
+ List<String> result = new ArrayList<>();
+ boolean removed = false;
+ for (String s : main) {
+ if (toRemove.contains(s)) {
+ removed = true;
+ } else {
+ if (removed) {
+ result.add("…");
+ removed = false;
+ }
+ result.add(s);
+ }
+ }
+ if (removed) {
+ result.add("…");
+ }
+ return Joiner.on(" ").join(result);
+ }
+
// private static boolean isDeprecated(DtdData dtdCurrent, String elementName, String attributeName) {
// try {
// return dtdCurrent.isDeprecated(elementName, attributeName, "*");
diff --git a/tools/java/org/unicode/cldr/tool/ChartGrammaticalForms.java b/tools/java/org/unicode/cldr/tool/ChartGrammaticalForms.java
new file mode 100644
index 0000000..56b900b
--- /dev/null
+++ b/tools/java/org/unicode/cldr/tool/ChartGrammaticalForms.java
@@ -0,0 +1,642 @@
+package org.unicode.cldr.tool;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+
+import org.unicode.cldr.draft.FileUtilities;
+import org.unicode.cldr.tool.FormattedFileWriter.Anchors;
+import org.unicode.cldr.util.CLDRConfig;
+import org.unicode.cldr.util.CLDRFile;
+import org.unicode.cldr.util.CLDRLocale;
+import org.unicode.cldr.util.CLDRPaths;
+import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.FileCopier;
+import org.unicode.cldr.util.GrammarInfo;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
+import org.unicode.cldr.util.ICUServiceBuilder;
+import org.unicode.cldr.util.LanguageTagParser;
+import org.unicode.cldr.util.MapComparator;
+import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.Rational;
+import org.unicode.cldr.util.Rational.FormatStyle;
+import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.SupplementalDataInfo;
+import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
+import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
+import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
+import org.unicode.cldr.util.UnitConverter;
+import org.unicode.cldr.util.UnitConverter.ConversionInfo;
+import org.unicode.cldr.util.UnitConverter.PlaceholderLocation;
+import org.unicode.cldr.util.UnitConverter.UnitId;
+import org.unicode.cldr.util.UnitPathType;
+import org.unicode.cldr.util.Validity;
+
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
+import com.ibm.icu.impl.locale.XCldrStub.ImmutableMap;
+import com.ibm.icu.text.DecimalFormat;
+import com.ibm.icu.text.MessageFormat;
+import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.PluralRules.SampleType;
+import com.ibm.icu.text.RuleBasedCollator;
+import com.ibm.icu.util.Output;
+import com.ibm.icu.util.ULocale;
+
+public class ChartGrammaticalForms extends Chart {
+
+ private static final String MAIN_HEADER = "<h2>Grammatical Forms</h2>";
+ private static final boolean DEBUG = false;
+ private static final String DIR = CLDRPaths.CHART_DIRECTORY + "grammar/";
+ public static final PluralRules ENGLISH_PLURAL_RULES = SDI.getPlurals("en").getPluralRules();
+
+ public static void main(String[] args) {
+ new ChartGrammaticalForms().writeChart(null);
+ }
+
+ @Override
+ public String getDirectory() {
+ return DIR;
+ }
+
+ @Override
+ public String getTitle() {
+ return "Grammatical Forms Charts";
+ }
+
+ @Override
+ public String getFileName() {
+ return "index";
+ }
+
+ @Override
+ public String getExplanation() {
+ return MAIN_HEADER + "<p>In this version a preliminary set of languages have additional grammatical information, as listed below.<p>";
+ }
+
+ @Override
+ public void writeContents(FormattedFileWriter pw) throws IOException {
+ FileCopier.ensureDirectoryExists(DIR);
+ FileCopier.copy(Chart.class, "index.css", DIR);
+ FormattedFileWriter.copyIncludeHtmls(DIR);
+
+ FormattedFileWriter.Anchors anchors = new FormattedFileWriter.Anchors();
+ writeSubcharts(anchors);
+ pw.setIndex("Main Chart Index", "../index.html");
+ pw.write(anchors.toString());
+ }
+
+ static final UnitConverter uc = SDI.getUnitConverter();
+ static final Map<String, Map<Rational, String>> BASE_TO_FACTOR_TO_UNIT;
+ static {
+ Map<String, Map<Rational, String>> _BASE_TO_BEST = new TreeMap<>();
+ ImmutableSet<String> skip = ImmutableSet.of("mile-scandinavian", "100-kilometer", "dunam");
+ Output<String> baseOut = new Output<>();
+ for (String longUnit : Validity.getInstance().getStatusToCodes(LstrType.unit).get(Validity.Status.regular)) {
+ String shortUnit = uc.getShortId(longUnit);
+ System.out.println(shortUnit);
+ if (skip.contains(shortUnit)) {
+ continue;
+ }
+ if ("mile-per-gallon".equals(shortUnit)) {
+ int debug = 0;
+ }
+ //Set<String> systems = uc.getSystems(unit);
+ ConversionInfo info = uc.parseUnitId(shortUnit, baseOut, false);
+ if (info == null) {
+ continue;
+ }
+ Map<Rational, String> factorToUnit = _BASE_TO_BEST.get(baseOut.value);
+ if (factorToUnit == null) {
+ _BASE_TO_BEST.put(baseOut.value, factorToUnit = new TreeMap<>());
+ factorToUnit.put(Rational.ONE, baseOut.value);
+ }
+
+ if (!info.factor.isPowerOfTen()) {
+ continue;
+ }
+
+ String old = factorToUnit.get(info.factor);
+ if (old == null || old.length() > shortUnit.length()) {
+ factorToUnit.put(info.factor, shortUnit);
+ }
+ }
+ BASE_TO_FACTOR_TO_UNIT = CldrUtility.protectCollection(_BASE_TO_BEST);
+ for (Entry<String, Map<Rational, String>> entry : BASE_TO_FACTOR_TO_UNIT.entrySet()) {
+ System.out.println(entry);
+ }
+ }
+
+ class BestUnitForGender implements Comparable<BestUnitForGender> {
+ final boolean durationOrLength; // true is better
+ final boolean metric; // true is better
+ final double distanceFromOne; // zero is better
+ final String quantity;
+ final String shortUnit;
+ public BestUnitForGender(String shortUnit, String quantity, Collection<String> systems, double baseSize) {
+ super();
+ this.shortUnit = shortUnit;
+ this.quantity = quantity;
+ this.durationOrLength = quantity.equals("duration") || quantity.equals("length");
+ this.metric = systems.contains("metric");
+ this.distanceFromOne = Math.abs(Math.log(baseSize));
+ }
+ @Override
+ public int compareTo(BestUnitForGender o) {
+ // negation, because we want the best one first
+ return ComparisonChain.start()
+ .compare(o.durationOrLength, durationOrLength)
+ .compare(o.metric, metric)
+ .compare(quantity, o.quantity)
+ .compare(distanceFromOne, o.distanceFromOne)
+ .compare(shortUnit, o.shortUnit)
+ .result();
+ }
+ @Override
+ public int hashCode() {
+ return shortUnit.hashCode();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return compareTo((BestUnitForGender)obj) == 0;
+ }
+ @Override
+ public String toString() {
+ return shortUnit + "(" + (durationOrLength ? "D" : "") + (metric ? "M" : "") + ":" + quantity + ":" + Math.round(distanceFromOne*10) + ")";
+ }
+ }
+
+ public class TablePrinterWithHeader {
+ final String header;
+ final TablePrinter tablePrinter;
+ public TablePrinterWithHeader(String header, TablePrinter tablePrinter) {
+ this.header = header;
+ this.tablePrinter = tablePrinter;
+ }
+ }
+
+ public void writeSubcharts(Anchors anchors) throws IOException {
+ Set<String> locales = GrammarInfo.SEED_LOCALES;
+
+ LanguageTagParser ltp = new LanguageTagParser();
+ //ImmutableSet<String> casesNominativeOnly = ImmutableSet.of(GrammaticalFeature.grammaticalCase.getDefault(null));
+ Factory factory = CLDRConfig.getInstance().getCldrFactory();
+
+ MapComparator<String> caseOrder = new MapComparator<>(new String[] {
+ "nominative", "vocative", "accusative", "oblique",
+ "genitive", "dative", "locative", "instrumental"});
+ Set<String> sortedCases = new TreeSet<>(caseOrder);
+
+ MapComparator<String> genderOrder = new MapComparator<>(new String[] {
+ "masculine", "inanimate", "animate", "common", "feminine", "neuter"});
+ Set<String> sortedGenders = new TreeSet<>(genderOrder);
+
+ Output<Double> sizeInBaseUnits = new Output<>();
+
+ // collect the "best unit ordering"
+ Map<String, BestUnitForGender> unitToBestUnit = new TreeMap<>();
+ for (String longUnit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ final String shortUnit = uc.getShortId(longUnit);
+ if (shortUnit.equals("generic")) {
+ continue;
+ }
+ String unitCell = getBestBaseUnit(uc, shortUnit, sizeInBaseUnits);
+ String quantity = shortUnit.contentEquals("generic") ? "temperature" : uc.getQuantityFromUnit(shortUnit, false);
+
+ Set<String> systems = uc.getSystems(shortUnit);
+ unitToBestUnit.put(shortUnit, new BestUnitForGender(shortUnit, quantity, systems, sizeInBaseUnits.value));
+ }
+ unitToBestUnit = ImmutableMap.copyOf(unitToBestUnit);
+ // quick check
+ final BestUnitForGender u1 = unitToBestUnit.get("meter");
+ final BestUnitForGender u2 = unitToBestUnit.get("square-centimeter");
+ int comp = u1.compareTo(u2); // should be less
+
+ Set<BestUnitForGender> sorted2 = new TreeSet<>(unitToBestUnit.values());
+ System.out.println(sorted2);
+
+ PlaceholderLocation placeholderPosition = PlaceholderLocation.missing;
+ Matcher placeholderMatcher = UnitConverter.PLACEHOLDER.matcher("");
+ Output<String> unitPatternOut = new Output<>();
+
+ for (String locale : locales) {
+ if (locale.equals("root")) {
+ continue;
+ }
+ ltp.set(locale);
+ String region = ltp.getRegion();
+ if (!region.isEmpty()) {
+ continue;
+ }
+ GrammarInfo grammarInfo = SupplementalDataInfo.getInstance().getGrammarInfo(locale, true);
+ if (grammarInfo == null || !grammarInfo.hasInfo(GrammaticalTarget.nominal)) {
+ continue;
+ }
+ CLDRFile cldrFile = factory.make(locale, true);
+
+ {
+ Collection<String> genders = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+ sortedGenders.clear();
+ sortedGenders.addAll(genders);
+ }
+ {
+ Collection<String> rawCases = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+ if (rawCases.isEmpty()) {
+ rawCases = ImmutableSet.of(GrammaticalFeature.grammaticalCase.getDefault(null));
+ }
+ sortedCases.clear();
+ sortedCases.addAll(rawCases);
+ }
+
+ //Collection<String> nomCases = rawCases.isEmpty() ? casesNominativeOnly : rawCases;
+
+ PluralInfo plurals = SupplementalDataInfo.getInstance().getPlurals(PluralType.cardinal, locale);
+ if (plurals == null) {
+ System.err.println("No " + PluralType.cardinal + " plurals for " + locale);
+ }
+ Collection<Count> adjustedPlurals = plurals.getCounts();
+ ICUServiceBuilder isb = ICUServiceBuilder.forLocale(CLDRLocale.getInstance(locale));
+ DecimalFormat decFormat = isb.getNumberFormat(1);
+
+ Map<String, TablePrinterWithHeader> info = new LinkedHashMap<>();
+
+
+ if (sortedCases.size() > 1) {
+ // set up the table and add the headers
+ TablePrinter caseTablePrinter = new TablePrinter()
+ .addColumn("Unit", "class='source' width='1%'", CldrUtility.getDoubleLinkMsg(), "class='source'", true)
+ .setSortPriority(2)
+ .setRepeatHeader(true)
+ .addColumn("Quantity", "class='source' width='1%'", null, "class='source'", true)
+ .setSortPriority(0)
+ .addColumn("Size", "class='source' width='1%'", null, "class='source'", true)
+ .setSortPriority(1)
+ .setHidden(true)
+ .addColumn("Gender", "class='source' width='1%'", null, "class='source'", true)
+ .addColumn("Case", "class='source' width='1%'", null, "class='source'", true)
+ ;
+ double width = ((int) ((99.0 / (adjustedPlurals.size()*2 + 1)) * 1000)) / 1000.0;
+ String widthStringTarget = "class='target' width='" + width + "%'";
+ final PluralRules pluralRules = plurals.getPluralRules();
+
+ addTwoColumns(caseTablePrinter, widthStringTarget, adjustedPlurals, pluralRules, true);
+
+ // now get the items
+ // also gather info on the "best power units"
+
+ for (String longUnit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ final String shortUnit = uc.getShortId(longUnit);
+ String unitCell = getBestBaseUnit(uc, shortUnit, sizeInBaseUnits);
+ String quantity = shortUnit.contentEquals("generic") ? "temperature" : uc.getQuantityFromUnit(shortUnit, false);
+
+ String gender = UnitPathType.gender.getTrans(cldrFile, "long", shortUnit, null, null, null, null);
+ Set<String> systems = uc.getSystems(shortUnit);
+
+ for (String case1 : sortedCases) { //
+ // start a row, then add the cells in the row.
+ caseTablePrinter
+ .addRow()
+ .addCell(unitCell)
+ .addCell(quantity)
+ .addCell(sizeInBaseUnits.value)
+ .addCell(gender)
+ .addCell(case1);
+
+ for (Count plural : adjustedPlurals) {
+ Double sample = getBestSample(pluralRules, plural);
+
+ // <caseMinimalPairs case="nominative">{0} kostet €3,50.</caseMinimalPairs>
+
+ String unitPattern = cldrFile.getStringValueWithBailey("//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + longUnit + "\"]/unitPattern"
+ + GrammarInfo.getGrammaticalInfoAttributes(grammarInfo, UnitPathType.unit, plural.toString(), null, case1));
+
+ caseTablePrinter.addCell(unitPattern);
+
+ String numberPlusUnit = MessageFormat.format(unitPattern, decFormat.format(sample));
+
+ String caseMinimalPair = cldrFile.getStringValue("//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"" + case1 + "\"]");
+ String withContext = caseMinimalPair == null ? numberPlusUnit : MessageFormat.format(caseMinimalPair, numberPlusUnit);
+
+ caseTablePrinter.addCell(withContext);
+ }
+ // finish the row
+ caseTablePrinter.finishRow();
+ }
+ }
+ info.put("Unit Case Info", new TablePrinterWithHeader(
+ "<p>This table has rows contains unit forms appropriate for different grammatical cases and plural forms. "
+ + "Each plural form has a sample value such as <i>(1.2)</i> or <i>2</i>. "
+ + "That value is used with the localized unit pattern to form a formatted measure, such as “2,0 Stunden”. "
+ + "That formatted measure is in turn substituted into a "
+ + "<b><a target='doc-minimal-pairs' href='http://cldr.unicode.org/translation/grammatical-inflection#TOC-Miscellaneous-Minimal-Pairs'>case minimal pair pattern</a></b>. "
+ + "The <b>Gender</b> column is informative; it just supplies the supplied gender for the unit.</p>\n"
+ + "<ul><li>For clarity, conversion values are supplied for non-metric units. "
+ + "For more information, see <a target='unit_conversions' href='../supplemental/unit_conversions.html'>Unit Conversions</a>.</li>"
+ + "</ul>\n"
+ , caseTablePrinter));
+ }
+
+ if (sortedCases.size() > 1 || sortedGenders.size() > 1) {
+
+ // get best units for gender.
+ Multimap<String, BestUnitForGender> bestUnitForGender = TreeMultimap.create();
+
+ for (String longUnit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ final String shortUnit = uc.getShortId(longUnit);
+ String gender = UnitPathType.gender.getTrans(cldrFile, "long", shortUnit, null, null, null, null);
+ final BestUnitForGender bestUnit = unitToBestUnit.get(shortUnit);
+ if (bestUnit != null) {
+ bestUnitForGender.put(gender, bestUnit);
+ }
+ }
+
+ for (Entry<String, Collection<BestUnitForGender>> entry : bestUnitForGender.asMap().entrySet()) {
+ List<String> items = entry.getValue()
+ .stream()
+ .map(x -> x.shortUnit)
+ .collect(Collectors.toList());
+ System.out.println(locale + "\t" + entry.getKey() + "\t" + items);
+ }
+
+
+ TablePrinter caseTablePrinter = new TablePrinter()
+ .addColumn("Unit", "class='source' width='1%'", CldrUtility.getDoubleLinkMsg(), "class='source'", true)
+ .setSortPriority(2)
+ .setRepeatHeader(true)
+ .addColumn("Case", "class='source' width='1%'", null, "class='source'", true)
+ .addColumn("Gender", "class='source' width='1%'", null, "class='source'", true)
+ ;
+ double width = ((int) ((99.0 / (adjustedPlurals.size()*2 + 1)) * 1000)) / 1000.0;
+ String widthStringTarget = "class='target' width='" + width + "%'";
+ final PluralRules pluralRules = plurals.getPluralRules();
+
+ addTwoColumns(caseTablePrinter, widthStringTarget, adjustedPlurals, pluralRules, false);
+
+ // now get the items
+ for (String power : Arrays.asList("power2", "power3")) {
+ String unitCell = power;
+
+ for (String gender : sortedGenders) {
+ Collection<BestUnitForGender> bestUnits = bestUnitForGender.get(gender);
+ String bestUnit = null;
+ if (!bestUnits.isEmpty()) {
+ bestUnit = bestUnits.iterator().next().shortUnit;
+ }
+
+ for (String case1 : sortedCases) { //
+ // start a row, then add the cells in the row.
+ caseTablePrinter
+ .addRow()
+ .addCell(unitCell)
+ .addCell(case1)
+ .addCell(gender + (bestUnit == null ? "" : "\n(" + bestUnit + ")"))
+ ;
+
+ for (Count plural : adjustedPlurals) {
+ String localizedPowerPattern = UnitPathType.power.getTrans(cldrFile, "long", power, plural.toString(), case1, gender, null);
+ caseTablePrinter.addCell(localizedPowerPattern);
+
+ if (bestUnit == null) {
+ caseTablePrinter.addCell("n/a");
+ } else {
+ Double samplePlural = getBestSample(pluralRules, plural);
+ String localizedUnitPattern = UnitPathType.unit.getTrans(cldrFile, "long", bestUnit, plural.toString(), case1, gender, null);
+ placeholderPosition = UnitConverter.extractUnit(placeholderMatcher, localizedUnitPattern, unitPatternOut);
+ if (placeholderPosition != PlaceholderLocation.middle) {
+ localizedUnitPattern = unitPatternOut.value;
+ String placeholderPattern = placeholderMatcher.group();
+
+ String combined;
+ try {
+ combined = UnitConverter.combineLowercasing(new ULocale(locale), "long", localizedPowerPattern, localizedUnitPattern);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(locale + ") Can't combine "
+ + "localizedPowerPattern=«" + localizedPowerPattern
+ + "» with localizedUnitPattern=«"+ localizedUnitPattern + "»"
+ );
+ }
+ String combinedWithPlaceholder = UnitConverter.addPlaceholder(combined, placeholderPattern, placeholderPosition);
+
+ String sample = MessageFormat.format(combinedWithPlaceholder, decFormat.format(samplePlural));
+
+ String caseMinimalPair = cldrFile.getStringValue("//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"" + case1 + "\"]");
+ String withContext = caseMinimalPair == null ? sample : MessageFormat.format(caseMinimalPair, sample);
+
+ caseTablePrinter.addCell(withContext);
+ }
+ }
+ }
+ // finish the row
+ caseTablePrinter.finishRow();
+ }
+ }
+ }
+ info.put("Unit Power Components", new TablePrinterWithHeader(
+ "<p>This table shows the square (power2) and cubic (power3) patterns, which may vary by case, gender, and plural forms. "
+ + "Each gender is illustrated with a unit where possible, such as <i>(second)</i> or <i>(meter)</i>. "
+ + "Each plural category is illustrated with a unit where possible, such as <i>(1)</i> or <i>(1.2)</i>. "
+ + "The patterns are first supplied, and then combined with the samples and "
+ + "<b><a target='doc-minimal-pairs' href='http://cldr.unicode.org/translation/grammatical-inflection#TOC-Miscellaneous-Minimal-Pairs'>case minimal pair patterns</a></b> "
+ + "in the next <b>Formatted Sample</b> column."
+ + "</p>", caseTablePrinter));
+ }
+
+
+ if (!info.isEmpty()) {
+ String name = ENGLISH.getName(locale);
+ new Subchart(name + ": Unit Grammar Info", locale, info).writeChart(anchors);
+ }
+ }
+ }
+
+ public void addTwoColumns(TablePrinter caseTablePrinter, String widthStringTarget, Collection<Count> adjustedPlurals, final PluralRules pluralRules, boolean spanRows) {
+ for (Count plural : adjustedPlurals) {
+ Double sample = getBestSample(pluralRules, plural);
+ final String pluralHeader = plural.toString() + " (" + sample + ")";
+ caseTablePrinter.addColumn("Form for: " + pluralHeader, widthStringTarget, null, "class='target'", true)
+ .setSpanRows(spanRows);
+ caseTablePrinter.addColumn("Formatted Sample: " + pluralHeader, widthStringTarget, null, "class='target'", true);
+ }
+ }
+
+ static final Map<String, Pair<String, Double>> BEST_UNIT_CACHE = new HashMap<>();
+
+ public static String getBestBaseUnit(UnitConverter uc, final String shortUnit, Output<Double> sizeInBaseUnits) {
+ Pair<String, Double> cached = BEST_UNIT_CACHE.get(shortUnit);
+ if (cached != null) {
+ sizeInBaseUnits.value = cached.getSecond();
+ return cached.getFirst();
+ }
+ if (shortUnit.equals("square-mile")) {
+ int debug = 0;
+ }
+ String unitCell = ENGLISH.getStringValue("//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + uc.getLongId(shortUnit)
+ + "\"]/displayName");
+ Output<String> baseUnit = new Output<>();
+ ConversionInfo info = uc.parseUnitId(shortUnit, baseUnit, false);
+
+ if (info != null) {
+ sizeInBaseUnits.value = info.factor.doubleValue();
+ Map<Rational, String> factorToUnit = BASE_TO_FACTOR_TO_UNIT.get(baseUnit.value);
+ if (factorToUnit == null) {
+ int debug = 0;
+ }
+ String bestUnit = null;
+ Rational bestFactor = null;
+ Rational inputBoundary = Rational.of(2).multiply(info.factor);
+ for (Entry<Rational, String> entry : factorToUnit.entrySet()) {
+ final Rational currentFactor = entry.getKey();
+ if (bestUnit != null && currentFactor.compareTo(inputBoundary) >= 0) {
+ break;
+ }
+ bestFactor = currentFactor;
+ bestUnit = entry.getValue();
+ }
+ bestFactor = info.factor.divide(bestFactor); // scale for bestUnit
+ if (!bestFactor.equals(Rational.ONE) || !shortUnit.equals(bestUnit)) {
+ final String string = bestFactor.toString(FormatStyle.repeating);
+ final double bestDoubleFactor = bestFactor.doubleValue();
+ String pluralCategory = ENGLISH_PLURAL_RULES.select(bestDoubleFactor);
+ final String unitPath = "//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + uc.getLongId(bestUnit)
+ + "\"]/unitPattern[@count=\"" + pluralCategory
+ + "\"]";
+ String unitPattern = ENGLISH.getStringValue(unitPath);
+ if (unitPattern == null) {
+ final UnitId unitId = uc.createUnitId(bestUnit);
+ unitPattern = unitId.toString(ENGLISH, "long", pluralCategory, null, null, false);
+ if (unitPattern == null) {
+ int debug = 0;
+ }
+ }
+ String unitMeasure = MessageFormat.format(unitPattern, string.contains("/") ? "~" + bestDoubleFactor : string);
+ unitCell = shortUnit + "\n( = " + unitMeasure + ")";
+ }
+ } else {
+ sizeInBaseUnits.value = Double.valueOf(-1);
+ }
+ BEST_UNIT_CACHE.put(shortUnit, Pair.of(unitCell, sizeInBaseUnits.value));
+ return unitCell;
+ }
+
+ private Double getBestSample(PluralRules pluralRules, Count plural) {
+ Collection<Double> samples = pluralRules.getSamples(plural.toString());
+ if (samples.isEmpty()) {
+ samples = pluralRules.getSamples(plural.toString(), SampleType.DECIMAL);
+ }
+ int size = samples.size();
+ switch (size) {
+ case 0:
+ throw new IllegalArgumentException("shouldn't happen");
+ case 1:
+ return samples.iterator().next();
+ }
+ return Iterables.skip(samples, 1).iterator().next();
+ }
+
+ private class Subchart extends Chart {
+ String title;
+ String file;
+ private Map<String,TablePrinterWithHeader> tablePrinter;
+
+ @Override
+ public boolean getShowDate() {
+ return false;
+ }
+
+ public Subchart(String title, String file, Map<String, TablePrinterWithHeader> info) {
+ super();
+ this.title = title;
+ this.file = file;
+ this.tablePrinter = info;
+ }
+
+ @Override
+ public String getDirectory() {
+ return DIR;
+ }
+
+ @Override
+ public String getTitle() {
+ return title;
+ }
+
+ @Override
+ public String getFileName() {
+ return file;
+ }
+
+ @Override
+ public String getExplanation() {
+ return MAIN_HEADER
+ + "<p><i>Unit Inflections, Phase 1:</i> The end goal is to add full case and gender support for formatted units. "
+ + "During Phase 1, a limited number of locales and units of measurement are being handled in CLDR v38, "
+ + "so that we can work kinks out of the process before expanding to all units for all locales.</p>\n"
+ + "<p>This chart shows grammatical information available for certain unit and/or power patterns. These patterns are also illustrated with <b>Formatted Samples</b> that combine the patterns with sample numbers and "
+ + "<b><a target='doc-minimal-pairs' href='http://cldr.unicode.org/translation/grammatical-inflection#TOC-Miscellaneous-Minimal-Pairs'>case minimal pair patterns</a></b>. "
+ + "For example, “… für {0} …” is a <i>case minimal pair pattern</i> that requires the placeholder {0} to be in the accusative case in German. By inserting into a minimal pair pattern, "
+ + "it is easier to ensure that the original unit and/or power patterns are correctly inflected. </p>\n"
+ + "<p><b>Notes</b>"
+ + "<ul><li>We don't have the cross-product of minimal pairs for both case and plural forms, "
+ + "so the <i>case minimal pair pattern</i> might not be correct for the row’s plural category, especially in the nominative.</li>"
+ + "<li>Translators often have difficulties with the the minimal pair patterns, "
+ + "since they are <i>transcreations</i> not translations. The Hindi minimal pair patterns for case and gender have been discarded because they were incorrectly translated.</li>"
+ + "<li>We don't expect translators to supply minimal pair patterns that are natural for any kind of placeholder: "
+ + "for example, it is probably not typical to use the vocative with 3.2 meters! So look at the <b>Formatted Samples</b> as an aid for helping to see the context for grammatical inflections, but one that has limitations.</li></ul>"
+ ;
+ }
+
+ @Override
+ public void writeContents(FormattedFileWriter pw) throws IOException {
+ if (tablePrinter.size() > 1) {
+ pw.write("<h2>Table of Contents</h2>\n");
+ pw.append("<ol>\n");
+ for (String header : tablePrinter.keySet()) {
+ pw.write("<li><b>"
+ + "<a href='#" + FileUtilities.anchorize(header)+ "'>" + header + "</a>"
+ + "</b></li>\n");
+ }
+ pw.append("</ol>\n");
+ }
+ for (Entry<String, TablePrinterWithHeader> entry : tablePrinter.entrySet()) {
+ final String header = entry.getKey();
+ pw.write("<h2><a name='" + FileUtilities.anchorize(header)+ "'>" + header + "</a></h2>\n");
+ final TablePrinterWithHeader explanation = entry.getValue();
+ pw.write(explanation.header);
+ pw.write(explanation.tablePrinter.toTable());
+ }
+ }
+ }
+
+ public static RuleBasedCollator RBC;
+ static {
+ Factory cldrFactory = Factory.make(CLDRPaths.COMMON_DIRECTORY + "collation/", ".*");
+ CLDRFile root = cldrFactory.make("root", false);
+ String rules = root.getStringValue("//ldml/collations/collation[@type=\"emoji\"][@visibility=\"external\"]/cr");
+
+// if (!rules.contains("'#⃣'")) {
+// rules = rules.replace("#⃣", "'#⃣'").replace("*⃣", "'*⃣'"); //hack for 8288
+// }
+
+ try {
+ RBC = new RuleBasedCollator(rules);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Failure in rules for " + CLDRPaths.COMMON_DIRECTORY + "collation/" + "root", e);
+ }
+ }
+}
diff --git a/tools/java/org/unicode/cldr/tool/ChartLanguageMatching.java b/tools/java/org/unicode/cldr/tool/ChartLanguageMatching.java
index 5a1ac96..4534c29 100644
--- a/tools/java/org/unicode/cldr/tool/ChartLanguageMatching.java
+++ b/tools/java/org/unicode/cldr/tool/ChartLanguageMatching.java
@@ -5,7 +5,6 @@
import org.unicode.cldr.util.CLDRFile;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row.R4;
public class ChartLanguageMatching extends Chart {
@@ -97,7 +96,7 @@
parts[2] = "XY";
}
}
- String result = ENGLISH.getName(CollectionUtilities.join(parts, "_"), true, CLDRFile.SHORT_ALTS);
+ String result = ENGLISH.getName(String.join("_", parts), true, CLDRFile.SHORT_ALTS);
if (user) {
result = result
.replace("Xxxx", "any-script")
diff --git a/tools/java/org/unicode/cldr/tool/ChartSubdivisionNames.java b/tools/java/org/unicode/cldr/tool/ChartSubdivisionNames.java
index 4beeca1..178c112 100644
--- a/tools/java/org/unicode/cldr/tool/ChartSubdivisionNames.java
+++ b/tools/java/org/unicode/cldr/tool/ChartSubdivisionNames.java
@@ -60,6 +60,7 @@
return MAIN_HEADER + "<p>The charts are presented in groups of related languages, for easier comparison.<p>";
}
+ @Override
public void writeContents(FormattedFileWriter pw) throws IOException {
FileCopier.ensureDirectoryExists(DIR);
FileCopier.copy(Chart.class, "index.css", DIR);
@@ -82,7 +83,7 @@
Set<String> subdivisions = Validity.getInstance().getStatusToCodes(LstrType.subdivision).get(Status.regular);
// set up right order for columns
- Map<String, String> nameToCode = new LinkedHashMap<String, String>();
+ Map<String, String> nameToCode = new LinkedHashMap<>();
Relation<LanguageGroup, R3<Integer, String, String>> groupToNameAndCodeSorted = Relation.of(
new EnumMap<LanguageGroup, Set<R3<Integer, String, String>>>(LanguageGroup.class),
TreeSet.class);
diff --git a/tools/java/org/unicode/cldr/tool/ChartSubdivisions.java b/tools/java/org/unicode/cldr/tool/ChartSubdivisions.java
index ed25074..bbe0f13 100644
--- a/tools/java/org/unicode/cldr/tool/ChartSubdivisions.java
+++ b/tools/java/org/unicode/cldr/tool/ChartSubdivisions.java
@@ -16,7 +16,7 @@
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
@@ -116,7 +116,8 @@
tablePrinter.addRow()
.addCell(ENGLISH.getName(CLDRFile.TERRITORY_NAME, region))
.addCell(region)
- .addCell(regionAliases == null ? "«none»" : "=" + CollectionUtilities.join(regionAliases, ", "))
+ .addCell(regionAliases == null ? "«none»" : "=" + Joiner.on(", ")
+ .join(regionAliases))
//.addCell(type)
.addCell("")
.addCell("")
diff --git a/tools/java/org/unicode/cldr/tool/CheckAnnotations.java b/tools/java/org/unicode/cldr/tool/CheckAnnotations.java
index fa6d882..8bc116e 100644
--- a/tools/java/org/unicode/cldr/tool/CheckAnnotations.java
+++ b/tools/java/org/unicode/cldr/tool/CheckAnnotations.java
@@ -12,7 +12,7 @@
AnnotationSet data = Annotations.getDataSet("en");
CLDRConfig config = CLDRConfig.getInstance();
//UnicodeMap<Annotations> data2 = Annotations.getData("de");
- Set<String> sorted = new TreeSet<String>(config.getCollator());
+ Set<String> sorted = new TreeSet<>(config.getCollator());
int i = 0;
boolean needMore = true;
diff --git a/tools/java/org/unicode/cldr/tool/CheckEnglishCurrencyNames.java b/tools/java/org/unicode/cldr/tool/CheckEnglishCurrencyNames.java
index 7ae8caa..f576601 100644
--- a/tools/java/org/unicode/cldr/tool/CheckEnglishCurrencyNames.java
+++ b/tools/java/org/unicode/cldr/tool/CheckEnglishCurrencyNames.java
@@ -30,7 +30,7 @@
Set<String> currencyCodes = sc.getGoodAvailableCodes("currency");
Relation<String, String> currencyCodesWithDates = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
Relation<String, String> modernCurrencyCodes2territory = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> territoriesWithoutModernCurrencies = new TreeSet<String>(sc.getGoodAvailableCodes("territory"));
+ Set<String> territoriesWithoutModernCurrencies = new TreeSet<>(sc.getGoodAvailableCodes("territory"));
for (String territory : sc.getGoodAvailableCodes("territory")) {
if (supplementalDataInfo.getContained(territory) != null) {
@@ -73,7 +73,7 @@
System.out.println(currency + "\t" + name);
}
}
- Set<String> remainder = new TreeSet<String>();
+ Set<String> remainder = new TreeSet<>();
remainder.addAll(currencyCodes);
remainder.removeAll(currencyCodesWithDates.keySet());
System.out.println("Currencies without Territories: " + remainder);
@@ -96,9 +96,9 @@
}
}
Relation<String, String> currency2symbols = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Map<String, Relation<String, String>> currency2symbol2locales = new TreeMap<String, Relation<String, String>>(); //
+ Map<String, Relation<String, String>> currency2symbol2locales = new TreeMap<>(); //
System.out.format("Raw usage data\n");
- Set<String> noOfficialLanguages = new TreeSet<String>();
+ Set<String> noOfficialLanguages = new TreeSet<>();
for (Entry<String, Set<String>> currencyAndTerritories : modernCurrencyCodes2territory.keyValuesSet()) {
String currency = currencyAndTerritories.getKey();
diff --git a/tools/java/org/unicode/cldr/tool/CheckHtmlFiles.java b/tools/java/org/unicode/cldr/tool/CheckHtmlFiles.java
index 45d70d6..af2ac57 100644
--- a/tools/java/org/unicode/cldr/tool/CheckHtmlFiles.java
+++ b/tools/java/org/unicode/cldr/tool/CheckHtmlFiles.java
@@ -38,14 +38,15 @@
import org.unicode.cldr.util.DtdData.Element;
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.RegexUtilities;
import org.unicode.cldr.util.SimpleHtmlParser;
import org.unicode.cldr.util.SimpleHtmlParser.Type;
import org.unicode.cldr.util.TransliteratorUtilities;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R4;
import com.ibm.icu.text.BreakIterator;
@@ -247,13 +248,13 @@
static Pattern WHITESPACE = PatternCache.get("[\\s]+");
static Pattern BADSECTION = PatternCache.get("^\\s*(\\d+\\s*)?Section\\s*\\d+\\s*[-:]\\s*");
- static final Set<String> FORCEBREAK = new HashSet<String>(Arrays.asList(
+ static final Set<String> FORCEBREAK = new HashSet<>(Arrays.asList(
"table", "div", "blockquote",
"p", "br", "td", "th", "h1", "h2", "h3", "h4", "h5", "li"));
// enum ContentsElements {h1, h2, h3, h4, h5, caption}
- static final Set<String> DO_CONTENTS = new HashSet<String>(Arrays.asList(
+ static final Set<String> DO_CONTENTS = new HashSet<>(Arrays.asList(
"h1", "h2", "h3", "h4", "h5", "caption"));
static class Levels implements Comparable<Levels> {
@@ -354,7 +355,7 @@
static class HeadingInfo {
private Levels levels = new Levels();
private String text = "";
- private Set<String> ids = new LinkedHashSet<String>();
+ private Set<String> ids = new LinkedHashSet<>();
private boolean suppressSection;
private boolean isHeader;
@@ -478,8 +479,8 @@
static class HeadingInfoList {
private static final long serialVersionUID = -6722150173224993960L;
Levels lastBuildLevel;
- private Set<String> errors = new LinkedHashSet<String>();
- Output<Boolean> missingLevel = new Output<Boolean>(false);
+ private Set<String> errors = new LinkedHashSet<>();
+ Output<Boolean> missingLevel = new Output<>(false);
private String fileName;
ArrayList<HeadingInfo> list = new ArrayList<>();
@@ -509,7 +510,7 @@
public void listContents() {
System.out.print("\n\t\t<!-- START Generated TOC: CheckHtmlFiles -->");
- Counter<String> idCounter = new Counter<String>();
+ Counter<String> idCounter = new Counter<>();
int lastLevel = new Levels().getDepth();
String pad = PAD;
@@ -640,12 +641,12 @@
static class Data implements Iterable<String> {
private static final Pattern ELEMENT_ATTLIST = Pattern.compile("<!(ELEMENT|ATTLIST)\\s+(\\S+)[^>]*>");
- List<String> sentences = new ArrayList<String>();
+ List<String> sentences = new ArrayList<>();
M4<String, String, String, Boolean> dtdItems = ChainedMap.of(
new LinkedHashMap<String, Object>(),
new TreeMap<String, Object>(),
new TreeMap<String, Object>(), Boolean.class);
- Counter<String> hashedSentences = new Counter<String>();
+ Counter<String> hashedSentences = new Counter<>();
int count = 0;
int totalErrorCount = 0;
int totalFatalCount = 0;
@@ -671,7 +672,7 @@
if (!sourceDirectory.exists()) {
throw new IllegalArgumentException("Can't find " + sourceDirectory);
}
- String canonicalBase = sourceDirectory.getCanonicalPath();
+ String canonicalBase = PathUtilities.getNormalizedPathString(sourceDirectory);
String FileRegex = canonicalBase + File.separator + regex;
FileRegex = FileRegex.replace("\\", "\\\\");
FileRegex = FileRegex.replace("\\\\.", "\\.");
@@ -731,7 +732,7 @@
// for detecting missing captions
boolean pushedTable = false;
boolean checkCaption = false;
- List<Integer> captionWarnings = new ArrayList<Integer>();
+ List<Integer> captionWarnings = new ArrayList<>();
main: while (true) {
int lineCount = parser.getLineCount();
@@ -879,7 +880,7 @@
}
if (!captionWarnings.isEmpty()) {
System.out.println("WARNING: Missing <caption> on the following lines: "
- + "\n " + CollectionUtilities.join(captionWarnings, ", ")
+ + "\n " + Joiner.on(", ").join(captionWarnings)
+ "\n\tTo fix, add <caption> after the <table>, such as:"
+ "\n\t\t<table>"
+ "\n\t\t\t<caption>Private Use Codes in CLDR</a></caption>"
diff --git a/tools/java/org/unicode/cldr/tool/CheckLangTagBNF.java b/tools/java/org/unicode/cldr/tool/CheckLangTagBNF.java
index 2e9fcf4..59ac6c5 100644
--- a/tools/java/org/unicode/cldr/tool/CheckLangTagBNF.java
+++ b/tools/java/org/unicode/cldr/tool/CheckLangTagBNF.java
@@ -46,7 +46,7 @@
private static final String[] groupNames = { "whole", "lang", "script", "region", "variants", "extensions",
"privateuse",
- "grandfathered", "privateuse", "localeExtensions"
+ "legacy", "privateuse", "localeExtensions"
};
/**
@@ -215,15 +215,6 @@
System.out.println(contents);
- // System.out.println(langTagPattern);
- // System.out.println(cleanedLangTagPattern);
-// StandardCodes sc = StandardCodes.make();
-// Set<String> grandfathered = sc.getAvailableCodes("grandfathered");
- // for (Iterator it = grandfathered.iterator(); it.hasNext();) {
- // System.out.print(it.next() + " | ");
- // }
- // System.out.println();
-
LanguageTagParser ltp = new LanguageTagParser();
SimpleLocaleParser simpleLocaleParser = new SimpleLocaleParser();
boolean expected = true;
@@ -286,7 +277,7 @@
checkStrings("script", ltp.getScript(), slp.getScript());
checkStrings("country", ltp.getRegion(), slp.getCountry());
checkStrings("variants", ltp.getVariants(), slp.getVariants());
- Map<String, String> foo = new LinkedHashMap<String, String>();
+ Map<String, String> foo = new LinkedHashMap<>();
foo.putAll(ltp.getExtensions());
foo.putAll(ltp.getLocaleExtensions());
checkStrings("variants", foo, slp.getExtensions());
@@ -294,7 +285,7 @@
if (ltp.getLanguage().length() != 0)
System.out.println("\tlang: \t" + ltp.getLanguage()
- + (ltp.isGrandfathered() ? " (grandfathered)" : ""));
+ + (ltp.isLegacy() ? " (legacy)" : ""));
if (ltp.getScript().length() != 0) System.out.println("\tscript:\t" + ltp.getScript());
if (ltp.getRegion().length() != 0) System.out.println("\tregion:\t" + ltp.getRegion());
if (ltp.getVariants().size() != 0) System.out.println("\tvariants:\t" + ltp.getVariants());
diff --git a/tools/java/org/unicode/cldr/tool/CldrVersion.java b/tools/java/org/unicode/cldr/tool/CldrVersion.java
index 93b7414..467cf62 100644
--- a/tools/java/org/unicode/cldr/tool/CldrVersion.java
+++ b/tools/java/org/unicode/cldr/tool/CldrVersion.java
@@ -22,20 +22,21 @@
* @author markdavis
*
*/
+// TODO compute the VersionInfo for each at creation time, and stash as field.
public enum CldrVersion {
- unknown,
- v1_1_1, v1_2, v1_3, v1_4_1, v1_5_1, v1_6_1, v1_7_2, v1_8_1, v1_9_1, v2_0_1,
+ unknown,
+ v1_1_1, v1_2, v1_3, v1_4_1, v1_5_1, v1_6_1, v1_7_2, v1_8_1, v1_9_1, v2_0_1,
v21_0, v22_1, v23_1, v24_0, v25_0, v26_0, v27_0, v28_0, v29_0, v30_0, v31_0, v32_0, v33_0, v33_1, v34_0,
- v35_0, v35_1, v36_0,
+ v35_0, v35_1, v36_0, v36_1, v37_0,
trunk;
private final String baseDirectory;
private final String dotName;
private final VersionInfo versionInfo;
-
- /**
+
+ /**
* Get the closest available version (successively dropping lower-significance values)
- * We do this because the archive might contain a dot-dot version
+ * We do this because the archive might contain a dot-dot version
* but have a folder called by the round(er) version number.
*/
public static CldrVersion from(VersionInfo versionInfo) {
@@ -51,22 +52,23 @@
: versionInfo.getMinor() != 0 ? VersionInfo.getInstance(versionInfo.getMajor())
: unknown.versionInfo; // will always terminate with unknown.
}
- };
+ }
public static CldrVersion from(String versionString) {
return valueOf(versionString.charAt(0) < 'A' ? "v" + versionString.replace('.', '_') : versionString);
- };
+ }
public VersionInfo getVersionInfo() {
return versionInfo;
}
+ @Override
public String toString() {
return dotName;
- };
+ }
public String getBaseDirectory() {
return baseDirectory;
}
-
+
public boolean isOlderThan(CldrVersion other) {
return compareTo(other) < 0;
}
@@ -116,8 +118,8 @@
public List<File> getPathsForFactory() {
return ImmutableList.copyOf(versionInfo != null && versionInfo.getMajor() < 27
? new File[] { new File(getBaseDirectory() + "common/main/") }
- : new File[] {
- new File(getBaseDirectory() + "common/main/"),
+ : new File[] {
+ new File(getBaseDirectory() + "common/main/"),
new File(getBaseDirectory() + "common/annotations/") });
}
@@ -164,7 +166,7 @@
LinkedHashSet<VersionInfo> fileMTc = new LinkedHashSet<>(allFileVersions);
fileMTc.removeAll(allTc);
if (!fileMTc.isEmpty()) {
- errorMessages.add("Extra " + CLDRPaths.ARCHIVE_DIRECTORY + " compared to ToolConstants.CLDR_VERSIONS: " + fileMTc);
+ errorMessages.add("Extra folders in " + CLDRPaths.ARCHIVE_DIRECTORY + " compared to ToolConstants.CLDR_VERSIONS: " + fileMTc);
}
}
diff --git a/tools/java/org/unicode/cldr/tool/CollectExemplars.java b/tools/java/org/unicode/cldr/tool/CollectExemplars.java
index d50d4ca..9bce5c4 100644
--- a/tools/java/org/unicode/cldr/tool/CollectExemplars.java
+++ b/tools/java/org/unicode/cldr/tool/CollectExemplars.java
@@ -10,7 +10,7 @@
public class CollectExemplars {
public static void main(String[] args) {
final String stock = "en|ar|de|es|fr|it|ja|ko|nl|pl|ru|th|tr|pt|zh|zh_Hant|bg|ca|cs|da|el|fa|fi|fil|hi|hr|hu|id|lt|lv|ro|sk|sl|sr|sv|uk|vi|he|nb|et|ms|am|bn|gu|is|kn|ml|mr|sw|ta|te|ur|eu|gl|af|zu|en_GB|es_419|pt_PT|fr_CA|zh_HK";
- final HashSet<String> REGION_LOCALES = new HashSet<String>(Arrays.asList(stock.split("\\|")));
+ final HashSet<String> REGION_LOCALES = new HashSet<>(Arrays.asList(stock.split("\\|")));
UnicodeSet target = new UnicodeSet();
add("special", null, new UnicodeSet("[㐀-䶵一-鿌﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩𠀀-𪛖 𪜀-𫜴𫝀-𫠝]"), target);
for (ULocale locale : ULocale.getAvailableLocales()) {
diff --git a/tools/java/org/unicode/cldr/tool/CompareData.java b/tools/java/org/unicode/cldr/tool/CompareData.java
index 6a8bcf6..29864ef 100644
--- a/tools/java/org/unicode/cldr/tool/CompareData.java
+++ b/tools/java/org/unicode/cldr/tool/CompareData.java
@@ -11,6 +11,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.LocaleIDParser;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PrettyPath;
import com.ibm.icu.dev.tool.UOption;
@@ -51,16 +52,16 @@
try {
UOption.parseArgs(args, options);
String sourceDir = options[SOURCEDIR].value + "common/main/";
- System.out.println(new File(sourceDir).getCanonicalPath());
+ System.out.println(PathUtilities.getNormalizedPathString(sourceDir));
String compareDir = options[DESTDIR].value + "common/main/";
- System.out.println(new File(compareDir).getCanonicalPath());
+ System.out.println(PathUtilities.getNormalizedPathString(compareDir));
cldrFactory = Factory.make(sourceDir, options[MATCH].value);
Factory oldFactory = Factory.make(compareDir, options[MATCH].value);
- locales = new TreeSet<String>(cldrFactory.getAvailable());
+ locales = new TreeSet<>(cldrFactory.getAvailable());
new CldrUtility.MatcherFilter(options[MATCH].value).retainAll(locales);
- Set<String> pathsSeen = new HashSet<String>();
+ Set<String> pathsSeen = new HashSet<>();
int newItemsTotal = 0;
int replacementItemsTotal = 0;
int deletedItemsTotal = 0;
@@ -73,9 +74,9 @@
int sameItems = 0;
String locale = it.next();
if (locale.startsWith("supplem") || locale.startsWith("character")) continue;
- CLDRFile file = (CLDRFile) cldrFactory.make(locale, false);
+ CLDRFile file = cldrFactory.make(locale, false);
try {
- CLDRFile oldFile = (CLDRFile) oldFactory.make(locale, false);
+ CLDRFile oldFile = oldFactory.make(locale, false);
pathsSeen.clear();
for (Iterator<String> it2 = file.iterator(); it2.hasNext();) {
String path = it2.next();
@@ -125,4 +126,4 @@
}
return count;
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/CompareEn.java b/tools/java/org/unicode/cldr/tool/CompareEn.java
index 7205429..647a64d 100644
--- a/tools/java/org/unicode/cldr/tool/CompareEn.java
+++ b/tools/java/org/unicode/cldr/tool/CompareEn.java
@@ -16,8 +16,6 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
-import com.ibm.icu.dev.util.CollectionUtilities;
-
public class CompareEn {
enum MyOptions {
@@ -72,11 +70,12 @@
// walk through all the new paths and values to check them.
- Set<String> paths = CollectionUtilities.addAll(en_GB.iterator(), new TreeSet<>());
+ TreeSet<String> paths = new TreeSet<>();
+ en_GB.forEach(paths::add);
for (String path : paths) {
if (path.startsWith("//ldml/identity")) {
- continue;
+ continue;
}
// skip certain paths
if (path.startsWith("//ldml/dates/timeZoneNames/") && path.contains("/short/")) {
@@ -130,8 +129,9 @@
// walk through all the new paths and values to check them.
- Set<String> paths = CollectionUtilities.addAll(en_GB.iterator(), new TreeSet<>());
- paths = CollectionUtilities.addAll(en_001.iterator(), paths);
+ TreeSet<String> paths = new TreeSet<>();
+ en_GB.forEach(paths::add);
+ en_001.forEach(paths::add);
for (String path : paths) {
if (path.startsWith("//ldml/identity")) {
diff --git a/tools/java/org/unicode/cldr/tool/CompareFilesBetweenReleases2.java b/tools/java/org/unicode/cldr/tool/CompareFilesBetweenReleases2.java
index 20d5dbf..ffb32e9 100644
--- a/tools/java/org/unicode/cldr/tool/CompareFilesBetweenReleases2.java
+++ b/tools/java/org/unicode/cldr/tool/CompareFilesBetweenReleases2.java
@@ -2,60 +2,110 @@
import java.io.File;
import java.io.IOException;
+import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
-
-import org.unicode.cldr.util.CLDRPaths;
+import java.util.stream.Collectors;
import com.google.common.collect.ImmutableSet;
+import org.unicode.cldr.util.CLDRPaths;
+import org.unicode.cldr.util.CLDRTool;
+import org.unicode.cldr.util.PathUtilities;
+
+@CLDRTool(alias = "CompareFilesBetweenReleases", description = "Print a report of which files changed since the last release")
public class CompareFilesBetweenReleases2 {
//private static final String STAGING_DIRECTORY = CldrUtility.getPath(CLDRPaths.BASE_DIRECTORY, "../cldr-staging/production");
private static final String RELEASE_DIRECTORY = CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + ToolConstants.LAST_RELEASE_VERSION + "/";
public static void main(String[] args) throws IOException {
- Set<String> staging = getFiles(new File(CLDRPaths.BASE_DIRECTORY));
- Set<String> lastRelease = getFiles(new File(RELEASE_DIRECTORY));
- System.out.println("\nIn trunk, but not last release:\n");
- showDiff(staging, lastRelease);
- System.out.println("\nIn last release, but not trunk:\n");
- showDiff(lastRelease, staging);
+ final File stagingFile = new File(CLDRPaths.BASE_DIRECTORY);
+ final File lastFile = new File(RELEASE_DIRECTORY);
+ System.out.println("Comparing " + lastFile.getAbsolutePath() + " vs " + stagingFile.getAbsolutePath());
+ Set<String> staging = getFiles(stagingFile, SKIP);
+ Set<String> lastRelease = getFiles(lastFile, SKIP);
+
+ // now, check common <-> seed
+ Set<String> stagingCommon = getFiles(new File(stagingFile, "common"), Collections.emptySet());
+ Set<String> stagingSeed = getFiles(new File(stagingFile, "seed"), Collections.emptySet());
+ Set<String> lastCommon = getFiles(new File(lastFile, "common"), Collections.emptySet());
+ Set<String> lastSeed = getFiles(new File(lastFile, "seed"), Collections.emptySet());
+
+ Set<String> seedToCommon = lastSeed.stream()
+ .distinct()
+ .filter(stagingCommon::contains)
+ .map((String s) -> "/common" + s)
+ .collect(Collectors.toCollection(() -> new TreeSet<String>()));
+ Set<String> commonToSeed = lastCommon.stream()
+ .distinct()
+ .filter(stagingSeed::contains)
+ .map((String s) -> "/seed" + s)
+ .collect(Collectors.toCollection(() -> new TreeSet<String>()));
+ // this is like commonToSeed but has /common in it, for exclusion
+ Set<String> commonToSeedExclude = lastCommon.stream()
+ .distinct()
+ .filter(stagingSeed::contains)
+ .map((String s) -> "/common" + s)
+ .collect(Collectors.toCollection(() -> new TreeSet<String>()));
+ if( !seedToCommon.isEmpty() ) {
+ System.out.println("\nMoved from Seed to Common:\n");
+ seedToCommon.forEach((final String f) -> System.out.println(f));
+ }
+ if( !commonToSeed.isEmpty() ) {
+ System.out.println("\nMoved from Common to Seed:\n");
+ commonToSeed.forEach((final String f) -> System.out.println(f));
+ }
+
+ System.out.println("\nIn master, but not "+ToolConstants.LAST_RELEASE_VERSION+":\n");
+ showDiff(staging, lastRelease, seedToCommon);
+ System.out.println("\nIn "+ToolConstants.LAST_RELEASE_VERSION+", but not master:\n");
+ showDiff(lastRelease, staging, commonToSeedExclude);
}
- private static void showDiff(Set<String> staging, Set<String> lastRelease) {
+ private static void showDiff(Set<String> staging, Set<String> lastRelease, Set<String> skip) {
Set<String> staging_release = new LinkedHashSet<>(staging);
staging_release.removeAll(lastRelease);
+ int skippedItems = 0;
for (String file : staging_release) {
+ if(skip.contains(file)) {
+ skippedItems++;
+ continue;
+ }
System.out.println(file);
}
+ if(skippedItems > 0) {
+ System.out.println("(plus " + skippedItems + " skipped item(s) listed above)");
+ }
}
- private static Set<String> getFiles(File base) throws IOException {
+ private static Set<String> getFiles(File base, Set<String> skip) throws IOException {
Set<String> result = new TreeSet<>();
- int baseLen = base.getCanonicalPath().length();
- getFiles(baseLen, base, result);
+ int baseLen = PathUtilities.getNormalizedPathString(base).length();
+ getFiles(baseLen, base, result, skip);
return result;
}
static final Set<String> SKIP = ImmutableSet.of("seed", "exemplars", "docs", "tools");
-
- private static void getFiles(int baseLen, File subdir, Set<String> names) throws IOException {
+
+ private static void getFiles(int baseLen, File subdir, Set<String> names, Set<String> skip) throws IOException {
String name = subdir.getName();
if (subdir.isDirectory()) {
- if (SKIP.contains(name)
+ if (skip.contains(name)
|| name.startsWith(".")) {
return;
}
for (File file : subdir.listFiles()) {
- getFiles(baseLen, file, names);
+ getFiles(baseLen, file, names, skip);
}
+ } else {
+ // Only add files.
+ if (name.startsWith(".")) {
+ return;
+ }
+ String fullName = PathUtilities.getNormalizedPathString(subdir);
+ names.add(fullName.substring(baseLen));
}
- if (name.startsWith(".")) {
- return;
- }
- String fullName = subdir.getCanonicalPath();
- names.add(fullName.substring(baseLen));
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/CompareHanTransliterators.java b/tools/java/org/unicode/cldr/tool/CompareHanTransliterators.java
index d277319..05eacb4 100644
--- a/tools/java/org/unicode/cldr/tool/CompareHanTransliterators.java
+++ b/tools/java/org/unicode/cldr/tool/CompareHanTransliterators.java
@@ -23,7 +23,7 @@
XMLFileReader.CONTENT_HANDLER, false);
UnicodeMap<String> trunk = handler.map;
- handler.map = new UnicodeMap<String>();
+ handler.map = new UnicodeMap<>();
reader.read(CLDRPaths.LAST_RELEASE_DIRECTORY + "/common/transforms/Han-Latin.xml",
XMLFileReader.CONTENT_HANDLER, false);
@@ -45,8 +45,9 @@
}
public static class MyContentHandler extends SimpleHandler {
- UnicodeMap<String> map = new UnicodeMap<String>();
+ UnicodeMap<String> map = new UnicodeMap<>();
+ @Override
public void handlePathValue(String path, String value) {
if (!path.contains("tRule")) return;
int pos = value.indexOf('→');
diff --git a/tools/java/org/unicode/cldr/tool/CompareStockDatetime.java b/tools/java/org/unicode/cldr/tool/CompareStockDatetime.java
index 16e100a..0234f76 100644
--- a/tools/java/org/unicode/cldr/tool/CompareStockDatetime.java
+++ b/tools/java/org/unicode/cldr/tool/CompareStockDatetime.java
@@ -28,7 +28,7 @@
{ "time", "short" },
};
- Map<String, Relation<String, String>> lengthToSkeletonToLocales = new TreeMap<String, Relation<String, String>>();
+ Map<String, Relation<String, String>> lengthToSkeletonToLocales = new TreeMap<>();
// new Relation(new TreeMap(), TreeSet.class);
Set<String> defaultContentLocales = info.getSupplementalDataInfo().getDefaultContentLocales();
diff --git a/tools/java/org/unicode/cldr/tool/ConvertLanguageData.java b/tools/java/org/unicode/cldr/tool/ConvertLanguageData.java
index 550a0b5..15510e6 100644
--- a/tools/java/org/unicode/cldr/tool/ConvertLanguageData.java
+++ b/tools/java/org/unicode/cldr/tool/ConvertLanguageData.java
@@ -54,9 +54,9 @@
import org.unicode.cldr.util.XPathParts;
import org.unicode.cldr.util.XPathParts.Comments;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.google.common.math.DoubleMath;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -81,7 +81,7 @@
private static final boolean ALLOW_SMALL_NUMBERS = true;
static final Comparator<String> GENERAL_COLLATOR = new GeneralCollator();
- static final Comparator<String> INVERSE_GENERAL = new InverseComparator<String>(GENERAL_COLLATOR);
+ static final Comparator<String> INVERSE_GENERAL = new InverseComparator<>(GENERAL_COLLATOR);
private static StandardCodes sc = StandardCodes.make();
@@ -90,8 +90,8 @@
static final int BAD_COUNTRY_NAME = 0, COUNTRY_CODE = 1, COUNTRY_POPULATION = 2, COUNTRY_LITERACY = 3,
COUNTRY_GDP = 4, OFFICIAL_STATUS = 5, BAD_LANGUAGE_NAME = 6, LANGUAGE_CODE = 7, LANGUAGE_POPULATION = 8,
LANGUAGE_LITERACY = 9, COMMENT = 10, NOTES = 11;
- static final Map<String, CodeAndPopulation> languageToMaxCountry = new TreeMap<String, CodeAndPopulation>();
- static final Map<String, CodeAndPopulation> languageToMaxScript = new TreeMap<String, CodeAndPopulation>();
+ static final Map<String, CodeAndPopulation> languageToMaxCountry = new TreeMap<>();
+ static final Map<String, CodeAndPopulation> languageToMaxScript = new TreeMap<>();
private static final double NON_OFFICIAL_WEIGHT = 0.40;
@@ -100,13 +100,13 @@
private static final ImmutableSet<String> scriptAssumedLocales = ImmutableSet.of(
"bm_ML", "ha_GH", "ha_NE", "ha_NG", "kk_KZ", "ks_IN", "ky_KG", "mn_MN", "ms_BN", "ms_MY", "ms_SG", "tk_TM", "tzm_MA", "ug_CN");
- static Set<String> skipLocales = new HashSet<String>(
+ static Set<String> skipLocales = new HashSet<>(
Arrays
.asList(
"sh sh_BA sh_CS sh_YU characters supplementalData supplementalData-old supplementalData-old2 supplementalData-old3 supplementalMetadata root"
.split("\\s")));
- static Map<String, String> defaultContent = new TreeMap<String, String>();
+ static Map<String, String> defaultContent = new TreeMap<>();
static Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
static CLDRFile english = cldrFactory.make("en", true);
@@ -130,13 +130,13 @@
Set<String> cldrParents = getCldrParents(available);
- List<String> failures = new ArrayList<String>();
- Map<String, RowData> localeToRowData = new TreeMap<String, RowData>();
+ List<String> failures = new ArrayList<>();
+ Map<String, RowData> localeToRowData = new TreeMap<>();
Set<RowData> sortedInput = getExcelData(failures, localeToRowData);
// get the locales (including parents)
- Set<String> localesWithData = new TreeSet<String>(localeToRowData.keySet());
+ Set<String> localesWithData = new TreeSet<>(localeToRowData.keySet());
for (String locale : localeToRowData.keySet()) {
while (true) {
String parent = LocaleIDParser.getParent(locale);
@@ -195,7 +195,7 @@
checkBasicData(localeToRowData);
- Set<String> defaultLocaleContent = new TreeSet<String>();
+ Set<String> defaultLocaleContent = new TreeSet<>();
showDefaults(cldrParents, nf, defaultContent, localeToRowData, defaultLocaleContent);
@@ -203,7 +203,7 @@
// certain items are overridden
- List<String> toRemove = new ArrayList<String>();
+ List<String> toRemove = new ArrayList<>();
for (String override : defaultOverrides) {
String replacement = getReplacement(override, defaultLocaleContent);
if (replacement != null) {
@@ -257,7 +257,7 @@
private static void getLanguageScriptSpreadsheet(PrintWriter out) {
out.println("#Lcode\tLanguageName\tStatus\tScode\tScriptName\tReferences");
- Pair<String, String> languageScript = new Pair<String, String>("", "");
+ Pair<String, String> languageScript = new Pair<>("", "");
for (String language : language_status_scripts.keySet()) {
Relation<BasicLanguageData.Type, String> status_scripts = language_status_scripts.get(language);
for (BasicLanguageData.Type status : status_scripts.keySet()) {
@@ -284,7 +284,7 @@
// Relation<String, BasicLanguageData> newLanguageData = new Relation(new TreeMap(), TreeSet.class);
LanguageTagParser ltp = new LanguageTagParser();
- Map<String, Relation<BasicLanguageData.Type, String>> language_status_territories = new TreeMap<String, Relation<BasicLanguageData.Type, String>>();
+ Map<String, Relation<BasicLanguageData.Type, String>> language_status_territories = new TreeMap<>();
//Map<String, Pair<String, String>> languageToBestCountry;
for (RowData rowData : sortedInput) {
if (rowData.countryCode.equals("ZZ")) continue;
@@ -305,11 +305,11 @@
}
}
- Set<String> allLanguages = new TreeSet<String>(language_status_territories.keySet());
+ Set<String> allLanguages = new TreeSet<>(language_status_territories.keySet());
allLanguages.addAll(language_status_scripts.keySet());
// now add all the remaining language-script info
// <language type="sv" scripts="Latn" territories="AX FI SE"/>
- Set<String> warnings = new LinkedHashSet<String>();
+ Set<String> warnings = new LinkedHashSet<>();
Log.println("\t<languageData>");
for (String languageSubtag : allLanguages) {
Relation<BasicLanguageData.Type, String> status_scripts = language_status_scripts.get(languageSubtag);
@@ -323,7 +323,7 @@
oldData = Collections.emptyMap();
}
- EnumMap<BasicLanguageData.Type, BasicLanguageData> newData = new EnumMap<BasicLanguageData.Type, BasicLanguageData>(
+ EnumMap<BasicLanguageData.Type, BasicLanguageData> newData = new EnumMap<>(
BasicLanguageData.Type.class);
for (BasicLanguageData.Type status : BasicLanguageData.Type.values()) {
Set<String> scripts = status_scripts == null ? null : status_scripts.getAll(status);
@@ -401,7 +401,7 @@
private static Map<String, BasicLanguageData.Type> getDataToType(
Collection<BasicLanguageData> collection, boolean script) {
- Map<String, BasicLanguageData.Type> result = new TreeMap<String, BasicLanguageData.Type>();
+ Map<String, BasicLanguageData.Type> result = new TreeMap<>();
for (BasicLanguageData i : collection) {
for (String s : i.getScripts()) {
result.put(s, i.getType());
@@ -422,17 +422,17 @@
}
}
// get primary combinations
- Set<String> primaryCombos = new TreeSet<String>();
- Set<String> basicCombos = new TreeSet<String>();
+ Set<String> primaryCombos = new TreeSet<>();
+ Set<String> basicCombos = new TreeSet<>();
for (String languageSubtag : language2BasicLanguageData.keySet()) {
for (BasicLanguageData item : language2BasicLanguageData.getAll(languageSubtag)) {
- Set<String> scripts = new TreeSet<String>();
+ Set<String> scripts = new TreeSet<>();
scripts.addAll(item.getScripts());
languageToScripts.putAll(StandardCodes.fixLanguageTag(languageSubtag), scripts);
if (scripts.size() == 0) {
scripts.add("Zzzz");
}
- Set<String> territories = new TreeSet<String>();
+ Set<String> territories = new TreeSet<>();
territories.addAll(item.getTerritories());
if (territories.size() == 0) {
territories.add("ZZ");
@@ -453,8 +453,8 @@
}
}
}
- Set<String> populationOver20 = new TreeSet<String>();
- Set<String> population = new TreeSet<String>();
+ Set<String> populationOver20 = new TreeSet<>();
+ Set<String> population = new TreeSet<>();
LanguageTagParser ltp = new LanguageTagParser();
for (String rawLocale : localeToRowData.keySet()) {
ltp.set(rawLocale);
@@ -473,7 +473,7 @@
}
}
}
- Set<String> inBasicButNotPopulation = new TreeSet<String>(primaryCombos);
+ Set<String> inBasicButNotPopulation = new TreeSet<>(primaryCombos);
inBasicButNotPopulation.removeAll(population);
for (String locale : inBasicButNotPopulation) {
@@ -498,7 +498,7 @@
+ "\"");
}
- Set<String> inPopulationButNotBasic = new TreeSet<String>(populationOver20);
+ Set<String> inPopulationButNotBasic = new TreeSet<>(populationOver20);
inPopulationButNotBasic.removeAll(basicCombos);
for (Iterator<String> it = inPopulationButNotBasic.iterator(); it.hasNext();) {
String locale = it.next();
@@ -514,13 +514,13 @@
static class LanguageInfo {
static LanguageInfo INSTANCE = new LanguageInfo();
- Map<String, Set<String>> languageToScripts = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> languageToRegions = new TreeMap<String, Set<String>>();
- Map<String, Comments> languageToComments = new TreeMap<String, Comments>();
+ Map<String, Set<String>> languageToScripts = new TreeMap<>();
+ Map<String, Set<String>> languageToRegions = new TreeMap<>();
+ Map<String, Comments> languageToComments = new TreeMap<>();
- Map<String, Set<String>> languageToScriptsAlt = new TreeMap<String, Set<String>>();
- Map<String, Set<String>> languageToRegionsAlt = new TreeMap<String, Set<String>>();
- Map<String, Comments> languageToCommentsAlt = new TreeMap<String, Comments>();
+ Map<String, Set<String>> languageToScriptsAlt = new TreeMap<>();
+ Map<String, Set<String>> languageToRegionsAlt = new TreeMap<>();
+ Map<String, Comments> languageToCommentsAlt = new TreeMap<>();
private LanguageInfo() {
cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
@@ -535,17 +535,17 @@
List<String> scripts = getAttributeList(x, "scripts");
if (scripts != null) {
if (alt) {
- putAll(languageToScriptsAlt, lang, new LinkedHashSet<String>(scripts));
+ putAll(languageToScriptsAlt, lang, new LinkedHashSet<>(scripts));
} else {
- putAll(languageToScripts, lang, new LinkedHashSet<String>(scripts));
+ putAll(languageToScripts, lang, new LinkedHashSet<>(scripts));
}
}
List<String> regions = getAttributeList(x, "territories");
if (regions != null) {
if (alt) {
- putAll(languageToRegionsAlt, lang, new LinkedHashSet<String>(regions));
+ putAll(languageToRegionsAlt, lang, new LinkedHashSet<>(regions));
} else {
- putAll(languageToRegions, lang, new LinkedHashSet<String>(regions));
+ putAll(languageToRegions, lang, new LinkedHashSet<>(regions));
}
}
}
@@ -594,7 +594,7 @@
private final String badLanguageName;
private final boolean relativeLanguagePopulation;
// String badLanguageCode = "";
- private final static Set<String> doneCountries = new HashSet<String>();
+ private final static Set<String> doneCountries = new HashSet<>();
private final static Set<String> countryCodes = sc.getGoodAvailableCodes("territory");
@@ -779,6 +779,7 @@
return result;
}
+ @Override
public int compareTo(Object o) {
RowData that = (RowData) o;
int result;
@@ -796,6 +797,7 @@
+ "\t" + "writingPopulation";
}
+ @Override
public String toString() {
return countryCode + "\t" + countryPopulation + "\t" + countryGdp
+ "\t" + countryLiteracy
@@ -909,6 +911,7 @@
}
static class RickComparator implements Comparator<RowData> {
+ @Override
public int compare(RowData me, RowData that) {
int result;
if (0 != (result = GENERAL_COLLATOR.compare(me.getCountryName(), that.getCountryName()))) return result;
@@ -1046,10 +1049,10 @@
}
static class References {
- Map<String, Pair<String, String>> Rxxx_to_reference = new TreeMap<String, Pair<String, String>>();
- Map<Pair<String, String>, String> reference_to_Rxxx = new TreeMap<Pair<String, String>, String>();
+ Map<String, Pair<String, String>> Rxxx_to_reference = new TreeMap<>();
+ Map<Pair<String, String>, String> reference_to_Rxxx = new TreeMap<>();
Map<String, Pair<String, String>> Rxxx_to_oldReferences = supplementalData.getReferences();
- Map<Pair<String, String>, String> oldReferences_to_Rxxx = new TreeMap<Pair<String, String>, String>();
+ Map<Pair<String, String>, String> oldReferences_to_Rxxx = new TreeMap<>();
{
for (String Rxxx : Rxxx_to_oldReferences.keySet()) {
oldReferences_to_Rxxx.put(Rxxx_to_oldReferences.get(Rxxx), Rxxx);
@@ -1069,7 +1072,7 @@
if (rawReferenceText == null || rawReferenceText.length() == 0) return "";
Pair<String, String> p;
if (URI.reset(rawReferenceText).matches()) {
- p = new Pair<String, String>(URI.group(1), URI.group(2) == null || URI.group(2).length() == 0 ? "[missing]"
+ p = new Pair<>(URI.group(1), URI.group(2) == null || URI.group(2).length() == 0 ? "[missing]"
: URI.group(2)).freeze();
} else {
p = new Pair<String, String>(null, rawReferenceText).freeze();
@@ -1129,20 +1132,20 @@
Set<String> languages = languagesNeeded; // sc.getGoodAvailableCodes("language");
- Set<String> territories = new TreeSet<String>(sc.getGoodAvailableCodes("territory"));
+ Set<String> territories = new TreeSet<>(sc.getGoodAvailableCodes("territory"));
territories.removeAll(supplementalData.getContainers());
territories.remove("EU");
territories.remove("QO");
- Set<String> countriesNotFound = new TreeSet<String>(territories);
- Set<OfficialStatus> statusFound = new TreeSet<OfficialStatus>();
- Set<String> countriesWithoutOfficial = new TreeSet<String>(territories);
+ Set<String> countriesNotFound = new TreeSet<>(territories);
+ Set<OfficialStatus> statusFound = new TreeSet<>();
+ Set<String> countriesWithoutOfficial = new TreeSet<>(territories);
countriesWithoutOfficial.remove("ZZ");
- Map<String, Row.R2<String, Double>> countryToLargestOfficialLanguage = new HashMap<String, Row.R2<String, Double>>();
+ Map<String, Row.R2<String, Double>> countryToLargestOfficialLanguage = new HashMap<>();
- Set<String> languagesNotFound = new TreeSet<String>(languages);
- Set<RowData> sortedInput = new TreeSet<RowData>();
+ Set<String> languagesNotFound = new TreeSet<>(languages);
+ Set<RowData> sortedInput = new TreeSet<>();
int count = 0;
for (List<String> row : input) {
++count;
@@ -1235,7 +1238,7 @@
"\tReferences" +
"\tNotes");
RickComparator rickSorting = new RickComparator();
- Set<RowData> rickSorted = new TreeSet<RowData>(rickSorting);
+ Set<RowData> rickSorted = new TreeSet<>(rickSorting);
rickSorted.addAll(sortedInput);
for (RowData row : rickSorted) {
@@ -1261,7 +1264,7 @@
private static Set<String> getCldrParents(Set<String> available) {
LanguageTagParser ltp2 = new LanguageTagParser();
- Set<String> cldrParents = new TreeSet<String>();
+ Set<String> cldrParents = new TreeSet<>();
for (String locale : available) {
if (skipLocales.contains(locale)) continue;
try {
@@ -1336,6 +1339,7 @@
}
static Comparator<Iterable> firstElementComparator = new Comparator<Iterable>() {
+ @Override
public int compare(Iterable o1, Iterable o2) {
int result = ((Comparable) o1.iterator().next()).compareTo((o2.iterator().next()));
assert result != 0;
@@ -1354,7 +1358,7 @@
}
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
- Set<String> locales = new TreeSet<String>(cldrFactory.getAvailable());
+ Set<String> locales = new TreeSet<>(cldrFactory.getAvailable());
LocaleIDParser lidp = new LocaleIDParser();
// add all the combinations of language, script, and territory.
@@ -1367,7 +1371,7 @@
}
// adding parents
- Set<String> toAdd = new TreeSet<String>();
+ Set<String> toAdd = new TreeSet<>();
while (true) {
for (String locale : locales) {
String newguy = LocaleIDParser.getParent(locale);
@@ -1384,19 +1388,19 @@
}
// get sets of siblings
- Set<Set<String>> siblingSets = new TreeSet<Set<String>>(firstElementComparator);
- Set<String> needsADoin = new TreeSet<String>(locales);
+ Set<Set<String>> siblingSets = new TreeSet<>(firstElementComparator);
+ Set<String> needsADoin = new TreeSet<>(locales);
- Set<String> deprecatedLanguages = new TreeSet<String>();
+ Set<String> deprecatedLanguages = new TreeSet<>();
deprecatedLanguages.add("sh");
- Set<String> deprecatedRegions = new TreeSet<String>();
+ Set<String> deprecatedRegions = new TreeSet<>();
deprecatedRegions.add("YU");
deprecatedRegions.add("CS");
deprecatedRegions.add("ZZ");
// first find all the language subtags that have scripts, and those we need to skip. Those are aliased-only
- Set<String> skippingItems = new TreeSet<String>();
- Set<String> hasAScript = new TreeSet<String>();
+ Set<String> skippingItems = new TreeSet<>();
+ Set<String> hasAScript = new TreeSet<>();
//Set<LocaleIDParser.Level> languageOnly = EnumSet.of(LocaleIDParser.Level.Language);
for (String locale : locales) {
lidp.set(locale);
@@ -1418,9 +1422,9 @@
}
}
// walk through the locales, getting the ones we care about.
- Map<String, Double> scriptLocaleToLanguageLiteratePopulation = new TreeMap<String, Double>();
+ Map<String, Double> scriptLocaleToLanguageLiteratePopulation = new TreeMap<>();
- for (String locale : new TreeSet<String>(needsADoin)) {
+ for (String locale : new TreeSet<>(needsADoin)) {
if (!needsADoin.contains(locale)) continue;
lidp.set(locale);
Set<Level> level = lidp.getLevels();
@@ -1459,9 +1463,9 @@
}
// walk through the data
- Set<String> skippingSingletons = new TreeSet<String>();
+ Set<String> skippingSingletons = new TreeSet<>();
- Set<String> missingData = new TreeSet<String>();
+ Set<String> missingData = new TreeSet<>();
for (Set<String> siblingSet : siblingSets) {
if (SHOW_OLD_DEFAULT_CONTENTS) System.out.println("** From siblings: " + siblingSet);
@@ -1490,7 +1494,7 @@
}
}
}
- data.add(new Pair<Double, String>(languageLiteratePopulation, locale));
+ data.add(new Pair<>(languageLiteratePopulation, locale));
if (best < languageLiteratePopulation) {
best = languageLiteratePopulation;
bestLocale = locale;
@@ -1644,6 +1648,7 @@
String code = null;
double population = Double.NaN;
+ @Override
public String toString() {
return "{" + code + "," + population + "}";
}
@@ -1657,6 +1662,7 @@
UCA.setNumericCollation(true);
}
+ @Override
public int compare(String s1, String s2) {
if (s1 == null) {
return s2 == null ? 0 : -1;
@@ -1667,7 +1673,7 @@
if (result != 0) return result;
return cpCompare.compare(s1, s2);
}
- };
+ }
public static class InverseComparator<T> implements Comparator<T> {
private Comparator<T> other;
@@ -1680,6 +1686,7 @@
this.other = other;
}
+ @Override
public int compare(T a, T b) {
return other == null
? ((Comparable) b).compareTo(a)
@@ -1687,7 +1694,7 @@
}
}
- static Set<String> languagesNeeded = new TreeSet<String>(
+ static Set<String> languagesNeeded = new TreeSet<>(
Arrays
.asList("ab ba bh bi bo fj fy gd ha ht ik iu ks ku ky lg mi na nb rm sa sd sg si sm sn su tg tk to tw vo yi za lb dv chr syr kha sco gv"
.split("\\s")));
@@ -1711,13 +1718,13 @@
static Relation<String, BasicLanguageData> language2BasicLanguageData = Relation.of(new TreeMap<String, Set<BasicLanguageData>>(), TreeSet.class);
static Map<String, Relation<BasicLanguageData.Type, String>> language_status_scripts;
- static Map<Pair<String, String>, String> language_script_references = new TreeMap<Pair<String, String>, String>();
+ static Map<Pair<String, String>, String> language_script_references = new TreeMap<>();
static final Map<String, Map<String, R2<List<String>, String>>> LOCALE_ALIAS_INFO = SupplementalDataInfo
.getInstance().getLocaleAliasInfo();
static void getLanguage2Scripts(Set<RowData> sortedInput) throws IOException {
- language_status_scripts = new TreeMap<String, Relation<BasicLanguageData.Type, String>>();
+ language_status_scripts = new TreeMap<>();
// // get current scripts
// Relation<String,String> languageToDefaultScript = new Relation(new TreeMap(), TreeSet.class);
@@ -1779,7 +1786,7 @@
if (row.size() > 5) {
String reference = row.get(5);
if (reference != null && reference.length() == 0) {
- language_script_references.put(new Pair<String, String>(language, script), reference);
+ language_script_references.put(new Pair<>(language, script), reference);
}
}
}
@@ -1844,7 +1851,7 @@
}
// check that every living language in the row data has a script
- Set<String> livingLanguagesWithTerritories = new TreeSet<String>();
+ Set<String> livingLanguagesWithTerritories = new TreeSet<>();
for (RowData rowData : sortedInput) {
String language = rowData.languageCode;
if (sc.isModernLanguage(language) && Iso639Data.getSource(language) != Iso639Data.Source.ISO_639_3) {
@@ -1939,7 +1946,7 @@
if (name2 != null) {
String name3 = name2.get("Description");
if (name3 != null) {
- names = new TreeSet<String>();
+ names = new TreeSet<>();
names.add(name3);
}
}
@@ -1953,8 +1960,8 @@
Set<String> fullScriptList = sc.getGoodAvailableCodes("script");
String[] scriptList = parts[2].split("[;,]\\s*");
- Set<String> scripts = new TreeSet<String>();
- Set<String> scriptsAlt = new TreeSet<String>();
+ Set<String> scripts = new TreeSet<>();
+ Set<String> scriptsAlt = new TreeSet<>();
for (String script : scriptList) {
if (script.length() == 0) continue;
boolean alt = false;
@@ -1973,12 +1980,12 @@
}
}
// now territories
- Set<String> territories = new TreeSet<String>();
+ Set<String> territories = new TreeSet<>();
if (parts.length > 4) {
String[] territoryList = parts[4].split("\\s*[;,-]\\s*");
for (String territoryName : territoryList) {
if (territoryName.equals("ISO/DIS 639") || territoryName.equals("3")) continue;
- String territoryCode = CountryCodeConverter.getCodeFromName(territoryName);
+ String territoryCode = CountryCodeConverter.getCodeFromName(territoryName, true);
if (territoryCode == null) {
BadItem.ERROR.show("no name found for territory", "<" + territoryName + ">", languageSubtag);
} else {
@@ -2049,7 +2056,7 @@
private static void showBasicLanguageData(String languageSubtag, Relation<String, String> primaryCombos,
Set<String> suppressEmptyScripts, BasicLanguageData.Type type) {
- Set<String> scriptsWithSameTerritories = new TreeSet<String>();
+ Set<String> scriptsWithSameTerritories = new TreeSet<>();
Set<String> lastTerritories = Collections.emptySet();
for (String script : primaryCombos.keySet()) {
Set<String> territories = primaryCombos.getAll(script);
@@ -2177,7 +2184,7 @@
return "* " + this
+ " *\t" + problem + ":"
+ "\t" + details
- + (row != null && row.size() > 0 ? "\t" + CollectionUtilities.join(row, "\t") : "");
+ + (row != null && row.size() > 0 ? "\t" + Joiner.on("\t").join(row) : "");
}
}
diff --git a/tools/java/org/unicode/cldr/tool/ConvertXTB.java b/tools/java/org/unicode/cldr/tool/ConvertXTB.java
index 2a5c13c..f484529 100644
--- a/tools/java/org/unicode/cldr/tool/ConvertXTB.java
+++ b/tools/java/org/unicode/cldr/tool/ConvertXTB.java
@@ -117,7 +117,7 @@
public XtbInfo(String locale) {
this.locale = locale;
- entries = new ArrayList<XtbEntry>();
+ entries = new ArrayList<>();
}
@Override
@@ -162,7 +162,7 @@
public XtbHandler(Set<String> oldMessages, XtbInfo output) {
daip = new DisplayAndInputProcessor(CLDRLocale.getInstance(output.locale));
currentText = new StringBuffer();
- orphanedMessages = new HashSet<String>();
+ orphanedMessages = new HashSet<>();
this.oldMessages = oldMessages;
this.output = output;
}
@@ -346,7 +346,7 @@
private Set<String> messageIds;
public WsbHandler() {
- messageIds = new HashSet<String>();
+ messageIds = new HashSet<>();
}
@Override
@@ -372,11 +372,11 @@
*/
private String getPlaceholderForName(String xpath, String name) {
if (loadedReverseTagMaps == null) {
- loadedReverseTagMaps = new HashMap<String, Map<String, String>>();
+ loadedReverseTagMaps = new HashMap<>();
}
Map<String, String> map = loadedReverseTagMaps.get(xpath);
if (map == null) {
- map = new HashMap<String, String>();
+ map = new HashMap<>();
loadedReverseTagMaps.put(xpath, map);
Map<String, PlaceholderInfo> tagMap = getTagMap(xpath);
for (Map.Entry<String, PlaceholderInfo> entry : tagMap.entrySet()) {
@@ -495,8 +495,8 @@
for (XtbEntry info : xtbInfo) {
cldrFile.add(info.xpath, info.value);
}
- Map<String, String> options = new HashMap<String, String>();
- List<CheckStatus> possibleErrors = new ArrayList<CheckStatus>();
+ Map<String, String> options = new HashMap<>();
+ List<CheckStatus> possibleErrors = new ArrayList<>();
checkCldr.setCldrFileToCheck(cldrFile, options, possibleErrors);
for (CheckStatus status : possibleErrors) {
System.out.println(locale + "\tLOCALE ERROR\t" + status.getMessage());
diff --git a/tools/java/org/unicode/cldr/tool/CopySubdivisionsIntoMain.java b/tools/java/org/unicode/cldr/tool/CopySubdivisionsIntoMain.java
index 624fb81..03c4111 100644
--- a/tools/java/org/unicode/cldr/tool/CopySubdivisionsIntoMain.java
+++ b/tools/java/org/unicode/cldr/tool/CopySubdivisionsIntoMain.java
@@ -82,7 +82,7 @@
if (true) {
throw new IllegalArgumentException("Should probably discontinue this, leaving translated subdivisions in main");
}
-
+
PathStarrer pathStarrer = new PathStarrer();
for (String localeId : mainFactory.getAvailable()) {
@@ -182,15 +182,15 @@
cldrFile.add(path, name);
System.out.println("Adding " + locale + ": " + path + "\t=«" + name + "»");
}
-
+
if (added) {
// write out new main with extra subdivisions
-
+
String fileName = locale + ".xml";
writeFile(MAIN_TARGET_DIR, fileName, cldrFile);
-
+
// remove from subdivisions file
-
+
CLDRFile sd = subdivisionFactory.make(locale, false).cloneAsThawed();
for (String key : target) {
String path = SubdivisionNames.getPathFromCode(key);
diff --git a/tools/java/org/unicode/cldr/tool/CountItems.java b/tools/java/org/unicode/cldr/tool/CountItems.java
index b1a24c3..5e02094 100644
--- a/tools/java/org/unicode/cldr/tool/CountItems.java
+++ b/tools/java/org/unicode/cldr/tool/CountItems.java
@@ -50,7 +50,8 @@
import org.unicode.cldr.util.XPathParts;
import org.unicode.cldr.util.props.ICUPropertyFactory;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.dev.util.UnicodeMapIterator;
import com.ibm.icu.impl.Relation;
@@ -84,35 +85,36 @@
+ " America/Los_Angeles America/Phoenix America/Denver America/Chicago America/Indianapolis"
+ " America/New_York";
- static final Map<String, String> country_map = CollectionUtilities.asMap(new String[][] {
- { "AQ", "http://www.worldtimezone.com/time-antarctica24.php" },
- { "AR", "http://www.worldtimezone.com/time-south-america24.php" },
- { "AU", "http://www.worldtimezone.com/time-australia24.php" },
- { "BR", "http://www.worldtimezone.com/time-south-america24.php" },
- { "CA", "http://www.worldtimezone.com/time-canada24.php" },
- { "CD", "http://www.worldtimezone.com/time-africa24.php" },
- { "CL", "http://www.worldtimezone.com/time-south-america24.php" },
- { "CN", "http://www.worldtimezone.com/time-cis24.php" },
- { "EC", "http://www.worldtimezone.com/time-south-america24.php" },
- { "ES", "http://www.worldtimezone.com/time-europe24.php" },
- { "FM", "http://www.worldtimezone.com/time-oceania24.php" },
- { "GL", "http://www.worldtimezone.com/index24.php" },
- { "ID", "http://www.worldtimezone.com/time-asia24.php" },
- { "KI", "http://www.worldtimezone.com/time-oceania24.php" },
- { "KZ", "http://www.worldtimezone.com/time-cis24.php" },
- { "MH", "http://www.worldtimezone.com/time-oceania24.php" },
- { "MN", "http://www.worldtimezone.com/time-cis24.php" },
- { "MX", "http://www.worldtimezone.com/index24.php" },
- { "MY", "http://www.worldtimezone.com/time-asia24.php" },
- { "NZ", "http://www.worldtimezone.com/time-oceania24.php" },
- { "PF", "http://www.worldtimezone.com/time-oceania24.php" },
- { "PT", "http://www.worldtimezone.com/time-europe24.php" },
- { "RU", "http://www.worldtimezone.com/time-russia24.php" },
- { "SJ", "http://www.worldtimezone.com/index24.php" },
- { "UA", "http://www.worldtimezone.com/time-cis24.php" },
- { "UM", "http://www.worldtimezone.com/time-oceania24.php" },
- { "US", "http://www.worldtimezone.com/time-usa24.php" },
- { "UZ", "http://www.worldtimezone.com/time-cis24.php" }, });
+ static final ImmutableMap<String, String> country_map = ImmutableMap.<String, String>builder()
+ .put("AQ", "http://www.worldtimezone.com/time-antarctica24.php")
+ .put("AR", "http://www.worldtimezone.com/time-south-america24.php")
+ .put("AU", "http://www.worldtimezone.com/time-australia24.php")
+ .put("BR", "http://www.worldtimezone.com/time-south-america24.php")
+ .put("CA", "http://www.worldtimezone.com/time-canada24.php")
+ .put("CD", "http://www.worldtimezone.com/time-africa24.php")
+ .put("CL", "http://www.worldtimezone.com/time-south-america24.php")
+ .put("CN", "http://www.worldtimezone.com/time-cis24.php")
+ .put("EC", "http://www.worldtimezone.com/time-south-america24.php")
+ .put("ES", "http://www.worldtimezone.com/time-europe24.php")
+ .put("FM", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("GL", "http://www.worldtimezone.com/index24.php")
+ .put("ID", "http://www.worldtimezone.com/time-asia24.php")
+ .put("KI", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("KZ", "http://www.worldtimezone.com/time-cis24.php")
+ .put("MH", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("MN", "http://www.worldtimezone.com/time-cis24.php")
+ .put("MX", "http://www.worldtimezone.com/index24.php")
+ .put("MY", "http://www.worldtimezone.com/time-asia24.php")
+ .put("NZ", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("PF", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("PT", "http://www.worldtimezone.com/time-europe24.php")
+ .put("RU", "http://www.worldtimezone.com/time-russia24.php")
+ .put("SJ", "http://www.worldtimezone.com/index24.php")
+ .put("UA", "http://www.worldtimezone.com/time-cis24.php")
+ .put("UM", "http://www.worldtimezone.com/time-oceania24.php")
+ .put("US", "http://www.worldtimezone.com/time-usa24.php")
+ .put("UZ", "http://www.worldtimezone.com/time-cis24.php")
+ .build();
/**
* Count the data.
@@ -162,7 +164,7 @@
// }
// return a.toString() + " " + b.toString();
// }});
- for (UnicodeMapIterator<String> it = new UnicodeMapIterator<String>(blocks); it
+ for (UnicodeMapIterator<String> it = new UnicodeMapIterator<>(blocks); it
.nextRange();) {
UnicodeSet range = new UnicodeSet(it.codepoint, it.codepointEnd);
boolean hasPat = range.containsSome(patterns);
@@ -206,9 +208,6 @@
Collator spaceCol = Collator.getInstance(new ULocale(locale));
spaceCol.setStrength(Collator.PRIMARY);
out.println(locale + ":\t\u200E" + v + '\u200E');
- // String fixedFull = CollectionUtilities.prettyPrint(exemplars, col, false);
- // System.out.println(" =>\t" + fixedFull);
- // verifyEquality(exemplars, new UnicodeSet(fixedFull));
String fixed = new UnicodeSetPrettyPrinter()
.setOrdering(col != null ? col : Collator.getInstance(ULocale.ROOT))
.setSpaceComparator(spaceCol != null ? spaceCol : ROOT_PRIMARY_COLLATOR)
@@ -240,7 +239,7 @@
public static void generateSupplementalCurrencyItems() {
IsoCurrencyParser isoCurrencyParser = IsoCurrencyParser.getInstance();
Relation<String, Data> codeList = isoCurrencyParser.getCodeList();
- Map<String, String> numericTocurrencyCode = new TreeMap<String, String>();
+ Map<String, String> numericTocurrencyCode = new TreeMap<>();
StringBuffer list = new StringBuffer();
for (Iterator<String> it = codeList.keySet().iterator(); it.hasNext();) {
@@ -310,7 +309,7 @@
// + broken + CldrUtility.LINE_SEPARATOR + "\t\t\t</variable>");
Set<String> isoTextFileCodes = StandardCodes.make().getAvailableCodes(
"currency");
- Set<String> temp = new TreeSet<String>(codeList.keySet());
+ Set<String> temp = new TreeSet<>(codeList.keySet());
temp.removeAll(isoTextFileCodes);
if (temp.size() != 0) {
throw new IllegalArgumentException("Missing from ISO4217.txt file: " + temp);
@@ -335,17 +334,17 @@
writeMetazonePrettyPath();
Map<String, String> old_new = sc.getZoneLinkold_new();
- Map<String, Set<String>> new_old = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> new_old = new TreeMap<>();
for (Iterator<String> it = old_new.keySet().iterator(); it.hasNext();) {
String old = it.next();
String newOne = old_new.get(old);
Set<String> oldSet = new_old.get(newOne);
if (oldSet == null)
- new_old.put(newOne, oldSet = new TreeSet<String>());
+ new_old.put(newOne, oldSet = new TreeSet<>());
oldSet.add(old);
}
- Map<String, String> fullMap = new TreeMap<String, String>(col);
+ Map<String, String> fullMap = new TreeMap<>(col);
for (Iterator<String> it = zone_country.keySet().iterator(); it.hasNext();) {
String zone = it.next();
String defaultName = TimezoneFormatter.getFallbackName(zone);
@@ -363,7 +362,7 @@
System.out.println("\t<timezoneData>");
System.out.println();
- Set<String> multizone = new TreeSet<String>();
+ Set<String> multizone = new TreeSet<>();
for (Iterator<String> it = country_zone.keySet().iterator(); it.hasNext();) {
String country = it.next();
Set<String> zones = country_zone.get(country);
@@ -375,7 +374,7 @@
+ toString(multizone, " ") + "\"" + " tzidVersion=\""
+ sc.getZoneVersion() + "\"" + ">");
- Set<String> orderedSet = new TreeSet<String>(col);
+ Set<String> orderedSet = new TreeSet<>(col);
orderedSet.addAll(zone_country.keySet());
orderedSet.addAll(sc.getDeprecatedZoneIDs());
StringBuffer tzid = new StringBuffer();
@@ -394,7 +393,7 @@
Set<String> aliases = new_old.get(zone);
if (aliases != null) {
- aliases = new TreeSet<String>(aliases);
+ aliases = new TreeSet<>(aliases);
aliases.remove(zone);
}
if (skipUnaliased)
@@ -432,7 +431,7 @@
CLDRConfig testInfo = ToolConfig.getToolInstance();
Map<String, Map<String, String>> map = testInfo.getSupplementalDataInfo().getMetazoneToRegionToZone();
Map zoneToCountry = testInfo.getStandardCodes().getZoneToCounty();
- Set<Pair<String, String>> results = new TreeSet<Pair<String, String>>();
+ Set<Pair<String, String>> results = new TreeSet<>();
Map<String, String> countryToContinent = getCountryToContinent(testInfo.getSupplementalDataInfo(),
testInfo.getEnglish());
@@ -445,7 +444,7 @@
String continent = zone.split("/")[0];
final Object country = zoneToCountry.get(zone);
- results.add(new Pair<String, String>(continent + "\t" + country + "\t" + countryToContinent.get(country)
+ results.add(new Pair<>(continent + "\t" + country + "\t" + countryToContinent.get(country)
+ "\t" + metazone, metazone));
}
for (Pair<String, String> line : results) {
@@ -455,7 +454,7 @@
private static Map<String, String> getCountryToContinent(SupplementalDataInfo supplementalDataInfo, CLDRFile english) {
Relation<String, String> countryToContinent = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> continents = new HashSet<String>(Arrays.asList("002", "019", "142", "150", "009"));
+ Set<String> continents = new HashSet<>(Arrays.asList("002", "019", "142", "150", "009"));
// note: we don't need more than 3 levels
for (String continent : continents) {
final Set<String> subcontinents = supplementalDataInfo.getContained(continent);
@@ -467,7 +466,7 @@
}
}
// convert to map
- Map<String, String> results = new TreeMap<String, String>();
+ Map<String, String> results = new TreeMap<>();
for (String item : countryToContinent.keySet()) {
final Set<String> containees = countryToContinent.getAll(item);
if (containees.size() != 1) {
@@ -481,10 +480,10 @@
private static void writeZonePrettyPath(RuleBasedCollator col, Map<String, String> zone_country,
CLDRFile english) throws IOException {
System.out.println("Writing zonePrettyPath");
- Set<String> masked = new HashSet<String>();
- Map<String, String> zoneNew_Old = new TreeMap<String, String>(col);
+ Set<String> masked = new HashSet<>();
+ Map<String, String> zoneNew_Old = new TreeMap<>(col);
String lastZone = "XXX";
- for (String zone : new TreeSet<String>(zone_country.keySet())) {
+ for (String zone : new TreeSet<>(zone_country.keySet())) {
String[] parts = zone.split("/");
String newPrefix = zone_country.get(zone); // english.getName("tzid", zone_country.get(zone),
// false).replace(' ', '_');
@@ -522,7 +521,7 @@
.println("# First are items that would be masked, and are moved forwards and sorted in reverse order");
Log.println();
//Comparator c;
- Set<String> temp = new TreeSet<String>(new ReverseComparator<Object>(col));
+ Set<String> temp = new TreeSet<>(new ReverseComparator<>(col));
temp.addAll(orderedList);
orderedList = temp;
} else {
@@ -558,6 +557,7 @@
this.other = other;
}
+ @Override
public int compare(T o1, T o2) {
return other.compare(o2, o1);
}
@@ -616,7 +616,7 @@
Set<String> available = Iso639Data.getAvailable();
// <languageAlias type="aju" replacement="jrb"/> <!-- Moroccan Judeo-Arabic ⇒ Judeo-Arabic -->
- Set<String> bad3letter = new HashSet<String>();
+ Set<String> bad3letter = new HashSet<>();
for (String lang : available) {
if (lang.length() != 2) continue;
String target = lang;
@@ -633,7 +633,7 @@
bad3letter.add(alpha3);
String targetAliased;
if (languageAliasInfo.containsKey(target)) {
- targetAliased = CollectionUtilities.join(languageAliasInfo.get(target).get0(), " ");
+ targetAliased = Joiner.on(" ").join(languageAliasInfo.get(target).get0());
} else {
targetAliased = target;
}
@@ -658,7 +658,7 @@
Set<String> encompassed = Iso639Data.getEncompassed();
Set<String> macros = Iso639Data.getMacros();
- Map<String, String> encompassed_macro = new HashMap<String, String>();
+ Map<String, String> encompassed_macro = new HashMap<>();
for (Entry<String, R2<List<String>, String>> typeAndData : languageAliasInfo.entrySet()) {
String type = typeAndData.getKey();
R2<List<String>, String> data = typeAndData.getValue();
@@ -671,7 +671,7 @@
encompassed_macro.put(type, replacement);
}
}
- Set<String> missing = new TreeSet<String>();
+ Set<String> missing = new TreeSet<>();
missing.addAll(macros);
missing.remove("no");
missing.remove("sh");
@@ -710,7 +710,7 @@
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile english = cldrFactory.make("en", true);
- Set<String> territories = new TreeSet<String>();
+ Set<String> territories = new TreeSet<>();
Relation<String, String> containers = supplementalData.getTerritoryToContained();
for (String region : sc.getAvailableCodes("territory")) {
if (containers.containsKey(region)) continue;
@@ -723,11 +723,13 @@
//final Map<String, R2<List<String>, String>> territoryAliasInfo = localeAliasInfo.get("territory");
addRegions(english, territories, "alpha3", "EA,EU,IC".split(","), new Transform<String, String>() {
+ @Override
public String transform(String region) {
return IsoRegionData.get_alpha3(region);
}
});
addRegions(english, territories, "numeric", "AC,CP,DG,EA,EU,IC,TA".split(","), new Transform<String, String>() {
+ @Override
public String transform(String region) {
return IsoRegionData.getNumeric(region);
}
@@ -750,7 +752,7 @@
System.out.println("Mapping equivalences - (Informational only...)");
System.out.println("{ bib , tech , bcp47 }");
- Set<R3<String, String, String>> rows = new TreeSet<R3<String, String, String>>();
+ Set<R3<String, String, String>> rows = new TreeSet<>();
for (String lang : Iso639Data.getAvailable()) {
String bib = Iso639Data.toBiblio3(lang);
String tech = Iso639Data.toAlpha3(lang);
@@ -776,7 +778,7 @@
System.out.println("Code Mappings");
System.out.println("Cut/paste into supplementaData.xml under the line");
System.out.println("<!-- start of data generated with CountItems tool ...");
- List<String> warnings = new ArrayList<String>();
+ List<String> warnings = new ArrayList<>();
territories.add("QO");
territories.add("EU");
// territories.add("MF");
@@ -805,7 +807,7 @@
}
System.out.println(" </codeMappings>");
System.out.println("<!-- end of Code Mappings generated with CountItems tool ...");
- System.out.println(CollectionUtilities.join(warnings, CldrUtility.LINE_SEPARATOR));
+ System.out.println(Joiner.on(CldrUtility.LINE_SEPARATOR).join(warnings));
}
enum VariableType {
@@ -814,10 +816,10 @@
public static Map<String, String> getVariables(VariableType variableType) {
String sep = CldrUtility.LINE_SEPARATOR + "\t\t\t\t";
- Map<String, String> variableSubstitutions = new LinkedHashMap<String, String>();
- for (String type : new String[] { "grandfathered", "territory", "script", "variant" }) {
+ Map<String, String> variableSubstitutions = new LinkedHashMap<>();
+ for (String type : new String[] { "legacy", "territory", "script", "variant" }) {
Set<String> i;
- i = (variableType == VariableType.full || type.equals("grandfathered")) ? sc.getAvailableCodes(type) : sc.getGoodAvailableCodes(type);
+ i = (variableType == VariableType.full || type.equals("legacy")) ? sc.getAvailableCodes(type) : sc.getGoodAvailableCodes(type);
addVariable(variableSubstitutions, type, i, sep);
}
@@ -826,7 +828,7 @@
for (String key : bcp47Keys.keySet()) {
Set<String> keyAliases = aliases.getAll(Row.of(key, ""));
Set<String> rawsubtypes = bcp47Keys.getAll(key);
- TreeSet<String> subtypes = new TreeSet<String>();
+ TreeSet<String> subtypes = new TreeSet<>();
for (String subtype : rawsubtypes) {
Set<String> keySubtypeAliases = aliases.getAll(Row.of(key, subtype));
if (keySubtypeAliases != null) {
@@ -844,7 +846,7 @@
private static void addVariable(Map<String, String> variableSubstitutions, String type, Set<String> sinput,
String sep) {
- TreeSet<String> s = new TreeSet<String>(ROOT_PRIMARY_COLLATOR);
+ TreeSet<String> s = new TreeSet<>(ROOT_PRIMARY_COLLATOR);
s.addAll(sinput);
StringBuffer b = new StringBuffer();
@@ -880,9 +882,9 @@
private static void addRegions(CLDRFile english, Set<String> availableCodes, String codeType, String[] exceptions,
Transform<String, String> trans) {
- Set<String> missingRegions = new TreeSet<String>();
- Set<String> exceptionSet = new HashSet<String>(Arrays.asList(exceptions));
- List<String> duplicateDestroyer = new ArrayList<String>();
+ Set<String> missingRegions = new TreeSet<>();
+ Set<String> exceptionSet = new HashSet<>(Arrays.asList(exceptions));
+ List<String> duplicateDestroyer = new ArrayList<>();
for (String region : availableCodes) {
if (exceptionSet.contains(region)) continue;
@@ -894,7 +896,7 @@
Map<String, R2<List<String>, String>> territoryAliasInfo = supplementalData.getLocaleAliasInfo().get("territory");
String result;
if (territoryAliasInfo.containsKey(region)) {
- result = CollectionUtilities.join(territoryAliasInfo.get(region).get0(), " ");
+ result = Joiner.on(" ").join(territoryAliasInfo.get(region).get0());
} else {
result = region;
}
@@ -961,7 +963,7 @@
.getFullXPath("//ldml/dates/timeZoneNames/singleCountries");
XPathParts parts = XPathParts.getFrozenInstance(temp);
String singleCountriesList = parts.findAttributes("singleCountries").get("list");
- Set<String> singleCountriesSet = new TreeSet<String>(CldrUtility.splitList(singleCountriesList, ' '));
+ Set<String> singleCountriesSet = new TreeSet<>(CldrUtility.splitList(singleCountriesList, ' '));
Map<String, String> zone_countries = StandardCodes.make().getZoneToCounty();
Map<String, Set<String>> countries_zoneSet = StandardCodes.make().getCountryToZoneSet();
@@ -1015,12 +1017,12 @@
int count = 0;
int resolvedCount = 0;
Set<String> locales = cldrFactory.getAvailable();
- Set<String> keys = new HashSet<String>();
- Set<String> values = new HashSet<String>();
- Set<String> fullpaths = new HashSet<String>();
+ Set<String> keys = new HashSet<>();
+ Set<String> values = new HashSet<>();
+ Set<String> fullpaths = new HashSet<>();
Matcher alt = CLDRFile.ALT_PROPOSED_PATTERN.matcher("");
- Set<String> temp = new HashSet<String>();
+ Set<String> temp = new HashSet<>();
for (Iterator<String> it = locales.iterator(); it.hasNext();) {
String locale = it.next();
if (CLDRFile.isSupplementalName(locale))
@@ -1042,7 +1044,7 @@
CLDRFile itemResolved = cldrFactory.make(locale, true);
temp.clear();
- CollectionUtilities.addAll(itemResolved.iterator(), temp);
+ itemResolved.forEach(temp::add);
int resolvedCurrent = temp.size();
System.out.println(locale + "\tPlain:\t" + current + "\tResolved:\t"
diff --git a/tools/java/org/unicode/cldr/tool/CountryCodeConverter.java b/tools/java/org/unicode/cldr/tool/CountryCodeConverter.java
index e8b5da2..e59b772 100644
--- a/tools/java/org/unicode/cldr/tool/CountryCodeConverter.java
+++ b/tools/java/org/unicode/cldr/tool/CountryCodeConverter.java
@@ -20,10 +20,10 @@
private static final boolean SHOW_SKIP = CldrUtility.getProperty("SHOW_SKIP", false);
- private static Map<String, String> nameToCountryCode = new TreeMap<String, String>(new UTF16.StringComparator(true, true, 0));
- private static Set<String> parseErrors = new LinkedHashSet<String>();
+ private static Map<String, String> nameToCountryCode = new TreeMap<>(new UTF16.StringComparator(true, true, 0));
+ private static Set<String> parseErrors = new LinkedHashSet<>();
- public static String getCodeFromName(String display) {
+ public static String getCodeFromName(String display, boolean showMissing) {
String trial = display.trim().toLowerCase(Locale.ENGLISH);
if (trial.startsWith("\"") && trial.endsWith("\"")) {
trial = trial.substring(1, trial.length() - 2);
@@ -44,8 +44,8 @@
// }
}
}
- if (SHOW_SKIP && result == null) {
- System.out.println("Missing code; add to external/alternate_country_names.txt a line like:" +
+ if (result == null && (showMissing || SHOW_SKIP)) {
+ System.err.println("CountryCodeConverter missing code; add to external/alternate_country_names.txt a line like:" +
"\t<code>;\t<name>;\t" + display);
}
return result;
@@ -81,7 +81,7 @@
Set<String> goodAvailableCodes = sc.getGoodAvailableCodes("territory");
for (String country : goodAvailableCodes) {
- String description = (String) sc.getFullData("territory", country).get(0);
+ String description = sc.getFullData("territory", country).get(0);
if (country.equals("057")) continue;
addName(description, country);
}
@@ -97,6 +97,7 @@
this.goodAvailableCodes = goodAvailableCodes;
}
+ @Override
public boolean handle(String line) {
if (line.trim().length() == 0) {
return true; // don't show skips
diff --git a/tools/java/org/unicode/cldr/tool/DeriveScripts.java b/tools/java/org/unicode/cldr/tool/DeriveScripts.java
index fd3ff0f..a6aa0b0 100644
--- a/tools/java/org/unicode/cldr/tool/DeriveScripts.java
+++ b/tools/java/org/unicode/cldr/tool/DeriveScripts.java
@@ -39,8 +39,8 @@
static {
File[] paths = {
-// new File(CLDRPaths.MAIN_DIRECTORY),
-// new File(CLDRPaths.SEED_DIRECTORY),
+// new File(CLDRPaths.MAIN_DIRECTORY),
+// new File(CLDRPaths.SEED_DIRECTORY),
new File(CLDRPaths.EXEMPLARS_DIRECTORY) };
final Factory fullCldrFactory = SimpleFactory.make(paths, ".*");
LikelySubtags ls = new LikelySubtags();
@@ -60,7 +60,7 @@
// if (!suppressValue.equals(likelyScript)) {
// System.out.println("#" + langCode + "\tWarning: likely=" + likelyScript + ", suppress=" + suppressValue);
// } else {
-// System.out.println("#" + langCode + "\tSuppress=Likely: " + suppressValue);
+// System.out.println("#" + langCode + "\tSuppress=Likely: " + suppressValue);
// }
continue;
}
@@ -97,7 +97,13 @@
// continue;
// }
- CLDRFile cldrFile = fullCldrFactory.make(lang, false);
+ CLDRFile cldrFile;
+ try {
+ cldrFile = fullCldrFactory.make(lang, false);
+ } catch(final SimpleFactory.NoSourceDirectoryException nsde) {
+ throw new RuntimeException("Cannot load locale "+ lang+" for " + file
+ + " (canonicalized from " + ltp.getLanguage()+")", nsde);
+ }
UnicodeSet exemplars = cldrFile.getExemplarSet("", WinningChoice.WINNING);
for (String s : exemplars) {
int scriptNum = UScript.getScript(s.codePointAt(0));
diff --git a/tools/java/org/unicode/cldr/tool/DiffCldr.java b/tools/java/org/unicode/cldr/tool/DiffCldr.java
index bfc028d..e0233b4 100644
--- a/tools/java/org/unicode/cldr/tool/DiffCldr.java
+++ b/tools/java/org/unicode/cldr/tool/DiffCldr.java
@@ -25,10 +25,10 @@
import org.unicode.cldr.util.With;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.util.Output;
public class DiffCldr {
@@ -217,6 +217,6 @@
cleanedValues.add(item);
}
}
- return CollectionUtilities.join(DtdData.CR_SPLITTER.split(CollectionUtilities.join(values, " ␍ ")), " ␍ ");
+ return Joiner.on(" ␍ ").join(DtdData.CR_SPLITTER.split(Joiner.on(" ␍ ").join(values)));
}
}
diff --git a/tools/java/org/unicode/cldr/tool/DiffWithParent.java b/tools/java/org/unicode/cldr/tool/DiffWithParent.java
index 4f7beb2..6b1db1f 100644
--- a/tools/java/org/unicode/cldr/tool/DiffWithParent.java
+++ b/tools/java/org/unicode/cldr/tool/DiffWithParent.java
@@ -86,13 +86,13 @@
XPathParts fullParts = XPathParts.getFrozenInstance(fullPath);
String path = CLDRFile.getDistinguishingXPath(fullPath, null);
XPathParts parts = XPathParts.getFrozenInstance(path);
- Set<Pair<String, String>> s = new TreeSet<Pair<String, String>>();
+ Set<Pair<String, String>> s = new TreeSet<>();
for (int i = 0; i < fullParts.size(); ++i) {
for (String key : fullParts.getAttributeKeys(i)) {
- s.add(new Pair<String, String>(key, fullParts.getAttributeValue(i, key)));
+ s.add(new Pair<>(key, fullParts.getAttributeValue(i, key)));
}
for (String key : parts.getAttributeKeys(i)) {
- s.remove(new Pair<String, String>(key, parts.getAttributeValue(i, key)));
+ s.remove(new Pair<>(key, parts.getAttributeValue(i, key)));
}
}
return s.toString();
diff --git a/tools/java/org/unicode/cldr/tool/DumpCoverage.java b/tools/java/org/unicode/cldr/tool/DumpCoverage.java
index 12d5f40..8d88e98 100644
--- a/tools/java/org/unicode/cldr/tool/DumpCoverage.java
+++ b/tools/java/org/unicode/cldr/tool/DumpCoverage.java
@@ -26,7 +26,7 @@
CoverageInfo covInfo = CLDRConfig.getInstance().getCoverageInfo();
for (String lang : languages) {
CLDRFile cf = cldrFactory.makeWithFallback(lang);
- Set<String> paths = new TreeSet<String>();
+ Set<String> paths = new TreeSet<>();
cf.getPaths("//ldml", null, paths);
System.out.println("Dumping coverage for locale --> " + lang);
for (String path : paths) {
diff --git a/tools/java/org/unicode/cldr/tool/ExtractListInfo.java b/tools/java/org/unicode/cldr/tool/ExtractListInfo.java
index ecbb192..23d0e4a 100644
--- a/tools/java/org/unicode/cldr/tool/ExtractListInfo.java
+++ b/tools/java/org/unicode/cldr/tool/ExtractListInfo.java
@@ -17,7 +17,7 @@
public static void main(String[] args) {
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
- Set<String> skipped = new LinkedHashSet<String>();
+ Set<String> skipped = new LinkedHashSet<>();
for (String locale : cldrFactory.getAvailableLanguages()) {
CLDRFile file = cldrFactory.make(locale, true);
StringBuilder sb = new StringBuilder("ListFormat.add(\"" + locale + "\"");
diff --git a/tools/java/org/unicode/cldr/tool/ExtractMessages.java b/tools/java/org/unicode/cldr/tool/ExtractMessages.java
index 296943d..ea2efc5 100644
--- a/tools/java/org/unicode/cldr/tool/ExtractMessages.java
+++ b/tools/java/org/unicode/cldr/tool/ExtractMessages.java
@@ -17,6 +17,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StandardCodes;
@@ -45,7 +46,7 @@
double startTime = System.currentTimeMillis();
output = FileUtilities.openUTF8Writer(DIR, "additions.txt");
int totalCount = 0;
- Set<String> skipped = new TreeSet<String>();
+ Set<String> skipped = new TreeSet<>();
try {
String sourceDirectory = getProperty("SOURCE", null);
@@ -70,7 +71,7 @@
continue;
if (file.length() == 0)
continue;
- String canonicalFile = file.getCanonicalPath();
+ String canonicalFile = PathUtilities.getNormalizedPathString(file);
if (!canonicalFile.endsWith(".xtb")) {
continue;
}
@@ -159,13 +160,14 @@
return fileRegex;
}
- private static Map<String, Pair<String, DataHandler>> numericId_Id = new TreeMap<String, Pair<String, DataHandler>>();
+ private static Map<String, Pair<String, DataHandler>> numericId_Id = new TreeMap<>();
private static Matcher numericIdMatcher = PatternCache.get("\\[@id=\"([^\"]+)\"\\]").matcher("");
private static Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
private static CLDRFile english = cldrFactory.make("en", true);
private static class EnglishHandler extends XMLFileReader.SimpleHandler {
+ @Override
public void handlePathValue(String path, String value) {
for (DataHandler handler : dataHandlers) {
if (handler.matches(path)) {
@@ -180,7 +182,7 @@
handler.missing.add(value);
return;
}
- numericId_Id.put(id, new Pair<String, DataHandler>(realID, handler));
+ numericId_Id.put(id, new Pair<>(realID, handler));
// System.out.println(id + "\t" + path + "\t" + value);
}
}
@@ -200,6 +202,7 @@
CLDRFile cldrFile;
boolean usesLatin;
+ @Override
public void handlePathValue(String path, String value) {
// //messagebundle/msg[@id="1907015897505457162"][@seq="71982"][@desc="Andorra is a display name for a timezone"][@xml:space="default"]
value = value.trim();
@@ -305,7 +308,7 @@
enum Type {
LANGUAGE, REGION, CURRENCY, MONTH, MONTHSHORT, DAY, DAYSHORT, TIMEZONE
- };
+ }
static StandardCodes sc = StandardCodes.make();
static DateFormatSymbols dfs = new DateFormatSymbols(ULocale.ENGLISH);
@@ -329,13 +332,13 @@
// mostly stable
private Matcher matcher;
private Type type;
- private Map<String, String> name_code = new TreeMap<String, String>();
+ private Map<String, String> name_code = new TreeMap<>();
// private Map<String,String> code_name = new TreeMap();
- private Set<String> missing = new TreeSet<String>();
+ private Set<String> missing = new TreeSet<>();
// changes with each locale, must call reset
private Relation<String, String> id_to_value = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- private Map<String, String> id_to_cldrValue = new TreeMap<String, String>();
+ private Map<String, String> id_to_cldrValue = new TreeMap<>();
private CasingAction forceCasing = CasingAction.NONE;
public void reset(CLDRFile cldrFile) {
@@ -651,6 +654,7 @@
return name_code.get(value);
}
+ @Override
public int compareTo(DataHandler o) {
throw new IllegalArgumentException();
}
diff --git a/tools/java/org/unicode/cldr/tool/FallbackIterator.java b/tools/java/org/unicode/cldr/tool/FallbackIterator.java
index 28204f4..134ec3d 100644
--- a/tools/java/org/unicode/cldr/tool/FallbackIterator.java
+++ b/tools/java/org/unicode/cldr/tool/FallbackIterator.java
@@ -24,7 +24,7 @@
public FallbackRule(String string) {
String[] data = string.split(";");
boolean first = true;
- List<String> strings = new ArrayList<String>();
+ List<String> strings = new ArrayList<>();
for (String datum : data) {
if (first) {
matcher = PatternCache.get(datum).matcher("");
@@ -42,7 +42,7 @@
}
public List<String> getAdditions() {
- List<String> results = new ArrayList<String>(additions.length);
+ List<String> results = new ArrayList<>(additions.length);
results.add(source);
for (String addition : additions) {
String copy = addition;
@@ -55,18 +55,19 @@
return results;
}
+ @Override
public String toString() {
return "{" + matcher.toString() + ", " + Arrays.asList(additions) + "}";
}
}
- private static final List<FallbackIterator.FallbackRule> FALLBACK_LIST = new ArrayList<FallbackIterator.FallbackRule>();
- private static final List<FallbackIterator.FallbackRule> CANONICALIZE_LIST = new ArrayList<FallbackIterator.FallbackRule>();
- private static final List<FallbackIterator.FallbackRule> DECANONICALIZE_LIST = new ArrayList<FallbackIterator.FallbackRule>();
+ private static final List<FallbackIterator.FallbackRule> FALLBACK_LIST = new ArrayList<>();
+ private static final List<FallbackIterator.FallbackRule> CANONICALIZE_LIST = new ArrayList<>();
+ private static final List<FallbackIterator.FallbackRule> DECANONICALIZE_LIST = new ArrayList<>();
private enum Type {
canonicalize, fallback, decanonicalize
- };
+ }
static {
// TODO add "JP" (ja_JP_JP) "TH" (th_TH_TH) "NY" (no_NO_NY)
@@ -76,18 +77,18 @@
"canonicalize", // mechanically generated
- // grandfathered
+ // Language tags marked as “Type: grandfathered” in BCP 47.
"art-lojban;jbo",
- "cel-gaulish;xcg", // Grandfathered code with special replacement: cel-gaulish
- "en-GB-oed;en-GB-x-oed", // Grandfathered code with special replacement: en-GB-oed
+ "cel-gaulish;xcg", // Special replacement: cel-gaulish
+ "en-GB-oed;en-GB-x-oed", // Special replacement: en-GB-oed
"i-ami;ami",
"i-bnn;bnn",
- "i-default;und", // Grandfathered code with special replacement: i-default
- "i-enochian;x-enochian", // Grandfathered code with special replacement: i-enochian
+ "i-default;und", // Special replacement: i-default
+ "i-enochian;x-enochian", // Special replacement: i-enochian
"i-hak;zh-hakka",
"i-klingon;tlh",
"i-lux;lb",
- "i-mingo;see", // Grandfathered code with special replacement: i-mingo
+ "i-mingo;see", // Special replacement: i-mingo
"i-navajo;nv",
"i-pwn;pwn",
"i-tao;tao",
@@ -104,7 +105,7 @@
"zh-gan;gan",
"zh-guoyu;zh-cmn",
"zh-hakka;hak",
- "zh-min;nan", // Grandfathered code with special replacement: zh-min
+ "zh-min;nan", // Special replacement: zh-min
"zh-min-nan;nan",
"zh-wuu;wuu",
"zh-xiang;hsn",
@@ -225,7 +226,7 @@
public FallbackIterator set(String source) {
// all of this can be optimized later
String original = source;
- List<String> items = new ArrayList<String>();
+ List<String> items = new ArrayList<>();
items.add(original);
// canonicalize (normally in constructor)
canonicalize: while (true) {
@@ -264,7 +265,7 @@
// for each decanonicalize rule, add all premutations it generates
for (FallbackIterator.FallbackRule rule : DECANONICALIZE_LIST) {
- List<String> localExpanded = new ArrayList<String>();
+ List<String> localExpanded = new ArrayList<>();
for (String localeItem : items) {
if (rule.matches(localeItem)) {
localExpanded.addAll(rule.getAdditions());
@@ -275,7 +276,7 @@
items = localExpanded;
}
// if we didn't need to start with the original, we could skip this bit.
- LinkedHashSet<String> results = new LinkedHashSet<String>();
+ LinkedHashSet<String> results = new LinkedHashSet<>();
// results.add(original);
results.addAll(items);
iterator = results.iterator();
@@ -284,14 +285,17 @@
// Matcher regularFallback = PatternCache.get("(.*)[-_][^-_]*").matcher("");
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
+ @Override
public boolean hasNext() {
return iterator.hasNext();
}
+ @Override
public String next() {
return iterator.next();
}
diff --git a/tools/java/org/unicode/cldr/tool/FallbackIteratorDataGenerator.java b/tools/java/org/unicode/cldr/tool/FallbackIteratorDataGenerator.java
index c6efbcd..a4edf72 100644
--- a/tools/java/org/unicode/cldr/tool/FallbackIteratorDataGenerator.java
+++ b/tools/java/org/unicode/cldr/tool/FallbackIteratorDataGenerator.java
@@ -14,16 +14,16 @@
public static void main(String[] args) {
final StandardCodes sc = testInfo.getStandardCodes();
- List<String> decanonicalizeList = new ArrayList<String>();
+ List<String> decanonicalizeList = new ArrayList<>();
System.out.println();
System.out.println("\t\t\"canonicalize\",\t\t// mechanically generated");
System.out.println();
for (String type : sc.getAvailableTypes()) {
final boolean isLanguage = type.equals("language");
- final boolean isGrandfathered = type.equals("grandfathered");
+ final boolean isLegacy = type.equals("legacy");
final boolean isRegion = type.equals("territory");
- final String canonicalizationFormat = isGrandfathered ? "\t\t\"%s;%s\","
+ final String canonicalizationFormat = isLegacy ? "\t\t\"%s;%s\","
: isLanguage ? "\t\t\"%s(-.*)?;%s$1\","
: isRegion ? "\t\t\"(.*-)%s(-.*)?;$1%s$2\","
: null;
@@ -42,8 +42,8 @@
if (canonicalValue == null || canonicalValue.length() == 0) {
// System.out.println("\t\t\\\\ skipping " + code);
- if (isGrandfathered) {
- System.out.println("\t\t// Grandfathered code with no replacement " + code);
+ if (isLegacy) {
+ System.out.println("\t\t// Legacy code with no replacement " + code);
continue;
} else {
continue;
@@ -55,10 +55,10 @@
}
System.out.format(canonicalizationFormat, code, canonicalValue);
if (special != null) {
- System.out.print("\t\t// Grandfathered code with special replacement: " + code);
+ System.out.print("\t\t// Legacy code with special replacement: " + code);
}
System.out.println();
- if (!isGrandfathered) {
+ if (!isLegacy) {
decanonicalizeList.add(String.format(canonicalizationFormat, canonicalValue, code));
}
}
diff --git a/tools/java/org/unicode/cldr/tool/FilterFactory.java b/tools/java/org/unicode/cldr/tool/FilterFactory.java
index 0b04397..51492a2 100644
--- a/tools/java/org/unicode/cldr/tool/FilterFactory.java
+++ b/tools/java/org/unicode/cldr/tool/FilterFactory.java
@@ -49,7 +49,7 @@
private String organization;
private boolean modifyValues;
- private List<Modifier> modifiers = new ArrayList<Modifier>();
+ private List<Modifier> modifiers = new ArrayList<>();
/**
* Creates a new Factory for filtering CLDRFiles.
@@ -151,7 +151,7 @@
String parent = LocaleIDParser.getParent(rawFile.getLocaleID());
CLDRFile resolvedParent = rawFactory.make(parent, true);
- List<String> duplicatePaths = new ArrayList<String>();
+ List<String> duplicatePaths = new ArrayList<>();
for (String xpath : rawFile) {
if (xpath.startsWith("//ldml/identity")) {
continue;
@@ -159,9 +159,10 @@
String value = rawFile.getStringValue(xpath);
// Remove count="x" if the value is equivalent to count="other".
if (xpath.contains("[@count=")) {
- XPathParts parts = XPathParts.getInstance(xpath); // not frozen, for setAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(xpath);
String count = parts.getAttributeValue(-1, "count");
if (!count.equals("other")) {
+ parts = parts.cloneAsThawed();
parts.setAttribute(-1, "count", "other");
String otherPath = parts.toString();
if (value.equals(rawFile.getStringValue(otherPath))) {
@@ -223,7 +224,7 @@
* Class for performing a specific type of data modification on a CLDRFile.
*/
private abstract class Modifier {
- protected List<ModifierEntry> entries = new ArrayList<ModifierEntry>();
+ protected List<ModifierEntry> entries = new ArrayList<>();
public abstract void modifyFile(CLDRFile file);
@@ -233,7 +234,7 @@
* @return the list of modifiers meant for the specified locale.
*/
protected List<ModifierEntry> getModifiersForLocale(String locale) {
- List<ModifierEntry> newFilters = new ArrayList<ModifierEntry>();
+ List<ModifierEntry> newFilters = new ArrayList<>();
for (ModifierEntry filter : entries) {
if (filter.localeMatches(locale)) {
newFilters.add(filter);
@@ -327,7 +328,7 @@
* Maps the value of XPaths onto other XPaths using regexes.
*/
private class PathRegexModifier extends Modifier {
- private RegexLookup<String> xpathLookup = new RegexLookup<String>();
+ private RegexLookup<String> xpathLookup = new RegexLookup<>();
@Override
public void addModifierEntry(ModifierEntry entry) {
@@ -338,7 +339,7 @@
@Override
public void modifyFile(CLDRFile file) {
if (xpathLookup.size() > 0) {
- Output<String[]> arguments = new Output<String[]>();
+ Output<String[]> arguments = new Output<>();
for (String xpath : file) {
String newValue = xpathLookup.get(xpath, null, arguments, null, null);
if (newValue != null) {
@@ -379,7 +380,7 @@
String oldValue = contents[1];
String newValue = contents[2];
// Process remaining options.
- Map<String, String> options = new HashMap<String, String>();
+ Map<String, String> options = new HashMap<>();
for (int i = 3; i < contents.length; i++) {
String rawLine = contents[i];
int pos = rawLine.indexOf('=');
diff --git a/tools/java/org/unicode/cldr/tool/FindHardInheritance.java b/tools/java/org/unicode/cldr/tool/FindHardInheritance.java
index 0682f6a..8666366 100644
--- a/tools/java/org/unicode/cldr/tool/FindHardInheritance.java
+++ b/tools/java/org/unicode/cldr/tool/FindHardInheritance.java
@@ -21,14 +21,14 @@
final int redundantCount;
final int constructedCount;
final int coverageCount;
-
+
final int regularCountCps;
final int inheritedCountCps;
final int redundantCountCps;
final int constructedCountCps;
final int coverageCountCps;
-
- public Info(int regularCount, int inheritedCount, int redundantCount, int constructedCount, int coverageCount,
+
+ public Info(int regularCount, int inheritedCount, int redundantCount, int constructedCount, int coverageCount,
int regularCountCps, int inheritedCountCps, int redundantCountCps, int constructedCountCps, int coverageCountCps) {
this.regularCount = regularCount;
this.inheritedCount = inheritedCount;
@@ -50,7 +50,7 @@
+ "\t" + coverageCount + "\t" + coverageCountCps
;
}
- static final String HEADER =
+ static final String HEADER =
"count\tcps"
+ "\tinher.\tcps"
+ "\tredund.\tcps"
@@ -68,7 +68,7 @@
// System.out.println(localeId + "\t" + name);
// }
// if (true) return;
-
+
Map<String, Info> data = new LinkedHashMap<>();
System.out.println(
"dir."
@@ -100,18 +100,18 @@
int constructedCount = 0;
int inheritedCount = 0;
int coverageCount = 0;
-
+
int redundantCountCps = 0;
int regularCountCps = 0;
int constructedCountCps = 0;
int inheritedCountCps = 0;
int coverageCountCps = 0;
-
+
boolean allConstructed = "annotationsDerived".equals(dir);
CoverageLevel2 coverage = CoverageLevel2.getInstance(localeId);
CLDRFile cldrFile = factory.make(localeId, true, DraftStatus.contributed);
CLDRFile unresolvedCldrFile = factory.make(localeId, false, DraftStatus.contributed);
-
+
for (String path : cldrFile) {
if (path.startsWith("//ldml/identity/")) {
continue;
@@ -141,7 +141,7 @@
regularCountCps+=cps;
}
}
- Info info = new Info(regularCount, inheritedCount, redundantCount, constructedCount, coverageCount,
+ Info info = new Info(regularCount, inheritedCount, redundantCount, constructedCount, coverageCount,
regularCountCps, inheritedCountCps, redundantCountCps, constructedCountCps, coverageCountCps);
return info;
}
diff --git a/tools/java/org/unicode/cldr/tool/FindPluralDifferences.java b/tools/java/org/unicode/cldr/tool/FindPluralDifferences.java
index 8f99fac..ea1494a 100644
--- a/tools/java/org/unicode/cldr/tool/FindPluralDifferences.java
+++ b/tools/java/org/unicode/cldr/tool/FindPluralDifferences.java
@@ -29,7 +29,7 @@
x.set(3, 6);
x.set(9);
x.set(11, 13);
- Map<String, BitSet> foo = new TreeMap<String, BitSet>();
+ Map<String, BitSet> foo = new TreeMap<>();
foo.put("x", x);
FindPluralDifferences.show(foo);
@@ -78,7 +78,7 @@
System.out.println("Modifications:");
for (String locale : oldLocales) {
- Map<String, BitSet> results = new TreeMap<String, BitSet>();
+ Map<String, BitSet> results = new TreeMap<>();
PluralInfo oldPluralInfo = supplementalOld.getPlurals(pluralType, locale);
PluralRules oldRules = oldPluralInfo.getPluralRules();
PluralInfo newPluralInfo = supplementalNew.getPlurals(pluralType, locale);
diff --git a/tools/java/org/unicode/cldr/tool/FindPreferredHours.java b/tools/java/org/unicode/cldr/tool/FindPreferredHours.java
index 8c7390f..ce8b929 100644
--- a/tools/java/org/unicode/cldr/tool/FindPreferredHours.java
+++ b/tools/java/org/unicode/cldr/tool/FindPreferredHours.java
@@ -22,7 +22,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.PopulationData;
import org.unicode.cldr.util.With;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.DateTimePatternGenerator.FormatParser;
import com.ibm.icu.text.DateTimePatternGenerator.VariableField;
@@ -33,7 +33,7 @@
private static final CLDRFile ENGLISH = INFO.getEnglish();
private static final UnicodeSet DIGITS = new UnicodeSet("[0-9]").freeze();
- private static final Set<Character> ONLY24 = Collections.unmodifiableSet(new LinkedHashSet<Character>(Arrays
+ private static final Set<Character> ONLY24 = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays
.asList('H')));
private final static Map<String, Set<Character>> OVERRIDE_ALLOWED = Builder
@@ -112,7 +112,7 @@
final Relation<String, Hours> lang2Hours = Relation.of(new TreeMap<String, Set<Hours>>(), TreeSet.class);
final Factory factory = INFO.getCldrFactory();
final FormatParser formatDateParser = new FormatParser();
- final LikelySubtags likely2Max = new LikelySubtags(INFO.getSupplementalDataInfo());
+ final LikelySubtags likely2Max = new LikelySubtags();
for (final String locale : factory.getAvailable()) {
if (locale.equals("root")) {
@@ -149,7 +149,7 @@
// gather data per region
- Map<String, Relation<Character, String>> region2Preferred2locales = new TreeMap<String, Relation<Character, String>>();
+ Map<String, Relation<Character, String>> region2Preferred2locales = new TreeMap<>();
Relation<String, Character> region2Allowed = Relation.of(new TreeMap<String, Set<Character>>(), TreeSet.class);
final LanguageTagParser ltp = new LanguageTagParser();
@@ -196,7 +196,7 @@
if (preferredSet.size() == 1) {
overrides.append(region + " didn't need override!!\n");
} else {
- LinkedHashSet<Entry<Character, String>> oldValues = new LinkedHashSet<Entry<Character, String>>();
+ LinkedHashSet<Entry<Character, String>> oldValues = new LinkedHashSet<>();
StringBuilder oldValuesString = new StringBuilder();
for (Entry<Character, String> x : preferredSet.keyValueSet()) {
if (!x.getKey().equals(resolvedValue)) {
@@ -212,7 +212,7 @@
}
}
- Set<Character> allAllowed = new TreeSet<Character>();
+ Set<Character> allAllowed = new TreeSet<>();
Character preferred = null;
for (Entry<Character, Set<String>> pref : preferredSet.keyValuesSet()) {
@@ -244,7 +244,7 @@
}
String subcontinent = Containment.getSubcontinent(region);
String continent = Containment.getContinent(region);
- String tag = CollectionUtilities.join(preferredSet.keySet(), ",");
+ String tag = Joiner.on(",").join(preferredSet.keySet());
if (tag.equals("h")) {
tag += "*";
}
@@ -270,9 +270,9 @@
+ preferredAndAllowedHour.preferred
+ "\""
+ " allowed=\""
- + CollectionUtilities.join(preferredAndAllowedHour.allowed, " ")
+ + Joiner.on(" ").join(preferredAndAllowedHour.allowed)
+ "\""
- + " regions=\"" + CollectionUtilities.join(regions, " ") + "\""
+ + " regions=\"" + Joiner.on(" ").join(regions) + "\""
+ "/>");
}
System.out.println(" </timeData>");
diff --git a/tools/java/org/unicode/cldr/tool/FindWidths.java b/tools/java/org/unicode/cldr/tool/FindWidths.java
index d51e64f..a6eaad3 100644
--- a/tools/java/org/unicode/cldr/tool/FindWidths.java
+++ b/tools/java/org/unicode/cldr/tool/FindWidths.java
@@ -45,8 +45,8 @@
nf.setMaximumFractionDigits(0);
CLDRFile english = testInfo.getEnglish();
Factory phf = PathHeader.getFactory(english);
- Map<PathHeader, Integer> englishWidths = new HashMap<PathHeader, Integer>();
- Map<PathHeader, Data> maxWidths = new TreeMap<PathHeader, Data>();
+ Map<PathHeader, Integer> englishWidths = new HashMap<>();
+ Map<PathHeader, Data> maxWidths = new TreeMap<>();
Set<String> sampleLocales = testInfo.getStandardCodes().getLocaleCoverageLocales("google");
for (String path : english) {
diff --git a/tools/java/org/unicode/cldr/tool/FixDelimiters.java b/tools/java/org/unicode/cldr/tool/FixDelimiters.java
index a21c4ad..448dc25 100644
--- a/tools/java/org/unicode/cldr/tool/FixDelimiters.java
+++ b/tools/java/org/unicode/cldr/tool/FixDelimiters.java
@@ -37,7 +37,7 @@
System.out.println(entry);
}
Factory factory = SimpleFactory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
- Set<String> remainder = new LinkedHashSet<String>(Data.locales2delimiters.keySet());
+ Set<String> remainder = new LinkedHashSet<>(Data.locales2delimiters.keySet());
String[] paths = {
"//ldml/delimiters/quotationStart",
@@ -98,13 +98,14 @@
end = quotes.group(2);
}
+ @Override
public String toString() {
return start + "...." + end;
}
}
static class Data {
- static Map<String, Row.R2<Quotes, Quotes>> locales2delimiters = new LinkedHashMap<String, Row.R2<Quotes, Quotes>>();
+ static Map<String, Row.R2<Quotes, Quotes>> locales2delimiters = new LinkedHashMap<>();
static Matcher localeString = PatternCache.get(".*\\((.*)\\)").matcher("");
static {
final String instructionFile = "delimiterFixes.txt";
diff --git a/tools/java/org/unicode/cldr/tool/FixTransformNames.java b/tools/java/org/unicode/cldr/tool/FixTransformNames.java
index 45e3bd6..99f4562 100644
--- a/tools/java/org/unicode/cldr/tool/FixTransformNames.java
+++ b/tools/java/org/unicode/cldr/tool/FixTransformNames.java
@@ -32,12 +32,12 @@
new FixTransformNames().run(args);
}
- Map<String, String> fieldToCode = new HashMap<String, String>();
- Map<String, String> oldToNewVariant = new HashMap<String, String>();
- Map<String, String> fieldToVariant = new HashMap<String, String>();
- Map<String, String> targetToCode = new HashMap<String, String>();
+ Map<String, String> fieldToCode = new HashMap<>();
+ Map<String, String> oldToNewVariant = new HashMap<>();
+ Map<String, String> fieldToVariant = new HashMap<>();
+ Map<String, String> targetToCode = new HashMap<>();
- Set<String> languageCodes = new HashSet<String>();
+ Set<String> languageCodes = new HashSet<>();
private void run(String[] args) {
CLDRFile file = testInfo.getEnglish();
@@ -78,7 +78,7 @@
<transformName type="x-Jamo">Jamo</transformName>
<transformName type="x-Pinyin">Pinyin</transformName>
<transformName type="x-Publishing">Publishing</transformName>
-
+
??Accents [Any-Accents]
??ConjoiningJamo [Latin-ConjoiningJamo]
??Fullwidth [Fullwidth-Halfwidth]
@@ -96,17 +96,17 @@
??Title [az-Title, el-Title, lt-Title, nl-Title, tr-Title]
??Traditional [Simplified-Traditional]
??Upper [az-Upper, el-Upper, lt-Upper, tr-Upper]
-
+
*/
//CLDRTransforms transforms = CLDRTransforms.getInstance();
Relation<String, String> missing = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> found = new TreeSet<String>();
- Map<String, String> allFields = new TreeMap<String, String>();
- Map<String, String> specialFields = new TreeMap<String, String>();
- Map<String, String> allVariants = new TreeMap<String, String>();
+ Set<String> found = new TreeSet<>();
+ Map<String, String> allFields = new TreeMap<>();
+ Map<String, String> specialFields = new TreeMap<>();
+ Map<String, String> allVariants = new TreeMap<>();
- Set<String> internal = new TreeSet<String>();
+ Set<String> internal = new TreeSet<>();
Set<String> cldrIds = getCldrIds(internal);
for (String id : CLDRTransforms.getAvailableIds()) {
@@ -122,7 +122,7 @@
System.out.println("*Missing:\t" + id);
}
}
- Set<String> icuOnlyIds = new TreeSet<String>();
+ Set<String> icuOnlyIds = new TreeSet<>();
for (Enumeration<String> x = Transliterator.getAvailableIDs(); x.hasMoreElements();) {
String icuId = x.nextElement();
if (!cldrIds.contains(icuId)) {
@@ -269,7 +269,7 @@
}
private Set<String> getCldrIds(Set<String> internal) {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
for (String s : CLDRTransforms.getAvailableIds()) {
//String dir;
ParsedTransformID directionInfo = new ParsedTransformID();
diff --git a/tools/java/org/unicode/cldr/tool/FormattedFileWriter.java b/tools/java/org/unicode/cldr/tool/FormattedFileWriter.java
index 1e7d7b9..a0ff08d 100644
--- a/tools/java/org/unicode/cldr/tool/FormattedFileWriter.java
+++ b/tools/java/org/unicode/cldr/tool/FormattedFileWriter.java
@@ -135,6 +135,7 @@
return this;
}
+ @Override
public void close() {
String contents = out.toString();
if (contents.isEmpty()) {
@@ -172,7 +173,7 @@
public static void copyIncludeHtmls (String targetDirectory) {
copyIncludeHtmls(targetDirectory, false);
}
-
+
public static void copyIncludeHtmls (String targetDirectory, boolean addPrevVersion) {
String[] replacements = {
"%version%", ToolConstants.CHART_DISPLAY_VERSION + (addPrevVersion ? " – " + ToolConstants.PREV_CHART_VERSION_WITH0 : ""),
@@ -186,10 +187,12 @@
return showDate ? CldrUtility.isoFormatDateOnly(new Date()) : "";
}
+ @Override
public void write(char[] cbuf, int off, int len) throws IOException {
out.write(cbuf, off, len);
}
+ @Override
public void flush() throws IOException {
out.flush();
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateAliases.java b/tools/java/org/unicode/cldr/tool/GenerateAliases.java
index cdcd97e..6afc0a6 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateAliases.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateAliases.java
@@ -27,7 +27,7 @@
}
static class Builder {
- Map<String, String> aliasMap = new LinkedHashMap<String, String>();
+ Map<String, String> aliasMap = new LinkedHashMap<>();
Factory factory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
SupplementalDataInfo dataInfo = SupplementalDataInfo.getInstance();
@@ -57,7 +57,7 @@
}
}
- Map<String, String> likely = new TreeMap<String, String>();
+ Map<String, String> likely = new TreeMap<>();
// get all the combinations
for (String max : likelySubtags.getToMaximized().values()) {
@@ -100,8 +100,6 @@
System.out.println("missing" + "\t" + localeID);
}
}
-
- // System.out.println(CollectionUtilities.join(aliasMap.entrySet(), "\n"));
}
private void addToLikely(Map<String, String> likely) {
@@ -223,7 +221,7 @@
*/
private Set<String> addExtras(String language, Relation<String, String> goodToBadLanguages) {
- Set<String> languages = new TreeSet<String>();
+ Set<String> languages = new TreeSet<>();
languages.add(language);
Set<String> badLanguages = goodToBadLanguages.get(language);
if (badLanguages != null) {
@@ -232,7 +230,7 @@
return languages;
}
- Map<String, Boolean> wholeAliasCache = new HashMap<String, Boolean>();
+ Map<String, Boolean> wholeAliasCache = new HashMap<>();
private boolean isWholeAlias(Factory factory, String localeID) {
Boolean result = wholeAliasCache.get(localeID);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateAllCharts.java b/tools/java/org/unicode/cldr/tool/GenerateAllCharts.java
index 8199ba4..2517be7 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateAllCharts.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateAllCharts.java
@@ -13,7 +13,7 @@
FormattedFileWriter.copyIncludeHtmls(CLDRPaths.CHART_DIRECTORY);
ShowLanguages.main(args);
-
+
new ChartAnnotations().writeChart(null);
new ChartSubdivisionNames().writeChart(null);
GenerateBcp47Text.main(args);
@@ -22,8 +22,9 @@
//GenerateTransformCharts.main(args);
ShowKeyboards.main(args);
ChartDelta.main(args);
+ ChartDelta.main(args, true); // churn
ChartCollation.main(args);
-
+
VerifyCompactNumbers.main(args);
VerifyZones.main(args);
DateTimeFormats.main(args);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateApproximateWidths.java b/tools/java/org/unicode/cldr/tool/GenerateApproximateWidths.java
index 93bf61a..7d0be54 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateApproximateWidths.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateApproximateWidths.java
@@ -43,6 +43,7 @@
private BufferedImage bimg;
private String string = "𝛛";
+ @Override
public void paint(Graphics g) {
Dimension d = getSize();
if (bimg == null || bimg.getWidth() != d.width || bimg.getHeight() != d.height) {
@@ -71,7 +72,7 @@
try {
PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY + "widths/", "ApproximateWidth.txt");
// TODO Auto-generated method stub
- UnicodeMap<Integer> map = new UnicodeMap<Integer>();
+ UnicodeMap<Integer> map = new UnicodeMap<>();
Widths widths = new Widths(g, new Font("Serif", 0, 100), new Font("SansSerif", 0, 100));
UnicodeSet CHECK = new UnicodeSet("[[:^c:][:cc:][:cf:]]");
@@ -101,7 +102,7 @@
out.println("# ApproximateWidth\n" +
"# @missing: 0000..10FFFF; " + defaultWidth);
- Set<Integer> values = new TreeSet<Integer>(map.values());
+ Set<Integer> values = new TreeSet<>(map.values());
for (Integer integer0 : values) {
if (integer0 == null) {
continue;
@@ -263,14 +264,17 @@
demo.init();
Frame f = new Frame("Frame");
f.addWindowListener(new WindowAdapter() {
+ @Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
+ @Override
public void windowDeiconified(WindowEvent e) {
demo.start();
}
+ @Override
public void windowIconified(WindowEvent e) {
demo.stop();
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateAttributeList.java b/tools/java/org/unicode/cldr/tool/GenerateAttributeList.java
index 7aae971..cfc4e89 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateAttributeList.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateAttributeList.java
@@ -25,6 +25,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.DtdData;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.TransliteratorUtilities;
@@ -37,9 +38,9 @@
import org.xml.sax.ext.DeclHandler;
public class GenerateAttributeList {
- Map<String, Map<String, Set<String>[]>> element_attribute_valueSet = new TreeMap<String, Map<String, Set<String>[]>>();
- Set<String> allElements = new TreeSet<String>();
- Map<String, String> defaults = new HashMap<String, String>();
+ Map<String, Map<String, Set<String>[]>> element_attribute_valueSet = new TreeMap<>();
+ Set<String> allElements = new TreeSet<>();
+ Map<String, String> defaults = new HashMap<>();
public GenerateAttributeList(Factory cldrFactory) throws IOException {
addFromStandardCodes();
@@ -104,7 +105,7 @@
private void addFromDirectory(String directory) throws IOException {
File dir = new File(directory);
- directory = dir.getCanonicalPath();
+ directory = PathUtilities.getNormalizedPathString(dir);
String[] files = dir.list();
for (int i = 0; i < files.length; ++i) {
if (files[i].startsWith(".#")) continue;
@@ -156,13 +157,13 @@
}
// now add
Map<String, Set<String>[]> attribute_valueSet = element_attribute_valueSet.get(element);
- if (attribute_valueSet == null) element_attribute_valueSet.put(element, attribute_valueSet = new TreeMap<String, Set<String>[]>());
+ if (attribute_valueSet == null) element_attribute_valueSet.put(element, attribute_valueSet = new TreeMap<>());
Set<String>[] valueSets = attribute_valueSet.get(attribute);
if (valueSets == null) {
Comparator<String> c = DtdData.getAttributeValueComparator(element, attribute);
valueSets = new Set[2];
- valueSets[0] = new TreeSet<String>(c);
- valueSets[1] = new TreeSet<String>();
+ valueSets[0] = new TreeSet<>(c);
+ valueSets[1] = new TreeSet<>();
attribute_valueSet.put(attribute, valueSets);
}
try {
@@ -211,8 +212,8 @@
String defaultKey = element + "|" + attribute;
pw.print(toString(valueSets[0], defaultKey));
pw.println("</td><td>");
- Set<String> toRemove = new TreeSet<String>(valueSets[0]);
- Set<String> remainder = new TreeSet<String>(valueSets[1]);
+ Set<String> toRemove = new TreeSet<>(valueSets[0]);
+ Set<String> remainder = new TreeSet<>(valueSets[1]);
remainder.removeAll(toRemove);
pw.print(toString(remainder, defaultKey));
pw.println("</td></tr>");
@@ -251,6 +252,7 @@
Matcher idmatcher = PatternCache.get("[a-zA-Z][-_a-zA-Z0-9]*").matcher("");
+ @Override
public void attributeDecl(String eName, String aName, String type, String mode, String value)
throws SAXException {
// System.out.println("Attribute\t" + eName + "\t" + aName + "\t" + type + "\t" + mode + "\t" + value);
@@ -269,6 +271,7 @@
*
* @see org.xml.sax.ext.DeclHandler#elementDecl(java.lang.String, java.lang.String)
*/
+ @Override
public void elementDecl(String name, String model) throws SAXException {
// TODO Auto-generated method stub
@@ -279,6 +282,7 @@
*
* @see org.xml.sax.ext.DeclHandler#internalEntityDecl(java.lang.String, java.lang.String)
*/
+ @Override
public void internalEntityDecl(String name, String value) throws SAXException {
// TODO Auto-generated method stub
@@ -289,6 +293,7 @@
*
* @see org.xml.sax.ext.DeclHandler#externalEntityDecl(java.lang.String, java.lang.String, java.lang.String)
*/
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
// TODO Auto-generated method stub
@@ -302,6 +307,7 @@
*
* @see org.xml.sax.ContentHandler#endDocument()
*/
+ @Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
@@ -312,6 +318,7 @@
*
* @see org.xml.sax.ContentHandler#startDocument()
*/
+ @Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
@@ -322,6 +329,7 @@
*
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
@@ -332,6 +340,7 @@
*
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
+ @Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
@@ -342,6 +351,7 @@
*
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
+ @Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
@@ -352,6 +362,7 @@
*
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
+ @Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
@@ -362,6 +373,7 @@
*
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
+ @Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
@@ -372,6 +384,7 @@
*
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
+ @Override
public void processingInstruction(String target, String data) throws SAXException {
// TODO Auto-generated method stub
@@ -382,6 +395,7 @@
*
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
+ @Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
// TODO Auto-generated method stub
@@ -392,6 +406,7 @@
*
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
+ @Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
@@ -403,6 +418,7 @@
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String,
* org.xml.sax.Attributes)
*/
+ @Override
public void startElement(String namespaceURI, String localName, String qName, Attributes attributes)
throws SAXException {
if (attributes == null) return;
@@ -417,4 +433,4 @@
public Map<String, Map<String, Set<String>[]>> getElement_attribute_valueSet() {
return element_attribute_valueSet;
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateBcp47Bits.java b/tools/java/org/unicode/cldr/tool/GenerateBcp47Bits.java
index 0935059..b37481f 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateBcp47Bits.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateBcp47Bits.java
@@ -74,7 +74,7 @@
*/
private static void writeBits(final Collection<String> source, StringBitTransform transform, String indent,
long[] testStatic) {
- Set<String> codes = new TreeSet<String>(source);
+ Set<String> codes = new TreeSet<>(source);
// Transform into bits
Bits bits = new Bits(transform.getLimit());
@@ -101,7 +101,7 @@
// Verify that the sets are the same afterwards
if (QUICK) System.out.println(bits);
- Set<String> verifySet = new TreeSet<String>();
+ Set<String> verifySet = new TreeSet<>();
for (int i = 0; i < transform.getLimit(); ++i) {
if (!bits.get(i)) continue;
String verify = transform.fromBit(i);
@@ -241,6 +241,7 @@
return -1;
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder("[");
int limit = bits.length;
@@ -272,7 +273,7 @@
static class Bcp47StringBitTransform implements StringBitTransform {
enum Type {
LANGUAGE, REGION
- };
+ }
Type type;
int limit;
@@ -282,13 +283,15 @@
limit = type == Type.LANGUAGE ? 26 * 26 + 26 * 26 * 26 : 26 * 26 + 1000;
}
+ @Override
public int getLimit() {
return limit;
}
- static final UnicodeSet alpha = (UnicodeSet) new UnicodeSet("[a-z]").freeze();
- static final UnicodeSet num = (UnicodeSet) new UnicodeSet("[0-9]").freeze();
+ static final UnicodeSet alpha = new UnicodeSet("[a-z]").freeze();
+ static final UnicodeSet num = new UnicodeSet("[0-9]").freeze();
+ @Override
public int toBit(String string) {
string = UCharacter.toLowerCase(ULocale.ENGLISH, string);
switch (string.length()) {
@@ -314,6 +317,7 @@
}
}
+ @Override
public String fromBit(int bit) {
StringBuilder result = new StringBuilder();
if (bit < 0) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateBcp47Tests.java b/tools/java/org/unicode/cldr/tool/GenerateBcp47Tests.java
index b2a479c..5154d42 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateBcp47Tests.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateBcp47Tests.java
@@ -29,7 +29,7 @@
System.out.println("#Tests");
Relation<String, String> extension2Keys = info.getBcp47Extension2Keys();
Relation<String, String> keys2subtypes = info.getBcp47Keys();
- Set<String> deprecatedSet = new LinkedHashSet<String>();
+ Set<String> deprecatedSet = new LinkedHashSet<>();
for (Entry<String, Set<String>> extensionKeys : extension2Keys.keyValuesSet()) {
String extension = extensionKeys.getKey();
Set<String> keys = extensionKeys.getValue();
diff --git a/tools/java/org/unicode/cldr/tool/GenerateBcp47Text.java b/tools/java/org/unicode/cldr/tool/GenerateBcp47Text.java
index a1a5e27..6d56d92 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateBcp47Text.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateBcp47Text.java
@@ -10,7 +10,7 @@
import org.unicode.cldr.draft.FileUtilities;
import org.unicode.cldr.util.SupplementalDataInfo;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -90,7 +90,7 @@
}
private void showField(PrintWriter out, String title, Collection<String> set) {
- showField(out, title, set == null || set.isEmpty() ? null : CollectionUtilities.join(set, ", "));
+ showField(out, title, set == null || set.isEmpty() ? null : Joiner.on(", ").join(set));
}
private void showField(PrintWriter out, String title, String item) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateBirth.java b/tools/java/org/unicode/cldr/tool/GenerateBirth.java
index 48abfb0..8a0460f 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateBirth.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateBirth.java
@@ -28,6 +28,7 @@
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StringId;
@@ -79,7 +80,7 @@
String filePattern = myOptions.get("file").getValue();
- ArrayList<Factory> list = new ArrayList<Factory>();
+ ArrayList<Factory> list = new ArrayList<>();
for (CldrVersion version : VERSIONS) {
if (version == CldrVersion.unknown) {
continue;
@@ -87,7 +88,7 @@
List<File> paths = version.getPathsForFactory();
// String base = version.getBaseDirectory();
// File[] paths = version.compareTo(CldrVersion.v27_0) > 0 ? // warning, order is reversed
-// new File[] { new File(base + "common/main/") } :
+// new File[] { new File(base + "common/main/") } :
// new File[] { new File(base + "common/main/"), new File(base + "common/annotations/") };
System.out.println(version + ", " + paths);
@@ -137,14 +138,14 @@
// Set up the binary data files for all others
File file = new File(dataDirectory + "/" + OutdatedPaths.OUTDATED_DATA);
- final String outputDataFile = file.getCanonicalPath();
+ final String outputDataFile = PathUtilities.getNormalizedPathString(file);
System.out.println("Writing data: " + outputDataFile);
DataOutputStream dataOut = new DataOutputStream(new FileOutputStream(file));
dataOut.writeUTF(OutdatedPaths.FORMAT_KEY);
// Load and process all the locales
- TreeMap<String, Set<String>> localeToNewer = new TreeMap<String, Set<String>>();
+ TreeMap<String, Set<String>> localeToNewer = new TreeMap<>();
LanguageTagParser ltp = new LanguageTagParser();
for (String fileName : factories[0].getAvailable()) {
if (fileName.equals("en")) {
@@ -175,7 +176,7 @@
// Doublecheck the data
OutdatedPaths outdatedPaths = new OutdatedPaths(dataDirectory);
- Set<String> needPrevious = new TreeSet<String>();
+ Set<String> needPrevious = new TreeSet<>();
int errorCount = 0;
for (Entry<String, Set<String>> localeAndNewer : localeToNewer.entrySet()) {
String locale = localeAndNewer.getKey();
@@ -215,7 +216,7 @@
final String locale;
static final Pattern TYPE = PatternCache.get("\\[@type=\"([^\"]*)\"");
final Matcher typeMatcher = TYPE.matcher("");
- Set<String> emptyPrevious = new HashSet<String>();
+ Set<String> emptyPrevious = new HashSet<>();
Births(String file) {
locale = file;
@@ -231,7 +232,7 @@
}
}
birthToPaths = Relation.of(new TreeMap<CldrVersion, Set<String>>(), TreeSet.class);
- pathToBirthCurrentPrevious = new HashMap<String, Row.R3<CldrVersion, String, String>>();
+ pathToBirthCurrentPrevious = new HashMap<>();
for (String xpath : files[0]) {
xpath = xpath.intern();
if (xpath.contains("[@type=\"ar\"]")) {
@@ -277,7 +278,7 @@
public void writeBirthValues(String file) throws IOException {
DataOutputStream dataOut = new DataOutputStream(new FileOutputStream(file));
dataOut.writeUTF(OutdatedPaths.FORMAT_KEY);
- System.out.println("Writing data: " + new File(file).getCanonicalPath());
+ System.out.println("Writing data: " + PathUtilities.getNormalizedPathString(file));
dataOut.writeInt(pathToBirthCurrentPrevious.size());
// Load and process all the locales
@@ -310,8 +311,8 @@
out.println("Loc\tVersion\tValue\tPrevValue\tEVersion\tEValue\tEPrevValue\tPath");
- Set<String> newer = new HashSet<String>();
- HashMap<Long, String> sanityCheck = new HashMap<Long, String>();
+ Set<String> newer = new HashSet<>();
+ HashMap<Long, String> sanityCheck = new HashMap<>();
CldrVersion onlyNewerVersion = null;
String otherValue = "n/a";
String olderOtherValue = "n/a";
diff --git a/tools/java/org/unicode/cldr/tool/GenerateCasingChart.java b/tools/java/org/unicode/cldr/tool/GenerateCasingChart.java
index b17af7e..255ef74 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateCasingChart.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateCasingChart.java
@@ -22,7 +22,6 @@
import org.unicode.cldr.util.XPathParts;
import com.google.common.base.Splitter;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.text.DisplayContext;
import com.ibm.icu.text.LocaleDisplayNames;
import com.ibm.icu.text.UnicodeSet;
@@ -58,7 +57,7 @@
<contextTransformUsage type="month-standalone-except-narrow">
<contextTransform type="stand-alone">titlecase-firstword</contextTransform>
</contextTransformUsage>
-
+
*/
public static void main(String[] args) {
check(ULocale.ENGLISH);
@@ -101,7 +100,7 @@
Level level = CLDRConfig.getInstance().getStandardCodes().getLocaleCoverageLevel("cldr", locale);
boolean hasCasedLetters = changesUpper.containsSome(exemplars);
Set<String> items = new LinkedHashSet<>();
- CollectionUtilities.addAll(cldrFile.iterator("//ldml/contextTransforms"), items);
+ cldrFile.iterator("//ldml/contextTransforms").forEachRemaining(items::add);
if (!hasCasedLetters) {
if (items.size() != 0) {
System.out.println(locale + "Uncased language has context!!!");
diff --git a/tools/java/org/unicode/cldr/tool/GenerateChangeChart.java b/tools/java/org/unicode/cldr/tool/GenerateChangeChart.java
index 5af8dbd..dedcd93 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateChangeChart.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateChangeChart.java
@@ -335,6 +335,7 @@
return title;
}
+ @Override
public void close() throws IOException {
out.write("</div>");
PrintWriter pw2 = org.unicode.cldr.draft.FileUtilities.openUTF8Writer(dir, filename);
@@ -345,10 +346,12 @@
pw2.close();
}
+ @Override
public void write(char[] cbuf, int off, int len) throws IOException {
out.write(cbuf, off, len);
}
+ @Override
public void flush() throws IOException {
out.flush();
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateCldrCollationTests.java b/tools/java/org/unicode/cldr/tool/GenerateCldrCollationTests.java
deleted file mode 100644
index af55fb4..0000000
--- a/tools/java/org/unicode/cldr/tool/GenerateCldrCollationTests.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Created on May 19, 2005
- * Copyright (C) 2004-2011, Unicode, Inc., International Business Machines Corporation, and others.
- * For terms of use, see http://www.unicode.org/terms_of_use.html
- */
-package org.unicode.cldr.tool;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.unicode.cldr.icu.CollationMapper;
-import org.unicode.cldr.icu.IcuData;
-import org.unicode.cldr.util.LocaleIDParser;
-import org.unicode.cldr.util.Log;
-
-import com.ibm.icu.text.Collator;
-import com.ibm.icu.text.RuleBasedCollator;
-import com.ibm.icu.text.Transliterator;
-import com.ibm.icu.util.ULocale;
-
-public class GenerateCldrCollationTests {
- String sourceDir;
- Set<String> validLocales = new TreeSet<String>();
- Map<String, Object> ulocale_rules = new TreeMap<String, Object>(GenerateCldrTests.ULocaleComparator);
- Map<String, Map<String, RuleBasedCollator>> locale_types_rules = new TreeMap<String, Map<String, RuleBasedCollator>>();
- Map<RuleBasedCollator, RuleBasedCollator> collation_collation = new HashMap<RuleBasedCollator, RuleBasedCollator>();
- RuleBasedCollator emptyCollator = (RuleBasedCollator) Collator.getInstance(new ULocale(""));
-
- public Set<String> getAvailableSet() {
- return ulocale_rules.keySet();
- }
-
- public RuleBasedCollator getInstance(String locale) {
- return (RuleBasedCollator) ulocale_rules.get(locale);
- }
-
- void show() {
- Log.logln("Showing Locales");
- Log.logln("Unique Collators: " + collation_collation.size());
- for (Iterator it2 = ulocale_rules.keySet().iterator(); it2.hasNext();) {
- ULocale locale = (ULocale) it2.next();
- RuleBasedCollator col = (RuleBasedCollator) ulocale_rules.get(locale);
- Log.logln("\t" + locale + ", " + col.getRules());
- }
- }
-
- GenerateCldrCollationTests(String sourceDir, String localeRegex, Set<String> locales) throws Exception {
- this.sourceDir = sourceDir;
- Set<String> s = GenerateCldrTests.getMatchingXMLFiles(sourceDir, localeRegex);
- for (Iterator<String> it = s.iterator(); it.hasNext();) {
- getCollationRules(it.next());
- }
-
- // now fixup the validLocales, adding in what they inherit
- // TODO, add check: validSubLocales are masked by intervening locales.
- for (Iterator<String> it = validLocales.iterator(); it.hasNext();) {
- String locale = it.next();
- Map<String, RuleBasedCollator> types_rules = locale_types_rules.get(locale);
- if (types_rules != null)
- Log.logln("Weird: overlap in validLocales: " + locale);
- else {
- for (String parentlocale = LocaleIDParser.getSimpleParent(locale); parentlocale != null; parentlocale = LocaleIDParser
- .getSimpleParent(parentlocale)) {
- types_rules = locale_types_rules.get(parentlocale);
- if (types_rules != null) {
- locale_types_rules.put(locale, types_rules);
- break;
- }
- }
- }
- }
- // now generate the @-style locales
- ulocale_rules.put("root", Collator.getInstance(ULocale.ROOT));
-
- for (Iterator<String> it = locale_types_rules.keySet().iterator(); it.hasNext();) {
- String locale = it.next();
- Map<String, RuleBasedCollator> types_rules = locale_types_rules.get(locale);
- for (Iterator<String> it2 = types_rules.keySet().iterator(); it2.hasNext();) {
- String type = it2.next();
- // TODO fix HACK
- if (type.equals("unihan")) {
- if (!locale.startsWith("zh")) continue;
- }
- RuleBasedCollator col = (RuleBasedCollator) types_rules.get(type);
- String name = type.equals("standard") ? locale : locale + "@collation=" + type;
- ulocale_rules.put(name, col);
- }
- }
- // now flesh out
- // Collator root = Collator.getInstance(ULocale.ROOT);
- for (Iterator<String> it = locales.iterator(); it.hasNext();) {
- String locale = it.next();
- if (ulocale_rules.get(locale) != null) continue;
- String parent = LocaleIDParser.getSimpleParent(locale); // GenerateCldrTests.getParent(locale);
- if (parent == null) continue;
- try {
- ulocale_rules.put(locale, ulocale_rules.get(parent));
- } catch (RuntimeException e) {
- throw e;
- }
- }
- }
-
- static Transliterator fromHex = Transliterator.getInstance("hex-any");
-
- private void getCollationRules(String locale) throws Exception {
- System.out.println("Loading collation:\t" + locale);
- CollationMapper mapper = new CollationMapper(sourceDir, null);
- StringBuilder stringBuilder = new StringBuilder();
- TreeMap<String, RuleBasedCollator> types_rules = new TreeMap<String, RuleBasedCollator>();
- IcuData[] dataList = mapper.fillFromCldr(locale);
- IcuData icuData = dataList[0];
- for (String rbPath : icuData.keySet()) {
- if (!rbPath.endsWith("/Sequence")) continue;
- // remove the \ u's, because they blow up
- stringBuilder.setLength(0);
- for (String line : icuData.get(rbPath).get(0)) {
- stringBuilder.append(line);
- }
- String originalRules = stringBuilder.toString();
- String rules = fromHex.transliterate(originalRules);
- String name = rbPath.split("/")[2];
- RuleBasedCollator fixed = generateCollator(locale, name, rules);
- if (fixed != null) {
- Log.logln("Rules for: " + locale + ", " + name);
- Log.logln(rules);
- if (!rules.equals(originalRules)) {
- Log.logln("Original Rules from Ram: ");
- Log.logln(originalRules);
- }
- types_rules.put(name, fixed);
- }
- locale_types_rules.put(locale, types_rules);
- }
- // now get the valid sublocales
- for (int i = 1; i < dataList.length; i++) {
- IcuData subLocale = dataList[i];
- Log.logln("Valid Sub Locale: " + subLocale.getName());
- validLocales.add(subLocale.getName());
- }
- }
-
- /**
- * @param locale
- * @param current
- * @param foo
- * @param rules
- */
- private RuleBasedCollator generateCollator(String locale, String current, String rules) {
- RuleBasedCollator fixed = null;
- try {
- if (rules.equals(""))
- fixed = emptyCollator;
- else {
- rules = GenerateCldrTests.replace(rules, "[optimize[", "[optimize [");
- rules = GenerateCldrTests.replace(rules, "[suppressContractions[", "[suppressContractions [");
- RuleBasedCollator col = new RuleBasedCollator(rules);
- fixed = (RuleBasedCollator) collation_collation.get(col);
- if (fixed == null) {
- collation_collation.put(col, col);
- fixed = col;
- }
- }
- } catch (Exception e) {
- Log.logln("***Cannot create collator from: " + locale + ", " + current + ", " + rules);
- e.printStackTrace(Log.getLog());
- RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(new ULocale(locale));
- String oldrules = coll.getRules();
- Log.logln("Old ICU4J: " + oldrules);
- Log.logln("Equal?: " + oldrules.equals(rules));
- }
- return fixed;
- }
-}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateCldrDateTimeTests.java b/tools/java/org/unicode/cldr/tool/GenerateCldrDateTimeTests.java
deleted file mode 100644
index a2e4982..0000000
--- a/tools/java/org/unicode/cldr/tool/GenerateCldrDateTimeTests.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Created on May 19, 2005
- * Copyright (C) 2004-2005, Unicode, Inc., International Business Machines Corporation, and others.
- * For terms of use, see http://www.unicode.org/terms_of_use.html
- */
-package org.unicode.cldr.tool;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.ICUServiceBuilder;
-import org.unicode.cldr.util.Log;
-
-import com.ibm.icu.text.UnicodeSet;
-import com.ibm.icu.util.ULocale;
-
-class GenerateCldrDateTimeTests {
- Map<ULocale, UnicodeSet> ulocale_exemplars = new TreeMap<ULocale, UnicodeSet>(GenerateCldrTests.ULocaleComparator);
- Map<UnicodeSet, UnicodeSet> uniqueExemplars = new HashMap<UnicodeSet, UnicodeSet>();
- Set<ULocale> locales = new TreeSet<ULocale>(GenerateCldrTests.ULocaleComparator);
-
- UnicodeSet getExemplarSet(ULocale locale) {
- return ulocale_exemplars.get(locale);
- }
-
- void show() {
- Log.logln("Showing Locales");
- Log.logln("Unique Exemplars: " + uniqueExemplars.size());
- for (Iterator<ULocale> it2 = ulocale_exemplars.keySet().iterator(); it2.hasNext();) {
- ULocale locale = it2.next();
- UnicodeSet us = getExemplarSet(locale);
- Log.logln("\t" + locale + ", " + us);
- }
- }
-
- static final ULocale ROOT = new ULocale("root"); // since CLDR has different root.
- private Factory cldrFactory;
- ICUServiceBuilder icuServiceBuilder;
-
- GenerateCldrDateTimeTests(String sourceDir, String localeRegex, boolean doResolved) {
- this.cldrFactory = Factory.make(sourceDir, ".*");
- icuServiceBuilder = new ICUServiceBuilder();
- Set<String> s = GenerateCldrTests.getMatchingXMLFiles(sourceDir, localeRegex);
- for (Iterator<String> it = s.iterator(); it.hasNext();) {
- getInfo(it.next(), doResolved);
- }
- // now do inheritance manually
- for (Iterator<ULocale> it = locales.iterator(); it.hasNext();) {
- ULocale locale = it.next();
- UnicodeSet ex = (UnicodeSet) ulocale_exemplars.get(locale);
- if (ex != null) continue;
- for (ULocale parent = locale.getFallback(); parent != null; parent = parent.getFallback()) {
- ULocale fixedParent = parent.getLanguage().length() == 0 ? ROOT : parent;
- ex = (UnicodeSet) ulocale_exemplars.get(fixedParent);
- if (ex == null) continue;
- ulocale_exemplars.put(locale, ex);
- break;
- }
- }
-
- }
-
- void getInfo(String locale, boolean doResolved) {
- System.out.println("Getting info for: " + locale);
- locales.add(new ULocale(locale));
- CLDRFile cldrFile = cldrFactory.make(locale, doResolved);
- // Node node = LDMLUtilities.getNode(doc, "//ldml/characters/exemplarCharacters");
- String cpath = "//ldml/characters/exemplarCharacters";
- String path = cldrFile.getFullXPath(cpath);
- if (path == null) return;
- // if (path.indexOf("[@draft=") >= 0) System.out.println("Skipping draft: " + locale + ",\t" + path);
- String exemplars = cldrFile.getStringValue(cpath);
- UnicodeSet exemplarSet = new UnicodeSet(exemplars);
- UnicodeSet fixed = (UnicodeSet) uniqueExemplars.get(exemplarSet);
- if (fixed == null) {
- uniqueExemplars.put(exemplarSet, exemplarSet);
- fixed = exemplarSet;
- }
- ulocale_exemplars.put(new ULocale(locale), fixed);
- }
-
- // ========== DATES ==========
-
- /*
- * Equator DateEquator = new Equator() {
- *//**
- * Must both be ULocales
- */
- /*
- * public boolean equals(Object o1, Object o2) {
- * ULocale loc1 = (ULocale) o1;
- * ULocale loc2 = (ULocale) o2;
- * for (int i = 0; i < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++i) {
- * for (int j = 0; j < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++j) {
- * if (i == 0 && j == 0) continue; // skip null case
- * DateFormat df1 = icuServiceBuilder.getDateFormat(loc1.toString(), i, j);
- * NumberFormat nf = df1.getNumberFormat();
- * nf.setCurrency(ICUServiceBuilder.NO_CURRENCY);
- * df1.setNumberFormat(nf);
- * DateFormat df2 = icuServiceBuilder.getDateFormat(loc2.toString(), i, j);
- * nf = df2.getNumberFormat();
- * nf.setCurrency(ICUServiceBuilder.NO_CURRENCY);
- * df2.setNumberFormat(nf);
- * if (!df1.equals(df2)) {
- * df1.equals(df2);
- * return false;
- * }
- * }
- * }
- * return true;
- * }
- * };
- */
-
- /*
- * Equator ZoneEquator = new Equator() {
- *
- * public boolean equals(Object o1, Object o2) {
- * ULocale loc1 = (ULocale) o1;
- * ULocale loc2 = (ULocale) o2;
- * // locales are equivalent they have the same zone resources.
- * CLDRFile cldrFile1 = cldrFactory.make(loc1.toString(),true);
- * CLDRFile cldrFile2 = cldrFactory.make(loc1.toString(),true);
- * for (int i = 0; i < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++i) {
- * for (int j = 0; j < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++j) {
- * if (i == 0 && j == 0) continue; // skip null case
- * DateFormat df1 = icuServiceBuilder.getDateFormat(loc1.toString(), i, j);
- * NumberFormat nf = df1.getNumberFormat();
- * nf.setCurrency(ICUServiceBuilder.NO_CURRENCY);
- * df1.setNumberFormat(nf);
- * DateFormat df2 = icuServiceBuilder.getDateFormat(loc2.toString(), i, j);
- * nf = df2.getNumberFormat();
- * nf.setCurrency(ICUServiceBuilder.NO_CURRENCY);
- * df2.setNumberFormat(nf);
- * if (!df1.equals(df2)) {
- * df1.equals(df2);
- * return false;
- * }
- * }
- * }
- * return false;
- * }
- * };
- */
- // ========== NUMBERS ==========
-
- /*
- * <numbers>
- * -
- * <symbols>
- * <decimal>.</decimal>
- * <group>,</group>
- * <list>;</list>
- * <percentSign>%</percentSign>
- * <nativeZeroDigit>0</nativeZeroDigit>
- * <patternDigit>#</patternDigit>
- * <plusSign>+</plusSign>
- * <minusSign>-</minusSign>
- * <exponential>E</exponential>
- * <perMille>\u2030</perMille>
- * <infinity>\u221E</infinity>
- * <nan>NaN</nan>
- * </symbols>
- * -
- * <decimalFormats>
- * -
- * <decimalFormatLength>
- * -
- * <decimalFormat>
- * <pattern>#,##0.###</pattern>
- */
-
- /*
- * Equator NumberEquator = new Equator() {
- *//**
- * Must both be ULocales
- */
- /*
- * public boolean equals(Object o1, Object o2) {
- * ULocale loc1 = (ULocale) o1;
- * ULocale loc2 = (ULocale) o2;
- * for (int i = 0; i < ICUServiceBuilder.LIMIT_NUMBER_INDEX; ++i) {
- * NumberFormat nf1 = icuServiceBuilder.getNumberFormat(loc1.toString(), i);
- * NumberFormat nf2 = icuServiceBuilder.getNumberFormat(loc2.toString(), i);
- * boolean result = nf1.equals(nf2);
- * if (!result) {
- * return false;
- * }
- * }
- * return true;
- * }
- * };
- */
-
- /**
- *
- */
- public ICUServiceBuilder getICUServiceBuilder() {
- return icuServiceBuilder;
- }
-}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/tool/GenerateCldrTests.java b/tools/java/org/unicode/cldr/tool/GenerateCldrTests.java
deleted file mode 100644
index fc4b537..0000000
--- a/tools/java/org/unicode/cldr/tool/GenerateCldrTests.java
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
- **********************************************************************
- * Copyright (c) 2002-2011, International Business Machines
- * Corporation and others. All Rights Reserved.
- **********************************************************************
- * Author: Mark Davis
- **********************************************************************
- */
-package org.unicode.cldr.tool;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-
-import org.unicode.cldr.draft.FileUtilities;
-import org.unicode.cldr.util.Builder;
-import org.unicode.cldr.util.CLDRFile;
-import org.unicode.cldr.util.CLDRFile.DraftStatus;
-import org.unicode.cldr.util.CLDRPaths;
-import org.unicode.cldr.util.CldrUtility;
-import org.unicode.cldr.util.Factory;
-import org.unicode.cldr.util.ICUServiceBuilder;
-import org.unicode.cldr.util.LanguageTagParser;
-import org.unicode.cldr.util.Log;
-import org.unicode.cldr.util.PatternCache;
-import org.unicode.cldr.util.SortedBag;
-import org.unicode.cldr.util.TimezoneFormatter;
-import org.unicode.cldr.util.TransliteratorUtilities;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-import com.ibm.icu.dev.tool.UOption;
-import com.ibm.icu.dev.util.UnicodeMap;
-import com.ibm.icu.impl.Relation;
-import com.ibm.icu.lang.UCharacter;
-import com.ibm.icu.text.Collator;
-import com.ibm.icu.text.DateFormat;
-import com.ibm.icu.text.DecimalFormat;
-import com.ibm.icu.text.Normalizer;
-import com.ibm.icu.text.RuleBasedCollator;
-import com.ibm.icu.text.SimpleDateFormat;
-import com.ibm.icu.text.UTF16;
-import com.ibm.icu.text.UnicodeSet;
-import com.ibm.icu.text.UnicodeSetIterator;
-import com.ibm.icu.util.ULocale;
-
-//import org.unicode.cldr.tool.GenerateCldrDateTimeTests;
-
-/**
- * Generated tests for CLDR.
- *
- * @author medavis
- */
-
-public class GenerateCldrTests {
-
- protected static final boolean METAZONES_WORK = false;
-
- // static private PrintWriter log;
- PrintWriter out;
-
- private static final int HELP1 = 0, HELP2 = 1, SOURCEDIR = 2, DESTDIR = 3,
- LOGDIR = 4, MATCH = 5, NOT_RESOLVED = 6, LANGUAGES = 7,
- SHOW = 8;
-
- private static final UOption[] options = {
- UOption.HELP_H(),
- UOption.HELP_QUESTION_MARK(),
- UOption.SOURCEDIR().setDefault(CLDRPaths.COMMON_DIRECTORY),
- UOption.DESTDIR().setDefault(CLDRPaths.GEN_DIRECTORY + "/test/"),
- UOption.create("log", 'l', UOption.REQUIRES_ARG).setDefault(CLDRPaths.GEN_DIRECTORY),
- UOption.create("match", 'm', UOption.REQUIRES_ARG).setDefault(".*"),
- UOption.create("notresolved", 'n', UOption.NO_ARG),
- UOption.create("languages", 'g', UOption.NO_ARG),
- // "C:\\ICU4J\\icu4j\\src\\com\\ibm\\icu\\dev\\tool\\cldr\\"),
- UOption.create("show", 's', UOption.NO_ARG), };
-
- private static final String VERSION = CLDRFile.GEN_VERSION;
-
- GenerateCldrCollationTests cldrCollations;
-
- static String logDir = null, destDir = null;
-
- public static boolean hasLocalizedLanguageFor(String locale,
- String otherLocale) {
- String lang = new LanguageTagParser().set(otherLocale).getLanguage();
- String localizedVersion = english.getName(locale);
- return !lang.equals(localizedVersion);
- }
-
- public static boolean hasLocalizedCountryFor(String locale,
- String otherLocale) {
- String country = new LanguageTagParser().set(otherLocale).getRegion();
- if (country.equals(""))
- return true;
- String localizedVersion = english.getName(CLDRFile.TERRITORY_NAME, locale);
- return !country.equals(localizedVersion);
- }
-
- public static void main(String[] args) throws Exception {
- double deltaTime = System.currentTimeMillis();
- UOption.parseArgs(args, options);
- Log.setLog(options[LOGDIR].value, "log.txt");
- // log = FileUtilities.openUTF8Writer(options[LOGDIR].value, "log.txt");
- try {
- if (options[LANGUAGES].doesOccur) {
- GenerateStatistics.generateSize(
- options[GenerateCldrTests.SOURCEDIR].value + "main/",
- options[GenerateCldrTests.LOGDIR].value,
- options[MATCH].value, true);
- return;
- }
- // compareAvailable();
-
- // if (true) return;
- // System.out.println(createCaseClosure(new
- // UnicodeSet("[a{bc}{def}{oss}]")));
- // System.out.println(createCaseClosure(new
- // UnicodeSet("[a-z\u00c3\u0178{aa}]")));
- GenerateCldrTests t = new GenerateCldrTests();
- // t.generate(new ULocale("hu"), null);
- t.generate(options[MATCH].value);
- } finally {
- Log.close();
- deltaTime = System.currentTimeMillis() - deltaTime;
- System.out.println("Elapsed: " + deltaTime / 1000.0 + " seconds");
- System.out.println("Done");
- }
- }
-
- /*
- * private static void compareAvailable() { String[] cols =
- * Collator.getAvailableULocales(); Locale[] alocs =
- * NumberFormat.getAvailableLocales(); Set sCols = filter(cols); Set sLocs =
- * filter(alocs); Set oldSLocs = new TreeSet(sCols); sLocs.removeAll(sCols);
- * log.println("main - collation"); showLocales(sLocs);
- * sCols.removeAll(oldSLocs); log.println();
- * log.println("collation - main"); showLocales(sCols); }
- */
-
- /**
- *
- */
- /*
- * private static void checkLocaleNames() {Stringe[] locales =
- * String.getAvailableLocales(); for (int i = 0; i < locales.length; ++i) {
- * if (!hasLocalizedCountryFor(String.ENGLISH, locales[i]) ||
- * !hasLocalizedLanguageFor(String.ENGLISH, locales[i]) ||
- * !hasLocalizedCountryFor(locales[i], locales[i]) ||
- * !hasLocalizedLanguageFor(locales[i], locales[i])) {
- * Log.getLog().print("FAILURE\t"); } else {
- * Log.getLog().print(" \t"); } Log.logln(locales[i] + "\t" +
- * locales[i].getDisplayName(String.ENGLISH) + "\t" +
- * locales[i].getDisplayName(locales[i])); } }
- */
- /**
- * @param sLocs
- */
- private static void showLocales(Set<String> sLocs) {
- for (Iterator<String> it = sLocs.iterator(); it.hasNext();) {
- String s = it.next();
- Log.logln(s + "\t" + ULocale.getDisplayLanguage(s, "en"));
- }
- }
-
- /**
- * @param cols
- * @return
- */
- private static Set<String> filter(Object[] cols) {
- Set<String> result = new TreeSet<String>();
- for (int i = 0; i < cols.length; ++i) {
- String s = cols[i].toString();
- if (s.indexOf('_') >= 0)
- continue;
- result.add(s);
- }
- return result;
- }
-
- Set<String> addULocales(Object[] objects, Set<String> target) {
- for (int i = 0; i < objects.length; ++i) {
- target.add(objects[i].toString());
- }
- return target;
- }
-
- LanguageTagParser ltp = new LanguageTagParser();
-
- private void addLocale(String locale) {
- String lang;
- try {
- lang = ltp.set(locale).getLanguageScript();
- // lang = locale.getLanguage();
- if (lang.length() == 0 || lang.equals("root"))
- return; // skip root
- } catch (RuntimeException e) {
- return; // illegal locale name, must be supplemental
- }
- // ULocale parent = new ULocale(lang);
- // System.out.println(item + ", " + parent);
- parentToLocales.put(lang, locale);
- /*
- * RuleBasedCollator col = cldrCollations.getInstance(item); if (col ==
- * null) { System.out.println("No collator for: " + item); } String
- * rules = col.getRules(); //
- * ((RuleBasedCollator)Collator.getInstance(item)).getRules();
- * rulesToLocales.add(rules, item); localesToRules.put(item, rules);
- */
- }
-
- Set<String> collationLocales = new TreeSet<String>(); // =ULocaleComparator
- // addULocales(Collator.getAvailableULocales(),
- // new
- // TreeSet(ULocaleComparator));
-
- // Set numberLocales = addULocales(NumberFormat.getAvailableLocales(), new
- // TreeSet(ULocaleComparator));
- // Set dateLocales = addULocales(DateFormat.getAvailableLocales(), new
- // TreeSet(ULocaleComparator));
- Set<String> allLocales = new TreeSet<String>(); // ULocaleComparator
-
- // Map localesToRules = new HashMap();
-
- // Relation rulesToLocales = new Relation(new TreeMap(ULocaleComparator),TreeSet.class);
-
- Relation<String, String> parentToLocales = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
-
- /*
- * void getLocaleList() { collationLocales = new TreeSet(ULocaleComparator);
- * collationLocales.addAll(cldrCollations.getAvailableSet());
- *
- * collationLocales = addULocales(new String[] { // HACK "ga", "nl", "pt",
- * "de@collation=phonebook", "es@collation=traditional",
- * "hi@collation=direct", "zh@collation=pinyin", "zh@collation=stroke",
- * "zh@collation=traditional", }, collationLocales);
- *
- * allLocales.addAll(collationLocales); allLocales.addAll(numberLocales);
- * allLocales.addAll(dateLocales); // HACK // get all collations with same
- * rules
- *
- * for (Iterator it = allLocales.iterator(); it.hasNext();) {
- * addLocale((ULocale) it.next()); }
- *
- * String[] others = new String[] { "de@collation=phonebook",
- * "es@collation=traditional", "hi@collation=direct", "zh@collation=pinyin",
- * "zh@collation=stroke", "zh@collation=traditional", }; for (int i = 0; i <
- * others.length; ++i) { addLocale(new ULocale(others[i])); }
- *
- * }
- */
-
- // GenerateCldrDateTimeTests cldrOthers;
- Factory mainCldrFactory;
-
- ICUServiceBuilder icuServiceBuilder;
-
- private static CLDRFile english;
-
- // static Transform<String,ULocale> TO_LOCALE = new Transform<String,ULocale>(){
- // public ULocale transform(String source) {
- // return new ULocale(source);
- // }
- // };
-
- void generate(String pat) throws Exception {
- mainCldrFactory = Factory.make(options[SOURCEDIR].value + "main"
- + File.separator, pat);
- english = mainCldrFactory.make("en", true);
- Factory collationCldrFactory = Factory.make(options[SOURCEDIR].value
- + "collation" + File.separator, pat);
- //Factory supplementalCldrFactory = Factory.make(options[SOURCEDIR].value
- // + "supplemental" + File.separator, ".*");
-
- // allLocales = Builder.with(allLocales)
- // .addAll(mainCldrFactory.getAvailable(), TO_LOCALE)
- // .addAll(collationCldrFactory.getAvailable(), TO_LOCALE)
- // .freeze();
- allLocales.addAll(mainCldrFactory.getAvailable());
- if (!allLocales.containsAll(collationCldrFactory.getAvailable())) {
- System.err.println("Collation locale that is not in main!\t"
- + Builder.with(new TreeSet<String>(collationCldrFactory.getAvailable())).removeAll(allLocales).get());
- }
- allLocales.addAll(collationCldrFactory.getAvailable());
- allLocales = Collections.unmodifiableSet(allLocales);
-
- cldrCollations = new GenerateCldrCollationTests(options[SOURCEDIR].value
- + "collation" + File.separator, pat, allLocales);
- if (options[SHOW].doesOccur)
- cldrCollations.show();
-
- for (Iterator<String> it = cldrCollations.getAvailableSet().iterator(); it
- .hasNext();) {
- collationLocales.add(it.next());
- }
- if (!allLocales.containsAll(collationLocales)) {
- System.err.println("Collation locale that is not in main!\t"
- + Builder.with(new TreeSet<String>(collationLocales)).removeAll(allLocales).get());
- }
- collationLocales = allLocales;
-
- // TODO HACK
- // collationLocales.remove("ar_IN");
- icuServiceBuilder = new ICUServiceBuilder();
- /*
- * cldrOthers = new GenerateCldrDateTimeTests(options[SOURCEDIR].value +
- * "main" + File.separator, pat,
- * !options[GenerateCldrTests.NOT_RESOLVED].doesOccur); if
- * (options[SHOW].doesOccur) cldrOthers.show();
- */
- // getLocaleList();
- for (Iterator<String> it = collationLocales.iterator(); it.hasNext();) {
- addLocale(it.next());
- }
-
- Matcher m = PatternCache.get(pat).matcher("");
- for (Iterator<String> it = parentToLocales.keySet().iterator(); it.hasNext();) {
- String p = it.next();
- if (!m.reset(p).matches())
- continue;
- generate2(p);
- }
- }
-
- private void generate2(String locale) throws Exception {
- System.out.println("Main Generation:\t" + locale);
- out = FileUtilities.openUTF8Writer(options[DESTDIR].value, locale + ".xml");
- out.println("<?xml version='1.0' encoding='UTF-8' ?>");
- out.println(
- // "<!DOCTYPE cldrTest SYSTEM 'http://www.unicode.org/cldr/dtd/1.5/cldrTest.dtd'>"
- // +
- "<!DOCTYPE cldrTest SYSTEM '../common/dtd/cldrTest.dtd'>");
- out.println("<!-- For information, see readme.html -->");
- out.println(" <cldrTest version='" + VERSION +
- "' base='" + locale + "'>");
- CLDRFile localeFile = mainCldrFactory.make(locale, true);
- out.println(" <!-- "
- + TransliteratorUtilities.toXML.transliterate(english.getName(locale)
- + " [" + localeFile.getName(locale))
- + "] -->");
- generateItems(locale, allLocales, NumberShower);
- generateItems(locale, allLocales, DateShower);
- generateItems(locale, allLocales, ZoneFieldShower);
- generateItems(locale, collationLocales, CollationShower);
- out.println(" </cldrTest>");
- out.close();
- ToolUtilities.generateBat(options[SOURCEDIR].value + "test" + File.separator,
- locale + ".xml", options[DESTDIR].value, locale + ".xml",
- new CldrUtility.SimpleLineComparator(0));
- }
-
- /*
- *
- * // first pass through and get all the functional equivalents Map
- * uniqueLocales = new TreeMap();
- *
- * String[] keywords = Collator.getKeywords(); boolean [] isAvailable = new
- * boolean[1]; for (int i = 0; i < locales.length; ++i) { add(locales[i],
- * uniqueLocales); if (true) continue; // TODO restore once Vladimir fixes
- * for (int j = 0; j < keywords.length; ++j) { String[] values =
- * Collator.getKeywordValues(keywords[j]); for (int k = 0; k <
- * values.length; ++k) { // TODO -- for a full job, would do all
- * combinations of different keywords! if (values[k].equals("standard"))
- * continue; add(new ULocale(locales[i] + "@" + keywords[j] + "=" +
- * values[k]), uniqueLocales); //ULocale other =
- * Collator.getFunctionalEquivalent(keywords[j], locales[i], isAvailable); }
- * } } for (int i = 0; i < extras.length; ++i) { add(new ULocale(extras[i]),
- * uniqueLocales); } // items are now sorted by rules. So resort by locale
- * Map toDo = new TreeMap(ULocaleComparator); for (Iterator it =
- * uniqueLocales.keySet().iterator(); it.hasNext();) { Object rules =
- * it.next(); Set s = (Set) uniqueLocales.get(rules); ULocale ulocale =
- * (ULocale) s.iterator().next(); // get first one toDo.put(ulocale, s); }
- * for (Iterator it = toDo.keySet().iterator(); it.hasNext();) { ULocale
- * ulocale = (ULocale) it.next(); Set s = (Set) toDo.get(ulocale);
- * generate(ulocale); }
- */
-
- /**
- * add locale into list. Replace old if shorter
- *
- * @param locale
- */
- void add(String locale, Map<String, Set<String>> uniqueLocales) {
- try {
- RuleBasedCollator col = cldrCollations.getInstance(locale); // (RuleBasedCollator)
- // Collator.getInstance(locale);
- // for our purposes, separate locales if we are using different
- // exemplars
- String key = col.getRules() + "\uFFFF" + getExemplarSet(locale, 0, DraftStatus.unconfirmed);
- Set<String> s = uniqueLocales.get(key);
- if (s == null) {
- s = new TreeSet<String>(ULocaleComparator);
- uniqueLocales.put(key, s);
- }
- System.out.println("Adding " + locale);
- s.add(locale);
- } catch (Throwable e) { // skip
- System.out.println("skipped " + locale);
- }
- }
-
- /**
- * Work-around
- */
- public UnicodeSet getExemplarSet(String locale, int options,
- DraftStatus minimalDraftStatus) {
- String n = locale.toString();
- int pos = n.indexOf('@');
- if (pos >= 0)
- locale = n.substring(0, pos);
- CLDRFile cldrFile = mainCldrFactory.make(locale.toString(), true,
- minimalDraftStatus);
- String v = cldrFile.getStringValue("//ldml/characters/exemplarCharacters");
- UnicodeSet result = new UnicodeSet(v);
- v = cldrFile
- .getStringValue("//ldml/characters/exemplarCharacters[@type=\"auxiliary\"]");
- if (v != null) {
- result.addAll(new UnicodeSet(v));
- }
- if (options == 0)
- result.closeOver(UnicodeSet.CASE);
- return result;
- }
-
- public static final Comparator<Object> ULocaleComparator = new Comparator<Object>() {
- public int compare(Object o1, Object o2) {
- return o1.toString().compareTo(o2.toString());
- }
- };
-
- /*
- * public interface Equator { public boolean equals(Object o1, Object o2); }
- */
- @SuppressWarnings("rawtypes")
- static boolean intersects(Collection a, Collection b) {
- for (Iterator it = a.iterator(); it.hasNext();) {
- if (b.contains(it.next()))
- return true;
- }
- return false;
- }
-
- /*
- * static Collection extract(Object x, Collection a, Equator e, Collection
- * output) { List itemsToRemove = new ArrayList(); for (Iterator it =
- * a.iterator(); it.hasNext();) { Object item = it.next(); if (e.equals(x,
- * item)) { itemsToRemove.add(item); // have to do this because iterator may
- * not allow output.add(item); } } a.removeAll(itemsToRemove); return
- * output; }
- */
- class ResultsPrinter {
- private Set<Map> listOfSettings = new LinkedHashSet<Map>();
-
- private transient LinkedHashMap<String, String> settings = new LinkedHashMap<String, String>();
-
- ResultsPrinter() {
- }
-
- ResultsPrinter(ResultsPrinter rpIncludeDraft, ResultsPrinter rpNoDraft) {
- Set<Map> listOfSettings1 = rpIncludeDraft.getListOfSettings();
- Set<Map> listOfSettings2 = rpNoDraft.getListOfSettings();
- if (listOfSettings1.size() != listOfSettings2.size()) {
- throw new InternalError("can't combine");
- }
- Iterator<Map> it1 = listOfSettings1.iterator();
- Iterator<Map> it2 = listOfSettings2.iterator();
- while (it1.hasNext()) {
- Map settings1 = it1.next();
- Map settings2 = it2.next();
- if (settings1.equals(settings2)) {
- settings1.put("draft", "unconfirmed approved");
- addToListOfSettings(settings1);
- } else {
- // they should only differ by result!
- settings1.put("draft", "unconfirmed");
- addToListOfSettings(settings1);
- settings2.put("draft", "approved");
- addToListOfSettings(settings2);
- }
- }
- }
-
- private void addToListOfSettings(Map settings1) {
- for (Object key : settings1.keySet()) {
- if (key == null || settings1.get(key) == null) {
- throw new IllegalArgumentException("null key or value in settings.");
- }
- }
- listOfSettings.add(settings1);
- }
-
- void set(String name, String value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("null key or value in settings.");
- }
- settings.put(name, value);
- }
-
- void setResult(String result) {
- if (result == null) {
- throw new IllegalArgumentException("null key or value in settings.");
- }
- settings.put("result", result);
- addToListOfSettings((Map) settings.clone());
- }
-
- void print() {
- Map oldSettings = new TreeMap();
- for (Iterator it2 = getListOfSettings().iterator(); it2.hasNext();) {
- Map settings = (Map) it2.next();
- String result = (String) settings.get("result");
- out.print(" <result");
- for (Iterator it = settings.keySet().iterator(); it.hasNext();) {
- Object key = it.next();
- if (key.equals("result"))
- continue;
- Object value = settings.get(key);
- if (!value.equals(oldSettings.get(key))) {
- out.print(" " + key + "='"
- + TransliteratorUtilities.toXML.transliterate(value.toString())
- + "'");
- }
- }
- out.println(">" + TransliteratorUtilities.toXML.transliterate(result)
- + "</result>");
- oldSettings = settings;
- }
- }
-
- public boolean equals(Object other) {
- try {
- ResultsPrinter that = (ResultsPrinter) other;
- return getListOfSettings().equals(that.getListOfSettings());
- } catch (Exception e) {
- return false;
- }
- }
-
- public int hashCode() {
- throw new IllegalArgumentException();
- }
-
- /**
- *
- */
-
- private void setListOfSettings(Set listOfSettings) {
- this.listOfSettings = listOfSettings;
- }
-
- private Set<Map> getListOfSettings() {
- return Collections.unmodifiableSet(listOfSettings);
- }
- }
-
- abstract class DataShower {
- abstract ResultsPrinter show(String first_locale, DraftStatus minimalDraftStatus);
-
- ResultsPrinter show(String first) throws Exception {
- ResultsPrinter rpIncludeDraft = show(first, DraftStatus.unconfirmed);
- ResultsPrinter rpNoDraft = show(first, DraftStatus.approved);
- return new ResultsPrinter(rpIncludeDraft, rpNoDraft);
- }
-
- abstract String getElement();
- }
-
- interface DataShower2 {
- void show(ULocale first, Collection others) throws Exception;
- }
-
- private void generateItems(String locale, Collection<String> onlyLocales,
- DataShower generator) throws Exception {
- Set<String> sublocales = new TreeSet<String>(); // ULocaleComparator
- sublocales.add(locale);
- sublocales.addAll(parentToLocales.getAll(locale));
- sublocales.retainAll(onlyLocales);
- Map<String, ResultsPrinter> locale_results = new TreeMap<String, ResultsPrinter>(ULocaleComparator);
- for (Iterator<String> it = sublocales.iterator(); it.hasNext();) {
- String current = it.next();
- locale_results.put(current, generator.show(current));
- }
- // do it this way so that the locales stay in order
- Set<String> matchingLocales = new TreeSet<String>(ULocaleComparator);
- while (sublocales.size() != 0) {
- String first = sublocales.iterator().next();
- ResultsPrinter r = locale_results.get(first);
- for (Iterator<String> it = sublocales.iterator(); it.hasNext();) {
- String other = it.next();
- ResultsPrinter r2 = locale_results.get(other);
- if (r2.equals(r))
- matchingLocales.add(other);
- }
- showLocales(generator.getElement(), matchingLocales);
- r.print();
- out.println(" </" + generator.getElement() + ">");
- sublocales.removeAll(matchingLocales);
- matchingLocales.clear();
- }
- //Comparator c;
- }
-
- public void showLocales(String elementName, Collection<String> others) {
- // System.out.println(elementName + ": " + locale);
- out.println(" <" + elementName + " ");
- StringBuffer comment = new StringBuffer();
- if (others != null && others.size() != 0) {
- out.print("locales='");
- boolean first = true;
- for (Iterator<String> it = others.iterator(); it.hasNext();) {
- if (first)
- first = false;
- else {
- out.print(" ");
- comment.append("; ");
- }
- String loc = it.next();
- out.print(loc);
- comment.append(english.getName(loc) + " ["
- + getNativeName(loc) + "]");
- }
- out.print("'");
- }
- out.println(">");
- out.println("<!-- "
- + TransliteratorUtilities.toXML.transliterate(comment.toString())
- + " -->");
- }
-
- private String getNativeName(String loc) {
- int atPos = loc.indexOf('@');
- String keywords = "";
- if (atPos >= 0) {
- keywords = loc.substring(atPos + 1);
- loc = loc.substring(0, atPos);
- }
- return mainCldrFactory.make(loc, true).getName(loc) + "@" + keywords;
- }
-
- DataShower ZoneFieldShower = new DataShower() {
-
- // Set zones = new
- // TreeSet(sc.getAvailableCodes("tzid"));
- List<String> zones = Arrays.asList(new String[] { "America/Los_Angeles",
- "America/Argentina/Buenos_Aires", "America/Buenos_Aires",
- "America/Havana", "Australia/ACT", "Australia/Sydney", "Europe/London",
- "Europe/Moscow", "Etc/GMT+3" });
-
- String[] perZoneSamples = { "Z", "ZZZZ", "z", "zzzz", "v", "vvvv", "V", "VVVV" };
-
- String[] dates = { "2004-01-15T12:00:00Z", "2004-07-15T12:00:00Z" };
-
- public ResultsPrinter show(String first, DraftStatus minimalDraftStatus) {
- TimezoneFormatter tzf = new TimezoneFormatter(mainCldrFactory, first
- .toString(), minimalDraftStatus);
- ResultsPrinter rp = new ResultsPrinter();
- if (!METAZONES_WORK) {
- return rp;
- }
- // TODO Auto-generated
- // method stub
- ParsePosition parsePosition = new ParsePosition(0);
- for (Iterator<String> it = zones.iterator(); it.hasNext();) {
- String tzid = it.next();
- rp.set("zone", tzid);
- for (int j = 0; j < dates.length; ++j) {
- String date = dates[j];
- Date datetime;
- try {
- datetime = ICUServiceBuilder.isoDateParse(date);
- } catch (ParseException e1) {
- throw new IllegalArgumentException(e1);
- }
- rp.set("date", dates[j]);
- for (int i = 0; i < perZoneSamples.length; ++i) {
- try {
- String pattern = perZoneSamples[i];
- if (!METAZONES_WORK && (pattern.contains("z") || pattern.contains("V"))) {
- continue;
- }
- rp.set("field", pattern);
- String formatted = tzf.getFormattedZone(tzid, pattern, datetime.getTime(), false);
- parsePosition.setIndex(0);
- String parsed = tzf.parse(formatted, parsePosition);
- if (parsed == null) {
- // for
- // debugging
- formatted = tzf.getFormattedZone(tzid, pattern, datetime.getTime(), false);
- parsePosition.setIndex(0);
- parsed = tzf.parse(formatted, parsePosition);
- }
- rp.set("parse", parsed);
- rp.setResult(formatted);
- } catch (RuntimeException e) {
- throw (IllegalArgumentException) new IllegalArgumentException(
- "Failure in " + first).initCause(e);
- }
- }
- }
- }
- return rp;
- /*
- * Date datetime = ICUServiceBuilder .isoDateParse (samples[j]);
- * rp.set("input", ICUServiceBuilder .isoDateFormat (datetime));
- */
- }
-
- public String getElement() {
- return "zoneFields";
- }
- };
-
- DataShower DateShower = new DataShower() {
- public ResultsPrinter show(String locale, DraftStatus minimalDraftStatus) {
- String[] samples = { "1900-01-31T00:00:00Z", "1909-02-28T00:00:01Z",
- "1918-03-26T00:59:59Z", "1932-04-24T01:00:00Z",
- "1945-05-20T01:00:01Z", "1952-06-18T11:59:59Z",
- "1973-07-16T12:00:00Z", "1999-08-14T12:00:01Z",
- "2000-09-12T22:59:59Z", "2001-10-08T23:00:00Z",
- "2004-11-04T23:00:01Z", "2010-12-01T23:59:59Z", };
- CLDRFile cldrFile = mainCldrFactory.make(locale.toString(), true,
- minimalDraftStatus);
- icuServiceBuilder.setCldrFile(cldrFile);
- ResultsPrinter rp = new ResultsPrinter();
- for (int j = 0; j < samples.length; ++j) {
- Date datetime;
- try {
- datetime = ICUServiceBuilder.isoDateParse(samples[j]);
- } catch (ParseException e) {
- throw new IllegalArgumentException(e);
- }
- rp.set("input", ICUServiceBuilder.isoDateFormat(datetime));
- for (int i = 0; i < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++i) {
- rp.set("dateType", ICUServiceBuilder.getDateNames(i));
- for (int k = 0; k < ICUServiceBuilder.LIMIT_DATE_FORMAT_INDEX; ++k) {
- if (i == 0 && k == 0)
- continue;
- DateFormat df = icuServiceBuilder.getDateFormat("gregorian", i, k);
- String pattern = ((SimpleDateFormat) df).toPattern();
- if (!METAZONES_WORK && (pattern.contains("z") || pattern.contains("V"))) {
- continue;
- }
- rp.set("timeType", ICUServiceBuilder.getDateNames(k));
- if (false && i == 2 && k == 0) {
- System.out.println("debug: date "
- + icuServiceBuilder.getDateNames(i) + ", time "
- + icuServiceBuilder.getDateNames(k) + " = "
- + df.format(datetime));
- }
- rp.setResult(df.format(datetime));
- }
- }
- }
- return rp;
- }
-
- public String getElement() {
- return "date";
- }
- };
-
- DataShower NumberShower = new DataShower() {
- public ResultsPrinter show(String locale, DraftStatus minimalDraftStatus) {
- CLDRFile cldrFile = mainCldrFactory.make(locale.toString(), true,
- minimalDraftStatus);
- icuServiceBuilder.setCldrFile(cldrFile);
-
- double[] samples = { 0, 0.01, -0.01, 1, -1, 123.456, -123.456, 123456.78,
- -123456.78, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
- Double.NaN };
- ResultsPrinter rp = new ResultsPrinter();
- for (int j = 0; j < samples.length; ++j) {
- double sample = samples[j];
- rp.set("input", String.valueOf(sample));
- for (int i = 0; i < ICUServiceBuilder.LIMIT_NUMBER_INDEX; ++i) {
- rp.set("numberType", icuServiceBuilder.getNumberNames(i));
- DecimalFormat nf = icuServiceBuilder.getNumberFormat(i);
- String formatted = nf.format(sample);
- if (formatted.indexOf("NaNNaN") >= 0) {
- formatted = nf.format(sample); // for
- // debugging
- }
- rp.setResult(formatted);
- }
- }
- return rp;
- }
-
- public String getElement() {
- return "number";
- }
- };
-
- // ========== COLLATION ==========
-
- /*
- * Equator CollationEquator = new Equator() {
- *//**
- * Must both be ULocales
- */
- /*
- * public boolean equals(Object o1, Object o2) { try { ULocale loc1 =
- * (ULocale) o1; ULocale loc2 = (ULocale) o2; if (loc1.equals(loc2)) return
- * true; return
- * cldrCollations.getInstance(loc1).equals(cldrCollations.getInstance
- * (loc2)); } catch (RuntimeException e) { System.out.println("Failed on: "
- * + o1 + " ;\t" + o2); throw e; } } };
- */static ULocale zhHack = new ULocale("zh"); // FIXME
- // hack
- // for
- // zh
-
- DataShower CollationShower = new DataShower() {
- public ResultsPrinter show(String locale, DraftStatus minimalDraftStatus) {
- // if
- // (locale.equals(zhHack))
- // return;
-
- Collator col = cldrCollations.getInstance(locale); // Collator.getInstance(locale);
-
- UnicodeSet tailored = new UnicodeSet();
- if (col != null) {
- tailored = col.getTailoredSet();
- if (new LanguageTagParser().set(locale).getLanguage().equals("zh")) {
- tailored.addAll(new UnicodeSet("[[a-z]-[v]]"));
- Log.logln("HACK for Pinyin");
- }
- tailored = createCaseClosure(tailored);
- tailored = nfc(tailored);
- } else {
- System.out.println("No collation for: " + locale);
- col = cldrCollations.getInstance("root");
- }
- // System.out.println(tailored.toPattern(true));
-
- UnicodeSet exemplars = getExemplarSet(locale, UnicodeSet.CASE,
- minimalDraftStatus);
- // add all the exemplars
-
- exemplars = createCaseClosure(exemplars);
- exemplars = nfc(exemplars);
- // System.out.println(exemplars.toPattern(true));
- tailored.addAll(exemplars);
- // UnicodeSet
- // tailoredMinusHan = new
- // UnicodeSet(tailored).removeAll(SKIP_COLLATION_SET);
- if (!exemplars.containsAll(tailored)) {
- // BagFormatter bf =
- // new
- // BagFormatter();
- Log.logln("In Tailored, but not Exemplar; Locale: " + locale + "\t"
- + english.getName(locale));
- Log.logln(new UnicodeSet(tailored).removeAll(exemplars)
- .toPattern(false));
- // bf.(log,"tailored",
- // tailored,
- // "exemplars",
- // exemplars);
- Log.getLog().flush();
- }
- tailored.addAll(new UnicodeSet("[\\ .02{12}]"));
- tailored.removeAll(SKIP_COLLATION_SET);
-
- SortedBag bag = new SortedBag(col);
- return doCollationResult(col, tailored, bag);
- }
-
- public String getElement() {
- return "collation";
- }
- };
-
- /*
- * public void show(ULocale locale, Collection others) {
- * showLocales("collation", others);
- *
- * Collator col = cldrCollations.getInstance(locale); //
- * Collator.getInstance(locale);
- *
- * UnicodeSet tailored = col.getTailoredSet(); if
- * (locale.getLanguage().equals("zh")) { tailored.addAll(new
- * UnicodeSet("[[a-z]-[v]]")); log.println("HACK for Pinyin"); } tailored =
- * createCaseClosure(tailored); tailored = nfc(tailored);
- * //System.out.println(tailored.toPattern(true));
- *
- * UnicodeSet exemplars = getExemplarSet(locale, UnicodeSet.CASE); // add
- * all the exemplars if (false) for (Iterator it = others.iterator();
- * it.hasNext(); ) { exemplars.addAll(getExemplarSet((ULocale)it.next(),
- * UnicodeSet.CASE)); }
- *
- * exemplars = createCaseClosure(exemplars); exemplars = nfc(exemplars);
- * //System.out.println(exemplars.toPattern(true));
- * tailored.addAll(exemplars); //UnicodeSet tailoredMinusHan = new
- * UnicodeSet(tailored).removeAll(SKIP_COLLATION_SET); if
- * (!exemplars.containsAll(tailored)) { //BagFormatter bf = new
- * BagFormatter(); log.println("In Tailored, but not Exemplar; Locale: " +
- * locale + "\t" + locale.getDisplayName()); log.println(new
- * UnicodeSet(tailored).removeAll(exemplars).toPattern(false));
- * //bf.(log,"tailored", tailored, "exemplars", exemplars); log.flush(); }
- * tailored.addAll(new UnicodeSet("[\\ .02{12}]"));
- * tailored.removeAll(SKIP_COLLATION_SET);
- *
- * SortedBag bag = new SortedBag(col); doCollationResult(col, tailored,
- * bag); out.println(" </collation>"); }};
- */
- static final UnicodeSet SKIP_COLLATION_SET = new UnicodeSet(
- "[[:script=han:][:script=hangul:]-[\u4e00-\u4eff \u9f00-\u9fff \uac00-\uacff \ud700-\ud7ff]]");
-
- /**
- * @param col
- * @param tailored
- * @param bag
- */
- private ResultsPrinter doCollationResult(Collator col, UnicodeSet tailored,
- SortedBag bag) {
- for (UnicodeSetIterator usi = new UnicodeSetIterator(tailored); usi.next();) {
- String s = usi.getString();
- bag.add('x' + s);
- bag.add('X' + s);
- bag.add('x' + s + 'x');
- }
- // out.println(" <set locale='" + locale + "'/>");
- /*
- * if (others != null) for (Iterator it = others.iterator();
- * it.hasNext(); ) { ULocale uloc = (ULocale) it.next(); if
- * (uloc.equals(locale)) continue; out.println(" <other locale='" +
- * uloc + "'/>"); }
- */
- String last = "";
- boolean needEquals = false;
- StringBuffer tempResult = new StringBuffer(CldrUtility.LINE_SEPARATOR);
- for (Iterator<String> it = bag.iterator(); it.hasNext();) {
- String s = it.next();
- if (col.compare(s, last) != 0) {
- if (needEquals)
- tempResult.append(last).append(CldrUtility.LINE_SEPARATOR);
- needEquals = false;
- last = s;
- } else {
- needEquals = true;
- }
- tempResult.append(TransliteratorUtilities.toXML.transliterate(s)).append(
- CldrUtility.LINE_SEPARATOR);
- }
- ResultsPrinter result = new ResultsPrinter();
- result.setResult(tempResult.toString());
- return result;
- }
-
- static public Set<String> getMatchingXMLFiles(String dir, String localeRegex) {
- Matcher m = PatternCache.get(localeRegex).matcher("");
- Set<String> s = new TreeSet<String>();
- File[] files = new File(dir).listFiles();
- for (int i = 0; i < files.length; ++i) {
- String name = files[i].getName();
- if (!name.endsWith(".xml"))
- continue;
- if (name.startsWith("supplementalData"))
- continue;
- String locale = name.substring(0, name.length() - 4); // drop .xml
- if (!locale.equals("root") && !m.reset(locale).matches())
- continue;
- s.add(locale);
- }
- return s;
- }
-
- /*
- * public static boolean isDraft(Node node) { for (; node.getNodeType() !=
- * Node.DOCUMENT_NODE; node = node.getParentNode()){ NamedNodeMap attributes
- * = node.getAttributes(); if (attributes == null) continue; for (int i = 0;
- * i < attributes.getLength(); ++i) { Node attribute = attributes.item(i);
- * if (attribute.getNodeName().equals("draft") &&
- * attribute.getNodeValue().equals("true")) return true; } } return false; }
- */
- public static String getXPath(Node node) {
- StringBuffer xpathFragment = new StringBuffer();
- StringBuffer xpath = new StringBuffer();
- for (; node.getNodeType() != Node.DOCUMENT_NODE; node = node
- .getParentNode()) {
- xpathFragment.setLength(0);
- xpathFragment.append('/').append(node.getNodeName());
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- for (int i = 0; i < attributes.getLength(); ++i) {
- Node attribute = attributes.item(i);
- xpathFragment.append("[@").append(attribute.getNodeName())
- .append('=').append(attribute.getNodeValue()).append(']');
- }
- }
- xpath.insert(0, xpathFragment);
- }
- xpath.insert(0, '/');
- return xpath.toString();
- }
-
- public static String replace(String source, String pattern, String replacement) {
- // dumb code for now
- for (int pos = source.indexOf(pattern, 0); pos >= 0; pos = source.indexOf(
- pattern, pos + 1)) {
- source = source.substring(0, pos) + replacement
- + source.substring(pos + pattern.length());
- }
- return source;
- }
-
- public static interface Apply {
- String apply(String source);
- }
-
- static UnicodeSet apply(UnicodeSet source, Apply apply) {
- UnicodeSet target = new UnicodeSet();
- for (UnicodeSetIterator usi = new UnicodeSetIterator(source); usi.next();) {
- String s = usi.getString();
- target.add(apply.apply(s));
- }
- return target;
- }
-
- static UnicodeSet nfc(UnicodeSet source) {
- return apply(source, new Apply() {
- public String apply(String source) {
- return Normalizer.compose(source, false);
- }
- });
- }
-
- public static interface CloseCodePoint {
- /**
- * @param cp
- * code point to get closure for
- * @param toAddTo
- * Unicode set for the closure
- * @return toAddTo (for chaining)
- */
- UnicodeSet close(int cp, UnicodeSet toAddTo);
- }
-
- public static UnicodeSet createCaseClosure(UnicodeSet source) {
- UnicodeSet target = new UnicodeSet();
- for (UnicodeSetIterator usi = new UnicodeSetIterator(source); usi.next();) {
- String s = usi.getString();
- UnicodeSet temp = createClosure(s, CCCP);
- if (temp == null)
- target.add(s);
- else
- target.addAll(temp);
- }
- return target;
- }
-
- public static class UnicodeSetComparator implements Comparator<Object> {
- UnicodeSetIterator ait = new UnicodeSetIterator();
-
- UnicodeSetIterator bit = new UnicodeSetIterator();
-
- public int compare(Object o1, Object o2) {
- if (o1 == o2)
- return 0;
- if (o1 == null)
- return -1;
- if (o2 == null)
- return 1;
- UnicodeSet a = (UnicodeSet) o1;
- UnicodeSet b = (UnicodeSet) o2;
- if (a.size() != b.size()) {
- return a.size() < b.size() ? -1 : 1;
- }
- ait.reset(a);
- bit.reset(b);
- while (ait.nextRange()) {
- bit.nextRange();
- if (ait.codepoint != bit.codepoint) {
- return ait.codepoint < bit.codepoint ? -1 : 1;
- }
- if (ait.codepoint == UnicodeSetIterator.IS_STRING) {
- int result = ait.string.compareTo(bit.string);
- if (result != 0)
- return result;
- } else if (ait.codepointEnd != bit.codepointEnd) {
- return ait.codepointEnd < bit.codepointEnd ? -1 : 1;
- }
- }
- return 0;
- }
- }
-
- public static final CloseCodePoint CCCP = new CloseCodePoint() {
- Locale locale = Locale.ENGLISH;
-
- UnicodeSet NONE = new UnicodeSet();
-
- UnicodeMap<UnicodeSet> map = new UnicodeMap<UnicodeSet>(); // new
-
- // UnicodeSetComparator()
-
- public UnicodeSet close(int cp, UnicodeSet toAddTo) {
- UnicodeSet result = map.getValue(cp);
- if (result == null) {
- result = new UnicodeSet();
- result.add(cp);
- String s = UCharacter.toLowerCase(locale, UTF16.valueOf(cp));
- result.add(s);
- s = UCharacter.toUpperCase(locale, UTF16.valueOf(cp));
- result.add(s);
- s = UCharacter.toTitleCase(locale, UTF16.valueOf(cp), null);
- result.add(s);
- // special hack
- if (result.contains("SS"))
- result.add("sS").add("ss");
- if (result.size() == 1)
- result = NONE;
- map.put(cp, result);
- }
- if (result != NONE)
- toAddTo.addAll(result);
- else
- toAddTo.add(cp);
- return toAddTo;
- }
- };
-
- public static UnicodeSet createClosure(String source, CloseCodePoint closer) {
- return createClosure(source, 0, closer);
- }
-
- public static UnicodeSet createClosure(String source, int position,
- CloseCodePoint closer) {
- UnicodeSet result = new UnicodeSet();
- // if at end, return empty set
- if (position >= source.length())
- return result;
- int cp = UTF16.charAt(source, position);
- // if last character, return its set
- int endPosition = position + UTF16.getCharCount(cp);
- if (endPosition >= source.length())
- return closer.close(cp, result);
- // otherwise concatenate its set with the remainder
- UnicodeSet remainder = createClosure(source, endPosition, closer);
- return createAppend(closer.close(cp, result), remainder);
- }
-
- /**
- * Produce the result of appending each element of this to each element of
- * other. That is, [a{cd}] + [d{ef}] => [{ad}{aef}{cdd}{cdef}]
- */
- public static UnicodeSet createAppend(UnicodeSet a, UnicodeSet b) {
- UnicodeSet target = new UnicodeSet();
- for (UnicodeSetIterator usi = new UnicodeSetIterator(a); usi.next();) {
- String s = usi.getString();
- for (UnicodeSetIterator usi2 = new UnicodeSetIterator(b); usi2.next();) {
- String s2 = usi2.getString();
- target.add(s + s2);
- }
- }
- return target;
- }
-}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateComparison.java b/tools/java/org/unicode/cldr/tool/GenerateComparison.java
index c81b900..2779139 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateComparison.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateComparison.java
@@ -16,11 +16,11 @@
import org.unicode.cldr.util.Counter;
import org.unicode.cldr.util.EscapingUtilities;
import org.unicode.cldr.util.Factory;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PrettyPath;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.Timer;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.text.Collator;
@@ -36,6 +36,7 @@
static class EnglishRowComparator implements Comparator<R2<String, String>> {
private static Comparator<String> unicode = new UTF16.StringComparator(true, false, 0);
+ @Override
public int compare(R2<String, String> arg0, R2<String, String> arg1) {
int result = collator.compare(arg0.get0(), arg1.get0());
if (result != 0) return result;
@@ -61,16 +62,19 @@
format = NumberFormat.getNumberInstance();
format.setGroupingUsed(true);
- Counter<String> totalCounter = new Counter<String>();
+ Counter<String> totalCounter = new Counter<>();
// Get the args
- String oldDirectory = CldrUtility.getProperty("oldDirectory", new File(CLDRPaths.BASE_DIRECTORY,
- "common/main").getCanonicalPath() + "/");
- String newDirectory = CldrUtility.getProperty("newDirectory", new File(CLDRPaths.BASE_DIRECTORY,
- "../cldr-release-1-7/common/main").getCanonicalPath() + "/");
- String changesDirectory = CldrUtility.getProperty("changesDirectory", new File(CLDRPaths.CHART_DIRECTORY
- + "/changes/").getCanonicalPath()
+ String oldDirectory = CldrUtility.getProperty("oldDirectory", PathUtilities.getNormalizedPathString(new File(
+ CLDRPaths.BASE_DIRECTORY,
+ "common/main")) + "/");
+ String newDirectory = CldrUtility.getProperty("newDirectory", PathUtilities.getNormalizedPathString(new File(
+ CLDRPaths.BASE_DIRECTORY,
+ "../cldr-release-1-7/common/main")) + "/");
+ String changesDirectory = CldrUtility.getProperty("changesDirectory", PathUtilities
+ .getNormalizedPathString(CLDRPaths.CHART_DIRECTORY
+ + "/changes/")
+ "/");
String filter = CldrUtility.getProperty("localeFilter", ".*");
@@ -87,9 +91,9 @@
Set<String> oldList = oldFactory.getAvailableLanguages();
Set<String> newList = newFactory.getAvailableLanguages();
- Set<String> unifiedList = new HashSet<String>(oldList);
+ Set<String> unifiedList = new HashSet<>(oldList);
unifiedList.addAll(newList);
- Set<R2<String, String>> pairs = new TreeSet<R2<String, String>>();
+ Set<R2<String, String>> pairs = new TreeSet<>();
for (String code : unifiedList) {
pairs.add(Row.of(english.getName(code), code));
}
@@ -98,7 +102,7 @@
int totalDifferences = 0;
int differences = 0;
- Set<R2<String, String>> indexInfo = new TreeSet<R2<String, String>>(ENG);
+ Set<R2<String, String>> indexInfo = new TreeSet<>(ENG);
// iterate through those
for (R2<String, String> pair : pairs) {
@@ -162,12 +166,12 @@
Set<String> paths;
try {
- paths = new HashSet<String>();
- CollectionUtilities.addAll(oldFile.iterator(), paths);
+ paths = new HashSet<>();
+ oldFile.forEach(paths::add);
if (oldList.contains(locale)) {
paths.addAll(oldFile.getExtraPaths());
}
- CollectionUtilities.addAll(newFile.iterator(), paths);
+ newFile.forEach(paths::add);
if (newList.contains(locale)) {
paths.addAll(newFile.getExtraPaths());
}
@@ -206,7 +210,7 @@
.addColumn("Status").setSortPriority(4).setCellAttributes("class=\"{0}\"")
.addColumn("Old" + localeDisplayName).setCellAttributes("class='old'")
.addColumn("New" + localeDisplayName).setCellAttributes("class='new'");
- Counter<String> fileCounter = new Counter<String>();
+ Counter<String> fileCounter = new Counter<>();
for (String path : paths) {
if (path.contains("/alias") || path.contains("/identity")) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateCoverageLevels.java b/tools/java/org/unicode/cldr/tool/GenerateCoverageLevels.java
index 8a9c32c..8a2273d 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateCoverageLevels.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateCoverageLevels.java
@@ -98,7 +98,7 @@
String locale = "en";
Set<String> sorted = Builder.with(new TreeSet<String>()).addAll(cldrFile.iterator())
.addAll(cldrFile.getExtraPaths()).get();
- Set<R3<Level, String, Inheritance>> items = new TreeSet<R3<Level, String, Inheritance>>(new RowComparator());
+ Set<R3<Level, String, Inheritance>> items = new TreeSet<>(new RowComparator());
for (String path : sorted) {
if (path.endsWith("/alias")) {
continue;
@@ -121,6 +121,7 @@
private static class RowComparator implements Comparator<R3<Level, String, Inheritance>> {
+ @Override
public int compare(R3<Level, String, Inheritance> o1, R3<Level, String, Inheritance> o2) {
int result = o1.get0().compareTo(o2.get0());
if (result != 0) return result;
@@ -166,7 +167,7 @@
Inheritance lastInheritance;
int count = 0;
- TreeMap<String, Relation<String, String>> differences = new TreeMap<String, Relation<String, String>>();
+ TreeMap<String, Relation<String, String>> differences = new TreeMap<>();
R5<Level, Inheritance, Integer, String, TreeMap<String, Relation<String, String>>> add(
R3<Level, String, Inheritance> next) {
@@ -192,7 +193,7 @@
R5<Level, Inheritance, Integer, String, TreeMap<String, Relation<String, String>>> results = Row.of(
lastLevel, lastInheritance, count - 1, lastParts.toString().replace("/", "\u200B/"), differences);
lastParts = nextParts;
- differences = new TreeMap<String, Relation<String, String>>();
+ differences = new TreeMap<>();
nextParts = new XPathParts();
lastLevel = level;
lastInheritance = inherited;
@@ -213,7 +214,7 @@
}
private XPathParts setNewParts(String path) {
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for removeElement
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); // not frozen, for removeElement
if (path.startsWith("//ldml/dates/timeZoneNames/metazone")
|| path.startsWith("//ldml/dates/timeZoneNames/zone")) {
String element = nextParts.getElement(-1);
@@ -284,12 +285,12 @@
decimal.setMaximumFractionDigits(2);
percent.setMaximumFractionDigits(2);
NumberFormat integer = NumberFormat.getIntegerInstance();
- Set<String> localesFound = new TreeSet<String>();
+ Set<String> localesFound = new TreeSet<>();
// get list of locales
LocaleLevelData mapLevelData = new LocaleLevelData();
- TreeSet<String> mainAvailableSource = new TreeSet<String>(cldrFactory.getAvailable());
- TreeSet<String> mainAvailable = new TreeSet<String>();
+ TreeSet<String> mainAvailableSource = new TreeSet<>(cldrFactory.getAvailable());
+ TreeSet<String> mainAvailable = new TreeSet<>();
Relation<String, String> localeToVariants = Relation.of(new HashMap(), HashSet.class);
for (String locale : mainAvailableSource) {
if (localeFilter.skipLocale(locale, localeToVariants)) {
@@ -299,8 +300,8 @@
}
System.out.println("gathering rbnf data");
- Set<String> ordinals = new TreeSet<String>();
- Set<String> spellout = new TreeSet<String>();
+ Set<String> ordinals = new TreeSet<>();
+ Set<String> spellout = new TreeSet<>();
localesFound.clear();
for (String locale : rbnfFactory.getAvailable()) {
if (localeFilter.skipLocale(locale, null)) continue;
@@ -316,7 +317,7 @@
}
System.out.println("gathering plural data");
- localesFound = new TreeSet<String>(supplementalData.getPluralLocales(PluralType.cardinal));
+ localesFound = new TreeSet<>(supplementalData.getPluralLocales(PluralType.cardinal));
markData("Plurals", localesFound, mapLevelData, mainAvailable, PLURALS_LEVEL, PLURALS_WEIGHT,
Row.of("//supplementalData/plurals", "UCA"));
@@ -481,6 +482,7 @@
return result != LocaleStatus.BASE;
}
+ @Override
public LocaleStatus transform(String locale) {
ltp.set(locale);
if (checkAliases) {
@@ -503,6 +505,7 @@
private static class BooleanLocaleFilter implements Transform<String, Boolean> {
private final LocaleFilter filter = new LocaleFilter(false);
+ @Override
public Boolean transform(String locale) {
return filter.transform(locale) == LocaleStatus.BASE ? Boolean.TRUE : Boolean.FALSE;
}
@@ -575,14 +578,14 @@
}
static class LevelData {
- Counter<Level> missing = new Counter<Level>();
+ Counter<Level> missing = new Counter<>();
Relation<Level, R2<String, String>> samples = Relation.of(new EnumMap<Level, Set<R2<String, String>>>(
Level.class), LinkedHashSet.class);
- Counter<Level> found = new Counter<Level>();
+ Counter<Level> found = new Counter<>();
}
static class LocaleLevelData {
- Map<String, LevelData> locale_levelData = new TreeMap<String, LevelData>();
+ Map<String, LevelData> locale_levelData = new TreeMap<>();
public LevelData get(String locale) {
if (locale.equals("zh_Hans") || locale.equals("iw")) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateDayPeriods.java b/tools/java/org/unicode/cldr/tool/GenerateDayPeriods.java
index 2bc111f..801348c 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateDayPeriods.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateDayPeriods.java
@@ -28,7 +28,7 @@
public static void main(String[] args) throws IOException {
try (PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY + "/supplemental", "dayPeriods.xml")) {
out.println(DtdType.supplementalData.header(MethodHandles.lookup().lookupClass())
- + "\t<version number=\"$Revision" /* bypass SVN */ + "$\"/>");
+ + "\t<version number=\"$Revision" + "$\"/>");
Factory factory = CLDRConfig.getInstance().getCldrFactory();
for (Type type : Type.values()) {
out.println("\t<dayPeriodRuleSet"
diff --git a/tools/java/org/unicode/cldr/tool/GenerateDerivedAnnotations.java b/tools/java/org/unicode/cldr/tool/GenerateDerivedAnnotations.java
index 8c8416d..aaebeef 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateDerivedAnnotations.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateDerivedAnnotations.java
@@ -5,17 +5,24 @@
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.unicode.cldr.draft.FileUtilities;
import org.unicode.cldr.test.DisplayAndInputProcessor;
+import org.unicode.cldr.tool.Option.Options;
+import org.unicode.cldr.tool.Option.Params;
import org.unicode.cldr.util.Annotations;
import org.unicode.cldr.util.Annotations.AnnotationSet;
import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRPaths;
+import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.Emoji;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.Level;
@@ -24,7 +31,10 @@
import org.unicode.cldr.util.XPathParts.Comments.CommentType;
import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSortedSet;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.impl.locale.XCldrStub.ImmutableMap;
import com.ibm.icu.text.UnicodeSet;
public class GenerateDerivedAnnotations {
@@ -38,24 +48,79 @@
.add(Annotations.MISSING_MARKER)
.freeze();
+ static Map<String,String> codepointToIsoCurrencyCode;
+ static {
+ final Splitter tabSplitter = Splitter.on('\t').trimResults();
+ Map<String,String> _codepointToIsoCurrencyCode = new TreeMap<>();
+ for (String line : FileUtilities.in(CldrUtility.class, "data/codepointToIsoCurrencyCode.tsv")) {
+ if (line.startsWith("#")) {
+ continue;
+ }
+ List<String> parts = tabSplitter.splitToList(line);
+ _codepointToIsoCurrencyCode.put(parts.get(0), parts.get(1));
+ }
+ codepointToIsoCurrencyCode = ImmutableMap.copyOf(_codepointToIsoCurrencyCode);
+ }
+
+ private enum MyOptions {
+ fileFilter(new Params().setHelp("filter files by dir/locale, eg: ^main/en$ or .*/en").setMatch(".*").setDefault(".*")),
+ missing(new Params().setHelp("only missing").setMatch("")),
+ ;
+
+ // BOILERPLATE TO COPY
+ final Option option;
+
+ private MyOptions(Params params) {
+ option = new Option(this, params);
+ }
+
+ private static Options myOptions = new Options();
+ static {
+ for (MyOptions option : MyOptions.values()) {
+ myOptions.add(option, option.option);
+ }
+ }
+
+ private static Set<String> parse(String[] args) {
+ return myOptions.parse(MyOptions.values()[0], args, true);
+ }
+ }
+
public static void main(String[] args) throws IOException {
- boolean missingOnly = args.length > 0 && args[0].equals("missing");
+ MyOptions.parse(args);
+
+ boolean missingOnly = MyOptions.missing.option.doesOccur();
if (missingOnly) {
System.out.println("With the 'missing' argument files will not be written, only the missing items will be written to the console");
}
+ Matcher localeMatcher = Pattern.compile(MyOptions.fileFilter.option.getValue()).matcher("");
Joiner BAR = Joiner.on(" | ");
AnnotationSet enAnnotations = Annotations.getDataSet("en");
CLDRFile english = CLDR_CONFIG.getEnglish();
- UnicodeSet derivables = new UnicodeSet(Emoji.getAllRgiNoES()).removeAll(enAnnotations.keySet()).freeze();
+ UnicodeSet derivables = new UnicodeSet(Emoji.getAllRgiNoES())
+ .addAll(codepointToIsoCurrencyCode.keySet())
+ .removeAll(enAnnotations.keySet())
+ .freeze();
+
+ for (String d : derivables) {
+ if (d.contains("💏🏻")) {
+ System.out.println(d + "\t" + Utility.hex(d));
+ }
+ }
+
Map<String, UnicodeSet> localeToFailures = new LinkedHashMap<>();
Set<String> locales = ImmutableSortedSet.copyOf(Annotations.getAvailable());
+ final Factory cldrFactory = CLDRConfig.getInstance().getCldrFactory();
for (String locale : locales) {
if ("root".equals(locale)) {
continue;
}
+ if (!localeMatcher.reset(locale).matches()) {
+ continue;
+ }
UnicodeSet failures = new UnicodeSet(Emoji.getAllRgiNoES());
localeToFailures.put(locale, failures);
@@ -69,6 +134,7 @@
continue;
}
CLDRFile target = new CLDRFile(new SimpleXMLSource(locale));
+ CLDRFile main = null;
DisplayAndInputProcessor DAIP = new DisplayAndInputProcessor(target);
Exception[] internalException = new Exception[1];
@@ -80,6 +146,20 @@
shortName = annotations.getShortName(derivable);
} catch (Exception e) {
}
+
+ if (shortName == null) {
+ String currencyCode = codepointToIsoCurrencyCode.get(derivable);
+ if (currencyCode != null) {
+ if (main == null) {
+ main = cldrFactory.make(locale, true);
+ }
+ shortName = main.getName(CLDRFile.CURRENCY_NAME, currencyCode);
+ if (shortName.contentEquals(currencyCode)) {
+ shortName = null; // don't want fallback raw code
+ }
+ }
+ }
+
if (shortName == null || SKIP.containsSome(shortName)) {
continue; // missing
}
@@ -106,10 +186,10 @@
failures.freeze();
if (!failures.isEmpty()) {
Level level = CLDR_CONFIG.getStandardCodes().getLocaleCoverageLevel(Organization.cldr, locale);
- System.out.println("Failures\t" + locale
+ System.out.println("Failures\t" + locale
+ "\t" + level
+ "\t" + english.getName(locale)
- + "\t" + failures.size()
+ + "\t" + failures.size()
+ "\t" + failures.toPattern(false));
}
if (missingOnly) {
@@ -124,6 +204,9 @@
if ("root".equals(locale)) {
continue;
}
+ if (!localeMatcher.reset(locale).matches()) {
+ continue;
+ }
CLDRFile cldrFileUnresolved = factory.make(locale, false);
CLDRFile cldrFileResolved = factory.make(locale, true);
Set<String> toRemove = new TreeSet<>(); // TreeSet just makes debugging easier
@@ -163,4 +246,5 @@
}
System.out.println("Be sure to run CLDRModify passes afterwards, and generate transformed locales (like de-CH).");
}
+
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateEnglishChanged.java b/tools/java/org/unicode/cldr/tool/GenerateEnglishChanged.java
index f51fba2..eaae45f 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateEnglishChanged.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateEnglishChanged.java
@@ -28,7 +28,7 @@
public class GenerateEnglishChanged {
private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance();
private static final File TRUNK_DIRECTORY = new File(CLDRPaths.BASE_DIRECTORY);
-// TODO
+// TODO
private static final File RELEASE_DIRECTORY = new File(CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + ToolConstants.LAST_RELEASE_VERSION + ".0" + "/");
private static final boolean TRIAL = false;
@@ -86,7 +86,7 @@
}
}
System.out.println("Errors: " + errorCount);
-
+
if (TRIAL) {
String multipath = "(";
@@ -96,7 +96,7 @@
for (List<String> list : entry.getValue()) {
// prepare the data
if (store == null) {
- store = new ArrayList<Set<String>>();
+ store = new ArrayList<>();
for (int i = 0; i < list.size(); ++i) {
store.add(new LinkedHashSet<String>());
}
@@ -118,7 +118,7 @@
String compressed = MinimizeRegex.compressWith(attrValues, alphabet);// (attrValues, alphabet);
//String compressed = MinimizeRegex.simplePattern(attrValues);// (attrValues, alphabet);
path = path.replaceFirst(placeholder, "(" + compressed + ")");
- }
+ }
multipath += "|" + path;
diff --git a/tools/java/org/unicode/cldr/tool/GenerateEnums.java b/tools/java/org/unicode/cldr/tool/GenerateEnums.java
index bd22596..22aff39 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateEnums.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateEnums.java
@@ -33,7 +33,7 @@
import org.unicode.cldr.util.Validity.Status;
import org.unicode.cldr.util.XPathParts;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.collect.ImmutableMap;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.Collator;
@@ -58,12 +58,12 @@
// private Factory supplementalFactory = Factory.make(
// CLDRPaths.SUPPLEMENTAL_DIRECTORY, ".*");
- private Set<String> cldrCodes = new TreeSet<String>();
+ private Set<String> cldrCodes = new TreeSet<>();
// private Map enum_canonical = new TreeMap();
- private Map<String, String> enum_alpha3 = new TreeMap<String, String>();
+ private Map<String, String> enum_alpha3 = new TreeMap<>();
- private Map<String, String> enum_UN = new TreeMap<String, String>();
+ private Map<String, String> enum_UN = new TreeMap<>();
// private Map enum_FIPS10 = new TreeMap();
@@ -78,9 +78,9 @@
private Relation<String, String> unlimitedCurrencyCodes;
- private Set<String> scripts = new TreeSet<String>();
+ private Set<String> scripts = new TreeSet<>();
- private Set<String> languages = new TreeSet<String>();
+ private Set<String> languages = new TreeSet<>();
public static void main(String[] args) throws IOException {
GenerateEnums gen = new GenerateEnums();
@@ -111,12 +111,12 @@
showGeneratedCommentStart(CODE_INDENT);
compareSets("currencies from sup.data", currencyCodes, "valid currencies",
validCurrencyCodes);
- Set<String> unused = new TreeSet<String>(validCurrencyCodes);
+ Set<String> unused = new TreeSet<>(validCurrencyCodes);
unused.removeAll(currencyCodes);
showCurrencies(currencyCodes);
Log.println();
showCurrencies(unused);
- Map<String, String> sorted = new TreeMap<String, String>(Collator
+ Map<String, String> sorted = new TreeMap<>(Collator
.getInstance(ULocale.ENGLISH));
for (String code : validCurrencyCodes) {
if (unused.contains(code) && !code.equals("CLF"))
@@ -169,7 +169,7 @@
Log.println();
showGeneratedCommentStart(CODE_INDENT);
- Map<String, String> code_replacements = new TreeMap<String, String>();
+ Map<String, String> code_replacements = new TreeMap<>();
int len = " /** Arabic */ Arab,"
.length();
for (Iterator<String> it = scripts.iterator(); it.hasNext();) {
@@ -328,7 +328,7 @@
}
BufferedReader codes = CldrUtility.getUTF8Data("UnMacroRegions.txt");
- Map<String, String> macro_name = new TreeMap<String, String>();
+ Map<String, String> macro_name = new TreeMap<>();
while (true) {
String line = codes.readLine();
if (line == null)
@@ -348,7 +348,7 @@
codes.close();
// String values = supplementalDataInfo.getValidityInfo().get("$territory").get1().trim();
Map<Status, Set<String>> validRegions = Validity.getInstance().getStatusToCodes(LstrType.region);
- Set<String> regions = new TreeSet<String>();
+ Set<String> regions = new TreeSet<>();
regions.addAll(validRegions.get(Status.regular));
regions.addAll(validRegions.get(Status.macroregion));
// String[] validTerritories = values.split("\\s+");
@@ -372,9 +372,9 @@
}
checkDuplicates(enum_UN);
checkDuplicates(enum_alpha3);
- Set<String> availableCodes = new TreeSet<String>(sc.getAvailableCodes("territory"));
+ Set<String> availableCodes = new TreeSet<>(sc.getAvailableCodes("territory"));
compareSets("RFC 4646", availableCodes, "CLDR", cldrCodes);
- Set<String> missing = new TreeSet<String>(availableCodes);
+ Set<String> missing = new TreeSet<>(availableCodes);
missing.removeAll(cldrCodes);
// don't care list: "003"
// missing.remove("003");
@@ -391,7 +391,7 @@
+ missing);
}
- Set<String> UNValues = new TreeSet<String>(enum_UN.values());
+ Set<String> UNValues = new TreeSet<>(enum_UN.values());
for (Iterator<String> it = macro_name.keySet().iterator(); it.hasNext();) {
Object key = it.next();
@@ -421,7 +421,7 @@
new SimpleDateFormat("yyyy-MM"), new SimpleDateFormat("yyyy"), };
Date today = new Date();
Date longAgo = new Date(1000 - 1900, 1, 1);
- currencyCodes = new TreeSet<String>();
+ currencyCodes = new TreeSet<>();
unlimitedCurrencyCodes = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class, null);
for (Iterator<String> it = supplementalData
.iterator("//supplementalData/currencyData/region"); it.hasNext();) {
@@ -451,7 +451,7 @@
currencyCodes.add(code);
}
- validCurrencyCodes = new TreeSet<String>();
+ validCurrencyCodes = new TreeSet<>();
Set<String> bcp47CurrencyCodes = supplementalDataInfo.getBcp47Keys().getAll("cu");
for (String code : bcp47CurrencyCodes) {
validCurrencyCodes.add(code.toUpperCase());
@@ -506,7 +506,7 @@
// addContains(region, temp);
// recursiveContainment.put(region, temp);
// }
- Set<String> startingFromWorld = new TreeSet<String>();
+ Set<String> startingFromWorld = new TreeSet<>();
addContains("001", startingFromWorld);
compareSets("World", startingFromWorld, "CLDR", cldrCodes);
// generateContains();
@@ -525,13 +525,13 @@
}
}
- Map<String, List<String>> containment = new TreeMap<String, List<String>>();
+ Map<String, List<String>> containment = new TreeMap<>();
// Map recursiveContainment = new TreeMap();
private void addContains(String string, Set<String> startingFromWorld) {
startingFromWorld.add(string);
- List<String> contained = (List<String>) containment.get(string);
+ List<String> contained = containment.get(string);
if (contained == null)
return;
for (Iterator<String> it = contained.iterator(); it.hasNext();) {
@@ -567,18 +567,17 @@
}
}
- Set<String> corrigendum = new TreeSet<String>(Arrays.asList(new String[] { "QE", "833",
+ Set<String> corrigendum = new TreeSet<>(Arrays.asList(new String[] { "QE", "833",
"830", "172" })); // 003, 419
- private Map extraNames = CollectionUtilities.asMap(new String[][] {
- { "BU", "Burma" }, { "TP", "East Timor" }, { "YU", "Yugoslavia" },
- { "ZR", "Zaire" }, { "CD", "Congo (Kinshasa, Democratic Republic)" },
- { "CI", "Ivory Coast (Cote d'Ivoire)" },
- { "FM", "Micronesia (Federated States)" },
- { "TL", "East Timor (Timor-Leste)" },
- // {"155","Western Europe"},
-
- });
+ private ImmutableMap<String, String> extraNames = ImmutableMap.<String, String>builder()
+ .put("BU", "Burma").put("TP", "East Timor").put("YU", "Yugoslavia")
+ .put("ZR", "Zaire").put("CD", "Congo (Kinshasa, Democratic Republic)")
+ .put("CI", "Ivory Coast (Cote d'Ivoire)")
+ .put("FM", "Micronesia (Federated States)")
+ .put("TL", "East Timor (Timor-Leste)")
+ // .put("155", "Western Europe")
+ .build();
private Set<String> currencyCodes;
@@ -599,9 +598,9 @@
System.out.println();
showGeneratedCommentStart(CODE_INDENT);
- Set<String> reordered = new TreeSet<String>(new LengthFirstComparator());
+ Set<String> reordered = new TreeSet<>(new LengthFirstComparator());
reordered.addAll(enum_UN.keySet());
- Map<String, String> code_replacements = new TreeMap<String, String>();
+ Map<String, String> code_replacements = new TreeMap<>();
int len = " /** Polynesia */ UN061,"
.length();
for (Iterator<String> it = reordered.iterator(); it.hasNext();) {
@@ -631,7 +630,7 @@
.getName("territory", territory));
// remove all the ISO 639-3 until they are part of BCP 47
// we need to remove in earlier pass so we have the count
- Set<String> languages = new TreeSet<String>();
+ Set<String> languages = new TreeSet<>();
for (String language : supplementalDataInfo
.getLanguagesForTerritoryWithPopulationData(territory)) {
if (Iso639Data.getSource(language) == Iso639Data.Source.ISO_639_3) {
@@ -668,7 +667,7 @@
showGeneratedCommentStart(DATA_INDENT);
// addInfo(RegionCode.US, 840, "USA", "US", "US/XX", ....); ... are
// containees
- reordered = new TreeSet<String>(new DeprecatedAndLengthFirstComparator("territory"));
+ reordered = new TreeSet<>(new DeprecatedAndLengthFirstComparator("territory"));
reordered.addAll(enum_UN.keySet());
for (Iterator<String> it = reordered.iterator(); it.hasNext();) {
String region = it.next();
@@ -678,7 +677,7 @@
// int un = Integer.parseInt((String) enum_UN.get(region)); // get around
// dumb octal
// syntax
- String isoCode = (String) enum_alpha3.get(region);
+ String isoCode = enum_alpha3.get(region);
if (isoCode == null)
continue;
Log.println(DATA_INDENT + "add(" + quote(isoCode) + ", " + "RegionCode."
@@ -696,7 +695,7 @@
// String cldrName = region.length() < 5 ? region : region.substring(2); // fix
// UN
// name
- int un = Integer.parseInt((String) enum_UN.get(region), 10); // get
+ int un = Integer.parseInt(enum_UN.get(region), 10); // get
// around
// dumb
// octal
@@ -716,7 +715,7 @@
if (newCode != null)
continue;
- int un = Integer.parseInt((String) enum_UN.get(region), 10); // get
+ int un = Integer.parseInt(enum_UN.get(region), 10); // get
// around
// dumb
// octal
@@ -773,6 +772,7 @@
}
public final static class LengthFirstComparator implements Comparator<Object> {
+ @Override
public int compare(Object a, Object b) {
String as = a.toString();
String bs = b.toString();
@@ -791,6 +791,7 @@
this.type = type;
}
+ @Override
public int compare(Object a, Object b) {
String as = a.toString();
String bs = b.toString();
@@ -834,7 +835,7 @@
XPathParts parts = XPathParts.getFrozenInstance(path);
String replacement = parts.findAttributeValue("territoryAlias", "replacement");
if (replacement == null) {
- return "";
+ return "";
}
return replacement;
}
@@ -887,7 +888,7 @@
private String getEnglishName(String codeName) {
if (codeName.length() > 3)
codeName = codeName.substring(2); // fix UN name
- String name = (String) extraNames.get(codeName);
+ String name = extraNames.get(codeName);
if (name != null)
return name;
name = english.getName(CLDRFile.TERRITORY_NAME, codeName);
@@ -902,7 +903,7 @@
List<String> list = sc.getFullData("territory", codeName);
if (list == null)
return null;
- return (String) list.get(0);
+ return list.get(0);
}
private String enumName(String codeName) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateG2xG2.java b/tools/java/org/unicode/cldr/tool/GenerateG2xG2.java
index 0f59716..e3fd328 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateG2xG2.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateG2xG2.java
@@ -47,16 +47,16 @@
root = cldrFactory.make("root", true);
StandardCodes sc = StandardCodes.make();
Map<Organization, Map<String, Level>> type_code_value = sc.getLocaleTypes();
- Set<String> sourceSet = new TreeSet<String>();
- Set<String> targetLanguageSet = new TreeSet<String>();
+ Set<String> sourceSet = new TreeSet<>();
+ Set<String> targetLanguageSet = new TreeSet<>();
targetLanguageSet.add("no");
addPriority("G2", "nn");
addPriority("G2", "no");
targetLanguageSet.add("nn");
- Set<String> targetScriptSet = new TreeSet<String>();
- Set<String> targetRegionSet = new TreeSet<String>();
- Set<String> targetTZSet = new TreeSet<String>();
- Set<String> targetCurrencySet = new TreeSet<String>();
+ Set<String> targetScriptSet = new TreeSet<>();
+ Set<String> targetRegionSet = new TreeSet<>();
+ Set<String> targetTZSet = new TreeSet<>();
+ Set<String> targetCurrencySet = new TreeSet<>();
for (Organization type : type_code_value.keySet()) {
Map<String, Level> code_value = type_code_value.get(type);
if (!type.equals(Organization.ibm)) continue;
@@ -85,7 +85,7 @@
}
// set the priorities for territories
Map<String, List<String>> worldBankInfo = sc.getWorldBankInfo();
- Set<String> euCodes = new HashSet<String>(Arrays.asList(new String[] { "AT", "BE", "CY", "CZ", "DK", "EE",
+ Set<String> euCodes = new HashSet<>(Arrays.asList(new String[] { "AT", "BE", "CY", "CZ", "DK", "EE",
"FI", "FR", "DE", "GR", "HU", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "SI", "ES", "SE", "GB" }));
for (String countryCode : worldBankInfo.keySet()) {
if (priorityMap.get(countryCode) == null) continue; // only use ones we already have: defaults G4
@@ -191,7 +191,7 @@
private static boolean showLocales(int choice) throws Exception {
ULocale desiredDisplayLocale = ULocale.ENGLISH;
- Set<String> testSet = new TreeSet<String>();
+ Set<String> testSet = new TreeSet<>();
StandardCodes sc = StandardCodes.make();
{
Set<String> countries = sc.getGoodAvailableCodes("territory");
@@ -224,11 +224,11 @@
} else {
boolean USE_3066bis = choice == 2;
// produce random list of RFC3066 language tags
- Set<String> grandfathered = sc.getAvailableCodes("grandfathered");
- List<String> language_subtags = new ArrayList<String>(sc.getGoodAvailableCodes("language"));
- List<String> script_subtags = new ArrayList<String>(sc.getGoodAvailableCodes("script"));
- List<String> region_subtags = new ArrayList<String>(sc.getGoodAvailableCodes("territory"));
- for (String possibility : grandfathered) {
+ Set<String> legacy = sc.getAvailableCodes("legacy");
+ List<String> language_subtags = new ArrayList<>(sc.getGoodAvailableCodes("language"));
+ List<String> script_subtags = new ArrayList<>(sc.getGoodAvailableCodes("script"));
+ List<String> region_subtags = new ArrayList<>(sc.getGoodAvailableCodes("territory"));
+ for (String possibility : legacy) {
System.out.println(possibility);
if (new ULocale(possibility).getScript().length() != 0) {
System.out.println("\tAdding");
@@ -271,12 +271,12 @@
private static void showExample(RuleBasedCollator col) {
String samples = "a A b B \u5416 \u93CA \u516b \u7C3F";
- Set<String> s = new TreeSet<String>(col);
+ Set<String> s = new TreeSet<>(col);
s.addAll(Arrays.asList(samples.split(" ")));
System.out.println(com.ibm.icu.impl.Utility.escape(s.toString()));
}
- static Map<String, String> priorityMap = new TreeMap<String, String>();
+ static Map<String, String> priorityMap = new TreeMap<>();
static void addPriority(String priority, String code) {
if (code.length() == 0) return;
@@ -290,7 +290,7 @@
int missingCount;
}
- static Map<String, Totals> totalMap = new TreeMap<String, Totals>();
+ static Map<String, Totals> totalMap = new TreeMap<>();
static void checkItems(PrintWriter pw, String sourceLocale, CLDRFile sourceData, int type, Set<String> targetItemSet) {
for (Iterator<String> it2 = targetItemSet.iterator(); it2.hasNext();) {
@@ -369,7 +369,7 @@
private static List<String> getCurrency(String territory) {
if (territory_currency == null) {
- territory_currency = new TreeMap<String, List<String>>();
+ territory_currency = new TreeMap<>();
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile supp = cldrFactory.make(CLDRFile.SUPPLEMENTAL_NAME, false);
for (String path : supp) {
@@ -388,7 +388,7 @@
}
List<String> info = territory_currency.get(iso3166);
if (info == null) {
- territory_currency.put(iso3166, info = new ArrayList<String>());
+ territory_currency.put(iso3166, info = new ArrayList<>());
}
info.add(iso4217);
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateIndexCharacters.java b/tools/java/org/unicode/cldr/tool/GenerateIndexCharacters.java
index 1a53cf8..2250d8e 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateIndexCharacters.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateIndexCharacters.java
@@ -39,7 +39,7 @@
ULocale uLocale = new ULocale(locale);
Collator collator = Collator.getInstance(uLocale);
collator.setStrength(Collator.PRIMARY); // TODO: ought to build the collator from CLDR instead of from ICU.
- AlphabeticIndex<String> index = new AlphabeticIndex<String>(uLocale);
+ AlphabeticIndex<String> index = new AlphabeticIndex<>(uLocale);
index.clearRecords();
UnicodeSet indexLabels = cFile.getExemplarSet("index", WinningChoice.WINNING);
if (indexLabels != null && indexLabels.size() > 0) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateItemCounts.java b/tools/java/org/unicode/cldr/tool/GenerateItemCounts.java
index 845db6c..6ebae34 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateItemCounts.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateItemCounts.java
@@ -32,6 +32,7 @@
import org.unicode.cldr.util.DtdData.Element;
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.PathStarrer;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.RegexUtilities;
import org.unicode.cldr.util.SupplementalDataInfo;
@@ -42,8 +43,8 @@
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -54,7 +55,7 @@
private static final SupplementalDataInfo SUPPLEMENTAL_DATA_INFO = CLDRConfig.getInstance().getSupplementalDataInfo();
private static final boolean SKIP_ORDERING = true;
private static final String OUT_DIRECTORY = CLDRPaths.GEN_DIRECTORY + "/itemcount/"; // CldrUtility.MAIN_DIRECTORY;
- private Map<String, List<StackTraceElement>> cantRead = new TreeMap<String, List<StackTraceElement>>();
+ private Map<String, List<StackTraceElement>> cantRead = new TreeMap<>();
static {
System.err.println("Probably obsolete tool");
}
@@ -115,7 +116,7 @@
: CLDRPaths.ARCHIVE_DIRECTORY + "/" + dir;
boolean isFinal = dir == DIRECTORIES[DIRECTORIES.length - 1];
- String fulldir = new File(pathname).getCanonicalPath();
+ String fulldir = PathUtilities.getNormalizedPathString(pathname);
String prefix = (MyOptions.rawfilter.option.doesOccur() ? "filtered_" : "");
String fileKey = dir.replace("/", "_");
try (
@@ -280,7 +281,7 @@
+ "\t" + noOccur);
}
out.println("\nERRORS/WARNINGS");
- out.println(CollectionUtilities.join(errors, "\n"));
+ out.println(Joiner.on("\n").join(errors));
}
}
@@ -288,7 +289,7 @@
Relation<String, String> elementPathToAttributes = Relation.of(new TreeMap<String, Set<String>>(),
TreeSet.class);
final PathStarrer PATH_STARRER = new PathStarrer().setSubstitutionPattern("*");
- final Set<String> STARRED_PATHS = new TreeSet<String>();
+ final Set<String> STARRED_PATHS = new TreeSet<>();
StringBuilder elementPath = new StringBuilder();
public void add(String path) {
@@ -330,10 +331,10 @@
static Pattern prefix = PatternCache.get("([^/]+/[^/]+)(.*)");
static class Delta {
- Counter<String> newCount = new Counter<String>();
- Counter<String> deletedCount = new Counter<String>();
- Counter<String> changedCount = new Counter<String>();
- Counter<String> unchangedCount = new Counter<String>();
+ Counter<String> newCount = new Counter<>();
+ Counter<String> deletedCount = new Counter<>();
+ Counter<String> changedCount = new Counter<>();
+ Counter<String> unchangedCount = new Counter<>();
void print(PrintWriter changesSummary, Set<String> prefixes) {
changesSummary.println("Total"
@@ -423,15 +424,15 @@
"([a-z]{2,3})(?:[_-]([A-Z][a-z]{3}))?(?:[_-]([a-zA-Z0-9]{2,3}))?([_-][a-zA-Z0-9]{1,8})*");
public static void doSummary() throws IOException {
- Map<String, R4<Counter<String>, Counter<String>, Counter<String>, Counter<String>>> key_release_count = new TreeMap<String, R4<Counter<String>, Counter<String>, Counter<String>, Counter<String>>>();
+ Map<String, R4<Counter<String>, Counter<String>, Counter<String>, Counter<String>>> key_release_count = new TreeMap<>();
Matcher countryLocale = LOCALE_PATTERN.matcher("");
- List<String> releases = new ArrayList<String>();
+ List<String> releases = new ArrayList<>();
Pattern releaseNumber = PatternCache.get("count_(?:.*-(\\d+(\\.\\d+)*)|trunk)\\.txt");
// int releaseCount = 1;
Relation<String, String> release_keys = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
Relation<String, String> localesToPaths = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> writtenLanguages = new TreeSet<String>();
- Set<String> countries = new TreeSet<String>();
+ Set<String> writtenLanguages = new TreeSet<>();
+ Set<String> countries = new TreeSet<>();
File[] listFiles = new File(OUT_DIRECTORY).listFiles();
// find the most recent version
@@ -471,7 +472,7 @@
VersionInfo vi = VersionInfo.getInstance(releaseNum);
boolean captureData = vi.equals(mostRecentVersion);
releases.add(releaseNum);
- BufferedReader in = FileUtilities.openUTF8Reader("", subdir.getCanonicalPath());
+ BufferedReader in = FileUtilities.openUTF8Reader("", PathUtilities.getNormalizedPathString(subdir));
while (true) {
String line = in.readLine();
if (line == null) break;
@@ -563,7 +564,7 @@
summary2.println("#Countries:\t" + countries.size());
summary2.println("#Locales:\t" + localesToPaths.size());
for (Entry<String, Set<String>> entry : localesToPaths.keyValuesSet()) {
- summary2.println(entry.getKey() + "\t" + CollectionUtilities.join(entry.getValue(), "\t"));
+ summary2.println(entry.getKey() + "\t" + Joiner.on("\t").join(entry.getValue()));
}
summary2.close();
}
@@ -676,7 +677,10 @@
}
private String fixKeyPath(String path) {
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for addAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ if (!SKIP_ORDERING) {
+ parts = parts.cloneAsThawed();
+ }
for (int i = 0; i < parts.size(); ++i) {
String element = parts.getElement(i);
if (!SKIP_ORDERING) {
@@ -724,16 +728,19 @@
}
static class MyErrorHandler implements ErrorHandler {
+ @Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("\nerror: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("\nfatalError: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("\nwarning: " + XMLFileReader.showSAX(exception));
throw exception;
diff --git a/tools/java/org/unicode/cldr/tool/GenerateKaraList.java b/tools/java/org/unicode/cldr/tool/GenerateKaraList.java
index f06f721..a3e17e9 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateKaraList.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateKaraList.java
@@ -97,7 +97,7 @@
private static void printCodes(PrintWriter log, Set<String> locales, Set<String> availableCodes, int choice) {
boolean hasAbbreviation = choice == CLDRFile.CURRENCY_NAME;
// boolean skipDraft = true;
- Set<String> errors = new HashSet<String>();
+ Set<String> errors = new HashSet<>();
for (Iterator<String> it = availableCodes.iterator(); it.hasNext();) {
String id = it.next();
String ename = english.getName(choice, id);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateLanguageContainment.java b/tools/java/org/unicode/cldr/tool/GenerateLanguageContainment.java
index 73bcd84..44fe547 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateLanguageContainment.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateLanguageContainment.java
@@ -33,6 +33,7 @@
import org.unicode.cldr.util.Validity;
import org.unicode.cldr.util.Validity.Status;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
@@ -42,7 +43,6 @@
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.util.ICUUncheckedIOException;
@@ -242,7 +242,7 @@
System.out.println("Checking " + "he" + "\t" + Containment.getAllDirected(childToParent, "he"));
PrintWriter out = new PrintWriter(System.out);
- print(out, parentToChild, new ArrayList<String>(Arrays.asList("mul")));
+ print(out, parentToChild, new ArrayList<>(Arrays.asList("mul")));
System.out.println(out);
SimpleXMLSource xmlSource = new SimpleXMLSource("languageGroup");
xmlSource.setNonInheriting(true); // should be gotten from DtdType...
@@ -291,10 +291,8 @@
if (base.equals("und")) {
// skip, no good info
} else {
- newFile.add("//" + DtdType.supplementalData + "/languageGroups/languageGroup[@parent=\"" + base + "\"]", CollectionUtilities.join(children, " "));
-// System.out.println("\t<languageGroup parent='"
-// + base + "'>"
-// + CollectionUtilities.join(children, " ") + "</languageGroup>");
+ newFile.add("//" + DtdType.supplementalData + "/languageGroups/languageGroup[@parent=\"" + base + "\"]",
+ Joiner.on(" ").join(children));
}
for (String child : children) {
printXML(newFile, parentToChild, child);
@@ -390,9 +388,9 @@
// }
// String last = chain.get(0);
// for (int i = 1; i < chain.size(); ++i) {
-// String item = chain.get(i);
+// String item = chain.get(i);
// if (!COLLECTIONS.contains(item)) {
-// chain.set(i, item.equals("zh") ? "zhx" : "");
+// chain.set(i, item.equals("zh") ? "zhx" : "");
// DROPPED_PARENTS_TO_CHILDREN.put(item, last);
// } else {
// last = item;
diff --git a/tools/java/org/unicode/cldr/tool/GenerateLanguageData.java b/tools/java/org/unicode/cldr/tool/GenerateLanguageData.java
index 25013c0..1cadb08 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateLanguageData.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateLanguageData.java
@@ -53,7 +53,7 @@
Set<String> all = Iso639Data.getAvailable();
newEn.addComment("//ldml", "by " +
GenerateLanguageData.class.getSimpleName() +
- " from Iso639Data v" + iso639Data.getVersion() + " on " + new java.util.Date()
+ " from Iso639Data v" + Iso639Data.getVersion() + " on " + new java.util.Date()
+ " - " + all.size() + " codes.",
CommentType.PREBLOCK);
System.out.println(all.size() + " ISO 639 codes to process");
@@ -81,7 +81,7 @@
}
// Set<String> languageRegistryCodes = sc.getAvailableCodes("language");
- Set<String> languageCodes = new TreeSet<String>(Iso639Data.getAvailable());
+ Set<String> languageCodes = new TreeSet<>(Iso639Data.getAvailable());
System.out.println("Macrolanguages");
for (String languageCode : languageCodes) {
@@ -96,7 +96,7 @@
// //+ "\t" + iso639Data.getType(languageCode)
// + "\t" + Utility.join(iso639Data.getNames(languageCode),"; ")
// );
- for (String suffix : new TreeSet<String>(suffixes)) {
+ for (String suffix : new TreeSet<>(suffixes)) {
System.out.println(
languageCode
+ "\t" + (bcp47languages.contains(languageCode) ? "4646" : "new")
diff --git a/tools/java/org/unicode/cldr/tool/GenerateLanguageMatches.java b/tools/java/org/unicode/cldr/tool/GenerateLanguageMatches.java
index 5ad0293..5c019b5 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateLanguageMatches.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateLanguageMatches.java
@@ -66,7 +66,7 @@
}
// Filter out what is in LanguageInfo already
-
+
if (desiredToSupported.containsEntry(locale, macroLanguage)) {
continue;
}
@@ -97,6 +97,7 @@
}
static final Transform<String, String> MENU = new Transform<String, String>() {
+ @Override
public String transform(@SuppressWarnings("unused") String source) {
return "menu";
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateLikelySubtagTests.java b/tools/java/org/unicode/cldr/tool/GenerateLikelySubtagTests.java
index 469d0fa..bca5d40 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateLikelySubtagTests.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateLikelySubtagTests.java
@@ -39,7 +39,7 @@
if (OUTPUT_STYLE == OutputStyle.C) {
writeTestLine2("FROM", "ADD-LIKELY", "REMOVE-LIKELY");
}
- Set<String> testedAlready = new HashSet<String>();
+ Set<String> testedAlready = new HashSet<>();
for (final String from : likelySubtags.keySet()) {
final String to = likelySubtags.get(from);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateLocaleIDTestData.java b/tools/java/org/unicode/cldr/tool/GenerateLocaleIDTestData.java
new file mode 100644
index 0000000..51dc383
--- /dev/null
+++ b/tools/java/org/unicode/cldr/tool/GenerateLocaleIDTestData.java
@@ -0,0 +1,47 @@
+package org.unicode.cldr.tool;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.unicode.cldr.util.CLDRPaths;
+import org.unicode.cldr.util.CldrUtility;
+import org.unicode.cldr.util.LsrvCanonicalizer;
+import org.unicode.cldr.util.LsrvCanonicalizer.TestDataTypes;
+import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.TempPrintWriter;
+
+public class GenerateLocaleIDTestData {
+ static final LsrvCanonicalizer rrs = LsrvCanonicalizer.getInstance();
+
+ public static void main(String[] args) throws IOException {
+ try (TempPrintWriter pw = TempPrintWriter.openUTF8Writer(CLDRPaths.TEST_DATA + "localeIdentifiers", "localeCanonicalization.txt")) {
+ pw.println("# Test data for locale identifier canonicalization");
+ pw.println(CldrUtility.getCopyrightString("# "));
+ pw.println("#\n"
+ + "# Format:\n"
+ + "# <source locale identifier>\t;\t<expected canonicalized locale identifier>\n"
+ + "#\n"
+ + "# The data lines are divided into 4 sets:\n"
+ + "# " + LsrvCanonicalizer.TestDataTypes.explicit + ": a short list of explicit test cases.\n"
+ + "# " + LsrvCanonicalizer.TestDataTypes.fromAliases + ": test cases generated from the alias data.\n"
+ + "# " + LsrvCanonicalizer.TestDataTypes.decanonicalized + ": test cases generated by reversing the normalization process.\n"
+ + "# " + LsrvCanonicalizer.TestDataTypes.withIrrelevants + ": test cases generated from the others by adding irrelevant fields where possible,\n"
+ + "# to ensure that the canonicalization implementation is not sensitive to irrelevant fields. These include:\n"
+ + "# Language: " + rrs.getIrrelevantField(LstrType.language) + "\n"
+ + "# Script: " + rrs.getIrrelevantField(LstrType.script) + "\n"
+ + "# Region: " + rrs.getIrrelevantField(LstrType.region) + "\n"
+ + "# Variant: " + rrs.getIrrelevantField(LstrType.variant) + "\n"
+ + "######\n\n");
+ for (Entry<TestDataTypes, Map<String, String>> mainEntry : rrs.getTestData(null).entrySet()) {
+ TestDataTypes type = mainEntry.getKey();
+ pw.println("\n# " + type + "\n");
+ for (Entry<String, String> entry : mainEntry.getValue().entrySet()) {
+ String toTest = entry.getKey();
+ String expected = entry.getValue();
+ pw.println(toTest + "\t;\t" + expected);
+ }
+ }
+ }
+ }
+}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateMaximalLocales.java b/tools/java/org/unicode/cldr/tool/GenerateMaximalLocales.java
index 9cf9cb8..3b5441d 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateMaximalLocales.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateMaximalLocales.java
@@ -22,6 +22,7 @@
import org.unicode.cldr.draft.ScriptMetadata;
import org.unicode.cldr.draft.ScriptMetadata.Info;
import org.unicode.cldr.util.Builder;
+import org.unicode.cldr.util.CLDRConfig;
import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.CLDRLocale;
import org.unicode.cldr.util.CLDRPaths;
@@ -34,6 +35,7 @@
import org.unicode.cldr.util.LanguageTagParser;
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.Log;
+import org.unicode.cldr.util.Organization;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StandardCodes;
@@ -43,9 +45,9 @@
import org.unicode.cldr.util.SupplementalDataInfo.OfficialStatus;
import org.unicode.cldr.util.SupplementalDataInfo.PopulationData;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -79,7 +81,7 @@
enum OutputStyle {
PLAINTEXT, C, C_ALT, XML
- };
+ }
private static OutputStyle OUTPUT_STYLE = OutputStyle.valueOf(CldrUtility.getProperty("OutputStyle", "XML", "XML")
.toUpperCase());
@@ -98,6 +100,7 @@
new File(CLDRPaths.EXEMPLARS_DIRECTORY) };
private static Factory factory = SimpleFactory.make(list, ".*");
+ private static Factory mainFactory = CLDRConfig.getInstance().getCldrFactory();
private static SupplementalDataInfo supplementalData = SupplementalDataInfo
.getInstance(CLDRPaths.SUPPLEMENTAL_DIRECTORY);
private static StandardCodes standardCodes = StandardCodes.make();
@@ -119,7 +122,7 @@
private static final ImmutableSet<String> deprecatedISONotInLST = ImmutableSet.of("scc", "scr");
/**
- * This is the simplest way to override, by supplying the max value.
+ * This is the simplest way to override, by supplying the max value.
* It gets a very low weight, so doesn't override any stronger value.
*/
private static final String[] MAX_ADDITIONS = new String[] {
@@ -284,6 +287,7 @@
{ "mis_Medf", "mis_Medf_NG" },
{ "ku_Yezi", "ku_Yezi_GE" },
+ { "und_EU", "en_Latn_IE" },
});
/**
@@ -306,7 +310,7 @@
{ "und", "Latn" }, // Ultimate fallback
};
- private static Map<String, String> localeToScriptCache = new TreeMap<String, String>();
+ private static Map<String, String> localeToScriptCache = new TreeMap<>();
static {
for (String language : standardCodes.getAvailableCodes("language")) {
Map<String, String> info = standardCodes.getLangData("language", language);
@@ -338,7 +342,7 @@
printDefaultLanguagesAndScripts();
- Map<String, String> toMaximized = new TreeMap<String, String>();
+ Map<String, String> toMaximized = new TreeMap<>();
tryDifferentAlgorithm(toMaximized);
@@ -366,7 +370,7 @@
Map<String, String> oldLikely = SupplementalDataInfo.getInstance().getLikelySubtags();
Set<String> changes = compareMapsAndFixNew("*WARNING* Likely Subtags: ", oldLikely, toMaximized, "ms_Arab",
"ms_Arab_ID");
- System.out.println(CollectionUtilities.join(changes, "\n"));
+ System.out.println(Joiner.on("\n").join(changes));
if (OUTPUT_STYLE == OutputStyle.C_ALT) {
doAlt(toMaximized);
@@ -487,6 +491,7 @@
return pop;
}
+ @Override
public int compareTo(RowData o) {
// TODO Auto-generated method stub
int result = os.compareTo(o.os);
@@ -496,10 +501,12 @@
return name.compareTo(o.name);
}
+ @Override
public boolean equals(Object o) {
return 0 == compareTo((RowData) o);
}
+ @Override
public int hashCode() {
throw new UnsupportedOperationException();
}
@@ -510,8 +517,8 @@
final int minTotalPopulation = 10000000;
final int minTerritoryPopulation = 1000000;
final double minTerritoryPercent = 1.0 / 3;
- Map<String, Set<RowData>> languageToReason = new TreeMap<String, Set<RowData>>();
- Counter<String> languageToLiteratePopulation = new Counter<String>();
+ Map<String, Set<RowData>> languageToReason = new TreeMap<>();
+ Counter<String> languageToLiteratePopulation = new Counter<>();
NumberFormat nf = NumberFormat.getIntegerInstance(ULocale.ENGLISH);
nf.setGroupingUsed(true);
LanguageTagParser ltp = new LanguageTagParser();
@@ -525,9 +532,10 @@
*
* B. X is an exception explicitly approved by the committee or X has minimal
* language coverage‡ in CLDR itself.
+ * C. The language is in the CLDR-target locales
*/
OfficialStatus minimalStatus = OfficialStatus.official_regional; // OfficialStatus.de_facto_official;
- Map<String, String> languages = new TreeMap<String, String>();
+ Map<String, String> languages = new TreeMap<>();
for (String language : standardCodes.getAvailableCodes("language")) {
String path = CLDRFile.getKey(CLDRFile.LANGUAGE_NAME, language);
String result = english.getStringValue(path);
@@ -539,6 +547,9 @@
System.out.println(language + "\t" + languages.get(language));
}
+ // also CLDR-target locales
+ final Set<String> CLDRMainLanguages = new TreeSet<>(StandardCodes.make().getLocaleCoverageLocales(Organization.cldr));
+
for (String territory : supplementalData.getTerritoriesWithPopulationData()) {
PopulationData territoryPop = supplementalData.getPopulationDataForTerritory(territory);
double territoryPopulation = territoryPop.getLiteratePopulation();
@@ -568,6 +579,9 @@
&& literatePopulation > minTerritoryPercent * territoryPopulation) {
add = true;
}
+ if (add == false && CLDRMainLanguages.contains(language)) {
+ add = true;
+ }
if (add) {
add(languageToReason, language, territory, status, literatePopulation);
// Add the containing regions
@@ -625,7 +639,7 @@
// now list them
- Set<String> others = new TreeSet<String>();
+ Set<String> others = new TreeSet<>();
others.addAll(standardCodes.getGoodAvailableCodes("language"));
others.removeAll(languageToReason.keySet());
System.out.println("\nIncluded Languages:\t" + languageToReason.keySet().size());
@@ -643,7 +657,7 @@
}
private static void showLanguages(Set<String> others, Map<String, Set<RowData>> languageToReason) {
- Set<String> sorted = new TreeSet<String>(Collator.getInstance(ULocale.ENGLISH));
+ Set<String> sorted = new TreeSet<>(Collator.getInstance(ULocale.ENGLISH));
for (String language : others) {
sorted.add(getLanguageName(language, languageToReason));
}
@@ -687,14 +701,14 @@
String territory = english.getName("territory", territoryRaw) + " [" + territoryRaw + "]";
Set<RowData> set = languageToReason.get(language);
if (set == null) {
- languageToReason.put(language, set = new TreeSet<RowData>());
+ languageToReason.put(language, set = new TreeSet<>());
}
set.add(new RowData(status, territory, population));
}
private static void printDefaultContent(Map<String, String> toMaximized) throws IOException {
- Set<String> defaultLocaleContent = new TreeSet<String>();
+ Set<String> defaultLocaleContent = new TreeSet<>();
// go through all the cldr locales, and add default contents
// now computed from toMaximized
@@ -703,7 +717,7 @@
LanguageTagParser ltp = new LanguageTagParser();
// System.out.println(maximize("az_Latn_AZ", toMaximized));
- Set<String> hasScript = new TreeSet<String>();
+ Set<String> hasScript = new TreeSet<>();
// first get a mapping to children
for (String locale : available) {
@@ -724,13 +738,17 @@
}
// Suppress script for locales for which we only have one locale in common/main. See ticket #7834.
- Set<String> suppressScriptLocales = new HashSet<String>(Arrays.asList(
+ Set<String> suppressScriptLocales = new HashSet<>(Arrays.asList(
"bm_ML", "en_US", "ha_NG", "iu_CA", "ms_MY", "mn_MN",
"byn_ER", "ff_SN", "dyo_SN", "kk_KZ", "ku_TR", "ky_KG", "ml_IN", "so_SO", "sw_TZ", "wo_SN", "yo_NG", "dje_NE",
- "blt_VN"));
+ "blt_VN",
+ "hi_IN",
+ "nv_US",
+ "doi_IN"
+ ));
// if any have a script, then throw out any that don't have a script (unless they're specifically included.)
- Set<String> toRemove = new TreeSet<String>();
+ Set<String> toRemove = new TreeSet<>();
for (String locale : hasScript) {
toRemove.clear();
Set<String> children = toChildren.getAll(locale);
@@ -740,7 +758,7 @@
}
}
if (toRemove.size() != 0) {
- System.out.println("Removing:\t" + locale + "\t" + toRemove + "\tfrom\t" + children);
+ System.out.println("\tRemoving:\t" + locale + "\t" + toRemove + "\tfrom\t" + children);
toChildren.removeAll(locale, toRemove);
}
}
@@ -753,7 +771,7 @@
continue;
}
Set<String> children = toChildren.getAll(locale);
- Map<String, String> debugStuff = new TreeMap<String, String>();
+ Map<String, String> debugStuff = new TreeMap<>();
for (String child : children) {
String maximizedChild = maximize(child, toMaximized);
if (maximized.equals(maximizedChild)) {
@@ -832,18 +850,18 @@
private static class MaxData {
Relation<String, Row.R3<Double, String, String>> languages = Relation.of(new TreeMap<String, Set<Row.R3<Double, String, String>>>(), TreeSet.class);
- Map<String, Counter<String>> languagesToScripts = new TreeMap<String, Counter<String>>();
- Map<String, Counter<String>> languagesToRegions = new TreeMap<String, Counter<String>>();
+ Map<String, Counter<String>> languagesToScripts = new TreeMap<>();
+ Map<String, Counter<String>> languagesToRegions = new TreeMap<>();
Relation<String, Row.R3<Double, String, String>> scripts = Relation.of(new TreeMap<String, Set<Row.R3<Double, String, String>>>(), TreeSet.class);
- Map<String, Counter<String>> scriptsToLanguages = new TreeMap<String, Counter<String>>();
- Map<String, Counter<String>> scriptsToRegions = new TreeMap<String, Counter<String>>();
+ Map<String, Counter<String>> scriptsToLanguages = new TreeMap<>();
+ Map<String, Counter<String>> scriptsToRegions = new TreeMap<>();
Relation<String, Row.R3<Double, String, String>> regions = Relation.of(new TreeMap<String, Set<Row.R3<Double, String, String>>>(), TreeSet.class);
- Map<String, Counter<String>> regionsToLanguages = new TreeMap<String, Counter<String>>();
- Map<String, Counter<String>> regionsToScripts = new TreeMap<String, Counter<String>>();
+ Map<String, Counter<String>> regionsToLanguages = new TreeMap<>();
+ Map<String, Counter<String>> regionsToScripts = new TreeMap<>();
- Map<String, Counter<Row.R2<String, String>>> containersToLanguage = new TreeMap<String, Counter<Row.R2<String, String>>>();
+ Map<String, Counter<Row.R2<String, String>>> containersToLanguage = new TreeMap<>();
Relation<String, Row.R4<Double, String, String, String>> containersToLangRegion = Relation.of(
new TreeMap<String, Set<Row.R4<Double, String, String, String>>>(), TreeSet.class);
@@ -891,7 +909,7 @@
containersToLangRegion.put(container, Row.of(order, language, script, region));
Counter<R2<String, String>> data = containersToLanguage.get(container);
if (data == null) {
- containersToLanguage.put(container, data = new Counter<R2<String, String>>());
+ containersToLanguage.put(container, data = new Counter<>());
}
data.add(Row.of(language, script), (long) (double) order);
@@ -923,7 +941,7 @@
// Set<Row.R3<String,String,String>,Double> rowsToCounts = new TreeMap();
MaxData maxData = new MaxData();
Set<String> cldrLocales = factory.getAvailable();
- Set<String> otherTerritories = new TreeSet<String>(standardCodes.getGoodAvailableCodes("territory"));
+ Set<String> otherTerritories = new TreeSet<>(standardCodes.getGoodAvailableCodes("territory"));
// process all the information to get the top values for each triple.
// each of the combinations of 1 or 2 components gets to be a key.
@@ -995,7 +1013,7 @@
String language = entry.getKey();
final Collection<String> values = entry.getValue();
if (values.size() != 1) {
- continue; // skip, no either way
+ continue; // skip, no either way
}
Set<R3<Double, String, String>> old = maxData.languages.get(language);
if (!maxData.languages.containsKey(language)) {
@@ -1047,16 +1065,16 @@
R3<Double, String, String> value = maxData.languages.getAll(language).iterator().next();
final Comparable<String> script = value.get1();
final Comparable<String> region = value.get2();
- add(language, language + "_" + script + "_" + region, toMaximized, "L->SR", Override.REPLACE_EXISTING,
+ add(language, language + "_" + script + "_" + region, toMaximized, "L->SR", LocaleOverride.REPLACE_EXISTING,
SHOW_ADD);
}
for (String language : maxData.languagesToScripts.keySet()) {
String script = maxData.languagesToScripts.get(language).getKeysetSortedByCount(true).iterator().next();
- add(language, language + "_" + script, toMaximized, "L->S", Override.REPLACE_EXISTING, SHOW_ADD);
+ add(language, language + "_" + script, toMaximized, "L->S", LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String language : maxData.languagesToRegions.keySet()) {
String region = maxData.languagesToRegions.get(language).getKeysetSortedByCount(true).iterator().next();
- add(language, language + "_" + region, toMaximized, "L->R", Override.REPLACE_EXISTING, SHOW_ADD);
+ add(language, language + "_" + region, toMaximized, "L->R", LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String script : maxData.scripts.keySet()) {
@@ -1064,15 +1082,15 @@
final Comparable<String> language = value.get1();
final Comparable<String> region = value.get2();
add("und_" + script, language + "_" + script + "_" + region, toMaximized, "S->LR",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String script : maxData.scriptsToLanguages.keySet()) {
String language = maxData.scriptsToLanguages.get(script).getKeysetSortedByCount(true).iterator().next();
- add("und_" + script, language + "_" + script, toMaximized, "S->L", Override.REPLACE_EXISTING, SHOW_ADD);
+ add("und_" + script, language + "_" + script, toMaximized, "S->L", LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String script : maxData.scriptsToRegions.keySet()) {
String region = maxData.scriptsToRegions.get(script).getKeysetSortedByCount(true).iterator().next();
- add("und_" + script, "und_" + script + "_" + region, toMaximized, "S->R", Override.REPLACE_EXISTING,
+ add("und_" + script, "und_" + script + "_" + region, toMaximized, "S->R", LocaleOverride.REPLACE_EXISTING,
SHOW_ADD);
}
@@ -1081,15 +1099,15 @@
final Comparable<String> language = value.get1();
final Comparable<String> script = value.get2();
add("und_" + region, language + "_" + script + "_" + region, toMaximized, "R->LS",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String region : maxData.regionsToLanguages.keySet()) {
String language = maxData.regionsToLanguages.get(region).getKeysetSortedByCount(true).iterator().next();
- add("und_" + region, language + "_" + region, toMaximized, "R->L", Override.REPLACE_EXISTING, SHOW_ADD);
+ add("und_" + region, language + "_" + region, toMaximized, "R->L", LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (String region : maxData.regionsToScripts.keySet()) {
String script = maxData.regionsToScripts.get(region).getKeysetSortedByCount(true).iterator().next();
- add("und_" + region, "und_" + script + "_" + region, toMaximized, "R->S", Override.REPLACE_EXISTING,
+ add("und_" + region, "und_" + script + "_" + region, toMaximized, "R->S", LocaleOverride.REPLACE_EXISTING,
SHOW_ADD);
}
@@ -1114,7 +1132,7 @@
if (skipLanguages != null
&& skipLanguages.contains(language)) {
add("und_" + region, language + "_" + script + "_" + region, toMaximized, "R*->LS",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
continue;
}
@@ -1124,7 +1142,7 @@
final Comparable<String> script2 = e.get2();
if (language2.equals(language) && script2.equals(script)) {
add("und_" + region, language + "_" + script + "_" + e.get3(), toMaximized, "R*->LS",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
break;
}
}
@@ -1136,7 +1154,7 @@
final Comparable<String> script = languageScript.get1();
final Comparable<String> region = value.get1();
add(language + "_" + script, language + "_" + script + "_" + region, toMaximized, "LS->R",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (R2<String, String> scriptRegion : maxData.scriptRegions.keySet()) {
@@ -1145,7 +1163,7 @@
final Comparable<String> region = scriptRegion.get1();
final Comparable<String> language = value.get1();
add("und_" + script + "_" + region, language + "_" + script + "_" + region, toMaximized, "SR->L",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
for (R2<String, String> languageRegion : maxData.languageRegions.keySet()) {
@@ -1154,26 +1172,26 @@
final Comparable<String> region = languageRegion.get1();
final Comparable<String> script = value.get1();
add(language + "_" + region, language + "_" + script + "_" + region, toMaximized, "LR->S",
- Override.REPLACE_EXISTING, SHOW_ADD);
+ LocaleOverride.REPLACE_EXISTING, SHOW_ADD);
}
// get the script info from metadata as fallback
- TreeSet<String> sorted = new TreeSet<String>(ScriptMetadata.getScripts());
+ TreeSet<String> sorted = new TreeSet<>(ScriptMetadata.getScripts());
for (String script : sorted) {
Info i = ScriptMetadata.getInfo(script);
String likelyLanguage = i.likelyLanguage;
String originCountry = i.originCountry;
final String result = likelyLanguage + "_" + script + "_" + originCountry;
add("und_" + script, result, toMaximized, "S->LR•",
- Override.KEEP_EXISTING, SHOW_ADD);
+ LocaleOverride.KEEP_EXISTING, SHOW_ADD);
add(likelyLanguage, result, toMaximized, "L->SR•",
- Override.KEEP_EXISTING, SHOW_ADD);
+ LocaleOverride.KEEP_EXISTING, SHOW_ADD);
}
// add overrides
for (String key : LANGUAGE_OVERRIDES.keySet()) {
- add(key, LANGUAGE_OVERRIDES.get(key), toMaximized, "OVERRIDE", Override.REPLACE_EXISTING, true);
+ add(key, LANGUAGE_OVERRIDES.get(key), toMaximized, "OVERRIDE", LocaleOverride.REPLACE_EXISTING, true);
}
}
@@ -1187,7 +1205,7 @@
private static void doAlt(Map<String, String> toMaximized) {
// TODO Auto-generated method stub
- Map<String, String> temp = new TreeMap<String, String>();
+ Map<String, String> temp = new TreeMap<>();
for (String locale : toMaximized.keySet()) {
String target = toMaximized.get(locale);
temp.put(toAlt(locale, true), toAlt(target, true));
@@ -1326,11 +1344,11 @@
// }
// }
- enum Override {
+ enum LocaleOverride {
KEEP_EXISTING, REPLACE_EXISTING
}
- private static void add(String key, String value, Map<String, String> toAdd, String kind, Override override,
+ private static void add(String key, String value, Map<String, String> toAdd, String kind, LocaleOverride override,
boolean showAction) {
if (key.equals(DEBUG_ADD_KEY)) {
System.out.println("*debug*");
@@ -1338,16 +1356,16 @@
String oldValue = toAdd.get(key);
if (oldValue == null) {
if (showAction) {
- System.out.println("Adding:\t\t" + getName(key) + "\t=>\t" + getName(value) + "\t\t\t\t" + kind);
+ System.out.println("\tAdding:\t\t" + getName(key) + "\t=>\t" + getName(value) + "\t\t\t\t" + kind);
}
- } else if (override == Override.KEEP_EXISTING || value.equals(oldValue)) {
+ } else if (override == LocaleOverride.KEEP_EXISTING || value.equals(oldValue)) {
// if (showAction) {
// System.out.println("Skipping:\t" + key + "\t=>\t" + value + "\t\t\t\t" + kind);
// }
return;
} else {
if (showAction) {
- System.out.println("Replacing:\t" + getName(key) + "\t=>\t" + getName(value) + "\t, was\t" + getName(oldValue) + "\t\t" + kind);
+ System.out.println("\tReplacing:\t" + getName(key) + "\t=>\t" + getName(value) + "\t, was\t" + getName(oldValue) + "\t\t" + kind);
}
}
toAdd.put(key, value);
@@ -1577,7 +1595,7 @@
+ "</supplementalData>";
out.println(header);
boolean first = true;
- Set<String> keys = new TreeSet<String>(new LocaleStringComparator());
+ Set<String> keys = new TreeSet<>(new LocaleStringComparator());
keys.addAll(fluffup.keySet());
for (String printingLocale : keys) {
String printingTarget = fluffup.get(printingLocale);
@@ -1716,7 +1734,7 @@
public static void minimize(Map<String, String> fluffup) {
LanguageTagParser parser = new LanguageTagParser();
LanguageTagParser targetParser = new LanguageTagParser();
- Set<String> removals = new TreeSet<String>();
+ Set<String> removals = new TreeSet<>();
while (true) {
removals.clear();
for (String locale : fluffup.keySet()) {
@@ -2025,7 +2043,7 @@
}
scriptBits.clear(UScript.COMMON);
scriptBits.clear(UScript.INHERITED);
- Set<String> scripts = new TreeSet<String>();
+ Set<String> scripts = new TreeSet<>();
for (int j = 0; j < scriptBits.size(); ++j) {
if (scriptBits.get(j)) {
scripts.add(UScript.getShortName(j));
@@ -2053,39 +2071,39 @@
// };
static void showDefaultContentDifferencesAndFix(Set<String> defaultLocaleContent) {
- Set<String> errors = new LinkedHashSet<String>();
+ Set<String> errors = new LinkedHashSet<>();
Map<String, String> oldDefaultContent = SupplementalDataInfo.makeLocaleToDefaultContents(
ConvertLanguageData.supplementalData.getDefaultContentLocales(), new TreeMap<String, String>(), errors);
if (!errors.isEmpty()) {
- System.out.println(CollectionUtilities.join(errors, "\n"));
+ System.out.println(Joiner.on("\n").join(errors));
errors.clear();
}
Map<String, String> newDefaultContent = SupplementalDataInfo.makeLocaleToDefaultContents(defaultLocaleContent,
new TreeMap<String, String>(), errors);
if (!errors.isEmpty()) {
- System.out.println("Default Content errors: " + CollectionUtilities.join(errors, "\n"));
+ System.out.println("Default Content errors: " + Joiner.on("\n").join(errors));
errors.clear();
}
Set<String> changes = compareMapsAndFixNew("*WARNING* Default Content: ", oldDefaultContent, newDefaultContent,
"ar", "ar_001");
- System.out.println(CollectionUtilities.join(changes, "\n"));
+ System.out.println(Joiner.on("\n").join(changes));
defaultLocaleContent.clear();
defaultLocaleContent.addAll(newDefaultContent.values());
newDefaultContent = SupplementalDataInfo.makeLocaleToDefaultContents(defaultLocaleContent,
new TreeMap<String, String>(), errors);
if (!errors.isEmpty()) {
- System.out.println("***New Errors: " + CollectionUtilities.join(errors, "\n"));
+ System.out.println("***New Errors: " + Joiner.on("\n").join(errors));
}
}
private static Set<String> compareMapsAndFixNew(String title,
Map<String, String> oldContent,
Map<String, String> newContent, String... allowedOverrideValues) {
- Map<String, String> allowedOverrideValuesTest = new HashMap<String, String>();
+ Map<String, String> allowedOverrideValuesTest = new HashMap<>();
for (int i = 0; i < allowedOverrideValues.length; i += 2) {
allowedOverrideValuesTest.put(allowedOverrideValues[i], allowedOverrideValues[i + 1]);
}
- Set<String> changes = new TreeSet<String>();
+ Set<String> changes = new TreeSet<>();
for (String parent : Builder.with(new TreeSet<String>()).addAll(newContent.keySet())
.addAll(oldContent.keySet()).get()) {
String oldValue = oldContent.get(parent);
@@ -2141,6 +2159,7 @@
LanguageTagParser ltp0 = new LanguageTagParser();
LanguageTagParser ltp1 = new LanguageTagParser();
+ @Override
public int compare(String arg0, String arg1) {
ltp0.set(arg0);
ltp1.set(arg1);
diff --git a/tools/java/org/unicode/cldr/tool/GeneratePluralConfirmation.java b/tools/java/org/unicode/cldr/tool/GeneratePluralConfirmation.java
index 8b7fa9b..652829e 100644
--- a/tools/java/org/unicode/cldr/tool/GeneratePluralConfirmation.java
+++ b/tools/java/org/unicode/cldr/tool/GeneratePluralConfirmation.java
@@ -40,7 +40,7 @@
for (String uLocale : new TreeSet<>(prf.getLocales())) {
for (PluralRules.PluralType type : PluralRules.PluralType.values()) {
for (Count count : Count.values()) {
- String pattern = prf.getSamplePattern(uLocale, type, count);
+ String pattern = PluralRulesFactory.getSamplePattern(uLocale, type, count);
if (pattern.contains("{no pattern available}")) {
continue;
}
@@ -71,7 +71,7 @@
}
EnumSet<Count> counts = EnumSet.noneOf(Count.class);
for (Count count : Count.VALUES) {
- String pat = prf.getSamplePattern(loc, ICU_ORDINAL, count);
+ String pat = PluralRulesFactory.getSamplePattern(loc, ICU_ORDINAL, count);
if (pat != null && !pat.contains("{no pattern available}")) {
counts.add(count);
}
@@ -81,13 +81,13 @@
System.out.format("%s\t%s\t%s\t%s\n", loc, "missing", "n/a", "n/a");
break;
case 1: {
- String pat = prf.getSamplePattern(loc, ICU_ORDINAL, Count.other);
+ String pat = PluralRulesFactory.getSamplePattern(loc, ICU_ORDINAL, Count.other);
System.out.format("%s\t%s\t%s\t%s\n", loc, "constant", Count.other, "n/a");
}
break;
default:
for (Count count : counts) {
- String pat = prf.getSamplePattern(loc, ICU_ORDINAL, count);
+ String pat = PluralRulesFactory.getSamplePattern(loc, ICU_ORDINAL, count);
System.out.format("%s\t%s\t%s\t%s\n", loc, "multiple", count, pat);
}
break;
@@ -185,7 +185,7 @@
for (Entry<Count, Set<FixedDecimal>> entry : soFar.keyValuesSet()) {
Count count = entry.getKey();
for (FixedDecimal fd : entry.getValue()) {
- String pattern = prf.getSamplePattern(locale, type.standardType, count);
+ String pattern = PluralRulesFactory.getSamplePattern(locale, type.standardType, count);
buffer.append(locale + "\t" + type + "\t" + count + "\t" + fd + "\t«" + pattern.replace("{0}", String.valueOf(fd)) + "»\n");
}
buffer.append("\n");
diff --git a/tools/java/org/unicode/cldr/tool/GeneratePluralList.java b/tools/java/org/unicode/cldr/tool/GeneratePluralList.java
index 7940679..7121bbc 100644
--- a/tools/java/org/unicode/cldr/tool/GeneratePluralList.java
+++ b/tools/java/org/unicode/cldr/tool/GeneratePluralList.java
@@ -48,7 +48,7 @@
this.out = out;
}
- private Map<String, Map<String, String>> localesToNouns = new HashMap<String, Map<String, String>>();
+ private Map<String, Map<String, String>> localesToNouns = new HashMap<>();
private void loadNouns() throws IOException {
BufferedReader reader = FileReaders.openFile(GeneratePluralList.class, "fractionnum.csv");
@@ -59,7 +59,7 @@
String format = fields[5];
Map<String, String> nouns = localesToNouns.get(locale);
if (nouns == null) {
- localesToNouns.put(locale, nouns = new HashMap<String, String>());
+ localesToNouns.put(locale, nouns = new HashMap<>());
}
nouns.put(count, format);
}
@@ -70,7 +70,7 @@
private Set<String> list3;
public ExampleManager() {
- list3 = new HashSet<String>();
+ list3 = new HashSet<>();
}
public void add(String example) {
@@ -102,11 +102,11 @@
// Setup.
Count[] digits = new Count[1000];
// 0 is always considered a plural type even if the plural rules say otherwise.
- Set<Count> missingTypes = new HashSet<Count>();
+ Set<Count> missingTypes = new HashSet<>();
for (String keyword : rules.getKeywords()) {
missingTypes.add(Count.valueOf(keyword));
}
- Map<String, List<Integer>> integerMap = new HashMap<String, List<Integer>>();
+ Map<String, List<Integer>> integerMap = new HashMap<>();
digits[0] = Count.zero;
missingTypes.remove(Count.zero);
put(integerMap, "zero", 0);
@@ -147,9 +147,9 @@
int limit = (int) Math.pow(10, numDigits);
// Generate all examples.
- Map<String, String> exampleMap = new HashMap<String, String>();
- Map<String, ExampleManager> positionedExamples = new HashMap<String, ExampleManager>();
- Set<String> allKeywords = new HashSet<String>(rules.getKeywords());
+ Map<String, String> exampleMap = new HashMap<>();
+ Map<String, ExampleManager> positionedExamples = new HashMap<>();
+ Set<String> allKeywords = new HashSet<>(rules.getKeywords());
allKeywords.add("zero");
allKeywords.retainAll(integerMap.keySet());
List<Integer> values;
@@ -181,7 +181,7 @@
}
// Output examples to file.
- Set<String> finalExamples = new TreeSet<String>(new Comparator<String>() {
+ Set<String> finalExamples = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String arg0, String arg1) {
String[] forms1 = arg1.split("\\|");
@@ -212,7 +212,7 @@
private static <A, B> void put(Map<A, List<B>> map, A key, B value) {
List<B> list = map.get(key);
if (list == null) {
- map.put(key, list = new ArrayList<B>());
+ map.put(key, list = new ArrayList<>());
}
list.add(value);
}
diff --git a/tools/java/org/unicode/cldr/tool/GeneratePluralRanges.java b/tools/java/org/unicode/cldr/tool/GeneratePluralRanges.java
index 5732b90..35264d9 100644
--- a/tools/java/org/unicode/cldr/tool/GeneratePluralRanges.java
+++ b/tools/java/org/unicode/cldr/tool/GeneratePluralRanges.java
@@ -1,8 +1,9 @@
package org.unicode.cldr.tool;
+import static com.google.common.collect.Comparators.lexicographical;
+
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.LinkedHashSet;
@@ -29,7 +30,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
import org.unicode.cldr.util.TempPrintWriter;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.MessageFormat;
@@ -56,7 +57,7 @@
private void generateSamples(CLDRFile english, Factory factory) {
//Map<ULocale, PluralRulesFactory.SamplePatterns> samples = PluralRulesFactory.getLocaleToSamplePatterns();
// add all the items with plural ranges
- Set<String> sorted = new TreeSet<String>(SUPPLEMENTAL.getPluralRangesLocales());
+ Set<String> sorted = new TreeSet<>(SUPPLEMENTAL.getPluralRangesLocales());
// add the core locales
// sorted.addAll(StandardCodes.make().getLocaleCoverageLocales("google", EnumSet.of(Level.MODERN)));
sorted.addAll(StandardCodes.make().getLocaleCoverageLocales(Organization.cldr, EnumSet.of(Level.MODERN)));
@@ -110,7 +111,7 @@
locale = "he";
}
//Map<ULocale, PluralRulesFactory.SamplePatterns> samples = PluralRulesFactory.getLocaleToSamplePatterns();
- List<RangeSample> list = new ArrayList<RangeSample>();
+ List<RangeSample> list = new ArrayList<>();
PluralInfo pluralInfo = SUPPLEMENTAL.getPlurals(locale);
Set<Count> counts = pluralInfo.getCounts();
PluralRanges pluralRanges = SUPPLEMENTAL.getPluralRanges(locale);
@@ -131,8 +132,8 @@
// }
// }
- Output<FixedDecimal> maxSample = new Output<FixedDecimal>();
- Output<FixedDecimal> minSample = new Output<FixedDecimal>();
+ Output<FixedDecimal> maxSample = new Output<>();
+ Output<FixedDecimal> minSample = new Output<>();
ICUServiceBuilder icusb = new ICUServiceBuilder();
icusb.setCldrFile(cldrFile);
@@ -220,21 +221,21 @@
private final SupplementalDataInfo SUPPLEMENTAL;
private final PluralRulesFactory prf;
- public static final Comparator<Set<String>> STRING_SET_COMPARATOR = new SetComparator<String, Set<String>>();
- public static final Comparator<Set<Count>> COUNT_SET_COMPARATOR = new SetComparator<Count, Set<Count>>();
-
- static final class SetComparator<T extends Comparable<T>, U extends Set<T>> implements Comparator<U> {
- public int compare(U o1, U o2) {
- return CollectionUtilities.compare((Collection<T>) o1, (Collection<T>) o2);
- }
- };
+ // Ordering by size-of-set first, and then lexicographically, with a final tie-break on the
+ // string representation.
+ private static final Comparator<Set<String>> STRING_SET_COMPARATOR =
+ Comparator.<Set<String>, Integer>comparing(Set::size)
+ .thenComparing(lexicographical(Comparator.<String>naturalOrder()));
+ private static final Comparator<Set<Count>> COUNT_SET_COMPARATOR =
+ Comparator.<Set<Count>, Integer>comparing(Set::size)
+ .thenComparing(lexicographical(Comparator.<Count>naturalOrder()));
public void reformatPluralRanges() {
- Map<Set<Count>, Relation<Set<String>, String>> seen = new TreeMap<Set<Count>, Relation<Set<String>, String>>(COUNT_SET_COMPARATOR);
+ Map<Set<Count>, Relation<Set<String>, String>> seen = new TreeMap<>(COUNT_SET_COMPARATOR);
try (TempPrintWriter out = TempPrintWriter.openUTF8Writer(CLDRPaths.SUPPLEMENTAL_DIRECTORY,"pluralRanges.xml")) {
- out.println(DtdType.supplementalData.header(MethodHandles.lookup().lookupClass()) +
- "\t<version number=\"$Revision$\" />\n" +
- "\t<plurals>"
+ out.println(DtdType.supplementalData.header(MethodHandles.lookup().lookupClass()) +
+ "\t<version number=\"$Revision$\" />\n" +
+ "\t<plurals>"
);
for (String locale : SUPPLEMENTAL.getPluralRangesLocales()) {
@@ -258,16 +259,17 @@
item.put(s, locale);
}
for (Entry<Set<Count>, Relation<Set<String>, String>> entry0 : seen.entrySet()) {
- out.println("\n<!-- " + CollectionUtilities.join(entry0.getKey(), ", ") + " -->");
+ out.println("\n<!-- " + Joiner.on(", ").join(entry0.getKey()) + " -->");
for (Entry<Set<String>, Set<String>> entry : entry0.getValue().keyValuesSet()) {
- out.println("\t\t<pluralRanges locales=\"" + CollectionUtilities.join(entry.getValue(), " ") + "\">");
+ out.println("\t\t<pluralRanges locales=\"" + Joiner.on(" ")
+ .join(entry.getValue()) + "\">");
for (String line : entry.getKey()) {
out.println("\t\t\t" + line);
}
out.println("\t\t</pluralRanges>");
}
}
- out.println("\t</plurals>\n" +
+ out.println("\t</plurals>\n" +
"</supplementalData>");
}
}
@@ -278,7 +280,7 @@
public Set<String> reformat(PluralRanges pluralRanges, Set<Count> counts) {
Set<String> s;
- s = new LinkedHashSet<String>();
+ s = new LinkedHashSet<>();
// first determine the general principle
// EnumSet<RangeStrategy> strategy = EnumSet.allOf(RangeStrategy.class);
@@ -317,11 +319,11 @@
}
Set<String> minimize(PluralRanges pluralRanges, PluralInfo pluralInfo) {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
// make it easier to manage
PluralRanges.Matrix matrix = new PluralRanges.Matrix();
- Output<FixedDecimal> maxSample = new Output<FixedDecimal>();
- Output<FixedDecimal> minSample = new Output<FixedDecimal>();
+ Output<FixedDecimal> maxSample = new Output<>();
+ Output<FixedDecimal> minSample = new Output<>();
for (Count s : Count.VALUES) {
for (Count e : Count.VALUES) {
if (!pluralInfo.rangeExists(s, e, minSample, maxSample)) {
@@ -349,7 +351,7 @@
endDone.add(end);
}
}
- Output<Boolean> emit = new Output<Boolean>();
+ Output<Boolean> emit = new Output<>();
for (Count start : pluralInfo.getCounts()) {
Count r = matrix.startSame(start, endDone, emit);
if (r != null
diff --git a/tools/java/org/unicode/cldr/tool/GenerateProductionData.java b/tools/java/org/unicode/cldr/tool/GenerateProductionData.java
index 5a77e68..bb41a39 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateProductionData.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateProductionData.java
@@ -59,7 +59,7 @@
static final Set<String> NON_XML = ImmutableSet.of("dtd", "properties", "testData", "uca");
static final Set<String> COPY_ANYWAY = ImmutableSet.of("casing", "collation"); // don't want to "clean up", makes format difficult to use
static final SupplementalDataInfo SDI = CLDRConfig.getInstance().getSupplementalDataInfo();
-
+
static final Multimap<String, Pair<String, String>> localeToSubdivisionsToMigrate = TreeMultimap.create();
enum MyOptions {
@@ -96,7 +96,7 @@
.setDefault("true")
.setMatch("true|false")),
verbose(new Params()
- .setHelp("verbose debugging messages")),
+ .setHelp("verbose debugging messages")),
Debug(new Params()
.setHelp("debug")),
fileMatch(new Params()
@@ -182,9 +182,9 @@
}
@Override
public String toString() {
- return
+ return
"files=" + files
- + (removed + retained + remaining == 0 ? ""
+ + (removed + retained + remaining == 0 ? ""
: "; removed=" + removed
+ "; retained=" + retained
+ "; remaining=" + remaining);
@@ -202,11 +202,11 @@
* @param destinationFile
* @param factory
* @param isLdmlDtdType
- * @param stats
+ * @param stats
* @param hasChildren
* @return true if the file is an ldml file with empty content.
*/
- private static boolean copyFilesAndReturnIsEmpty(File sourceFile, File destinationFile,
+ private static boolean copyFilesAndReturnIsEmpty(File sourceFile, File destinationFile,
Factory factory, boolean isLdmlDtdType, Stats stats) {
if (sourceFile.isDirectory()) {
@@ -255,7 +255,7 @@
}
}
stats.showNonZero("\tTOTAL:\t");
- // if there are empty ldml files, AND we aren't in /main/,
+ // if there are empty ldml files, AND we aren't in /main/,
// then remove any without children
if (!emptyLocales.isEmpty() && !sourceFile.getName().equals("main")) {
Set<String> childless = getChildless(emptyLocales, factory.getAvailable());
@@ -279,7 +279,7 @@
boolean isRoot = localeId.equals("root");
String directoryName = sourceFile.getParentFile().getName();
boolean isSubdivisionDirectory = "subdivisions".equals(directoryName);
-
+
CLDRFile cldrFileUnresolved = factory.make(localeId, false);
CLDRFile cldrFileResolved = factory.make(localeId, true);
boolean gotOne = false;
@@ -287,7 +287,7 @@
Set<String> toRetain = new TreeSet<>();
Output<String> pathWhereFound = new Output<>();
Output<String> localeWhereFound = new Output<>();
-
+
boolean isArabicSpecial = localeId.equals("ar") || localeId.startsWith("ar_");
String debugPath = null; // "//ldml/units/unitLength[@type=\"short\"]/unit[@type=\"power-kilowatt\"]/displayName";
@@ -315,7 +315,7 @@
continue;
}
}
-
+
// special case for Arabic defaultNumberingSystem
if (isArabicSpecial && xpath.contains("/defaultNumberingSystem")) {
toRetain.add(xpath);
@@ -324,11 +324,11 @@
// remove items that are the same as their bailey values. This also catches Inheritance Marker
String bailey = cldrFileResolved.getConstructedBaileyValue(xpath, pathWhereFound, localeWhereFound);
- if (value.equals(bailey)
- && (!ADD_SIDEWAYS
+ if (value.equals(bailey)
+ && (!ADD_SIDEWAYS
|| pathEqualsOrIsAltVariantOf(xpath, pathWhereFound.value))
- && (!ADD_ROOT
- || (!Objects.equals(XMLSource.ROOT_ID, localeWhereFound.value)
+ && (!ADD_ROOT
+ || (!Objects.equals(XMLSource.ROOT_ID, localeWhereFound.value)
&& !Objects.equals(XMLSource.CODE_FALLBACK_ID, localeWhereFound.value)))) {
toRemove.add(xpath);
continue;
@@ -366,7 +366,7 @@
}
}
- // check to see if we might need to flesh out datetime.
+ // check to see if we might need to flesh out datetime.
// TODO Should be done in the converter tool!!
if (ADD_DATETIME && isDateTimePath(xpath)) {
toRetain.addAll(dateTimePaths(xpath));
@@ -422,8 +422,8 @@
outCldrFile.removeAll(toRemove, false);
if (DEBUG) {
for (String xpath : toRemove) {
- System.out.println(localeId + ": removing: «"
- + cldrFileUnresolved.getStringValue(xpath)
+ System.out.println(localeId + ": removing: «"
+ + cldrFileUnresolved.getStringValue(xpath)
+ "», " + xpath);
}
}
@@ -439,7 +439,7 @@
} else {
if (DEBUG) {
String oldValue = cldrFileUnresolved.getStringValue(xpath);
- System.out.println("Restoring: «" + oldValue + "» ⇒ «" + value
+ System.out.println("Restoring: «" + oldValue + "» ⇒ «" + value
+ "»\t" + xpath);
}
outCldrFile.add(xpath, value);
@@ -498,7 +498,7 @@
if (desiredPath.contains("type=\"en_GB\"") && desiredPath.contains("alt=")) {
int debug = 0;
}
- if (foundPath == null) {
+ if (foundPath == null) {
// We can do this, because the bailey value has already been checked
// Since it isn't null, a null indicates a constructed alt value
return true;
@@ -534,7 +534,7 @@
}
private static boolean isDateTimePath(String xpath) {
- return xpath.startsWith("//ldml/dates/calendars/calendar")
+ return xpath.startsWith("//ldml/dates/calendars/calendar")
&& xpath.contains("FormatLength[@type=");
}
@@ -561,7 +561,7 @@
for (String locale : available) {
String parent = LocaleIDParser.getParent(locale);
if (parent != null) {
- parent2child.put(parent, locale);
+ parent2child.put(parent, locale);
}
}
@@ -578,13 +578,13 @@
/**
* Recursively checks that all children are empty (including that there are no children)
* @param name
- * @param emptyLocales
+ * @param emptyLocales
* @param parent2child
* @return
*/
private static boolean allChildrenAreEmpty(
- String locale,
- Set<String> emptyLocales,
+ String locale,
+ Set<String> emptyLocales,
Multimap<String, String> parent2child) {
Collection<String> children = parent2child.get(locale);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateScriptMetadata.java b/tools/java/org/unicode/cldr/tool/GenerateScriptMetadata.java
index a953734..82f449d 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateScriptMetadata.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateScriptMetadata.java
@@ -11,7 +11,7 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.FileCopier;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R3;
import com.ibm.icu.impl.Utility;
@@ -25,14 +25,14 @@
// FileUtilities.appendFile(GenerateScriptMetadata.class, "GenerateScriptMetadata.txt", out);
FileCopier.copy(GenerateScriptMetadata.class, "GenerateScriptMetadata.txt", out);
- Set<R3<Integer, String, Info>> sorted = new TreeSet<R3<Integer, String, Info>>();
+ Set<R3<Integer, String, Info>> sorted = new TreeSet<>();
for (String script : ScriptMetadata.getScripts()) {
Info i = ScriptMetadata.getInfo(script);
R3<Integer, String, Info> r = Row.of(i.rank, script, i);
sorted.add(r);
}
if (ScriptMetadata.errors.size() > 0) {
- System.err.println(CollectionUtilities.join(ScriptMetadata.errors, "\n\t"));
+ System.err.println(Joiner.on("\n\t").join(ScriptMetadata.errors));
//throw new IllegalArgumentException();
}
VersionInfo currentUnicodeVersion = UCharacter.getUnicodeVersion();
diff --git a/tools/java/org/unicode/cldr/tool/GenerateSeedDurations.java b/tools/java/org/unicode/cldr/tool/GenerateSeedDurations.java
index f0125f5..5f641c5 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateSeedDurations.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateSeedDurations.java
@@ -46,7 +46,7 @@
public static void main(String[] args) {
Factory cldrFactory = testInfo.getCldrFactory();
String[] data = new String[4];
- Set<String> warnings = new LinkedHashSet<String>();
+ Set<String> warnings = new LinkedHashSet<>();
for (String locale : cldrFactory.getAvailableLanguages()) {
CLDRFile cldrFile = cldrFactory.make(locale, true);
String localeString = locale + "\t" + testInfo.getEnglish().getName(locale);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateSidewaysView.java b/tools/java/org/unicode/cldr/tool/GenerateSidewaysView.java
index 2434c85..9e7a457 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateSidewaysView.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateSidewaysView.java
@@ -143,7 +143,7 @@
UCA = new org.unicode.cldr.util.MultiComparator(UCA2, new UTF16.StringComparator(true, false, 0));
}
- private static Map<PathHeader, Map<String, Set<String>>> path_value_locales = new TreeMap<PathHeader, Map<String, Set<String>>>();
+ private static Map<PathHeader, Map<String, Set<String>>> path_value_locales = new TreeMap<>();
private static long startTime = System.currentTimeMillis();
static RuleBasedCollator standardCollation = (RuleBasedCollator) Collator.getInstance(ULocale.ENGLISH);
@@ -309,14 +309,6 @@
.format((System.currentTimeMillis() - startTime) / 1000.0));
}
- // static Comparator UCA;
- // static {
- // RuleBasedCollator UCA2 = (RuleBasedCollator) Collator.getInstance(ULocale.ROOT);
- // UCA2.setNumericCollation(true);
- // UCA2.setStrength(UCA2.IDENTICAL);
- // UCA = new CollectionUtilities.MultiComparator(UCA2, new UTF16.StringComparator(true, false, 0) );
- // }
-
static final String[][] EXEMPLARS = {
{ "//ldml/characters/exemplarCharacters", "main", "Main Exemplars" },
{ "//ldml/characters/exemplarCharacters[@type=\"punctuation\"]", "punctuation", "Punctuation Exemplars" },
@@ -334,7 +326,7 @@
// TODO change logic so that aux characters characters work well.
- Map<String, UnicodeMap<Set<String>>> script_UnicodeMap = new TreeMap<String, UnicodeMap<Set<String>>>();
+ Map<String, UnicodeMap<Set<String>>> script_UnicodeMap = new TreeMap<>();
// UnicodeMap mapping = new UnicodeMap();
UnicodeSet stuffToSkip = new UnicodeSet("[:Han:]");
@@ -371,12 +363,12 @@
if (script == null) {
script = UScript.getName(UScript.UNKNOWN);
}
- Set<String> temp = new HashSet<String>();
+ Set<String> temp = new HashSet<>();
temp.add(locale);
checkTr(script_UnicodeMap);
UnicodeMap<Set<String>> mapping = script_UnicodeMap.get(script);
if (mapping == null) {
- script_UnicodeMap.put(script, mapping = new UnicodeMap<Set<String>>());
+ script_UnicodeMap.put(script, mapping = new UnicodeMap<>());
}
checkTr(script_UnicodeMap);
mapping.composeWith(exemplars, temp, setComposer);
@@ -413,9 +405,9 @@
return; // skip these
}
// find out all the locales and all the characters
- Set<String> allLocales = new TreeSet<String>(UCA);
- Set<String> allChars = new TreeSet<String>(UCA);
- Set<String> allStrings = new TreeSet<String>(UCA);
+ Set<String> allLocales = new TreeSet<>(UCA);
+ Set<String> allChars = new TreeSet<>(UCA);
+ Set<String> allStrings = new TreeSet<>(UCA);
for (Set<String> locales : mapping.getAvailableValues()) {
allLocales.addAll(locales);
UnicodeSet unicodeSet = mapping.keySet(locales);
@@ -602,20 +594,21 @@
// }
static UnicodeMap.Composer<Set<String>> setComposer = new UnicodeMap.Composer<Set<String>>() {
+ @Override
public Set<String> compose(int codepoint, String string, Set<String> a, Set<String> b) {
if (a == null) {
return b;
} else if (b == null) {
return a;
} else {
- TreeSet<String> result = new TreeSet<String>(a);
+ TreeSet<String> result = new TreeSet<>(a);
result.addAll(b);
return result;
}
}
};
- static Map<String, String> LOCALE_TO_SCRIPT = new HashMap<String, String>();
+ static Map<String, String> LOCALE_TO_SCRIPT = new HashMap<>();
private static void loadInformation(Factory cldrFactory) {
Set<String> alllocales = cldrFactory.getAvailable();
@@ -671,12 +664,12 @@
}
Map<String, Set<String>> value_locales = path_value_locales.get(cleanPath);
if (value_locales == null) {
- path_value_locales.put(cleanPath, value_locales = new TreeMap<String, Set<String>>(
+ path_value_locales.put(cleanPath, value_locales = new TreeMap<>(
standardCollation));
}
Set<String> locales = value_locales.get(value);
if (locales == null) {
- value_locales.put(value, locales = new TreeSet<String>());
+ value_locales.put(value, locales = new TreeSet<>());
}
locales.add(localeID + postFix[0]);
}
@@ -693,7 +686,7 @@
static PathHeader.Factory pathHeaderFactory;
/**
- *
+ *
* @param path
* @param localePrefix
* @return
@@ -706,13 +699,13 @@
}
private static String removeAttributes(String xpath, Set<String> skipAttributes) {
- XPathParts parts = XPathParts.getInstance(xpath); // not frozen, for removeAttributes
+ XPathParts parts = XPathParts.getFrozenInstance(xpath).cloneAsThawed(); // not frozen, for removeAttributes
removeAttributes(parts, skipAttributes);
return parts.toString();
}
/**
- *
+ *
* @param parts
* @param skipAttributes
*/
@@ -727,7 +720,7 @@
}
}
- static Set<String> skipSet = new HashSet<String>(Arrays.asList("draft", "alt"));
+ static Set<String> skipSet = new HashSet<>(Arrays.asList("draft", "alt"));
static Status status = new Status();
@@ -747,7 +740,7 @@
return value;
}
if (value.length() == 0) {
- XPathParts parts = XPathParts.getInstance(fullPath); // not frozen, for removeAttributes
+ XPathParts parts = XPathParts.getFrozenInstance(fullPath).cloneAsThawed(); // not frozen, for removeAttributes
removeAttributes(parts, skipSet);
int limit = parts.size();
value = parts.toString(limit - 1, limit);
@@ -847,7 +840,7 @@
private static void finishAll(PrintWriter out, PrintWriter tsvFile) {
// TODO Auto-generated method stub
- tsvFile.println("# EOF");
+ //tsvFile.println("# EOF");
tsvFile.close();
}
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateStatistics.java b/tools/java/org/unicode/cldr/tool/GenerateStatistics.java
index 618f07e..74c6c49 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateStatistics.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateStatistics.java
@@ -55,10 +55,10 @@
//String dir = logDir + "main" + File.separator;
// DraftChecker dc = new DraftChecker(dir);
english = factory.make("en", true);
- Set<String> languages = new TreeSet<String>(col), countries = new TreeSet<String>(col), draftLanguages = new TreeSet<String>(
- col), draftCountries = new TreeSet<String>(col);
- Set<Object> nativeLanguages = new TreeSet<Object>(), nativeCountries = new TreeSet<Object>(), draftNativeLanguages = new TreeSet<Object>(),
- draftNativeCountries = new TreeSet<Object>();
+ Set<String> languages = new TreeSet<>(col), countries = new TreeSet<>(col), draftLanguages = new TreeSet<>(
+ col), draftCountries = new TreeSet<>(col);
+ Set<Object> nativeLanguages = new TreeSet<>(), nativeCountries = new TreeSet<>(), draftNativeLanguages = new TreeSet<>(),
+ draftNativeCountries = new TreeSet<>();
int localeCount = 0;
int draftLocaleCount = 0;
@@ -117,7 +117,7 @@
*/
private static Set<String> removeSingleLanguagesWhereWeHaveScripts(Set<String> contents) {
StandardCodes sc = StandardCodes.make();
- contents = new TreeSet<String>(contents); // make writable
+ contents = new TreeSet<>(contents); // make writable
if (false && HACK) {
contents.add("bs_Latn");
contents.add("bs_Cyrl");
@@ -125,7 +125,7 @@
contents.add("bs_Cyrl_BA");
}
// find the languages with scripts
- Set<String> toRemove = new HashSet<String>();
+ Set<String> toRemove = new HashSet<>();
if (HACK) toRemove.add("sh");
for (Iterator<String> it = contents.iterator(); it.hasNext();) {
@@ -189,8 +189,8 @@
s.add(llist);
}
- Set<String> titleSet = new TreeSet<String>(col);
- Set<String> qualifierSet = new TreeSet<String>(col);
+ Set<String> titleSet = new TreeSet<>(col);
+ Set<String> qualifierSet = new TreeSet<>(col);
for (Iterator<String> it = sb.keySet().iterator(); it.hasNext();) {
String englishName = it.next();
@@ -332,6 +332,7 @@
contents = new Object[] { englishName, locale, localName };
}
+ @Override
public int compareTo(Object o) {
return comp.compare(contents, ((LanguageList) o).contents);
}
@@ -353,8 +354,8 @@
if (notitlecase) return in;
String result = UCharacter.toTitleCase(new ULocale(localeID), in, null);
if (HACK) {
- result = GenerateCldrTests.replace(result, "U.s.", "U.S.");
- result = GenerateCldrTests.replace(result, "S.a.r.", "S.A.R.");
+ result = result.replace("U.s.", "U.S.");
+ result = result.replace("S.a.r.", "S.A.R.");
}
return result;
}
@@ -405,7 +406,7 @@
return name;
}
- static Map<String, String> fixCountryNames = new HashMap<String, String>();
+ static Map<String, String> fixCountryNames = new HashMap<>();
static {
fixCountryNames.put("\u0408\u0443\u0433\u043E\u0441\u043B\u0430\u0432\u0438\u0458\u0430",
"\u0421\u0440\u0431\u0438\u0458\u0430 \u0438 \u0426\u0440\u043D\u0430 \u0413\u043E\u0440\u0430");
@@ -416,7 +417,7 @@
public static class DraftChecker {
String dir;
- Map<String, Object> cache = new HashMap<String, Object>();
+ Map<String, Object> cache = new HashMap<>();
Object TRUE = new Object();
Object FALSE = new Object();
diff --git a/tools/java/org/unicode/cldr/tool/GenerateSubdivisions.java b/tools/java/org/unicode/cldr/tool/GenerateSubdivisions.java
index bd27ccd..ec3018f 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateSubdivisions.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateSubdivisions.java
@@ -31,7 +31,7 @@
// TODO: consider whether to use the last archive directory to generate
- // There are pros and cons.
+ // There are pros and cons.
// Pros are that we don't introduce "fake" deprecated elements that are introduced and deprecated during the 6 month CLDR cycle
// Cons are that we may have to repeat work
@@ -99,8 +99,8 @@
SubdivisionSet sdset1 = new SubdivisionSet(GenerateSubdivisions.ISO_SUBDIVISION_CODES);
SubDivisionExtractor sdset = new SubDivisionExtractor(sdset1,
- SubdivisionInfo.VALIDITY_FORMER,
- SubdivisionInfo.SUBDIVISION_ALIASES_FORMER,
+ SubdivisionInfo.VALIDITY_FORMER,
+ SubdivisionInfo.SUBDIVISION_ALIASES_FORMER,
SubdivisionInfo.formerRegionToSubdivisions);
try (PrintWriter pw = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "subdivision/subdivisions.xml")) {
diff --git a/tools/java/org/unicode/cldr/tool/GenerateSupplementalZoneData.java b/tools/java/org/unicode/cldr/tool/GenerateSupplementalZoneData.java
index 762fa7f..817252a 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateSupplementalZoneData.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateSupplementalZoneData.java
@@ -26,7 +26,7 @@
*/
public static void main(String[] args) throws Exception {
ZoneParser zp = new ZoneParser();
- Set<String> tzids = new TreeSet<String>();
+ Set<String> tzids = new TreeSet<>();
tzids.addAll(zp.getZoneData().keySet());
// Add POSIX legacy IDs
tzids.add("EST5EDT");
diff --git a/tools/java/org/unicode/cldr/tool/GenerateTempDateData.java b/tools/java/org/unicode/cldr/tool/GenerateTempDateData.java
index 7c6b2c9..6ef1185 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateTempDateData.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateTempDateData.java
@@ -95,6 +95,7 @@
* }
*/
static class RBundle extends ListResourceBundle {
+ @Override
protected Object[][] getContents() {
// TODO Auto-generated method stub
return null;
diff --git a/tools/java/org/unicode/cldr/tool/GenerateTransform.java b/tools/java/org/unicode/cldr/tool/GenerateTransform.java
index daf91ef..2c6cb05 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateTransform.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateTransform.java
@@ -35,13 +35,13 @@
+ "transforms"
+ File.separator;
- private final Set<Pair<String, String>> pairs = new TreeSet<Pair<String, String>>(
+ private final Set<Pair<String, String>> pairs = new TreeSet<>(
new MyComparator(ULocale.ROOT));
- private final Map<String, String> source_target = new LinkedHashMap<String, String>();
- private final Map<String, String> target_source = new LinkedHashMap<String, String>();
+ private final Map<String, String> source_target = new LinkedHashMap<>();
+ private final Map<String, String> target_source = new LinkedHashMap<>();
private final UnicodeContext addDotBetween = new UnicodeContext();
private final UnicodeContext removeDot = new UnicodeContext();
- private final Map<String, String> target_retarget = new LinkedHashMap<String, String>();
+ private final Map<String, String> target_retarget = new LinkedHashMap<>();
private boolean sourceCased = false;
private boolean targetCased = false;
@@ -217,6 +217,7 @@
collator.setStrength(Collator.IDENTICAL);
}
+ @Override
public int compare(Pair<String, String> arg0, Pair<String, String> arg1) {
int result = arg0.getFirst().length()
- arg1.getFirst().length();
@@ -234,7 +235,7 @@
}
static class UnicodeContext {
- Map<String, UnicodeSet> first_second = new LinkedHashMap<String, UnicodeSet>();
+ Map<String, UnicodeSet> first_second = new LinkedHashMap<>();
void add(String a, String b) {
UnicodeSet second = first_second.get(a);
@@ -245,7 +246,7 @@
}
Set<UnicodeSet[]> get() {
- Map<UnicodeSet, UnicodeSet> second_first = new LinkedHashMap<UnicodeSet, UnicodeSet>();
+ Map<UnicodeSet, UnicodeSet> second_first = new LinkedHashMap<>();
for (String first : first_second.keySet()) {
UnicodeSet second = first_second.get(first);
UnicodeSet firstSet = second_first.get(second);
@@ -254,7 +255,7 @@
}
firstSet.add(first);
}
- Set<UnicodeSet[]> result = new LinkedHashSet<UnicodeSet[]>();
+ Set<UnicodeSet[]> result = new LinkedHashSet<>();
for (UnicodeSet second : second_first.keySet()) {
UnicodeSet first = second_first.get(second);
result.add(new UnicodeSet[] { first, second });
@@ -299,10 +300,12 @@
output.setLength(0);
}
+ @Override
public String toString() {
return output.toString();
}
+ @Override
public void handlePathValue(String path, String value) {
if (path.indexOf("/comment") >= 0) {
if (!value.trim().startsWith("#"))
diff --git a/tools/java/org/unicode/cldr/tool/GenerateTransformCharts.java b/tools/java/org/unicode/cldr/tool/GenerateTransformCharts.java
index 57bf22c..d8e7bef 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateTransformCharts.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateTransformCharts.java
@@ -72,7 +72,7 @@
// Latin Arabic Bengali Cyrillic Devanagari Greek Greek/UNGEGN Gujarati Gurmukhi Hangul Hebrew Hiragana Kannada
// Katakana Malayalam Oriya Tamil Telugu Thai
- static Map<String, UnicodeSet> scriptExtras = new HashMap<String, UnicodeSet>();
+ static Map<String, UnicodeSet> scriptExtras = new HashMap<>();
static {
scriptExtras.put("Arab", new UnicodeSet("[\u0660-\u0669]"));
scriptExtras.put("Hang", TestTransformsSimple.getRepresentativeHangul());
@@ -353,7 +353,7 @@
+ "For more information, see below.</blockquote>");
index.flush();
index.println("<ul>");
- Set<String> nonScripts = new TreeSet<String>(Arrays.asList("ConjoiningJamo", "InterIndic", "Han",
+ Set<String> nonScripts = new TreeSet<>(Arrays.asList("ConjoiningJamo", "InterIndic", "Han",
"el", "Jamo", "JapaneseKana", "Korean", "NumericPinyin", "ThaiLogical", "ThaiSemi"));
try {
// SimpleEquivalenceClass ec = new SimpleEquivalenceClass(UCA);
@@ -486,15 +486,15 @@
// return;
// }
CLDRTransforms.ParsedTransformID parsedID = new CLDRTransforms.ParsedTransformID();
- Set<String> ids = new TreeSet<String>();
- Map<String, UnicodeSet> id_unmapped = new HashMap<String, UnicodeSet>();
- Map<String, Map<String, String>> id_noRoundTrip = new HashMap<String, Map<String, String>>();
- Set<String> latinItems = new TreeSet<String>(UCA);
+ Set<String> ids = new TreeSet<>();
+ Map<String, UnicodeSet> id_unmapped = new HashMap<>();
+ Map<String, Map<String, String>> id_noRoundTrip = new HashMap<>();
+ Set<String> latinItems = new TreeSet<>(UCA);
- Map<String, String> nonLatinToLatin = new TreeMap<String, String>(UCA);
- Set<String> totalLatin = new TreeSet<String>();
- Map<String, Map<String, Map<String, Boolean>>> latinToTaggedNonLatin = new TreeMap<String, Map<String, Map<String, Boolean>>>(UCA);
- Map<String, Map<String, Map<String, Boolean>>> nonLatinToLatinTagged = new TreeMap<String, Map<String, Map<String, Boolean>>>(UCA);
+ Map<String, String> nonLatinToLatin = new TreeMap<>(UCA);
+ Set<String> totalLatin = new TreeSet<>();
+ Map<String, Map<String, Map<String, Boolean>>> latinToTaggedNonLatin = new TreeMap<>(UCA);
+ Map<String, Map<String, Map<String, Boolean>>> nonLatinToLatinTagged = new TreeMap<>(UCA);
UnicodeSet totalNonLatinSet = new UnicodeSet();
@@ -514,7 +514,7 @@
// }
UnicodeSet nonLatinUnmapped = new UnicodeSet();
id_unmapped.put(id, nonLatinUnmapped);
- Map<String, String> noRoundTrip = new TreeMap<String, String>(UCA);
+ Map<String, String> noRoundTrip = new TreeMap<>(UCA);
id_noRoundTrip.put(id, noRoundTrip);
ids.add(parsedID.toString());
UnicodeSet nonLatinUnicodeSet = getNonLatinSet(script, scriptCode);
@@ -776,13 +776,13 @@
Map<String, Map<String, Map<String, Boolean>>> xToTagToYToRoundtrip, boolean fromNonLatinToLatin,
String scriptChoice, UnicodeSet totalNonLatinSet) {
- Set<String> extras = new TreeSet<String>(UCA);
+ Set<String> extras = new TreeSet<>(UCA);
for (UnicodeSetIterator it = new UnicodeSetIterator(totalNonLatinSet); it.next();) {
extras.add(it.getString());
}
// find the ids that actually occur
- Set<String> ids = new TreeSet<String>(UCA);
+ Set<String> ids = new TreeSet<>(UCA);
for (String x : xToTagToYToRoundtrip.keySet()) {
ids.addAll(xToTagToYToRoundtrip.get(x).keySet());
}
@@ -945,6 +945,7 @@
@SuppressWarnings({ "rawtypes", "unchecked" })
static public class CollectionOfComparablesComparator implements Comparator {
+ @Override
public int compare(Object o1, Object o2) {
if (o1 == null) {
if (o2 == null) return 0;
@@ -973,6 +974,7 @@
}
static class ReverseComparator implements Comparator<Object> {
+ @Override
public int compare(Object o1, Object o2) {
String a = o1.toString();
char a1 = a.charAt(0);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateUnicodeCounts.java b/tools/java/org/unicode/cldr/tool/GenerateUnicodeCounts.java
index 13fe4e3..3d56af6 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateUnicodeCounts.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateUnicodeCounts.java
@@ -8,8 +8,8 @@
public class GenerateUnicodeCounts {
public static void main(String[] args) {
- UnicodeMap<VersionInfo> ages = new UnicodeMap<VersionInfo>();
- UnicodeMap<String> scripts = new UnicodeMap<String>();
+ UnicodeMap<VersionInfo> ages = new UnicodeMap<>();
+ UnicodeMap<String> scripts = new UnicodeMap<>();
UnicodeSet us = new UnicodeSet("[[:cn:][:cs:][:co:]]").complement();
for (String s : us) {
int i = s.codePointAt(0);
diff --git a/tools/java/org/unicode/cldr/tool/GenerateValidityXml.java b/tools/java/org/unicode/cldr/tool/GenerateValidityXml.java
index 55db9b6..1eecefd 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateValidityXml.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateValidityXml.java
@@ -128,7 +128,7 @@
Status oldStatus = get(currency);
if (oldStatus == null || newStatus.compareTo(oldStatus) < 0) {
put(currency, newStatus);
- }
+ }
}
}
@@ -148,7 +148,7 @@
try (TempPrintWriter output = TempPrintWriter.openUTF8Writer(CLDRPaths.COMMON_DIRECTORY, "validity/" + type + ".xml")) {
adder.target = output;
output.append(DtdType.supplementalData.header(MethodHandles.lookup().lookupClass())
- + "\t<version number=\"$Revision" /*hack to stop SVN changing this*/ + "$\"/>\n"
+ + "\t<version number=\"$Revision" + "$\"/>\n"
+ "\t<idValidity>\n");
for (Entry<Status, Collection<String>> entry2 : subtypeMap.asMap().entrySet()) {
Validity.Status subtype = entry2.getKey();
@@ -321,7 +321,7 @@
switch (code) {
case "Aran":
case "Qaag":
- case "Zsye":
+ case "Zsye":
case "Zanb":
case "Zinh":
case "Zyyy":
@@ -329,7 +329,7 @@
break;
default:
switch (subtype) {
- case private_use:
+ case private_use:
if (code.compareTo("Qaaq") < 0) {
subtype = Validity.Status.reserved;
}
diff --git a/tools/java/org/unicode/cldr/tool/GenerateXMB.java b/tools/java/org/unicode/cldr/tool/GenerateXMB.java
index 6e66428..f7dd199 100644
--- a/tools/java/org/unicode/cldr/tool/GenerateXMB.java
+++ b/tools/java/org/unicode/cldr/tool/GenerateXMB.java
@@ -67,7 +67,7 @@
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -94,7 +94,7 @@
DATE = dateFormat.format(new Date());
}
static final String stock = "en|ar|de|es|fr|it|ja|ko|nl|pl|ru|th|tr|pt|zh|zh_Hant|bg|ca|cs|da|el|fa|fi|fil|hi|hr|hu|id|lt|lv|ro|sk|sl|sr|sv|uk|vi|he|nb|et|ms|am|bn|gu|is|kn|ml|mr|sw|ta|te|ur|eu|gl|af|zu|en_GB|es_419|pt_PT|fr_CA|zh_Hant_HK";
- private static final HashSet<String> REGION_LOCALES = new HashSet<String>(Arrays.asList(stock.split("\\|")));
+ private static final HashSet<String> REGION_LOCALES = new HashSet<>(Arrays.asList(stock.split("\\|")));
final static Options myOptions = new Options("In normal usage, you set the -t option for the target.")
.add("target", ".*", CLDRPaths.TMP_DIRECTORY + "dropbox/xmb/",
@@ -119,7 +119,7 @@
// static Matcher contentMatcher;
static Matcher pathMatcher;
static RegexLookup<String> pathFindRemover = new RegexLookup<String>().loadFromFile(GenerateXMB.class,
- "xmbSkip.txt");; // .compile("//ldml/dates/calendars/calendar\\[@type=\"(?!gregorian).*").matcher("");
+ "xmbSkip.txt"); // .compile("//ldml/dates/calendars/calendar\\[@type=\"(?!gregorian).*").matcher("");
static PrettyPath prettyPath = new PrettyPath();
static int errors = 0;
static Relation<String, String> path2errors = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
@@ -129,7 +129,7 @@
public static final boolean DEBUG = false;
- private static final HashSet<String> SKIP_LOCALES = new HashSet<String>(
+ private static final HashSet<String> SKIP_LOCALES = new HashSet<>(
Arrays.asList(new String[] { "en", "root" }));
public static String DTD_VERSION;
@@ -140,7 +140,7 @@
BRACES, // e.g. {NAME}
XML, // e.g. <ph name='NAME' />
XML_EXAMPLE // e.g. <ph name='NAME' /><ex>EXAMPLE</ex>{0}</ph>
- };
+ }
public static void main(String[] args) throws Exception {
myOptions.parse(args, true);
@@ -300,9 +300,9 @@
log.close();
}
- static Output<String[]> matches = new Output<String[]>();
- static List<String> failures = new ArrayList<String>();
- static Output<Finder> matcherFound = new Output<Finder>();
+ static Output<String[]> matches = new Output<>();
+ static List<String> failures = new ArrayList<>();
+ static Output<Finder> matcherFound = new Output<>();
enum PathStatus {
SKIP, KEEP, MAYBE
@@ -316,7 +316,7 @@
}
String skipPath = pathFindRemover.get(path, null, matches, matcherFound, myFailures);
if (myFailures != null && failures.size() != 0) {
- System.out.println("Failures\n\t" + CollectionUtilities.join(failures, "\n\t"));
+ System.out.println("Failures\n\t" + Joiner.on("\n\t").join(failures));
failures.clear();
}
if (skipPath == null || skipPath.equals("MAYBE")) {
@@ -374,7 +374,7 @@
private static void showDefaultContents(String targetDir, CLDRFile english) throws IOException {
PrintWriter out = FileUtilities.openUTF8Writer(targetDir + "/log/", "locales.txt");
String[] locales = stock.split("\\|");
- Set<R2<String, String>> sorted = new TreeSet<R2<String, String>>();
+ Set<R2<String, String>> sorted = new TreeSet<>();
for (String locale : locales) {
if (locale.isEmpty()) continue;
String name = english.getName(locale);
@@ -440,7 +440,7 @@
String extension = "xml";
Relation<String, String> reasonsToPaths = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> seenStarred = new HashSet<String>();
+ Set<String> seenStarred = new HashSet<>();
Relation<String, Row.R2<PathInfo, String>> countItems = Relation.of(
new TreeMap<String, Set<Row.R2<PathInfo, String>>>(), TreeSet.class);
@@ -647,10 +647,10 @@
int wordCount = 0;
PluralInfo pluralInfo = supplementalDataInfo.getPlurals(locale);
int lineCount = 0;
- Set<String> errorSet = new LinkedHashSet<String>();
+ Set<String> errorSet = new LinkedHashSet<>();
for (Entry<String, Set<R2<PathInfo, String>>> entry : countItems.keyValuesSet()) {
String countLessPath = entry.getKey();
- Map<String, String> fullValues = new TreeMap<String, String>();
+ Map<String, String> fullValues = new TreeMap<>();
PathInfo pathInfo = null;
String value = null;
for (R2<PathInfo, String> entry2 : entry.getValue()) {
@@ -924,7 +924,7 @@
public Map<String, String> getPlaceholderReplacementsToOriginal() {
if (placeholders == null) return null;
- Map<String, String> placeholderOutput = new LinkedHashMap<String, String>();
+ Map<String, String> placeholderOutput = new LinkedHashMap<>();
for (String id : placeholders.keySet()) {
placeholderOutput.put(id, getPlaceholderWithExample(id));
}
@@ -988,6 +988,7 @@
return path.compareTo(arg0.path);
}
+ @Override
public String toString() {
return path;
}
@@ -995,8 +996,8 @@
static class EnglishInfo implements Iterable<PathInfo> {
- final Map<String, PathInfo> pathToPathInfo = new TreeMap<String, PathInfo>();
- final Map<Long, PathInfo> longToPathInfo = new HashMap<Long, PathInfo>();
+ final Map<String, PathInfo> pathToPathInfo = new TreeMap<>();
+ final Map<Long, PathInfo> longToPathInfo = new HashMap<>();
final CLDRFile english;
PathInfo getPathInfo(long hash) {
@@ -1022,9 +1023,9 @@
this.english = english;
// we don't want the fully resolved paths, but we do want the direct inheritance from root.
//Status status = new Status();
- Map<String, List<Set<String>>> starredPaths = new TreeMap<String, List<Set<String>>>();
+ Map<String, List<Set<String>>> starredPaths = new TreeMap<>();
- HashSet<String> metazonePaths = new HashSet<String>();
+ HashSet<String> metazonePaths = new HashSet<>();
// ^//ldml/dates/timeZoneNames/metazone\[@type="([^"]*)"]
for (MetazoneInfo metazoneInfo : MetazoneInfo.METAZONE_LIST) {
for (String item : metazoneInfo.getTypes()) {
@@ -1035,7 +1036,7 @@
}
// TODO add short countries
- HashSet<String> extraLanguages = new HashSet<String>();
+ HashSet<String> extraLanguages = new HashSet<>();
// ldml/localeDisplayNames/languages/language[@type=".*"]
for (String langId : PathDescription.EXTRA_LANGUAGES) {
@@ -1047,6 +1048,7 @@
.addAll(english)
.removeAll(
new Transform<String, Boolean>() {
+ @Override
public Boolean transform(String source) {
return source.startsWith("//ldml/dates/timeZoneNames/metazone") ? Boolean.TRUE
: Boolean.FALSE;
@@ -1055,14 +1057,14 @@
.get();
sorted.addAll(metazonePaths);
if (DEBUG) {
- TreeSet<String> diffs = new TreeSet<String>(extraLanguages);
+ TreeSet<String> diffs = new TreeSet<>(extraLanguages);
diffs.removeAll(sorted);
System.out.println(diffs);
}
sorted.addAll(extraLanguages);
// add the extra Count items.
- Map<String, String> extras = new HashMap<String, String>();
+ Map<String, String> extras = new HashMap<>();
Matcher m = COUNT_ATTRIBUTE.matcher("");
for (String path : sorted) {
@@ -1080,7 +1082,7 @@
sorted.addAll(extras.keySet());
Relation<String, String> reasonsToPaths = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
- Set<String> missingDescriptions = new TreeSet<String>();
+ Set<String> missingDescriptions = new TreeSet<>();
//Output<String[]> pathArguments = new Output<String[]>();
CoverageLevel2 coverageLevel = CoverageLevel2.getInstance("en");
@@ -1208,7 +1210,7 @@
static final Set<String> HAS_DAYLIGHT;
static {
- Set<String> hasDaylightTemp = new HashSet<String>();
+ Set<String> hasDaylightTemp = new HashSet<>();
Date date = new Date();
main: for (String zoneId : sc.getCanonicalTimeZones()) {
TimeZone zone = TimeZone.getTimeZone(zoneId);
@@ -1232,7 +1234,7 @@
private static PrintWriter countFile;
static {
// start with certain special-case countries
- Set<String> singularCountries = new HashSet<String>(
+ Set<String> singularCountries = new HashSet<>(
Arrays.asList("CL EC ES NZ PT AQ FM GL KI UM PF".split(" ")));
Map<String, Set<String>> countryToZoneSet = sc.getCountryToZoneSet();
@@ -1248,7 +1250,7 @@
continue;
}
// make a set of sets
- List<TimeZone> initial = new ArrayList<TimeZone>();
+ List<TimeZone> initial = new ArrayList<>();
for (String s : zones) {
initial.add(TimeZone.getTimeZone(s));
}
@@ -1312,7 +1314,7 @@
static final List<MetazoneInfo> METAZONE_LIST;
static {
// Set<String> zones = supplementalDataInfo.getCanonicalTimeZones();
- ArrayList<MetazoneInfo> result = new ArrayList<MetazoneInfo>();
+ ArrayList<MetazoneInfo> result = new ArrayList<>();
Map<String, String> zoneToCountry = sc.getZoneToCounty();
@@ -1341,6 +1343,7 @@
METAZONE_LIST = Collections.unmodifiableList(result);
}
+ @Override
public String toString() {
return sc.getZoneToCounty().get(golden)
+ "\t" + metazoneId
@@ -1390,7 +1393,7 @@
FileInputStream fis = new FileInputStream(file);
XMLReader xmlReader = XMLFileReader.createXMLReader(false);
xmlReader.setErrorHandler(new MyErrorHandler());
- Map<String, String> data = new TreeMap<String, String>();
+ Map<String, String> data = new TreeMap<>();
xmlReader.setContentHandler(new MyContentHandler(locale, data, info));
InputSource is = new InputSource(fis);
is.setSystemId(file);
@@ -1415,16 +1418,19 @@
}
static class MyErrorHandler implements ErrorHandler {
+ @Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("\nerror: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("\nfatalError: " + XMLFileReader.showSAX(exception));
throw exception;
}
+ @Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("\nwarning: " + XMLFileReader.showSAX(exception));
throw exception;
@@ -1439,7 +1445,7 @@
private StringBuilder currentText = new StringBuilder();
private long lastId;
private String lastPluralTag;
- private Map<String, String> pluralTags = new LinkedHashMap<String, String>();
+ private Map<String, String> pluralTags = new LinkedHashMap<>();
private Set<String> pluralKeywords;
public MyContentHandler(ULocale locale, Map<String, String> data, EnglishInfo info) {
diff --git a/tools/java/org/unicode/cldr/tool/GeneratedPluralSamples.java b/tools/java/org/unicode/cldr/tool/GeneratedPluralSamples.java
index 0655846..4432c91 100644
--- a/tools/java/org/unicode/cldr/tool/GeneratedPluralSamples.java
+++ b/tools/java/org/unicode/cldr/tool/GeneratedPluralSamples.java
@@ -25,10 +25,11 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
import org.unicode.cldr.util.TempPrintWriter;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
+import com.ibm.icu.text.FixedDecimal;
import com.ibm.icu.text.PluralRules;
-import com.ibm.icu.text.PluralRules.FixedDecimal;
+import com.ibm.icu.text.PluralRules.Operand;
/**
* Regenerate the plural files. Related classes are:
@@ -46,7 +47,7 @@
private static final int UNBOUNDED_LIMIT = 20;
private static final String RANGE_SEPARATOR = "~";
public static final String SEQUENCE_SEPARATOR = ", ";
-
+
static SupplementalDataInfo sInfo = CLDRConfig.getInstance().getSupplementalDataInfo(); // forward declaration
static class Range implements Comparable<Range> {
@@ -127,11 +128,13 @@
return b;
}
+ @Override
public String toString() {
return format(new StringBuilder()).toString();
}
}
+
private static void append(StringBuilder b, long startValue2, long visibleFractionDigitCount2) {
int len = b.length();
for (int i = 0; i < visibleFractionDigitCount2; ++i) {
@@ -155,11 +158,11 @@
*/
static class Ranges {
@SuppressWarnings("unchecked")
- Set<Range>[] data = new Set[5];
+ Set<Range>[] data = new Set[10];
int size = 0;
{
for (int i = 0; i < data.length; ++i) {
- data[i] = new TreeSet<Range>();
+ data[i] = new TreeSet<>();
}
}
@@ -231,7 +234,7 @@
Warning, Error
}
- Set<String> bounds = new TreeSet<String>();
+ Set<String> bounds = new TreeSet<>();
public void add(Type type, String string) {
if (string != null && !string.isEmpty()) {
@@ -254,16 +257,18 @@
static class DataSample {
int count;
int countNoTrailing = -1;
- final Set<Double> noTrailing = new TreeSet<Double>();
+ final Set<Double> noTrailing = new TreeSet<>();
final Ranges samples = new Ranges();
- final FixedDecimal[] digitToSample = new FixedDecimal[10];
+ final FixedDecimal[] digitToSample = new FixedDecimal[20];
final PluralRules.SampleType sampleType;
+ final Set<FixedDecimal> exponentSamples = new TreeSet<>();
private boolean isBounded;
public DataSample(PluralRules.SampleType sampleType) {
this.sampleType = sampleType;
}
+ @Override
public String toString() {
Ranges samples2 = new Ranges(samples);
for (FixedDecimal ni : digitToSample) {
@@ -271,10 +276,29 @@
samples2.add(ni);
}
}
- return samples2 + (isBounded ? "" : ", …");
+ return format(samples2) + (isBounded ? "" : ", …");
+ }
+
+ private String format(Ranges samples2) {
+ StringBuilder builder = new StringBuilder().append(samples2);
+ int max = 5;
+ for (FixedDecimal exponentSample : exponentSamples) {
+ if (builder.length() != 0) {
+ builder.append(", ");
+ }
+ builder.append(exponentSample);
+ if (--max < 0) {
+ break;
+ }
+ }
+ return builder.toString();
}
private void add(FixedDecimal ni) {
+ if (ni.getPluralOperand(Operand.e) != 0) {
+ exponentSamples.add(ni);
+ return;
+ }
++count;
if (samples.size() < SAMPLE_LIMIT * 2) {
samples.add(ni);
@@ -293,17 +317,19 @@
DataSample other = (DataSample) obj;
return count == other.count
&& samples.equals(other.samples)
- && digitToSample.equals(other.digitToSample);
+ && digitToSample.equals(other.digitToSample)
+ && exponentSamples.equals(other.exponentSamples)
+ ;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
- return count ^ samples.hashCode() ^ Arrays.asList(digitToSample).hashCode();
+ return count ^ samples.hashCode() ^ Arrays.asList(digitToSample).hashCode() ^ exponentSamples.hashCode();
}
public void freeze(String keyword, PluralRules rule) {
- countNoTrailing = noTrailing.size();
+ countNoTrailing = noTrailing.size() + exponentSamples.size();
//System.out.println(sampleType + ", " + keyword + ", " + countNoTrailing + ", " + rule);
isBounded = computeBoundedWithSize(keyword, rule);
if (countNoTrailing > 0) {
@@ -370,6 +396,7 @@
}
}
+ @Override
public String toString() {
String integersString = integers.toString();
String decimalsString = type == PluralType.ordinal ? "" : decimals.toString();
@@ -440,33 +467,50 @@
return result;
}
- private final TreeMap<String, DataSamples> keywordToData = new TreeMap<String, DataSamples>();
+ private final TreeMap<String, DataSamples> keywordToData = new TreeMap<>();
private final PluralType type;
- GeneratedPluralSamples(PluralInfo pluralInfo, PluralType type) {
+ GeneratedPluralSamples(PluralInfo pluralInfo, PluralType type, Set<String> equivalentLocales) {
this.type = type;
- PluralInfo pluralRule = pluralInfo;
+
// 9999, powers; no decimals
- collect(pluralRule, 10000, 0);
- collect10s(pluralRule, 10000, 1000000, 0);
+ collect(pluralInfo, 0, 10_000, 0);
+ collect10s(pluralInfo, 10_000, 1_000_000, 0);
if (type == PluralType.cardinal) {
-
// 9999.9, powers .0
- collect(pluralRule, 10000, 1);
- collect10s(pluralRule, 10000, 1000000, 1);
+ collect(pluralInfo, 0, 10_000, 1);
+ collect10s(pluralInfo, 10_000, 1_000_000, 1);
// 999.99, powers .00
- collect(pluralRule, 1000, 2);
- collect10s(pluralRule, 1000, 1000000, 2);
+ collect(pluralInfo, 0, 1000, 2);
+ collect10s(pluralInfo, 1000, 1_000_000, 2);
// 99.999, powers .000
- collect(pluralRule, 100, 3);
- collect10s(pluralRule, 100, 1000000, 3);
+ collect(pluralInfo, 0, 100, 3);
+ collect10s(pluralInfo, 100, 1_000_000, 3);
// 9.9999, powers .0000
- collect(pluralRule, 10, 4);
- collect10s(pluralRule, 10, 1000000, 4);
+ collect(pluralInfo, 0, 10, 4);
+ collect10s(pluralInfo, 10, 1_000_000, 4);
+
+ // add some exponent samples for French
+ // TODO check for any rule with exponent operand and do the same.
+ if (equivalentLocales.contains("fr")) {
+ final PluralRules pluralRules = pluralInfo.getPluralRules();
+ for (int i = 1; i < 15; ++i) {
+ add(pluralRules, i, 0, 3);
+ add(pluralRules, i, 0, 6);
+ add(pluralRules, i, 0, 9);
+ add(pluralRules, i+0.1, 1, 3);
+ add(pluralRules, i+0.1, 1, 6);
+ add(pluralRules, i+0.1, 1, 9);
+ add(pluralRules, i+0.0001, 4, 3);
+ add(pluralRules, i+0.0000001, 7, 6);
+ add(pluralRules, i+0.0000000001, 10, 9);
+ }
+ int debug = 0;
+ }
}
for (Entry<String, DataSamples> entry : keywordToData.entrySet()) {
@@ -474,16 +518,16 @@
}
}
- private void collect10s(PluralInfo pluralInfo, int start, int end, int decimals) {
+ private void collect10s(PluralInfo pluralInfo, long start, long end, int decimals) {
double power = Math.pow(10, decimals);
for (long i = start * (int) power; i <= end * (int) power; i *= 10) {
add(pluralInfo, i / power, decimals);
}
}
- private void collect(PluralInfo pluralInfo, int limit, int decimals) {
+ private void collect(PluralInfo pluralInfo, long start, long limit, int decimals) {
double power = Math.pow(10, decimals);
- for (int i = 0; i <= limit * (int) power; ++i) {
+ for (long i = start; i <= limit * (int) power; ++i) {
add(pluralInfo, i / power, decimals);
}
}
@@ -497,6 +541,23 @@
String keyword = pluralRules.select(ni);
INFO.add(Info.Type.Warning, checkForDuplicates(pluralRules, ni));
+ add(pluralRules, keyword, ni);
+ }
+
+ public void add(final PluralRules pluralRules, double n, int v, int e) {
+ FixedDecimal ni = FixedDecimal.createWithExponent(n * Math.pow(10, e), v, e);
+ String keyword = pluralRules.select(ni);
+ System.out.println("{" + n + ", " + v + ", " + e + "} " + ni + " => " + keyword + ", " + (ni.getVisibleDecimalDigitCount() == 0 ? "integer" : "decimal"));
+ add(pluralRules, keyword, ni);
+ }
+
+// public void add(PluralRules pluralRules, FixedDecimal ni) {
+// String keyword = pluralRules.select(ni);
+// System.out.println(ni + " => " + keyword + ", " + (ni.getVisibleDecimalDigitCount() == 0 ? "integer" : "decimal"));
+// add(pluralRules, keyword, ni);
+// }
+
+ public void add(PluralRules pluralRules, String keyword, FixedDecimal ni) {
DataSamples data = keywordToData.get(keyword);
if (data == null) {
keywordToData.put(keyword, data = new DataSamples(keyword, pluralRules));
@@ -506,19 +567,20 @@
public static String checkForDuplicates(PluralRules pluralRules, FixedDecimal ni) {
// add test that there are no duplicates
- Set<String> keywords = new LinkedHashSet<String>();
- for (String keywordCheck : pluralRules.getKeywords()) {
- if (pluralRules.matches(ni, keywordCheck)) {
- keywords.add(keywordCheck);
- }
- }
- if (!keywords.contains("other") || keywords.size() > 2) { // should be either {other, x} or {other}
- String message = "";
- for (String keywordCheck : keywords) {
- message += keywordCheck + ": " + pluralRules.getRules(keywordCheck) + "; ";
- }
- return "Duplicate rules with " + ni + ":\t" + message;
- }
+ // TODO restore when "CLDR-14206", "Fix CLDR code for FixedDecimal" is done
+// Set<String> keywords = new LinkedHashSet<>();
+// for (String keywordCheck : pluralRules.getKeywords()) {
+// if (pluralRules.matches(ni, keywordCheck)) {
+// keywords.add(keywordCheck);
+// }
+// }
+// if (!keywords.contains("other") || keywords.size() > 2) { // should be either {other, x} or {other}
+// String message = "";
+// for (String keywordCheck : keywords) {
+// message += keywordCheck + ": " + pluralRules.getRules(keywordCheck) + "; ";
+// }
+// return "Duplicate rules with " + ni + ":\t" + message;
+// }
return null;
}
@@ -551,10 +613,8 @@
}
}
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) {
myOptions.parse(MyOptions.filter, args, true);
- PluralRules test = PluralRules.parseDescription("one: n in 3,4 or f mod 5 in 3..4;");
- System.out.println("Check: " + test);
Matcher localeMatcher = !MyOptions.filter.option.doesOccur() ? null : PatternCache.get(MyOptions.filter.option.getValue()).matcher("");
boolean fileFormat = true; //MyOptions.xml.option.doesOccur();
@@ -565,7 +625,7 @@
int failureCount = 0;
PluralRules pluralRules2 = PluralRules.createRules("one: n is 3..9; two: n is 7..12");
- System.out.println("Check: " + checkForDuplicates(pluralRules2, new FixedDecimal(8)));
+ System.out.println("Check: " + checkForDuplicates(pluralRules2, new FixedDecimal("8e1")));
for (PluralType type : PluralType.values()) {
try (TempPrintWriter out = TempPrintWriter.openUTF8Writer(MyOptions.output.option.getValue(), type == PluralType.cardinal ? "plurals.xml" : "ordinals.xml")) {
@@ -587,8 +647,8 @@
}
// sort if necessary
- Set<Entry<PluralInfo, Set<String>>> sorted = sortNew ? new LinkedHashSet<Entry<PluralInfo, Set<String>>>()
- : new TreeSet<Entry<PluralInfo, Set<String>>>(new HackComparator(type == PluralType.cardinal
+ Set<Entry<PluralInfo, Set<String>>> sorted = sortNew ? new LinkedHashSet<>()
+ : new TreeSet<>(new HackComparator(type == PluralType.cardinal
? WritePluralRules.HACK_ORDER_PLURALS : WritePluralRules.HACK_ORDER_ORDINALS));
for (Entry<PluralInfo, Set<String>> entry : seenAlready.keyValuesSet()) {
sorted.add(entry);
@@ -609,13 +669,20 @@
if (fileFormat) {
if (!keywords.equals(oldKeywords)) {
- out.println("\n <!-- " + keywords.size() + ": " + CollectionUtilities.join(keywords, ",") + " -->\n");
+ out.println("\n <!-- " + keywords.size() + ": " + Joiner.on(",")
+ .join(keywords) + " -->\n");
oldKeywords = keywords;
}
out.println(WritePluralRules.formatPluralRuleHeader(equivalentLocales));
System.out.println(type + "\t" + equivalentLocales);
}
- GeneratedPluralSamples samples = new GeneratedPluralSamples(pluralInfo, type);
+ GeneratedPluralSamples samples;
+ try {
+ samples = new GeneratedPluralSamples(pluralInfo, type, equivalentLocales);
+ } catch (Exception e) {
+ out.dontReplaceFile();
+ throw e;
+ }
samplesToPlurals.put(samples, pluralInfo);
for (String keyword : keywords) {
Count count = Count.valueOf(keyword);
@@ -659,10 +726,11 @@
if (entry.getValue().size() == 1) {
continue;
}
- Set<String> remainder = new LinkedHashSet<String>(entry.getValue());
+ Set<String> remainder = new LinkedHashSet<>(entry.getValue());
String first = remainder.iterator().next();
remainder.remove(first);
- System.err.println(type + "\tEQUIV:\t\t" + first + "\t≣\t" + CollectionUtilities.join(remainder, ", "));
+ System.err.println(type + "\tEQUIV:\t\t" + first + "\t≣\t" + Joiner.on(", ")
+ .join(remainder));
}
System.out.println();
}
diff --git a/tools/java/org/unicode/cldr/tool/GetChanges.java b/tools/java/org/unicode/cldr/tool/GetChanges.java
index 9fb4b6d..3c1e704 100644
--- a/tools/java/org/unicode/cldr/tool/GetChanges.java
+++ b/tools/java/org/unicode/cldr/tool/GetChanges.java
@@ -51,7 +51,7 @@
continue;
}
for (File commonSeed : commonSeedFiles) {
- if (!commonSeed.isDirectory()
+ if (!commonSeed.isDirectory()
|| "dtd".equals(commonSeed.getName())) {
continue;
}
@@ -149,7 +149,7 @@
if (verbose) {
System.out.println(
dir
- +";\tnew\t"
+ +";\tnew\t"
+ "\tlocale=" + localeID + ";"
+ "\taction=add;"
+ "\tpath=\t" + path
@@ -157,7 +157,7 @@
);
}
} else {
- // we do a lot of processing on the annotations, so most likely are just changes introduced by that.
+ // we do a lot of processing on the annotations, so most likely are just changes introduced by that.
// So ignore for now
if (path.startsWith("//ldml/annotations")) {
continue;
@@ -220,8 +220,8 @@
int totalCount = 0;
int localeCount = 0;
- Output<String> localeWhereFound = new Output<String>();
- Output<String> pathWhereFound = new Output<String>();
+ Output<String> localeWhereFound = new Output<>();
+ Output<String> pathWhereFound = new Output<>();
CLDRFile englishCldrFile = trunkFactory.make("en", false);
final Set<String> paths = ImmutableSet.copyOf(englishCldrFile.iterator());
@@ -261,11 +261,11 @@
} catch (Exception e) {
}
- Map<PathHeader, Data> results = new TreeMap<PathHeader, Data>();
+ Map<PathHeader, Data> results = new TreeMap<>();
for (String xpath : paths) {
- if (xpath.contains("fallbackRegionFormat")
- || xpath.contains("exemplar")
+ if (xpath.contains("fallbackRegionFormat")
+ || xpath.contains("exemplar")
|| xpath.contains("/identity")) {
continue;
}
@@ -311,19 +311,19 @@
for (Entry<PathHeader, Data> entry : results.entrySet()) {
PathHeader ph = entry.getKey();
String englishValue = englishCldrFile.getStringValue(ph.getOriginalPath());
- System.out.println(localeCount
- + "\t" + ++itemCount
- + "\t" + locale
- + "\t" + english.getName(locale)
- + "\t" + ph
- + "\t«" + englishValue
+ System.out.println(localeCount
+ + "\t" + ++itemCount
+ + "\t" + locale
+ + "\t" + english.getName(locale)
+ + "\t" + ph
+ + "\t«" + englishValue
+ "»\t" + entry.getValue());
}
totalCount += itemCount;
}
System.out.println("##Total:\t" + totalCount);
for ( Entry<String, PathHeader> entry : missing.entries()) {
- System.out.println(entry.getKey() + "\t" + entry.getValue());
+ System.out.println(entry.getKey() + "\t" + entry.getValue());
}
}
diff --git a/tools/java/org/unicode/cldr/tool/GetDescriptions.java b/tools/java/org/unicode/cldr/tool/GetDescriptions.java
index 02d73f4..1ac586d 100644
--- a/tools/java/org/unicode/cldr/tool/GetDescriptions.java
+++ b/tools/java/org/unicode/cldr/tool/GetDescriptions.java
@@ -19,19 +19,19 @@
static Matcher matcher = PatternCache.get("([^,(]+)(,([^(]+))?(.*)").matcher("");
- static Map<String, String> items = new TreeMap<String, String>();
+ static Map<String, String> items = new TreeMap<>();
static int allCount = 1;
static int commaCount = 1;
- private static Map<String, Map<String, Set<String>>> name_type_codes = new TreeMap<String, Map<String, Set<String>>>();
+ private static Map<String, Map<String, Set<String>>> name_type_codes = new TreeMap<>();
- private static Set<String> preCommas = new TreeSet<String>();
+ private static Set<String> preCommas = new TreeSet<>();
- private static Set<String> postCommas = new TreeSet<String>();
+ private static Set<String> postCommas = new TreeSet<>();
- private static Map<String, String> descriptionWithoutComments = new TreeMap<String, String>();
+ private static Map<String, String> descriptionWithoutComments = new TreeMap<>();
- private static Set<String> uninvertedNames = new HashSet<String>();
+ private static Set<String> uninvertedNames = new HashSet<>();
public static void main(String[] args) throws IOException {
StandardCodes sc = StandardCodes.make();
@@ -200,9 +200,9 @@
String code, String newDescriptionWithoutComment) {
Map<String, Set<String>> type_codes = name_type_codes.get(newDescriptionWithoutComment);
if (type_codes == null)
- name_type_codes.put(newDescriptionWithoutComment, type_codes = new TreeMap<String, Set<String>>());
+ name_type_codes.put(newDescriptionWithoutComment, type_codes = new TreeMap<>());
Set<String> codes = type_codes.get(type);
- if (codes == null) type_codes.put(type, codes = new TreeSet<String>());
+ if (codes == null) type_codes.put(type, codes = new TreeSet<>());
codes.add(code);
}
@@ -216,7 +216,7 @@
.matcher("");
private static void checkInversion(PrintWriter commas, String type, String code, String[] parts) {
- Set<String> items = new TreeSet<String>(Arrays.asList(parts));
+ Set<String> items = new TreeSet<>(Arrays.asList(parts));
for (String item : items) {
if (!directional.reset(item).matches()) {
continue;
diff --git a/tools/java/org/unicode/cldr/tool/GetLanguageData.java b/tools/java/org/unicode/cldr/tool/GetLanguageData.java
index 0c4bbe0..e820501 100644
--- a/tools/java/org/unicode/cldr/tool/GetLanguageData.java
+++ b/tools/java/org/unicode/cldr/tool/GetLanguageData.java
@@ -18,8 +18,8 @@
.make(CLDRPaths.MAIN_DIRECTORY, ".*");
CLDRFile english = cldrFactory.make("en", true);
Set<String> euCountries = sdata.getContained("EU");
- Counter<String> languageToGdp = new Counter<String>();
- Counter<String> languageToPop = new Counter<String>();
+ Counter<String> languageToGdp = new Counter<>();
+ Counter<String> languageToPop = new Counter<>();
public static void main(String[] args) {
new GetLanguageData().run();
@@ -90,7 +90,7 @@
}
if (langUnknown > 0) {
languageToGdp.add("und", (long) (gdp * langUnknown / territoryPop));
- languageToPop.add("und", (long) (langUnknown));
+ languageToPop.add("und", (langUnknown));
}
}
}
diff --git a/tools/java/org/unicode/cldr/tool/IdToPath.java b/tools/java/org/unicode/cldr/tool/IdToPath.java
index 065e642..aa074f3 100644
--- a/tools/java/org/unicode/cldr/tool/IdToPath.java
+++ b/tools/java/org/unicode/cldr/tool/IdToPath.java
@@ -7,7 +7,7 @@
* Do not manually edit this file.
*/
public class IdToPath {
- static final HashMap<String, String> map = new HashMap<String, String>();
+ static final HashMap<String, String> map = new HashMap<>();
public static String getPath(String id) {
return map.get(id);
diff --git a/tools/java/org/unicode/cldr/tool/KeymanCheck.java b/tools/java/org/unicode/cldr/tool/KeymanCheck.java
index 2669748..4ee747a 100644
--- a/tools/java/org/unicode/cldr/tool/KeymanCheck.java
+++ b/tools/java/org/unicode/cldr/tool/KeymanCheck.java
@@ -144,8 +144,8 @@
for (String lang : langs) {
PopulationData pop = getPopulationData(lang);
System.out.println(
-// ++count
-// + "\t" +
+// ++count
+// + "\t" +
en.getName(lang)
+ "\t" + lang
+ "\t" + (pop != null ? (long) pop.getLiteratePopulation() : "-1")
diff --git a/tools/java/org/unicode/cldr/tool/LanguageCodeConverter.java b/tools/java/org/unicode/cldr/tool/LanguageCodeConverter.java
index f415f12..5d66a1b 100644
--- a/tools/java/org/unicode/cldr/tool/LanguageCodeConverter.java
+++ b/tools/java/org/unicode/cldr/tool/LanguageCodeConverter.java
@@ -24,9 +24,9 @@
import com.ibm.icu.util.ULocale;
public class LanguageCodeConverter {
- private static Map<String, String> languageNameToCode = new TreeMap<String, String>();
- private static Set<String> exceptionCodes = new TreeSet<String>();
- private static Set<String> parseErrors = new LinkedHashSet<String>();
+ private static Map<String, String> languageNameToCode = new TreeMap<>();
+ private static Set<String> exceptionCodes = new TreeSet<>();
+ private static Set<String> parseErrors = new LinkedHashSet<>();
private static Map<String, R2<List<String>, String>> languageAliases = CLDRConfig.getInstance().getSupplementalDataInfo().getLocaleAliasInfo()
.get("language");
@@ -81,7 +81,7 @@
// http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
Map<String, Map<String, Map<String, String>>> lstreg = StandardCodes.getLStreg();
Map<String, Map<String, String>> languages = lstreg.get("language");
- Set<String> validCodes = new HashSet<String>();
+ Set<String> validCodes = new HashSet<>();
for (Entry<String, Map<String, String>> codeInfo : languages.entrySet()) {
String code = codeInfo.getKey();
diff --git a/tools/java/org/unicode/cldr/tool/LikelySubtags.java b/tools/java/org/unicode/cldr/tool/LikelySubtags.java
index fef007e..7ac57c6 100644
--- a/tools/java/org/unicode/cldr/tool/LikelySubtags.java
+++ b/tools/java/org/unicode/cldr/tool/LikelySubtags.java
@@ -11,6 +11,7 @@
import org.unicode.cldr.util.Builder;
import org.unicode.cldr.util.LanguageTagParser;
+import org.unicode.cldr.util.LanguageTagParser.OutputOption;
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.BasicLanguageData;
import org.unicode.cldr.util.SupplementalDataInfo.BasicLanguageData.Type;
@@ -26,8 +27,9 @@
private Map<String, String> toMaximized;
private boolean favorRegion = false;
- private SupplementalDataInfo supplementalDataInfo;
- private Map<String, String> currencyToLikelyTerritory = new HashMap<String, String>();
+ private static SupplementalDataInfo supplementalDataInfo;
+ private static Map<String, String> currencyToLikelyTerritory;
+ private static final Object SYNC = new Object();
/**
* Create the likely subtags.
@@ -35,50 +37,43 @@
* @param toMaximized
*/
public LikelySubtags(Map<String, String> toMaximized) {
- this(SupplementalDataInfo.getInstance(), toMaximized);
- }
-
- /**
- * Create the likely subtags.
- *
- * @param toMaximized
- */
- public LikelySubtags(SupplementalDataInfo supplementalDataInfo) {
- this(supplementalDataInfo, supplementalDataInfo.getLikelySubtags());
- }
-
- /**
- * Create the likely subtags.
- *
- * @param toMaximized
- */
- public LikelySubtags(SupplementalDataInfo supplementalDataInfo, Map<String, String> toMaximized) {
- this.supplementalDataInfo = supplementalDataInfo;
- this.toMaximized = toMaximized;
-
- Date now = new Date();
- Set<Row.R2<Double, String>> sorted = new TreeSet<Row.R2<Double, String>>();
- for (String territory : supplementalDataInfo.getTerritoriesWithPopulationData()) {
- PopulationData pop = supplementalDataInfo.getPopulationDataForTerritory(territory);
- double population = pop.getPopulation();
- sorted.add(Row.of(-population, territory));
+ loadStaticVariables();
+ if (this.toMaximized == null) {
+ this.toMaximized = supplementalDataInfo.getLikelySubtags();
+ } else {
+ this.toMaximized = toMaximized;
}
- for (R2<Double, String> item : sorted) {
- String territory = item.get1();
- Set<CurrencyDateInfo> targetCurrencyInfo = supplementalDataInfo.getCurrencyDateInfo(territory);
- if (targetCurrencyInfo == null) {
- continue;
+ }
+
+ private static void loadStaticVariables() {
+ if (supplementalDataInfo != null && currencyToLikelyTerritory != null) {
+ return;
+ }
+ synchronized(SYNC) {
+ supplementalDataInfo = SupplementalDataInfo.getInstance();
+ currencyToLikelyTerritory = new HashMap<>();
+ Date now = new Date();
+ Set<Row.R2<Double, String>> sorted = new TreeSet<>();
+ for (String territory : supplementalDataInfo.getTerritoriesWithPopulationData()) {
+ PopulationData pop = supplementalDataInfo.getPopulationDataForTerritory(territory);
+ double population = pop.getPopulation();
+ sorted.add(Row.of(-population, territory));
}
- for (CurrencyDateInfo cdi : targetCurrencyInfo) {
- String currency = cdi.getCurrency();
- if (!currencyToLikelyTerritory.containsKey(currency) && cdi.getStart().before(now)
- && cdi.getEnd().after(now) && cdi.isLegalTender()) {
- currencyToLikelyTerritory.put(currency, territory);
+ for (R2<Double, String> item : sorted) {
+ String territory = item.get1();
+ Set<CurrencyDateInfo> targetCurrencyInfo = supplementalDataInfo.getCurrencyDateInfo(territory);
+ if (targetCurrencyInfo == null) {
+ continue;
+ }
+ for (CurrencyDateInfo cdi : targetCurrencyInfo) {
+ String currency = cdi.getCurrency();
+ if (!currencyToLikelyTerritory.containsKey(currency) && cdi.getStart().before(now)
+ && cdi.getEnd().after(now) && cdi.isLegalTender()) {
+ currencyToLikelyTerritory.put(currency, territory);
+ }
}
}
}
- // System.out.println("Currency to Territory:\n\t" +
- // CollectionUtilities.join(currencyToLikelyTerritory.entrySet(), "\n\t"));
}
/**
@@ -87,7 +82,7 @@
* @param toMaximized
*/
public LikelySubtags() {
- this(SupplementalDataInfo.getInstance());
+ this(null);
}
public boolean isFavorRegion() {
@@ -225,7 +220,11 @@
// TODO, optimize if needed by adding private routine that maximizes a LanguageTagParser instead of multiple parsings
// TODO Old, crufty code, needs reworking.
- public synchronized String minimize(String input) {
+ public String minimize(String input) {
+ return minimize(input, OutputOption.ICU_LCVARIANT);
+ }
+
+ public synchronized String minimize(String input, OutputOption oo) {
String maximized = maximize(input, toMaximized);
if (maximized == null) {
return null;
@@ -262,7 +261,7 @@
.setVariants(variants)
.setExtensions(extensions)
.setLocaleExtensions(extensions)
- .toString();
+ .toString(oo);
}
}
return maximized;
diff --git a/tools/java/org/unicode/cldr/tool/ListCoverageLevels.java b/tools/java/org/unicode/cldr/tool/ListCoverageLevels.java
index a2cc163..64fed3a 100644
--- a/tools/java/org/unicode/cldr/tool/ListCoverageLevels.java
+++ b/tools/java/org/unicode/cldr/tool/ListCoverageLevels.java
@@ -30,6 +30,7 @@
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.SupplementalDataInfo;
+import com.google.common.base.Joiner;
import com.google.common.collect.Comparators;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableList;
@@ -37,7 +38,6 @@
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
public class ListCoverageLevels {
public static void main(String[] args) {
@@ -50,7 +50,7 @@
Factory mainAndAnnotationsFactory = config.getMainAndAnnotationsFactory();
Set<String> toTest = sc.getLocaleCoverageLocales(Organization.cldr, EnumSet.allOf(Level.class));
- // ImmutableSortedSet.of("it", "root", "ja");
+ // ImmutableSortedSet.of("it", "root", "ja");
// mainAndAnnotationsFactory.getAvailable();
final Set<CLDRLocale> ALL;
{
@@ -61,12 +61,12 @@
M4<Level, String, Attributes, Boolean> data = ChainedMap.of(
new TreeMap<Level,Object>(),
- new TreeMap<String,Object>(),
+ new TreeMap<String,Object>(),
new TreeMap<Attributes,Object>(),
Boolean.class);
M5<String, Level, CLDRLocale, List<String>, Boolean> starredToLevels = ChainedMap.of(
new TreeMap<String,Object>(),
- new TreeMap<Level,Object>(),
+ new TreeMap<Level,Object>(),
new TreeMap<CLDRLocale,Object>(),
new HashMap<List<String>,Object>(),
Boolean.class);
@@ -111,7 +111,7 @@
// starredToLevels.put(starred, level, cLoc, Boolean.TRUE);
// }
// }
-
+
System.out.println("ALL=" + getLocaleName(null, ALL));
for (Entry<String, Map<Level, Map<CLDRLocale, Map<List<String>, Boolean>>>> entry : starredToLevels) {
@@ -137,7 +137,7 @@
String localeName = getLocaleName(ALL, locales);
items.add(level + ":" + (mixed ? "" : "°") + localeName);
}
- System.out.println(starred + "\t" + items.size() + "\t" + CollectionUtilities.join(items, " "));
+ System.out.println(starred + "\t" + items.size() + "\t" + Joiner.on(" ").join(items));
}
for (Level level : data.keySet()) {
M3<String, Attributes, Boolean> data2 = data.get(level);
@@ -146,10 +146,10 @@
Multimap<String, List<String>> localesToAttrs = Attributes.getLocaleNameToAttributeList(ALL, attributes);
for (Entry<String, Collection<List<String>>> entry : localesToAttrs.asMap().entrySet()) {
Collection<List<String>> attrs = entry.getValue();
- System.out.println(level
- + "\t" + starred
- + "\t" + entry.getKey()
- + "\t" + attrs.size()
+ System.out.println(level
+ + "\t" + starred
+ + "\t" + entry.getKey()
+ + "\t" + attrs.size()
+ "\t" + Attributes.compact(attrs, new StringBuilder()));
}
}
@@ -160,12 +160,12 @@
Function<Set<CLDRLocale>,String> remainderName = x -> {
Set<CLDRLocale> y = new LinkedHashSet<>(all);
y.removeAll(x);
- return "AllLcs-(" + CollectionUtilities.join(y, "|") + ")";
+ return "AllLcs-(" + Joiner.on("|").join(y) + ")";
};
- return all == null ? CollectionUtilities.join(locales, "|")
- : locales.equals(all) ? "AllLcs"
+ return all == null ? Joiner.on("|").join(locales)
+ : locales.equals(all) ? "AllLcs"
: locales.size()*2 > all.size() ? remainderName.apply(locales)
- : CollectionUtilities.join(locales, "|");
+ : Joiner.on("|").join(locales);
}
static class Attributes implements Comparable<Attributes>{
@@ -195,18 +195,8 @@
// Collection<List<String>> attrList = entry.getValue();
// Map<String, Map> map = getMap(attrList);
// getName(map, result);
-// }
+// }
//
-//
-//// localeNameToAttributeList.forEach((name,list) -> {
-//// if (result.length() != 0) {
-//// result.append(' ');
-//// }
-//// result.append(name);
-//// if (!list.isEmpty()) {
-//// result.append(':').append(CollectionUtilities.join(list, "|"));
-//// }
-//// });
// return result;
// }
@@ -266,7 +256,7 @@
for (Iterable<T> list : source) {
Map<T, Map> top = items;
for (T item : list) {
- Map<T, Map> value = (Map<T, Map>) top.get(item);
+ Map<T, Map> value = top.get(item);
if (value == null) {
top.put(item, value = new LinkedHashMap<>());
}
@@ -285,7 +275,8 @@
}
@Override
public String toString() {
- return attributes.isEmpty() ? cLoc.toString() : cLoc + "|" + CollectionUtilities.join(attributes, "|");
+ return attributes.isEmpty() ? cLoc.toString() : cLoc + "|" + Joiner.on("|")
+ .join(attributes);
}
}
}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/tool/ListRedundantUnicodeSets.java b/tools/java/org/unicode/cldr/tool/ListRedundantUnicodeSets.java
index e06e726..1fab28f 100644
--- a/tools/java/org/unicode/cldr/tool/ListRedundantUnicodeSets.java
+++ b/tools/java/org/unicode/cldr/tool/ListRedundantUnicodeSets.java
@@ -104,16 +104,16 @@
colExemplars.removeAll(forTranslit);
}
- System.out.println(localeID
+ System.out.println(localeID
+ "\t" + localeCoverageLevel
- + "\t" + exemplarType
+ + "\t" + exemplarType
+ "\t" + exemplarSet.strings().size()
+ "\t" + (remaining.size() + forTranslit.size())
+ "\t" + remaining
+ "\t" + forTranslit
+ "\t" + indexSet
+ "\t" + colAndEx
- + "\t" + redundants
+ + "\t" + redundants
+ "\t" + colExemplars.size()
);
}
@@ -149,7 +149,7 @@
}
static final Normalizer2 nfkd = Normalizer2.getNFKDInstance();
- static final Set<String> CAN_BE_COMPOSED;
+ static final Set<String> CAN_BE_COMPOSED;
static {
Set<String> _toComposed = new TreeSet<>();
@@ -175,10 +175,10 @@
.build();
private static boolean isForTranslit(String locale, String s) {
boolean result = CAN_BE_COMPOSED.contains(nfkd.normalize(s));
- if (result && (NUKTA.containsSome(s)
+ if (result && (NUKTA.containsSome(s)
|| TRANSLIT_CLUSTERS.containsEntry(locale, s))) {
return true;
- };
+ }
return false;
}
}
diff --git a/tools/java/org/unicode/cldr/tool/ListUnits.java b/tools/java/org/unicode/cldr/tool/ListUnits.java
index 97406d1..8baea75 100644
--- a/tools/java/org/unicode/cldr/tool/ListUnits.java
+++ b/tools/java/org/unicode/cldr/tool/ListUnits.java
@@ -220,6 +220,7 @@
final String path;
final String value;
+ @Override
public String toString() {
return "locale=en"
+ " ; action=add"
@@ -229,7 +230,7 @@
}
private static Set<String> getUnits(CLDRFile cldrFile, Task task, Map<String, Data> extra) {
- Set<String> seen = new TreeSet<String>();
+ Set<String> seen = new TreeSet<>();
for (String path : cldrFile) {
if (!path.contains("/unit")) {
continue;
diff --git a/tools/java/org/unicode/cldr/tool/LocaleReplacements.java b/tools/java/org/unicode/cldr/tool/LocaleReplacements.java
index 958d2a1..af28516 100644
--- a/tools/java/org/unicode/cldr/tool/LocaleReplacements.java
+++ b/tools/java/org/unicode/cldr/tool/LocaleReplacements.java
@@ -20,7 +20,7 @@
import org.unicode.cldr.util.StandardCodes;
import org.unicode.cldr.util.SupplementalDataInfo;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -32,8 +32,8 @@
/**
* eg language, eng, <overlong,en>
*/
- static Map<String, Map<String, Row.R2<Set<String>, String>>> type2item2replacementAndReason = new HashMap<String, Map<String, Row.R2<Set<String>, String>>>();
- static Map<String, Relation<String, Row.R2<String, Set<String>>>> type2reason2itemAndreplacement = new TreeMap<String, Relation<String, Row.R2<String, Set<String>>>>();
+ static Map<String, Map<String, Row.R2<Set<String>, String>>> type2item2replacementAndReason = new HashMap<>();
+ static Map<String, Relation<String, Row.R2<String, Set<String>>>> type2reason2itemAndreplacement = new TreeMap<>();
static Relation<String, String> fixed = Relation.of(new TreeMap<String, Set<String>>(), LinkedHashSet.class);
public String get(String old, Output<String> reason) {
@@ -107,7 +107,7 @@
R2<Set<String>, String> replacementAndReason = entry2.getValue();
Set<String> replacements = replacementAndReason.get0();
//String reason = replacementAndReason.get1();
- Set<String> newReplacements = new LinkedHashSet<String>(replacements.size());
+ Set<String> newReplacements = new LinkedHashSet<>(replacements.size());
boolean gotChange = false;
for (String oldRep : replacements) {
R2<Set<String>, String> newRepAndReason = item2replacementAndReason.get(oldRep);
@@ -169,7 +169,7 @@
if (key == null) {
return;
}
- if (type.equals("grandfathered") || type.equals("redundant")) {
+ if (type.equals("legacy") || type.equals("redundant")) {
type = "language";
}
@@ -181,7 +181,7 @@
Map<String, R2<Set<String>, String>> item2replacementAndReason = type2item2replacementAndReason.get(type);
if (item2replacementAndReason == null) {
- type2item2replacementAndReason.put(type, item2replacementAndReason = new HashMap<String, R2<Set<String>, String>>());
+ type2item2replacementAndReason.put(type, item2replacementAndReason = new HashMap<>());
}
R2<Set<String>, String> oldReplacementAndReason = item2replacementAndReason.get(key);
@@ -197,7 +197,7 @@
return;
}
}
- Set<String> list = new LinkedHashSet<String>(1);
+ Set<String> list = new LinkedHashSet<>(1);
if (!preferredValue.isEmpty()) {
list.add(preferredValue);
}
@@ -208,8 +208,8 @@
Map<String, Map<String, R2<List<String>, String>>> localeAliasInfo = SupplementalDataInfo.getInstance()
.getLocaleAliasInfo();
- Set<String> newStuff = new TreeSet<String>();
- Set<String> oldStuff = new TreeSet<String>();
+ Set<String> newStuff = new TreeSet<>();
+ Set<String> oldStuff = new TreeSet<>();
for (Entry<String, Relation<String, R2<String, Set<String>>>> entry : type2reason2itemAndreplacement.entrySet()) {
String type = entry.getKey();
for (Entry<String, R2<String, Set<String>>> entry2 : entry.getValue().entrySet()) {
@@ -218,7 +218,7 @@
String key = replacementAndReason.get0();
Set<String> replacements = replacementAndReason.get1();
final String message = type + "\t" + reason + "\t" + key + "\t"
- + CollectionUtilities.join(replacements, " ");
+ + Joiner.on(" ").join(replacements);
// System.out.println(message);
newStuff.add(message);
}
@@ -235,13 +235,13 @@
List<String> replacements = replacementAndReason.get0();
String reason = replacementAndReason.get1();
oldStuff.add(type + "\t" + reason + "\t" + item
- + "\t" + (replacements == null ? "" : CollectionUtilities.join(replacements, " ")));
+ + "\t" + (replacements == null ? "" : Joiner.on(" ").join(replacements)));
}
}
- Set<Row.R2<String, String>> merged = new TreeSet<Row.R2<String, String>>();
+ Set<Row.R2<String, String>> merged = new TreeSet<>();
- Set<String> oldNotNew = Builder.with(new TreeSet<String>(oldStuff)).removeAll(newStuff).get();
- Set<String> newNotOld = Builder.with(new TreeSet<String>(newStuff)).removeAll(oldStuff).get();
+ Set<String> oldNotNew = Builder.with(new TreeSet<>(oldStuff)).removeAll(newStuff).get();
+ Set<String> newNotOld = Builder.with(new TreeSet<>(newStuff)).removeAll(oldStuff).get();
//Set<String> shared = Builder.with(new TreeSet<String>(oldStuff)).retainAll(newStuff).get();
// for (String s : shared) {
// merged.add(Row.of(s,"\tSAME"));
diff --git a/tools/java/org/unicode/cldr/tool/MakeAnnotationHistogram.java b/tools/java/org/unicode/cldr/tool/MakeAnnotationHistogram.java
index a6f22b5..49eb02b 100644
--- a/tools/java/org/unicode/cldr/tool/MakeAnnotationHistogram.java
+++ b/tools/java/org/unicode/cldr/tool/MakeAnnotationHistogram.java
@@ -16,7 +16,7 @@
import com.ibm.icu.util.ULocale;
public class MakeAnnotationHistogram {
- private static final Integer ZERO = (Integer) 0;
+ private static final Integer ZERO = 0;
public static void main(String[] args) {
AnnotationSet english = Annotations.getDataSet("en");
diff --git a/tools/java/org/unicode/cldr/tool/MakeTransliterator.java b/tools/java/org/unicode/cldr/tool/MakeTransliterator.java
index 4302912..4c7c9d0 100644
--- a/tools/java/org/unicode/cldr/tool/MakeTransliterator.java
+++ b/tools/java/org/unicode/cldr/tool/MakeTransliterator.java
@@ -250,7 +250,7 @@
Transliterator base = Transliterator.createFromRules("foo", coreRules, Transliterator.FORWARD);
// build up the transliterator one length at a time.
- List<String> newRules = new ArrayList<String>();
+ List<String> newRules = new ArrayList<>();
StringBuilder buffer = new StringBuilder();
int lastSourceLength = 1;
@@ -436,7 +436,7 @@
sourceCharacters.addAll(source);
targetCharacters.addAll(target);
- store.put(source, new Pair<String, Long>(target, frequency));
+ store.put(source, new Pair<>(target, frequency));
totalFrequency += frequency;
}
@@ -606,6 +606,7 @@
*/
static Comparator MyComparator = new Comparator() {
+ @Override
public int compare(Object a, Object b) {
String as = (String) a;
String bs = (String) b;
@@ -681,7 +682,7 @@
private static Transliterator coreBase;
public static Map<String, String> getOverrides() throws IOException {
- Map<String, String> result = new TreeMap<String, String>();
+ Map<String, String> result = new TreeMap<>();
BufferedReader br = FileUtilities.openUTF8Reader(cldrDataDir, "internal_overrides.txt");
try {
int counter = 0;
diff --git a/tools/java/org/unicode/cldr/tool/MatchStrings.java b/tools/java/org/unicode/cldr/tool/MatchStrings.java
index 8186384..c1fc1df 100644
--- a/tools/java/org/unicode/cldr/tool/MatchStrings.java
+++ b/tools/java/org/unicode/cldr/tool/MatchStrings.java
@@ -33,6 +33,7 @@
this.fixedIpa = fixedIpa.equals(ipa) ? ipa : fixedIpa; // make ==
}
+ @Override
public String toString() {
return "{" + english + "/" + ipa + (fixedIpa == ipa ? "" : "/" + fixedIpa) + "}";
}
@@ -85,7 +86,7 @@
String ipa;
List<Info> output;
int highWater = 0;
- List<Info> highWaterList = new ArrayList<Info>();
+ List<Info> highWaterList = new ArrayList<>();
private int longestEnglish;
private int longestIpa;
@@ -202,7 +203,7 @@
return -1;
}
- List<Info> current = new ArrayList<Info>();
+ List<Info> current = new ArrayList<>();
/**
* Fix the IPA in a string
diff --git a/tools/java/org/unicode/cldr/tool/MinimizeRegex.java b/tools/java/org/unicode/cldr/tool/MinimizeRegex.java
index 179a9df..da98d7f 100644
--- a/tools/java/org/unicode/cldr/tool/MinimizeRegex.java
+++ b/tools/java/org/unicode/cldr/tool/MinimizeRegex.java
@@ -9,9 +9,9 @@
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import com.google.common.base.Joiner;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.Output;
@@ -35,27 +35,27 @@
//defaultArg = "aa|ace|ad[ay]|ain|al[et]|anp?|arp|ast|av|awa|ay|ma[dgik]|mdf|men|mh|mi[cn]|mni|mos|mu[ls]|mwl|myv";
String regexString = args.length < 1 ? defaultArg : args[0];
UnicodeSet set = new UnicodeSet(args.length < 2 ? "[:ascii:]" : args[1]);
-
+
System.out.println(defaultArg + "\n");
Output<Set<String>> flattenedOut = new Output<>();
String recompressed = compressWith(regexString, set, flattenedOut);
- System.out.println(CollectionUtilities.join(flattenedOut.value,"|") + "\n");
+ System.out.println(Joiner.on("|").join(flattenedOut.value) + "\n");
System.out.println(recompressed + "\n");
}
public static String compressWith(String regexString, UnicodeSet set) {
return compressWith(regexString, set, null);
}
-
+
public static String simplePattern(Collection<String> strings) {
TreeSet<String> temp = new TreeSet<>(LENGTH_FIRST_COMPARE);
temp.addAll(strings);
- return CollectionUtilities.join(temp,"|");
+ return Joiner.on("|").join(temp);
}
-
+
public static String compressWith(String regexString, UnicodeSet set, Output<Set<String>> flattenedOut) {
Set<String> flattened = flatten(Pattern.compile(regexString), "", set);
- String regexString2 = CollectionUtilities.join(flattened,"|");
+ String regexString2 = Joiner.on("|").join(flattened);
Set<String> flattened2 = flatten(Pattern.compile(regexString2), "", set);
if (!flattened2.equals(flattened)) {
throw new IllegalArgumentException("Failed to compress: " + regexString + " using " + set + ", got " + regexString2);
@@ -135,11 +135,11 @@
}
switch (strings.size()) {
case 0: throw new IllegalArgumentException();
- case 1:
+ case 1:
isSingle.value = true;
return strings.iterator().next() + (hasEmpty ? "?" : "");
default:
- String result = CollectionUtilities.join(strings, "|");
+ String result = Joiner.on("|").join(strings);
if (hasEmpty) {
isSingle.value = true;
return '(' + result + ")?";
@@ -152,7 +152,7 @@
public static TreeSet<String> flatten(Pattern pattern, String prefix, UnicodeSet set) {
return flatten(pattern.matcher(""), prefix, set, new TreeSet<>(LENGTH_FIRST_COMPARE));
}
-
+
private static TreeSet<String> flatten(Matcher matcher, String prefix, UnicodeSet set, TreeSet<String> results) {
for (String s : set) {
String trial = prefix + s;
diff --git a/tools/java/org/unicode/cldr/tool/Misc.java b/tools/java/org/unicode/cldr/tool/Misc.java
index a2486ac..fb2f81d 100644
--- a/tools/java/org/unicode/cldr/tool/Misc.java
+++ b/tools/java/org/unicode/cldr/tool/Misc.java
@@ -143,7 +143,7 @@
english = cldrFactory.make("en", false);
resolvedRoot = cldrFactory.make("root", true);
if (options[MATCH].value.equals("group1")) options[MATCH].value = "(en|fr|de|it|es|pt|ja|ko|zh)";
- Set<String> languages = new TreeSet<String>(cldrFactory.getAvailableLanguages());
+ Set<String> languages = new TreeSet<>(cldrFactory.getAvailableLanguages());
// new Utility.MatcherFilter(options[MATCH].value).retainAll(languages);
// new Utility.MatcherFilter("(sh|zh_Hans|sr_Cyrl)").removeAll(languages);
@@ -272,7 +272,7 @@
// ICU info: http://oss.software.ibm.com/cvs/icu/~checkout~/icu/source/common/putil.c
// search for "Mapping between Windows zone IDs"
- static Set<String> priorities = new TreeSet<String>(Arrays.asList(new String[] { "en", "zh_Hans",
+ static Set<String> priorities = new TreeSet<>(Arrays.asList(new String[] { "en", "zh_Hans",
"zh_Hant", "da", "nl", "fi", "fr", "de", "it",
"ja", "ko", "nb", "pt_BR", "ru", "es", "sv", "ar", "bg", "ca",
"hr", "cs", "et", "el", "he", "hi", "hu", "is", "id", "lv", "lt",
@@ -283,7 +283,7 @@
private static void printAllZoneLocalizations() throws IOException {
StandardCodes sc = StandardCodes.make();
Set<String> zones = sc.getAvailableCodes("tzid");
- Map<Integer, Map<String, Map<String, String>>> offset_zone_locale_name = new TreeMap<Integer, Map<String, Map<String, String>>>();
+ Map<Integer, Map<String, Map<String, String>>> offset_zone_locale_name = new TreeMap<>();
for (Iterator<String> it2 = priorities.iterator(); it2.hasNext();) {
String locale = it2.next();
System.out.println(locale);
@@ -301,10 +301,10 @@
Map<String, Map<String, String>> zone_locale_name = offset_zone_locale_name.get(standardOffset);
if (zone_locale_name == null)
- offset_zone_locale_name.put(standardOffset, zone_locale_name = new TreeMap<String, Map<String, String>>());
+ offset_zone_locale_name.put(standardOffset, zone_locale_name = new TreeMap<>());
Map<String, String> locale_name = zone_locale_name.get(zone);
- if (locale_name == null) zone_locale_name.put(zone, locale_name = new TreeMap<String, String>());
+ if (locale_name == null) zone_locale_name.put(zone, locale_name = new TreeMap<>());
locale_name.put(locale, fullName);
}
@@ -400,7 +400,7 @@
* @throws IOException
*/
private static void printCurrentTimezoneLocalizations(Set<String> languages) throws IOException {
- Set<String> rtlLanguages = new TreeSet<String>();
+ Set<String> rtlLanguages = new TreeSet<>();
for (Iterator<String> it = languages.iterator(); it.hasNext();) {
String language = it.next();
CLDRFile desiredLocaleFile = cldrFactory.make(language, true);
@@ -441,15 +441,15 @@
StandardCodes sc = StandardCodes.make();
Map<String, String> zone_countries = sc.getZoneToCounty();
Map<String, String> old_new = sc.getZoneLinkold_new();
- Map<String, Set<String>> new_old = new TreeMap<String, Set<String>>(col);
- Map<String, Set<String>> country_zones = new TreeMap<String, Set<String>>(col);
+ Map<String, Set<String>> new_old = new TreeMap<>(col);
+ Map<String, Set<String>> country_zones = new TreeMap<>(col);
for (Iterator<String> it = zone_countries.keySet().iterator(); it.hasNext();) {
String zone = it.next();
new_old.put(zone, new TreeSet<String>(col));
String country = zone_countries.get(zone);
String name = english.getName("territory", country) + " (" + country + ")";
Set<String> oldSet = country_zones.get(name);
- if (oldSet == null) country_zones.put(name, oldSet = new TreeSet<String>(col));
+ if (oldSet == null) country_zones.put(name, oldSet = new TreeSet<>(col));
oldSet.add(zone);
}
for (Iterator<String> it = old_new.keySet().iterator(); it.hasNext();) {
@@ -632,12 +632,12 @@
*/
RuleBasedCollator col = (RuleBasedCollator) Collator.getInstance(new ULocale(locale));
col.setNumericCollation(true);
- Set<String> orderedAliases = new TreeSet<String>(col);
+ Set<String> orderedAliases = new TreeSet<>(col);
Map<String, String> zone_countries = StandardCodes.make().getZoneToCounty();
//Map<String, Set<String>> countries_zoneSet = StandardCodes.make().getCountryToZoneSet();
- Map<String, String> reordered = new TreeMap<String, String>(col);
+ Map<String, String> reordered = new TreeMap<>(col);
CLDRFile desiredLocaleFile = cldrFactory.make(locale, true);
for (Iterator<String> it = zone_countries.keySet().iterator(); it.hasNext();) {
@@ -775,7 +775,7 @@
Set<String> modernIDs = sc.getZoneData().keySet();
System.out.println();
System.out.println("Zones without countries");
- TreeSet<String> temp = new TreeSet<String>(m2.keySet());
+ TreeSet<String> temp = new TreeSet<>(m2.keySet());
temp.removeAll(modernIDs);
System.out.println(temp);
@@ -821,11 +821,11 @@
// Map rule_abbreviations = getAbbreviations(m);
Map<String, List<RuleLine>> ruleID_Rules = sc.getZoneRuleID_rules();
- Map<String, Set<String>> abb_zones = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> abb_zones = new TreeMap<>();
m2 = sc.getZone_rules();
for (Iterator<String> it = m2.keySet().iterator(); it.hasNext();) {
String key = it.next();
- Set<String> abbreviations = new TreeSet<String>();
+ Set<String> abbreviations = new TreeSet<>();
// rule_abbreviations.put(key, abbreviations);
ZoneLine lastZoneLine = null;
@@ -868,7 +868,7 @@
continue;
}
Set<String> zones = abb_zones.get(abb);
- if (zones == null) abb_zones.put(abb, zones = new TreeSet<String>());
+ if (zones == null) abb_zones.put(abb, zones = new TreeSet<>());
zones.add(key);
}
System.out.println(key + " => " + XPathParts.NEWLINE + "\t"
@@ -901,7 +901,7 @@
}
private static Set<String> getAbbreviations(Map<String, List<RuleLine>> rules, ZoneLine lastZoneLine, ZoneLine zoneLine) {
- Set<String> result = new TreeSet<String>();
+ Set<String> result = new TreeSet<>();
List<RuleLine> ruleList = rules.get(zoneLine.rulesSave);
for (Iterator<RuleLine> it2 = ruleList.iterator(); it2.hasNext();) {
RuleLine ruleLine = it2.next();
@@ -934,14 +934,14 @@
Set<String> territories = sc.getAvailableCodes("territory");
Map<String, List<String>> zoneData = sc.getZoneData();
- Set<String> s = new TreeSet<String>(sc.getTZIDComparator());
+ Set<String> s = new TreeSet<>(sc.getTZIDComparator());
s.addAll(sc.getZoneData().keySet());
int counter = 0;
for (Iterator<String> it = s.iterator(); it.hasNext();) {
String key = it.next();
System.out.println(++counter + "\t" + key + "\t" + zoneData.get(key));
}
- Set<String> missing2 = new TreeSet<String>(sc.getZoneData().keySet());
+ Set<String> missing2 = new TreeSet<>(sc.getZoneData().keySet());
missing2.removeAll(sc.getZoneToCounty().keySet());
System.out.println(missing2);
missing2.clear();
@@ -950,8 +950,8 @@
System.out.println(missing2);
if (true) return;
- Map<String, Map<String, String>> country_city_data = new TreeMap<String, Map<String, String>>();
- Map<String, String> territoryName_code = new HashMap<String, String>();
+ Map<String, Map<String, String>> country_city_data = new TreeMap<>();
+ Map<String, String> territoryName_code = new HashMap<>();
Map<String, String> zone_to_country = sc.getZoneToCounty();
for (Iterator<String> it = territories.iterator(); it.hasNext();) {
String code = it.next();
@@ -963,7 +963,7 @@
"NFD; [:m:]Remove; NFC");
BufferedReader br = FileUtilities.openUTF8Reader("c:/data/", "cities.txt");
counter = 0;
- Set<String> missing = new TreeSet<String>();
+ Set<String> missing = new TreeSet<>();
while (true) {
String line = br.readLine();
if (line == null) break;
@@ -980,7 +980,7 @@
if (code == null) missing.add(country);
Map<String, String> city_data = country_city_data.get(code);
if (city_data == null) {
- city_data = new TreeMap<String, String>();
+ city_data = new TreeMap<>();
country_city_data.put(code, city_data);
}
city_data.put(place2,
@@ -1041,7 +1041,7 @@
}
// territories
- Map<String, Collection<String>> groups = new TreeMap<String, Collection<String>>();
+ Map<String, Collection<String>> groups = new TreeMap<>();
for (Iterator<String> it = supp.iterator(); it.hasNext();) {
String path = it.next();
XPathParts parts = XPathParts.getFrozenInstance(supp.getFullXPath(path));
@@ -1053,11 +1053,11 @@
.splitList(attributes.get("contains"), ' ', true, new ArrayList<String>());
groups.put(type, contents);
}
- Set<String> seen = new TreeSet<String>();
+ Set<String> seen = new TreeSet<>();
printTimezonesToLocalize(log, desiredLocaleFile, groups, seen, col, false, english);
StandardCodes sc = StandardCodes.make();
Set<String> codes = sc.getAvailableCodes("territory");
- Set<String> missing = new TreeSet<String>(codes);
+ Set<String> missing = new TreeSet<>(codes);
missing.removeAll(seen);
if (log != null) {
log.close();
@@ -1074,8 +1074,8 @@
CLDRFile english) throws IOException {
@SuppressWarnings("unchecked")
Set<String>[] missing = new Set[2];
- missing[0] = new TreeSet<String>();
- missing[1] = new TreeSet<String>(StandardCodes.make().getTZIDComparator());
+ missing[0] = new TreeSet<>();
+ missing[1] = new TreeSet<>(StandardCodes.make().getTZIDComparator());
printWorldTimezoneCategorization(log, localization, groups, "001", 0, seen, col, showCode, zones_countrySet(),
missing);
if (missing[0].size() == 0 && missing[1].size() == 0) return;
@@ -1152,7 +1152,7 @@
}
if (log != null) log.println(">");
- Map<String, String> reorder = new TreeMap<String, String>(col);
+ Map<String, String> reorder = new TreeMap<>(col);
for (Iterator<String> it = s.iterator(); it.hasNext();) {
key = it.next();
String value = getName(localization, key, missing);
@@ -1207,14 +1207,14 @@
static Map<String, Set<String>> zones_countrySet() {
Map<String, List<String>> m = StandardCodes.make().getZoneData();
- Map<String, Set<String>> result = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> result = new TreeMap<>();
for (Iterator<String> it = m.keySet().iterator(); it.hasNext();) {
String tzid = it.next();
List<String> list = m.get(tzid);
String country = list.get(2);
Set<String> zones = result.get(country);
if (zones == null) {
- zones = new TreeSet<String>();
+ zones = new TreeSet<>();
result.put(country, zones);
}
zones.add(tzid);
@@ -1239,7 +1239,7 @@
Factory cldrFactory = Factory.make(options[SOURCEDIR].value + "main\\", ".*");
// CLDRKey.main(new String[]{"-mde.*"});
Set<String> locales = cldrFactory.getAvailable();
- Set<String> cldr = new TreeSet<String>();
+ Set<String> cldr = new TreeSet<>();
LanguageTagParser parser = new LanguageTagParser();
for (Iterator<String> it = locales.iterator(); it.hasNext();) {
// if doesn't have exactly one _, skip
@@ -1250,7 +1250,7 @@
cldr.add(locale.replace('_', '-'));
}
- Set<String> tex = new TreeSet<String>();
+ Set<String> tex = new TreeSet<>();
while (true) {
String line = in.readLine();
if (line == null) break;
@@ -1259,10 +1259,10 @@
int p = line.indexOf(' ');
tex.add(line.substring(0, p));
}
- Set<String> inCldrButNotTex = new TreeSet<String>(cldr);
+ Set<String> inCldrButNotTex = new TreeSet<>(cldr);
inCldrButNotTex.removeAll(tex);
System.out.println(" inCldrButNotTex " + inCldrButNotTex);
- Set<String> inTexButNotCLDR = new TreeSet<String>(tex);
+ Set<String> inTexButNotCLDR = new TreeSet<>(tex);
inTexButNotCLDR.removeAll(cldr);
System.out.println(" inTexButNotCLDR " + inTexButNotCLDR);
}
diff --git a/tools/java/org/unicode/cldr/tool/Option.java b/tools/java/org/unicode/cldr/tool/Option.java
index a1b8b6e..b749cce 100644
--- a/tools/java/org/unicode/cldr/tool/Option.java
+++ b/tools/java/org/unicode/cldr/tool/Option.java
@@ -10,7 +10,7 @@
import org.unicode.cldr.util.CLDRTool;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
/**
* Simpler mechanism for handling options, where everything can be defined in one place.
@@ -123,7 +123,7 @@
}
public Option(Enum<?> optionEnumValue, String argumentPattern, String defaultArgument, String helpText) {
- this(optionEnumValue, optionEnumValue.name(), (Character) (optionEnumValue.name().charAt(0)), Pattern.compile(argumentPattern), defaultArgument,
+ this(optionEnumValue, optionEnumValue.name(), (optionEnumValue.name().charAt(0)), Pattern.compile(argumentPattern), defaultArgument,
helpText);
}
@@ -162,7 +162,7 @@
} else if (match instanceof Class) {
try {
Enum[] valuesMethod = (Enum[]) ((Class) match).getMethod("values").invoke(null);
- return Pattern.compile(CollectionUtilities.join(valuesMethod, "|"));
+ return Pattern.compile(Joiner.on("|").join(valuesMethod));
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
@@ -172,6 +172,7 @@
static final String PAD = " ";
+ @Override
public String toString() {
return "-" + flag
+ " (" + tag + ")"
@@ -210,10 +211,10 @@
public static class Options implements Iterable<Option> {
private String mainMessage;
- final Map<String, Option> stringToValues = new LinkedHashMap<String, Option>();
- final Map<Enum<?>, Option> enumToValues = new LinkedHashMap<Enum<?>, Option>();
- final Map<Character, Option> charToValues = new LinkedHashMap<Character, Option>();
- final Set<String> results = new LinkedHashSet<String>();
+ final Map<String, Option> stringToValues = new LinkedHashMap<>();
+ final Map<Enum<?>, Option> enumToValues = new LinkedHashMap<>();
+ final Map<Character, Option> charToValues = new LinkedHashMap<>();
+ final Set<String> results = new LinkedHashSet<>();
{
add("help", null, "Provide the list of possible options");
}
diff --git a/tools/java/org/unicode/cldr/tool/PivotData.java b/tools/java/org/unicode/cldr/tool/PivotData.java
index eedbaa2..0922227 100644
--- a/tools/java/org/unicode/cldr/tool/PivotData.java
+++ b/tools/java/org/unicode/cldr/tool/PivotData.java
@@ -117,7 +117,7 @@
// find all the unique paths that I have, where the value or fullpath is different from the parent.
// AND the parent has the path
- Set<String> uniquePaths = new TreeSet<String>();
+ Set<String> uniquePaths = new TreeSet<>();
CLDRFile resolvedParent = factory.make(parentID, true);
if (resolvedParent.getFullXPath("//ldml/alias", true) != null) {
throw new IllegalArgumentException("File cannot be completely aliased: " + localeID);
diff --git a/tools/java/org/unicode/cldr/tool/PluralMinimalPairs.java b/tools/java/org/unicode/cldr/tool/PluralMinimalPairs.java
index 8022a7e..9142ec8 100644
--- a/tools/java/org/unicode/cldr/tool/PluralMinimalPairs.java
+++ b/tools/java/org/unicode/cldr/tool/PluralMinimalPairs.java
@@ -45,9 +45,12 @@
XPathParts parts = XPathParts.getFrozenInstance(path);
String sample = cldrFile.getStringValue(path);
String element = parts.getElement(-1);
- PluralType type = "pluralMinimalPairs".equals(element) ? PluralType.CARDINAL
- : "ordinalMinimalPairs".equals(element) ? PluralType.ORDINAL
- : null;
+ PluralType type;
+ switch(element) {
+ case "pluralMinimalPairs": type = PluralType.CARDINAL; break;
+ case "ordinalMinimalPairs": type = PluralType.ORDINAL; break;
+ default: continue; // skip grammar, case
+ }
PluralInfo.Count category = PluralInfo.Count.valueOf(
parts.getAttributeValue(-1, type == PluralType.CARDINAL ? "count" : "ordinal"));
if (category == null || type == null) {
diff --git a/tools/java/org/unicode/cldr/tool/PluralRulesFactory.java b/tools/java/org/unicode/cldr/tool/PluralRulesFactory.java
index e922cdf..7b72ba2 100644
--- a/tools/java/org/unicode/cldr/tool/PluralRulesFactory.java
+++ b/tools/java/org/unicode/cldr/tool/PluralRulesFactory.java
@@ -29,20 +29,21 @@
private final SupplementalDataInfo supplementalDataInfo;
+ @Override
public abstract boolean hasOverride(ULocale locale);
public enum Type {
NORMAL, ALTERNATE
- };
+ }
public static PluralRulesFactory getInstance(SupplementalDataInfo supplementalDataInfo) {
return getInstance(supplementalDataInfo, Type.NORMAL);
}
- private static ConcurrentHashMap<Pair<Type, String>, PluralRulesFactory> singletons = new ConcurrentHashMap<Pair<Type, String>, PluralRulesFactory>();
+ private static ConcurrentHashMap<Pair<Type, String>, PluralRulesFactory> singletons = new ConcurrentHashMap<>();
public static PluralRulesFactory getInstance(SupplementalDataInfo supplementalDataInfo, Type type) {
- Pair<Type, String> key = new Pair<Type, String>(type, supplementalDataInfo.getDirectory().getAbsolutePath());
+ Pair<Type, String> key = new Pair<>(type, supplementalDataInfo.getDirectory().getAbsolutePath());
PluralRulesFactory prf = singletons.get(key);
if (prf == null) {
switch (type) {
@@ -196,7 +197,7 @@
// XPathParts parts = XPathParts.getFrozenInstance(path);
// String sample = cldrFile.getStringValue(path);
// String element = parts.getElement(-1);
-// PluralType type = "pluralMinimalPairs".equals(element) ? PluralType.CARDINAL
+// PluralType type = "pluralMinimalPairs".equals(element) ? PluralType.CARDINAL
// : "ordinalMinimalPairs".equals(element) ? PluralType.ORDINAL
// : null;
// PluralInfo.Count category = PluralInfo.Count.valueOf(
@@ -219,7 +220,7 @@
<ordinalMinimalPairs ordinal="two">Take the {0}nd right.</ordinalMinimalPairs>
</minimalPairs>
</numbers>
-
+
*/
// }
@@ -291,7 +292,7 @@
}
// LOCALE_TO_SAMPLE_PATTERNS = Collections.unmodifiableMap(temp);
// OVERRIDES = Collections.unmodifiableMap(tempOverrides);
- EXTRA_SAMPLES = (Relation<ULocale, FixedDecimal>) tempSamples.freeze();
+ EXTRA_SAMPLES = tempSamples.freeze();
}
// static String[][] OLDRULES = {
diff --git a/tools/java/org/unicode/cldr/tool/ReadSql.java b/tools/java/org/unicode/cldr/tool/ReadSql.java
index 858d41a..ffe342b 100644
--- a/tools/java/org/unicode/cldr/tool/ReadSql.java
+++ b/tools/java/org/unicode/cldr/tool/ReadSql.java
@@ -206,7 +206,7 @@
static class Data {
final String key;
- final List<Items> dataItems = new ArrayList<Items>();
+ final List<Items> dataItems = new ArrayList<>();
static Map<String, Data> map = new TreeMap<>();
public Data(String key) {
diff --git a/tools/java/org/unicode/cldr/tool/ReadXMB.java b/tools/java/org/unicode/cldr/tool/ReadXMB.java
index 2f6d3a2..4b8202f 100644
--- a/tools/java/org/unicode/cldr/tool/ReadXMB.java
+++ b/tools/java/org/unicode/cldr/tool/ReadXMB.java
@@ -32,7 +32,7 @@
}
private static class CasingHandler extends XMLFileReader.SimpleHandler {
- public Map<String, String> info = new LinkedHashMap<String, String>();
+ public Map<String, String> info = new LinkedHashMap<>();
String path;
String id;
String value;
diff --git a/tools/java/org/unicode/cldr/tool/RegexModify.java b/tools/java/org/unicode/cldr/tool/RegexModify.java
index 3bb0df6..dc8d530 100644
--- a/tools/java/org/unicode/cldr/tool/RegexModify.java
+++ b/tools/java/org/unicode/cldr/tool/RegexModify.java
@@ -129,6 +129,7 @@
return count;
}
+ @Override
public String apply(String line) {
if (lineMatcher.reset(line).matches()) {
String oldLine = line;
diff --git a/tools/java/org/unicode/cldr/tool/RemoveEmptyCLDR.java b/tools/java/org/unicode/cldr/tool/RemoveEmptyCLDR.java
index 5756d47..dbbe23f 100644
--- a/tools/java/org/unicode/cldr/tool/RemoveEmptyCLDR.java
+++ b/tools/java/org/unicode/cldr/tool/RemoveEmptyCLDR.java
@@ -12,6 +12,7 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.Pair;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.XMLFileReader;
import com.google.common.collect.BiMap;
@@ -39,18 +40,18 @@
}
main: for (File f : dirFile.listFiles()) {
List<Pair<String, String>> data = new ArrayList<>();
- String canonicalPath = f.getCanonicalPath();
- if (!canonicalPath.endsWith(".xml") || canonicalPath.endsWith("root.xml")) {
+ String normalizedPath = PathUtilities.getNormalizedPathString(f);
+ if (!normalizedPath.endsWith(".xml") || normalizedPath.endsWith("root.xml")) {
continue;
}
String name = f.getName();
name = name.substring(0,name.length()-4); // remove .xml
- XMLFileReader.loadPathValues(canonicalPath, data, false);
+ XMLFileReader.loadPathValues(normalizedPath, data, false);
for (Pair<String, String> item : data) {
if (item.getFirst().contains("/identity")) {
continue;
}
- System.out.println(++counter + ") NOT-EMPTY: " + canonicalPath);
+ System.out.println(++counter + ") NOT-EMPTY: " + normalizedPath);
addNameAndParents(nonEmpty, name);
continue main;
}
@@ -66,7 +67,7 @@
continue;
}
File file = entry.getValue();
- System.out.println(++counter + ") Deleting: " + file.getCanonicalPath());
+ System.out.println(++counter + ") Deleting: " + PathUtilities.getNormalizedPathString(file));
if (!PREFLIGHT) {
file.delete();
}
diff --git a/tools/java/org/unicode/cldr/tool/RemoveEmptyCldrFiles.java b/tools/java/org/unicode/cldr/tool/RemoveEmptyCldrFiles.java
index 7e25b74..6dbc239 100644
--- a/tools/java/org/unicode/cldr/tool/RemoveEmptyCldrFiles.java
+++ b/tools/java/org/unicode/cldr/tool/RemoveEmptyCldrFiles.java
@@ -9,7 +9,7 @@
public class RemoveEmptyCldrFiles {
public static void main(String[] args) {
- File[] paths = {
+ File[] paths = {
new File(CLDRPaths.ANNOTATIONS_DIRECTORY)
};
Factory factory = SimpleFactory.make(paths, ".*");
diff --git a/tools/java/org/unicode/cldr/tool/ScriptPopulations.java b/tools/java/org/unicode/cldr/tool/ScriptPopulations.java
index 4e20f31..d721018 100644
--- a/tools/java/org/unicode/cldr/tool/ScriptPopulations.java
+++ b/tools/java/org/unicode/cldr/tool/ScriptPopulations.java
@@ -23,9 +23,9 @@
// iterate through the language populations, picking up the script
SupplementalDataInfo info = supplementalDataInfo;
LanguageTagParser languageTagParser = new LanguageTagParser();
- Counter<String> langScriptLitPop = new Counter<String>();
- Counter<String> scriptLitPop = new Counter<String>();
- Map<String, OfficialStatus> bestStatus = new HashMap<String, OfficialStatus>();
+ Counter<String> langScriptLitPop = new Counter<>();
+ Counter<String> scriptLitPop = new Counter<>();
+ Map<String, OfficialStatus> bestStatus = new HashMap<>();
for (String territory : info.getTerritoriesWithPopulationData()) {
for (String language : info.getLanguagesForTerritoryWithPopulationData(territory)) {
diff --git a/tools/java/org/unicode/cldr/tool/SearchCLDR.java b/tools/java/org/unicode/cldr/tool/SearchCLDR.java
index b771fa0..56b4178 100644
--- a/tools/java/org/unicode/cldr/tool/SearchCLDR.java
+++ b/tools/java/org/unicode/cldr/tool/SearchCLDR.java
@@ -29,12 +29,12 @@
import org.unicode.cldr.util.Level;
import org.unicode.cldr.util.PathHeader;
import org.unicode.cldr.util.PathHeader.BaseUrl;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.StandardCodes;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.util.ICUUncheckedIOException;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.VersionInfo;
@@ -107,13 +107,12 @@
public static void main(String[] args) {
myOptions.parse(args, true);
- // System.out.println("Arguments: " + CollectionUtilities.join(args, " "));
long startTime = System.currentTimeMillis();
String sourceDirectory = myOptions.get("source").getValue();
- Output<Boolean> exclude = new Output<Boolean>();
+ Output<Boolean> exclude = new Output<>();
fileMatcher = myOptions.get("file").getValue();
pathMatcher = getMatcher(myOptions.get("path").getValue(), exclude);
@@ -144,9 +143,9 @@
new File(CLDRPaths.MAIN_DIRECTORY),
new File(sourceDirectory) };
- Factory cldrFactory = SimpleFactory.make(paths, fileMatcher);
+ Factory cldrFactory = SimpleFactory.make(paths, fileMatcher);
- Set<String> locales = new TreeSet<String>(cldrFactory.getAvailable());
+ Set<String> locales = new TreeSet<>(cldrFactory.getAvailable());
String rawVersion = myOptions.get("diff").getValue();
@@ -161,7 +160,7 @@
String errorMatcherText = myOptions.get("Error").getValue();
subtype = null;
- checkCldr = null;
+ checkCldr = null;
if (errorMatcherText != null) {
int errorSepPos = errorMatcherText.indexOf(':');
if (errorSepPos >= 0) {
@@ -203,8 +202,8 @@
Level organizationLevel = organization == null ? null
: StandardCodes.make().getLocaleCoverageLevel(organization, locale);
- CLDRFile file = (CLDRFile) cldrFactory.make(locale, resolved);
- CLDRFile resolvedFile = resolved == true ? file
+ CLDRFile file = cldrFactory.make(locale, resolved);
+ CLDRFile resolvedFile = resolved == true ? file
: (CLDRFile) cldrFactory.make(locale, true);
CLDRFile diffFile = null;
@@ -224,7 +223,7 @@
}
}
- Counter<Level> levelCounter = new Counter<Level>();
+ Counter<Level> levelCounter = new Counter<>();
//CLDRFile parent = null;
boolean headerShown = false;
@@ -234,7 +233,7 @@
level = CoverageLevel2.getInstance(locale);
Status status = new Status();
- Set<PathHeader> sorted = new TreeSet<PathHeader>();
+ Set<PathHeader> sorted = new TreeSet<>();
for (String path : file.fullIterable()) {
if (locale.equals("eo") && path.contains("type=\"MK\"")) {
int debug = 0;
@@ -300,7 +299,7 @@
for (CheckStatus item : result) {
if (item.getSubtype() == subtype) {
++count;
- };
+ }
}
if (count == 0) {
continue;
@@ -331,7 +330,7 @@
: file.getSourceLocaleID(path, status)
+ (path.equals(status.pathWhereFound) ? "\t≣" : "\t" + status);
if (checkCldr != null) {
- SearchXml.show(ConfigOption.delete, locale, file.getDistinguishingXPath(fullPath, null), value, null, null, null);
+ SearchXml.show(ConfigOption.delete, "", locale, CLDRFile.getDistinguishingXPath(fullPath, null), value, null, null, null);
} else {
showLine(showPath, showParent, showEnglish, resolved, locale,
path, fullPath, value,
@@ -351,7 +350,7 @@
}
}
if (localeCount != 0) {
- System.out.println("# " + locale
+ System.out.println("# " + locale
+ " Total " + localeCount + " found");
}
System.out.flush();
@@ -366,16 +365,12 @@
File[] newDirs = new File[sourceDirs.length];
int item = 0;
for (File s : sourceDirs) {
- try {
- String path = s.getCanonicalPath();
- int baseLoc = path.lastIndexOf("/cldr/");
- if (baseLoc < 0) {
- throw new ICUUncheckedIOException("source doesn't contain /cldr/");
- }
- newDirs[item++] = new File(base, path.substring(baseLoc + 5));
- } catch (IOException e) {
- throw new ICUUncheckedIOException(e);
+ String path = PathUtilities.getNormalizedPathString(s);
+ int baseLoc = path.lastIndexOf("/cldr/");
+ if (baseLoc < 0) {
+ throw new ICUUncheckedIOException("source doesn't contain /cldr/");
}
+ newDirs[item++] = new File(base, path.substring(baseLoc + 5));
}
return newDirs;
}
@@ -396,10 +391,10 @@
}
}
System.out.println("# "
- + locale
+ + locale
+ "\t⟪" + value + "⟫"
+ (showEnglish ? "\t⟪" + englishValue + "⟫" : "")
- + (!showParent ? "" : CollectionUtilities.equals(value, parentValue) ? "\t≣" : "\t⟪" + parentValue + "⟫")
+ + (!showParent ? "" : Objects.equals(value, parentValue) ? "\t≣" : "\t⟪" + parentValue + "⟫")
+ "\t" + shortPath
+ (showPath ? "\t" + fullPath : "")
+ (resolved ? "\t" + resolvedSource : "")
@@ -438,4 +433,4 @@
}
return ImmutableSet.copyOf(result);
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/SearchXml.java b/tools/java/org/unicode/cldr/tool/SearchXml.java
index ef21352..300d9e5 100644
--- a/tools/java/org/unicode/cldr/tool/SearchXml.java
+++ b/tools/java/org/unicode/cldr/tool/SearchXml.java
@@ -18,6 +18,7 @@
import org.unicode.cldr.util.PathHeader;
import org.unicode.cldr.util.PathHeader.BaseUrl;
import org.unicode.cldr.util.PathStarrer;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.PatternCache;
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.XMLFileReader;
@@ -53,15 +54,15 @@
private static boolean fileExclude = false;
private static boolean unique = false;
private static boolean groups = false;
- private static Counter<String> uniqueData = new Counter<String>();
+ private static Counter<String> uniqueData = new Counter<>();
private static String valuePattern;
private static File comparisonDirectory;
private static boolean recursive;
-
+
private static Counter<String> kountRegexMatches;
private static Counter<String> starCounter;
- private static final Set<String> ERRORS = new LinkedHashSet<String>();
+ private static final Set<String> ERRORS = new LinkedHashSet<>();
private static final PathStarrer pathStarrer = new PathStarrer();
private static PathHeader.Factory PATH_HEADER_FACTORY = null;
@@ -92,7 +93,7 @@
System.out.println("#" + "Need Source Directory! ");
return;
}
- Output<Boolean> exclude = new Output<Boolean>();
+ Output<Boolean> exclude = new Output<>();
fileMatcher = getMatcher(myOptions.get("file").getValue(), exclude);
fileExclude = exclude.value;
@@ -106,7 +107,7 @@
valueExclude = exclude.value;
if (myOptions.get("Star").doesOccur()) {
- starCounter = new Counter<String>();
+ starCounter = new Counter<>();
}
if (pathMatcher != null && valueMatcher != null) {
@@ -124,7 +125,7 @@
groups = myOptions.get("groups").doesOccur();
countOnly = myOptions.get("count").doesOccur();
- kountRegexMatches = myOptions.get("kount").doesOccur() ? new Counter<String>() : null;
+ kountRegexMatches = myOptions.get("kount").doesOccur() ? new Counter<>() : null;
recursive = myOptions.get("recursive").doesOccur();
@@ -211,7 +212,7 @@
}
String fileName = file.getName();
- String canonicalFile = file.getCanonicalPath();
+ String canonicalFile = PathUtilities.getNormalizedPathString(file);
if (!fileName.endsWith(".xml")) {
continue;
@@ -254,7 +255,7 @@
ListHandler listHandler = new ListHandler();
XMLFileReader xfr = new XMLFileReader().setHandler(listHandler);
try {
- String fileName2 = directory.getCanonicalPath() + "/" + fileName;
+ String fileName2 = PathUtilities.getNormalizedPathString(directory) + "/" + fileName;
xfr.read(fileName2, XMLFileReader.CONTENT_HANDLER
| XMLFileReader.ERROR_HANDLER, false);
} catch (Exception e) {
@@ -271,6 +272,7 @@
public Relation<String, String> data = Relation.of(new LinkedHashMap<String, Set<String>>(),
LinkedHashSet.class);
+ @Override
public void handlePathValue(String path, String value) {
data.put(path, value);
}
@@ -319,7 +321,7 @@
CoverageLevel2 level = null;
String firstMessage;
String file;
- Counter<Level> levelCounter = new Counter<Level>();
+ Counter<Level> levelCounter = new Counter<>();
String canonicalFile = fileName;
firstMessage = "* " + canonicalFile;
file = canonicalFile;
@@ -341,7 +343,7 @@
System.out.println();
}
- Set<String> keys = new LinkedHashSet<String>(source.keySet());
+ Set<String> keys = new LinkedHashSet<>(source.keySet());
if (other != null) {
keys.addAll(other.keySet());
}
@@ -383,7 +385,7 @@
diffInfo.sameCount += values.size();
}
if (diff && showValues) {
- show(ConfigOption.add, file, null, null, path, values, otherValues);
+ show(ConfigOption.add, filePath, file, null, null, path, values, otherValues);
}
}
} else {
@@ -428,7 +430,7 @@
}
// http://st.unicode.org/cldr-apps/v#/en/Fields/59d8178ec2fe04ae
if (!groups && pathHeaderInfo.isEmpty()) {
- show(ConfigOption.add, file, null, null, path, Collections.singleton(value), null);
+ show(ConfigOption.add, filePath, file, null, null, path, Collections.singleton(value), null);
} else {
System.out.println("#?" +
(recursive ? filePath + "\t" : "")
@@ -452,31 +454,33 @@
}
}
- enum ConfigOption {delete, add, addNew, replace};
-
- public static void show(ConfigOption configOption,
- String localeOrFile,
- String match_path,
- String match_value,
- String new_path,
- Set<String> new_values,
+ enum ConfigOption {delete, add, addNew, replace}
+
+ public static void show(ConfigOption configOption,
+ String fileParent,
+ String localeOrFile,
+ String match_path,
+ String match_value,
+ String new_path,
+ Set<String> new_values,
Set<String> otherValues) {
// locale= sv ; action=delete; value= YER ; path= //ldml/numbers/currencies/currency[@type="YER"]/symbol ;
// locale=en ; action=delete ; path=/.*short.*/
// locale=en ; action=add ; new_path=//ldml/localeDisplayNames/territories/territory[@type="PS"][@alt="short"] ; new_value=Palestine
- // locale= af ; action=add ; new_path= //ldml/dates/fields/field[@type="second"]/relative[@type="0"] ; new_value= nou
+ // locale= af ; action=add ; new_path= //ldml/dates/fields/field[@type="second"]/relative[@type="0"] ; new_value= nou
int extensionPos = localeOrFile.lastIndexOf('.');
String fileWithoutSuffix = extensionPos >= 0 ? localeOrFile.substring(0, extensionPos) : localeOrFile;
- String values2 = new_values == null ? null
- : new_values.size() != 1 ? new_values.toString()
+ String values2 = new_values == null ? null
+ : new_values.size() != 1 ? new_values.toString()
: new_values.iterator().next();
-
- System.out.println("locale=" + fileWithoutSuffix
+
+ System.out.println(fileParent
+ + ";\tlocale=" + fileWithoutSuffix
+ ";\taction=" + configOption
+ (match_value == null ? "" : ";\tvalue=" + escape(match_value))
+ (match_path == null ? "" : ";\tpath=" + match_path)
@@ -517,4 +521,4 @@
// static class StarCounter {
// Map<String,Counter<String>> data = new HashMap();
// }
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/ShowChildren.java b/tools/java/org/unicode/cldr/tool/ShowChildren.java
index 4d15f2d..76ae61d 100644
--- a/tools/java/org/unicode/cldr/tool/ShowChildren.java
+++ b/tools/java/org/unicode/cldr/tool/ShowChildren.java
@@ -15,18 +15,17 @@
import org.unicode.cldr.util.LocaleIDParser;
import org.unicode.cldr.util.PrettyPath;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
public class ShowChildren {
public static void main(String[] args) {
- System.out.println("Arguments: " + CollectionUtilities.join(args, " "));
+ System.out.println("Arguments: " + String.join(" ", args));
long startTime = System.currentTimeMillis();
Factory cldrFactory = Factory.make(CLDRPaths.MAIN_DIRECTORY, ".*");
- Set<String> locales = new TreeSet<String>(cldrFactory.getAvailable());
+ Set<String> locales = new TreeSet<>(cldrFactory.getAvailable());
Relation<String, String> parent2children = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
LanguageTagParser ltp = new LanguageTagParser();
@@ -39,17 +38,17 @@
PrettyPath prettyPath = new PrettyPath();
final CLDRFile english = ToolConfig.getToolInstance().getEnglish();
- Counter<String> deviations = new Counter<String>();
+ Counter<String> deviations = new Counter<>();
for (Entry<String, Set<String>> entry : parent2children.keyValuesSet()) {
- Map<String, Relation<String, String>> path2value2locales = new TreeMap<String, Relation<String, String>>();
+ Map<String, Relation<String, String>> path2value2locales = new TreeMap<>();
String parent = entry.getKey();
String parentName = english.getName(parent);
- CLDRFile parentFile = (CLDRFile) cldrFactory.make(parent, true);
+ CLDRFile parentFile = cldrFactory.make(parent, true);
Set<String> children = entry.getValue();
for (String child : children) {
- CLDRFile file = (CLDRFile) cldrFactory.make(child, false);
+ CLDRFile file = cldrFactory.make(child, false);
for (String path : file) {
if (path.startsWith("//ldml/identity")
|| path.endsWith("/alias")
diff --git a/tools/java/org/unicode/cldr/tool/ShowData.java b/tools/java/org/unicode/cldr/tool/ShowData.java
index 943a7e2..3cebe52 100644
--- a/tools/java/org/unicode/cldr/tool/ShowData.java
+++ b/tools/java/org/unicode/cldr/tool/ShowData.java
@@ -38,8 +38,8 @@
import org.unicode.cldr.util.StringId;
import org.unicode.cldr.util.TransliteratorUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.dev.tool.UOption;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Collator;
@@ -123,10 +123,10 @@
// .make(sourceDir.replace("incoming/vetted/","common/") + "../collation/", ".*");
// ExtractCollationRules collationRules = new ExtractCollationRules();
- locales = new TreeSet<String>(cldrFactory.getAvailable());
+ locales = new TreeSet<>(cldrFactory.getAvailable());
new CldrUtility.MatcherFilter(options[MATCH].value).retainAll(locales);
// Set paths = new TreeSet();
- Set<PathHeader> prettySet = new TreeSet<PathHeader>();
+ Set<PathHeader> prettySet = new TreeSet<>();
CLDRFile.Status status = new CLDRFile.Status();
LocaleIDParser localeIDParser = new LocaleIDParser();
@@ -134,7 +134,7 @@
//Map nonDistinguishingAttributes = new LinkedHashMap();
//CLDRFile parent = null;
- Map<PathHeader, Relation<String, String>> pathHeaderToValuesToLocale = new TreeMap<PathHeader, Relation<String, String>>();
+ Map<PathHeader, Relation<String, String>> pathHeaderToValuesToLocale = new TreeMap<>();
Set<String> defaultContents = testInfo.getSupplementalDataInfo().getDefaultContentLocales();
@@ -166,7 +166,7 @@
for (Entry<String, Set<String>> group : parentToChildren.keyValuesSet()) {
String locale = group.getKey();
Set<String> children = group.getValue();
- Map<String, CLDRFile> sublocales = new TreeMap<String, CLDRFile>();
+ Map<String, CLDRFile> sublocales = new TreeMap<>();
boolean doResolved = localeIDParser.set(locale).getRegion().length() == 0;
String languageSubtag = localeIDParser.getLanguage();
@@ -178,13 +178,13 @@
// get all of the paths
Set<String> allPaths = new HashSet<>();
- CollectionUtilities.addAll(file.iterator(), allPaths);
+ file.forEach(allPaths::add);
if (!locale.equals("root")) {
for (String childLocale : children) {
CLDRFile childCldrFile = cldrFactory.make(childLocale, false);
if (childCldrFile != null) {
- CollectionUtilities.addAll(childCldrFile.iterator(), allPaths);
+ childCldrFile.forEach(allPaths::add);
}
sublocales.put(childLocale, childCldrFile);
}
@@ -294,8 +294,8 @@
for (Entry<String, CLDRFile> s : sublocales.entrySet()) {
String newChildValue = s.getValue().getStringValue(path);
- if (newChildValue == null
- || CldrUtility.equals(newChildValue, value)
+ if (newChildValue == null
+ || CldrUtility.equals(newChildValue, value)
|| CldrUtility.INHERITANCE_MARKER.equals(newChildValue)) {
continue;
}
@@ -410,7 +410,7 @@
.append("</td><td class='v'>")
.append(DataShower.getPrettyValue(value.substring(breakPoint + 2)))
.append("</td><td>")
- .append(CollectionUtilities.join(s.getValue(), ", "))
+ .append(Joiner.on(", ").join(s.getValue()))
.append("</td></tr>")
.append(System.lineSeparator());
addRow = true;
@@ -429,7 +429,7 @@
final boolean noLocales = locales == null || locales.isEmpty();
pw.println("<td"
+ (isExemplar ? " style='max-width:20%'" : "")
- + (noLocales ? "" : " title='" + CollectionUtilities.join(locales, ", ") + "'")
+ + (noLocales ? "" : " title='" + Joiner.on(", ").join(locales) + "'")
+ (value == null ? "></i>n/a</i>" : " class='v'" + DataShower.getBidiStyle(value) + ">" + DataShower.getPrettyValue(value))
+ "</td>");
}
@@ -448,8 +448,8 @@
private static void getScripts() throws IOException {
Set<String> locales = cldrFactory.getAvailableLanguages();
- Set<String> scripts = new TreeSet<String>();
- Map<String, Map<String, Set<String>>> script_name_locales = new TreeMap<String, Map<String, Set<String>>>();
+ Set<String> scripts = new TreeSet<>();
+ Map<String, Map<String, Set<String>>> script_name_locales = new TreeMap<>();
PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "scriptNames.txt");
for (Iterator<String> it = locales.iterator(); it.hasNext();) {
String locale = it.next();
@@ -472,10 +472,10 @@
if (getScripts(name, scripts).contains(script)) {
Map<String, Set<String>> names_locales = script_name_locales.get(script);
if (names_locales == null)
- script_name_locales.put(script, names_locales = new TreeMap<String, Set<String>>());
+ script_name_locales.put(script, names_locales = new TreeMap<>());
Set<String> localeSet = names_locales.get(name);
if (localeSet == null)
- names_locales.put(name, localeSet = new TreeSet<String>());
+ names_locales.put(name, localeSet = new TreeSet<>());
localeSet.add(getLocaleNameAndCode(locale));
}
}
@@ -489,7 +489,7 @@
out.close();
}
- static Set<String> UnicodeScripts = Collections.unmodifiableSet(new TreeSet<String>(Arrays
+ static Set<String> UnicodeScripts = Collections.unmodifiableSet(new TreeSet<>(Arrays
.asList(new String[] { "Arab", "Armn", "Bali", "Beng", "Bopo", "Brai",
"Bugi", "Buhd", "Cans", "Cher", "Copt", "Cprt", "Cyrl", "Deva",
"Dsrt", "Ethi", "Geor", "Glag", "Goth", "Grek", "Gujr", "Guru",
@@ -711,7 +711,7 @@
// "$" //
// + "Date" //
// + "$") // odd style to keep CVS from substituting
- ; // isoDateFormat.format(new Date())
+ // isoDateFormat.format(new Date())
BufferedReader input = ToolUtilities.getUTF8Data("chart-template.html");
StringBuffer result = new StringBuffer();
while (true) {
diff --git a/tools/java/org/unicode/cldr/tool/ShowDtdDiffs.java b/tools/java/org/unicode/cldr/tool/ShowDtdDiffs.java
index ac66935..91aa011 100644
--- a/tools/java/org/unicode/cldr/tool/ShowDtdDiffs.java
+++ b/tools/java/org/unicode/cldr/tool/ShowDtdDiffs.java
@@ -17,7 +17,7 @@
import org.unicode.cldr.util.DtdType;
import org.unicode.cldr.util.SupplementalDataInfo;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
public class ShowDtdDiffs {
static final SupplementalDataInfo SDI = CLDRConfig.getInstance().getSupplementalDataInfo();
@@ -153,7 +153,7 @@
}
names.add(name);
}
- return names.isEmpty() ? "" : CollectionUtilities.join(names, ", ");
+ return names.isEmpty() ? "" : Joiner.on(", ").join(names);
}
private static boolean isDeprecated(DtdType dtdType, String elementName, String attributeName) {
diff --git a/tools/java/org/unicode/cldr/tool/ShowKeyboards.java b/tools/java/org/unicode/cldr/tool/ShowKeyboards.java
index eb8f9d4..23a2b2d 100644
--- a/tools/java/org/unicode/cldr/tool/ShowKeyboards.java
+++ b/tools/java/org/unicode/cldr/tool/ShowKeyboards.java
@@ -42,7 +42,7 @@
import org.unicode.cldr.util.TransliteratorUtilities;
import org.unicode.cldr.util.UnicodeSetPrettyPrinter;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -117,12 +117,12 @@
}
public static void showRepertoire(Matcher idMatcher) {
- Set<Exception> totalErrors = new LinkedHashSet<Exception>();
- Set<Exception> errors = new LinkedHashSet<Exception>();
+ Set<Exception> totalErrors = new LinkedHashSet<>();
+ Set<Exception> errors = new LinkedHashSet<>();
UnicodeSet controls = new UnicodeSet("[:Cc:]").freeze();
// check what the characters are, excluding controls.
- Map<Id, UnicodeSet> id2unicodeset = new TreeMap<Id, UnicodeSet>();
- Set<String> totalModifiers = new LinkedHashSet<String>();
+ Map<Id, UnicodeSet> id2unicodeset = new TreeMap<>();
+ Set<String> totalModifiers = new LinkedHashSet<>();
Relation<String, Id> locale2ids = Relation.of(new TreeMap<String, Set<Id>>(), TreeSet.class);
LanguageTagCanonicalizer canonicalizer = new LanguageTagCanonicalizer();
IdInfo idInfo = new IdInfo();
@@ -153,7 +153,8 @@
}
}
if (totalErrors.size() != 0) {
- System.out.println("Errors\t" + CollectionUtilities.join(totalErrors, System.lineSeparator() + "\t"));
+ System.out.println("Errors\t" + Joiner.on(System.lineSeparator() + "\t")
+ .join(totalErrors));
}
for (String item : totalModifiers) {
System.out.println(item);
@@ -205,10 +206,10 @@
}
private static void showHtml(Matcher idMatcher) throws IOException {
- Set<Exception> errors = new LinkedHashSet<Exception>();
+ Set<Exception> errors = new LinkedHashSet<>();
Relation<String, Row.R3<String, String, String>> locale2keyboards = Relation.of(
new TreeMap<String, Set<Row.R3<String, String, String>>>(), TreeSet.class);
- Map<String, String> localeIndex = new TreeMap<String, String>();
+ Map<String, String> localeIndex = new TreeMap<>();
for (String platformId : Keyboard.getPlatformIDs()) {
//Platform p = Keyboard.getPlatform(platformId);
@@ -407,7 +408,7 @@
String keyString = key == Gesture.LONGPRESS ? "LP" : key.toString();
final V value = entry.getValue();
String valueString = value instanceof Collection
- ? CollectionUtilities.join((Collection) value, " ")
+ ? Joiner.on(" ").join((Collection) value)
: value.toString();
hover.append(TransliteratorUtilities.toHTML.transform(keyString)).append("→")
.append(TransliteratorUtilities.toHTML.transform(valueString));
@@ -451,9 +452,9 @@
.addColumn("Statistics").setCellAttributes("class='cell'")
.addColumn("Characters").setSpanRows(true).setCellAttributes("class='cell'");
- Map<String, UnicodeSet> commonSets = new HashMap<String, UnicodeSet>();
- Counter<String> commonCount = new Counter<String>();
- Set<String> commonDone = new HashSet<String>();
+ Map<String, UnicodeSet> commonSets = new HashMap<>();
+ Counter<String> commonCount = new Counter<>();
+ Set<String> commonDone = new HashSet<>();
for (Entry<String, Set<Id>> localeAndIds : locale2ids.keyValuesSet()) {
final String key = localeAndIds.getKey();
@@ -578,7 +579,7 @@
{
collator.setStrength(Collator.IDENTICAL);
for (int i = 0; i < charToKeyboards.length; ++i) {
- charToKeyboards[i] = new TreeMap<String, IdSet>(collator);
+ charToKeyboards[i] = new TreeMap<>(collator);
}
}
IdSet allIds = new IdSet();
@@ -648,7 +649,7 @@
.addColumn("Code").setCellAttributes("class='c'")
.addColumn("Name").setCellAttributes("class='n'")
.addColumn("Keyboards").setSpanRows(true).setCellAttributes("class='k'");
- Set<String> missingScripts = new TreeSet<String>();
+ Set<String> missingScripts = new TreeSet<>();
UnicodeSet notNFKC = new UnicodeSet("[:nfkcqc=n:]");
UnicodeSet COMMONINHERITED = new UnicodeSet("[[:sc=common:][:sc=inherited:]]");
@@ -737,7 +738,7 @@
}
private static String getInfo(Id keyboardId, UnicodeSet common, CLDRFile cldrFile) {
- Counter<String> results = new Counter<String>();
+ Counter<String> results = new Counter<>();
for (String s : common) {
int first = s.codePointAt(0); // first char is good enough
results.add(UScript.getShortName(UScript.getScript(first)), 1);
@@ -848,7 +849,7 @@
}
static class IdSet {
- Map<String, Relation<String, String>> data = new TreeMap<String, Relation<String, String>>();
+ Map<String, Relation<String, String>> data = new TreeMap<>();
public void add(Id id) {
Relation<String, String> platform2variant = data.get(id.platform);
@@ -946,6 +947,7 @@
return data.equals(((IdSet) other).data);
}
+ @Override
public int hashCode() {
return data.hashCode();
}
diff --git a/tools/java/org/unicode/cldr/tool/ShowLanguageData.java b/tools/java/org/unicode/cldr/tool/ShowLanguageData.java
index 92ff140..4e97caf 100644
--- a/tools/java/org/unicode/cldr/tool/ShowLanguageData.java
+++ b/tools/java/org/unicode/cldr/tool/ShowLanguageData.java
@@ -18,7 +18,7 @@
public static void main(String[] args) {
- Map<String, Counter<String>> map = new TreeMap<String, Counter<String>>();
+ Map<String, Counter<String>> map = new TreeMap<>();
for (String language : data.getLanguagesForTerritoriesPopulationData()) {
if (language.equals("und")) {
@@ -27,7 +27,7 @@
for (String territory : data.getTerritoriesForPopulationData(language)) {
Counter<String> langCounter = map.get(territory);
if (langCounter == null) {
- map.put(territory, langCounter = new Counter<String>());
+ map.put(territory, langCounter = new Counter<>());
}
PopulationData popData = data.getLanguageAndTerritoryPopulationData(language, territory);
OfficialStatus status = popData.getOfficialStatus();
diff --git a/tools/java/org/unicode/cldr/tool/ShowLanguages.java b/tools/java/org/unicode/cldr/tool/ShowLanguages.java
index 6b11496..908c945 100644
--- a/tools/java/org/unicode/cldr/tool/ShowLanguages.java
+++ b/tools/java/org/unicode/cldr/tool/ShowLanguages.java
@@ -63,10 +63,11 @@
import org.unicode.cldr.util.TransliteratorUtilities;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.impl.Row.R4;
@@ -130,7 +131,9 @@
new ChartUnitConversions().writeChart(SUPPLEMENTAL_INDEX_ANCHORS);
new ChartUnitPreferences().writeChart(SUPPLEMENTAL_INDEX_ANCHORS);
}
-
+ if (ToolConstants.CHART_VERSION.compareTo("37") >= 0) {
+ new ChartGrammaticalForms().writeChart(SUPPLEMENTAL_INDEX_ANCHORS);
+ }
// since we don't want these listed on the supplemental page, use null
new ShowPlurals().printPlurals(english, null, pw, cldrFactory);
@@ -191,8 +194,8 @@
}
private static void writeSupplementalIndex(String filename, StringWriter sw) throws IOException {
- String[] replacements = {
- "%date%", CldrUtility.isoFormatDateOnly(new Date()),
+ String[] replacements = {
+ "%date%", CldrUtility.isoFormatDateOnly(new Date()),
"%contents%", SUPPLEMENTAL_INDEX_ANCHORS.toString(),
"%data%", sw.toString(),
"%index%", "../index.html" };
@@ -228,7 +231,7 @@
.addColumn("P", "class='target' title='primary'", null, "class='target'", true).setSortPriority(3);
// get the codes so we can show the remainder
- Set<String> remainingScripts = new TreeSet<String>(getScriptsToShow()); // StandardCodes.MODERN_SCRIPTS);
+ Set<String> remainingScripts = new TreeSet<>(getScriptsToShow()); // StandardCodes.MODERN_SCRIPTS);
UnicodeSet temp = new UnicodeSet();
for (String script : getScriptsToShow()) {
temp.clear();
@@ -250,7 +253,7 @@
remainingScripts.remove("Zzzz");
remainingScripts.remove("Zyyy");
- Set<String> remainingLanguages = new TreeSet<String>(getLanguagesToShow());
+ Set<String> remainingLanguages = new TreeSet<>(getLanguagesToShow());
for (String language : getLanguagesToShow()) {
Scope s = Iso639Data.getScope(language);
Type t = Iso639Data.getType(language);
@@ -290,7 +293,7 @@
}
- static final Map<String, OfficialStatus> languageToBestStatus = new HashMap<String, OfficialStatus>();
+ static final Map<String, OfficialStatus> languageToBestStatus = new HashMap<>();
static {
for (String language : supplementalDataInfo.getLanguagesForTerritoriesPopulationData()) {
Set<String> territories = supplementalDataInfo.getTerritoriesForPopulationData(language);
@@ -335,7 +338,7 @@
}
private static Set<String> getEnglishTypes(String type, int code) {
- Set<String> result = new HashSet<String>(sc.getSurveyToolDisplayCodes(type));
+ Set<String> result = new HashSet<>(sc.getSurveyToolDisplayCodes(type));
for (Iterator<String> it = english.getAvailableIterator(code); it.hasNext();) {
XPathParts parts = XPathParts.getFrozenInstance(it.next());
String newType = parts.getAttributeValue(-1, "type");
@@ -368,8 +371,8 @@
.addColumn("Code", "class='target'", null, "class='target'", true);
// get the codes so we can show the remainder
- Set<String> remainingScripts = new TreeSet<String>(getScriptsToShow());
- Set<String> remainingTerritories = new TreeSet<String>(sc.getGoodAvailableCodes("territory"));
+ Set<String> remainingScripts = new TreeSet<>(getScriptsToShow());
+ Set<String> remainingTerritories = new TreeSet<>(sc.getGoodAvailableCodes("territory"));
UnicodeSet temp = new UnicodeSet();
for (String script : getScriptsToShow()) {
temp.clear();
@@ -391,7 +394,7 @@
remainingScripts.remove("Zzzz");
remainingScripts.remove("Zyyy");
- Set<String> remainingLanguages = new TreeSet<String>(getLanguagesToShow());
+ Set<String> remainingLanguages = new TreeSet<>(getLanguagesToShow());
for (String language : getLanguagesToShow()) {
Scope s = Iso639Data.getScope(language);
Type t = Iso639Data.getType(language);
@@ -413,7 +416,7 @@
// mainTerritories.add("ZZ");
}
- TreeSet<String> mainScripts = new TreeSet<String>(basicData.getScripts());
+ TreeSet<String> mainScripts = new TreeSet<>(basicData.getScripts());
if (mainScripts.size() == 0) {
continue;
}
@@ -450,7 +453,7 @@
}
Set<String> territories = territoryFix.getAll(language);
if (territories == null) {
- territories = new TreeSet<String>();
+ territories = new TreeSet<>();
}
return territories;
}
@@ -568,13 +571,13 @@
.finishRow();
}
- static Map<String, String> fixScriptGif = CollectionUtilities.asMap(new String[][] {
- { "hangul", "hangulsyllables" },
- { "japanese", "hiragana" },
- { "unknown or invalid script", "unknown" },
- { "Hant", "Hant" },
- { "Hans", "Hans" },
- });
+ static ImmutableMap<String, String> fixScriptGif = ImmutableMap.<String, String>builder()
+ .put("hangul", "hangulsyllables")
+ .put("japanese", "hiragana")
+ .put("unknown or invalid script", "unknown")
+ .put("Hant", "Hant")
+ .put("Hans", "Hans")
+ .build();
private static String getGifName(String script) {
String temp = fixScriptGif.get(script);
@@ -641,13 +644,13 @@
}
static class LanguageInfo {
- private static final Map<String, Map<String, String>> localeAliasInfo = new TreeMap<String, Map<String, String>>();
+ private static final Map<String, Map<String, String>> localeAliasInfo = new TreeMap<>();
Multimap<String, String> language_scripts = TreeMultimap.create();
Multimap<String, String> language_territories = TreeMultimap.create();
- List<Map<String, String>> deprecatedItems = new ArrayList<Map<String, String>>();
+ List<Map<String, String>> deprecatedItems = new ArrayList<>();
Multimap<String, String> territory_languages;
@@ -665,19 +668,19 @@
Map<String, Set> territory_currency = new TreeMap<String, Set>(col);
- Set<String> territoriesWithCurrencies = new TreeSet<String>();
+ Set<String> territoriesWithCurrencies = new TreeSet<>();
- Set<String> currenciesWithTerritories = new TreeSet<String>();
+ Set<String> currenciesWithTerritories = new TreeSet<>();
- Map<String, Map<String, Set<String>>> territoryData = new TreeMap<String, Map<String, Set<String>>>();
+ Map<String, Map<String, Set<String>>> territoryData = new TreeMap<>();
- Set<String> territoryTypes = new TreeSet<String>();
+ Set<String> territoryTypes = new TreeSet<>();
Map<String, LinkedHashSet<String>> charSubstitutions = new TreeMap<String, LinkedHashSet<String>>(col);
String defaultDigits = null;
- Map<String, Map<String, Object>> territoryLanguageData = new TreeMap<String, Map<String, Object>>();
+ Map<String, Map<String, Object>> territoryLanguageData = new TreeMap<>();
private Relation<String, String> territoriesToModernCurrencies = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class,
null);
@@ -881,8 +884,8 @@
String type = entry2.getKey();
R2<List<String>, String> replacementReason = entry2.getValue();
List<String> replacementList = replacementReason.get0();
- String replacement = replacementList == null ? null : CollectionUtilities
- .join(replacementList, " ");
+ String replacement = replacementList == null ? null :
+ Joiner.on(" ").join(replacementList);
String reason = replacementReason.get1();
if (element.equals("timezone")) {
element = "zone";
@@ -981,6 +984,7 @@
}
static final Comparator INVERSE_COMPARABLE = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
return ((Comparable) o2).compareTo(o1);
}
@@ -1020,22 +1024,9 @@
}
}
- // http://trac.edgewall.org/wiki/TracTickets#PresetValuesforNewTickets
- // http://unicode.org/cldr/trac/newticket?summary=Fix_XXX
private String addBug(int bugNumber, String text, String from, String subject, String body) {
- String parameters = "";
- // if (from != null && from.length() != 0) {
- // parameters += "&from=" + urlEncode(from);
- // }
- if (body != null && body.length() != 0) {
- parameters += "&description=" + urlEncode(body);
- }
- if (subject != null && subject.length() != 0) {
- parameters += "&summary=" + urlEncode(subject);
- }
- if (parameters.length() != 0) parameters = "?" + parameters;
return "<a target='_blank' href='" + CLDRURLS.CLDR_NEWTICKET_URL
- + parameters + "'>" + text + "</a>";
+ + "'>" + text + "</a>";
}
private void showLanguageCountryInfo(PrintWriter pw) throws IOException {
@@ -1075,11 +1066,11 @@
// .addColumn("Territory Literacy", "class='target'", "{0,number,00.0}%", "class='targetRight'", true)
// .addColumn("Territory GDP (PPP)", "class='target'", "{0,number,#,##0}", "class='targetRight'", true)
;
- TreeSet<String> languages = new TreeSet<String>();
- Collection<Comparable[]> data = new ArrayList<Comparable[]>();
+ TreeSet<String> languages = new TreeSet<>();
+ Collection<Comparable[]> data = new ArrayList<>();
String msg = "<br><i>Please click on each country code</i>";
- Collection<Comparable[]> plainData = new ArrayList<Comparable[]>();
+ Collection<Comparable[]> plainData = new ArrayList<>();
for (String territoryCode : supplementalDataInfo.getTerritoriesWithPopulationData()) {
// PopulationData territoryData = supplementalDataInfo.getPopulationDataForTerritory(territoryCode);
@@ -1137,7 +1128,7 @@
pw2.close();
try (PrintWriter pw21plain = FileUtilities.openUTF8Writer(ffw.getDir(), ffw.getBaseFileName() + ".txt")) {
for (Comparable[] row : plainData) {
- pw21plain.println(CollectionUtilities.join(row, "\t"));
+ pw21plain.println(Joiner.on("\t").join(row));
}
}
}
@@ -1183,7 +1174,7 @@
.addColumn("Code", "class='source'",
"<a href=\"http://www.unicode.org/cldr/data/common/main/{0}.xml\">{0}</a>", "class='source'", false);
Map<Organization, Map<String, Level>> vendordata = sc.getLocaleTypes();
- Set<String> locales = new TreeSet<String>();
+ Set<String> locales = new TreeSet<>();
Set<Organization> vendors = new LinkedHashSet<>();
Set<Organization> smallVendors = new LinkedHashSet<>();
@@ -1201,8 +1192,8 @@
locales.addAll(data.keySet());
}
- Collection<Comparable[]> data = new ArrayList<Comparable[]>();
- List<String> list = new ArrayList<String>();
+ Collection<Comparable[]> data = new ArrayList<>();
+ List<String> list = new ArrayList<>();
LanguageTagParser ltp = new LanguageTagParser();
//String alias2 = getAlias("sh_YU");
@@ -1547,7 +1538,7 @@
return;
LinkedHashSet<String> already = charSubstitutions.get(value);
if (already == null)
- charSubstitutions.put(value, already = new LinkedHashSet<String>(0));
+ charSubstitutions.put(value, already = new LinkedHashSet<>(0));
already.add(substitute);
Log.logln(hex(value, " ") + "; " + hex(substitute, " "));
}
@@ -1584,11 +1575,11 @@
String territory = getName(CLDRFile.TERRITORY_NAME, territories[i], false);
Map<String, Set<String>> s = territoryData.get(territory);
if (s == null) {
- territoryData.put(territory, s = new TreeMap<String, Set<String>>());
+ territoryData.put(territory, s = new TreeMap<>());
}
Set<String> ss = s.get(type);
if (ss == null) {
- s.put(type, ss = new TreeSet<String>());
+ s.put(type, ss = new TreeSet<>());
}
ss.add(info);
}
@@ -1644,7 +1635,7 @@
public void showCorrespondances() {
// show correspondances between language and script
- Map<String, String> name_script = new TreeMap<String, String>();
+ Map<String, String> name_script = new TreeMap<>();
for (Iterator<String> it = sc.getAvailableCodes("script").iterator(); it.hasNext();) {
String script = it.next();
String name = english.getName(CLDRFile.SCRIPT_NAME, script);
@@ -1658,7 +1649,7 @@
* : source == CLDRFile.LANGUAGE_NAME && target == CLDRFile.SCRIPT_NAME ? language_scripts
*/}
String delimiter = "\\P{L}+";
- Map<String, String> name_language = new TreeMap<String, String>();
+ Map<String, String> name_language = new TreeMap<>();
for (Iterator<String> it = sc.getAvailableCodes("language").iterator(); it.hasNext();) {
String language = it.next();
String names = english.getName(CLDRFile.LANGUAGE_NAME, language);
@@ -2112,7 +2103,7 @@
if (contains == null) {
contains = sc.getCountryToZoneSet().get(start);
if (contains == null && depth == 3) {
- contains = new TreeSet<String>();
+ contains = new TreeSet<>();
if (start.compareTo("A") >= 0) {
contains.add("<font color='red'>MISSING TZID</font>");
} else {
@@ -2129,7 +2120,7 @@
*
*/
public void printMissing(PrintWriter pw, int source, int table) {
- Set<String> missingItems = new HashSet<String>();
+ Set<String> missingItems = new HashSet<>();
String type = null;
if (source == CLDRFile.TERRITORY_NAME) {
type = "territory";
@@ -2240,6 +2231,7 @@
}
Comparator territoryNameComparator = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
return col.compare(getName(CLDRFile.TERRITORY_NAME, (String) o1, false),
getName(CLDRFile.TERRITORY_NAME, (String) o2, false));
@@ -2249,14 +2241,14 @@
static String[] stringArrayPattern = new String[0];
static String[][] string2ArrayPattern = new String[0][];
- public static Map<String, String> territoryAliases = new HashMap<String, String>();
+ public static Map<String, String> territoryAliases = new HashMap<>();
public void printContains(PrintWriter index) throws IOException {
String title = "Territory Containment (UN M.49)";
PrintWriter pw = new PrintWriter(new FormattedFileWriter(null, title, null, SUPPLEMENTAL_INDEX_ANCHORS));
// doTitle(pw, title);
- List<String[]> rows = new ArrayList<String[]>();
+ List<String[]> rows = new ArrayList<>();
printContains3("001", rows, new ArrayList<String>());
TablePrinter tablePrinter = new TablePrinter()
.addColumn("World", "class='source'", null, "class='z0'", true).setSortPriority(0)
@@ -2377,7 +2369,7 @@
*/
private static Map<String, Set<String>> getInverse(Map<String, Set<String>> language_territories) {
// get inverse relation
- Map<String, Set<String>> territory_languages = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> territory_languages = new TreeMap<>();
for (Iterator<String> it = language_territories.keySet().iterator(); it.hasNext();) {
String language = it.next();
Set<String> territories = language_territories.get(language);
diff --git a/tools/java/org/unicode/cldr/tool/ShowLocaleCoverage.java b/tools/java/org/unicode/cldr/tool/ShowLocaleCoverage.java
index 737ae59..a3c21d5 100644
--- a/tools/java/org/unicode/cldr/tool/ShowLocaleCoverage.java
+++ b/tools/java/org/unicode/cldr/tool/ShowLocaleCoverage.java
@@ -66,6 +66,7 @@
import org.unicode.cldr.util.VoteResolver.VoterInfo;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -73,18 +74,18 @@
import com.google.common.collect.Multimap;
import com.google.common.collect.Ordering;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.UnicodeSet;
+import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.VersionInfo;
public class ShowLocaleCoverage {
private static final String VXML_CONSTANT = CLDRPaths.AUX_DIRECTORY + "voting/" + CLDRFile.GEN_VERSION + "/vxml/common/";
private static final CLDRConfig CONFIG = CLDRConfig.getInstance();
- private static final String TSV_MISSING_SUMMARY_HEADER =
+ private static final String TSV_MISSING_SUMMARY_HEADER =
"#Path Level"
+ "\t#Locales"
+ "\tLocales"
@@ -93,7 +94,7 @@
+ "\tHeader"
+ "\tCode"
;
- private static final String TSV_LOCALE_COVERAGE_HEADER =
+ private static final String TSV_LOCALE_COVERAGE_HEADER =
"#Dir"
+ "\tCode"
+ "\tEnglish Name"
@@ -108,7 +109,7 @@
+ "\tCore\tMiss +UC"
+ "\tCore-Missing";
- private static final String TSV_MISSING_HEADER =
+ private static final String TSV_MISSING_HEADER =
"#LCode"
+ "\tEnglish Name"
+ "\tScript"
@@ -131,7 +132,7 @@
+ "\tConfig Action"
;
private static final String TSV_MISSING_BASIC_HEADER = "";
-
+
private static final boolean DEBUG = true;
private static final char DEBUG_FILTER = 0; // use letter to only load locales starting with that letter
@@ -164,14 +165,14 @@
enum MyOptions {
filter(".+", ".*", "Filter the information based on id, using a regex argument."),
// draftStatus(".+", "unconfirmed", "Filter the information to a minimum draft status."),
- chart(null, null, "chart only"),
- growth("true", "true", "Compute growth data"),
- organization(".+", null, "Only locales for organization"),
+ chart(null, null, "chart only"),
+ growth("true", "true", "Compute growth data"),
+ organization(".+", null, "Only locales for organization"),
version(".+",
- LATEST, "To get different versions"),
- rawData(null, null, "Output the raw data from all coverage levels"),
+ LATEST, "To get different versions"),
+ rawData(null, null, "Output the raw data from all coverage levels"),
targetDir(".*",
- CLDRPaths.GEN_DIRECTORY + "/statistics/", "target output file."),
+ CLDRPaths.GEN_DIRECTORY + "/statistics/", "target output file."),
directories("(.*:)?[a-z]+(,[a-z]+)*", "common",
"Space-delimited list of main source directories: common,seed,exemplar.\n" +
"Optional, <baseDir>:common,seed"),;
@@ -340,7 +341,7 @@
out.println();
first = false;
}
- out.println(entry.getKey() + "\t" + CollectionUtilities.join(entry.getValue(), "\t"));
+ out.println(entry.getKey() + "\t" + Joiner.on("\t").join(entry.getValue()));
}
}
@@ -352,7 +353,7 @@
VersionInfo version;
int year;
}
-
+
// TODO merge this into ToolConstants, and have the version expressed as VersionInfo.
static final List<ReleaseInfo> versionToYear;
static {
@@ -512,9 +513,9 @@
// }
// }
// END HACK
- Counter<Level> foundCounter = new Counter<Level>();
- Counter<Level> unconfirmedCounter = new Counter<Level>();
- Counter<Level> missingCounter = new Counter<Level>();
+ Counter<Level> foundCounter = new Counter<>();
+ Counter<Level> unconfirmedCounter = new Counter<>();
+ Counter<Level> missingCounter = new Counter<>();
Set<String> unconfirmedPaths = null;
Relation<MissingStatus, String> missingPaths = null;
unconfirmedPaths = new LinkedHashSet<>();
@@ -597,7 +598,7 @@
fixCommonLocales();
- System.out.println(CollectionUtilities.join(languageToRegion.keyValuesSet(), "\n"));
+ System.out.println(Joiner.on("\n").join(languageToRegion.keyValuesSet()));
System.out.println("# Checking: " + availableLanguages);
@@ -616,7 +617,7 @@
Relation<MissingStatus, String> missingPaths = Relation.of(new EnumMap<MissingStatus, Set<String>>(
MissingStatus.class), TreeSet.class, CLDRFile.getComparator(DtdType.ldml));
- Set<String> unconfirmed = new TreeSet<String>(CLDRFile.getComparator(DtdType.ldml));
+ Set<String> unconfirmed = new TreeSet<>(CLDRFile.getComparator(DtdType.ldml));
//Map<String, String> likely = testInfo.getSupplementalDataInfo().getLikelySubtags();
Set<String> defaultContents = SUPPLEMENTAL_DATA_INFO.getDefaultContentLocales();
@@ -632,9 +633,9 @@
// System.out.println();
// Factory pathHeaderFactory = PathHeader.getFactory(testInfo.getCldrFactory().make("en", true));
- Counter<Level> foundCounter = new Counter<Level>();
- Counter<Level> unconfirmedCounter = new Counter<Level>();
- Counter<Level> missingCounter = new Counter<Level>();
+ Counter<Level> foundCounter = new Counter<>();
+ Counter<Level> unconfirmedCounter = new Counter<>();
+ Counter<Level> missingCounter = new Counter<>();
List<Level> levelsToShow = new ArrayList<>(EnumSet.allOf(Level.class));
levelsToShow.remove(Level.COMPREHENSIVE);
@@ -689,16 +690,16 @@
.setCellPattern("{0,number,0.0%}")
.setBreakSpans(true);
switch(level) {
- case CORE:
+ case CORE:
tablePrinter.setSortPriority(5).setSortAscending(false);
break;
- case BASIC:
+ case BASIC:
tablePrinter.setSortPriority(4).setSortAscending(false);
break;
- case MODERATE:
+ case MODERATE:
tablePrinter.setSortPriority(3).setSortAscending(false);
break;
- case MODERN:
+ case MODERN:
tablePrinter.setSortPriority(2).setSortAscending(false);
break;
}
@@ -706,7 +707,7 @@
// .addColumn("∪ UC%", "class='target'", null, "class='targetRight'", true)
// .setCellPattern("{0,number,0.0%}")
// .setBreakSpans(true)
- ;
+
}
tablePrinter.addColumn("Core Missing", "class='target'", null, "class='targetRight'", true)
.setBreakSpans(true);
@@ -731,7 +732,7 @@
for (String locale : availableLanguages) {
try {
if (locale.contains("supplemental") // for old versionsl
- || locale.startsWith("sr_Latn")) {
+ || locale.startsWith("sr_Latn")) {
continue;
}
if (locales != null && !locales.contains(locale)) {
@@ -849,7 +850,7 @@
.append('\t').append(script)
.append('\t').append(cldrLocaleLevelGoal.toString())
.append('\t').append(sublocales.size()+"");
- ;
+
}
// String header = language
@@ -943,7 +944,7 @@
if (goalLevel.compareTo(foundLevel) >= 0) {
String line = spreadsheetLine(locale, language, script, file.getStringValue(path), goalLevel, foundLevel, "n/a", path, file, vxmlCldrFile2, pathToLocale);
tsv_missing.println(line);
- }
+ }
}
} else {
Level goalLevel = Level.BASIC;
@@ -959,17 +960,17 @@
Level foundLevel = coverageInfo.getCoverageLevel(path, locale);
if (goalLevel.compareTo(foundLevel) >= 0) {
gatherStarred(path, starredCounter);
- }
+ }
}
}
tsv_missing_basic.println(TSV_MISSING_BASIC_HEADER);
for (R2<Long, String> starred : starredCounter.getEntrySetSortedByCount(false, null)) {
// PathHeader ph = pathHeaderFactory.fromPath(starred.get1());
- tsv_missing_basic.println(locale + "\t" + starred.get0() + "\t" + starred.get1());
+ tsv_missing_basic.println(locale + "\t" + starred.get0() + "\t" + starred.get1().replace("\"*\"", "'*'"));
}
-
- for (Level level : levelsToShow) {
+
+ for (Level level : levelsToShow) {
long foundCount = foundCounter.get(level);
long unconfirmedCount = unconfirmedCounter.get(level);
long missingCount = missingCounter.get(level);
@@ -978,9 +979,9 @@
sumUnconfirmed += unconfirmedCount;
sumMissing += missingCount;
- confirmed.put(level, (int) sumFound);
+ confirmed.put(level, sumFound);
// unconfirmedByLevel.put(level, (int)(foundCount + unconfirmedCount));
- totals.put(level, (int)(sumFound + sumUnconfirmed + sumMissing));
+ totals.put(level, sumFound + sumUnconfirmed + sumMissing);
}
double modernTotal = totals.get(Level.MODERN);
@@ -1034,8 +1035,8 @@
// ;
// }
}
- String coreMissingString =
- CollectionUtilities.join(coreMissing, ", ");
+ String coreMissingString =
+ Joiner.on(", ").join(coreMissing);
tablePrinter
.addCell(coreMissingString)
@@ -1048,8 +1049,6 @@
.append('\n');
}
- //out2.println(header + "\t" + coreValue + "\t" + CollectionUtilities.join(missing, ", "));
-
// Write missing paths (for >99% and specials
// if (false) { // checkModernLocales.contains(locale)
@@ -1111,9 +1110,9 @@
localeSet = entry2.getValue();
String s = TSV_MISSING_SUMMARY_HEADER; // check for changes
tsv_missing_summary.println(
- level
+ level
+ "\t" + localeSet.size()
- + "\t" + CollectionUtilities.join(localeSet, " ")
+ + "\t" + Joiner.on(" ").join(localeSet)
+ "\t" + phString
);
}
@@ -1252,30 +1251,38 @@
static final VoterInfo dummyVoterInfo = new VoterInfo(Organization.cldr, org.unicode.cldr.util.VoteResolver.Level.vetter, "somename");
static final UserInfo dummyUserInfo = new UserInfo() {
+ @Override
public VoterInfo getVoterInfo() {
return dummyVoterInfo;
}
};
static final PathValueInfo dummyPathValueInfo = new PathValueInfo() {
// pathValueInfo.getCoverageLevel().compareTo(Level.COMPREHENSIVE)
+ @Override
public Collection<? extends CandidateInfo> getValues() {
throw new UnsupportedOperationException();
}
+ @Override
public CandidateInfo getCurrentItem() {
throw new UnsupportedOperationException();
}
+ @Override
public String getBaselineValue() {
throw new UnsupportedOperationException();
}
+ @Override
public Level getCoverageLevel() {
return Level.MODERN;
}
+ @Override
public boolean hadVotesSometimeThisRelease() {
throw new UnsupportedOperationException();
}
+ @Override
public CLDRLocale getLocale() {
throw new UnsupportedOperationException();
}
+ @Override
public String getXpath() {
throw new UnsupportedOperationException();
}
@@ -1303,8 +1310,8 @@
public static void gatherStarred(String path, Counter<String> starredCounter) {
starredCounter.add(new PathStarrer().setSubstitutionPattern("*").set(path), 1);
}
-
- public static String spreadsheetLine(String locale, String language, String script, String nativeValue, Level cldrLocaleLevelGoal,
+
+ public static String spreadsheetLine(String locale, String language, String script, String nativeValue, Level cldrLocaleLevelGoal,
Level itemLevel, String status, String path, CLDRFile resolvedFile, CLDRFile vxmlCldrFile,
Multimap<String, String> pathToLocale) {
if (pathToLocale != null) {
@@ -1357,7 +1364,7 @@
String s = TSV_MISSING_HEADER; // make sure in sync
- String line =
+ String line =
language
+ "\t" + ENGLISH.getName(language)
+ "\t" + ENGLISH.getName("script", script)
@@ -1374,7 +1381,7 @@
+ "\t" + vxmlValue
+ "\t" + vxmlDraftStatus
+ "\t" + phString
- + "\t" + PathHeader.getUrlForLocalePath(locale, path)
+ + "\t" + PathHeader.getUrlForLocalePath(locale, path)
+ "\t" + config_text
;
return line;
@@ -1383,55 +1390,10 @@
private static String getIcuValue(String locale) {
- return ICU_Locales.contains(locale) ? "ICU" : "";
+ return ICU_Locales.contains(new ULocale(locale)) ? "ICU" : "";
}
- static final Set<String> ICU_Locales = ImmutableSet.of("af", "af_NA", "af_ZA", "agq", "agq_CM", "ak", "ak_GH", "am", "am_ET", "ar", "ar_001", "ar_AE",
- "ar_BH", "ar_DJ", "ar_DZ", "ar_EG", "ar_EH", "ar_ER", "ar_IL", "ar_IQ", "ar_JO", "ar_KM", "ar_KW", "ar_LB", "ar_LY", "ar_MA", "ar_MR", "ar_OM", "ar_PS",
- "ar_QA", "ar_SA", "ar_SD", "ar_SO", "ar_SS", "ar_SY", "ar_TD", "ar_TN", "ar_YE", "ars", "as", "as_IN", "asa", "asa_TZ", "ast", "ast_ES", "az", "az_AZ",
- "az_Cyrl", "az_Cyrl_AZ", "az_Latn", "az_Latn_AZ", "bas", "bas_CM", "be", "be_BY", "bem", "bem_ZM", "bez", "bez_TZ", "bg", "bg_BG", "bm", "bm_ML", "bn",
- "bn_BD", "bn_IN", "bo", "bo_CN", "bo_IN", "br", "br_FR", "brx", "brx_IN", "bs", "bs_Cyrl", "bs_Cyrl_BA", "bs_Latn", "bs_Latn_BA", "bs_BA", "ca",
- "ca_AD", "ca_ES", "ca_FR", "ca_IT", "ccp", "ccp_BD", "ccp_IN", "ce", "ce_RU", "cgg", "cgg_UG", "chr", "chr_US", "ckb", "ckb_IQ", "ckb_IR", "cs",
- "cs_CZ", "cy", "cy_GB", "da", "da_DK", "da_GL", "dav", "dav_KE", "de", "de_AT", "de_BE", "de_CH", "de_DE", "de_IT", "de_LI", "de_LU", "dje", "dje_NE",
- "dsb", "dsb_DE", "dua", "dua_CM", "dyo", "dyo_SN", "dz", "dz_BT", "ebu", "ebu_KE", "ee", "ee_GH", "ee_TG", "el", "el_CY", "el_GR", "en", "en_001",
- "en_150", "en_AG", "en_AI", "en_AS", "en_AT", "en_AU", "en_BB", "en_BE", "en_BI", "en_BM", "en_BS", "en_BW", "en_BZ", "en_CA", "en_CC", "en_CH",
- "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", "en_GB", "en_GD", "en_GG", "en_GH",
- "en_GI", "en_GM", "en_GU", "en_GY", "en_HK", "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE", "en_KI", "en_KN", "en_KY", "en_LC",
- "en_LR", "en_LS", "en_MG", "en_MH", "en_MO", "en_MP", "en_MS", "en_MT", "en_MU", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG", "en_NL", "en_NR", "en_NU",
- "en_NZ", "en_PG", "en_PH", "en_PK", "en_PN", "en_PR", "en_PW", "en_RH", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL",
- "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", "en_TT", "en_TV", "en_TZ", "en_UG", "en_UM", "en_US", "en_US_POSIX", "en_VC", "en_VG", "en_VI",
- "en_VU", "en_WS", "en_ZA", "en_ZM", "en_ZW", "eo", "es", "es_003", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", "es_CL", "es_CO", "es_CR", "es_CU",
- "es_DO", "es_EA", "es_EC", "es_ES", "es_GQ", "es_GT", "es_HN", "es_IC", "es_MX", "es_NI", "es_PA", "es_PE", "es_PH", "es_PR", "es_PY", "es_SV", "es_US",
- "es_UY", "es_VE", "et", "et_EE", "eu", "eu_ES", "ewo", "ewo_CM", "fa", "fa_AF", "fa_IR", "ff", "ff_CM", "ff_GN", "ff_MR", "ff_SN", "fi", "fi_FI", "fil",
- "fil_PH", "fo", "fo_DK", "fo_FO", "fr", "fr_BE", "fr_BF", "fr_BI", "fr_BJ", "fr_BL", "fr_CA", "fr_CD", "fr_CF", "fr_CG", "fr_CH", "fr_CI", "fr_CM",
- "fr_DJ", "fr_DZ", "fr_FR", "fr_GA", "fr_GF", "fr_GN", "fr_GP", "fr_GQ", "fr_HT", "fr_KM", "fr_LU", "fr_MA", "fr_MC", "fr_MF", "fr_MG", "fr_ML", "fr_MQ",
- "fr_MR", "fr_MU", "fr_NC", "fr_NE", "fr_PF", "fr_PM", "fr_RE", "fr_RW", "fr_SC", "fr_SN", "fr_SY", "fr_TD", "fr_TG", "fr_TN", "fr_VU", "fr_WF", "fr_YT",
- "fur", "fur_IT", "fy", "fy_NL", "ga", "ga_IE", "gd", "gd_GB", "gl", "gl_ES", "gsw", "gsw_CH", "gsw_FR", "gsw_LI", "gu", "gu_IN", "guz", "guz_KE", "gv",
- "gv_IM", "ha", "ha_GH", "ha_NE", "ha_NG", "haw", "haw_US", "he", "he_IL", "hi", "hi_IN", "hr", "hr_BA", "hr_HR", "hsb", "hsb_DE", "hu", "hu_HU", "hy",
- "hy_AM", "ia", "ia_001", "id", "id_ID", "ig", "ig_NG", "ii", "ii_CN", "in", "in_ID", "is", "is_IS", "it", "it_CH", "it_IT", "it_SM", "it_VA", "iw",
- "iw_IL", "ja", "ja_JP", "jgo", "jgo_CM", "jmc", "jmc_TZ", "jv", "jv_ID", "ka", "ka_GE", "kab", "kab_DZ", "kam", "kam_KE", "kde", "kde_TZ", "kea",
- "kea_CV", "khq", "khq_ML", "ki", "ki_KE", "kk", "kk_KZ", "kkj", "kkj_CM", "kl", "kl_GL", "kln", "kln_KE", "km", "km_KH", "kn", "kn_IN", "ko", "ko_KP",
- "ko_KR", "kok", "kok_IN", "ks", "ks_IN", "ksb", "ksb_TZ", "ksf", "ksf_CM", "ksh", "ksh_DE", "ku", "ku_TR", "kw", "kw_GB", "ky", "ky_KG", "lag",
- "lag_TZ", "lb", "lb_LU", "lg", "lg_UG", "lkt", "lkt_US", "ln", "ln_AO", "ln_CD", "ln_CF", "ln_CG", "lo", "lo_LA", "lrc", "lrc_IQ", "lrc_IR", "lt",
- "lt_LT", "lu", "lu_CD", "luo", "luo_KE", "luy", "luy_KE", "lv", "lv_LV", "mas", "mas_KE", "mas_TZ", "mer", "mer_KE", "mfe", "mfe_MU", "mg", "mg_MG",
- "mgh", "mgh_MZ", "mgo", "mgo_CM", "mi", "mi_NZ", "mk", "mk_MK", "ml", "ml_IN", "mn", "mn_MN", "mo", "mr", "mr_IN", "ms", "ms_BN", "ms_MY", "ms_SG",
- "mt", "mt_MT", "mua", "mua_CM", "my", "my_MM", "mzn", "mzn_IR", "naq", "naq_NA", "nb", "nb_NO", "nb_SJ", "nd", "nd_ZW", "nds", "nds_DE", "nds_NL", "ne",
- "ne_IN", "ne_NP", "nl", "nl_AW", "nl_BE", "nl_BQ", "nl_CW", "nl_NL", "nl_SR", "nl_SX", "nmg", "nmg_CM", "nn", "nn_NO", "nnh", "nnh_CM", "no", "no_NO",
- "nus", "nus_SS", "nyn", "nyn_UG", "om", "om_ET", "om_KE", "or", "or_IN", "os", "os_GE", "os_RU", "pa", "pa_Arab", "pa_Arab_PK", "pa_Guru", "pa_Guru_IN",
- "pa_IN", "pa_PK", "pl", "pl_PL", "ps", "ps_AF", "pt", "pt_AO", "pt_BR", "pt_CH", "pt_CV", "pt_GQ", "pt_GW", "pt_LU", "pt_MO", "pt_MZ", "pt_PT", "pt_ST",
- "pt_TL", "qu", "qu_BO", "qu_EC", "qu_PE", "rm", "rm_CH", "rn", "rn_BI", "ro", "ro_MD", "ro_RO", "rof", "rof_TZ", "root", "ru", "ru_BY", "ru_KG",
- "ru_KZ", "ru_MD", "ru_RU", "ru_UA", "rw", "rw_RW", "rwk", "rwk_TZ", "sah", "sah_RU", "saq", "saq_KE", "sbp", "sbp_TZ", "sd", "sd_PK", "se", "se_FI",
- "se_NO", "se_SE", "seh", "seh_MZ", "ses", "ses_ML", "sg", "sg_CF", "sh", "sh_BA", "sh_CS", "sh_YU", "shi", "shi_Latn", "shi_Latn_MA", "shi_Tfng",
- "shi_Tfng_MA", "shi_MA", "si", "si_LK", "sk", "sk_SK", "sl", "sl_SI", "smn", "smn_FI", "sn", "sn_ZW", "so", "so_DJ", "so_ET", "so_KE", "so_SO", "sq",
- "sq_AL", "sq_MK", "sq_XK", "sr", "sr_Cyrl", "sr_Cyrl_BA", "sr_Cyrl_ME", "sr_Cyrl_RS", "sr_Cyrl_CS", "sr_Cyrl_XK", "sr_Cyrl_YU", "sr_Latn", "sr_Latn_BA",
- "sr_Latn_ME", "sr_Latn_RS", "sr_Latn_CS", "sr_Latn_XK", "sr_Latn_YU", "sr_BA", "sr_ME", "sr_RS", "sr_CS", "sr_YU", "sv", "sv_AX", "sv_FI", "sv_SE",
- "sw", "sw_CD", "sw_KE", "sw_TZ", "sw_UG", "ta", "ta_IN", "ta_LK", "ta_MY", "ta_SG", "te", "te_IN", "teo", "teo_KE", "teo_UG", "tg", "tg_TJ", "th",
- "th_TH", "ti", "ti_ER", "ti_ET", "tk", "tk_TM", "tl", "tl_PH", "to", "to_TO", "tr", "tr_CY", "tr_TR", "tt", "tt_RU", "twq", "twq_NE", "tzm", "tzm_MA",
- "ug", "ug_CN", "uk", "uk_UA", "ur", "ur_IN", "ur_PK", "uz", "uz_AF", "uz_Arab", "uz_Arab_AF", "uz_Cyrl", "uz_Cyrl_UZ", "uz_Latn", "uz_Latn_UZ", "uz_UZ",
- "vai", "vai_Latn", "vai_Latn_LR", "vai_LR", "vai_Vaii", "vai_Vaii_LR", "vi", "vi_VN", "vun", "vun_TZ", "wae", "wae_CH", "wo", "wo_SN", "xh", "xh_ZA",
- "xog", "xog_UG", "yav", "yav_CM", "yi", "yi_001", "yo", "yo_BJ", "yo_NG", "yue", "yue_Hans", "yue_Hans_CN", "yue_Hant", "yue_Hant_HK", "zgh", "zgh_MA",
- "zh", "zh_Hans", "zh_Hans_CN", "zh_Hans_HK", "zh_Hans_MO", "zh_Hans_SG", "zh_Hant", "zh_Hant_HK", "zh_Hant_MO", "zh_Hant_TW", "zh_CN", "zh_HK", "zh_MO",
- "zh_SG", "zh_TW", "zu", "zu_ZA");
+ static final Set<ULocale> ICU_Locales = ImmutableSet.copyOf(ULocale.getAvailableLocales());
private static CLDRURLS URLS = CONFIG.urls();
}
diff --git a/tools/java/org/unicode/cldr/tool/ShowPathHeaderDescriptions.java b/tools/java/org/unicode/cldr/tool/ShowPathHeaderDescriptions.java
index c4e8092..d96f652 100644
--- a/tools/java/org/unicode/cldr/tool/ShowPathHeaderDescriptions.java
+++ b/tools/java/org/unicode/cldr/tool/ShowPathHeaderDescriptions.java
@@ -15,11 +15,11 @@
import org.unicode.cldr.util.PathHeader.PageId;
import org.unicode.cldr.util.PathHeader.SectionId;
+import com.google.common.base.Joiner;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.impl.Row.R3;
@@ -33,16 +33,16 @@
PathHeader.Factory phf = PathHeader.getFactory(english);
String localeToTest = "cs";
-
+
CLDRFile localeFile = factory.make(localeToTest, true);
Multiset<String> sectionPageHeader = LinkedHashMultiset.create();
Multiset<String> sectionPage = LinkedHashMultiset.create();
Set<PathHeader> pathHeaders = new TreeSet<>();
UnicodeSet emoji = new UnicodeSet("[:emoji:]");
-
+
for (String path : localeFile.fullIterable()) {
if (emoji.containsSome(path)) {
-
+
}
PathHeader pathHeader = phf.fromPath(path);
if (pathHeader.getSectionId() == SectionId.Characters) {
@@ -139,7 +139,7 @@
process(SphType.sph, sphv, done);
- System.out.println(CollectionUtilities.join(urls, "\n"));
+ System.out.println(Joiner.on("\n").join(urls));
}
private static void showProgress(Set<String> done, Multimap<String, R3<SectionId, PageId, String>> valueToKey) {
@@ -160,7 +160,7 @@
remaining.removeAll(done);
if (remaining.size() == 1) {
String value = remaining.iterator().next();
- if (type == type.s || type == type.p || type == type.sp) {
+ if (type == SphType.s || type == SphType.p || type == SphType.sp) {
done.add(value);
} else {
newDone.add(value);
diff --git a/tools/java/org/unicode/cldr/tool/ShowPlurals.java b/tools/java/org/unicode/cldr/tool/ShowPlurals.java
index bfcc4c9..710b627 100644
--- a/tools/java/org/unicode/cldr/tool/ShowPlurals.java
+++ b/tools/java/org/unicode/cldr/tool/ShowPlurals.java
@@ -19,7 +19,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
@@ -101,7 +101,7 @@
//Map<ULocale, PluralRulesFactory.SamplePatterns> samples = PluralRulesFactory.getLocaleToSamplePatterns();
Set<String> cardinalLocales = supplementalDataInfo.getPluralLocales(PluralType.cardinal);
Set<String> ordinalLocales = supplementalDataInfo.getPluralLocales(PluralType.ordinal);
- Set<String> all = new LinkedHashSet<String>(cardinalLocales);
+ Set<String> all = new LinkedHashSet<>(cardinalLocales);
all.addAll(ordinalLocales);
LanguageTagCanonicalizer canonicalizer = new LanguageTagCanonicalizer();
@@ -221,7 +221,7 @@
}
private String getExamples(FixedDecimalSamples exampleList) {
- return CollectionUtilities.join(exampleList.getSamples(), ", ") + (exampleList.bounded ? "" : ", …");
+ return Joiner.on(", ").join(exampleList.getSamples()) + (exampleList.bounded ? "" : ", …");
}
private String getSample(FixedDecimal numb, String samplePattern, NumberFormat nf) {
diff --git a/tools/java/org/unicode/cldr/tool/ShowRegionalVariants.java b/tools/java/org/unicode/cldr/tool/ShowRegionalVariants.java
index 78075d3..9a7ac95 100644
--- a/tools/java/org/unicode/cldr/tool/ShowRegionalVariants.java
+++ b/tools/java/org/unicode/cldr/tool/ShowRegionalVariants.java
@@ -200,7 +200,7 @@
+ ENGLISH.getName(s.toString()));
}
- ArrayList<CLDRFile> parentChain = new ArrayList<CLDRFile>();
+ ArrayList<CLDRFile> parentChain = new ArrayList<>();
for (CLDRLocale current = parent;;) {
parentChain.add(FACTORY.make(current.toString(), true));
CLDRLocale grand = current.getParent();
diff --git a/tools/java/org/unicode/cldr/tool/ShowStarredCoverage.java b/tools/java/org/unicode/cldr/tool/ShowStarredCoverage.java
index f9b30a3..f7db26a 100644
--- a/tools/java/org/unicode/cldr/tool/ShowStarredCoverage.java
+++ b/tools/java/org/unicode/cldr/tool/ShowStarredCoverage.java
@@ -44,10 +44,10 @@
import org.unicode.cldr.util.XMLFileReader;
import org.unicode.cldr.util.XPathParts;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
@@ -332,7 +332,7 @@
pathHeaders.add(ph);
SurveyToolStatus stStatus = ph.getSurveyToolStatus();
String starred = pathStarrer.set(path);
- String attributes = CollectionUtilities.join(pathStarrer.getAttributes(), "|");
+ String attributes = Joiner.on("|").join(pathStarrer.getAttributes());
levelToData.put(level, starred + "|" + stStatus + "|" + requiredVotes, attributes, Boolean.TRUE);
counter.add(level, 1);
}
@@ -350,7 +350,7 @@
count = 1;
}
if (true) {
- String samples = CollectionUtilities.join(attributes.keySet(), ", ");
+ String samples = Joiner.on(", ").join(attributes.keySet());
if (samples.length() > 50) samples = samples.substring(0, 50) + "…";
System.out.println(count
+ "\t" + level
@@ -427,12 +427,12 @@
badLines.add(written
+ "\t" + name
+ "\t" + languageFix.get(written).get0()
- + "\t" + CollectionUtilities.join(source, " "));
+ + "\t" + Joiner.on(" ").join(source));
source = Collections.singleton(Source.alias);
}
System.out.println(written
+ "\t" + name
- + "\t" + CollectionUtilities.join(source, " "));
+ + "\t" + Joiner.on(" ").join(source));
}
for (String s : badLines) {
System.out.println("BAD:\t" + s);
diff --git a/tools/java/org/unicode/cldr/tool/ShowZoneEquivalences.java b/tools/java/org/unicode/cldr/tool/ShowZoneEquivalences.java
index 02cbdf6..fc171c1 100644
--- a/tools/java/org/unicode/cldr/tool/ShowZoneEquivalences.java
+++ b/tools/java/org/unicode/cldr/tool/ShowZoneEquivalences.java
@@ -46,14 +46,14 @@
// System.out.println("in available? " + Arrays.asList(TimeZone.getAvailableIDs()).contains(tzid));
// System.out.println(new TreeSet(Arrays.asList(TimeZone.getAvailableIDs())));
- Set<String> needsTranslation = new TreeSet<String>(Arrays.asList(CountItems.needsTranslationString
+ Set<String> needsTranslation = new TreeSet<>(Arrays.asList(CountItems.needsTranslationString
.split("[,]?\\s+")));
- Set<String> singleCountries = new TreeSet<String>(
+ Set<String> singleCountries = new TreeSet<>(
Arrays
.asList(
"Africa/Bamako America/Godthab America/Santiago America/Guayaquil Asia/Shanghai Asia/Tashkent Asia/Kuala_Lumpur Europe/Madrid Europe/Lisbon Europe/London Pacific/Auckland Pacific/Tahiti"
.split("\\s")));
- Set<String> defaultItems = new TreeSet<String>(
+ Set<String> defaultItems = new TreeSet<>(
Arrays
.asList(
"Antarctica/McMurdo America/Buenos_Aires Australia/Sydney America/Sao_Paulo America/Toronto Africa/Kinshasa America/Santiago Asia/Shanghai America/Guayaquil Europe/Madrid Europe/London America/Godthab Asia/Jakarta Africa/Bamako America/Mexico_City Asia/Kuala_Lumpur Pacific/Auckland Europe/Lisbon Europe/Moscow Europe/Kiev America/New_York Asia/Tashkent Pacific/Tahiti Pacific/Kosrae Pacific/Tarawa Asia/Almaty Pacific/Majuro Asia/Ulaanbaatar Arctic/Longyearbyen Pacific/Midway"
@@ -61,7 +61,7 @@
StandardCodes sc = StandardCodes.make();
Collection<String> codes = sc.getGoodAvailableCodes("tzid");
- TreeSet<String> extras = new TreeSet<String>();
+ TreeSet<String> extras = new TreeSet<>();
Map<String, Set<String>> m = sc.getZoneLinkNew_OldSet();
for (String code : codes) {
Collection<String> s = m.get(code);
@@ -70,11 +70,11 @@
extras.addAll(s);
}
extras.addAll(codes);
- Set<String> icu4jTZIDs = new TreeSet<String>(Arrays.asList(TimeZone.getAvailableIDs()));
- Set<String> diff2 = new TreeSet<String>(icu4jTZIDs);
+ Set<String> icu4jTZIDs = new TreeSet<>(Arrays.asList(TimeZone.getAvailableIDs()));
+ Set<String> diff2 = new TreeSet<>(icu4jTZIDs);
diff2.removeAll(extras);
System.out.println("icu4jTZIDs - StandardCodes: " + diff2);
- diff2 = new TreeSet<String>(extras);
+ diff2 = new TreeSet<>(extras);
diff2.removeAll(icu4jTZIDs);
System.out.println("StandardCodes - icu4jTZIDs: " + diff2);
ArrayComparator ac = new ArrayComparator(new Comparator[] {
@@ -85,8 +85,8 @@
TreeSet<Object[]> country_inflection_names = new TreeSet<Object[]>(ac);
PrintWriter out = FileUtilities.openUTF8Writer(CLDRPaths.GEN_DIRECTORY, "inflections.txt");
- TreeMap<Integer, TreeSet<String>> minOffsetMap = new TreeMap<Integer, TreeSet<String>>();
- TreeMap<Integer, TreeSet<String>> maxOffsetMap = new TreeMap<Integer, TreeSet<String>>();
+ TreeMap<Integer, TreeSet<String>> minOffsetMap = new TreeMap<>();
+ TreeMap<Integer, TreeSet<String>> maxOffsetMap = new TreeMap<>();
for (Iterator<String> it = codes.iterator(); it.hasNext();) {
String zoneID = it.next();
@@ -98,12 +98,12 @@
TreeSet<String> s = minOffsetMap.get(zip.getMinOffset());
if (s == null)
- minOffsetMap.put(zip.getMinOffset(), s = new TreeSet<String>());
+ minOffsetMap.put(zip.getMinOffset(), s = new TreeSet<>());
s.add(zone.getID());
s = maxOffsetMap.get(zip.getMaxOffset());
if (s == null)
- maxOffsetMap.put(zip.getMaxOffset(), s = new TreeSet<String>());
+ maxOffsetMap.put(zip.getMaxOffset(), s = new TreeSet<>());
s.add(zone.getID());
}
diff --git a/tools/java/org/unicode/cldr/tool/SimpleLocaleParser.java b/tools/java/org/unicode/cldr/tool/SimpleLocaleParser.java
index ceb603a..a86ab5e 100644
--- a/tools/java/org/unicode/cldr/tool/SimpleLocaleParser.java
+++ b/tools/java/org/unicode/cldr/tool/SimpleLocaleParser.java
@@ -40,7 +40,7 @@
" | ( x (?: [-_] [a-z 0-9]{1,8} )+ )"
+ // private use
" | ( en [-_] GB [-_] oed"
- + // grandfathered gorp
+ + // legacy gorp
" | i [-_] (?: ami | bnn | default | enochian | hak | klingon | lux | mingo | navajo | pwn | tao | tay | tsu )"
+
" | no [-_] (?: bok | nyn )" +
@@ -89,7 +89,7 @@
}
language = root.group(1);
if (language == null) {
- language = root.group(8); // grandfathered
+ language = root.group(8); // marked as “Type: grandfathered” in BCP 47
if (language == null) {
language = "und"; // placeholder for completely private use
}
@@ -113,11 +113,11 @@
// make uppercase for compatibility with CLDR.
variants = Arrays.asList(variantSeparatorPattern.split(variantList.toUpperCase(Locale.ENGLISH)));
// check for duplicate variants
- if (new HashSet<String>(variants).size() != variants.size()) {
+ if (new HashSet<>(variants).size() != variants.size()) {
throw new IllegalArgumentException("Duplicate variants");
}
}
- extensions = new LinkedHashMap<String, String>(); // group 5 are extensions, 6 is private use
+ extensions = new LinkedHashMap<>(); // group 5 are extensions, 6 is private use
// extensions are a bit more complicated
addExtensions(root.group(5), extensionPattern);
addExtensions(root.group(6), privateUsePattern);
@@ -231,6 +231,7 @@
return extensions;
}
+ @Override
public String toString() {
return "{language=" + language
+ ", script=" + script
diff --git a/tools/java/org/unicode/cldr/tool/SubdivisionNames.java b/tools/java/org/unicode/cldr/tool/SubdivisionNames.java
index b516393..42f8cd7 100644
--- a/tools/java/org/unicode/cldr/tool/SubdivisionNames.java
+++ b/tools/java/org/unicode/cldr/tool/SubdivisionNames.java
@@ -41,7 +41,7 @@
public SubdivisionNames(String locale, String... dirs) {
// do inheritance
-
+
Map<String,String> builder = new TreeMap<>();
while (true) {
addSubdivisionNames(locale, builder, dirs);
@@ -50,8 +50,8 @@
break;
}
locale = parent;
- };
-
+ }
+
subdivisionToName = ImmutableMap.copyOf(builder);
}
@@ -126,7 +126,7 @@
}
public static boolean isRegionCode(String regionOrSubdivision) {
- return regionOrSubdivision.length() == 2
+ return regionOrSubdivision.length() == 2
|| (regionOrSubdivision.length() == 3 && regionOrSubdivision.compareTo("A") < 0);
}
@@ -141,7 +141,7 @@
public static boolean isOldSubdivisionCode(String item) {
return item.length() > 4 && item.length() < 7 && OLD_SUBDIVISION.matcher(item).matches();
}
-
+
public static void main(String[] args) {
Factory annotations = CLDRConfig.getInstance().getAnnotationsFactory();
for (String locale : annotations.getAvailable()) {
@@ -152,7 +152,7 @@
<subdivision type="gbwls">Wales</subdivision>
*/
- System.out.println(locale
+ System.out.println(locale
+ " gbeng=" + sd.get("gbeng")
+ " gbsct=" + sd.get("gbsct")
+ " gbwls=" + sd.get("gbwls")
diff --git a/tools/java/org/unicode/cldr/tool/SubdivisionNode.java b/tools/java/org/unicode/cldr/tool/SubdivisionNode.java
index 8c6c6c2..baed3e2 100644
--- a/tools/java/org/unicode/cldr/tool/SubdivisionNode.java
+++ b/tools/java/org/unicode/cldr/tool/SubdivisionNode.java
@@ -40,7 +40,7 @@
import org.unicode.cldr.util.XPathParts;
import org.unicode.cldr.util.XPathParts.Comments.CommentType;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.impl.Utility;
@@ -102,7 +102,7 @@
new TreeMap<String, Object>(),
new TreeMap<String, Object>(),
String.class);
- final Map<String, String> TO_COUNTRY_CODE = new TreeMap<String, String>();
+ final Map<String, String> TO_COUNTRY_CODE = new TreeMap<>();
final Relation<String, String> ID_SAMPLE = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
final Map<String, String> SUB_TO_CAT = new TreeMap<>();
final Relation<String, String> REGION_CONTAINS = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
@@ -180,7 +180,7 @@
"municipality"
};
- static final Pattern CRUFT_PATTERN = PatternCache.get("(?i)\\b" + CollectionUtilities.join(CRUFT, "|") + "\\b");
+ static final Pattern CRUFT_PATTERN = PatternCache.get("(?i)\\b" + String.join("|", CRUFT) + "\\b");
static final Pattern BRACKETED = PatternCache.get("\\[.*\\]");
static String clean(String input) {
@@ -270,7 +270,7 @@
if (cldrName != null) {
return fixName(cldrName);
}
-
+
Collection<String> oldAliases = SubdivisionInfo.subdivisionIdToOld.get(value);
if (oldAliases != null) {
for (String oldAlias : oldAliases) {
@@ -475,13 +475,13 @@
static class SubDivisionExtractor {
final SubdivisionSet sdset;
- final Validity validityFormer;
+ final Validity validityFormer;
final Map<String, R2<List<String>, String>> subdivisionAliasesFormer;
final Relation<String, String> formerRegionToSubdivisions;
- public SubDivisionExtractor(SubdivisionSet sdset,
- Validity validityFormer,
- Map<String, R2<List<String>, String>> subdivisionAliasesFormer,
+ public SubDivisionExtractor(SubdivisionSet sdset,
+ Validity validityFormer,
+ Map<String, R2<List<String>, String>> subdivisionAliasesFormer,
Relation<String, String> formerRegionToSubdivisions) {
this.sdset = sdset;
this.validityFormer = validityFormer;
@@ -501,7 +501,7 @@
*/
output.append(
DtdType.supplementalData.header(MethodHandles.lookup().lookupClass())
- + "\t<version number=\"$Revision" /*hack to stop SVN changing this*/ + "$\"/>\n"
+ + "\t<version number=\"$Revision" + "$\"/>\n"
+ "\t<subdivisionContainment>\n");
printXml(output, sdset.BASE, 0);
output.append("\t</subdivisionContainment>\n</supplementalData>\n");
@@ -550,7 +550,7 @@
String reason = "deprecated";
R2<List<String>, String> aliasInfo = subdivisionAliasesFormer.get(toReplace);
if (aliasInfo != null) {
- replaceBy = aliasInfo.get0(); // == null ? null : CollectionUtilities.join(aliasInfo.get0(), " ");
+ replaceBy = aliasInfo.get0();
reason = aliasInfo.get1();
System.out.println("Adding former alias: " + toReplace + " => " + replaceBy);
} else {
@@ -573,7 +573,8 @@
}
output.append("<subdivisionAlias"
+ " type=\"" + toReplace + "\""
- + " replacement=\"" + (replaceBy == null ? toReplace.substring(0, 2) + "?" : CollectionUtilities.join(replaceBy, " ")) + "\""
+ + " replacement=\"" + (replaceBy == null ? toReplace.substring(0, 2) + "?" :
+ Joiner.on(" ").join(replaceBy)) + "\""
+ " reason=\"" + reason + "\"/>"
+ (replaceBy == null ? " <!- - " : " <!-- ")
+ sdset.getBestName(toReplace, true) + " => " + (replaceBy == null ? "??" : getBestName(replaceBy, true)) + " -->"
@@ -653,7 +654,7 @@
output.append(ENGLISH_ICU.regionDisplayName(lastCC) + "\t\t\tEquals:\t" + countEqual.size() + "\t" + countEqual + "\n");
}
countEqual.clear();
- ;
+
lastCC = countryCode;
}
for (String value : entry.getValue()) {
diff --git a/tools/java/org/unicode/cldr/tool/TablePrinter.java b/tools/java/org/unicode/cldr/tool/TablePrinter.java
index ac7035b..a3a1cb3 100644
--- a/tools/java/org/unicode/cldr/tool/TablePrinter.java
+++ b/tools/java/org/unicode/cldr/tool/TablePrinter.java
@@ -41,10 +41,10 @@
System.out.println(s);
}
- private List<Column> columns = new ArrayList<Column>();
+ private List<Column> columns = new ArrayList<>();
private String tableAttributes;
private transient Column[] columnsFlat;
- private List<Comparable<Object>[]> rows = new ArrayList<Comparable<Object>[]>();
+ private List<Comparable<Object>[]> rows = new ArrayList<>();
private String caption;
public String getTableAttributes() {
@@ -171,7 +171,7 @@
if (partialRow != null) {
throw new IllegalArgumentException("Cannot add partial row before calling finishRow()");
}
- partialRow = new ArrayList<Comparable<Object>>();
+ partialRow = new ArrayList<>();
return this;
}
@@ -227,18 +227,19 @@
return this;
}
+ @Override
public String toString() {
return toTable();
}
public void toTsv(PrintWriter tsvFile) {
- Comparable[][] sortedFlat = (Comparable[][]) (rows.toArray(new Comparable[rows.size()][]));
+ Comparable[][] sortedFlat = (rows.toArray(new Comparable[rows.size()][]));
toTsvInternal(sortedFlat, tsvFile);
}
@SuppressWarnings("rawtypes")
public String toTable() {
- Comparable[][] sortedFlat = (Comparable[][]) (rows.toArray(new Comparable[rows.size()][]));
+ Comparable[][] sortedFlat = (rows.toArray(new Comparable[rows.size()][]));
return toTableInternal(sortedFlat);
}
@@ -248,6 +249,7 @@
private BitSet ascending = new BitSet();
Collator englishCollator = Collator.getInstance(ULocale.ENGLISH);
+ @Override
@SuppressWarnings("unchecked")
public int compare(T[] o1, T[] o2) {
int result;
@@ -287,7 +289,7 @@
}
@SuppressWarnings("rawtypes")
- ColumnSorter<Comparable> columnSorter = new ColumnSorter<Comparable>();
+ ColumnSorter<Comparable> columnSorter = new ColumnSorter<>();
private boolean sort;
public void toTsvInternal(@SuppressWarnings("rawtypes") Comparable[][] sortedFlat, PrintWriter tsvFile) {
diff --git a/tools/java/org/unicode/cldr/tool/ToolConstants.java b/tools/java/org/unicode/cldr/tool/ToolConstants.java
index 09a1272..0904e28 100644
--- a/tools/java/org/unicode/cldr/tool/ToolConstants.java
+++ b/tools/java/org/unicode/cldr/tool/ToolConstants.java
@@ -26,7 +26,7 @@
release // for release version
}
- // TODO change this to a list of VersionInfos, add add in the ShowLocaleCoverage years.
+ // TODO change this to CldrVersion, add add in the ShowLocaleCoverage years.
public static final List<String> CLDR_VERSIONS = ImmutableList.of(
"1.1.1",
"1.2",
@@ -56,10 +56,11 @@
"35.0",
"35.1",
"36.0",
- "36.1"
+ "36.1",
+ "37.0"
// add to this once the release is final!
);
- public static final String DEV_VERSION = "37";
+ public static final String DEV_VERSION = "38";
public static final Set<String> CLDR_RELEASE_VERSION_SET = ImmutableSet.copyOf(ToolConstants.CLDR_VERSIONS);
public static final Set<String> CLDR_RELEASE_AND_DEV_VERSION_SET = ImmutableSet.<String>builder().addAll(CLDR_RELEASE_VERSION_SET).add(DEV_VERSION).build();
@@ -93,9 +94,9 @@
public static final VersionInfo PREV_CHART_VI = VersionInfo.getInstance(PREV_CHART_VERSION);
public static final String PREV_CHART_VERSION_WITH0 = PREV_CHART_VI.getVersionString(2, 2); // must have 1 decimal
- public static final ChartStatus CHART_STATUS = ChartStatus.valueOf(CldrUtility.getProperty("CHART_STATUS",
- CLDR_RELEASE_VERSION_SET.contains(CHART_VERSION)
- ? "release"
+ public static final ChartStatus CHART_STATUS = ChartStatus.valueOf(CldrUtility.getProperty("CHART_STATUS",
+ CLDR_RELEASE_VERSION_SET.contains(CHART_VERSION)
+ ? "release"
: "beta"));
public static final boolean BETA = CHART_STATUS == ChartStatus.beta;
diff --git a/tools/java/org/unicode/cldr/tool/ToolUtilities.java b/tools/java/org/unicode/cldr/tool/ToolUtilities.java
index 8b1f9fd..6f0fcbb 100644
--- a/tools/java/org/unicode/cldr/tool/ToolUtilities.java
+++ b/tools/java/org/unicode/cldr/tool/ToolUtilities.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.tool;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPathString;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -10,6 +12,7 @@
import org.unicode.cldr.util.CldrUtility;
import org.unicode.cldr.util.CldrUtility.LineComparer;
import org.unicode.cldr.util.FileReaders;
+import org.unicode.cldr.util.PathUtilities;
/**
* Utilities for CLDR tools.
@@ -58,26 +61,25 @@
if (!new File(sourceDir, sourceFile).exists()) {
File f = new File(batDir, batName);
if (f.exists()) {
- if (DEBUG_SHOW_BAT) System.out.println("*Deleting old " + f.getCanonicalPath());
+ if (DEBUG_SHOW_BAT) System.out.println("*Deleting old " + getNormalizedPathString(f));
f.delete();
}
} else if (!CldrUtility.areFileIdentical(fullSource, fullTarget, failureLines, lineComparer)) {
PrintWriter bat = FileUtilities.openUTF8Writer(batDir, batName);
try {
bat.println(CLDRPaths.COMPARE_PROGRAM + " " +
- new File(fullSource).getCanonicalPath() + " " +
- new File(fullTarget).getCanonicalPath());
+ getNormalizedPathString(fullSource) + " " + getNormalizedPathString(fullTarget));
} finally {
bat.close();
}
} else {
File f = new File(batDir, batName);
if (f.exists()) {
- if (DEBUG_SHOW_BAT) System.out.println("*Deleting old:\t" + f.getCanonicalPath());
+ if (DEBUG_SHOW_BAT) System.out.println("*Deleting old:\t" + getNormalizedPathString(f));
f.delete();
}
f = new File(fullTarget);
- if (FileUtilities.SHOW_FILES) System.out.println("*Deleting old:\t" + f.getCanonicalPath());
+ if (FileUtilities.SHOW_FILES) System.out.println("*Deleting old:\t" + getNormalizedPathString(f));
f.delete();
}
} catch (IOException e) {
diff --git a/tools/java/org/unicode/cldr/tool/VerifyAttributeValues.java b/tools/java/org/unicode/cldr/tool/VerifyAttributeValues.java
index ba9eb7a..c99e846 100644
--- a/tools/java/org/unicode/cldr/tool/VerifyAttributeValues.java
+++ b/tools/java/org/unicode/cldr/tool/VerifyAttributeValues.java
@@ -85,6 +85,7 @@
}
}
+ @Override
public void handlePathValue(String path, String value) {
XPathParts parts = XPathParts.getFrozenInstance(path);
if (dtdData == null) {
@@ -146,7 +147,6 @@
for (DayPeriod period : dayPeriods.getPeriods()) {
result.add(period.toString());
}
- ;
result.add("am");
result.add("pm");
return new LinkedHashSet<>(result);
diff --git a/tools/java/org/unicode/cldr/tool/VettingAdder.java b/tools/java/org/unicode/cldr/tool/VettingAdder.java
index c3d18f8..d9c95cc 100644
--- a/tools/java/org/unicode/cldr/tool/VettingAdder.java
+++ b/tools/java/org/unicode/cldr/tool/VettingAdder.java
@@ -27,6 +27,7 @@
import org.unicode.cldr.util.CLDRFile.DraftStatus;
import org.unicode.cldr.util.Factory;
import org.unicode.cldr.util.Log;
+import org.unicode.cldr.util.PathUtilities;
import org.unicode.cldr.util.SimpleFactory;
import org.unicode.cldr.util.XPathParts;
@@ -42,7 +43,7 @@
*/
public class VettingAdder {
- private Map<String, Set<String>> locale_files = new TreeMap<String, Set<String>>();
+ private Map<String, Set<String>> locale_files = new TreeMap<>();
private Comparator<String> scomp = new UTF16.StringComparator();
private Set<Object[]> conflictSet = new TreeSet<Object[]>(
new ArrayComparator(new Comparator[] { scomp, scomp, scomp }));
@@ -53,25 +54,25 @@
private void addFiles(String sourceDirectory) throws IOException {
File f = new File(sourceDirectory);
- String canonicalName = f.getCanonicalPath();
+ String normalizedPath = PathUtilities.getNormalizedPathString(f);
if (!f.isDirectory()) {
String name = f.getName();
if (name.startsWith("fixed-")) return; // skip
if (name.equals(".htaccess")) return; // skip
if (!name.endsWith(".xml")) {
- Log.logln("Wrong filename format: " + f.getCanonicalPath());
+ Log.logln("Wrong filename format: " + PathUtilities.getNormalizedPathString(f));
return;
}
String localeName = name.substring(0, name.length() - 4);
Set<String> s = locale_files.get(localeName);
if (s == null) {
- locale_files.put(localeName, s = new TreeSet<String>());
+ locale_files.put(localeName, s = new TreeSet<>());
}
s.add(f.getParent());
} else {
String[] subnames = f.list();
for (int i = 0; i < subnames.length; ++i) {
- addFiles(canonicalName + File.separatorChar + subnames[i]);
+ addFiles(normalizedPath + File.separatorChar + subnames[i]);
}
}
}
@@ -87,6 +88,7 @@
this.dir = dir;
}
+ @Override
public String toString() {
return "source: " + dir + ";\t value: <" + value + ">";
}
@@ -100,18 +102,19 @@
}
static Comparator PathAndValueComparator = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
return ((VettingInfo) o1).compareByPathAndValue((VettingInfo) o2);
}
};
static class VettingInfoSet {
- private Map<String, List<VettingInfo>> path_vettingInfoList = new TreeMap<String, List<VettingInfo>>();
+ private Map<String, List<VettingInfo>> path_vettingInfoList = new TreeMap<>();
public void add(String path, String dir, String fullPath, String value) {
VettingInfo vi = new VettingInfo(dir, fullPath, value);
List<VettingInfo> s = path_vettingInfoList.get(path);
- if (s == null) path_vettingInfoList.put(path, s = new ArrayList<VettingInfo>(1));
+ if (s == null) path_vettingInfoList.put(path, s = new ArrayList<>(1));
s.add(vi);
}
@@ -272,7 +275,7 @@
Log.logln("D. Missing Vetting");
Log.logln("");
- Set<String> availableLocales = new TreeSet<String>(cldrFactory.getAvailable());
+ Set<String> availableLocales = new TreeSet<>(cldrFactory.getAvailable());
availableLocales.removeAll(vettedLocales);
for (Iterator<String> it = availableLocales.iterator(); it.hasNext();) {
@@ -300,7 +303,7 @@
String lastLocale = "";
CLDRFile cldr = null;
Transliterator any_latin = Transliterator.getInstance("any-latin");
- Set<String> emails = new LinkedHashSet<String>();
+ Set<String> emails = new LinkedHashSet<>();
String[] pieces = new String[5];
for (Iterator<Object[]> it = s.iterator(); it.hasNext();) {
@@ -376,4 +379,4 @@
}
return path;
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/WritePluralRules.java b/tools/java/org/unicode/cldr/tool/WritePluralRules.java
index cf197ec..90d079d 100644
--- a/tools/java/org/unicode/cldr/tool/WritePluralRules.java
+++ b/tools/java/org/unicode/cldr/tool/WritePluralRules.java
@@ -12,15 +12,25 @@
import org.unicode.cldr.util.SupplementalDataInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Comparators;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.PluralRules;
public class WritePluralRules {
+ // Ordering by size-of-set first, and then lexicographically, with a final tie-break on the
+ // string representation.
+ private static final Comparator<PluralRules> PLURAL_RULES_COMPARATOR =
+ Comparator.<PluralRules, Integer>comparing(r -> r.getKeywords().size())
+ .thenComparing(PluralRules::getKeywords,
+ Comparators.lexicographical(Comparator.<String>naturalOrder()))
+ .thenComparing(Object::toString);
+
static SupplementalDataInfo sInfo = CLDRConfig.getInstance().getSupplementalDataInfo();
public static void main(String[] args) {
- Relation<PluralRules, String> rulesToLocales = Relation.of(new TreeMap<PluralRules, Set<String>>(new PluralRulesComparator()), TreeSet.class);
+ Relation<PluralRules, String> rulesToLocales =
+ Relation.of(new TreeMap<>(PLURAL_RULES_COMPARATOR), TreeSet.class);
for (String locale : sInfo.getPluralLocales(PluralType.cardinal)) {
if (locale.equals("root")) {
continue;
@@ -34,7 +44,7 @@
}
System.out.println(
formatPluralHeader(PluralType.cardinal, "WritePluralRules"));
- TreeSet<Entry<PluralRules, Set<String>>> sorted = new TreeSet<Entry<PluralRules, Set<String>>>(new HackComparator());
+ TreeSet<Entry<PluralRules, Set<String>>> sorted = new TreeSet<>(new HackComparator());
sorted.addAll(rulesToLocales.keyValuesSet());
for (Entry<PluralRules, Set<String>> entry : sorted) {
PluralRules rules = entry.getKey();
@@ -57,7 +67,7 @@
<pluralRule count="few">n mod 100 in 3..10</pluralRule>
<pluralRule count="many">n mod 100 in 11..99</pluralRule>
</pluralRules>
-
+
*/
}
System.out.println(formatPluralFooter());
@@ -87,7 +97,7 @@
}
public static String formatPluralRuleHeader(Set<String> values) {
- String locales = CollectionUtilities.join(values, " ");
+ String locales = Joiner.on(" ").join(values);
String result = (" <pluralRules locales=\"" + locales + "\">"
//+ (comment != null ? comment : "")
);
@@ -125,8 +135,6 @@
static class HackComparator implements Comparator<Entry<PluralRules, Set<String>>> {
// we get the order of the first items in each of the old rules, and use that order where we can.
- PluralRulesComparator prc = new PluralRulesComparator();
-
@Override
public int compare(Entry<PluralRules, Set<String>> o1, Entry<PluralRules, Set<String>> o2) {
Integer firstLocale1 = HACK_ORDER_PLURALS.get(o1.getValue().iterator().next());
@@ -139,13 +147,13 @@
} else if (firstLocale2 != null) {
return 1;
} else { // only if BOTH are null, use better comparison
- return prc.compare(o1.getKey(), o2.getKey());
+ return PLURAL_RULES_COMPARATOR.compare(o1.getKey(), o2.getKey());
}
}
}
- static Map<String, Integer> HACK_ORDER_PLURALS = new HashMap<String, Integer>();
- static Map<String, Integer> HACK_ORDER_ORDINALS = new HashMap<String, Integer>();
+ static Map<String, Integer> HACK_ORDER_PLURALS = new HashMap<>();
+ static Map<String, Integer> HACK_ORDER_ORDINALS = new HashMap<>();
static {
// int i = 0;
// for (String s : "ar he iw af asa ast az bem bez bg brx cgg chr ckb dv ee el eo es eu fo fur fy gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts uz ve vo vun wae xh xog ak bh guw ln mg nso pa ti wa ff fr hy kab lv iu kw naq se sma smi smj smn sms ga mo ro lt be cs sk pl sl mt mk cy lag shi br ksh tzm gv gd bm bo dz id in ig ii ja jbo jv jw kde kea km ko lkt lo ms my nqo sah ses sg th to vi wo yo zh fil tl ca de en et fi gl it nl sv sw ur yi ji pt da pt_PT am bn fa gu hi kn mr zu is si bs hr sh sr ru uk"
@@ -158,25 +166,10 @@
// }
}
- static class PluralRulesComparator implements Comparator<PluralRules> {
- CollectionUtilities.CollectionComparator<String> comp = new CollectionUtilities.CollectionComparator<String>();
-
- @Override
- public int compare(PluralRules arg0, PluralRules arg1) {
- Set<String> key0 = arg0.getKeywords();
- Set<String> key1 = arg1.getKeywords();
- int diff = comp.compare(key0, key1);
- if (diff != 0) {
- return diff;
- }
- return arg0.toString().compareTo(arg1.toString());
- }
- }
-
static PluralRules forLocale(String locale) {
PluralRules override = null; // PluralRulesFactory.getPluralOverrides().get(new ULocale(locale));
return override != null
? override
: sInfo.getPlurals(locale).getPluralRules();
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/tool/WritePluralRulesSpreadsheets.java b/tools/java/org/unicode/cldr/tool/WritePluralRulesSpreadsheets.java
index db644ac..bb258a3 100644
--- a/tools/java/org/unicode/cldr/tool/WritePluralRulesSpreadsheets.java
+++ b/tools/java/org/unicode/cldr/tool/WritePluralRulesSpreadsheets.java
@@ -185,12 +185,20 @@
for (String start : keywords) {
FixedDecimal small = getSample(rules, start, null); // smallest
String startPattern = getSamplePattern(samplePatterns, start);
+ if (startPattern == null) {
+ throw new NullPointerException("no startPattern: getSamplePattern(["+locale+"],"+start+") returned null"+
+ "- samplePatterns: " + samplePatterns.toString());
+ }
for (String end : keywords) {
FixedDecimal large = getSample(rules, end, small); // smallest
if (large == null) {
continue;
}
String endPattern = getSamplePattern(samplePatterns, end);
+ if (endPattern == null) {
+ throw new NullPointerException("no endPattern: getSamplePattern(["+locale+"],"+end+") returned null"+
+ "- samplePatterns: " + samplePatterns.toString());
+ }
String range = MessageFormat.format(rangePattern, small.toString(), large.toString());
Count rangeCount = pluralRanges == null ? null : pluralRanges.get(Count.valueOf(start), Count.valueOf(end));
String rangeCountPattern = rangeCount == null ? "<copy correct pattern>" : getSamplePattern(samplePatterns, rangeCount.toString());
diff --git a/tools/java/org/unicode/cldr/tool/XMLModify.java b/tools/java/org/unicode/cldr/tool/XMLModify.java
index 399237b..cf69098 100644
--- a/tools/java/org/unicode/cldr/tool/XMLModify.java
+++ b/tools/java/org/unicode/cldr/tool/XMLModify.java
@@ -57,7 +57,7 @@
private static Set<String> parse(String[] args, boolean showArguments) {
/*
* TODO: instead of the last arg below being "true", should it be "showArguments", which is otherwise unused?
- * Also myOptions.parse doesn't use its first parameter...
+ * Also myOptions.parse doesn't use its first parameter...
*/
return myOptions.parse(MyOptions.values()[0], args, true);
}
@@ -85,7 +85,7 @@
out.println("<!--" + value + " -->");
continue;
}
- XPathParts parts = XPathParts.getInstance(path); // not frozen, for setAttribute
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); // not frozen, for setAttribute
if (pathMatcher.reset(path).matches()) {
String type = parts.getAttributeValue(-1, "type");
parts.setAttribute(-1, "type", type.toLowerCase(Locale.ROOT).replaceAll("-", ""));
diff --git a/tools/java/org/unicode/cldr/tool/modify_config.txt b/tools/java/org/unicode/cldr/tool/modify_config.txt
index f2af29a..5f102ea 100644
--- a/tools/java/org/unicode/cldr/tool/modify_config.txt
+++ b/tools/java/org/unicode/cldr/tool/modify_config.txt
@@ -1,183 +1,6413 @@
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AKUAPEM"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ARANES"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ASANTE"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AUVERN"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BASICENG"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BAUDDHA"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BISCAYAN"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CISAUP"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CORNU"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CREISS"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONKIRSH"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONNAPA"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONXSAMP"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GASCON"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRCLASS"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRITAL"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRMISTR"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="HOGNORSK"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="HSISTEMO"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ITIHASA"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="IVANCHOV"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="JAUER"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="JYUTPING"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="KOCIEWIE"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LAUKIKA"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LEMOSIN"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LENGADOC"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LUNA1918"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NEWFOUND"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NICARD"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH2"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH3"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH4"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PETR1708"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PROVENC"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PUTER"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="RUMGR"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SCOUSE"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SIMPLE"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SPANGLIS"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SURMIRAN"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SURSILV"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SUTSILV"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ULSTER"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="VAIDIKA"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="VALLADER"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="VIVARAUP"]
-locale=ms; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="XSISTEMO"]
-# ms Total 48 found
-# vi ⟪Value⟫ PathHeader Org-Level
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Adlm"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Gong"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Hmnp"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Osge"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Rohg"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Wcho"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Aghb"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Bhks"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Dogr"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Elba"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Elym"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Gonm"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Hatr"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Mahj"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Maka"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Marc"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Medf"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Mult"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Nand"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Pauc"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Sidd"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Sogd"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Sogo"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Soyo"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Zanb"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ABL1943"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AKUAPEM"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AO1990"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ARANES"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ASANTE"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AUVERN"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BALANKA"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BARLA"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BASICENG"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CISAUP"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="COLB1945"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CORNU"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CREISS"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="EKAVSK"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONKIRSH"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONNAPA"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GASCON"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRCLASS"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRITAL"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRMISTR"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="HSISTEMO"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="IJEKAVSK"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="IVANCHOV"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="KOCIEWIE"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LEMOSIN"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LENGADOC"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NEWFOUND"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NICARD"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="OXENDICT"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH2"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH3"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH4"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PROVENC"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SIMPLE"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SOTAV"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SPANGLIS"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="UNIFON"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="VIVARAUP"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="XSISTEMO"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="UYW"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="UYW"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ISJ"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ISJ"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ALK"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ALK"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ILR"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="ILR"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="CNX"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="CNX"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="MVP"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="MVP"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="XSU"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="XSU"]/displayName[@count="other"]
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="XUA"]/displayName
-locale=vi; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="XUA"]/displayName[@count="other"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Gong"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Hmnp"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Rohg"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Wcho"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Chrs"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Diak"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Dogr"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Elym"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Kits"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Maka"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Medf"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Nand"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Sogd"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Sogo"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/scripts/script[@type="Yezi"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AKUAPEM"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ARANES"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="ASANTE"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="AUVERN"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BASICENG"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="BORNHOLM"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CISAUP"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CORNU"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="CREISS"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONKIRSH"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="FONNAPA"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GASCON"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRCLASS"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRITAL"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="GRMISTR"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="HSISTEMO"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="IVANCHOV"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="KOCIEWIE"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LEMOSIN"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="LENGADOC"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NEWFOUND"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="NICARD"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH2"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH3"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PAHAWH4"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="PROVENC"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SIMPLE"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="SPANGLIS"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="UNIFON"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="VIVARAUP"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/variants/variant[@type="XSISTEMO"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/types/type[@key="numbers"][@type="diak"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/types/type[@key="numbers"][@type="gong"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/types/type[@key="numbers"][@type="hmnp"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/types/type[@key="numbers"][@type="rohg"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/localeDisplayNames/types/type[@key="numbers"][@type="wcho"]
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="CNX"]/displayName
-locale=zh_Hant_HK; action=delete; value=↑↑↑; path=//ldml/numbers/currencies/currency[@type="CNX"]/displayName[@count="other"]
\ No newline at end of file
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g-kraft
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g-kraft
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acre
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hektar
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektar
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratfod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratfod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratmil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratmil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} procent
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} procent
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk mil per gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske mil per gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk mil per gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske mil per gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dag
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dage
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} time
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} timer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minut
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} måned
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} måneder
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} sekund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sekunder
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} uge
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} uger
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} år
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} år
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kalorie
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalorier
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilokalorie
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilokalorier
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tomme
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tommer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsec
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pikometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pikometer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solradius
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solradius
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yard
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solluminositet
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solluminositet
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atommasseenhed
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atommasseenheder
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jordmasse
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jordmasse
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gran
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gran
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ounce
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounces
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solmasse
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solmasse
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascal
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer i timen
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer i timen
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per sekund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per sekund
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mil i timen
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil i timen
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad celsius
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader celsius
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad fahrenheit
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader fahrenheit
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvin
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centiliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centiliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikcentimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikcentimeter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikfod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikfod
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikmil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikmil
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk standard kop
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske standard kopper
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} deciliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} deciliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk dessertske
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske dessertskeer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessertske
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessertskeer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk flydende dram
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske flydende dramme
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dråbe
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dråber
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk flydende ounce
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske flydende ounces
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} flydende ounce
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} flydende ounces
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske gallons
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} US gallon
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} US gallons
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jigger
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milliliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milliliter
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} knivspids
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} knivspidser
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pint
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pints
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk quart
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske quarts
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarts
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} spiseske
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} spiseskeer
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} teske
+locale=da; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} teskeer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meters pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meter pro Quadratsekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Grads
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="angle-degree"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Acres
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Acre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Hektars
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Hektar
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quadratzentimetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratzentimeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quadratzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratfußes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quadratfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quadratkilometern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratkilometers
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quadratkilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quadratmetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratmeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quadratmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quadratmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quadratmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quadratmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quadratmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quadratmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quadratmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Prozents
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Prozent
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Litern pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Liter pro 100 Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meile pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meilen pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meile pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Meilen pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meile pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meilen pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meile pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meilen pro britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerikanische Meile pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerikanische Meilen pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerikanischer Meile pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerikanischen Meilen pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerikanischer Meile pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerikanischer Meilen pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikanische Meile pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanische Meilen pro Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Bit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Bits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Bit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Bits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Bits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Bits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Bit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Bits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Byte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Bytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Byte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Bytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Bytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Bytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Byte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Bytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Gigabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Gigabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Gigabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Gigabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Gigabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Gigabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Gigabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Gigabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Gigabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Gigabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Gigabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Gigabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Gigabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Gigabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Gigabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Gigabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilobit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilobits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilobit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilobits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilobits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilobits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilobit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilobits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilobyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilobytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilobyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilobytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilobytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilobytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilobyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilobytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Megabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Megabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Megabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Megabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Megabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Megabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Megabit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Megabits
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Megabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Megabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Megabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Megabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Megabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Megabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Megabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Megabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Terabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Terabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Terabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Terabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Terabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Terabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Terabyte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Terabytes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Tag
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Tage
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Tag
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Tagen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Tages
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Tage
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Tag
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Tage
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Stunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Stunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Stunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Stunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Minute
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Minuten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Minute
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Minuten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Minute
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Minuten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Minute
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Minuten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Monat
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Monate
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Monat
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Monaten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Monats
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Monate
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Monat
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Monate
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Sekunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Sekunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Sekunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Sekunden
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Woche
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Wochen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Woche
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Wochen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Woche
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Wochen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Woche
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Wochen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Jahr
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Jahre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Jahr
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Jahren
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Jahrs
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Jahre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Jahr
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Jahre
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Volts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="electric-volt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Volt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilokalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilokalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilokalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilokalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilokalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilokalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilokalorie
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilokalorien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Zentimetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Zentimeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Zentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Fußes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Fuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Zolls
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Zoll
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilometern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilometers
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Metern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Meilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Millimetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Millimeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Millimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Parsec
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Pikometern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Pikometers
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Pikometer
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenradius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenradien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenradius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenradien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenradius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenradien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Sonnenradius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Sonnenradien
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Yards
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Yard
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenleuchtkraft
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenleuchtkräfte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenleuchtkraft
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenleuchtkräften
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenleuchtkraft
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenleuchtkräfte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Sonnenleuchtkraft
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Sonnenleuchtkräfte
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} atomare Masseneinheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} atomare Masseneinheiten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} atomarer Masseneinheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} atomaren Masseneinheiten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} atomarer Masseneinheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} atomarer Masseneinheiten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atomare Masseneinheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atomare Masseneinheiten
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Erdmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Erdmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Erdmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Erdmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Erdmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Erdmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Erdmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Erdmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Messerspitze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Messerspitzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Messerspitze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Messerspitzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Messerspitze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Messerspitzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Messerspitze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Messerspitzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Gramms
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Gramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilogramms
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilogramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Milligramms
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Milligramm
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Unze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Unzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Unze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Unzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Unze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Unzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Unze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Unzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Pfunds
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Pfund
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Sonnenmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Sonnenmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Sonnenmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Sonnenmasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Sonnenmassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilowatts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilowatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Megawatts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Megawatt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Watts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Watt
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilopascals
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilopascal
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kilometern pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kilometers pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kilometer pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Metern pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meters pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meter pro Sekunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Meile pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Meilen pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Meile pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Meilen pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Meile pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Meilen pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Meile pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Meilen pro Stunde
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Grads Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Grad Celsius
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Grads Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Grad Fahrenheit
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Grads
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Grad
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kelvins
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kelvin
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Zentilitern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Zentiliters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Zentiliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kubikzentimetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikzentimeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kubikzentimeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikfußes
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kubikfuß
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kubikmetern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikmeters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kubikmeter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Kubikmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Kubikmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Kubikmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Kubikmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kubikmeile
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kubikmeilen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Tasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Tassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Tasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Tassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Tasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Tassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Tasse
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Tassen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Dezilitern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Deziliters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Deziliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} britischen Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} britische Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} britischem Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} britischen Dessertlöffeln
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} britischen Dessertlöffels
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britischer Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britische Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Dessertlöffeln
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Dessertlöffels
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Dessertlöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} britisches Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} britische Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} britischem Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} britischen Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} britischen Flüssigdrams
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisches Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britische Flüssigdram
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Tropfens
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Tropfen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} britische Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} britische Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} britischer Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} britischen Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britische Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britische Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Flüssigunze
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Flüssigunzen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} britische Gallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} britischer Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} britischen Gallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Gallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britische Gallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britische Gallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerikanische Flüssiggallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerikanische Flüssiggallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerikanischer Flüssiggallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerikanischen Flüssiggallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerikanischer Flüssiggallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerikanischer Flüssiggallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikanische Flüssiggallone
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanische Flüssiggallonen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Schusses
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Schuss
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Litern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Liters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Liter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Millilitern
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Milliliters
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Milliliter
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Prise
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Prisen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Prise
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Prisen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Prise
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Prisen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Prise
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Prisen
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Pint
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Pints
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Pint
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Pints
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Pints
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Pints
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Pint
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Pints
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} britisches Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} britische Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} britischem Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} britischen Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} britischen Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} britischer Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisches Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britische Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Quart
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Quarts
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Esslöffeln
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Esslöffels
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Esslöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Teelöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Teelöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Teelöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Teelöffeln
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Teelöffels
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Teelöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Teelöffel
+locale=de; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Teelöffel
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g-force
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} G's
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per second squared
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meters per second squared
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acres
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectare
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectares
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} square centimeter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} square centimeters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} square foot
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} square feet
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} square kilometer
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} square kilometers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} square mile
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} square miles
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} percent
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} percent
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter per 100 kilometers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liters per 100 kilometers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile per gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles per gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile per gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles per gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} day
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} days
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hour
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hours
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minute
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutes
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} month
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} months
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} second
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} seconds
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} week
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} weeks
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} year
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} years
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} calorie
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calories
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilocalorie
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilocalories
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimeter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimeters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} foot
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} feet
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} inch
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} inches
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimeter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimeters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsecs
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picometer
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picometers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solar radius
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solar radii
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yards
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solar luminosity
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solar luminosities
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atomic mass unit
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atomic mass units
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} earth mass
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} earth masses
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grain
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grains
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grams
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogram
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilograms
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligram
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligrams
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ounce
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounces
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pound
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pounds
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solar mass
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solar masses
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascals
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer per hour
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometers per hour
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per second
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meters per second
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile per hour
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles per hour
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degree Celsius
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrees Celsius
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degree Fahrenheit
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrees Fahrenheit
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degree
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrees
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvins
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centiliter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centiliters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cubic centimeter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cubic centimeters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cubic foot
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cubic feet
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cubic mile
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cubic miles
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cup
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cups
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} deciliter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} deciliters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial dessert spoon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial dessert spoons
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessert spoon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessert spoons
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial fluid dram
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial fluid drams
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} drop
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} drops
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial fluid ounce
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial fluid ounces
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fluid ounce
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fluid ounces
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial gallons
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liquid gallon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liquid gallons
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jiggers
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milliliter
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milliliters
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pinch
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pinches
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pint
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pints
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial quart
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial quarts
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarts
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tablespoon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tablespoons
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} teaspoon
+locale=en; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} teaspoons
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fuerza g
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fuerzas g
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro por segundo al cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros por segundo al cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acres
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectárea
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectáreas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros cuadrados
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pie cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pies cuadrados
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilómetro cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilómetros cuadrados
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro cuadrado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros cuadrados
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla cuadrada
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas cuadradas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} por ciento
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} por ciento
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro por 100 kilómetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litros por 100 kilómetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla por galón imperial
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas por galón imperial
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla estadounidense por galón
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas estadounidenses por galón
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} bit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-bit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} bits
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} byte
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-byte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} bytes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gigabit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gigabits
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gigabyte
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gigabytes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilobit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilobits
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilobyte
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilobytes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} megabit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} megabits
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} megabyte
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} megabytes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} terabyte
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} terabytes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} día
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} días
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hora
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} horas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minuto
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mes
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meses
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} segundo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} segundos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} semana
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} semanas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} año
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} años
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} caloría
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calorías
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilocaloría
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilocalorías
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pie
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pies
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pulgada
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pulgadas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilómetro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilómetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milímetro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milímetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pársec
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pársecs
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picómetro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picómetros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} radio solar
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} radios solares
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yarda
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yardas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} luminosidad solar
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} luminosidades solares
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dalton
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dalton
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masa terrestre
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masas terrestres
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grano
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} granos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gramo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gramos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogramo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogramos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miligramo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miligramos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onza
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onzas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} libra
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} libras
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masa solar
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masas solares
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilovatio
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-kilowatt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilovatios
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} megavatio
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-megawatt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} megavatios
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vatio
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="power-watt"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vatios
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascales
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilómetro por hora
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilómetros por hora
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro por segundo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros por segundo
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla por hora
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas por hora
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado Celsius
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grados Celsius
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado Fahrenheit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grados Fahrenheit
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grados
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kelvin
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kelvin
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centilitro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centilitros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro cúbico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros cúbicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pie cúbico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pies cúbicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pulgada cúbica
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pulgadas cúbicas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilómetro cúbico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilómetros cúbicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro cúbico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros cúbicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milla cúbica
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millas cúbicas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} taza
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tazas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} decilitro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decilitros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucharada de postre imperial
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucharadas de postre imperiales
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucharada de postre
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucharadas de postre
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dracma líquido británico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dracmas líquidos británicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gota
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gotas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onza líquida británica
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onzas líquidas británicas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onza líquida estadounidense
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onzas líquidas estadounidenses
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} galón imperial
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galones imperiales
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} galón
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galones
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectolitro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectolitros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jiggers
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mililitro
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mililitros
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pizca
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pizcas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pinta estadounidense
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pintas estadounidenses
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuarto británico
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cuartos británicos
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuarto estadounidense
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cuartos estadounidenses
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucharada
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucharadas
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucharada
+locale=es; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucharadas
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mètre par seconde carrée
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectare
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectare
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimètre carré
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pied carré
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilomètre carré
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilomètres carrés
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mille carré
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milles carrés
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pour cent
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pour cent
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litre aux 100 kilomètres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mille par gallon impérial
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mille par gallon américain
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jour
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jours
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} heure
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} heures
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minute
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutes
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mois
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mois
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} seconde
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} secondes
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} semaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} semaines
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} année
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} années
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} calorie
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calories
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilocalorie
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilocalories
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimètre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimètres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pied
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pieds
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pouce
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pouces
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilomètre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilomètres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mètre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mètres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimètre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimètres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picomètre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} rayon solaire
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yards
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} luminosité solaire
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} unité de masse atomique unifiée
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masse terrestre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grain
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grains
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gramme
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grammes
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilo
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilos
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligramme
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} once
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onces
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} livre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} livres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masse solaire
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilomètre par heure
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilomètres par heure
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mètre par seconde
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mètres par seconde
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mille par heure
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milles par heure
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degré Celsius
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrés Celsius
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degré Fahrenheit
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrés Fahrenheit
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} degré
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} degrés
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvins
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centilitre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centilitres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimètre cube
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimètres cubes
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pied cube
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mille cube
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tasse américaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tasses américaines
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} décilitre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} décilitres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuillère à dessert impériale
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuillère à dessert
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} drachme impériale
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} goutte
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gouttes
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} once liquide impériale
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} once liquide américaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onces liquides américaines
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gallon impérial
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gallon américain
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} shot
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} shots
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millilitre
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millilitres
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pincée
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pincées
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pinte américaine liquide
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pintes américaines liquides
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart impérial
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart américain
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarts américains
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuillère à soupe américaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cuillères à soupe américaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cuillère à café américaine
+locale=fr; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cuillères à café américaines
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} गुरुत्वाकर्षण बल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} गुरुत्वाकर्षण बल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} गुरुत्वाकर्षण बल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} गुरुत्वाकर्षण बल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मीटर प्रति वर्ग सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मीटर प्रति वर्ग सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर प्रति वर्ग सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर प्रति वर्ग सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} एकड़
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} एकड़
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} एकड़
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} एकड़
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} हेक्टेयर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} हेक्टेयर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} हेक्टेयर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} हेक्टेयर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} वर्ग सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} वर्ग सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} वर्ग फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} वर्ग फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} वर्ग किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} वर्ग किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} वर्ग मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} वर्ग मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} वर्ग मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} प्रतिशत
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} प्रतिशत
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} प्रतिशत
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} प्रतिशत
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} 100 किलोमीटर प्रति लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 100 किलोमीटर प्रति लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} 100 किलोमीटर प्रति लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} 100 किलोमीटर प्रति लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} दिन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} दिन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} दिन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} दिन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} घंटे
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} घंटे
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} घंटों
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मिनट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मिनट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मिनट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मिनट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} महीना
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} महीने
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} महीने
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} महीनो
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सेकेंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सेकेंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सेकेंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सेकेंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सप्ताह
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सप्ताह
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सप्ताह
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सप्ताह
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} साल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} साल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} साल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} साल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} कैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} कैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} कैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} कैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} किलोकैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} किलोकैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} किलोकैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} किलोकैलोरी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} इंच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} इंच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} इंच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} इंच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} किलोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मिलीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मिलीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} पारसैक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} पारसैक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} पारसैक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} पारसैक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} पिकोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} पिकोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} पिकोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} पिकोमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सौर अर्धव्यास
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सौर अर्धव्यास
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सौर अर्धव्यास
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सौर अर्धव्यास
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} गज
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} गज
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} गज
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} गज
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सौर ज्योति
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सौर ज्योति
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सौर ज्योति
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सौर ज्योति
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} एकीकृत परमाण्वीय द्रव्यमान मात्रक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} एकीकृत परमाण्वीय द्रव्यमान मात्रक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} एकीकृत परमाण्वीय द्रव्यमान मात्रक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} एकीकृत परमाण्वीय द्रव्यमान मात्रक
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} पृथ्वी द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} पृथ्वी द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} पृथ्वी द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} पृथ्वी द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डेढ़ रत्ती
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डेढ़ रत्ती
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डेढ़ रत्ती
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डेढ़ रत्ती
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} ग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} ग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} किलोग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} किलोग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} किलोग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} किलोग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मिलीग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मिलीग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीग्राम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} आउन्स
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} आउन्स
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} आउन्स
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} आउन्स
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} पाउंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} पाउंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} पाउंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} पाउंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सौर द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सौर द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सौर द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सौर द्रव्यमान
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} किलोपास्कल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} किलोपास्कल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} किलोपास्कल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} किलोपास्कल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} किलोमीटर प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} किलोमीटर प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} किलोमीटर प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} किलोमीटर प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मीटर प्रति सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मीटर प्रति सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर प्रति सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मीटर प्रति सेकंड
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मील प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मील प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मील प्रति घंटा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डिग्री सेल्सियस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डिग्री सेल्सियस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री सेल्सियस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री सेल्सियस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डिग्री फॉरेन्हाइट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डिग्री फॉरेन्हाइट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री फॉरेन्हाइट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री फॉरेन्हाइट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डिग्री
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डिग्री
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डिग्री
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} केल्विन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} केल्विन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} केल्विन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} केल्विन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} सेंटीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} सेंटीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} सेंटीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} सेंटीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} घन सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} घन सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} घन सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} घन सेंटीमीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} घन फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} घन फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} घन फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} घन फुट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} घन मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} घन मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} घन मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} घन मील
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} यूएस प्याला
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} यूएस प्याला
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस प्याला
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस प्याला
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डेसीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डेसीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डेसीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डेसीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} इम्पीरियल डेज़र्टस्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} इम्पीरियल डेज़र्टस्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} इम्पीरियल डेज़र्टस्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} इम्पीरियल डेज़र्टस्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} डेज़र्ट स्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} डेज़र्ट स्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} डेज़र्ट स्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} डेज़र्ट स्पून
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} इम्पीरियल तरल ड्रम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} इम्पीरियल तरल ड्रम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} इम्पीरियल तरल ड्रम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} इम्पीरियल तरल ड्रम
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} बूंद
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} बूंद
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} बूंद
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} बूंद
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} द्रव औंस शाही
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} द्रव औंस शाही
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} द्रव औंस शाही
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} द्रव औंस शाही
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} अमरीकी तरल आउंस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} अमरीकी तरल आउंस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} अमरीकी तरल आउंस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} अमरीकी तरल आउंस
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} इंपीरियल गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} इंपीरियल गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} इंपीरियल गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} इंपीरियल गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} यूएस गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} यूएस गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस गैलन
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} जिगर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} जिगर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} जिगर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} जिगर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} लीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} मिलीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} मिलीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} मिलीलीटर
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} चुटकी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} चुटकी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} चुटकी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} चुटकी
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} अमेरिकी पाइंट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} अमेरिकी पाइंट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} अमेरिकी पाइंट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} अमेरिकी पाइंट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} क्वार्ट इम्पीरियल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} क्वार्ट इम्पीरियल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} क्वार्ट इम्पीरियल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} क्वार्ट इम्पीरियल
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} यूएस क्वार्ट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} यूएस क्वार्ट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस क्वार्ट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} यूएस क्वार्ट
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} चमचा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} चमचा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} चमचा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} चमचा
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} छोटी चम्मच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} छोटी चम्मच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="oblique"][@draft="provisional"]; new_value={0} छोटी चम्मच
+locale=hi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="oblique"][@draft="provisional"]; new_value={0} छोटी चम्मच
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g-force
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per detik kuadrat
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ekar
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektare
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sentimeter persegi
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kaki persegi
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer persegi
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil persegi
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} persen
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil per galon imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil per galon Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hari
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jam
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} menit
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} bulan
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} detik
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minggu
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tahun
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalori
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilokalori
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sentimeter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kaki
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} inci
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milimeter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsek
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pikometer
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} radius Matahari
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yard
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} luminositas Matahari
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dalton
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} massa Bumi
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grain
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gram
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogram
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miligram
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ons
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pon
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} massa Matahari
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascal
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer per jam
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per detik
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil per jam
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} derajat Celsius
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} derajat Fahrenheit
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} derajat
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kelvin
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sentiliter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sentimeter kubik
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kaki kubik
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil kubik
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cangkir Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} desiliter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sendok dessert imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sendok dessert
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dram cairan imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tetes
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ons cairan imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ons cairan Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galon imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galon Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jigger
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mililiter
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jumput
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pint Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kuart imperial
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kuart Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sendok makan Amerika
+locale=id; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sendok teh Amerika
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro al secondo quadrato
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metri al secondo quadrato
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ettaro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ettari
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimetro quadrato
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimetri quadrati
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} piede quadrato
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} piedi quadrati
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilometro quadrato
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilometri quadrati
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio quadro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia quadre
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} percento
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} percento
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro per cento chilometri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litri per cento chilometri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio per gallone imperiale
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia per gallone imperiale
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio per gallone americano
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia per gallone americano
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} giorno
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} giorni
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ora
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ore
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minuto
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minuti
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mese
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mesi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} secondo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} secondi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} settimana
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} settimane
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} anno civile
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} anni civili
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} caloria
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calorie
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilocaloria
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilocalorie
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimetro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimetri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} piede
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} piedi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pollice
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pollici
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilometro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilometri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimetro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimetri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsec
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picometro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picometri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} raggio solare
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} raggi solari
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} iarda
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} iarde
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} luminosità solare
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} luminosità solari
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} unità di massa atomica
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} unità di massa atomica
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} massa terrestre
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masse terrestri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grano
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grani
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grammo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grammi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilogrammo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilogrammi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligrammo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligrammi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} oncia
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} once
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} libbra
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} libbre
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} massa solare
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masse solari
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilopascal
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilopascal
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilometro orario
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilometri orari
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro al secondo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metri al secondo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio orario
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia orarie
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado Celsius
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gradi Celsius
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado Fahrenheit
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gradi Fahrenheit
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gradi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grado Kelvin
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gradi Kelvin
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-acre-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} piede acro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-acre-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} piedi acri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-barrel"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} barile
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-barrel"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} barili
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centilitro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centilitri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimetro cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimetri cubi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} piede cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} piedi cubi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pollice cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pollici cubi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chilometro cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chilometri cubi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metri cubi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miglio cubo
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miglia cube
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tazza
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tazze
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} decilitro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decilitri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucchiaio
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucchiai
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucchiaino da dessert
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucchiaini da dessert
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dramma
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dramme
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} goccia
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gocce
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} oncia
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} once
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} oncia
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} once
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gallone imperiale
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galloni imperiali
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gallone americano
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galloni americani
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ettolitro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ettolitri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jigger
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millilitro
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millilitri
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pizzico
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pizzichi
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pinta
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pinte
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quarto imperiale
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarti imperiali
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quarto di gallone
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarti di gallone
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucchiaio
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucchiai
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cucchiaino
+locale=it; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cucchiaini
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} G
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} メートル毎秒毎秒
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} エーカー
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ヘクタール
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 平方センチメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 平方フィート
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 平方キロメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 平方マイル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} パーセント
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} リットル毎100キロメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} マイル毎英ガロン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} マイル毎米ガロン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 日
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 時間
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 分
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} か月
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 秒
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 週
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 年
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} カロリー
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} キロカロリー
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} センチメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} フィート
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} インチ
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} キロ
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} メートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} マイル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ミリ
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} パーセク
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ピコメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 太陽半径
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ヤード
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 太陽光度
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ダルトン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 地球質量
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} グレーン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} グラム
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} キログラム
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ミリグラム
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} オンス
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ポンド
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 太陽質量
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} キロパスカル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} キロメートル毎時
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} メートル毎秒
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} マイル毎時
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 度
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 度
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 度
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ケルビン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} センチリットル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 立方センチメートル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 立方フィート
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 立方マイル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} アメリカカップ
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} デシリットル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 英デザートスプーン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} デザートスプーン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 英液量ドラム
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 滴
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 英液量オンス
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米液量オンス
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 英ガロン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米液量ガロン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ジガー
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} リットル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ミリリットル
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} つまみ
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米液量パイント
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 英クォート
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米液量クォート
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米テーブルスプーン
+locale=ja; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} 米ティースプーン
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}중력가속도
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미터 퍼 세크 제곱
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}에이커
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}헥타르
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}제곱센티미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}제곱피트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}제곱킬로미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}제곱마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}백분율
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}100킬로미터당 리터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 갤런당 마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}갤런당 마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}시간
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}분
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}개월
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}초
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}주
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}년
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}칼로리
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}킬로칼로리
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}센티미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}피트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}인치
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}킬로미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}밀리미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}파섹
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}피코미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}태양반경
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}야드
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}태양광도
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}돌턴
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}지구질량
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}그레인
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}그램
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}킬로그램
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}밀리그램
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}온스
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}파운드
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}태양질량
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}킬로파스칼
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}시간당 킬로미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}초당 미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}시간당 마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}섭씨
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}화씨
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}도
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}켈빈
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}센티리터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}세제곱센티미터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}세제곱피트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}세제곱마일
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}컵
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}데시리터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 디저트스푼
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}디저트스푼
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 액량 드램
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}방울
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 액량 온스
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미국 액량 온스
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 갤런
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미국 액량 갤런
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}지거
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}리터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}밀리리터
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}꼬집
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미국 액량 파인트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}영국 쿼트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}미국 액량 쿼트
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}큰술
+locale=ko; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}작은술
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g-kraft
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g-krefter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acre
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hektar
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektar
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratfot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratfot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelsk kvadratmil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelske kvadratmil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} prosent
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} prosent
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk mil per gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske mil per gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk mile per gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske miles per gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dag
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dager
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} time
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} timer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minutt
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} måned
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} måneder
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} sekund
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sekunder
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} uke
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} uker
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kalenderår
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalenderår
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kalori
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalorier
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilokalori
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilokalorier
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-decimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} desimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-decimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} desimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tomme
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tommer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile-scandinavian"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile-scandinavian"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelsk mil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelske mil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsec
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pikometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pikometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solradius
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solradier
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yard
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solluminositet
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solluminositeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atommasseenhet
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atommasseenheter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jordmasse
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jordmasser
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grain
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grain
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ounce
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounces
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pound
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pounds
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solmasse
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} solmasse
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascal
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer i timen
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer i timen
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter i sekundet
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter i sekundet
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile i timen
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles i timen
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad celsius
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader celsius
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad fahrenheit
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader fahrenheit
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvin
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-barrel"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} oljefat
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-barrel"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} oljefat
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centiliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centiliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikkcentimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikkcentimeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikkfot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikkfot
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikktomme
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikktommer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikkilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikkilometer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikkmeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikkmeter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikkmil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikkmil
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup-metric"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metrisk cup
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup-metric"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metriske cups
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk cup
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske cups
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} desiliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} desiliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk dessertskje
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske dessertskjeer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessertskje
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessertskjeer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk flytende dram
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske flytende drammer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dråpe
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dråper
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk flytende ounce
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske flytende ounces
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk ounce
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske ounces
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske gallons
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk gallon
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske gallons
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hektoliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-hectoliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektoliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigg
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jigg
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milliliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milliliter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} klype
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} klyper
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk pint
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske pints
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} britisk quart
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} britiske quarts
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk kvart
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske kvarter
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk spiseskje
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske spiseskjeer
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk teskje
+locale=nb; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanske teskjeer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g-kracht
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g-kracht
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per seconde kwadraat
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per seconde kwadraat
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acre
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectare
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectares
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vierkante centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vierkante centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vierkante voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vierkante voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vierkante kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vierkante kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vierkante mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vierkante mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} procent
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} procent
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mijl per imperial gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mijl per imperial gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mijl per US gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mijl per US gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dag
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dagen
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minuut
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minuten
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} maand
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} maanden
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} seconde
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} seconden
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} week
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} weken
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jaar
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jaar
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} calorie
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calorieën
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilocalorie
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilocalorieën
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} inch
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} inch
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsecs
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picometer
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} zonneradius
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} zonneradius
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yard
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} zonnelichtkracht
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} zonnelichtkracht
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atomaire massa-eenheid
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atomaire massa-eenheden
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} aardmassa
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} aardmassa's
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} korrel
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} korrels
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligram
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ons
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ons
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pond
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pond
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} zonsmassa
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} zonsmassa's
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascal
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer per uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer per uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per seconde
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per seconde
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mijl per uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mijl per uur
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} graad Celsius
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graden Celsius
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} graad Fahrenheit
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graden Fahrenheit
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} graad
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graden
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Kelvin
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kelvin
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centiliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centiliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubieke centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubieke centimeter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubieke voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubieke voet
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubieke mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubieke mijl
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kopje
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kopjes
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} deciliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} deciliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessertlepel (imperiale systeem)
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessertlepels (imperiale systeem)
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessertlepel
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessertlepels
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vloeistof drachm
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} vloeistof drachm
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} druppel
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} druppels
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Britse vloeistof-ounce
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Britse vloeistof-ounces
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Amerikaanse fluid ounce
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperial gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperial gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Amerikaanse liquid gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Amerikaanse liquid gallon
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jiggers
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milliliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milliliter
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} snufje
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} snufjes
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pint
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pinten
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarts
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Amerikaanse liquid quart
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} eetlepel
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} eetlepels
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} theelepel
+locale=nl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} theelepels
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} metr na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} metrom na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} metrowi na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} metrom na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} metrów na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} metra na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} metrów na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} metrem na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} metrach na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} metrze na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} metrach na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metr na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} metrze na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} metry na sekundę do kwadratu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} akr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} akrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} akrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} akrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} akrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} akra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} akrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} akrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} akrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} akrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} akrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} akrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} akrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} akr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} akrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} akry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} hektar
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} hektarom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} hektarowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} hektarom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} hektarów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} hektara
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} hektarów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} hektarami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} hektarem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} hektarami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} hektarach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} hektarze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} hektarach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hektar
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} hektarze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} hektary
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} centymetr kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} centymetrowi kwadratowemu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} centymetra kwadratowego
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrem kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} centymetrze kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centymetr kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} centymetrze kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopy kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopę kwadratową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopy kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopie kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stóp kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopy kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stóp kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopą kwadratową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopie kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopy kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopa kwadratowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopy kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopy kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopo kwadratowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopy kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilometr kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilometrowi kwadratowemu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilometra kwadratowego
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrem kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilometrze kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometr kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilometrze kwadratowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę kwadratową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom kwadratowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą kwadratową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami kwadratowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach kwadratowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili kwadratowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila kwadratowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo kwadratowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile kwadratowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} procent
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} procentom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} procentowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} procentom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} procentów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} procentu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} procentów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} procentami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} procentem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} procentami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} procentach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} procencie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} procentach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} procent
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} procencie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} procenty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} litr na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} litrom na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} litrowi na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} litrom na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} litrów na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} litra na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} litrów na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} litrami na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} litrem na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} litrami na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} litrach na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} litrze na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} litrach na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litr na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} litrze na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} litry na 100 kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile na galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile na galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} dobę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} dobom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} dobie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} dobom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} dób
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} dób
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} dobami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} dobą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} dobami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} dobach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} dobie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} dobach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} doba
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} dobo
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} doby
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} godzinom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} godzinie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} godzinom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} godzin
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} godzin
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} godzinami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} godziną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} godzinami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} godzinach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} godzinie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} godzinach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} godzina
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} godzino
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} godziny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} minutę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} minutom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} minucie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} minutom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} minut
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} minut
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} minutami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} minutą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} minutami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} minutach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} minucie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} minutach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minuta
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} minuto
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} minuty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} miesiąc
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} miesiącom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} miesiącowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} miesiącom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} miesięcy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} miesiąca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} miesięcy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} miesiącami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} miesiącem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} miesiącami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} miesiącach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} miesiącu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} miesiącach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miesiąc
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} miesiącu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} miesiące
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} sekundom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} sekundzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} sekundom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} sekund
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} sekund
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} sekundami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} sekundą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} sekundami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} sekundach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} sekundzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} sekundach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} sekunda
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} sekundo
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} sekundy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} tydzień
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} tygodniom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} tygodniowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} tygodniom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} tygodni
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} tygodnia
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} tygodni
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} tygodniami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} tygodniem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} tygodniami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} tygodniach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} tygodniu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} tygodniach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tydzień
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} tygodniu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} tygodnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} rok kalendarzowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} lata kalendarzowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} latom kalendarzowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} rokowi kalendarzowemu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} latom kalendarzowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} lat kalendarzowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} roku kalendarzowego
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} lat kalendarzowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} latami kalendarzowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} rokiem kalendarzowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} latami kalendarzowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} latach kalendarzowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} roku kalendarzowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} latach kalendarzowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} rok kalendarzowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} lata kalendarzowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} lata kalendarzowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} roku kalendarzowy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} lata kalendarzowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kalorię
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kaloriom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kaloriom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kaloriami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kalorią
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kaloriami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kaloriach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kaloriach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kaloria
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kalorio
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilokalorię
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilokalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilokaloriom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilokaloriom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilokaloriami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilokalorią
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilokaloriami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilokaloriach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilokaloriach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilokalorii
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilokaloria
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilokalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilokalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilokalorio
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilokalorie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} centymetr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} centymetrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} centymetra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} centymetrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centymetr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} centymetrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stóp
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stóp
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopo
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} cal
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} calom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} calowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} calom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} calów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} cala
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} calów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} calami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} calem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} calami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} calach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} calu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} calach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cal
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} calu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} cale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilometr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilometrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilometra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilomentrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilometrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilometrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} metr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} metrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} metrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} metrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} metrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} metra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} metrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} metrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} metrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} metrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} metrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} metrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} metry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili międzynarodowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę międzynarodową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile międzynarodowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom międzynarodowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili międzynarodowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom międzynarodowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil międzynarodowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili międzynarodowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil międzynarodowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami międzynarodowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą międzynarodową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami międzynarodowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach międzynarodowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili międzynarodowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach międzynarodowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili międzynarodowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila międzynarodowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile międzynarodowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile międzynarodowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo międzynarodowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile międzynarodowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milimetr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milimetrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} milimetrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milimetrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} milimetrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} milimetra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} milimetrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milimetrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milimentrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milimetrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milimetrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} milimetrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milimetrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milimetr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milimetrrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} milimetry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} parsek
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} parsekom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} parsekowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} parsekom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} parseków
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} parseka
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} parseków
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} parsekami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} parsekiem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} parsekami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} parsekach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} parseku
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} parsekach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsek
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} parseku
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} parseki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} pikometr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} pikometrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} pikometrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} pikometrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} pikometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} pikometra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} pikometrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} pikometrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} pikometrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} pikometrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} pikometrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} pikometrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} pikometrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pikometr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} pikometrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} pikometry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} promień Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} promieniom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} promieniowi Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} promieniom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} promieni Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} promienia Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} promieni Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} promieniami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} promieniem Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} promieniami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} promieniach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} promieniu Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} promieniach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} promień Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} promieniu Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} promienie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} jard
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} jardy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} jardom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} jardowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} jardom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} jardów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} jardu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} jardów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} jardami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} jardem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} jardami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} jardach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} jardach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jard
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jardy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} jardzie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} jasność Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} jasnościom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} jasnościom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} jasnościami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} jasnością Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} jasnościami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} jasnościach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} jasnościach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jasność Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} jasności Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} jednostkę masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} jednostkom masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} jednostce masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} jednostkom masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} jednostek masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} jednostek masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} jednostkami masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} jednostką masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} jednostkami masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} jednostkach masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} jednostce masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} jednostkach masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jednostka masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} jednostko masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} jednostki masy atomowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} masę Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} masom Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} masie Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} masom Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mas Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mas Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} masami Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} masą Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} masami Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} masach Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} masie Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} masach Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masa Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} maso Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} masy Ziemi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} gran
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} granom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} granowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} granom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} granów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} grana
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} granów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} granami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} granem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} granami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} granach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} granie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} granach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gran
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} granie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} grany
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} gram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} gramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} gramowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} gramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} gramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} grama
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} gramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} gramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} gramem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} gramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} gramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} gramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} gramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} gramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} gramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilogram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilogramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilogramowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilogramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilogramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilograma
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilogramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilogramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilogramem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilogramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilogramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilogramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilogramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilogram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilogramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilogramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} miligram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} miligramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} miligramowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} miligramom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} miligramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} miligrama
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} miligramów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} miligramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} miligramem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} miligramami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} miligramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} miligramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} miligramach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miligram
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} miligramie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} miligramy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} uncję
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} uncje
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} uncjom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} uncjom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} uncjami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} uncją
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} uncjami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} uncjach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} uncjach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} uncji
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} uncja
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} uncje
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} uncje
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} uncjo
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} uncje
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} funt
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} funtom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} funtowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} funtom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} funtów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} funta
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} funtów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} funtami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} funtem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} funtami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} funtach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} funcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} funtach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} funt
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} funcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} funty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} masę Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} masom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} masie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} masom Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mas Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mas Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} masami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} masą Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} masami Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} masach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} masie Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} masach Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} masa Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} maso Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} masy Słońca
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilopaskal
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilopaskalom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilopaskalowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilopaskalom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilopaskali
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilopaskala
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilopaskali
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilopaskalami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilopaskalem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilopaskalami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilopaskalach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilopaskalu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilopaskalach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopaskal
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilopaskalu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilopaskale
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kilometr na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kilometrowi na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kilometrom na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kilometra na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kilometrów na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrem na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kilometrami na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kilometrze na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kilometrach na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometr na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kilometrze na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kilometry na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} metr na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} metrom na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} metrowi na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} metrom na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} metrów na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} metra na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} metrów na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} metrem na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} metrami na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} metrach na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} metrze na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} metrach na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metr na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} metrze na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} metry na sekundę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile na godzinę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopień Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopniom Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopniowi Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopniom Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stopni Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopnia Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stopni Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniem Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopniach Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopniu Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopniach Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopień Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopniu Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie Celsjusza
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopień Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopniom Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopniowi Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopniom Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stopni Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopnia Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stopni Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniem Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopniach Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopniu Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopniach Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopień Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopniu Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie Fahrenheita
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopień
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopniom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopniowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopniom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stopni
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopnia
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stopni
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopniami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopniach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopniu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopniach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopień
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopniu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopnie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kelwin
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kelwinom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kelwinowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kelwinom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kelwinów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kelwina
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kelwinów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kelwinami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kelwinem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kelwinami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kelwinach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kelwinie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kelwinach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelwin
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kelwinie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kelwiny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} centylitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} centylitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} centylitrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} centylitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} centylitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} centylitra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} centylitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} centylitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} centylitrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} centylitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} centylitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} centylitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} centylitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centylitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} centylitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} centylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} centymetr sześcienny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} centymetrowi sześciennemu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} centymetrom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} centymetra sześciennego
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} centymetrów sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrem sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} centymetrami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} centymetrze sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} centymetrach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centymetr sześcienny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} centymetrze sześcienny
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} centymetry sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} stopy sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} stopę sześcienną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} stopy sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} stopom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} stopie sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} stopom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} stóp sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} stopy sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} stóp sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} stopą sześcienną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} stopami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} stopach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} stopie sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} stopach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} stopy sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} stopa sześcienna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} stopy sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} stopy sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} stopo sześcienna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} stopy sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mili sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} milę sześcienną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mile sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} milom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mili sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} milom sześciennym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mil sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mili sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mil sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} milami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} milą sześcienną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} milami sześciennymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} milach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mili sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} milach sześciennych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mili sześciennej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mila sześcienna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mile sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mile sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} milo sześcienna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mile sześcienne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskiej szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańską szklankę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskie szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim szklankom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskiej szklance
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim szklankom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich szklanek
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskiej szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich szklanek
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi szklankami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańską szklanką
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi szklankami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich szklankach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskiej szklance
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich szklankach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} amerykańskiej szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerykańska szklanka
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerykańskie szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańska szklanko
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie szklanki
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} decylitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} decylitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} decylitrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} decylitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} decylitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} decylitra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} decylitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} decylitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} decylitrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} decylitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} decylitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} decylitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} decylitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} decylitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} decylitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} decylitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} imperialnej łyżeczki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} imperialną łyżeczkę deserową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} imperialne łyżeczki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} imperialnym łyżeczkom deserowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} imperialnej łyżeczkce deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} imperialnym łyżeczkom deserowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} imperialnych łyżeczek deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} imperialnej łyżeczki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} imperialnych łyżeczek deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} imperialnymi łyżeczkami deserowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} imperialną łyżeczką deserową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} imperialnymi łyżeczkami deserowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} imperialnych łyżeczkach deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} imperialnej łyżeczce deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} imperialnych łyżeczkach deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} imperialnej łyżeczki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} imperialna łyżeczka deserowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} imperialne łyżeczki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} imperialne łyżeczki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} imperialna łyżeczko deserowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} imperialne łyżeczki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} łyżki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} łyżkę deserową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} łyżki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} łyżkom deserowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} łyżce deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} łyżkom deserowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} łyżek deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} łyżki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} łyżek deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżkami deserowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżką deserową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżkami deserowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} łyżkach deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} łyżce deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} łyżkach deserowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} łyżki deserowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} łyżka deserowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} łyżki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} łyżki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} łyżko deserowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} łyżki deserowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} drachmy płynnej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} drachmę płynną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} drachmy płynne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} drachmom płynnym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} drachmie płynnej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} drachmom płynnym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} drachm płynnych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} drachmy płynnej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} drachm płynnych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} drachmami płynnymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} drachmą płynną
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} drachmami płynnymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} drachmach płynnych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} drachmie płynnej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} drachmach płynnych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} drachmy płynnej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} drachma płynna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} drachmy płynne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} drachmy płynne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} drachmo płynna
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} drachmy płynne
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kropli
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kroplę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} krople
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kroplom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kropli
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kroplom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kropel
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kropli
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kropel
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kroplami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kroplą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kroplami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kroplach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kropli
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kroplach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kropli
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kropla
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} krople
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} krople
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kroplo
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} krople
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjską uncję cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskim uncjom cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskim uncjom cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskich uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskich uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjskimi uncjami cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjską uncją cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjskimi uncjami cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskicj uncjach cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskicj uncjach cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} brytyjskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brytyjska uncja cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brytyjskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjska uncjo cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańską uncję cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim uncjom cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim uncjom cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi uncjami cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańską uncją cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi uncjami cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich uncjach cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich uncjach cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} amerykańskiej uncji cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerykańska uncja cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerykańskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańska uncjo cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie uncje cieczy
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} angielski galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} angielskim galonom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} angielskiemu galonowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} angielskim galonom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} angielskich galonów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} angielskiego galonu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} angielskich galonów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} angielskimi galonami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} angielskim galonem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} angielskimi galonami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} angielskich galonach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} angielskim galonie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} angielskich galonach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} angielski galon
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} angielski galonie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} angielskie galony
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} galonom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} galonowi amerykańskiemu
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} galonom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} galonów amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} galona amerykańskiego
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} galonów amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} galonami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} galonem amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} galonami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} galonach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} galonie amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} galonach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} galon amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} galonie amerykański
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} galony amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} jigger
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} jiggerom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} jiggerowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} jiggerom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} jiggerów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} jiggera
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} jiggerów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} jiggerami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} jiggerem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} jiggerami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} jiggerach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} jiggerze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} jiggerach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} jiggerze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} jiggery
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} litr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} litrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} litrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} litrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} litrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} litra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} litrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} litrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} litrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} litrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} litrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} litrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} litrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} litrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} litry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} mililitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} mililitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} mililitrowi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} mililitrom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} mililitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} mililitra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} mililitrów
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} mililitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} mililitrem
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} mililitrami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} mililitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} mililitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} mililitrach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mililitr
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} mililitrze
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} mililitry
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} szczyptę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} szczyptom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} szczypcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} szczyptom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} szczypt
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} szczypt
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} szczyptami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} szczyptą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} szczyptami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} szczyptach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} szczypcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} szczyptach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} szczypta
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} szczypto
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} szczypty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskiej pinty mokrej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańską pintę mokrą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskie pinty mokre
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim pintom mokrym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskiej pincie mokrej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim pintom mokrym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich pint mokrych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskiej pinty mokrej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich pint mokrych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi pintami mokrymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańską pintą mokrą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi pintami mokrymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich pintach mokrych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskiej pincie mokrej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich pintach mokrych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} amerykańskiej pinty mokrej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerykańska pinta mokra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerykańskie pinty mokre
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie pinty mokre
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańska pinto mokra
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie pinty mokre
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjskiej kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjską kwartę
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} brytyjskie kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskim kwartom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskiej kwarcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} brytyjskim kwartom
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskich kwart
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskiej kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} brytyjskich kwart
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjskimi kwartami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjską kwartą
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} brytyjskimi kwartami
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskich kwartach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskiej kwarcie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} brytyjskich kwartach
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} brytyjskiej kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brytyjska kwarta
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brytyjskie kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjskie kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjska kwarto
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} brytyjskie kwarty
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} kwarty amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} kwartę amerykańską
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} kwarty amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} kwartom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} kwarcie amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} kwartom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} kwart amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} kwarty amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} kwart amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} kwartami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} kwartą amerykańską
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} kwartami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} kwartach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} kwarcie amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} kwartach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} kwarty amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kwarta amerykańska
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kwarty amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} kwarty amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} kwarto amerykańska
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} kwarty amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskiej łyżki stołowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańską łyżkę stołową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} amerykańskie łyżki stołowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim łyżkom stołowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskiej łyżce stołowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} amerykańskim łyżkom stołowym
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich łyżek stołowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskiej łyżki stołowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} amerykańskich łyżek stołowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi łyżkami stołowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańską łyżką stołową
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} amerykańskimi łyżkami stołowymi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich łyżkach stołowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskiej łyżce stołowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} amerykańskich łyżkach stołowych
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} amerykańskiej łyżki stołowej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerykańska łyżka stołowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerykańskie łyżki stołowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie łyżki stołowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańska łyżko stołowa
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} amerykańskie łyżki stołowe
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} łyżeczki amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} łyżeczkę amerykańską
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} łyżeczki amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} łyżeczkom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} łyżeczkce amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} łyżeczkom amerykańskim
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} lyżeczek amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} łyżeczki amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} lyżeczek amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżeczkami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżeczką amerykańską
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} łyżeczkami amerykańskimi
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} łyżeczkach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} łyżeczce amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} łyżeczkach amerykańskich
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} łyżeczki amerykańskiej
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} łyżeczka amerykańska
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} łyżeczki amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} łyżeczki amerykańskie
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} łyżeczko amerykańska
+locale=pl; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} łyżeczki amerykańskie
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} força gravítica
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} força gravítica
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro por segundo ao quadrado
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros por segundo ao quadrado
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} acre
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} acres
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hectare
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hectares
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro quadrado
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros quadrados
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pé quadrado
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pés quadrados
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilómetro quadrado
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilómetros quadrados
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha quadrada
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millhas quadradas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} por cento
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} por cento
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro por 100 quilómetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litros por 100 quilómetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro por quilómetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litros por quilómetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha por galão
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milhas por galão
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha por galão americano
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milhas por galão americano
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dia
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dias
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hora
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} horas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minuto
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minutos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mês
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meses
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} segundo
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} segundos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} semana
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} semanas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ano
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} anos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} caloria
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calorias
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilocaloria
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilocalorias
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pé
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pés
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} polegada
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} polegadas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilómetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilómetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milhas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milímetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milímetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsecs
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} picómetro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picómetros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} raio solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} raio solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jarda
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jardas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} luminosidade solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} luminosidade solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dalton
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} daltons
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} massa da Terra
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} massa da Terra
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grão
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grãos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grama
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gramas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilograma
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilogramas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} miligrama
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miligramas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onça
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onças
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} libra
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} libras
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} massa solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} massa solar
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilopascal
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilopascais
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quilómetro por hora
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quilómetros por hora
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} metro por segundo
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} metros por segundo
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha por hora
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milhas por hora
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grau Celsius
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graus Celsius
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grau Fahrenheit
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graus Fahrenheit
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grau
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} graus
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvins
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centilitro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centilitros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centímetro cúbico
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centímetros cúbicos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pé cúbico
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pés cúbicos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milha cúbica
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milhas cúbicas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} chávena
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} chávenas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} decilitro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decilitros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} colher de sobremesa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} colheres de sobremesa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} colher de sobremesa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} colheres de sobremesa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dracma líquido
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dracmas líquidos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gota
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gotas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onça líquida
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onças líquidas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} onça líquida americana
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} onças líquidas americanas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} galão
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galões
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} galão americano
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} galões americanos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jigger
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jiggers
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} litro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} litros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mililitro
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mililitros
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pitada
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pitadas
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quartilho líquido americano
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quartilhos líquidos americanos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quarto
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quartos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quarto líquido
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quartos líquidos
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} colher de sopa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} colheres de sopa
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} colher de chá
+locale=pt; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} colheres de chá
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} g
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} метра на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} метр на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} метры на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} метрам на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} метру на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} метрам на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} метров на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} метра на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} метров на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} метром на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} метрах на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} метре на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} метрах на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} метра на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} метр на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} метры на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} метре на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} метры на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} метр на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} метры на секунду в квадрате
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} акра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} акр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} акры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} акрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} акру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} акрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} акров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} акра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} акров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} акрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} акром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} акрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} акрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} акре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} акрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} акра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} акр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} акры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} акрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} акре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} акрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} акры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} акр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} акры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} гектара
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} гектар
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} гектары
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} гектарам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} гектару
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} гектарам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} гектаров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} гектара
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} гектаров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} гектарами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} гектаром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} гектарами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} гектарах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} гектаре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} гектарах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} гектара
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} гектар
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} гектары
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} гектарах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} гектаре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} гектарах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} гектары
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} гектар
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} гектары
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} квадратного сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} квадратный сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} квадратные сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} квадратным сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} квадратному сантиметру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} квадратным сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} квадратного сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратным сантиметром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} квадратных сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} квадратном сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} квадратных сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} квадратного сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} квадратный сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} квадратные сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратном сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} квадратный сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} квадратного фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} квадратный фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} квадратные футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} квадратным футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} квадратному футу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} квадратным футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} квадратного фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратным футом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} квадратных футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} квадратном футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} квадратных футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} квадратного фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} квадратный фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} квадратные футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратном футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} квадратный фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} квадратного километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} квадратный километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} квадратные километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} квадратным километрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} квадратному километру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} квадратным километрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} квадратного километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными километрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратным километром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными километрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} квадратных километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} квадратном километре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} квадратных километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} квадратного километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} квадратный километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} квадратные километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратном километре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} квадратный километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} квадратной мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} квадратную милю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} квадратные мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} квадратным милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} квадратной миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} квадратным милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} квадратной мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} квадратных миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратной милей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} квадратными милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} квадратных милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} квадратной миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} квадратных милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} квадратной мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} квадратная миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} квадратные мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратной миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} квадратных милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} квадратная миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} квадратные мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} процента
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} процент
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} проценты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} процентам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} проценту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} процентам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} процентов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} процента
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} процентов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} процентами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} процентом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} процентами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} процентах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} проценте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} процентах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} процента
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} процент
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} проценты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} процентах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} проценте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} процентах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} проценты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} процент
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} проценты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} литра на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} литр на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} литры на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} литрам на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} литру на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} литрам на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} литров на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} литра на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} литров на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} литрами на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} литром на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} литрами на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} литрах на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} литре на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} литрах на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} литра на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} литр на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} литры на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} литрах на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} литре на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} литрах на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} литры на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} литр на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} литры на 100 километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} милю на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} милям на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миле на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} милям на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миль на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миль на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} милями на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} милей на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} милями на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} милях на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миле на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} милях на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миля на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} милях на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миле на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} милях на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миля на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мили на галлон (Великобритания)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} милю на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} милям на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миле на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} милям на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миль на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миль на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} милями на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} милей на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} милями на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} милях на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миле на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} милях на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миля на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} милях на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миле на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} милях на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миля на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мили на галлон (США)
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} гигабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} гигабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} гигабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} гигабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} гигабиту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} гигабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} гигабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} гигабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} гигабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабитом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} гигабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} гигабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} гигабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} гигабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} гигабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} гигабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} гигабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} гигабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} гигабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} гигабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} гигабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} гигабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} гигабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} гигабайту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} гигабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} гигабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} гигабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} гигабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабайтом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} гигабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} гигабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} гигабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} гигабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} гигабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} гигабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} гигабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} гигабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} гигабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} гигабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-gigabyte"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} гигабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} килобита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} килобит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} килобиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} килобитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} килобиту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} килобитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} килобит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} килобита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} килобит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} килобитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} килобитом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} килобитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} килобитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} килобите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} килобитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} килобита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} килобит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} килобиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} килобитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} килобите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} килобитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} килобиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} килобит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} килобиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} килобайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} килобайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} килобайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} килобайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} килобайту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} килобайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} килобайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} килобайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} килобайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} килобайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} килобайтом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} килобайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} килобайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} килобайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} килобайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} килобайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} килобайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} килобайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} килобайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} килобайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} килобайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} килобайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} килобайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-kilobyte"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} килобайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мегабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} мегабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мегабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} мегабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} мегабиту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} мегабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} мегабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мегабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} мегабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабитом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} мегабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} мегабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} мегабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мегабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} мегабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мегабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мегабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} мегабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мегабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мегабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} мегабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мегабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} мегабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} мегабайту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} мегабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} мегабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мегабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} мегабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабайтом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} мегабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} мегабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} мегабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} мегабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мегабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} мегабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мегабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} мегабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мегабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} мегабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-megabyte"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мегабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} терабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} терабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} терабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} терабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} терабиту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} терабитам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} терабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} терабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} терабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} терабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} терабитом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} терабитами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} терабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} терабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} терабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} терабита
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} терабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} терабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} терабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} терабите
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} терабитах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} терабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} терабит
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} терабиты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} терабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} терабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} терабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} терабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} терабайту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} терабайтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} терабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} терабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} терабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} терабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} терабайтом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} терабайтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} терабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} терабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} терабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} терабайта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} терабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} терабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} терабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} терабайте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} терабайтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} терабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} терабайт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="digital-terabyte"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} терабайты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} дня
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} день
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} дни
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} дням
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} дню
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} дням
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} дней
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} дня
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} дней
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} днями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} днём
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} днями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} днях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} дне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} днях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} дня
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} день
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} дни
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} днях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} дне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} днях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} дни
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} день
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} дни
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} часа
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} часы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} часам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} часу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} часам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} часов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} часа
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} часов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} часами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} часом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} часами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} часах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} часе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} часах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} часа
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} часы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} часах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} часе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} часах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} часы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} часы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} минуту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} минутам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} минуте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} минутам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} минут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} минут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} минутами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} минутой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} минутами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} минутах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} минуте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} минутах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} минута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} минутах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} минуте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} минутах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} минута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} минуты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} месяца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} месяц
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} месяцы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} месяцам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} месяцу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} месяцам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} месяцев
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} месяца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} месяцев
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} месяцами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} месяцем
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} месяцами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} месяцах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} месяце
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} месяцах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} месяца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} месяц
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} месяцы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} месяцах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} месяце
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} месяцах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} месяцы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} месяц
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} месяцы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} секундам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} секунде
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} секундам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} секунд
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} секунд
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} секундами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} секундой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} секундами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} секундах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} секунде
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} секундах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} секунда
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} секундах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} секунде
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} секундах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} секунда
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} секунды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} неделю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} неделям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} неделе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} неделям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} недель
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} недель
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} неделями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} неделей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} неделями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} неделях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} неделе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} неделях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} неделя
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} неделях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} неделе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} неделях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} неделя
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} недели
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} года
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} год
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} годы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} годам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} году
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} годам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} лет
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} года
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} лет
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} годами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} годом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} годами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} годах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} годе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} годах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} года
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} год
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} годы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} годах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} годе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} годах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} годы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} год
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} годы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} калорию
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} калориям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} калориям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} калорий
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} калорий
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} калориями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} калорией
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} калориями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} калориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} калориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} калория
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} калориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} калориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} калория
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} калории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} килокалорию
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} килокалориям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} килокалориям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} килокалорий
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} килокалорий
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} килокалориями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} килокалорией
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} килокалориями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} килокалориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} килокалориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} килокалория
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} килокалориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} килокалориях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} килокалория
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} килокалории
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} сантиметру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} сантиметром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} футу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} футом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} дюйма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} дюйм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} дюймы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} дюймам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} дюйму
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} дюймам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} дюймов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} дюйма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} дюймов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} дюймами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} дюймом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} дюймами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} дюймах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} дюйме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} дюймах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} дюйма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} дюйм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} дюймы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} дюймах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} дюйме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} дюймах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} дюймы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} дюйм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} дюймы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} километрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} километру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} километрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} километров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} километрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} километром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} километрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} километре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} километра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} километре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} километрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} километр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} километры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} метра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} метр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} метры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} метрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} метру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} метрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} метров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} метра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} метров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} метром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} метрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} метре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} метрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} метра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} метр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} метры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} метре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} метры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} метр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} метры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} милю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} милей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} миллиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} миллиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} миллиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} миллиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миллиметру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} миллиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миллиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} миллиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миллиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиметром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} миллиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миллиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} миллиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} миллиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миллиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} миллиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} миллиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миллиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} миллиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} парсека
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} парсек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} парсеки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} парсекам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} парсеку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} парсекам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} парсеков
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} парсека
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} парсеков
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} парсеками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} парсеком
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} парсеками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} парсеках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} парсеке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} парсеках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} парсека
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} парсек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} парсеки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} парсеках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} парсеке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} парсеках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} парсеки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} парсек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} парсеки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} пикометра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} пикометр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} пикометры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} пикометрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} пикометру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} пикометрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} пикометров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} пикометра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} пикометров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} пикометрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} пикометром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} пикометрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} пикометрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} пикометре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} пикометрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} пикометра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} пикометр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} пикометры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} пикометрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} пикометре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} пикометрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} пикометры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} пикометр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} пикометры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} радиуса Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} радиус Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} радиусы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} радиусам Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} радиусу Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} радиусам Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} радиусов Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} радиуса Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} радиусов Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} радиусами Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} радиусом Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} радиусами Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} радиусах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} радиусе Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} радиусах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} радиуса Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} радиус Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} радиусы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} радиусах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} радиусе Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} радиусах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} радиусы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} радиус Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} радиусы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} ярда
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} ярд
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} ярды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} ярдам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} ярду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} ярдам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} ярдов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} ярда
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} ярдов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} ярдами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} ярдом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} ярдами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} ярдах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} ярде
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} ярдах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} ярда
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ярд
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ярды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} ярдах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} ярде
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} ярдах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} ярды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} ярд
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} ярды
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} солнечную светимость
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} солнечные светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} солнечным светимостям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} солнечным светимостям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} солнечных светимостей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} солнечных светимостей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} солнечными светимостями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} солнечной светимостью
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} солнечными светимостями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} солнечных светимостях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} солнечных светимостях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} солнечная светимость
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} солнечные светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} солнечных светимостях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} солнечной светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} солнечных светимостях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} солнечные светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} солнечная светимость
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} солнечные светимости
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} атомной единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} атомную единицу массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} атомные единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} атомным единицам массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} атомной единице массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} атомным единицам массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} атомных единиц массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} атомной единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} атомных единиц массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} атомными единицами массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} атомной единицей массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} атомными единицами массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} атомных единицах массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} атомной единице массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} атомных единицах массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} атомной единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} атомная единица массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} атомные единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} атомных единицах массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} атомной единице массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} атомных единицах массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} атомные единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} атомная единица массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} атомные единицы массы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} массу Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} массам Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} массе Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} массам Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} масс Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} масс Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} массами Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} массой Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} массами Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} массах Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} массе Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} массах Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} масса Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} массах Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} массе Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} массах Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} масса Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} массы Земли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} грана
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} гран
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} граны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} гранам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} грану
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} гранам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} гранов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} грана
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} гранов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} гранами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} граном
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} гранами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} гранах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} гране
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} гранах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} грана
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} гран
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} граны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} гранах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} гране
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} гранах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} граны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} гран
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} граны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} грамма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} грамм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} граммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} граммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} грамму
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} граммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} грамм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} грамма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} грамм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} граммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} граммом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} граммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} граммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} грамме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} граммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} грамма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} грамм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} граммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} граммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} грамме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} граммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} граммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} грамм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} граммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} килограмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} килограмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} килограммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} килограммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} килограмму
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} килограммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} килограмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} килограмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} килограмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} килограммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} килограммом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} килограммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} килограммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} килограмме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} килограммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} килограмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} килограмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} килограммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} килограммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} килограмме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} килограммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} килограммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} килограмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} килограммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} миллиграмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} миллиграмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} миллиграммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} миллиграммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миллиграмму
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} миллиграммам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миллиграмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} миллиграмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миллиграмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиграммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиграммом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} миллиграммами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} миллиграммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миллиграмме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} миллиграммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} миллиграмма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миллиграмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} миллиграммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиграммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиграмме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} миллиграммах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} миллиграммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миллиграмм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} миллиграммы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} унцию
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} унцией
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} фунта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} фунт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} фунты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} фунтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} фунту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} фунтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} фунтов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} фунта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} фунтов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} фунтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} фунтом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} фунтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} фунтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} фунте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} фунтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} фунта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} фунт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} фунты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} фунтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} фунте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} фунтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} фунты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} фунт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} фунты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} массу Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} массам Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} массе Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} массам Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} масс Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} масс Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} массами Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} массой Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} массами Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} массах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} массе Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} массах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} масса Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} массах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} массе Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} массах Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} масса Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} массы Солнца
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} килопаскаля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} килопаскаль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} килопаскали
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} килопаскалям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} килопаскалю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} килопаскалям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} килопаскалей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} килопаскаля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} килопаскалей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} килопаскалями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} килопаскалем
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} килопаскалями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} килопаскалях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} килопаскале
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} килопаскалях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} килопаскаля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} килопаскаль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} килопаскали
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} килопаскалях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} килопаскале
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} килопаскалях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} килопаскали
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} килопаскаль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} килопаскали
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} километра в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} километр в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} километры в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} километрам в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} километру в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} километрам в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} километров в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} километра в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} километров в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} километрами в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} километром в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} километрами в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} километрах в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} километре в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} километрах в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} километра в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} километр в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} километры в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} километрах в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} километре в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} километрах в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} километры в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} километр в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} километры в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} метра в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} метр в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} метры в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} метрам в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} метру в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} метрам в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} метров в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} метра в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} метров в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} метром в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} метрами в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} метрах в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} метре в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} метрах в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} метра в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} метр в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} метры в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} метре в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} метрах в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} метры в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} метр в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} метры в секунду
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} милю в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} милям в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миле в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} милям в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миль в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миль в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} милями в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} милей в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} милями в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} милях в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миле в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} милях в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миля в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} милях в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миле в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} милях в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миля в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} мили в час
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} градуса Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} градус Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} градусы Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} градусам Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} градусу Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} градусам Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} градусов Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} градуса Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} градусов Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} градусом Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} градусах Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} градусе Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} градусах Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} градуса Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} градус Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} градусы Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} градусе Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} градусы Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} градус Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} градусы Цельсия
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} градуса Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} градус Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} градусы Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} градусам Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} градусу Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} градусам Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} градусов Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} градуса Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} градусов Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} градусом Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} градусах Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} градусе Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} градусах Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} градуса Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} градус Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} градусы Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} градусе Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} градусы Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} градус Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} градусы Фаренгейта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} градуса
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} градус
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} градусы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} градусам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} градусу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} градусам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} градусов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} градуса
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} градусов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} градусом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} градусами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} градусах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} градусе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} градусах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} градуса
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} градус
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} градусы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} градусе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} градусах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} градусы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} градус
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} градусы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} Кельвина
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} Кельвин
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} Кельвины
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} Кельвинам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} Кельвину
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} Кельвинам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} Кельвинов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} Кельвина
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} Кельвинов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} Кельвинами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} Кельвином
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} Кельвинами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} Кельвинах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} Кельвине
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} Кельвинах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} Кельвина
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} Кельвин
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Кельвины
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} Кельвинах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} Кельвине
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} Кельвинах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} Кельвины
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} Кельвин
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} Кельвины
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} сантилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} сантилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} сантилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} сантилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} сантилитру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} сантилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} сантилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} сантилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} сантилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} сантилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} сантилитром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} сантилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} сантилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} сантилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} сантилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} сантилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} сантилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} сантилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} сантилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} сантилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} сантилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} сантилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} сантилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} сантилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} кубического сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} кубический сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} кубические сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} кубическим сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} кубическому сантиметру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} кубическим сантиметрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} кубических сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} кубического сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} кубических сантиметров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическим сантиметром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими сантиметрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} кубических сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} кубическом сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} кубических сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} кубического сантиметра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} кубический сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} кубические сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} кубическом сантиметре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических сантиметрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} кубические сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} кубический сантиметр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} кубические сантиметры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} кубического фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} кубический фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} кубические футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} кубическим футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} кубическому футу
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} кубическим футам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} кубических футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} кубического фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} кубических футов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическим футом
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими футами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} кубических футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} кубическом футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} кубических футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} кубического фута
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} кубический фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} кубические футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} кубическом футе
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических футах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} кубические футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} кубический фут
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} кубические футы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} кубической мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} кубическую милю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} кубические мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} кубическим милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} кубической миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} кубическим милям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} кубических миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} кубической мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} кубических миль
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} кубической милей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} кубическими милями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} кубических милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} кубической миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} кубических милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} кубической мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} кубическая миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} кубические мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} кубической миле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} кубических милях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} кубические мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} кубическая миля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} кубические мили
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую чашку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским чашкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской чашке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским чашкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских чашек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских чашек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими чашками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской чашкой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими чашками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских чашках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской чашке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских чашках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская чашка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских чашках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской чашке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских чашках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская чашка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские чашки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} децилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} децилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} децилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} децилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} децилитру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} децилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} децилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} децилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} децилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} децилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} децилитром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} децилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} децилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} децилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} децилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} децилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} децилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} децилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} децилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} децилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} децилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} децилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} децилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} децилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} британской десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} британскую десертную ложку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} британские десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} британским десертным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} британской десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} британским десертным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} британских десертных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} британской десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} британских десертных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} британскими десертными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} британской десертной ложкой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} британскими десертными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} британских десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} британской десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} британских десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} британской десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} британская десертная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} британские десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} британских десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} британской десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} британских десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} британские десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} британская десертная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} британские десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} десертную ложку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} десертным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} десертным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} десертных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} десертных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} десертными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} десертной ложкой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} десертными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} десертной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} десертная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} десертной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} десертных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} десертная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} десертные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} британской жидкой драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} британскую жидкую драхму
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} британские жидкие драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} британским жидким драхмам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} британской жидкой драхме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} британским жидким драхмам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} британских жидких драхм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} британской жидкой драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} британских жидких драхм
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} британскими жидкими драхмами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} британской жидкой драхмой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} британскими жидкими драхмами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} британских жидких драхмах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} британской жидкой драхме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} британских жидких драхмах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} британской жидкой драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} британская жидкая драхма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} британские жидкие драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} британских жидких драхмах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} британской жидкой драхме
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} британских жидких драхмах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} британские жидкие драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} британская жидкая драхма
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} британские жидкие драхмы
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} каплю
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} каплям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} капле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} каплям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} капель
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} капель
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} каплями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} каплей
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} каплями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} каплях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} капле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} каплях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} капля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} каплях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} капле
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} каплях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} капля
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} капли
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} имперскую жидкую унцию
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} имперские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} имперским жидким унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} имперским жидким унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} имперских жидких унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} имперских жидких унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими жидкими унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} имперской жидкой унцией
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими жидкими унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} имперских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} имперских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} имперская жидкая унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} имперские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} имперской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} имперские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} имперская жидкая унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} имперские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую жидкую унцию
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким унциям
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких унций
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской жидкой унцией
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими унциями
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская жидкая унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской жидкой унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких унциях
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская жидкая унция
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие унции
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} имперского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} имперский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} имперские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} имперским галлонам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} имперскому галлону
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} имперским галлонам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} имперских галлонов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} имперского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} имперских галлонов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими галлонами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} имперским галлоном
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими галлонами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} имперских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} имперском галлоне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} имперских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} имперского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} имперский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} имперские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} имперском галлоне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} имперские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} имперский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} имперские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским галлонам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американскому галлону
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским галлонам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских галлонов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских галлонов
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими галлонами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американским галлоном
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими галлонами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американском галлоне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американского галлона
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американском галлоне
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских галлонах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американский галлон
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские галлоны
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} джиггера
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} джиггер
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} джиггеры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} джиггерам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} джиггеру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} джиггерам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} джиггеров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} джиггера
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} джиггеров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} джиггерами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} джиггером
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} джиггерами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} джиггерах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} джиггере
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} джиггерах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} джиггера
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} джиггер
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} джиггеры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} джиггерах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} джиггере
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} джиггерах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} джиггеры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} джиггер
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} джиггеры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} литра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} литр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} литры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} литрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} литру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} литрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} литров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} литра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} литров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} литрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} литром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} литрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} литрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} литре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} литрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} литра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} литр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} литры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} литрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} литре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} литрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} литры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} литр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} литры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} миллилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} миллилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} миллилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} миллилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} миллилитру
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} миллилитрам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} миллилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} миллилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} миллилитров
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} миллилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} миллилитром
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} миллилитрами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} миллилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} миллилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} миллилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} миллилитра
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} миллилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} миллилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} миллилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} миллилитре
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} миллилитрах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} миллилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} миллилитр
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} миллилитры
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} щепотку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} щепоткам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} щепотке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} щепоткам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} щепоток
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} щепоток
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} щепотками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} щепоткой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} щепотками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} щепотках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} щепотке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} щепотках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} щепотка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} щепотках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} щепотке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} щепотках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} щепотка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} щепотки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской жидкой пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую жидкую пинту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские жидкие пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким пинтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской жидкой пинте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким пинтам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких пинт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской жидкой пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких пинт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими пинтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской жидкой пинтой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими пинтами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких пинтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской жидкой пинте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких пинтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской жидкой пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская жидкая пинта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские жидкие пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких пинтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской жидкой пинте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких пинтах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская жидкая пинта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие пинты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} имперской кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} имперскую кварту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} имперские кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} имперским квартам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} имперской кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} имперским квартам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} имперских кварт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} имперской кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} имперских кварт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими квартами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} имперской квартой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} имперскими квартами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} имперских квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} имперской кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} имперских квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} имперской кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} имперская кварта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} имперские кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} имперской кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} имперских квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} имперские кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} имперская кварта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} имперские кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской жидкой кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую жидкую кварту
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские жидкие кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким квартам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской жидкой кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским жидким квартам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких кварт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской жидкой кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских жидких кварт
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими квартами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской жидкой квартой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими жидкими квартами
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской жидкой кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских жидких квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской жидкой кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская жидкая кварта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские жидкие кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской жидкой кварте
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских жидких квартах
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская жидкая кварта
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские жидкие кварты
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской столовой ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую столовую ложку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские столовые ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским столовым ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской столовой ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским столовым ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских столовых ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской столовой ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских столовых ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими столовыми ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской столовой ложкой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими столовыми ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских столовых ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской столовой ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских столовых ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской столовой ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская столовая ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские столовые ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских столовых ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской столовой ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских столовых ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские столовые ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская столовая ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские столовые ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="accusative"][@draft="provisional"]; new_value={0} американской чайной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="accusative"][@draft="provisional"]; new_value={0} американскую чайную ложку
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="accusative"][@draft="provisional"]; new_value={0} американские чайные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="dative"][@draft="provisional"]; new_value={0} американским чайным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="dative"][@draft="provisional"]; new_value={0} американской чайной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="dative"][@draft="provisional"]; new_value={0} американским чайным ложкам
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="genitive"][@draft="provisional"]; new_value={0} американских чайных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="genitive"][@draft="provisional"]; new_value={0} американской чайной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="genitive"][@draft="provisional"]; new_value={0} американских чайных ложек
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими чайными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="instrumental"][@draft="provisional"]; new_value={0} американской чайной ложкой
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="instrumental"][@draft="provisional"]; new_value={0} американскими чайными ложками
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="locative"][@draft="provisional"]; new_value={0} американских чайных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="locative"][@draft="provisional"]; new_value={0} американской чайной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="locative"][@draft="provisional"]; new_value={0} американских чайных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@draft="provisional"]; new_value={0} американской чайной ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} американская чайная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} американские чайные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="prepositional"][@draft="provisional"]; new_value={0} американских чайных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="prepositional"][@draft="provisional"]; new_value={0} американской чайной ложке
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="prepositional"][@draft="provisional"]; new_value={0} американских чайных ложках
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="few"][@case="vocative"][@draft="provisional"]; new_value={0} американские чайные ложки
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@case="vocative"][@draft="provisional"]; new_value={0} американская чайная ложка
+locale=ru; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@case="vocative"][@draft="provisional"]; new_value={0} американские чайные ложки
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} g-kraft
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} g-krafter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per kvadratsekund
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelskt tunnland
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelska tunnland
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} hektar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hektar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratcentimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratfot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratfot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kvadratkilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelsk kvadratmil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelska kvadratmil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} procent
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} procent
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter per 100 kilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelsk mil per gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelska mil per gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk mil per gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanska mil per gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dag
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dagar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} timme
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} timmar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} minut
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} minuter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} månad
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} månader
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} sekund
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} sekunder
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} vecka
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} veckor
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} år
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} år
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kalori
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kalorier
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilokalori
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilokalorier
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-decimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} decimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-decimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tum
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tum
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile-scandinavian"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile-scandinavian"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} engelsk mil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} engelska mil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} millimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} millimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} parsec
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsec
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pikometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pikometer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solradie
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} yard
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} yard
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solluminositet
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} atommassenhet
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} atommassenheter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} jordmassa
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grain
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grains
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} gram
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gram
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilo
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilo
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milligram
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milligram
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} ounce
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounces
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pound
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pound
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} solmassa
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilopascal
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilopascal
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kilometer per timme
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilometer per timme
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} meter per sekund
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} meter per sekund
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mile per timme
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miles per timme
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad Celsius
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader Celsius
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad Fahrenheit
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader Fahrenheit
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} grad
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grader
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kelvin
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kelvin
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} centiliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centiliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikcentimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikcentimeter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikfot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikfot
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} kubikmil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kubikmil
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} cup
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} cups
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} deciliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} deciliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brittisk dessertsked
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brittisk dessertskedar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} dessertsked
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dessertskedar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brittisk dram
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brittiska dramer
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} droppe
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} droppar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brittiskt fluid ounce
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brittiska fluid ounce
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} fluid ounce
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} fluid ounces
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brittisk gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brittiska gallons
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} amerikansk gallon
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} amerikanska gallons
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} mätglas
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mätglas
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} liter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} liter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} milliliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milliliter
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} nypa
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} nypor
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} pint
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} pints
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} brittisk quart
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} brittiska quarts
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} quart
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} quarts
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} matsked
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} matskedar
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="one"][@draft="provisional"]; new_value={0} tesked
+locale=sv; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} teskedar
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} แรงจี
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เมตรต่อวินาทีกำลังสอง
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เอเคอร์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เฮกตาร์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ตารางเซนติเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ตารางฟุต
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ตารางกิโลเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ตารางไมล์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ร้อยละ
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ลิตรต่อ 100 กิโลเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ไมล์ต่อแกลลอน (อังกฤษ)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ไมล์ต่อแกลลอน (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} วัน
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ชั่วโมง
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} นาที
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เดือน
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} วินาที
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} สัปดาห์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ปี
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} แคลอรี
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กิโลแคลอรี
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เซนติเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ฟุต
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} นิ้ว
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กิโลเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ไมล์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} มิลลิเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} พาร์เซก
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} พิโกเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} รัศมีดวงอาทิตย์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} หลา
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กำลังส่องสว่างของดวงอาทิตย์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} หน่วยมวลอะตอม
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} มวลของโลก
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เกรน
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กรัม
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กิโลกรัม
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} มิลลิกรัม
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ออนซ์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ปอนด์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} มวลดวงอาทิตย์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กิโลปาสกาล
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} กิโลเมตรต่อชั่วโมง
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เมตรต่อวินาที
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ไมล์ต่อชั่วโมง
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} องศาเซลเซียส
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} องศาฟาเรนไฮต์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} องศา
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เคลวิน
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เซนติลิตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ลูกบาศก์เซนติเมตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ลูกบาศก์ฟุต
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ลูกบาศก์ไมล์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ถ้วย (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} เดซิลิตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ช้อนของหวาน (อังกฤษ)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ช้อนของหวาน
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ดรัมของเหลว (อังกฤษ)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} หยด
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ออนซ์ของเหลว (อังกฤษ)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ออนซ์ของเหลว (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} แกลลอน (อังกฤษ)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} แกลลอนของเหลว (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} จิกเกอร์
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ลิตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} มิลลิลิตร
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} หยิบมือ
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ไพนต์ของเหลว (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ควอร์ต
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ควอร์ตของเหลว (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ช้อนโต๊ะ (สหรัฐอเมริกา)
+locale=th; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ช้อนชา (สหรัฐอเมริกา)
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} lực G
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mét trên giây bình phương
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mẫu Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} hécta
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimét vuông
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} foot vuông
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilômét vuông
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm vuông
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} phần trăm
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} lít trên 100 kilômét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm trên gallon Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm Mỹ trên gallon
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ngày
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} giờ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} phút
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tháng
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} giây
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tuần
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} năm
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} calo
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilôcalo
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centimét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} foot
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} inch
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilômét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} milimét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} parsec
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} picômét
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} bán kính Mặt Trời
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Yard
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} độ sáng của Mặt Trời
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} đơn vị khối lượng nguyên tử
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} khối lượng Trái Đất
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} grain
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gam
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilôgam
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} miligam
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounce
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Pound
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} khối lượng Mặt Trời
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilôpascal
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} kilômét trên giờ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mét trên giây
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm trên giờ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} độ Celsius
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} độ Fahrenheit
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} độ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} Kelvin
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} centilít
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} phân khối
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} foot khối
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dặm khối
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} tách Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} decilít
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} muỗng ăn tráng miệng Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} muỗng ăn tráng miệng
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} dram chất lỏng Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} giọt
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounce chất lỏng Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} ounce chất lỏng Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gallon Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} gallon chất lỏng Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} jigger
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} lít
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} mililít
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} nhúm
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} panh chất lỏng Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} lít Anh
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} một phần tư gallon chất lỏng Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} muỗng canh Mỹ
+locale=vi; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0} muỗng cà phê Mỹ
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}G 力
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每二次方秒{0}米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英畝
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公頃
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方厘米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方呎
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方公里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value=百分之{0}
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每百公里{0}公升
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每加侖{0}英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每美制加侖{0}英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}日
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個鐘
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分鐘
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個月
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個禮拜
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}年
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個卡路里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千卡
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}厘米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}呎
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}吋
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒差距
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}皮米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽半徑
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}碼
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽光度
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個原子質量單位
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}地球質量
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}格令
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}克
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公斤
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫克
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}安士
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}磅
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽質量
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千帕
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每小時{0}公里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每秒{0}米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每小時{0}英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value=攝氏{0}度
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value=華氏{0}度
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}度
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}開氏
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}厘升
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方厘米
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方呎
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方英里
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制杯
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分升
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value=英制甜品匙{0}匙
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}甜品匙
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制液量打蘭
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}滴
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}液量安士
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制液量安士
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}加侖
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制加侖
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value=量酒器{0}杯
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公升
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫升
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}小撮
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制品脫
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}夸脫
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制夸脫
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}湯匙
+locale=yue; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}茶匙
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}G力
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每平方秒{0}米
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英畝
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公頃
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方公分
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方英呎
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方公里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value=百分之{0}
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每 100 公里{0}公升
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每英制加侖{0}英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每美制加侖{0}英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}天
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}小時
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分鐘
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}個月
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}星期
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}年
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}卡路里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}大卡
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公分
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英呎
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英吋
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公尺
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫米
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒差距
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}皮米
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽半徑
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}碼
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽光度
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}道爾頓
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}地球質量
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}格令
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公克
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公斤
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫克
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}盎司
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}磅
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太陽質量
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千帕
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每小時{0}公里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每秒{0}公尺
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value=每小時{0}英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value=攝氏{0}度
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value=華氏{0}度
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}度
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}厘升
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方公分
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方英呎
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方英里
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制杯
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分升
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value=英制甜點匙{0}匙
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value=甜點匙{0}匙
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制打蘭
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}滴
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英液盎司
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美液盎司
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制加侖
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制加侖
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value=量酒器{0}杯
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公升
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫升
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}小撮
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美液品脫
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制夸脫
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制夸脫
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}湯匙
+locale=zh_Hant; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}茶匙
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-g-force"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}G力
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="acceleration-meter-per-square-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}米/二次方秒
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-acre"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英亩
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-hectare"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}公顷
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方厘米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方英尺
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方千米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="area-square-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}平方英里
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="concentr-percent"]/unitPattern[@count="other"][@draft="provisional"]; new_value=百分之{0}
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-liter-per-100-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}升/百公里
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里/加仑
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="consumption-mile-per-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里/美制加仑
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-day"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}天
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}个小时
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-minute"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分钟
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-month"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}个月
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-week"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}个星期
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="duration-year"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}年
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-foodcalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}卡路里
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="energy-kilocalorie"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千卡
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}厘米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英尺
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-inch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英寸
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-kilometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-meter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-millimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-parsec"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}秒差距
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-picometer"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}皮米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-solar-radius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太阳半径
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="length-yard"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}码
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="light-solar-luminosity"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太阳光度
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-dalton"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}道尔顿
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-earth-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}地球质量
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-grain"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}格令
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-gram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}克
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-kilogram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千克
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-milligram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫克
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}盎司
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-pound"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}磅
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="mass-solar-mass"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}太阳质量
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="pressure-kilopascal"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千帕
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-kilometer-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}千米/小时
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-meter-per-second"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}米/秒
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="speed-mile-per-hour"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英里/小時
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-celsius"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}摄氏度
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-fahrenheit"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}华氏度
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-generic"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}度
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="temperature-kelvin"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}开尔文
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-centiliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}厘升
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-centimeter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方厘米
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-foot"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方英尺
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cubic-mile"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}立方英里
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-cup"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制杯
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-deciliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}分升
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制甜点匙
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dessert-spoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}甜点匙
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-dram"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制液量打兰
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-drop"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}滴
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制液量盎司
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-fluid-ounce"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制液量盎司
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制加仑
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-gallon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制加仑
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-jigger"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}吉尔
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-liter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}升
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-milliliter"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}毫升
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pinch"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}撮
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-pint"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制品脱
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart-imperial"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}英制夸脱
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-quart"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制液量夸脱
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-tablespoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制汤匙
+locale=zh; action=addNew; new_path=//ldml/units/unitLength[@type="long"]/unit[@type="volume-teaspoon"]/unitPattern[@count="other"][@draft="provisional"]; new_value={0}美制茶匙
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/tool/resolver/CldrResolver.java b/tools/java/org/unicode/cldr/tool/resolver/CldrResolver.java
index 252bc42..f879ba6 100644
--- a/tools/java/org/unicode/cldr/tool/resolver/CldrResolver.java
+++ b/tools/java/org/unicode/cldr/tool/resolver/CldrResolver.java
@@ -191,7 +191,7 @@
public Set<String> getLocaleNames(String localeRegex) {
ResolverUtils.debugPrint("Getting list of locales...", 3);
Set<String> allLocales = cldrFactory.getAvailable();
- Set<String> locales = new TreeSet<String>();
+ Set<String> locales = new TreeSet<>();
// Iterate through all the locales
for (String locale : allLocales) {
// Check if the locale name matches the regex
@@ -229,7 +229,7 @@
private CLDRFile resolveLocaleInternal(CLDRFile file, ResolutionType resolutionType) {
String locale = file.getLocaleID();
// Make parent files for simple resolution.
- List<CLDRFile> ancestors = new ArrayList<CLDRFile>();
+ List<CLDRFile> ancestors = new ArrayList<>();
if (resolutionType == ResolutionType.SIMPLE && !locale.equals(ROOT)) {
String parentLocale = locale;
do {
diff --git a/tools/java/org/unicode/cldr/tool/resolver/ResolverUtils.java b/tools/java/org/unicode/cldr/tool/resolver/ResolverUtils.java
index 136470a..b99bb08 100644
--- a/tools/java/org/unicode/cldr/tool/resolver/ResolverUtils.java
+++ b/tools/java/org/unicode/cldr/tool/resolver/ResolverUtils.java
@@ -39,7 +39,7 @@
*/
public static Set<String> getAllPaths(CLDRFile file) {
String locale = file.getLocaleID();
- Set<String> paths = new HashSet<String>();
+ Set<String> paths = new HashSet<>();
for (String path : file) {
paths.add(path);
}
diff --git a/tools/java/org/unicode/cldr/util/Annotations.java b/tools/java/org/unicode/cldr/util/Annotations.java
index 65082c9..854e9ff 100644
--- a/tools/java/org/unicode/cldr/util/Annotations.java
+++ b/tools/java/org/unicode/cldr/util/Annotations.java
@@ -18,11 +18,11 @@
import org.unicode.cldr.tool.SubdivisionNames;
import org.unicode.cldr.util.XMLFileReader.SimpleHandler;
+import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.CharSequences;
@@ -56,21 +56,14 @@
static {
File directory = new File(CLDRPaths.COMMON_DIRECTORY, "annotations");
- try {
- DIR = directory.getCanonicalPath();
- } catch (IOException e) {
- throw new ICUUncheckedIOException(e);
- }
+ DIR = PathUtilities.getNormalizedPathString(directory);
if (DEBUG) {
System.out.println(DIR);
}
Builder<String> temp = ImmutableSet.builder();
for (File file : directory.listFiles()) {
if (DEBUG) {
- try {
- System.out.println(file.getCanonicalPath());
- } catch (IOException e) {
- }
+ System.out.println(PathUtilities.getNormalizedPathString(file));
}
String name = file.toString();
String shortName = file.getName();
@@ -126,7 +119,7 @@
}
static final Pattern SPACES = Pattern.compile("\\s+");
-
+
@Override
public void handlePathValue(String path, String value) {
if (value.contains(CldrUtility.INHERITANCE_MARKER)) {
@@ -270,6 +263,7 @@
/**
* @deprecated Use {@link #getLabelSet(String)} instead
*/
+ @Deprecated
private Set<String> getLabelSet() {
return getLabelSet("flag");
}
@@ -413,22 +407,22 @@
// code = code.substring(0,code.length()-EmojiConstants.JOINER_MALE_SIGN.length());
// } // otherwise "🚴🏿♂️","man biking: dark skin tone"
// } else if (code.endsWith(EmojiConstants.JOINER_FEMALE_SIGN)){
-// if (matchesInitialPattern(code)) { //
+// if (matchesInitialPattern(code)) { //
// rem = EmojiConstants.WOMAN + rem;
// code = code.substring(0,code.length()-EmojiConstants.JOINER_FEMALE_SIGN.length());
// }
-// } else
+// } else
if (code.contains(EmojiConstants.KISS)) {
rem = code + rem;
code = "💏";
skipSet = EmojiConstants.REM_GROUP_SKIP_SET;
- } else if (code.contains(EmojiConstants.HEART)) {
+ } else if (code.contains(EmojiConstants.HEART) && !code.startsWith(EmojiConstants.HEART)) {
rem = code + rem;
code = "💑";
skipSet = EmojiConstants.REM_GROUP_SKIP_SET;
} else if (code.contains(EmojiConstants.HANDSHAKE)) {
code = code.startsWith(EmojiConstants.MAN) ? "👬"
- : code.endsWith(EmojiConstants.MAN) ? "👫"
+ : code.endsWith(EmojiConstants.MAN) ? "👫"
: code.startsWith(EmojiConstants.WOMAN) ? "👭"
: NEUTRAL_HOLDING;
skipSet = EmojiConstants.REM_GROUP_SKIP_SET;
@@ -464,12 +458,12 @@
annotations.addAll(stock.getKeywords());
} else if (otherSource != null) {
shortName = otherSource.transform(base);
- if (shortName == null) {
- return null;
- }
} else {
return null;
}
+ if (shortName == null) {
+ return null;
+ }
}
boolean hackBlond = EmojiConstants.HAIR_EXPLICIT.contains(base.codePointAt(0));
@@ -505,7 +499,7 @@
modName = Utility.hex(mod); // ultimate fallback
}
}
- if (hackBlond && shortName != null) {
+ if (hackBlond && shortName != null) {
// HACK: make the blond names look like the other hair names
// Split the short name into pieces, if possible, and insert the modName first
String sep = initialPattern.format("", "");
@@ -537,6 +531,7 @@
/**
* @deprecated Use {@link #toString(String,boolean,AnnotationSet)} instead
*/
+ @Deprecated
public String toString(String code, boolean html) {
return toString(code, html, null);
}
@@ -561,7 +556,7 @@
keywords = Collections.singleton(EQUIVALENT);
}
- String result = CollectionUtilities.join(keywords, " |\u00a0");
+ String result = Joiner.on(" |\u00a0").join(keywords);
if (shortName != null) {
String ttsString = (html ? "*<b>" : "*") + shortName + (html ? "</b>" : "*");
if (result.isEmpty()) {
@@ -585,7 +580,7 @@
String shortName = getShortName(code);
Set<String> keywords = getKeywords(code);
if (shortName != null && keywords.contains(shortName)) {
- keywords = new LinkedHashSet<String>(keywords);
+ keywords = new LinkedHashSet<>(keywords);
keywords.remove(shortName);
}
return keywords;
@@ -639,10 +634,10 @@
public String toString(boolean html) {
Set<String> annotations2 = getKeywords();
if (getShortName() != null && annotations2.contains(getShortName())) {
- annotations2 = new LinkedHashSet<String>(getKeywords());
+ annotations2 = new LinkedHashSet<>(getKeywords());
annotations2.remove(getShortName());
}
- String result = CollectionUtilities.join(annotations2, " |\u00a0");
+ String result = Joiner.on(" |\u00a0").join(annotations2);
if (getShortName() != null) {
String ttsString = (html ? "*<b>" : "*") + getShortName() + (html ? "</b>" : "*");
if (result.isEmpty()) {
@@ -687,7 +682,7 @@
System.out.println(Utility.hex(key, 4, "_").toLowerCase(Locale.ROOT)
+ "\t" + key
+ "\t" + map.get(key).getShortName()
- + "\t" + CollectionUtilities.join(map.get(key).getKeywords(), " | "));
+ + "\t" + Joiner.on(" | ").join(map.get(key).getKeywords()));
}
for (String s : Arrays.asList(
"💏", "👩❤️💋👩",
@@ -699,7 +694,8 @@
"🚴", "🚴🏿", "🚴♂️", "🚴🏿♂️", "🚴♀️", "🚴🏿♀️")) {
final String shortName = eng.getShortName(s);
final Set<String> keywords = eng.getKeywords(s);
- System.out.println("{\"" + s + "\",\"" + shortName + "\",\"" + CollectionUtilities.join(keywords, "|") + "\"},");
+ System.out.println("{\"" + s + "\",\"" + shortName + "\",\"" + Joiner.on("|")
+ .join(keywords) + "\"},");
}
}
@@ -718,8 +714,8 @@
System.out.println(key + "\tname\t"
+ "\t" + value.getShortName()
+ "\t" + (value100 == null ? "" : value100.getShortName())
- + "\t" + CollectionUtilities.join(value.getKeywords(), " | ")
- + "\t" + (keywords100 == null ? "" : CollectionUtilities.join(keywords100, " | ")));
+ + "\t" + Joiner.on(" | ").join(value.getKeywords())
+ + "\t" + (keywords100 == null ? "" : Joiner.on(" | ").join(keywords100)));
}
}
}
diff --git a/tools/java/org/unicode/cldr/util/ApproximateWidth.java b/tools/java/org/unicode/cldr/util/ApproximateWidth.java
index cd3bfa4..04382f2 100644
--- a/tools/java/org/unicode/cldr/util/ApproximateWidth.java
+++ b/tools/java/org/unicode/cldr/util/ApproximateWidth.java
@@ -3,7 +3,7 @@
import com.ibm.icu.dev.util.UnicodeMap;
public class ApproximateWidth {
- static UnicodeMap<Integer> data = new UnicodeMap<Integer>();
+ static UnicodeMap<Integer> data = new UnicodeMap<>();
static Integer defaultWidth;
public static Integer getWidth(int cp) {
@@ -11,8 +11,8 @@
return result == null ? defaultWidth : result;
}
- /**
- * Return # of ems * 10
+ /**
+ * Return # of ems * 10
*/
public static int getWidth(CharSequence s) {
int result = 0;
@@ -32,7 +32,7 @@
String[] items = SPLIT.split(line);
defaultWidth = Integer.parseInt(items[1]);
}
- };
+ }
@Override
protected boolean handleLine(int lineCount, int start, int end, String[] items) {
diff --git a/tools/java/org/unicode/cldr/util/ArrayComparator.java b/tools/java/org/unicode/cldr/util/ArrayComparator.java
index 6c8ced5..a53d672 100644
--- a/tools/java/org/unicode/cldr/util/ArrayComparator.java
+++ b/tools/java/org/unicode/cldr/util/ArrayComparator.java
@@ -10,6 +10,7 @@
public class ArrayComparator implements Comparator {
public static final Comparator COMPARABLE = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
return ((Comparable) o1).compareTo(o2);
}
@@ -37,10 +38,11 @@
}
/* Lexigraphic compare. Returns the first difference
- * @return zero if equal. Otherwise +/- (i+1)
+ * @return zero if equal. Otherwise +/- (i+1)
* where i is the index of the first comparator finding a difference
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
+ @Override
public int compare(Object a0, Object a1) {
Object[] arg0 = (Object[]) a0;
Object[] arg1 = (Object[]) a1;
@@ -63,6 +65,7 @@
this.other = other;
}
+ @Override
public int compare(Object arg0, Object arg1) throws RuntimeException {
try {
return other.compare(arg0, arg1);
diff --git a/tools/java/org/unicode/cldr/util/AttributeValueValidity.java b/tools/java/org/unicode/cldr/util/AttributeValueValidity.java
index 481e39e..c5983d6 100644
--- a/tools/java/org/unicode/cldr/util/AttributeValueValidity.java
+++ b/tools/java/org/unicode/cldr/util/AttributeValueValidity.java
@@ -48,8 +48,8 @@
private static final SupplementalDataInfo supplementalData = CLDRConfig.getInstance().getSupplementalDataInfo();
private static Map<DtdType, Map<String, Map<String, MatcherPattern>>> dtd_element_attribute_validity = new EnumMap<>(DtdType.class);
- private static Map<String, MatcherPattern> common_attribute_validity = new LinkedHashMap<String, MatcherPattern>();
- private static Map<String, MatcherPattern> variables = new LinkedHashMap<String, MatcherPattern>();
+ private static Map<String, MatcherPattern> common_attribute_validity = new LinkedHashMap<>();
+ private static Map<String, MatcherPattern> variables = new LinkedHashMap<>();
private static final RegexMatcher NOT_DONE_YET = new RegexMatcher(".*", Pattern.COMMENTS);
private static final Map<AttributeValidityInfo, String> failures = new LinkedHashMap<>();
private static final boolean DEBUG = false;
@@ -218,7 +218,7 @@
DtdData data = DtdData.getInstance(dtdType);
Map<String, Map<String, MatcherPattern>> element_attribute_validity = dtd_element_attribute_validity.get(dtdType);
if (element_attribute_validity == null) {
- dtd_element_attribute_validity.put(dtdType, element_attribute_validity = new TreeMap<String, Map<String, MatcherPattern>>());
+ dtd_element_attribute_validity.put(dtdType, element_attribute_validity = new TreeMap<>());
}
// <attributeValues dtds="supplementalData" elements="currency" attributes="before from to">$currencyDate</attributeValues>
@@ -255,7 +255,7 @@
// System.out.println("\t" + element);
Map<String, MatcherPattern> attribute_validity = element_attribute_validity.get(element);
if (attribute_validity == null) {
- element_attribute_validity.put(element, attribute_validity = new TreeMap<String, MatcherPattern>());
+ element_attribute_validity.put(element, attribute_validity = new TreeMap<>());
}
addAttributes(attributeList, attribute_validity, mp);
}
@@ -366,6 +366,7 @@
public abstract String _getPattern();
+ @Override
public String toString() {
return getClass().getName() + "\t" + getPattern();
}
@@ -479,6 +480,7 @@
matcher = Pattern.compile(pattern, flags).matcher("");
}
+ @Override
public boolean matches(String value, Output<String> reason) {
matcher.reset(value.toString());
boolean result = matcher.matches();
@@ -518,6 +520,7 @@
static final int MAX_STRING = 64;
+ @Override
public boolean matches(String value, Output<String> reason) {
boolean result = LOCALE_SPECIFIC.get(ls).contains(value);
if (!result && reason != null) {
@@ -631,6 +634,7 @@
this.operands = operands;
}
+ @Override
public boolean matches(String value, Output<String> reason) {
StringBuilder fullReason = reason == null ? null : new StringBuilder();
for (MatcherPattern operand : operands) {
@@ -670,6 +674,7 @@
this.other = other;
}
+ @Override
public boolean matches(String value, Output<String> reason) {
List<String> values = SPACE.splitToList(value);
if (values.isEmpty()) return true;
@@ -691,7 +696,6 @@
}
public static class LocaleMatcher extends MatcherPattern {
- //final ObjectMatcherReason grandfathered = getNonNullVariable("$grandfathered").matcher;
final MatcherPattern language;
final MatcherPattern script = getNonNullVariable("$_script");
final MatcherPattern territory = getNonNullVariable("$_region");
@@ -705,11 +709,9 @@
language = getNonNullVariable(variable);
}
+ @Override
public boolean matches(String value, Output<String> reason) {
-// if (grandfathered.matches(value, reason)) {
-// return true;
-// }
- lip.set((String) value);
+ lip.set(value);
String field = lip.getLanguage();
if (!language.matches(field, reason)) {
if (reason != null) {
diff --git a/tools/java/org/unicode/cldr/util/BNF.java b/tools/java/org/unicode/cldr/util/BNF.java
index 9f31954..8fb1d68 100644
--- a/tools/java/org/unicode/cldr/util/BNF.java
+++ b/tools/java/org/unicode/cldr/util/BNF.java
@@ -44,18 +44,18 @@
+ "core = string | unicodeSet | '(' alternation ')';"
+ "sequence = (core quantifier*)+;"
+ "alternation = sequence (weight? ('|' sequence weight?)+)?;"
- + "rule = string '=' alternation;";
-
-
+ + "rule = string '=' alternation;";
+
+
* Match 0 or more times
+ Match 1 or more times
? Match 1 or 0 times
{n} Match exactly n times
{n,} Match at least n times
- {n,m} Match at least n but not more than m times
-
-
-
+ {n,m} Match at least n but not more than m times
+
+
+
*/
public BNF(Random random, Quoter quoter) {
@@ -74,7 +74,7 @@
public BNF complete() {
// check that the rules match the variables, except for $root in rules
Set ruleSet = map.keySet();
- // add also
+ // add also
variables.add("$root");
variables.addAll(t.getLookedUpItems());
if (!ruleSet.equals(variables)) {
diff --git a/tools/java/org/unicode/cldr/util/Builder.java b/tools/java/org/unicode/cldr/util/Builder.java
index a95be5f..aad1880 100644
--- a/tools/java/org/unicode/cldr/util/Builder.java
+++ b/tools/java/org/unicode/cldr/util/Builder.java
@@ -68,19 +68,19 @@
}
public static <E, C extends Collection<E>> CBuilder<E, C> with(C collection, EqualAction ea) {
- return new CBuilder<E, C>(collection, ea);
+ return new CBuilder<>(collection, ea);
}
public static <E, C extends Collection<E>> CBuilder<E, C> with(C collection) {
- return new CBuilder<E, C>(collection, EqualAction.NATIVE);
+ return new CBuilder<>(collection, EqualAction.NATIVE);
}
public static <K, V, M extends Map<K, V>> MBuilder<K, V, M> with(M map, EqualAction ea) {
- return new MBuilder<K, V, M>(map, ea);
+ return new MBuilder<>(map, ea);
}
public static <K, V, M extends Map<K, V>> MBuilder<K, V, M> with(M map) {
- return new MBuilder<K, V, M>(map, EqualAction.NATIVE);
+ return new MBuilder<>(map, EqualAction.NATIVE);
}
// ===== Collections ======
@@ -233,7 +233,7 @@
}
public CBuilder<E, U> keepNew(Collection<? extends E> c) {
- HashSet<E> extras = new HashSet<E>(c);
+ HashSet<E> extras = new HashSet<>(c);
extras.removeAll(collection);
collection.clear();
collection.addAll(extras);
@@ -251,7 +251,7 @@
}
public CBuilder<E, U> filter(Transform<E, Boolean> filter) {
- HashSet<E> temp = new HashSet<E>();
+ HashSet<E> temp = new HashSet<>();
for (E item : collection) {
if (filter.transform(item) == Boolean.FALSE) {
temp.add(item);
@@ -283,6 +283,7 @@
return temp;
}
+ @Override
public String toString() {
return collection.toString();
}
@@ -455,7 +456,7 @@
}
public <N extends Map<K, V>> MBuilder<K, V, M> keepNew(N c) {
- HashSet<K> extras = new HashSet<K>(c.keySet());
+ HashSet<K> extras = new HashSet<>(c.keySet());
extras.removeAll(map.keySet());
map.clear();
for (K key : extras) {
@@ -482,6 +483,7 @@
return temp;
}
+ @Override
public String toString() {
return map.toString();
}
diff --git a/tools/java/org/unicode/cldr/util/CLDRConfig.java b/tools/java/org/unicode/cldr/util/CLDRConfig.java
index 602140e..ef3cc53 100644
--- a/tools/java/org/unicode/cldr/util/CLDRConfig.java
+++ b/tools/java/org/unicode/cldr/util/CLDRConfig.java
@@ -27,6 +27,7 @@
import com.ibm.icu.util.VersionInfo;
public class CLDRConfig extends Properties {
+ public static boolean SKIP_SEED = System.getProperty("CLDR_SKIP_SEED") != null;
/**
*
*/
@@ -62,7 +63,7 @@
* Object to use for synchronization when interacting with Factory
*/
private static final Object ANNOTATIONS_FACTORY_SYNC = new Object();
-
+
/**
* Object to use for synchronization when interacting with Factory
*/
@@ -98,7 +99,7 @@
SMOKETEST, // staging area
PRODUCTION, // production server!
UNITTEST // unit test setting
- };
+ }
public static CLDRConfig getInstance() {
synchronized (CLDRConfig.class) {
@@ -172,6 +173,7 @@
.maximumSize(200)
.build(
new CacheLoader<String, CLDRFile>() {
+ @Override
public CLDRFile load(String locale) {
return getFullCldrFactory().make(locale, true);
}
@@ -182,6 +184,7 @@
.maximumSize(1000)
.build(
new CacheLoader<String, CLDRFile>() {
+ @Override
public CLDRFile load(String locale) {
return getFullCldrFactory().make(locale, false);
}
@@ -319,8 +322,8 @@
File[] paths = {
new File(CLDRPaths.MAIN_DIRECTORY),
new File(CLDRPaths.ANNOTATIONS_DIRECTORY),
- new File(CLDRPaths.SEED_DIRECTORY),
- new File(CLDRPaths.SEED_ANNOTATIONS_DIRECTORY)
+ SKIP_SEED ? null : new File(CLDRPaths.SEED_DIRECTORY),
+ SKIP_SEED ? null : new File(CLDRPaths.SEED_ANNOTATIONS_DIRECTORY)
};
commonAndSeedAndMainAndAnnotationsFactory = SimpleFactory.make(paths, ".*");
}
@@ -332,8 +335,8 @@
synchronized (FULL_FACTORY_SYNC) {
if (fullFactory == null) {
File[] paths = {
- new File(CLDRPaths.MAIN_DIRECTORY),
- new File(CLDRPaths.SEED_DIRECTORY)};
+ new File(CLDRPaths.MAIN_DIRECTORY),
+ SKIP_SEED ? null : new File(CLDRPaths.SEED_DIRECTORY)};
fullFactory = SimpleFactory.make(paths, ".*");
}
}
@@ -412,7 +415,7 @@
return result;
}
- private Set<String> shown = new HashSet<String>();
+ private Set<String> shown = new HashSet<>();
private Map<String, String> localSet = null;
@@ -485,7 +488,7 @@
throw new InternalError("setProperty() only valid in UNITTEST Environment.");
}
if (localSet == null) {
- localSet = new ConcurrentHashMap<String, String>();
+ localSet = new ConcurrentHashMap<>();
}
shown.remove(k); // show it again with -D
return localSet.put(k, v);
@@ -531,13 +534,28 @@
}
}
- public File getCldrBaseDirectory() {
- String dir = getProperty("CLDR_DIR", null);
- if (dir != null) {
- return new File(dir);
- } else {
- return null;
+ private static class FileWrapper {
+ private File cldrDir = null;
+ private FileWrapper() {
+ String dir = getInstance().getProperty("CLDR_DIR", null);
+ if (dir != null) {
+ cldrDir = new File(dir);
+ } else {
+ cldrDir = null;
+ }
}
+ public File getCldrDir() {
+ return this.cldrDir;
+ }
+ // singleton
+ private static FileWrapper fileWrapperInstance = new FileWrapper();
+ public static FileWrapper getFileWrapperInstance() {
+ return fileWrapperInstance;
+ }
+ }
+
+ public File getCldrBaseDirectory() {
+ return FileWrapper.getFileWrapperInstance().getCldrDir();
}
/**
@@ -546,6 +564,7 @@
*/
public Set<File> getAllCLDRFilesEndingWith(final String suffix) {
FilenameFilter filter = new FilenameFilter() {
+ @Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix) && !isJunkFile(name); // skip junk and backup files
}
@@ -564,7 +583,7 @@
*/
public Set<File> getCLDRFilesMatching(FilenameFilter filter, final File baseDir) {
Set<File> list;
- list = new LinkedHashSet<File>();
+ list = new LinkedHashSet<>();
for (String subdir : getCLDRDataDirectories()) {
getFilesRecursively(new File(baseDir, subdir), filter, list);
}
diff --git a/tools/java/org/unicode/cldr/util/CLDRFile.java b/tools/java/org/unicode/cldr/util/CLDRFile.java
index 2bdae75..19deab0 100644
--- a/tools/java/org/unicode/cldr/util/CLDRFile.java
+++ b/tools/java/org/unicode/cldr/util/CLDRFile.java
@@ -11,9 +11,10 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
-import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -37,30 +38,29 @@
import java.util.regex.Pattern;
import org.unicode.cldr.util.DayPeriodInfo.DayPeriod;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
import org.unicode.cldr.util.With.SimpleIterator;
+import org.unicode.cldr.util.XMLFileReader.AllHandler;
import org.unicode.cldr.util.XMLSource.ResolvingSource;
import org.unicode.cldr.util.XPathParts.Comments;
import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
-import org.xml.sax.ext.DeclHandler;
-import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.UncheckedExecutionException;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -99,8 +99,10 @@
* http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/DTDHandler.html
*/
-public class CLDRFile implements Freezable<CLDRFile>, Iterable<String> {
+public class CLDRFile implements Freezable<CLDRFile>, Iterable<String>, LocaleStringProvider {
+ private static final boolean SEED_ONLY = true;
+ private static final ImmutableSet<String> casesNominativeOnly = ImmutableSet.of(GrammaticalFeature.grammaticalCase.getDefault(null));
/**
* Variable to control whether File reads are buffered; this will about halve the time spent in
* loadFromFile() and Factory.make() from about 20 % to about 10 %. It will also noticeably improve the different
@@ -123,12 +125,13 @@
public static final String SUPPLEMENTAL_NAME = "supplementalData";
public static final String SUPPLEMENTAL_METADATA = "supplementalMetadata";
public static final String SUPPLEMENTAL_PREFIX = "supplemental";
- public static final String GEN_VERSION = "37";
- public static final List<String> SUPPLEMENTAL_NAMES = Arrays.asList("characters", "coverageLevels", "dayPeriods", "genderList", "grammaticalFeatures", "languageInfo",
- "languageGroup", "likelySubtags", "metaZones", "numberingSystems", "ordinals", "plurals", "postalCodeData", "rgScope", "supplementalData",
- "supplementalMetadata", "telephoneCodeData", "units", "windowsZones");
+ public static final String GEN_VERSION = "38.1";
+ public static final List<String> SUPPLEMENTAL_NAMES = Arrays.asList("characters", "coverageLevels", "dayPeriods", "genderList", "grammaticalFeatures",
+ "languageInfo",
+ "languageGroup", "likelySubtags", "metaZones", "numberingSystems", "ordinals", "pluralRanges", "plurals", "postalCodeData", "rgScope",
+ "supplementalData", "supplementalMetadata", "telephoneCodeData", "units", "windowsZones");
- private Collection<String> extraPaths = null;
+ private Set<String> extraPaths = null;
private boolean locked;
private DtdType dtdType;
@@ -145,8 +148,9 @@
return string == null ? DraftStatus.approved
: DraftStatus.valueOf(string.toLowerCase(Locale.ENGLISH));
}
- };
+ }
+ @Override
public String toString() {
return "{"
+ "locked=" + locked
@@ -196,8 +200,21 @@
}
}
+ /**
+ * get Unresolved CLDRFile
+ * @param localeId
+ * @param file
+ * @param minimumDraftStatus
+ */
+ public CLDRFile(String localeId, List<File> dirs, DraftStatus minimalDraftStatus) {
+ // order matters
+ this.dataSource = XMLSource.getFrozenInstance(localeId, dirs, minimalDraftStatus);
+ this.dtdType = dataSource.getXMLNormalizingDtdType();
+ this.dtdData = DtdData.getInstance(this.dtdType);
+ }
+
public CLDRFile(XMLSource dataSource, XMLSource... resolvingParents) {
- List<XMLSource> sourceList = new ArrayList<XMLSource>();
+ List<XMLSource> sourceList = new ArrayList<>();
sourceList.add(dataSource);
sourceList.addAll(Arrays.asList(resolvingParents));
this.dataSource = new ResolvingSource(sourceList);
@@ -211,7 +228,7 @@
public static CLDRFile loadFromFile(File f, String localeName, DraftStatus minimalDraftStatus, XMLSource source) {
String fullFileName = f.getAbsolutePath();
try {
- fullFileName = f.getCanonicalPath();
+ fullFileName = PathUtilities.getNormalizedPathString(f);
if (DEBUG_LOGGING) {
System.out.println("Parsing: " + fullFileName);
Log.logln(LOG_PROGRESS, "Parsing: " + fullFileName);
@@ -255,7 +272,7 @@
for (File dir : dirs) {
File f = new File(dir, localeName + ".xml");
try (InputStream fis = InputStreamFactory.createInputStream(f)) {
- cldrFile.loadFromInputStream(f.getCanonicalPath(), localeName, fis, minimalDraftStatus);
+ cldrFile.loadFromInputStream(PathUtilities.getNormalizedPathString(f), localeName, fis, minimalDraftStatus);
}
}
return cldrFile;
@@ -314,43 +331,24 @@
*/
public CLDRFile loadFromInputStream(String fileName, String localeName, InputStream fis, DraftStatus minimalDraftStatus) {
CLDRFile cldrFile = this;
- try {
- fis = new StripUTF8BOMInputStream(fis);
- MyDeclHandler DEFAULT_DECLHANDLER = new MyDeclHandler(cldrFile, minimalDraftStatus);
-
- // now fill it.
-
- XMLReader xmlReader = createXMLReader(true);
- xmlReader.setContentHandler(DEFAULT_DECLHANDLER);
- xmlReader.setErrorHandler(DEFAULT_DECLHANDLER);
- xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", DEFAULT_DECLHANDLER);
- xmlReader.setProperty("http://xml.org/sax/properties/declaration-handler", DEFAULT_DECLHANDLER);
- InputSource is = new InputSource(fis);
- is.setSystemId(fileName);
- xmlReader.parse(is);
- if (DEFAULT_DECLHANDLER.isSupplemental < 0) {
- throw new IllegalArgumentException("root of file must be either ldml or supplementalData");
- }
- cldrFile.setNonInheriting(DEFAULT_DECLHANDLER.isSupplemental > 0);
- if (DEFAULT_DECLHANDLER.overrideCount > 0) {
- throw new IllegalArgumentException("Internal problems: either data file has duplicate path, or" +
- " CLDRFile.isDistinguishing() or CLDRFile.isOrdered() need updating: "
- + DEFAULT_DECLHANDLER.overrideCount
- + "; The exact problems are printed on the console above.");
- }
- if (localeName == null) {
- cldrFile.dataSource.setLocaleID(cldrFile.getLocaleIDFromIdentity());
- }
- return cldrFile;
- } catch (SAXParseException e) {
- // System.out.println(CLDRFile.showSAX(e));
- throw (IllegalArgumentException) new IllegalArgumentException("Can't read " + localeName + "\t"
- + CLDRFile.showSAX(e)).initCause(e);
- } catch (SAXException e) {
- throw (IllegalArgumentException) new IllegalArgumentException("Can't read " + localeName).initCause(e);
- } catch (IOException e) {
- throw new ICUUncheckedIOException("Can't read " + localeName, e);
+ fis = new StripUTF8BOMInputStream(fis);
+ InputStreamReader reader = new InputStreamReader(fis, Charset.forName("UTF-8"));
+ MyDeclHandler DEFAULT_DECLHANDLER = new MyDeclHandler(cldrFile, minimalDraftStatus);
+ XMLFileReader.read(fileName, reader, -1, true, DEFAULT_DECLHANDLER);
+ if (DEFAULT_DECLHANDLER.isSupplemental < 0) {
+ throw new IllegalArgumentException("root of file must be either ldml or supplementalData");
}
+ cldrFile.setNonInheriting(DEFAULT_DECLHANDLER.isSupplemental > 0);
+ if (DEFAULT_DECLHANDLER.overrideCount > 0) {
+ throw new IllegalArgumentException("Internal problems: either data file has duplicate path, or" +
+ " CLDRFile.isDistinguishing() or CLDRFile.isOrdered() need updating: "
+ + DEFAULT_DECLHANDLER.overrideCount
+ + "; The exact problems are printed on the console above.");
+ }
+ if (localeName == null) {
+ cldrFile.dataSource.setLocaleID(cldrFile.getLocaleIDFromIdentity());
+ }
+ return cldrFile;
}
/**
@@ -358,11 +356,12 @@
*
* @see com.ibm.icu.dev.test.util.Freezeble
*/
+ @Override
public CLDRFile cloneAsThawed() {
try {
CLDRFile result = (CLDRFile) super.clone();
result.locked = false;
- result.dataSource = (XMLSource) result.dataSource.cloneAsThawed();
+ result.dataSource = result.dataSource.cloneAsThawed();
return result;
} catch (CloneNotSupportedException e) {
throw new InternalError("should never happen");
@@ -406,8 +405,8 @@
* TODO: shorten this method (over 170 lines) using subroutines.
*/
public boolean write(PrintWriter pw, Map<String, ?> options) {
- Set<String> orderedSet = new TreeSet<String>(getComparator());
- CollectionUtilities.addAll(dataSource.iterator(), orderedSet);
+ Set<String> orderedSet = new TreeSet<>(getComparator());
+ dataSource.forEach(orderedSet::add);
String firstPath = null;
String firstFullPath = null;
@@ -416,7 +415,7 @@
boolean suppressInheritanceMarkers = false;
if (orderedSet.size() > 0) { // May not have any elements.
- firstPath = (String) orderedSet.iterator().next();
+ firstPath = orderedSet.iterator().next();
firstFullPath = getFullXPath(firstPath);
firstFullPathParts = XPathParts.getFrozenInstance(firstFullPath);
dtdType = DtdType.valueOf(firstFullPathParts.getElement(0));
@@ -447,7 +446,7 @@
* <language type="en"/>
*/
// if ldml has any attributes, get them.
- Set<String> identitySet = new TreeSet<String>(getComparator());
+ Set<String> identitySet = new TreeSet<>(getComparator());
if (!isNonInheriting()) {
String ldml_identity = "//ldml/identity";
if (firstFullPath != null) { // if we had a path
@@ -491,11 +490,11 @@
* There is no difference between "filtered" and "not filtered" in this loop.
*/
for (Iterator<String> it2 = identitySet.iterator(); it2.hasNext();) {
- String xpath = (String) it2.next();
+ String xpath = it2.next();
if (isResolved && xpath.contains("/alias")) {
continue;
}
- XPathParts current = XPathParts.getInstance(xpath);
+ XPathParts current = XPathParts.getFrozenInstance(xpath).cloneAsThawed();
current.writeDifference(pw, current, last, "", tempComments);
last = current;
}
@@ -520,12 +519,12 @@
* The difference between "filtered" (currentFiltered) and "not filtered" (current) is that
* current uses getFullXPath(xpath), while currentFiltered uses xpath.
*/
- XPathParts currentFiltered = XPathParts.getInstance(xpath);
+ XPathParts currentFiltered = XPathParts.getFrozenInstance(xpath).cloneAsThawed();
if (currentFiltered.size() >= 2
&& currentFiltered.getElement(1).equals("identity")) {
continue;
}
- XPathParts current = XPathParts.getInstance(getFullXPath(xpath));
+ XPathParts current = XPathParts.getFrozenInstance(getFullXPath(xpath)).cloneAsThawed();
current.writeDifference(pw, currentFiltered, last, v, tempComments);
last = current;
wroteAtLeastOnePath = true;
@@ -589,11 +588,12 @@
/**
* Get a string value from an xpath.
*/
+ @Override
public String getStringValue(String xpath) {
try {
String result = dataSource.getValueAtPath(xpath);
if (result == null && dataSource.isResolving()) {
- final String fallbackPath = getFallbackPath(xpath, false);
+ final String fallbackPath = getFallbackPath(xpath, false, true);
if (fallbackPath != null) {
result = dataSource.getValueAtPath(fallbackPath);
}
@@ -605,15 +605,29 @@
}
/**
- * Get GeorgeBailey value: that is, what the value would be if it were not directly contained in the file.
+ * Get GeorgeBailey value: that is, what the value would be if it were not directly contained in the file at that path.
+ * If the value is null or INHERITANCE_MARKER (with resolving), then baileyValue = resolved value.
* A non-resolving CLDRFile will always return null.
*/
public String getBaileyValue(String xpath, Output<String> pathWhereFound, Output<String> localeWhereFound) {
String result = dataSource.getBaileyValue(xpath, pathWhereFound, localeWhereFound);
if ((result == null || result.equals(CldrUtility.INHERITANCE_MARKER)) && dataSource.isResolving()) {
- final String fallbackPath = getFallbackPath(xpath, false);
+ final String fallbackPath = getFallbackPath(xpath, false, false); // return null if there is no different sideways path
+ if (xpath.equals(fallbackPath)) {
+ getFallbackPath(xpath, false, true);
+ throw new IllegalArgumentException(); // should never happen
+ }
if (fallbackPath != null) {
- result = dataSource.getBaileyValue(fallbackPath, pathWhereFound, localeWhereFound);
+ result = dataSource.getValueAtPath(fallbackPath);
+ if (result != null) {
+ Status status = new Status();
+ if (localeWhereFound != null) {
+ localeWhereFound.value = dataSource.getSourceLocaleID(fallbackPath, status);
+ }
+ if (pathWhereFound != null) {
+ pathWhereFound.value = status.pathWhereFound;
+ }
+ }
}
}
return result;
@@ -626,10 +640,11 @@
this.alt = alt;
}
+ @Override
public String transform(@SuppressWarnings("unused") String source) {
return alt;
}
- };
+ }
/**
* Get the constructed GeorgeBailey value: that is, if the item would otherwise be constructed (such as "Chinese (Simplified)") use that.
@@ -653,18 +668,19 @@
/**
* Only call if xpath doesn't exist in the current file.
* <p>
- * For now, just handle counts: see getCountPath Also handle extraPaths
+ * For now, just handle counts and cases: see getCountPath Also handle extraPaths
*
* @param xpath
* @param winning
* TODO
+ * @param checkExtraPaths TODO
* @return
*/
- private String getFallbackPath(String xpath, boolean winning) {
- if (xpath.contains("[@count=")) {
+ private String getFallbackPath(String xpath, boolean winning, boolean checkExtraPaths) {
+ if (GrammaticalFeature.pathHasFeature(xpath) != null) {
return getCountPathWithFallback(xpath, Count.other, winning);
}
- if (getRawExtraPaths().contains(xpath)) {
+ if (checkExtraPaths && getRawExtraPaths().contains(xpath)) {
return xpath;
}
return null;
@@ -689,14 +705,15 @@
throw new NullPointerException("Null distinguishing xpath");
}
String result = dataSource.getFullPath(xpath);
- if (result == null && dataSource.isResolving()) {
- String fallback = getFallbackPath(xpath, true);
- if (fallback != null) {
- // TODO, add attributes from fallback into main
- result = xpath;
- }
- }
- return result;
+ return result != null ? result : xpath; // we can't add any non-distinguishing values if there is nothing there.
+// if (result == null && dataSource.isResolving()) {
+// String fallback = getFallbackPath(xpath, true);
+// if (fallback != null) {
+// // TODO, add attributes from fallback into main
+// result = xpath;
+// }
+// }
+// return result;
}
/**
@@ -716,6 +733,7 @@
* @param status
* the distinguished path where the item was found. Pass in null if you don't care.
*/
+ @Override
public String getSourceLocaleID(String distinguishedXPath, CLDRFile.Status status) {
return getSourceLocaleIdExtended(distinguishedXPath, status, true /* skipInheritanceMarker */);
}
@@ -734,7 +752,7 @@
public String getSourceLocaleIdExtended(String distinguishedXPath, CLDRFile.Status status, boolean skipInheritanceMarker) {
String result = dataSource.getSourceLocaleIdExtended(distinguishedXPath, status, skipInheritanceMarker);
if (result == XMLSource.CODE_FALLBACK_ID && dataSource.isResolving()) {
- final String fallbackPath = getFallbackPath(distinguishedXPath, false);
+ final String fallbackPath = getFallbackPath(distinguishedXPath, false, true);
if (fallbackPath != null && !fallbackPath.equals(distinguishedXPath)) {
result = dataSource.getSourceLocaleIdExtended(fallbackPath, status, skipInheritanceMarker);
}
@@ -813,7 +831,7 @@
dataSource.putAll(other.dataSource, MERGE_REPLACE_MINE);
} else if (conflict_resolution == MERGE_REPLACE_MY_DRAFT) {
// first find all my alt=..proposed items
- Set<String> hasDraftVersion = new HashSet<String>();
+ Set<String> hasDraftVersion = new HashSet<>();
for (Iterator<String> it = dataSource.iterator(); it.hasNext();) {
String cpath = it.next();
String fullpath = getFullXPath(cpath);
@@ -857,7 +875,7 @@
&& !key.startsWith("//ldml/identity")) {
for (int i = 0;; ++i) {
String prop = "proposed" + (i == 0 ? "" : String.valueOf(i));
- XPathParts parts = XPathParts.getInstance(other.getFullXPath(key)); // not frozen, for addAttribut
+ XPathParts parts = XPathParts.getFrozenInstance(other.getFullXPath(key)).cloneAsThawed(); // not frozen, for addAttribut
String fullPath = parts.addAttribute("alt", prop).toString();
String path = getDistinguishingXPath(fullPath, null);
if (dataSource.getValueAtPath(path) != null) {
@@ -962,7 +980,7 @@
"|numbers/symbols/(decimal/group)" +
"|timeZoneNames/(hourFormat|gmtFormat|regionFormat)" +
"|pattern" +
- ")");
+ ")");
static public final Pattern specialsToPushFromRoot = PatternCache.get(
"/(" +
@@ -973,7 +991,7 @@
"(?!.*\\[@type=\"stand-alone\"].*\\[@type=\"(abbreviated|wide)\"])" +
"|numbers/symbols/(decimal/group)" +
"|timeZoneNames/(hourFormat|gmtFormat|regionFormat)" +
- ")");
+ ")");
private static final boolean MINIMIZE_ALT_PROPOSED = false;
@@ -1001,11 +1019,11 @@
// Matcher specialPathMatcher = dontRemoveSpecials ? specialsToKeep.matcher("") : null;
boolean first = true;
if (removedItems == null) {
- removedItems = new ArrayList<String>();
+ removedItems = new ArrayList<>();
} else {
removedItems.clear();
}
- Set<String> checked = new HashSet<String>();
+ Set<String> checked = new HashSet<>();
for (Iterator<String> it = iterator(); it.hasNext();) { // see what items we have that the other also has
String curXpath = it.next();
boolean logicDuplicate = true;
@@ -1046,7 +1064,7 @@
continue;
}
}
- String keepValue = (String) XMLSource.getPathsAllowingDuplicates().get(xpath);
+ String keepValue = XMLSource.getPathsAllowingDuplicates().get(xpath);
if (keepValue != null && keepValue.equals(currentValue)) {
logicDuplicate = false;
continue;
@@ -1115,6 +1133,7 @@
/**
* @return Returns the locale ID. In the case of a supplemental data file, it is SUPPLEMENTAL_NAME.
*/
+ @Override
public String getLocaleID() {
return dataSource.getLocaleID();
}
@@ -1144,6 +1163,7 @@
/**
* @see com.ibm.icu.util.Freezable#isFrozen()
*/
+ @Override
public synchronized boolean isFrozen() {
return locked;
}
@@ -1151,6 +1171,7 @@
/**
* @see com.ibm.icu.util.Freezable#freeze()
*/
+ @Override
public synchronized CLDRFile freeze() {
locked = true;
dataSource.freeze();
@@ -1179,7 +1200,7 @@
if (locked) throw new UnsupportedOperationException("Attempt to modify locked object");
dataSource.getXpathComments().setFinalComment(
CldrUtility
- .joinWithSeparation(dataSource.getXpathComments().getFinalComment(), XPathParts.NEWLINE, comment));
+ .joinWithSeparation(dataSource.getXpathComments().getFinalComment(), XPathParts.NEWLINE, comment));
return this;
}
@@ -1199,7 +1220,7 @@
* Note that supplementalData is always skipped, and root is always included.
*/
public static Set<String> getMatchingXMLFiles(File sourceDirs[], Matcher m) {
- Set<String> s = new TreeSet<String>();
+ Set<String> s = new TreeSet<>();
for (File dir : sourceDirs) {
if (!dir.exists()) {
@@ -1221,6 +1242,7 @@
return s;
}
+ @Override
public Iterator<String> iterator() {
return dataSource.iterator();
}
@@ -1236,11 +1258,11 @@
public Iterator<String> iterator(String prefix, Comparator<String> comparator) {
Iterator<String> it = (prefix == null || prefix.length() == 0)
? dataSource.iterator()
- : dataSource.iterator(prefix);
- if (comparator == null) return it;
- Set<String> orderedSet = new TreeSet<String>(comparator);
- CollectionUtilities.addAll(it, orderedSet);
- return orderedSet.iterator();
+ : dataSource.iterator(prefix);
+ if (comparator == null) return it;
+ Set<String> orderedSet = new TreeSet<>(comparator);
+ it.forEachRemaining(orderedSet::add);
+ return orderedSet.iterator();
}
public Iterable<String> fullIterable() {
@@ -1308,9 +1330,9 @@
return xpath;
}
synchronized (syncObject) {
- XPathParts parts = XPathParts.getInstance(xpath); // can't be frozen since we call removeAttributes
+ XPathParts parts = XPathParts.getFrozenInstance(xpath).cloneAsThawed(); // can't be frozen since we call removeAttributes
String restore;
- HashSet<String> toRemove = new HashSet<String>();
+ HashSet<String> toRemove = new HashSet<>();
for (int i = 0; i < parts.size(); ++i) {
if (parts.getAttributeCount(i) == 0) {
continue;
@@ -1323,7 +1345,7 @@
if (attribute.equals("draft")) {
toRemove.add(attribute);
} else if (attribute.equals("alt")) {
- String value = (String) attributes.get(attribute);
+ String value = attributes.get(attribute);
int proposedPos = value.indexOf("proposed");
if (proposedPos >= 0) {
toRemove.add(attribute);
@@ -1370,9 +1392,9 @@
try {
result = (testList[i].length() != 0)
? XMLReaderFactory.createXMLReader(testList[i])
- : XMLReaderFactory.createXMLReader();
- result.setFeature("http://xml.org/sax/features/validation", validating);
- break;
+ : XMLReaderFactory.createXMLReader();
+ result.setFeature("http://xml.org/sax/features/validation", validating);
+ break;
} catch (SAXException e1) {
}
}
@@ -1408,6 +1430,7 @@
*/
public File[] getSupplementalXMLFiles() {
return getSupplementalDirectory().listFiles(new FilenameFilter() {
+ @Override
public boolean accept(@SuppressWarnings("unused") File dir, String name) {
return name.endsWith(".xml");
}
@@ -1438,26 +1461,26 @@
// "gb2312han"};
/* *//**
- * Value that contains a node. WARNING: this is not done yet, and may change.
- * In particular, we don't want to return a Node, since that is mutable, and makes caching unsafe!!
- */
+ * Value that contains a node. WARNING: this is not done yet, and may change.
+ * In particular, we don't want to return a Node, since that is mutable, and makes caching unsafe!!
+ */
/*
* static public class NodeValue extends Value {
* private Node nodeValue;
*//**
- * Creation. WARNING, may change.
- *
- * @param value
- * @param currentFullXPath
- */
+ * Creation. WARNING, may change.
+ *
+ * @param value
+ * @param currentFullXPath
+ */
/*
* public NodeValue(Node value, String currentFullXPath) {
* super(currentFullXPath);
* this.nodeValue = value;
* }
*//**
- * boilerplate
- */
+ * boilerplate
+ */
/*
* public boolean hasSameValue(Object other) {
@@ -1465,8 +1488,8 @@
* return nodeValue.equals(((NodeValue)other).nodeValue);
* }
*//**
- * boilerplate
- */
+ * boilerplate
+ */
/*
* public String getStringValue() {
* return nodeValue.toString();
@@ -1481,7 +1504,7 @@
* }
*/
- private static class MyDeclHandler implements DeclHandler, ContentHandler, LexicalHandler, ErrorHandler {
+ private static class MyDeclHandler implements AllHandler {
private static UnicodeSet whitespace = new UnicodeSet("[:whitespace:]");
private DraftStatus minimalDraftStatus;
private static final boolean SHOW_START_END = false;
@@ -1619,7 +1642,7 @@
/**
* Types which changed from 'type' to 'choice', but not in supplemental data.
*/
- private static Set<String> changedTypes = new HashSet<String>(Arrays.asList(new String[] {
+ private static Set<String> changedTypes = new HashSet<>(Arrays.asList(new String[] {
"abbreviationFallback",
"default", "mapping", "measurementSystem", "preferenceOrdering" }));
@@ -1724,10 +1747,10 @@
private void warnOnOverride(String former, String formerPath) {
String distinguishing = CLDRFile.getDistinguishingXPath(formerPath, null);
System.out.println("\tERROR in " + target.getLocaleID()
- + ";\toverriding old value <" + former + "> at path " + distinguishing +
- "\twith\t<" + lastChars + ">" +
- CldrUtility.LINE_SEPARATOR + "\told fullpath: " + formerPath +
- CldrUtility.LINE_SEPARATOR + "\tnew fullpath: " + currentFullXPath);
+ + ";\toverriding old value <" + former + "> at path " + distinguishing +
+ "\twith\t<" + lastChars + ">" +
+ CldrUtility.LINE_SEPARATOR + "\told fullpath: " + formerPath +
+ CldrUtility.LINE_SEPARATOR + "\tnew fullpath: " + currentFullXPath);
overrideCount += 1;
}
@@ -1778,22 +1801,24 @@
// SAX items we need to catch
+ @Override
public void startElement(
String uri,
String localName,
String qName,
Attributes attributes)
- throws SAXException {
+ throws SAXException {
Log.logln(LOG_PROGRESS || SHOW_START_END, "startElement uri\t" + uri
+ "\tlocalName " + localName
+ "\tqName " + qName
+ "\tattributes " + show(attributes));
try {
if (isSupplemental < 0) { // set by first element
- attributeOrder = new TreeMap<String, String>(
+ attributeOrder = new TreeMap<>(
// HACK for ldmlIcu
dtdData.dtdType == DtdType.ldml
- ? CLDRFile.getAttributeOrdering() : dtdData.getAttributeComparator());
+ ? CLDRFile.getAttributeOrdering()
+ : dtdData.getAttributeComparator());
isSupplemental = target.dtdType == DtdType.ldml ? 0 : 1;
}
push(qName, attributes);
@@ -1803,6 +1828,7 @@
}
}
+ @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.logln(LOG_PROGRESS || SHOW_START_END, "endElement uri\t" + uri + "\tlocalName " + localName
@@ -1818,6 +1844,7 @@
//static final char XML_LINESEPARATOR = (char) 0xA;
//static final String XML_LINESEPARATOR_STRING = String.valueOf(XML_LINESEPARATOR);
+ @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
@@ -1835,6 +1862,7 @@
}
}
+ @Override
public void startDTD(String name, String publicId, String systemId) throws SAXException {
Log.logln(LOG_PROGRESS, "startDTD name: " + name
+ ", publicId: " + publicId
@@ -1844,11 +1872,13 @@
target.dtdData = dtdData = DtdData.getInstance(target.dtdType);
}
+ @Override
public void endDTD() throws SAXException {
Log.logln(LOG_PROGRESS, "endDTD");
commentStack--;
}
+ @Override
public void comment(char[] ch, int start, int length) throws SAXException {
final String string = new String(ch, start, length);
Log.logln(LOG_PROGRESS, commentStack + " comment " + string);
@@ -1866,6 +1896,7 @@
}
}
+ @Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
if (LOG_PROGRESS)
Log.logln(LOG_PROGRESS,
@@ -1882,11 +1913,13 @@
// }
}
+ @Override
public void startDocument() throws SAXException {
Log.logln(LOG_PROGRESS, "startDocument");
commentStack = 0; // initialize
}
+ @Override
public void endDocument() throws SAXException {
Log.logln(LOG_PROGRESS, "endDocument");
try {
@@ -1899,58 +1932,71 @@
// ==== The following are just for debuggin =====
+ @Override
public void elementDecl(String name, String model) throws SAXException {
Log.logln(LOG_PROGRESS, "Attribute\t" + name + "\t" + model);
}
+ @Override
public void attributeDecl(String eName, String aName, String type, String mode, String value)
throws SAXException {
Log.logln(LOG_PROGRESS, "Attribute\t" + eName + "\t" + aName + "\t" + type + "\t" + mode + "\t" + value);
}
+ @Override
public void internalEntityDecl(String name, String value) throws SAXException {
Log.logln(LOG_PROGRESS, "Internal Entity\t" + name + "\t" + value);
}
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
Log.logln(LOG_PROGRESS, "Internal Entity\t" + name + "\t" + publicId + "\t" + systemId);
}
+ @Override
public void processingInstruction(String target, String data)
throws SAXException {
Log.logln(LOG_PROGRESS, "processingInstruction: " + target + ", " + data);
}
+ @Override
public void skippedEntity(String name)
throws SAXException {
Log.logln(LOG_PROGRESS, "skippedEntity: " + name);
}
+ @Override
public void setDocumentLocator(Locator locator) {
Log.logln(LOG_PROGRESS, "setDocumentLocator Locator " + locator);
}
+ @Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
Log.logln(LOG_PROGRESS, "startPrefixMapping prefix: " + prefix +
", uri: " + uri);
}
+ @Override
public void endPrefixMapping(String prefix) throws SAXException {
Log.logln(LOG_PROGRESS, "endPrefixMapping prefix: " + prefix);
}
+ @Override
public void startEntity(String name) throws SAXException {
Log.logln(LOG_PROGRESS, "startEntity name: " + name);
}
+ @Override
public void endEntity(String name) throws SAXException {
Log.logln(LOG_PROGRESS, "endEntity name: " + name);
}
+ @Override
public void startCDATA() throws SAXException {
Log.logln(LOG_PROGRESS, "startCDATA");
}
+ @Override
public void endCDATA() throws SAXException {
Log.logln(LOG_PROGRESS, "endCDATA");
}
@@ -1960,6 +2006,7 @@
*
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
+ @Override
public void error(SAXParseException exception) throws SAXException {
Log.logln(LOG_PROGRESS || true, "error: " + showSAX(exception));
throw exception;
@@ -1970,6 +2017,7 @@
*
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
Log.logln(LOG_PROGRESS, "fatalError: " + showSAX(exception));
throw exception;
@@ -1980,6 +2028,7 @@
*
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
+ @Override
public void warning(SAXParseException exception) throws SAXException {
Log.logln(LOG_PROGRESS, "warning: " + showSAX(exception));
throw exception;
@@ -2001,7 +2050,7 @@
* Says whether the whole file is draft
*/
public boolean isDraft() {
- String item = (String) iterator().next();
+ String item = iterator().next();
return item.startsWith("//ldml[@draft=\"unconfirmed\"]");
}
@@ -2266,7 +2315,6 @@
return -1;
}
-
/**
* Returns the name of the given bcp47 identifier. Note that extensions must
* be specified using the old "\@key=type" syntax.
@@ -2332,8 +2380,7 @@
Transform<String, String> altPicker,
String localeKeyTypePattern,
String localePattern,
- String localeSeparator
- ) {
+ String localeSeparator) {
String name;
String original;
@@ -2379,53 +2426,54 @@
}
// Look for key-type pairs.
- main:
- for (Entry<String, List<String>> extension : lparser.getLocaleExtensionsDetailed().entrySet()) {
- String key = extension.getKey();
- if (key.equals("h0")) {
- continue;
- }
- List<String> keyValue = extension.getValue();
- String oldFormatType = (key.equals("ca") ? JOIN_HYPHEN : JOIN_UNDERBAR).join(keyValue); // default value
- // Check if key/type pairs exist in the CLDRFile first.
- String value = getKeyValueName(key, oldFormatType);
- if (value != null) {
- value = value.replace('(', '[').replace(')', ']').replace('(', '[').replace(')', ']');
- } else {
- // if we fail, then we construct from the key name and the value
- String kname = getKeyName(key);
- if (kname == null) {
- kname = key; // should not happen, but just in case
- }
- switch(key) {
- case "t":
- List<String> hybrid = lparser.getLocaleExtensionsDetailed().get("h0");
- if (hybrid != null) {
- kname = getKeyValueName("h0", JOIN_UNDERBAR.join(hybrid));
- }
- oldFormatType = getName(oldFormatType);
- break;
- case "h0":
- continue main;
- case "cu":
- oldFormatType = getName(CURRENCY_SYMBOL, oldFormatType.toUpperCase(Locale.ROOT));
- break;
- case "tz":
- oldFormatType = getTZName(oldFormatType, "VVVV");
- break;
- case "kr":
- oldFormatType = getReorderName(localeSeparator, keyValue);
- break;
- case "rg": case "sd":
- oldFormatType = getName(SUBDIVISION_NAME, oldFormatType);
- break;
- default: oldFormatType = JOIN_HYPHEN.join(keyValue);
- }
- value = MessageFormat.format(localeKeyTypePattern, new Object[] { kname, oldFormatType });
- value = value.replace('(', '[').replace(')', ']').replace('(', '[').replace(')', ']');
- }
- extras = extras.isEmpty() ? value : MessageFormat.format(localeSeparator, new Object[] { extras, value });
+ main: for (Entry<String, List<String>> extension : lparser.getLocaleExtensionsDetailed().entrySet()) {
+ String key = extension.getKey();
+ if (key.equals("h0")) {
+ continue;
}
+ List<String> keyValue = extension.getValue();
+ String oldFormatType = (key.equals("ca") ? JOIN_HYPHEN : JOIN_UNDERBAR).join(keyValue); // default value
+ // Check if key/type pairs exist in the CLDRFile first.
+ String value = getKeyValueName(key, oldFormatType);
+ if (value != null) {
+ value = value.replace('(', '[').replace(')', ']').replace('(', '[').replace(')', ']');
+ } else {
+ // if we fail, then we construct from the key name and the value
+ String kname = getKeyName(key);
+ if (kname == null) {
+ kname = key; // should not happen, but just in case
+ }
+ switch (key) {
+ case "t":
+ List<String> hybrid = lparser.getLocaleExtensionsDetailed().get("h0");
+ if (hybrid != null) {
+ kname = getKeyValueName("h0", JOIN_UNDERBAR.join(hybrid));
+ }
+ oldFormatType = getName(oldFormatType);
+ break;
+ case "h0":
+ continue main;
+ case "cu":
+ oldFormatType = getName(CURRENCY_SYMBOL, oldFormatType.toUpperCase(Locale.ROOT));
+ break;
+ case "tz":
+ oldFormatType = getTZName(oldFormatType, "VVVV");
+ break;
+ case "kr":
+ oldFormatType = getReorderName(localeSeparator, keyValue);
+ break;
+ case "rg":
+ case "sd":
+ oldFormatType = getName(SUBDIVISION_NAME, oldFormatType);
+ break;
+ default:
+ oldFormatType = JOIN_HYPHEN.join(keyValue);
+ }
+ value = MessageFormat.format(localeKeyTypePattern, new Object[] { kname, oldFormatType });
+ value = value.replace('(', '[').replace(')', ']').replace('(', '[').replace(')', ']');
+ }
+ extras = extras.isEmpty() ? value : MessageFormat.format(localeSeparator, new Object[] { extras, value });
+ }
// now handle stray extensions
for (Entry<String, List<String>> extension : lparser.getExtensionsDetailed().entrySet()) {
String value = MessageFormat.format(localeKeyTypePattern, new Object[] { extension.getKey(), JOIN_HYPHEN.join(extension.getValue()) });
@@ -2519,8 +2567,6 @@
return result;
}
-
-
/**
* Returns the name of the given bcp47 identifier. Note that extensions must
* be specified using the old "\@key=type" syntax.
@@ -2536,6 +2582,7 @@
* For use in getting short names.
*/
public static final Transform<String, String> SHORT_ALTS = new Transform<String, String>() {
+ @Override
public String transform(@SuppressWarnings("unused") String source) {
return "short";
}
@@ -2558,8 +2605,7 @@
getWinningValueWithBailey("//ldml/localeDisplayNames/localeDisplayPattern/localeKeyTypePattern"),
getWinningValueWithBailey("//ldml/localeDisplayNames/localeDisplayPattern/localePattern"),
getWinningValueWithBailey("//ldml/localeDisplayNames/localeDisplayPattern/localeSeparator"),
- altPicker
- );
+ altPicker);
}
/**
@@ -2603,6 +2649,7 @@
* @return ordered collection with items.
* @deprecated
*/
+ @Deprecated
public static List<String> getElementOrder() {
return Collections.emptyList(); // elementOrdering.getOrder(); // already unmodifiable
}
@@ -2688,8 +2735,8 @@
public CLDRFile makeDraft(DraftStatus draftStatus) {
if (locked) throw new UnsupportedOperationException("Attempt to modify locked object");
for (Iterator<String> it = dataSource.iterator(); it.hasNext();) {
- String path = (String) it.next();
- XPathParts parts = XPathParts.getInstance(dataSource.getFullPath(path)); // not frozen, for addAttribute
+ String path = it.next();
+ XPathParts parts = XPathParts.getFrozenInstance(dataSource.getFullPath(path)).cloneAsThawed(); // not frozen, for addAttribute
parts.addAttribute("draft", draftStatus.toString());
dataSource.putValueAtPath(parts.toString(), dataSource.getValueAtPath(path));
}
@@ -2706,7 +2753,7 @@
static final UnicodeSet HACK_CASE_CLOSURE_SET = new UnicodeSet(
"[ſẛffẞ{i̇}\u1F71\u1F73\u1F75\u1F77\u1F79\u1F7B\u1F7D\u1FBB\u1FBE\u1FC9\u1FCB\u1FD3\u1FDB\u1FE3\u1FEB\u1FF9\u1FFB\u2126\u212A\u212B]")
- .freeze();
+ .freeze();
public enum ExemplarType {
main, auxiliary, index, punctuation, numbers;
@@ -2749,7 +2796,7 @@
private NumberingSystem(String path) {
this.path = path;
}
- };
+ }
public UnicodeSet getExemplarsNumeric(NumberingSystem system) {
String numberingSystem = system.path == null ? "latn" : getStringValue(system.path);
@@ -2789,7 +2836,7 @@
public String getCurrentMetazone(String zone) {
for (Iterator<String> it2 = iterator(); it2.hasNext();) {
- String xpath = (String) it2.next();
+ String xpath = it2.next();
if (xpath.startsWith("//ldml/dates/timeZoneNames/zone[@type=\"" + zone + "\"]/usesMetazone")) {
XPathParts parts = XPathParts.getFrozenInstance(xpath);
if (!parts.containsAttribute("to")) {
@@ -2822,8 +2869,8 @@
"normalizedPathMap:" + normalizedPathMap.size();
}
- private static Map<String, String> distinguishingMap = new ConcurrentHashMap<String, String>();
- private static Map<String, String> normalizedPathMap = new ConcurrentHashMap<String, String>();
+ private static Map<String, String> distinguishingMap = new ConcurrentHashMap<>();
+ private static Map<String, String> normalizedPathMap = new ConcurrentHashMap<>();
static {
distinguishingMap.put("", ""); // seed this to make the code simpler
@@ -2831,12 +2878,12 @@
public static String getDistinguishingXPath(String xpath, String[] normalizedPath) {
// synchronized (distinguishingMap) {
- String result = (String) distinguishingMap.get(xpath);
+ String result = distinguishingMap.get(xpath);
if (result == null) {
- XPathParts distinguishingParts = XPathParts.getInstance(xpath); // not frozen, for removeAttributes
+ XPathParts distinguishingParts = XPathParts.getFrozenInstance(xpath).cloneAsThawed(); // not frozen, for removeAttributes
DtdType type = distinguishingParts.getDtdData().dtdType;
- Set<String> toRemove = new HashSet<String>();
+ Set<String> toRemove = new HashSet<>();
// first clean up draft and alt
String draft = null;
@@ -2855,14 +2902,14 @@
Map<String, String> attributes = distinguishingParts.getAttributes(i);
for (String attribute : attributes.keySet()) {
if (attribute.equals("draft")) {
- draft = (String) attributes.get(attribute);
+ draft = attributes.get(attribute);
toRemove.add(attribute);
} else if (attribute.equals("alt")) {
- alt = (String) attributes.get(attribute);
+ alt = attributes.get(attribute);
toRemove.add(attribute);
} else if (attribute.equals("references")) {
if (references.length() != 0) references += " ";
- references += (String) attributes.get("references");
+ references += attributes.get("references");
toRemove.add(attribute);
}
}
@@ -2913,7 +2960,7 @@
distinguishingMap.put(xpath, result);
}
if (normalizedPath != null) {
- normalizedPath[0] = (String) normalizedPathMap.get(xpath);
+ normalizedPath[0] = normalizedPathMap.get(xpath);
if (normalizedPath[0] == null) {
normalizedPath[0] = xpath;
}
@@ -2924,7 +2971,7 @@
public Map<String, String> getNonDistinguishingAttributes(String fullPath, Map<String, String> result,
Set<String> skipList) {
if (result == null) {
- result = new LinkedHashMap<String, String>();
+ result = new LinkedHashMap<>();
} else {
result.clear();
}
@@ -2947,6 +2994,7 @@
public static class Status {
public String pathWhereFound;
+ @Override
public String toString() {
return pathWhereFound;
}
@@ -2985,7 +3033,7 @@
String versionString = parts.findFirstAttributeValue("version");
return versionString == null
? null
- : VersionInfo.getInstance(versionString);
+ : VersionInfo.getInstance(versionString);
}
private boolean contains(Map<String, String> a, Map<String, String> b) {
@@ -3010,7 +3058,7 @@
Map<String, String> lastAttributes = parts.getAttributes(parts.size() - 1);
String base = parts.toString(parts.size() - 1) + "/" + parts.getElement(parts.size() - 1); // trim final element
for (Iterator<String> it = iterator(base); it.hasNext();) {
- String otherPath = (String) it.next();
+ String otherPath = it.next();
XPathParts other = XPathParts.getFrozenInstance(otherPath);
if (other.size() != parts.size()) {
continue;
@@ -3079,8 +3127,8 @@
public String getWinningValueWithBailey(String path) {
String winningValue = getWinningValue(path);
if (CldrUtility.INHERITANCE_MARKER.equals(winningValue)) {
- Output<String> localeWhereFound = new Output<String>();
- Output<String> pathWhereFound = new Output<String>();
+ Output<String> localeWhereFound = new Output<>();
+ Output<String> pathWhereFound = new Output<>();
winningValue = getBaileyValue(path, pathWhereFound, localeWhereFound);
}
return winningValue;
@@ -3100,8 +3148,8 @@
public String getStringValueWithBailey(String path) {
String value = getStringValue(path);
if (CldrUtility.INHERITANCE_MARKER.equals(value)) {
- Output<String> localeWhereFound = new Output<String>();
- Output<String> pathWhereFound = new Output<String>();
+ Output<String> localeWhereFound = new Output<>();
+ Output<String> pathWhereFound = new Output<>();
value = getBaileyValue(path, pathWhereFound, localeWhereFound);
}
return value;
@@ -3142,7 +3190,7 @@
*/
public Set<String> getPathsWithValue(String valueToMatch, String pathPrefix, Matcher pathMatcher, Set<String> result) {
if (result == null) {
- result = new HashSet<String>();
+ result = new HashSet<>();
}
dataSource.getPathsWithValue(valueToMatch, pathPrefix, result);
if (pathMatcher == null) {
@@ -3167,7 +3215,7 @@
*/
public Set<String> getPaths(String pathPrefix, Matcher pathMatcher, Set<String> result) {
if (result == null) {
- result = new HashSet<String>();
+ result = new HashSet<>();
}
for (Iterator<String> it = dataSource.iterator(pathPrefix); it.hasNext();) {
String path = it.next();
@@ -3181,7 +3229,7 @@
public enum WinningChoice {
NORMAL, WINNING
- };
+ }
/**
* Used in TestUser to get the "winning" path. Simple implementation just for testing.
@@ -3201,6 +3249,7 @@
* at
* the number of votes next, and whither there was an approved or provisional path.
*/
+ @Override
public int compare(String o1, String o2) {
if (o1.contains(user)) {
if (!o2.contains(user)) {
@@ -3221,7 +3270,7 @@
*/
public static class TestUser extends CLDRFile {
- Map<String, String> userOverrides = new HashMap<String, String>();
+ Map<String, String> userOverrides = new HashMap<>();
public TestUser(CLDRFile baseFile, String user, boolean resolved) {
super(resolved ? baseFile.dataSource : baseFile.dataSource.getUnresolving());
@@ -3264,7 +3313,7 @@
* @return
*/
public Collection<String> getExtraPaths() {
- Set<String> toAddTo = new HashSet<String>();
+ Set<String> toAddTo = new HashSet<>();
toAddTo.addAll(getRawExtraPaths());
for (String path : this) {
toAddTo.remove(path);
@@ -3294,9 +3343,9 @@
*
* @return
*/
- public Collection<String> getRawExtraPaths() {
+ public Set<String> getRawExtraPaths() {
if (extraPaths == null) {
- extraPaths = Collections.unmodifiableCollection(getRawExtraPathsPrivate(new HashSet<String>()));
+ extraPaths = ImmutableSet.copyOf(getRawExtraPathsPrivate(new LinkedHashSet<String>()));
if (DEBUG) {
System.out.println(getLocaleID() + "\textras: " + extraPaths.size());
}
@@ -3332,7 +3381,7 @@
if (plurals == null && DEBUG) {
System.err.println("No " + PluralType.cardinal + " plurals for " + getLocaleID() + " in " + supplementalData.getDirectory().getAbsolutePath());
}
- Set<Count> pluralCounts = null;
+ Set<Count> pluralCounts = Collections.emptySet();
if (plurals != null) {
pluralCounts = plurals.getCounts();
if (pluralCounts.size() != 1) {
@@ -3344,7 +3393,7 @@
String locale = getLocaleID();
DayPeriodInfo dayPeriods = supplementalData.getDayPeriods(DayPeriodInfo.Type.format, locale);
if (dayPeriods != null) {
- LinkedHashSet<DayPeriod> items = new LinkedHashSet<DayPeriod>(dayPeriods.getPeriods());
+ LinkedHashSet<DayPeriod> items = new LinkedHashSet<>(dayPeriods.getPeriods());
items.add(DayPeriod.am);
items.add(DayPeriod.pm);
for (String context : new String[] { "format", "stand-alone" }) {
@@ -3391,13 +3440,70 @@
String currencyCode = code.toUpperCase();
toAddTo.add("//ldml/numbers/currencies/currency[@type=\"" + currencyCode + "\"]/symbol");
toAddTo.add("//ldml/numbers/currencies/currency[@type=\"" + currencyCode + "\"]/displayName");
- if (pluralCounts != null) {
+ if (!pluralCounts.isEmpty()) {
for (Count count : pluralCounts) {
toAddTo.add("//ldml/numbers/currencies/currency[@type=\"" + currencyCode + "\"]/displayName[@count=\"" + count.toString() + "\"]");
}
}
}
+ // grammatical info
+
+ GrammarInfo grammarInfo = supplementalData.getGrammarInfo(getLocaleID(), true);
+
+ if ("de".equals(getLocaleID())) {
+ int debug = 0;
+ }
+
+ if (grammarInfo != null) {
+ if (grammarInfo.hasInfo(GrammaticalTarget.nominal)) {
+ Collection<String> genders = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+ Collection<String> rawCases = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+ Collection<String> nomCases = rawCases.isEmpty() ? casesNominativeOnly : rawCases;
+ Collection<Count> adjustedPlurals = GrammarInfo.NON_COMPUTABLE_PLURALS.get(locale);
+ if (adjustedPlurals.isEmpty()) {
+ adjustedPlurals = pluralCounts;
+ } else {
+ int debug = 0;
+ }
+
+ // TODO use UnitPathType to get paths
+ if (!genders.isEmpty()) {
+ for (String unit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ toAddTo.add("//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + unit + "\"]/gender");
+ }
+ for (Count plural : adjustedPlurals) {
+ for (String gender : genders) {
+ for (String case1 : nomCases) {
+ final String grammaticalAttributes = GrammarInfo.getGrammaticalInfoAttributes(grammarInfo, UnitPathType.power, plural.toString(),
+ gender, case1);
+ toAddTo
+ .add("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power2\"]/compoundUnitPattern1" + grammaticalAttributes);
+ toAddTo
+ .add("//ldml/units/unitLength[@type=\"long\"]/compoundUnit[@type=\"power3\"]/compoundUnitPattern1" + grammaticalAttributes);
+ }
+ }
+ }
+ // <genderMinimalPairs gender="masculine">Der {0} ist …</genderMinimalPairs>
+ for (String gender : genders) {
+ toAddTo.add("//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"" + gender + "\"]");
+ }
+ }
+ if (!rawCases.isEmpty()) {
+ for (String case1 : rawCases) {
+ // <caseMinimalPairs case="nominative">{0} kostet €3,50.</caseMinimalPairs>
+ toAddTo.add("//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"" + case1 + "\"]");
+
+ for (Count plural : adjustedPlurals) {
+ for (String unit : GrammarInfo.SPECIAL_TRANSLATION_UNITS) {
+ toAddTo.add("//ldml/units/unitLength[@type=\"long\"]/unit[@type=\"" + unit + "\"]/unitPattern"
+ + GrammarInfo.getGrammaticalInfoAttributes(grammarInfo, UnitPathType.unit, plural.toString(), null, case1));
+ }
+ }
+ }
+ }
+ }
+ }
return toAddTo;
}
@@ -3442,7 +3548,7 @@
if (excludedZones == null) {
SupplementalDataInfo supplementalData = CLDRConfig.getInstance().getSupplementalDataInfo();
// SupplementalDataInfo.getInstance(getSupplementalDirectory());
- excludedZones = new HashSet<String>(supplementalData.getSingleRegionZones());
+ excludedZones = new HashSet<>(supplementalData.getSingleRegionZones());
excludedZones = Collections.unmodifiableSet(excludedZones); // protect
}
return excludedZones;
@@ -3450,13 +3556,16 @@
}
/**
- * Get the path with the given count.
- * It acts like there is an alias in root from count=n to count=one,
+ * Get the path with the given count, case, or gender, with fallback. The fallback acts like an alias in root.
+ * <p>Count:</p>
+ * <p>It acts like there is an alias in root from count=n to count=one,
* then for currency display names from count=one to no count <br>
* For unitPatterns, falls back to Count.one. <br>
- * For others, falls back to Count.one, then no count.
- * <p>
- * The fallback acts like an alias in root.
+ * For others, falls back to Count.one, then no count.</p>
+ * <p>Case</p>
+ * <p>The fallback is to no case, which = nominative.</p>
+ * <p>Case</p>
+ * <p>The fallback is to no case, which = nominative.</p>
*
* @param xpath
* @param count
@@ -3467,43 +3576,74 @@
*/
public String getCountPathWithFallback(String xpath, Count count, boolean winning) {
String result;
- XPathParts parts = XPathParts.getInstance(xpath); // not frozen, addAttribute in getCountPathWithFallback2
+ XPathParts parts = XPathParts.getFrozenInstance(xpath).cloneAsThawed(); // not frozen, addAttribute in getCountPathWithFallback2
+
+ // In theory we should do all combinations of gender, case, count (and eventually definiteness), but for simplicity
+ // we just successively try "zeroing" each one in a set order.
+ // tryDefault modifies the parts in question
+ Output<String> newPath = new Output<>();
+ if (tryDefault(parts, "gender", null, newPath)) {
+ return newPath.value;
+ }
+
+ if (tryDefault(parts, "case", null, newPath)) {
+ return newPath.value;
+ }
+
boolean isDisplayName = parts.contains("displayName");
- String intCount = parts.getAttributeValue(-1, "count");
- if (intCount != null && CldrUtility.DIGITS.containsAll(intCount)) {
- try {
- int item = Integer.parseInt(intCount);
- String locale = getLocaleID();
- // TODO get data from SupplementalDataInfo...
- PluralRules rules = PluralRules.forLocale(new ULocale(locale));
- String keyword = rules.select(item);
- Count itemCount = Count.valueOf(keyword);
- result = getCountPathWithFallback2(parts, xpath, itemCount, winning);
- if (result != null && isNotRoot(result)) {
- return result;
+ String actualCount = parts.getAttributeValue(-1, "count");
+ if (actualCount != null) {
+ if (CldrUtility.DIGITS.containsAll(actualCount)) {
+ try {
+ int item = Integer.parseInt(actualCount);
+ String locale = getLocaleID();
+ // TODO get data from SupplementalDataInfo...
+ PluralRules rules = PluralRules.forLocale(new ULocale(locale));
+ String keyword = rules.select(item);
+ Count itemCount = Count.valueOf(keyword);
+ result = getCountPathWithFallback2(parts, xpath, itemCount, winning);
+ if (result != null && isNotRoot(result)) {
+ return result;
+ }
+ } catch (NumberFormatException e) {
}
- } catch (NumberFormatException e) {
}
- }
- // try the given count first
- result = getCountPathWithFallback2(parts, xpath, count, winning);
- if (result != null && isNotRoot(result)) {
- return result;
- }
- // now try fallback
- if (count != Count.other) {
- result = getCountPathWithFallback2(parts, xpath, Count.other, winning);
+ // try the given count first
+ result = getCountPathWithFallback2(parts, xpath, count, winning);
if (result != null && isNotRoot(result)) {
return result;
}
+ // now try fallback
+ if (count != Count.other) {
+ result = getCountPathWithFallback2(parts, xpath, Count.other, winning);
+ if (result != null && isNotRoot(result)) {
+ return result;
+ }
+ }
+ // now try deletion (for currency)
+ if (isDisplayName) {
+ result = getCountPathWithFallback2(parts, xpath, null, winning);
+ }
+ return result;
}
- // now try deletion (for currency)
- if (isDisplayName) {
- result = getCountPathWithFallback2(parts, xpath, null, winning);
+ return null;
+ }
+
+ /**
+ * Modify the parts by setting the attribute in question to the default value (typically null to clear). If there is a value for that path, use it.
+ */
+ public boolean tryDefault(XPathParts parts, String attribute, String defaultValue, Output<String> newPath) {
+ String oldValue = parts.getAttributeValue(-1, attribute);
+ if (oldValue != null) {
+ parts.setAttribute(-1, attribute, null);
+ newPath.value = parts.toString();
+ if (dataSource.getValueAtPath(newPath.value) != null) {
+ return true;
+ }
}
- return result;
+ return false;
}
private String getCountPathWithFallback2(XPathParts parts, String xpathWithNoCount,
@@ -3545,7 +3685,7 @@
if (isNotRoot(winningPath)) {
return getStringValue(winningPath);
}
- String fallbackPath = getFallbackPath(winningPath, true);
+ String fallbackPath = getFallbackPath(winningPath, true, true);
if (fallbackPath != null) {
String value = getWinningValue(fallbackPath);
if (value != null) {
@@ -3704,7 +3844,7 @@
}
String result = dataSource.getValueAtPath(xpath);
if (result == null && dataSource.isResolving()) {
- final String fallbackPath = getFallbackPath(xpath, false);
+ final String fallbackPath = getFallbackPath(xpath, false, true);
if (fallbackPath != null) {
result = dataSource.getValueAtPath(fallbackPath);
}
@@ -3727,4 +3867,42 @@
return sourceFileUnresolved.getStringValue(xpath);
}
+ /**
+ * Create an overriding LocaleStringProvider for testing and example generation
+ * @param pathAndValueOverrides
+ * @return
+ */
+ public LocaleStringProvider makeOverridingStringProvider(Map<String, String> pathAndValueOverrides) {
+ return new OverridingStringProvider(pathAndValueOverrides);
+ }
+
+ public class OverridingStringProvider implements LocaleStringProvider {
+ private final Map<String, String> pathAndValueOverrides;
+
+ public OverridingStringProvider(Map<String, String> pathAndValueOverrides) {
+ this.pathAndValueOverrides = pathAndValueOverrides;
+ }
+
+ @Override
+ public String getStringValue(String xpath) {
+ String value = pathAndValueOverrides.get(xpath);
+ return value != null ? value : CLDRFile.this.getStringValue(xpath);
+ }
+
+ @Override
+ public String getLocaleID() {
+ return CLDRFile.this.getLocaleID();
+ }
+
+ @Override
+ public String getSourceLocaleID(String xpath, Status status) {
+ if (pathAndValueOverrides.containsKey(xpath)) {
+ if (status != null) {
+ status.pathWhereFound = xpath;
+ }
+ return getLocaleID() + "-override";
+ }
+ return CLDRFile.this.getSourceLocaleID(xpath, status);
+ }
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/CLDRInfo.java b/tools/java/org/unicode/cldr/util/CLDRInfo.java
index f455c8d..e171c44 100644
--- a/tools/java/org/unicode/cldr/util/CLDRInfo.java
+++ b/tools/java/org/unicode/cldr/util/CLDRInfo.java
@@ -21,7 +21,7 @@
CandidateInfo getCurrentItem();
String getBaselineValue();
-
+
default Status getBaselineStatus() {
return Status.missing;
}
@@ -29,7 +29,7 @@
Level getCoverageLevel();
boolean hadVotesSometimeThisRelease();
-
+
CLDRLocale getLocale();
String getXpath();
diff --git a/tools/java/org/unicode/cldr/util/CLDRLocale.java b/tools/java/org/unicode/cldr/util/CLDRLocale.java
index d4ad987..76ea9ef 100644
--- a/tools/java/org/unicode/cldr/util/CLDRLocale.java
+++ b/tools/java/org/unicode/cldr/util/CLDRLocale.java
@@ -209,7 +209,7 @@
public enum FormatBehavior {
replace, extend, extendHtml
- };
+ }
/**
* The parent locale id string, or null if no parent
@@ -291,6 +291,7 @@
/**
* Return the full locale name, in CLDR format.
*/
+ @Override
public String toString() {
return fullname;
}
@@ -318,6 +319,7 @@
/**
* Compare to another CLDRLocale. Uses string order of toString().
*/
+ @Override
public int compareTo(CLDRLocale o) {
if (o == this) return 0;
return fullname.compareTo(o.fullname);
@@ -326,6 +328,7 @@
/**
* Hashcode - is the hashcode of the full string
*/
+ @Override
public int hashCode() {
return fullname.hashCode();
}
@@ -389,7 +392,7 @@
return getInstance(u.getBaseName());
}
- private static ConcurrentHashMap<String, CLDRLocale> stringToLoc = new ConcurrentHashMap<String, CLDRLocale>();
+ private static ConcurrentHashMap<String, CLDRLocale> stringToLoc = new ConcurrentHashMap<>();
/**
* Return the parent locale of this item. Null if no parent (root has no parent)
@@ -440,14 +443,17 @@
public Iterable<CLDRLocale> getParentIterator() {
final CLDRLocale newThis = this;
return new Iterable<CLDRLocale>() {
+ @Override
public Iterator<CLDRLocale> iterator() {
return new Iterator<CLDRLocale>() {
CLDRLocale what = newThis;
+ @Override
public boolean hasNext() {
return what.getParent() != null;
}
+ @Override
public CLDRLocale next() {
CLDRLocale curr = what;
if (what != null) {
@@ -456,6 +462,7 @@
return curr;
}
+ @Override
public void remove() {
throw new InternalError("unmodifiable iterator");
}
@@ -506,6 +513,7 @@
/**
* Most objects should be singletons, and so equality/inequality comparison is done first.
*/
+ @Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof CLDRLocale)) return false;
@@ -615,7 +623,7 @@
* @return
*/
public static Set<CLDRLocale> getInstance(Iterable<String> available) {
- Set<CLDRLocale> s = new TreeSet<CLDRLocale>();
+ Set<CLDRLocale> s = new TreeSet<>();
for (String str : available) {
s.add(CLDRLocale.getInstance(str));
}
diff --git a/tools/java/org/unicode/cldr/util/CLDRPaths.java b/tools/java/org/unicode/cldr/util/CLDRPaths.java
index 7d86111..5ca0a85 100644
--- a/tools/java/org/unicode/cldr/util/CLDRPaths.java
+++ b/tools/java/org/unicode/cldr/util/CLDRPaths.java
@@ -17,24 +17,25 @@
*/
public class CLDRPaths {
- private static final String CASING_SUBDIR = "casing/";
- private static final String VALIDITY_SUBDIR = "validity/";
- private static final String ANNOTATIONS_DERIVED_SUBDIR = "annotationsDerived/";
- private static final String COLLATION_SUBDIR = "collation/";
- private static final String RBNF_SUBDIR = "rbnf/";
- private static final String TRANSFORMS_SUBDIR = "transforms/";
- private static final String MAIN_SUBDIR = "main/";
- private static final String SUBDIVISIONS_SUBDIR = "subdivisions/";
- private static final String ANNOTATIONS_SUBDIR = "annotations/";
-
+ public static final String COMMON_SUBDIR = "common/";
+ public static final String CASING_SUBDIR = "casing/";
+ public static final String VALIDITY_SUBDIR = "validity/";
+ public static final String ANNOTATIONS_DERIVED_SUBDIR = "annotationsDerived/";
+ public static final String COLLATION_SUBDIR = "collation/";
+ public static final String RBNF_SUBDIR = "rbnf/";
+ public static final String TRANSFORMS_SUBDIR = "transforms/";
+ public static final String MAIN_SUBDIR = "main/";
+ public static final String SUBDIVISIONS_SUBDIR = "subdivisions/";
+ public static final String ANNOTATIONS_SUBDIR = "annotations/";
+
/** default working directory for Eclipse is . = ${workspace_loc:cldr}, which is <CLDR>/tools/java/ */
// set the base directory with -Dcldrdata=<value>
// if the main is different, use -Dcldrmain=<value>
/** Maintained in GitHub, base directory for CLDR */
-
+
public static final String BASE_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("CLDR_DIR", null));
-
+
public static final String COMMON_DIRECTORY = CldrUtility.getPath(BASE_DIRECTORY, "common/");
public static final String COLLATION_DIRECTORY = CldrUtility.getPath(COMMON_DIRECTORY, COLLATION_SUBDIR);
public static final String CASING_DIRECTORY = CldrUtility.getPath(COMMON_DIRECTORY, CASING_SUBDIR);
@@ -62,21 +63,20 @@
public static final String EXEMPLARS_DIRECTORY = CldrUtility.getPath(CLDRPaths.BASE_DIRECTORY, "exemplars/" + MAIN_SUBDIR);
public static final String BIRTH_DATA_DIR = CldrUtility.getPath(BASE_DIRECTORY, "tools/java/org/unicode/cldr/util/data/births/");
+ public static final String CHART_DIRECTORY = CldrUtility.getPath(STAGING_DIRECTORY + "docs/charts/", ToolConstants.CHART_VERSION);
+ public static final String VERIFY_DIR = CLDRPaths.CHART_DIRECTORY + "verify/";
+
/** Maintained in SVN */
-
+
public static final String SVN_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("SVN_DIR", BASE_DIRECTORY + "/../"));
public static final String AUX_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("CLDR_TMP_DIR",
CldrUtility.getPath(SVN_DIRECTORY, "cldr-aux/")));
- public static final String CHART_DIRECTORY = CldrUtility.getPath(AUX_DIRECTORY + "charts/", ToolConstants.CHART_VERSION);
- public static final String VERIFY_DIR = CLDRPaths.CHART_DIRECTORY + "verify/";
public static final String UCD_DATA_DIRECTORY = CldrUtility.getPath(SVN_DIRECTORY + "unicodetools/unicodetools/data/");
-
- public static final String ICU_DATA_DIR = CldrUtility.getPath(CldrUtility.getProperty("ICU_DATA_DIR", null)); // eg
/** Local files, not backed up on either Github or SVN **/
-
+
public static final String LOCAL_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("LOCAL_DIR", BASE_DIRECTORY + "/../"));
public static final String ARCHIVE_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("ARCHIVE",
@@ -97,11 +97,12 @@
CldrUtility.getPath(LOCAL_DIRECTORY, "../cldr-tmp/")));
public static final String TMP2_DIRECTORY = CldrUtility.getPath(CldrUtility.getProperty("CLDR_TMP_DIR",
CldrUtility.getPath(LOCAL_DIRECTORY, "../cldr-tmp2/")));
-
+
/**
* @deprecated please use XMLFile and CLDRFILE getSupplementalDirectory()
* @see DEFAULT_SUPPLEMENTAL_DIRECTORY
*/
+ @Deprecated
public static final String SUPPLEMENTAL_DIRECTORY = CldrUtility.getPath(COMMON_DIRECTORY, "supplemental/");
/**
* Only the default, if no other directory is specified.
@@ -109,14 +110,15 @@
public static final String DEFAULT_SUPPLEMENTAL_DIRECTORY = CldrUtility.getPath(COMMON_DIRECTORY, "supplemental/");
public static final String LOG_DIRECTORY = CldrUtility.getPath(TMP_DIRECTORY, "logs/");
public static final String TEST_DIR = CldrUtility.getPath(CLDRPaths.TMP_DIRECTORY, "test/");
-
+
/** If the generated BAT files are to work, this needs to be set right */
public static final String COMPARE_PROGRAM = "\"C:\\Program Files (x86)\\Compare It!\\wincmp3.exe\"";
-
+
/**
* @deprecated Don't use this from any code that is run from the .JAR (SurveyTool, tests, etc).
* If it must be used, add a comment next to the usage to explain why it is needed.
*/
+ @Deprecated
public static final String UTIL_DATA_DIR = FileReaders.getRelativeFileName(CldrUtility.class, "data/");
public enum DIRECTORIES {
diff --git a/tools/java/org/unicode/cldr/util/CLDRTransforms.java b/tools/java/org/unicode/cldr/util/CLDRTransforms.java
index e99b8d6..2e639f7 100644
--- a/tools/java/org/unicode/cldr/util/CLDRTransforms.java
+++ b/tools/java/org/unicode/cldr/util/CLDRTransforms.java
@@ -58,7 +58,7 @@
return this;
}
- final Set<String> overridden = new HashSet<String>();
+ final Set<String> overridden = new HashSet<>();
final DependencyOrder dependencyOrder = new DependencyOrder();
static public class RegexFindFilenameFilter implements FilenameFilter {
@@ -72,7 +72,7 @@
public boolean accept(File dir, String name) {
return matcher.reset(name).find();
}
- };
+ }
/**
*
@@ -279,10 +279,10 @@
}
public Set<String> getOrderedItems(Collection<String> rawInput, Matcher filter, boolean hasXmlSuffix) {
- Set<String> input = new LinkedHashSet<String>(rawInput);
+ Set<String> input = new LinkedHashSet<>(rawInput);
// input.addAll(extras);
- Set<String> ordered = new LinkedHashSet<String>();
+ Set<String> ordered = new LinkedHashSet<>();
// for (String other : doFirst) {
// ordered.add(hasXmlSuffix ? other + ".xml" : other);
@@ -343,11 +343,11 @@
}
private BiMap<String,String> displayNameToId = HashBiMap.create();
-
+
public BiMap<String, String> getDisplayNameToId() {
return displayNameToId;
}
-
+
private void addDisplayNameToId(Map<String, String> ids2, ParsedTransformID directionInfo) {
displayNameToId.put(directionInfo.getDisplayId(), directionInfo.toString());
}
@@ -364,10 +364,10 @@
}
throw e;
}
-
+
String id = directionInfo.getId();
addDisplayNameToId(displayNameToId, directionInfo);
-
+
if (directionInfo.getDirection() == Direction.both || directionInfo.getDirection() == Direction.forward) {
internalRegister(id, ruleString, Transliterator.FORWARD);
for (String alias : directionInfo.getAliases()) {
@@ -487,15 +487,15 @@
Matcher getSource = PatternCache.get("\\s*(\\S*)\\s*\\{\\s*\\\"(.*)\\\".*").matcher("");
Matcher translitID = PatternCache.get("([^-]+)-([^/]+)+(?:[/](.+))?").matcher("");
- Map<String, String> fixedIDs = new TreeMap<String, String>();
- Set<String> oddIDs = new TreeSet<String>();
+ Map<String, String> fixedIDs = new TreeMap<>();
+ Set<String> oddIDs = new TreeSet<>();
File dir = new File(directory);
// get the list of files to take, and their directions
BufferedReader input = FileUtilities.openUTF8Reader(directory, "root.txt");
String id = null;
String filename = null;
- Map<String, String> aliasMap = new LinkedHashMap<String, String>();
+ Map<String, String> aliasMap = new LinkedHashMap<>();
// deregisterIcuTransliterators();
@@ -612,7 +612,7 @@
Transliterator.registerAny(); // do this last!
}
- Map<String, RuleDirection> idToRules = new TreeMap<String, RuleDirection>();
+ Map<String, RuleDirection> idToRules = new TreeMap<>();
private class RuleDirection {
String ruleString;
@@ -668,7 +668,7 @@
public void deregisterIcuTransliterators(Matcher filter) {
// Remove all of the current registrations
// first load into array, so we don't get sync problems.
- List<String> rawAvailable = new ArrayList<String>();
+ List<String> rawAvailable = new ArrayList<>();
for (Enumeration<String> en = Transliterator.getAvailableIDs(); en.hasMoreElements();) {
final String id = en.nextElement();
if (filter != null && !filter.reset(id).matches()) {
@@ -680,7 +680,7 @@
// deregisterIcuTransliterators(rawAvailable);
Set<String> available = dependencyOrder.getOrderedItems(rawAvailable, filter, false);
- List<String> reversed = new LinkedList<String>();
+ List<String> reversed = new LinkedList<>();
for (String item : available) {
reversed.add(0, item);
}
@@ -779,9 +779,9 @@
return sourceOrTarget;
}
}
-
+
static final LikelySubtags likely = new LikelySubtags();
-
+
public static String getScriptCode(String sourceOrTarget) {
int uscript = UScript.getCodeFromName(sourceOrTarget);
if (uscript >= 0) {
@@ -882,6 +882,7 @@
return source;
}
+ @Override
public String toString() {
return source + "-" + getTargetVariant();
}
@@ -955,6 +956,7 @@
this.directionInfo = directionInfo;
}
+ @Override
public void handlePathValue(String path, String value) {
if (first) {
if (path.startsWith("//supplementalData/version")) {
diff --git a/tools/java/org/unicode/cldr/util/CLDRURLS.java b/tools/java/org/unicode/cldr/util/CLDRURLS.java
index 4d38ae6..16addc1 100644
--- a/tools/java/org/unicode/cldr/util/CLDRURLS.java
+++ b/tools/java/org/unicode/cldr/util/CLDRURLS.java
@@ -11,7 +11,7 @@
public static final String DEFAULT_HOST = "st.unicode.org";
public static final String DEFAULT_PATH = "/cldr-apps";
public static final String DEFAULT_BASE = "http://" + DEFAULT_HOST + DEFAULT_PATH;
- public static final String CLDR_NEWTICKET_URL = "https://unicode.org/cldr/trac/newticket"; // This is an alias to Jira
+ public static final String CLDR_NEWTICKET_URL = "http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket";
/**
* Override this property if you want to change the absolute URL to the SurveyTool base from DEFAULT_BASE
*/
@@ -250,9 +250,9 @@
*/
public static String gitHashToLink(String hash) {
if(!isKnownHash(hash)) return "<span class=\"githashLink\">"+hash+"</span>"; // Not linkifiable
- return "<a class=\"githashLink\" href=\"" +
- CldrUtility.getProperty("CLDR_COMMIT_BASE", "https://github.com/unicode-org/cldr/commit/")
- + hash + "\">" + hash + "</a>";
+ return "<a class=\"githashLink\" href=\"" +
+ CldrUtility.getProperty("CLDR_COMMIT_BASE", "https://github.com/unicode-org/cldr/commit/")
+ + hash + "\">" + hash.substring(0, 8) + "</a>";
}
/**
diff --git a/tools/java/org/unicode/cldr/util/CaseIterator.java b/tools/java/org/unicode/cldr/util/CaseIterator.java
index def0f6c..525ba30 100644
--- a/tools/java/org/unicode/cldr/util/CaseIterator.java
+++ b/tools/java/org/unicode/cldr/util/CaseIterator.java
@@ -36,10 +36,10 @@
private static Map toCaseFold = new HashMap();
private static int maxLength = 0;
- // This exception list is generated on the console by turning on the GENERATED flag,
+ // This exception list is generated on the console by turning on the GENERATED flag,
// which MUST be false for normal operation.
// Once the list is generated, it is pasted in here.
- // A bit of a cludge, but this bootstrapping is the easiest way
+ // A bit of a cludge, but this bootstrapping is the easiest way
// to get around certain complications in the data.
private static final boolean GENERATE = false;
@@ -298,7 +298,7 @@
fromCaseFold = fromCaseFold2;
// We have processed everything, so the iterator will now work
- // The following is normally OFF.
+ // The following is normally OFF.
// It is here to generate (under the GENERATE flag) the static exception list.
// It must be at the very end of initialization, so that the iterator is functional.
// (easiest to do it that way)
@@ -396,7 +396,7 @@
}
}
- // ============ PRIVATE CLASS DATA ============
+ // ============ PRIVATE CLASS DATA ============
// pieces that we will put together
// is not changed during iteration
@@ -410,7 +410,7 @@
// internal buffer for efficiency
private StringBuffer nextBuffer = new StringBuffer();
- // ========================
+ // ========================
/**
* Reset to different source. Once reset, the iteration starts from the beginning.
diff --git a/tools/java/org/unicode/cldr/util/ChainedMap.java b/tools/java/org/unicode/cldr/util/ChainedMap.java
index 5974db8..dc09eb2 100644
--- a/tools/java/org/unicode/cldr/util/ChainedMap.java
+++ b/tools/java/org/unicode/cldr/util/ChainedMap.java
@@ -52,7 +52,7 @@
@SuppressWarnings("unchecked")
public Iterable<Row.R3<K2, K1, V>> rows() {
- List<R3<K2, K1, V>> result = new ArrayList<R3<K2, K1, V>>();
+ List<R3<K2, K1, V>> result = new ArrayList<>();
for (Entry<Object, Object> entry0 : super.mapBase.entrySet()) {
for (Entry<Object, Object> entry1 : ((Map<Object, Object>) entry0.getValue()).entrySet()) {
R3<K2, K1, V> item = (R3<K2, K1, V>) Row.of(entry0.getKey(), entry1.getKey(), entry1.getValue());
@@ -85,7 +85,7 @@
public M3<K2, K1, V> get(K3 key3) {
final Map<?, ?> submap = (Map<?, ?>) super.handleGet(key3);
- return submap == null ? null : new M3<K2, K1, V>(submap, super.mapConstructors, super.indexStart + 1);
+ return submap == null ? null : new M3<>(submap, super.mapConstructors, super.indexStart + 1);
}
@SuppressWarnings("unchecked")
@@ -101,7 +101,7 @@
@SuppressWarnings("unchecked")
public Iterable<Row.R4<K3, K2, K1, V>> rows() {
- List<R4<K3, K2, K1, V>> result = new ArrayList<R4<K3, K2, K1, V>>();
+ List<R4<K3, K2, K1, V>> result = new ArrayList<>();
for (Entry<Object, Object> entry0 : super.mapBase.entrySet()) {
for (Entry<Object, Object> entry1 : ((Map<Object, Object>) entry0.getValue()).entrySet()) {
for (Entry<Object, Object> entry2 : ((Map<Object, Object>) entry1.getValue()).entrySet()) {
@@ -133,7 +133,7 @@
public M4<K3, K2, K1, V> get(K4 key4) {
final Map<?, ?> submap = (Map<?, ?>) super.handleGet(key4);
return submap == null ? null
- : new M4<K3, K2, K1, V>(submap, super.mapConstructors, super.indexStart + 2);
+ : new M4<>(submap, super.mapConstructors, super.indexStart + 2);
}
@SuppressWarnings("unchecked")
@@ -149,7 +149,7 @@
@SuppressWarnings("unchecked")
public Iterable<Row.R5<K4, K3, K2, K1, V>> rows() {
- List<R5<K4, K3, K2, K1, V>> result = new ArrayList<R5<K4, K3, K2, K1, V>>();
+ List<R5<K4, K3, K2, K1, V>> result = new ArrayList<>();
for (Entry<Object, Object> entry0 : super.mapBase.entrySet()) {
for (Entry<Object, Object> entry1 : ((Map<Object, Object>) entry0.getValue()).entrySet()) {
for (Entry<Object, Object> entry2 : ((Map<Object, Object>) entry1.getValue()).entrySet()) {
@@ -211,16 +211,16 @@
}
public static <K2, K1, V> M3<K2, K1, V> of(Map<K2, Object> map2, Map<K1, Object> map1, Class<V> valueClass) {
- return new M3<K2, K1, V>(map2, map1, valueClass);
+ return new M3<>(map2, map1, valueClass);
}
public static <K3, K2, K1, V> M4<K3, K2, K1, V> of(Map<K3, Object> map3, Map<K2, Object> map2, Map<K1, Object> map1, Class<V> valueClass) {
- return new M4<K3, K2, K1, V>(map3, map2, map1, valueClass);
+ return new M4<>(map3, map2, map1, valueClass);
}
public static <K4, K3, K2, K1, V> M5<K4, K3, K2, K1, V> of(
Map<K4, Object> map4, Map<K3, Object> map3, Map<K2, Object> map2, Map<K1, Object> map1, Class<V> valueClass) {
- return new M5<K4, K3, K2, K1, V>(map4, map3, map2, map1, valueClass);
+ return new M5<>(map4, map3, map2, map1, valueClass);
}
private Object iterator() {
diff --git a/tools/java/org/unicode/cldr/util/CharUtilities.java b/tools/java/org/unicode/cldr/util/CharUtilities.java
index 454f6be..bd058ca 100644
--- a/tools/java/org/unicode/cldr/util/CharUtilities.java
+++ b/tools/java/org/unicode/cldr/util/CharUtilities.java
@@ -15,30 +15,37 @@
this.source = source;
}
+ @Override
public boolean hasCharAt(int index) {
return index < source.length();
}
+ @Override
public char charAt(int index) {
return source.charAt(index);
}
+ @Override
public int toSourceOffset(int index) {
return index;
}
+ @Override
public CharSource sublist(int start, int end) {
- return new CharSourceWrapper<CharSequence>(source.subSequence(start, end));
+ return new CharSourceWrapper<>(source.subSequence(start, end));
}
+ @Override
public CharSource sublist(int start) {
- return new CharSourceWrapper<CharSequence>(source.subSequence(start, source.length()));
+ return new CharSourceWrapper<>(source.subSequence(start, source.length()));
}
+ @Override
public int getKnownLength() {
return source.length();
}
+ @Override
public CharSequence subSequence(int start, int end) {
return source.subSequence(start, end);
}
@@ -52,14 +59,17 @@
return source.subSequence(toSourceOffset(start), toSourceOffset(end));
}
+ @Override
public int fromSourceOffset(int index) {
return index;
}
+ @Override
public CharSource setStart(int index) {
return this;
}
+ @Override
public int getStart() {
return 0;
}
diff --git a/tools/java/org/unicode/cldr/util/CharacterFallbacks.java b/tools/java/org/unicode/cldr/util/CharacterFallbacks.java
index 5d9ea60..e87c643 100644
--- a/tools/java/org/unicode/cldr/util/CharacterFallbacks.java
+++ b/tools/java/org/unicode/cldr/util/CharacterFallbacks.java
@@ -8,7 +8,7 @@
public class CharacterFallbacks {
private static CharacterFallbacks SINGLETON = new CharacterFallbacks();
- private HashMap<Integer, List<String>> data = new HashMap<Integer, List<String>>();
+ private HashMap<Integer, List<String>> data = new HashMap<>();
static public CharacterFallbacks make() {
return SINGLETON;
@@ -41,7 +41,7 @@
List<String> substitutes = data.get(cp);
if (substitutes == null) {
- data.put(cp, substitutes = new ArrayList<String>());
+ data.put(cp, substitutes = new ArrayList<>());
}
substitutes.add(substitute);
}
diff --git a/tools/java/org/unicode/cldr/util/CldrUtility.java b/tools/java/org/unicode/cldr/util/CldrUtility.java
index 9edfed8..554b472 100644
--- a/tools/java/org/unicode/cldr/util/CldrUtility.java
+++ b/tools/java/org/unicode/cldr/util/CldrUtility.java
@@ -13,10 +13,14 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -46,6 +50,9 @@
import org.unicode.cldr.draft.FileUtilities;
import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
@@ -60,7 +67,7 @@
public class CldrUtility {
public static final boolean DEBUG_MISSING_DIRECTORIES = false;
-
+
public static final Charset UTF8 = Charset.forName("utf-8");
public static final boolean BETA = false;
@@ -96,7 +103,7 @@
*/
public static class VariableReplacer {
// simple implementation for now
- private Map<String, String> m = new TreeMap<String, String>(Collections.reverseOrder());
+ private Map<String, String> m = new TreeMap<>(Collections.reverseOrder());
public VariableReplacer add(String variable, String value) {
m.put(variable, value);
@@ -135,20 +142,20 @@
boolean handle(String line) throws Exception;
}
- public static String getPath(String path, String filename) {
- if (path == null) {
+ public static String getPath(String fileOrDir, String filename) {
+ // Required for cases where a system property is read but not default is given.
+ // TODO: Fix callers to not fail silently if properties are missing.
+ if (fileOrDir == null) {
return null;
}
- final File file = filename == null ? new File(path)
- : new File(path, filename);
- try {
- if (DEBUG_MISSING_DIRECTORIES && !file.exists()) {
- System.err.println("Warning: directory doesn't exist: " + file);
- }
- return file.getCanonicalPath() + File.separatorChar;
- } catch (IOException e) {
- return file.getPath() + File.separatorChar;
+ Path path = Paths.get(fileOrDir);
+ if (filename != null) {
+ path = path.resolve(filename);
}
+ if (DEBUG_MISSING_DIRECTORIES && !Files.exists(path)) {
+ System.err.println("Warning: directory doesn't exist: " + path);
+ }
+ return PathUtilities.getNormalizedPathString(path) + File.separatorChar;
}
static String getPath(String path) {
@@ -193,6 +200,7 @@
this.flags = flags;
}
+ @Override
public int compare(String line1, String line2) {
// first, see if we want to skip one or the other lines
int skipper = 0;
@@ -368,7 +376,7 @@
// each item is of the form abc...
// or "..." (required if a comma or quote is contained)
// " in a field is represented by ""
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
StringBuilder item = new StringBuilder();
boolean inQuote = false;
for (int i = 0; i < line.length(); ++i) {
@@ -421,7 +429,7 @@
}
public static List<String> splitList(String source, String separator, boolean trim, List<String> output) {
- if (output == null) output = new ArrayList<String>();
+ if (output == null) output = new ArrayList<>();
if (source.length() == 0) return output;
int pos = 0;
do {
@@ -443,16 +451,23 @@
public static <T> T protectCollection(T source) {
// TODO - exclude UnmodifiableMap, Set, ...
if (source instanceof Map) {
- Map sourceMap = (Map) source;
- Map resultMap = clone(sourceMap);
- if (resultMap == null) return (T) sourceMap; // failed
- resultMap.clear();
- for (Object key : sourceMap.keySet()) {
- resultMap.put(protectCollection(key), protectCollection(sourceMap.get(key)));
+ Map<Object,Object> sourceMap = (Map) source;
+ ImmutableMap.Builder<Object,Object> builder = ImmutableMap.builder();
+ for (Entry<Object,Object> entry : sourceMap.entrySet()) {
+ final Object key = entry.getKey();
+ final Object value = entry.getValue();
+ builder.put(protectCollection(key), protectCollection(value));
}
- return resultMap instanceof SortedMap ? (T) Collections.unmodifiableSortedMap((SortedMap) resultMap)
- : (T) Collections.unmodifiableMap(resultMap);
+ return (T) builder.build();
+ } else if (source instanceof Multimap) {
+ Multimap<Object,Object> sourceMap = (Multimap) source;
+ ImmutableMultimap.Builder<Object,Object> builder = ImmutableMultimap.builder();
+ for (Entry<Object,Object> entry : sourceMap.entries()) {
+ builder.put(protectCollection(entry.getKey()), protectCollection(entry.getValue()));
+ }
+ return (T) builder.build();
} else if (source instanceof Collection) {
+ // TODO use ImmutableSet, List, ...
Collection sourceCollection = (Collection) source;
Collection<Object> resultCollection = clone(sourceCollection);
if (resultCollection == null) return (T) sourceCollection; // failed
@@ -519,7 +534,7 @@
}
}
- private static final Set<Object> KNOWN_IMMUTABLES = new HashSet<Object>(Arrays.asList(
+ private static final Set<Object> KNOWN_IMMUTABLES = new HashSet<>(Arrays.asList(
String.class));
public static boolean isImmutable(Object source) {
@@ -595,7 +610,7 @@
} else {
output.append(separator);
}
- output.append(transform != null ? transform.transform(item) : item == null ? item : item.toString());
+ output.append(transform != null ? transform.transform(item) : item);
}
return output.toString();
}
@@ -633,7 +648,7 @@
*/
public static String getCanonicalName(String file) {
try {
- return new File(file).getCanonicalPath();
+ return PathUtilities.getNormalizedPathString(file);
} catch (Exception e) {
return file;
}
@@ -724,7 +739,7 @@
// otherwise, we figure out what is in the set, and will return
StringBuilder base = new StringBuilder("[");
StringBuilder alternates = new StringBuilder();
- Map<UnicodeSet, UnicodeSet> lastToFirst = new TreeMap<UnicodeSet, UnicodeSet>(new UnicodeSetComparator());
+ Map<UnicodeSet, UnicodeSet> lastToFirst = new TreeMap<>(new UnicodeSetComparator());
int alternateCount = 0;
while (it.nextRange()) {
if (it.codepoint == UnicodeSetIterator.IS_STRING) {
@@ -797,18 +812,21 @@
}
public static class UnicodeSetComparator implements Comparator<UnicodeSet> {
+ @Override
public int compare(UnicodeSet o1, UnicodeSet o2) {
return o1.compareTo(o2);
}
}
public static class CollectionComparator<T extends Comparable<T>> implements Comparator<Collection<T>> {
+ @Override
public int compare(Collection<T> o1, Collection<T> o2) {
return UnicodeSet.compare(o1, o2, UnicodeSet.ComparisonStyle.SHORTER_FIRST);
}
}
public static class ComparableComparator<T extends Comparable<T>> implements Comparator<T> {
+ @Override
public int compare(T arg0, T arg1) {
return Utility.checkCompare(arg0, arg1);
}
@@ -819,13 +837,14 @@
Map<Object, Object> base = coverageData;
for (int i = 0; i < objects.length - 2; ++i) {
Map<Object, Object> nextOne = (Map<Object, Object>) base.get(objects[i]);
- if (nextOne == null) base.put(objects[i], nextOne = new TreeMap<Object, Object>());
+ if (nextOne == null) base.put(objects[i], nextOne = new TreeMap<>());
base = nextOne;
}
base.put(objects[objects.length - 2], objects[objects.length - 1]);
}
public static abstract class CollectionTransform<S, T> implements Transform<S, T> {
+ @Override
public abstract T transform(S source);
public Collection<T> transform(Collection<S> input, Collection<T> output) {
@@ -929,6 +948,7 @@
return this;
}
+ @Override
public boolean contains(T o) {
return matcher.reset(o.toString()).matches();
}
@@ -1128,7 +1148,7 @@
public static void showMethods(Class<?> cls) throws ClassNotFoundException {
System.out.println("Possible methods of " + cls.getCanonicalName() + " are: ");
Method[] methods = cls.getMethods();
- Set<String> names = new TreeSet<String>();
+ Set<String> names = new TreeSet<>();
for (int i = 0; i < methods.length; ++i) {
if (methods[i].getGenericParameterTypes().length != 0) continue;
//int mods = methods[i].getModifiers();
@@ -1255,18 +1275,18 @@
public static String checkValidFile(String sourceDirectory, boolean checkForDirectory, String correction) {
File file = null;
- String canonicalPath = null;
+ String normalizedPath = null;
try {
file = new File(sourceDirectory);
- canonicalPath = file.getCanonicalPath() + File.separatorChar;
+ normalizedPath = PathUtilities.getNormalizedPathString(file) + File.separatorChar;
} catch (Exception e) {
}
- if (file == null || canonicalPath == null || checkForDirectory && !file.isDirectory()) {
+ if (file == null || normalizedPath == null || checkForDirectory && !file.isDirectory()) {
throw new RuntimeException("Directory not found: " + sourceDirectory
- + (canonicalPath == null ? "" : " => " + canonicalPath)
+ + (normalizedPath == null ? "" : " => " + normalizedPath)
+ (correction == null ? "" : CldrUtility.LINE_SEPARATOR + correction));
}
- return canonicalPath;
+ return normalizedPath;
}
/**
@@ -1326,7 +1346,7 @@
public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap() {
// http://ria101.wordpress.com/2011/12/12/concurrenthashmap-avoid-a-common-misuse/
- return new ConcurrentHashMap<K, V>(4, 0.9f, 1);
+ return new ConcurrentHashMap<>(4, 0.9f, 1);
}
public static <K, V> ConcurrentHashMap<K, V> newConcurrentHashMap(Map<K, V> source) {
@@ -1366,7 +1386,7 @@
public static String getCopyrightString() {
return getCopyrightString("");
}
-
+
public static String getCopyrightString(String linePrefix) {
// now do the rest
return linePrefix + "Copyright \u00A9 1991-" + Calendar.getInstance().get(Calendar.YEAR) + " Unicode, Inc." + CldrUtility.LINE_SEPARATOR
@@ -1536,4 +1556,46 @@
}
return item.toString();
}
+
+ /**
+ * Return the git hash for the CLDR base directory.
+ *
+ * @return the hash, like "9786e05e95a2e4f02687fa3b84126782f9f698a3"
+ */
+ public static String getCldrBaseDirHash() {
+ final File baseDir = CLDRConfig.getInstance().getCldrBaseDirectory();
+ return getGitHashForDir(baseDir.toString());
+ }
+
+ /**
+ * Return the git hash for a directory.
+ *
+ * @param dir the directory name
+ * @return the hash, like "9786e05e95a2e4f02687fa3b84126782f9f698a3"
+ */
+ public final static String getGitHashForDir(String dir) {
+ final String GIT_HASH_COMMANDS[] = { "git", "rev-parse", "HEAD" };
+ try {
+ if (dir == null) {
+ return CLDRURLS.UNKNOWN_REVISION; // no dir
+ }
+ File f = new File(dir);
+ if (!f.isDirectory()) {
+ return CLDRURLS.UNKNOWN_REVISION; // does not exist
+ }
+ Process p = Runtime.getRuntime().exec(GIT_HASH_COMMANDS, null, f);
+ try (BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+ String str = is.readLine();
+ if (str.length() == 0) {
+ throw new Exception("git returned empty");
+ }
+ return str;
+ }
+ } catch(Throwable t) {
+ // We do not expect this to be called frequently.
+ System.err.println("While trying to get 'git' hash for " + dir + " : " + t.getMessage());
+ t.printStackTrace();
+ return CLDRURLS.UNKNOWN_REVISION;
+ }
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/CollationMapMaker.java b/tools/java/org/unicode/cldr/util/CollationMapMaker.java
index bbc9e09..46c3ceb 100644
--- a/tools/java/org/unicode/cldr/util/CollationMapMaker.java
+++ b/tools/java/org/unicode/cldr/util/CollationMapMaker.java
@@ -49,6 +49,7 @@
static class ExemplarComparator implements java.util.Comparator {
Comparator comp;
+ @Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
@@ -85,10 +86,11 @@
public static class Folder implements Cloneable {
private UnicodeMap m = new UnicodeMap();
+ @Override
public Object clone() {
try {
Folder result = (Folder) super.clone();
- result.m = (UnicodeMap) m.cloneAsThawed();
+ result.m = m.cloneAsThawed();
return result;
} catch (CloneNotSupportedException e) {
throw new InternalError("Clone problem");
@@ -118,7 +120,7 @@
}
public void minimalize() {
- UnicodeMap newMap = (UnicodeMap) (m.cloneAsThawed());
+ UnicodeMap newMap = (m.cloneAsThawed());
for (UnicodeSetIterator i = new UnicodeSetIterator(m.keySet()); i.next();) {
String s = (String) m.getValue(i.codepoint);
@@ -199,7 +201,7 @@
}
public UnicodeMap getUnicodeMap() {
- return (UnicodeMap) m.cloneAsThawed();
+ return m.cloneAsThawed();
}
@@ -207,7 +209,7 @@
static final boolean showDetails = false;
static final RuleBasedCollator uca = (RuleBasedCollator) Collator.getInstance(ULocale.ROOT);
- static final UnicodeSet filteredChars = (UnicodeSet) new UnicodeSet(
+ static final UnicodeSet filteredChars = new UnicodeSet(
"[{ss}[^[:Co:][:Cf:][:Cc:][:Cn:][:Cs:][:script=Han:][:script=Hangul:]-[:nfkcquickcheck=no:]]]").freeze(); // skip
// a
// bunch
@@ -232,7 +234,7 @@
this.equivalenceClassCollator = equivalenceClassCollator;
try {
RuleBasedCollator exemplarCollator = (RuleBasedCollator) equivalenceClassCollator.clone();
- exemplarCollator.setStrength(exemplarCollator.IDENTICAL);
+ exemplarCollator.setStrength(Collator.IDENTICAL);
exemplarCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
exemplarCollator.setUpperCaseFirst(false);
exemplarCollator.setAlternateHandlingShifted(false);
@@ -278,7 +280,7 @@
// if there is only one result, drop it
if (values1.size() == 1) {
if (false && SHOW_DEBUG) {
- String item = (String) values1.iterator().next();
+ String item = values1.iterator().next();
System.out.println("Skipping: " + item + "\t"
+ equivalenceClassCollator.getRawCollationKey(item, null));
}
@@ -349,6 +351,7 @@
VariantFolder caseFolder = new VariantFolder(new CaseVariantFolder());
VariantFolder.AlternateFetcher COLLATION_FETCHER = new VariantFolder.AlternateFetcher() {
+ @Override
public Set<String> getAlternates(String item, Set<String> output) {
output.add(item);
Set set = equivMap.getEquivalences(item);
@@ -362,8 +365,8 @@
private void closeUnderFolding() {
if (false) return;
// TODO Generalize
- Set<String> others = new HashSet<String>();
- List<Collection<String>> input = new ArrayList<Collection<String>>();
+ Set<String> others = new HashSet<>();
+ List<Collection<String>> input = new ArrayList<>();
VariantFolder recursiveFolder = new VariantFolder(COLLATION_FETCHER);
TreeSet<CharSequence> hack = new TreeSet();
hack.add("aa");
@@ -507,7 +510,7 @@
}
}
- Set<CharSequence> seenSoFar = new TreeSet<CharSequence>();
+ Set<CharSequence> seenSoFar = new TreeSet<>();
private void addToEquiv(String item, String original) {
if (item.equals("aA")) {
diff --git a/tools/java/org/unicode/cldr/util/CollationStringByteConverter.java b/tools/java/org/unicode/cldr/util/CollationStringByteConverter.java
index b21b67a..9b0e732 100644
--- a/tools/java/org/unicode/cldr/util/CollationStringByteConverter.java
+++ b/tools/java/org/unicode/cldr/util/CollationStringByteConverter.java
@@ -20,7 +20,7 @@
}
private static StateDictionary<String> getDictionaryInfo(RuleBasedCollator collation, StringByteConverter byteMaker) {
- Map<CharSequence, String> map = new TreeMap<CharSequence, String>(Dictionary.CHAR_SEQUENCE_COMPARATOR);
+ Map<CharSequence, String> map = new TreeMap<>(Dictionary.CHAR_SEQUENCE_COMPARATOR);
new CollationMapMaker().generateCollatorFolding(collation, map);
return new StateDictionaryBuilder<String>().setByteConverter(byteMaker)
.setIntMapFactory(new IntMap.CompactStringIntMapFactory()).make(map);
diff --git a/tools/java/org/unicode/cldr/util/CompactStringByteConverter.java b/tools/java/org/unicode/cldr/util/CompactStringByteConverter.java
index c03cd21..e02abae 100644
--- a/tools/java/org/unicode/cldr/util/CompactStringByteConverter.java
+++ b/tools/java/org/unicode/cldr/util/CompactStringByteConverter.java
@@ -30,6 +30,7 @@
*
* @see org.unicode.cldr.util.StringByteConverter#clear()
*/
+ @Override
public void clear() {
last = 0x40;
}
@@ -39,6 +40,7 @@
*
* @see org.unicode.cldr.util.StringByteConverter#toBytes(char, byte[])
*/
+ @Override
public int toBytes(char cp, byte[] output, int bytePosition) {
if (deltaEncoded) {
// get the delta from the previous
@@ -57,6 +59,7 @@
*
* @see org.unicode.cldr.util.StringByteConverter#toBytes(java.lang.CharSequence, int, byte[])
*/
+ @Override
public int toBytes(CharSequence source, byte[] output, int bytePosition) {
if (deltaEncoded) {
int last = 0x40;
@@ -82,6 +85,7 @@
*
* @see org.unicode.cldr.util.StringByteConverter#fromBytes(byte[], int, int, java.lang.Appendable)
*/
+ @Override
public Appendable fromBytes(byte[] input, int byteStart, int byteLength, Appendable result) {
try {
int[] ioBytePosition = new int[1];
diff --git a/tools/java/org/unicode/cldr/util/Containment.java b/tools/java/org/unicode/cldr/util/Containment.java
index e0e2b89..72884b0 100644
--- a/tools/java/org/unicode/cldr/util/Containment.java
+++ b/tools/java/org/unicode/cldr/util/Containment.java
@@ -22,7 +22,7 @@
static final Set<String> continents = containmentCore.get("001");
static final Set<String> subcontinents;
static {
- LinkedHashSet<String> temp = new LinkedHashSet<String>();
+ LinkedHashSet<String> temp = new LinkedHashSet<>();
for (String continent : continents) {
temp.addAll(containmentCore.get(continent));
}
@@ -30,7 +30,7 @@
}
static final Relation<String, String> containmentFull = supplementalData
.getTerritoryToContained();
- static final Relation<String, String> containedToContainer = (Relation<String, String>) Relation
+ static final Relation<String, String> containedToContainer = Relation
.of(new HashMap<String, Set<String>>(),
HashSet.class)
.addAllInverted(containmentFull)
@@ -44,7 +44,7 @@
// for each container, get all of its leaf nodes
Set<String> containers = supplementalData.getContainers();
for (String s : containers) {
- HashSet<String> leaves = new HashSet<String>();
+ HashSet<String> leaves = new HashSet<>();
addLeaves(s, leaves, containers);
leavesToContainers.putAll(leaves, s);
}
@@ -54,12 +54,12 @@
// }
}
- static final Relation<String, String> containedToContainerCore = (Relation<String, String>) Relation
+ static final Relation<String, String> containedToContainerCore = Relation
.of(new HashMap<String, Set<String>>(),
HashSet.class)
.addAllInverted(containmentCore)
.freeze();
- static final Map<String, Integer> toOrder = new LinkedHashMap<String, Integer>();
+ static final Map<String, Integer> toOrder = new LinkedHashMap<>();
static int level = 0;
static int order;
static {
@@ -201,7 +201,7 @@
}
public static Set<List<String>> getAllDirected(Multimap<String, String> multimap, String lang) {
- LinkedHashSet<List<String>> result = new LinkedHashSet<List<String>>();
+ LinkedHashSet<List<String>> result = new LinkedHashSet<>();
getAllDirected(multimap, lang, new ArrayList<String>(), result);
return result;
}
diff --git a/tools/java/org/unicode/cldr/util/CoreCoverageInfo.java b/tools/java/org/unicode/cldr/util/CoreCoverageInfo.java
index df9e890..a886d16 100644
--- a/tools/java/org/unicode/cldr/util/CoreCoverageInfo.java
+++ b/tools/java/org/unicode/cldr/util/CoreCoverageInfo.java
@@ -30,24 +30,24 @@
private static final CLDRConfig config = CLDRConfig.getInstance();
private static final String CLDR_BASE_DIRECTORY = config.getCldrBaseDirectory().toString();
private static final SupplementalDataInfo sdi = SupplementalDataInfo.getInstance();
- private static final LikelySubtags ls = new LikelySubtags(sdi);
+ private static final LikelySubtags ls = new LikelySubtags();
public enum CoreItems {
- // Drop the exemplars, since
+ // Drop the exemplars, since
// main_exemplar, auxiliary_exemplar, // numbers_exemplar, punctuation_exemplar, index_exemplar(Level.MODERN)
- orientation,
- plurals,
- default_content, likely_subtags,
- country_data,
- casing,
+ orientation,
+ plurals,
+ default_content, likely_subtags,
+ country_data,
+ casing,
collation,
- romanization(Level.MODERATE),
- ordinals(Level.MODERN),
+ romanization(Level.MODERATE),
+ ordinals(Level.MODERN),
;
-
+
public static Set<CoreItems> ONLY_RECOMMENDED = ImmutableSet.copyOf(
EnumSet.of(romanization, ordinals));
-
+
// private static final Set<CoreItems> EXEMPLARS = ImmutableSet.copyOf(EnumSet.of(
// main_exemplar, auxiliary_exemplar
// //, numbers_exemplar, punctuation_exemplar, index_exemplar
@@ -55,7 +55,7 @@
public static final int COUNT = CoreItems.values().length;
public final Level desiredLevel;
-
+
CoreItems(Level desiredLevel) {
this.desiredLevel = desiredLevel;
}
diff --git a/tools/java/org/unicode/cldr/util/Counter.java b/tools/java/org/unicode/cldr/util/Counter.java
index b2f0a04..dab3613 100644
--- a/tools/java/org/unicode/cldr/util/Counter.java
+++ b/tools/java/org/unicode/cldr/util/Counter.java
@@ -39,9 +39,9 @@
public Counter(Comparator<T> comparator) {
if (comparator != null) {
this.comparator = comparator;
- map = new TreeMap<T, RWLong>(comparator);
+ map = new TreeMap<>(comparator);
} else {
- map = new LinkedHashMap<T, RWLong>();
+ map = new LinkedHashMap<>();
}
}
@@ -57,6 +57,7 @@
}
}
+ @Override
public int compareTo(RWLong that) {
if (that.value < value) return -1;
if (that.value > value) return 1;
@@ -67,6 +68,7 @@
return 1; // the forceUnique values must be different, so this is the only remaining case
}
+ @Override
public String toString() {
return String.valueOf(value);
}
@@ -154,6 +156,7 @@
this.byValue = byValue;
}
+ @Override
public int compare(Entry<T> o1, Entry<T> o2) {
if (o1.count.value < o2.count.value) return -countOrdering;
if (o1.count.value > o2.count.value) return countOrdering;
@@ -169,12 +172,12 @@
}
public Set<T> getKeysetSortedByCount(boolean ascending, Comparator<T> byValue) {
- Set<Entry<T>> count_key = new TreeSet<Entry<T>>(new EntryComparator<T>(ascending, byValue));
+ Set<Entry<T>> count_key = new TreeSet<>(new EntryComparator<>(ascending, byValue));
int counter = 0;
for (T key : map.keySet()) {
- count_key.add(new Entry<T>(map.get(key), key, counter++));
+ count_key.add(new Entry<>(map.get(key), key, counter++));
}
- Set<T> result = new LinkedHashSet<T>();
+ Set<T> result = new LinkedHashSet<>();
for (Entry<T> entry : count_key) {
result.add(entry.value);
}
@@ -182,12 +185,12 @@
}
public Set<Row.R2<Long, T>> getEntrySetSortedByCount(boolean ascending, Comparator<T> byValue) {
- Set<Entry<T>> count_key = new TreeSet<Entry<T>>(new EntryComparator<T>(ascending, byValue));
+ Set<Entry<T>> count_key = new TreeSet<>(new EntryComparator<>(ascending, byValue));
int counter = 0;
for (T key : map.keySet()) {
- count_key.add(new Entry<T>(map.get(key), key, counter++));
+ count_key.add(new Entry<>(map.get(key), key, counter++));
}
- Set<R2<Long, T>> result = new LinkedHashSet<Row.R2<Long, T>>();
+ Set<R2<Long, T>> result = new LinkedHashSet<>();
for (Entry<T> entry : count_key) {
result.add(Row.of(entry.count.value, entry.value));
}
@@ -195,7 +198,7 @@
}
public Set<T> getKeysetSortedByKey() {
- Set<T> s = new TreeSet<T>(comparator);
+ Set<T> s = new TreeSet<>(comparator);
s.addAll(map.keySet());
return s;
}
@@ -214,6 +217,7 @@
return map.keySet();
}
+ @Override
public Iterator<T> iterator() {
return map.keySet().iterator();
}
@@ -226,6 +230,7 @@
return map.size();
}
+ @Override
public String toString() {
return map.toString();
}
@@ -246,6 +251,7 @@
return this;
}
+ @Override
public int compareTo(Counter<T> o) {
Iterator<T> i = map.keySet().iterator();
Iterator<T> j = o.map.keySet().iterator();
@@ -275,10 +281,12 @@
return map.containsKey(key);
}
+ @Override
public boolean equals(Object o) {
return map.equals(o);
}
+ @Override
public int hashCode() {
return map.hashCode();
}
diff --git a/tools/java/org/unicode/cldr/util/Counter2.java b/tools/java/org/unicode/cldr/util/Counter2.java
index 2c45b6f..ae21788 100644
--- a/tools/java/org/unicode/cldr/util/Counter2.java
+++ b/tools/java/org/unicode/cldr/util/Counter2.java
@@ -36,9 +36,9 @@
public Counter2(Comparator<T> comparator) {
if (comparator != null) {
this.comparator = comparator;
- map = new TreeMap<T, Double>(comparator);
+ map = new TreeMap<>(comparator);
} else {
- map = new LinkedHashMap<T, Double>();
+ map = new LinkedHashMap<>();
}
}
@@ -112,6 +112,7 @@
this.byValue = byValue;
}
+ @Override
public int compare(Entry<T> o1, Entry<T> o2) {
if (o1.count != o2.count) {
if (o1.count < o2.count) return -countOrdering;
@@ -129,12 +130,12 @@
}
public Set<T> getKeysetSortedByCount(boolean ascending, Comparator<T> byValue) {
- Set<Entry<T>> count_key = new TreeSet<Entry<T>>(new EntryComparator<T>(ascending, byValue));
+ Set<Entry<T>> count_key = new TreeSet<>(new EntryComparator<>(ascending, byValue));
int counter = 0;
for (T key : map.keySet()) {
- count_key.add(new Entry<T>(map.get(key), key, counter++));
+ count_key.add(new Entry<>(map.get(key), key, counter++));
}
- Set<T> result = new LinkedHashSet<T>();
+ Set<T> result = new LinkedHashSet<>();
for (Entry<T> entry : count_key) {
result.add(entry.value);
}
@@ -142,7 +143,7 @@
}
public Set<T> getKeysetSortedByKey() {
- Set<T> s = new TreeSet<T>(comparator);
+ Set<T> s = new TreeSet<>(comparator);
s.addAll(map.keySet());
return s;
}
@@ -161,6 +162,7 @@
return map.keySet();
}
+ @Override
public Iterator<T> iterator() {
return map.keySet().iterator();
}
@@ -173,6 +175,7 @@
return map.size();
}
+ @Override
public String toString() {
return map.toString();
}
@@ -191,6 +194,7 @@
return this;
}
+ @Override
public int compareTo(Counter2<T> o) {
Iterator<T> i = map.keySet().iterator();
Iterator<T> j = o.map.keySet().iterator();
diff --git a/tools/java/org/unicode/cldr/util/CoverageInfo.java b/tools/java/org/unicode/cldr/util/CoverageInfo.java
index 0848497..6d2b779 100644
--- a/tools/java/org/unicode/cldr/util/CoverageInfo.java
+++ b/tools/java/org/unicode/cldr/util/CoverageInfo.java
@@ -25,10 +25,12 @@
this.location);
}
+ @Override
public int hashCode() {
return hashCode;
}
+ @Override
public boolean equals(Object other) {
if (other == null) {
return false;
diff --git a/tools/java/org/unicode/cldr/util/DateTimeFormats.java b/tools/java/org/unicode/cldr/util/DateTimeFormats.java
index 5b569f9..94123b0 100644
--- a/tools/java/org/unicode/cldr/util/DateTimeFormats.java
+++ b/tools/java/org/unicode/cldr/util/DateTimeFormats.java
@@ -842,14 +842,14 @@
Factory factory = Factory.make(CLDRPaths.MAIN_DIRECTORY, LOCALES);
System.out.println("Total locales: " + factory.getAvailableLanguages().size());
DateTimeFormats english = new DateTimeFormats().set(englishFile, "gregorian");
-
+
new File(DIR).mkdirs();
FileCopier.copy(ShowData.class, "verify-index.html", CLDRPaths.VERIFY_DIR, "index.html");
FileCopier.copy(ChartDelta.class, "index.css", CLDRPaths.VERIFY_DIR, "index.css");
FormattedFileWriter.copyIncludeHtmls(CLDRPaths.VERIFY_DIR);
PrintWriter index = openIndex(DIR, "Date/Time");
- Map<String, String> sorted = new TreeMap<String, String>();
+ Map<String, String> sorted = new TreeMap<>();
SupplementalDataInfo sdi = SupplementalDataInfo.getInstance();
Set<String> defaultContent = sdi.getDefaultContentLocales();
for (String localeID : factory.getAvailableLanguages()) {
diff --git a/tools/java/org/unicode/cldr/util/DayPeriodConverter.java b/tools/java/org/unicode/cldr/util/DayPeriodConverter.java
index 60e0718..e3ed903 100644
--- a/tools/java/org/unicode/cldr/util/DayPeriodConverter.java
+++ b/tools/java/org/unicode/cldr/util/DayPeriodConverter.java
@@ -27,8 +27,8 @@
static class DayInfo {
ULocale locale;
DayPeriods.DayPeriod[] data = new DayPeriod[24];
- Map<DayPeriod, String> toNativeName = new EnumMap<DayPeriod, String>(DayPeriod.class);
- Map<String, DayPeriod> toDayPeriod = new HashMap<String, DayPeriod>();
+ Map<DayPeriod, String> toNativeName = new EnumMap<>(DayPeriod.class);
+ Map<String, DayPeriod> toDayPeriod = new HashMap<>();
@Override
public String toString() {
diff --git a/tools/java/org/unicode/cldr/util/DayPeriodInfo.java b/tools/java/org/unicode/cldr/util/DayPeriodInfo.java
index 63ca491..401bbcc 100644
--- a/tools/java/org/unicode/cldr/util/DayPeriodInfo.java
+++ b/tools/java/org/unicode/cldr/util/DayPeriodInfo.java
@@ -119,7 +119,7 @@
public boolean isFixed() {
return span != null;
}
- };
+ }
// the arrays must be in sorted order. First must have start= zero. Last must have end = DAY_LIMIT (and !includesEnd)
// each of these will have the same length, and correspond.
@@ -241,6 +241,9 @@
*/
public R3<Integer, Integer, Boolean> getFirstDayPeriodInfo(DayPeriodInfo.DayPeriod dayPeriod) {
Span span = getFirstDayPeriodSpan(dayPeriod);
+ if (span == null) {
+ return null;
+ }
return Row.of(span.start, span.end, true);
}
@@ -334,11 +337,16 @@
break;
}
StringBuilder result = new StringBuilder();
- for (Span span : dayPeriodsToSpans.get(dayPeriod)) {
- if (result.length() != 0) {
- result.append("; ");
+ Set<Span> set = dayPeriodsToSpans.get(dayPeriod);
+ if (set != null) {
+ for (Span span : set) {
+ if (span != null) {
+ if (result.length() != 0) {
+ result.append("; ");
+ }
+ result.append(span.toStringPlain());
+ }
}
- result.append(span.toStringPlain());
}
return result.toString();
}
@@ -351,7 +359,7 @@
}
// Day periods that are allowed to collide
- private static final EnumMap<DayPeriod, EnumSet<DayPeriod>> allowableCollisions = new EnumMap<DayPeriod, EnumSet<DayPeriod>>(DayPeriod.class);
+ private static final EnumMap<DayPeriod, EnumSet<DayPeriod>> allowableCollisions = new EnumMap<>(DayPeriod.class);
static {
allowableCollisions.put(DayPeriod.am, EnumSet.of(DayPeriod.morning1, DayPeriod.morning2));
allowableCollisions.put(DayPeriod.pm, EnumSet.of(DayPeriod.afternoon1, DayPeriod.afternoon2, DayPeriod.evening1, DayPeriod.evening2));
diff --git a/tools/java/org/unicode/cldr/util/DelegatingIterator.java b/tools/java/org/unicode/cldr/util/DelegatingIterator.java
index 4d02f24..f7add6c 100644
--- a/tools/java/org/unicode/cldr/util/DelegatingIterator.java
+++ b/tools/java/org/unicode/cldr/util/DelegatingIterator.java
@@ -13,6 +13,7 @@
this.iterators = iterators;
}
+ @Override
public boolean hasNext() {
while (item < iterators.length) {
boolean result = iterators[item].hasNext();
@@ -24,6 +25,7 @@
return false;
}
+ @Override
public T next() {
while (item < iterators.length) {
try {
@@ -35,13 +37,14 @@
throw new NoSuchElementException();
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
public static <T> Iterable<T> iterable(Iterable<T>... s) {
- return new MyIterable<T>(s);
+ return new MyIterable<>(s);
}
@SuppressWarnings("unchecked")
@@ -57,13 +60,14 @@
iterables = s;
}
+ @Override
@SuppressWarnings("unchecked")
public Iterator<T> iterator() {
Iterator<T>[] iterators = new Iterator[iterables.length];
for (int i = 0; i < iterables.length; ++i) {
iterators[i] = iterables[i].iterator();
}
- return new DelegatingIterator<T>(iterators);
+ return new DelegatingIterator<>(iterators);
}
}
}
diff --git a/tools/java/org/unicode/cldr/util/Dictionary.java b/tools/java/org/unicode/cldr/util/Dictionary.java
index 8d4c80d..923214f 100644
--- a/tools/java/org/unicode/cldr/util/Dictionary.java
+++ b/tools/java/org/unicode/cldr/util/Dictionary.java
@@ -166,7 +166,7 @@
* @return
*/
public Matcher<T> setText(CharSequence text) {
- this.text = new CharUtilities.CharSourceWrapper<CharSequence>(text);
+ this.text = new CharUtilities.CharSourceWrapper<>(text);
return setOffset(0);
}
@@ -290,7 +290,7 @@
* Only one value: the longest MATCH or PARTIAL (but only the Partial if it is at the end).
*/
LONGEST_WITH_FINAL_PARTIAL
- };
+ }
/**
* Finds the next match, and sets the matchValue and matchEnd. Normally you
@@ -425,6 +425,7 @@
/**
* For debugging
*/
+ @Override
public String toString() {
return "{offset: " + offset + ", end: " + matchEnd + ", value: " + matchValue + ", text: \""
+ text.subSequence(0, text.getKnownLength())
@@ -451,6 +452,7 @@
* If the text has isolated surrogates, they will not sort correctly.
*/
public static final Comparator<CharSequence> CHAR_SEQUENCE_COMPARATOR = new Comparator<CharSequence>() {
+ @Override
public int compare(CharSequence o1, CharSequence o2) {
return CharUtilities.compare(o1, o2);
}
@@ -470,6 +472,7 @@
sourceOffsets = new int[source.length()];
}
+ @Override
public boolean hasCharAt(int index) {
if (index >= buffer.length()) {
if (atEnd) {
@@ -481,6 +484,7 @@
return true;
}
+ @Override
public char charAt(int index) {
if (!atEnd && index >= buffer.length()) {
growToOffset(index + 1);
@@ -527,11 +531,13 @@
}
}
+ @Override
public int fromSourceOffset(int offset) {
// TODO fix to do real binary search; returning a determinate value.
return Arrays.binarySearch(sourceOffsets, offset);
}
+ @Override
public int toSourceOffset(int offset) {
if (offset > buffer.length()) {
growToOffset(offset);
@@ -542,6 +548,7 @@
return sourceOffsets[offset];
}
+ @Override
public CharSequence subSequence(int start, int end) {
if (!atEnd && end > buffer.length()) {
growToOffset(end);
@@ -549,6 +556,7 @@
return buffer.subSequence(start, end);
}
+ @Override
public CharSequence sourceSubSequence(int start, int end) {
// TODO Auto-generated method stub
return source.subSequence(toSourceOffset(start), toSourceOffset(end));
diff --git a/tools/java/org/unicode/cldr/util/DictionaryStringByteConverter.java b/tools/java/org/unicode/cldr/util/DictionaryStringByteConverter.java
index 85b2eea..ed28222 100644
--- a/tools/java/org/unicode/cldr/util/DictionaryStringByteConverter.java
+++ b/tools/java/org/unicode/cldr/util/DictionaryStringByteConverter.java
@@ -113,7 +113,7 @@
byteMaker.fromBytes(input, byteStart, byteLength, internal);
// then convert using dictionary
if (backMatcher == null) {
- Map<CharSequence, CharSequence> back = new TreeMap<CharSequence, CharSequence>(
+ Map<CharSequence, CharSequence> back = new TreeMap<>(
Dictionary.CHAR_SEQUENCE_COMPARATOR);
for (Iterator<Entry<CharSequence, String>> m = dictionary.getMapping(); m.hasNext();) {
Entry<CharSequence, String> entry = m.next();
diff --git a/tools/java/org/unicode/cldr/util/DiscreteComparator.java b/tools/java/org/unicode/cldr/util/DiscreteComparator.java
index ca1e8fc..efc9537 100644
--- a/tools/java/org/unicode/cldr/util/DiscreteComparator.java
+++ b/tools/java/org/unicode/cldr/util/DiscreteComparator.java
@@ -62,6 +62,7 @@
* thrown if there is no backup comparator, and at least one of
* the items is not explicit in the collator.
*/
+ @Override
public int compare(T o1, T o2) {
// TODO add option for back ordering
Integer a = ordering.get(o1);
@@ -92,7 +93,7 @@
* @return a list
*/
public List<T> getOrdering() {
- return new ArrayList<T>(ordering.keySet());
+ return new ArrayList<>(ordering.keySet());
}
@Override
@@ -121,9 +122,9 @@
*/
public Builder(Ordering order) {
this.order = order;
- all = order == Ordering.CHRONOLOGICAL ? new LinkedHashMap<T, Node<T>>()
- : order == Ordering.NATURAL ? new TreeMap<T, Node<T>>()
- : new HashMap<T, Node<T>>();
+ all = order == Ordering.CHRONOLOGICAL ? new LinkedHashMap<>()
+ : order == Ordering.NATURAL ? new TreeMap<>()
+ : new HashMap<>();
}
/**
@@ -237,7 +238,7 @@
if (DEBUG) {
debugIndent = new Exception().getStackTrace().length;
}
- Map<T, Integer> ordering = new LinkedHashMap<T, Integer>();
+ Map<T, Integer> ordering = new LinkedHashMap<>();
for (Node<T> subNode : all.values()) {
if (!subNode.visited) {
try {
@@ -253,7 +254,7 @@
}
// clean up, so another call doesn't mess things up
all.clear();
- return new DiscreteComparator<T>(ordering, backupOrdering);
+ return new DiscreteComparator<>(ordering, backupOrdering);
}
/**
@@ -262,7 +263,7 @@
* @return list of items that form a cycle, in order from least to greatest
*/
public List<T> getCycle() {
- List<T> result = new LinkedList<T>();
+ List<T> result = new LinkedList<>();
Collection<Node<T>> lesser = all.values();
main: while (true) {
for (Node<T> item : lesser) {
@@ -289,7 +290,7 @@
}
private Node<T> addNew(T a) {
- Node<T> aNode = new Node<T>(a, order);
+ Node<T> aNode = new Node<>(a, order);
all.put(a, aNode);
return aNode;
}
@@ -302,10 +303,10 @@
private boolean chained = false;
public Node(T a, Ordering order) {
- less = new LinkedHashSet<Node<T>>();
- less = order == Ordering.CHRONOLOGICAL ? new LinkedHashSet<Node<T>>()
- : order == Ordering.NATURAL ? new TreeSet<Node<T>>()
- : new HashSet<Node<T>>();
+ less = new LinkedHashSet<>();
+ less = order == Ordering.CHRONOLOGICAL ? new LinkedHashSet<>()
+ : order == Ordering.NATURAL ? new TreeSet<>()
+ : new HashSet<>();
me = a;
}
@@ -331,6 +332,7 @@
resultOrdering.put(currentNode.me, resultOrdering.size());
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(me == null ? null : me.toString()).append(" >");
@@ -340,9 +342,10 @@
return result.toString();
}
+ @Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compareTo(Node<T> o) {
- return ((Comparable) me).compareTo((Comparable) (o.me));
+ return ((Comparable) me).compareTo((o.me));
}
}
diff --git a/tools/java/org/unicode/cldr/util/DtdData.java b/tools/java/org/unicode/cldr/util/DtdData.java
index 4cefe32..a0acd3f 100644
--- a/tools/java/org/unicode/cldr/util/DtdData.java
+++ b/tools/java/org/unicode/cldr/util/DtdData.java
@@ -23,13 +23,13 @@
import java.util.regex.Pattern;
import com.google.common.base.CharMatcher;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.Transform;
@@ -46,7 +46,7 @@
private static final Pattern FILLER = PatternCache.get("[^-a-zA-Z0-9#_:]");
private final Relation<String, Attribute> nameToAttributes = Relation.of(new TreeMap<String, Set<Attribute>>(), LinkedHashSet.class);
- private Map<String, Element> nameToElement = new HashMap<String, Element>();
+ private Map<String, Element> nameToElement = new HashMap<>();
private MapComparator<String> elementComparator;
private MapComparator<String> attributeComparator;
@@ -61,8 +61,8 @@
private DtdComparator dtdComparator;
public enum AttributeStatus {
- distinguished ("§d"),
- value ("§v"),
+ distinguished ("§d"),
+ value ("§v"),
metadata ("§m︎");
public final String shortName;
AttributeStatus(String shortName) {
@@ -99,9 +99,15 @@
CDATA, ID, IDREF, IDREFS, ENTITY, ENTITIES, NMTOKEN, NMTOKENS, ENUMERATED_TYPE
}
- static final Set<String> DRAFT_ON_NON_LEAF_ALLOWED = ImmutableSet.of("collation", "transform", "unitPreferenceData");
-
+ static final Set<String> DRAFT_ON_NON_LEAF_ALLOWED = ImmutableSet.of("collation", "transform", "unitPreferenceData", "rulesetGrouping");
+
public static class Attribute implements Named {
+ private static final Joiner JOINER_COMMA_SPACE = Joiner.on(", ");
+ public static final String AUG_TRAIL = "⟫";
+ public static final String AUG_LEAD = "⟪";
+ public static final String ENUM_TRAIL = "⟩";
+ public static final String ENUM_LEAD = "⟨";
+ public static final Pattern LEAD_TRAIL = Pattern.compile("(.*[" + AUG_LEAD + ENUM_LEAD + "])(.*)([" + AUG_TRAIL + ENUM_TRAIL + "].*)");
public final String name;
public final Element element;
public final Mode mode;
@@ -145,7 +151,7 @@
type = _type;
if (_type == AttributeType.ENUMERATED_TYPE) {
- LinkedHashMap<String, Integer> temp = new LinkedHashMap<String, Integer>();
+ LinkedHashMap<String, Integer> temp = new LinkedHashMap<>();
for (String part : split) {
if (part.length() != 0) {
temp.put(part.intern(), temp.size());
@@ -162,6 +168,12 @@
return element.name + ":" + name;
}
+ public String getSampleValue() {
+ return type == AttributeType.ENUMERATED_TYPE ? (values.containsKey("year") ? "year" : values.keySet().iterator().next())
+ : matchValue != null ? matchValue.getSample()
+ : MatchValue.DEFAULT_SAMPLE;
+ }
+
public StringBuilder appendDtdString(StringBuilder b) {
Attribute a = this;
b.append("<!ATTLIST " + element.name + " " + a.name);
@@ -295,16 +307,16 @@
}
public ValueStatus getValueStatus(String value) {
- return deprecatedValues.contains(value) ? ValueStatus.invalid
+ return deprecatedValues.contains(value) ? ValueStatus.invalid
: type == AttributeType.ENUMERATED_TYPE ? (values.containsKey(value) ? ValueStatus.valid : ValueStatus.invalid)
: matchValue == null ? ValueStatus.unknown
- : matchValue.is(value) ? ValueStatus.valid
+ : matchValue.is(value) ? ValueStatus.valid
: ValueStatus.invalid;
}
public String getMatchString() {
- return type == AttributeType.ENUMERATED_TYPE ? "⟨" + CollectionUtilities.join(values.keySet(), ", ") + "⟩"
- : matchValue != null ? "⟪" + matchValue.toString() + "⟫"
+ return type == AttributeType.ENUMERATED_TYPE ? ENUM_LEAD + JOINER_COMMA_SPACE.join(values.keySet()) + ENUM_TRAIL
+ : matchValue != null ? AUG_LEAD + matchValue.toString() + AUG_TRAIL
: "";
}
@@ -361,8 +373,8 @@
public final String name;
private String rawModel;
private ElementType type;
- private final Map<Element, Integer> children = new LinkedHashMap<Element, Integer>();
- private final Map<Attribute, Integer> attributes = new LinkedHashMap<Attribute, Integer>();
+ private final Map<Element, Integer> children = new LinkedHashMap<>();
+ private final Map<Attribute, Integer> attributes = new LinkedHashMap<>();
private Set<String> commentsPre;
private Set<String> commentsPost;
private String model;
@@ -579,6 +591,7 @@
/**
* @deprecated
*/
+ @Deprecated
@Override
public void handleElementDecl(String name, String model) {
if (SHOW_ALL) {
@@ -592,17 +605,19 @@
/**
* @deprecated
*/
+ @Deprecated
@Override
public void handleStartDtd(String name, String publicId, String systemId) {
DtdType explicitDtdType = DtdType.valueOf(name);
if (explicitDtdType != dtdType && explicitDtdType != dtdType.rootType) {
throw new IllegalArgumentException("Mismatch in dtdTypes");
}
- };
+ }
/**
* @deprecated
*/
+ @Deprecated
@Override
public void handleAttributeDecl(String eName, String aName, String type, String mode, String value) {
if (SHOW_ALL) {
@@ -627,6 +642,7 @@
/**
* @deprecated
*/
+ @Deprecated
@Override
public void handleComment(String path, String comment) {
if (SHOW_ALL) {
@@ -640,6 +656,7 @@
/**
* @deprecated
*/
+ @Deprecated
@Override
public void handleEndDtd() {
throw new XMLFileReader.AbortException();
@@ -649,6 +666,7 @@
* Note that it always gets the trunk version
* @deprecated depends on static config, use {@link DtdData#getInstance(DtdType, File)} instead
*/
+ @Deprecated
public static DtdData getInstance(DtdType type) {
return getInstance(type, CLDRConfig.getInstance().getCldrBaseDirectory());
}
@@ -725,9 +743,9 @@
private void freeze() {
if (version == null) { // only generate for new versions
- MergeLists<String> elementMergeList = new MergeLists<String>();
+ MergeLists<String> elementMergeList = new MergeLists<>();
elementMergeList.add(dtdType.toString());
- MergeLists<String> attributeMergeList = new MergeLists<String>();
+ MergeLists<String> attributeMergeList = new MergeLists<>();
attributeMergeList.add("_q");
for (Element element : nameToElement.values()) {
@@ -752,15 +770,15 @@
System.out.println("Element Ordering:\t" + elementList);
System.out.println("Attribute Ordering:\t" + attributeList);
}
- elementComparator = new MapComparator<String>(elementList).setErrorOnMissing(true).freeze();
- attributeComparator = new MapComparator<String>(attributeList).setErrorOnMissing(true).freeze();
+ elementComparator = new MapComparator<>(elementList).setErrorOnMissing(true).freeze();
+ attributeComparator = new MapComparator<>(attributeList).setErrorOnMissing(true).freeze();
}
nameToAttributes.freeze();
nameToElement = Collections.unmodifiableMap(nameToElement);
}
private Collection<String> getNames(Collection<? extends Named> keySet) {
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (Named e : keySet) {
result.add(e.getName());
}
@@ -779,11 +797,19 @@
return dtdComparator;
}
- private class DtdComparator implements Comparator<String> {
+ public DtdComparator getDtdComparator() {
+ return dtdComparator;
+ }
+
+ public class DtdComparator implements Comparator<String> {
@Override
public int compare(String path1, String path2) {
XPathParts a = XPathParts.getFrozenInstance(path1);
XPathParts b = XPathParts.getFrozenInstance(path2);
+ return xpathComparator(a, b);
+ }
+
+ public int xpathComparator(XPathParts a, XPathParts b) {
// there must always be at least one element
String baseA = a.getElement(0);
String baseB = b.getElement(0);
@@ -873,6 +899,7 @@
return attributeComparator;
}
+
public MapComparator<String> getElementComparator() {
return elementComparator;
}
@@ -885,6 +912,7 @@
return nameToElement;
}
+ @Override
public String toString() {
StringBuilder b = new StringBuilder();
// <!ELEMENT ldml (identity, (alias | (fallback*, localeDisplayNames?, layout?, contextTransforms?, characters?, delimiters?, measurement?, dates?, numbers?, units?, listPatterns?, collations?, posix?, segmentations?, rbnf?, metadata?, references?, special*))) >
@@ -909,8 +937,8 @@
}
static final class Seen {
- Set<Element> seenElements = new HashSet<Element>();
- Set<Attribute> seenAttributes = new HashSet<Attribute>();
+ Set<Element> seenElements = new HashSet<>();
+ Set<Attribute> seenAttributes = new HashSet<>();
public Seen(DtdType dtdType) {
if (dtdType.rootType == dtdType) {
@@ -954,7 +982,7 @@
Element aliasElement = getElementFromName().get("alias");
//b.append(current.rawChildren);
if (!current.children.isEmpty()) {
- LinkedHashSet<Element> elements = new LinkedHashSet<Element>(current.children.keySet());
+ LinkedHashSet<Element> elements = new LinkedHashSet<>(current.children.keySet());
boolean hasAlias = aliasElement != null && elements.remove(aliasElement);
//boolean hasSpecial = specialElement != null && elements.remove(specialElement);
if (hasAlias) {
@@ -1050,7 +1078,8 @@
if (attributeDeprecated) {
b.append(COMMENT_PREFIX + "<!--@DEPRECATED-->");
} else if (!deprecatedValues.isEmpty()) {
- b.append(COMMENT_PREFIX + "<!--@DEPRECATED:" + CollectionUtilities.join(deprecatedValues, ", ") + "-->");
+ b.append(COMMENT_PREFIX + "<!--@DEPRECATED:" + Joiner.on(", ")
+ .join(deprecatedValues) + "-->");
}
}
if (current.children.size() > 0) {
@@ -1101,11 +1130,11 @@
}
public Set<Element> getElements() {
- return new LinkedHashSet<Element>(nameToElement.values());
+ return new LinkedHashSet<>(nameToElement.values());
}
public Set<Attribute> getAttributes() {
- return new LinkedHashSet<Attribute>(nameToAttributes.values());
+ return new LinkedHashSet<>(nameToAttributes.values());
}
public boolean isDistinguishing(String elementName, String attribute) {
@@ -1237,7 +1266,10 @@
"minute", "minute-short", "minute-narrow",
"second", "second-short", "second-narrow",
"zone", "zone-short", "zone-narrow").freeze();
- static MapComparator<String> unitOrder = new MapComparator<String>().add(
+
+ /* TODO: change this to be data-file driven. Can do with new Unit preferences info; also put them in a more meaningful order (metric vs other; size) */
+
+ public static final MapComparator<String> unitOrder = new MapComparator<String>().add(
"acceleration-g-force", "acceleration-meter-per-square-second",
"angle-revolution", "angle-radian", "angle-degree", "angle-arc-minute", "angle-arc-second",
"area-square-kilometer", "area-hectare", "area-square-meter", "area-square-centimeter",
@@ -1245,6 +1277,8 @@
"area-dunam",
"concentr-karat",
"concentr-milligram-per-deciliter", "concentr-millimole-per-liter",
+ "concentr-item",
+ "concentr-portion",
"concentr-permillion", "concentr-percent", "concentr-permille", "concentr-permyriad",
"concentr-mole",
"consumption-liter-per-kilometer", "consumption-liter-per-100-kilometer",
@@ -1269,7 +1303,10 @@
"frequency-gigahertz", "frequency-megahertz", "frequency-kilohertz", "frequency-hertz",
"graphics-em", "graphics-pixel", "graphics-megapixel",
"graphics-pixel-per-centimeter", "graphics-pixel-per-inch",
- "graphics-dot-per-centimeter", "graphics-dot-per-inch",
+ "graphics-dot-per-centimeter", "graphics-dot-per-inch",
+ "graphics-dot",
+ "length-earth-radius",
+ "length-100-kilometer",
"length-kilometer", "length-meter", "length-decimeter", "length-centimeter",
"length-millimeter", "length-micrometer", "length-nanometer", "length-picometer",
"length-mile", "length-yard", "length-foot", "length-inch",
@@ -1279,6 +1316,8 @@
"length-point",
"length-solar-radius",
"light-lux",
+ "light-candela",
+ "light-lumen",
"light-solar-luminosity",
"mass-metric-ton", "mass-kilogram", "mass-gram", "mass-milligram", "mass-microgram",
"mass-ton", "mass-stone", "mass-pound", "mass-ounce",
@@ -1286,12 +1325,16 @@
"mass-dalton",
"mass-earth-mass",
"mass-solar-mass",
+
+ "mass-grain",
+
"power-gigawatt", "power-megawatt", "power-kilowatt", "power-watt", "power-milliwatt",
"power-horsepower",
"pressure-millimeter-ofhg",
+ "pressure-ofhg",
"pressure-pound-force-per-square-inch", "pressure-inch-ofhg", "pressure-bar", "pressure-millibar", "pressure-atmosphere",
"pressure-pascal",
- "pressure-hectopascal",
+ "pressure-hectopascal",
"pressure-kilopascal",
"pressure-megapascal",
"speed-kilometer-per-hour", "speed-meter-per-second", "speed-mile-per-hour", "speed-knot",
@@ -1305,7 +1348,17 @@
"volume-acre-foot",
"volume-bushel", "volume-gallon", "volume-gallon-imperial", "volume-quart", "volume-pint", "volume-cup",
"volume-fluid-ounce", "volume-fluid-ounce-imperial", "volume-tablespoon", "volume-teaspoon",
- "volume-barrel").freeze();
+ "volume-barrel",
+
+ "volume-dessert-spoon",
+ "volume-dessert-spoon-imperial",
+ "volume-drop",
+ "volume-dram",
+ "volume-jigger",
+ "volume-pinch",
+ "volume-quart-imperial"
+ // "volume-pint-imperial"
+ ).freeze();
static MapComparator<String> countValueOrder = new MapComparator<String>().add(
"0", "1", "zero", "one", "two", "few", "many", "other").freeze();
@@ -1499,7 +1552,7 @@
if (attributeValues.size() == 1) {
addAttribute(attribute, attributeValues.iterator().next());
} else {
- // duplicate all the items in the list with the given values
+ // duplicate all the items in the list with the given values
Set<XPathParts> newList = new LinkedHashSet<>();
for (XPathParts item : list) {
for (String attributeValue : attributeValues) {
@@ -1560,7 +1613,7 @@
boolean hasValue = hasValue(element);
// if it doesn't have a value, we construct new child elements, with _ prefix
// if it does have a value, we have to play a further trick, since
- // we can't have a value and child elements at the same level.
+ // we can't have a value and child elements at the same level.
// So we use a _ suffix on the element.
if (hasValue) {
pathResult.setElement(i, element + "_");
diff --git a/tools/java/org/unicode/cldr/util/DtdDataCheck.java b/tools/java/org/unicode/cldr/util/DtdDataCheck.java
index 76907d5..4ff754a 100644
--- a/tools/java/org/unicode/cldr/util/DtdDataCheck.java
+++ b/tools/java/org/unicode/cldr/util/DtdDataCheck.java
@@ -19,7 +19,7 @@
import org.unicode.cldr.util.DtdData.Element;
import org.unicode.cldr.util.DtdData.ElementType;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -29,20 +29,20 @@
static SupplementalDataInfo SUPPLEMENTAL = SupplementalDataInfo.getInstance();
- static final Set<Row.R4<DtdType, String, String, String>> DEPRECATED = new LinkedHashSet<Row.R4<DtdType, String, String, String>>();
- static final Map<Row.R2<DtdType, String>, Relation<Boolean, String>> TYPE_ATTRIBUTE_TO_DIST_ELEMENTS = new TreeMap<Row.R2<DtdType, String>, Relation<Boolean, String>>();
+ static final Set<Row.R4<DtdType, String, String, String>> DEPRECATED = new LinkedHashSet<>();
+ static final Map<Row.R2<DtdType, String>, Relation<Boolean, String>> TYPE_ATTRIBUTE_TO_DIST_ELEMENTS = new TreeMap<>();
private static final boolean CHECK_CORRECTNESS = false;
private static class Walker {
- HashSet<Element> seen = new HashSet<Element>();
- Set<Element> elementsMissingDraft = new LinkedHashSet<Element>();
- Set<Element> elementsMissingAlt = new LinkedHashSet<Element>();
- static final Set<String> SKIP_ATTRIBUTES = new HashSet<String>(Arrays.asList(
+ HashSet<Element> seen = new HashSet<>();
+ Set<Element> elementsMissingDraft = new LinkedHashSet<>();
+ Set<Element> elementsMissingAlt = new LinkedHashSet<>();
+ static final Set<String> SKIP_ATTRIBUTES = new HashSet<>(Arrays.asList(
"draft", "alt", "standard", "references"));
- static final Set<String> SKIP_ELEMENTS = new HashSet<String>(Arrays.asList(
+ static final Set<String> SKIP_ELEMENTS = new HashSet<>(Arrays.asList(
"alias", "special"));
- Set<Attribute> attributesWithDefaultValues = new LinkedHashSet<Attribute>();
+ Set<Attribute> attributesWithDefaultValues = new LinkedHashSet<>();
private DtdData dtdData;
@@ -184,7 +184,7 @@
}
new Walker(dtdData).show(dtdData.ROOT);
if (CHECK_CORRECTNESS && type == DtdType.ldml) {
- Set<String> errors = new LinkedHashSet<String>();
+ Set<String> errors = new LinkedHashSet<>();
// checkOrder(dtdData.ROOT, errors);
// for (String error : errors) {
// System.out.println("ERROR:\t" + error);
@@ -201,7 +201,7 @@
Comparator<String> comp = dtdData.getDtdComparator(null);
CLDRFile test = ToolConfig.getToolInstance().getEnglish();
Set<String> sorted = new TreeSet(test.getComparator());
- CollectionUtilities.addAll(test.iterator(), sorted);
+ test.forEach(sorted::add);
String[] sortedArray = sorted.toArray(new String[sorted.size()]);
// compare for identity
@@ -240,7 +240,7 @@
}
int i = 0;
System.out.println(" <distinguishing>");
- Set<String> allElements = new TreeSet<String>();
+ Set<String> allElements = new TreeSet<>();
allElements.add("_q");
DtdType lastType = null;
@@ -266,12 +266,12 @@
}
System.out.println(" <distinguishingItems"
+ " type=\"" + type
- + "\" elements=\"" + CollectionUtilities.join(areDisting, " ")
+ + "\" elements=\"" + Joiner.on(" ").join(areDisting)
+ "\" attributes=\"" + attribute
+ "\"/>"
+ "\n <!-- NONDISTINGUISH."
+ " TYPE=\"" + type
- + "\" ELEMENTS=\"" + CollectionUtilities.join(areNotDisting, " ")
+ + "\" ELEMENTS=\"" + Joiner.on(" ").join(areNotDisting)
+ "\" ATTRIBUTES=\"" + attribute
+ "\" -->");
}
@@ -294,7 +294,7 @@
System.out.println(" <distinguishingItems"
+ " type=\"" + type
+ "\" elements=\"*"
- + "\" attributes=\"" + CollectionUtilities.join(allElements, " ")
+ + "\" attributes=\"" + Joiner.on(" ").join(allElements)
+ "\"/>");
allElements.clear();
allElements.add("_q");
diff --git a/tools/java/org/unicode/cldr/util/DtdPathIterator.java b/tools/java/org/unicode/cldr/util/DtdPathIterator.java
new file mode 100644
index 0000000..cf70115
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/DtdPathIterator.java
@@ -0,0 +1,192 @@
+package org.unicode.cldr.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.unicode.cldr.util.DtdData.Attribute;
+import org.unicode.cldr.util.DtdData.AttributeStatus;
+import org.unicode.cldr.util.DtdData.Element;
+import org.unicode.cldr.util.DtdData.Mode;
+import org.unicode.cldr.util.PathHeader.Factory;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Walk through all the possible paths in a DTDData
+ * @author markdavis
+ *
+ */
+public class DtdPathIterator {
+ public DtdPathIterator(DtdData dtdData) {
+ super();
+ this.dtdData = dtdData;
+ this.xpathParts = new XPathParts();
+ }
+
+ final DtdData dtdData;
+ final XPathParts xpathParts;
+
+ /**
+ * Visit the generated parts. Warning: the function must not modify the XPathParts.
+ * @param function
+ */
+ public void visit(Consumer<XPathParts> function, Function<Attribute, String> sample) {
+ xpathParts.clear();
+ visit(dtdData.ROOT, function, sample);
+ }
+
+ private void visit(Element parent, Consumer<XPathParts> visitor, Function<Attribute, String> sample) {
+ if (parent.isDeprecated()) {
+ return;
+ }
+ // add element and all its possible attributes
+ final String parentName = parent.getName();
+ if (parentName.contentEquals("exemplarCharacters")) {
+ int debug = 0;
+ }
+ if (parentName.equals("alias") || parentName.equals("identity") || parentName.equals("special")) {
+ return;
+ }
+ Set<Element> children = parent.getChildren().keySet();
+ // filter children to non-deprecated
+ if (!children.isEmpty()) {
+ Set<Element> temp = new LinkedHashSet<>();
+ for (Element e : children) {
+ if (!e.isDeprecated()) {
+ temp.add(e);
+ }
+ }
+ children = ImmutableSet.copyOf(temp);
+ }
+ int index = xpathParts.size();
+ xpathParts.addElement(parentName);
+
+ // get possible attributes
+ List<Attribute> optionalAttributes = new ArrayList<>();
+ for (Attribute attribute : parent.getAttributes().keySet()) {
+ if (attribute.isDeprecated()
+ || attribute.getStatus() != AttributeStatus.distinguished) {
+ continue;
+ }
+ String attributeName = attribute.getName();
+ if (!attributeName.equals("alt")) {
+ if (attribute.mode == Mode.OPTIONAL) {
+ if (parentName.equals("displayName") && attributeName.equals("count") && !xpathParts.contains("currency")) {
+ // skip
+ } else {
+ optionalAttributes.add(attribute);
+ }
+ } else {
+ xpathParts.setAttribute(index, attributeName, sample.apply(attribute));
+ }
+ }
+ }
+ if (!optionalAttributes.isEmpty()) {
+ int comboMax = (1 << optionalAttributes.size());
+ for (int bitmask = comboMax - 1; bitmask >= 0; --bitmask) {
+ // for two items, go from 0b11, 0b10, 0b01, 0b00; for 1: 0b1, 0b0
+ for (int bit = 0; bit < optionalAttributes.size(); ++bit) {
+ final Attribute attribute = optionalAttributes.get(bit);
+ String attributeName = attribute.getName();
+ if ((bitmask & (1 << bit)) == 0) {
+ xpathParts.setAttribute(index, attributeName, sample.apply(attribute));
+ } else {
+ xpathParts.removeAttribute(index, attributeName);
+ }
+ if (children.isEmpty()) {
+ // check the path.
+ visitor.accept(xpathParts);
+ } else {
+ for (Element child : children) {
+ visit(child, visitor, sample);
+ }
+ }
+ }
+ }
+ } else {
+ if (children.isEmpty()) {
+ // check the path.
+ visitor.accept(xpathParts);
+ } else {
+ for (Element child : children) {
+ visit(child, visitor, sample);
+ }
+ }
+ }
+ // cleanup
+ // remove the element we added
+ xpathParts.removeElement(index);
+ }
+
+ public static void main(String[] args) {
+ Set<XPathParts>seen = new HashSet<>();
+ Set<PathHeader>seenPh = new HashSet<>();
+ DtdPathIterator dtdPathIterator = new DtdPathIterator(DtdData.getInstance(DtdType.ldml));
+ Factory phf = PathHeader.getFactory();
+ List<String> failures = new ArrayList<>();
+ org.unicode.cldr.util.Factory factory = CLDRConfig.getInstance().getCommonAndSeedAndMainAndAnnotationsFactory();
+
+ // get all the actual starred patterns
+
+ PathStarrer ps = new PathStarrer().setSubstitutionPattern("%A");
+ Map<String, String> starredToSample = new TreeMap<>();
+ for (String locale : Arrays.asList("en", "de", "zh", "ar", "ru")) {
+ CLDRFile cfile = factory.make(locale, true);
+ for (String path : cfile.fullIterable()) {
+ String starred = ps.set(path);
+ starred = starred.replace("[@alt=\"%A\"]","");
+ if (!starredToSample.containsKey(starred) && !starred.endsWith("/alias") && !starred.startsWith("//ldml/identity/")) {
+ starredToSample.put(starred, path);
+ }
+ }
+ }
+ Set<String> starredUnseen = new TreeSet<>(starredToSample.keySet());
+
+ dtdPathIterator.visit(x -> {
+ if (seen.contains(x)) {
+ int debug = 0;
+ } else {
+ failures.clear();
+ final String xString = x.toString();
+// PathHeader ph = null;
+// try {
+// ph = phf.fromPath(xString, failures);
+// if (seenPh.contains(ph)) {
+// failures.add("NON_UNIQUE");
+// } else {
+// seenPh.add(ph);
+// if (ph.getPageId() == PageId.Deprecated) {
+// return;
+// }
+// }
+// } catch (Exception e) {
+// failures.add(e.getMessage());
+// }
+ final String sample = starredToSample.get(xString);
+ starredUnseen.remove(xString);
+ System.out.println(seen.size() + "\t" + x + "\t" + failures + "\t" + sample);
+ seen.add(x.cloneAsThawed().freeze());
+ if ((seen.size() % 25) == 0) {
+ int debug = 0;
+ }
+ }
+ },
+// y -> y.getSampleValue()
+ y -> "%A"
+ );
+ if (!starredUnseen.isEmpty()) {
+ System.out.println("ERROR: In files, not dtd");
+ System.out.println(Joiner.on("\n\t").join(starredUnseen));
+ }
+ }
+}
diff --git a/tools/java/org/unicode/cldr/util/DtdType.java b/tools/java/org/unicode/cldr/util/DtdType.java
index d41446c..508e436 100644
--- a/tools/java/org/unicode/cldr/util/DtdType.java
+++ b/tools/java/org/unicode/cldr/util/DtdType.java
@@ -16,16 +16,16 @@
"collation",
"rbnf",
"segments",
- "subdivisions"),
- ldmlICU("common/dtd/ldmlICU.dtd", ldml),
+ "subdivisions"),
+ ldmlICU("common/dtd/ldmlICU.dtd", ldml),
supplementalData("common/dtd/ldmlSupplemental.dtd", null, null,
"supplemental",
"transforms",
- "validity"),
+ "validity"),
ldmlBCP47("common/dtd/ldmlBCP47.dtd", "1.7.2", null,
- "bcp47"),
+ "bcp47"),
keyboard("keyboards/dtd/ldmlKeyboard.dtd", "22.1", null,
- "../keyboards"),
+ "../keyboards"),
platform("keyboards/dtd/ldmlPlatform.dtd", "22.1", null,
"../keyboards");
public static final Set<DtdType> STANDARD_SET = ImmutableSet.of(
@@ -60,7 +60,7 @@
}
/**
- * Print a header for an XML file, where the generatedBy is normally MethodHandles.lookup().lookupClass().
+ * Print a header for an XML file, where the generatedBy is normally MethodHandles.lookup().lookupClass().
* The only time it needs to be changed is if it is not being called directly from the generating tool.
* @param generatedBy
* @return
diff --git a/tools/java/org/unicode/cldr/util/DualWriter.java b/tools/java/org/unicode/cldr/util/DualWriter.java
index 1daed65..fe01084 100644
--- a/tools/java/org/unicode/cldr/util/DualWriter.java
+++ b/tools/java/org/unicode/cldr/util/DualWriter.java
@@ -40,6 +40,7 @@
return autoflush;
}
+ @Override
public void write(char cbuf[],
int off,
int len) throws IOException {
@@ -48,11 +49,13 @@
if (autoflush) flush();
}
+ @Override
public void close() throws IOException {
a.close();
b.close();
}
+ @Override
public void flush() throws IOException {
a.flush();
b.flush();
diff --git a/tools/java/org/unicode/cldr/util/ElementAttributeInfo.java b/tools/java/org/unicode/cldr/util/ElementAttributeInfo.java
index 5b9fe6b..40459e0 100644
--- a/tools/java/org/unicode/cldr/util/ElementAttributeInfo.java
+++ b/tools/java/org/unicode/cldr/util/ElementAttributeInfo.java
@@ -26,12 +26,12 @@
public class ElementAttributeInfo {
private DtdType dtdType;
- private Map<R2<String, String>, R3<Set<String>, String, String>> elementAttribute2Data = new TreeMap<R2<String, String>, R3<Set<String>, String, String>>();
+ private Map<R2<String, String>, R3<Set<String>, String, String>> elementAttribute2Data = new TreeMap<>();
private Relation<String, String> element2children = Relation.of(new LinkedHashMap<String, Set<String>>(), LinkedHashSet.class);
private Relation<String, String> element2parents = Relation.of(new LinkedHashMap<String, Set<String>>(), LinkedHashSet.class);
private Relation<String, String> element2attributes = Relation.of(new LinkedHashMap<String, Set<String>>(), LinkedHashSet.class);
- static Map<String, Map<DtdType, ElementAttributeInfo>> cache = new HashMap<String, Map<DtdType, ElementAttributeInfo>>(); // new
+ static Map<String, Map<DtdType, ElementAttributeInfo>> cache = new HashMap<>(); // new
// HashMap<DtdType,
// Data>();
@@ -53,7 +53,7 @@
}
}
if (result == null) {
- result = new HashMap<DtdType, ElementAttributeInfo>();
+ result = new HashMap<>();
// pick short files that are in repository
result.put(DtdType.ldml, new ElementAttributeInfo(canonicalCommonDirectory + "/main/root.xml",
DtdType.ldml));
@@ -140,6 +140,7 @@
myData = indata;
}
+ @Override
public void attributeDecl(String eName, String aName, String type, String mode, String value)
throws SAXException {
if (SHOW)
@@ -158,7 +159,7 @@
}
private Set<String> getIdentifiers(String type) {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
idmatcher.reset(type);
while (idmatcher.find()) {
result.add(idmatcher.group());
@@ -169,6 +170,7 @@
return result;
}
+ @Override
public void elementDecl(String name, String model) throws SAXException {
if (SHOW) System.out.println(myData.getDtdType() + "\tElement\t" + name + "\t" + model);
Set<String> identifiers = getIdentifiers(model);
@@ -183,11 +185,13 @@
}
}
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
// TODO Auto-generated method stub
}
+ @Override
public void internalEntityDecl(String name, String value) throws SAXException {
// TODO Auto-generated method stub
diff --git a/tools/java/org/unicode/cldr/util/Emoji.java b/tools/java/org/unicode/cldr/util/Emoji.java
index e304c82..f26d0bf 100644
--- a/tools/java/org/unicode/cldr/util/Emoji.java
+++ b/tools/java/org/unicode/cldr/util/Emoji.java
@@ -1,5 +1,6 @@
package org.unicode.cldr.util;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -33,6 +34,7 @@
public static final UnicodeSet SPECIALS = new UnicodeSet("["
+ "{🐈⬛}{🐻❄}{👨🍼}{👩🍼}{🧑🍼}{🧑🎄}{🧑🤝🧑}{🏳🌈} {👁🗨} {🏴☠} {🐕🦺} {👨🦯} {👨🦼} {👨🦽} {👩🦯} {👩🦼} {👩🦽}"
+ "{🏳⚧}{🧑⚕}{🧑⚖}{🧑✈}{🧑🌾}{🧑🍳}{🧑🎓}{🧑🎤}{🧑🎨}{🧑🏫}{🧑🏭}{🧑💻}{🧑💼}{🧑🔧}{🧑🔬}{🧑🚀}{🧑🚒}{🧑🦯}{🧑🦼}{🧑🦽}"
+ + "{❤🔥}, {❤🩹}, {😮💨}, {😵💫}" // #E13.1
+ "]").freeze();
// May have to add from above, if there is a failure in testAnnotationPaths. Failure will be like:
// got java.util.TreeSet<[//ldml/annotations/annotation[@cp="🏳⚧"][@type="tts"], //ldml/annotations/annotation[@cp="🧑⚕"][@type="tts"], ...
@@ -101,11 +103,19 @@
continue;
}
Iterator<String> it = semi.split(line).iterator();
+
String emojiHex = it.next();
- if (emojiHex.contains("1F6FC")) {
+ if (emojiHex.contains("1F48F")) {
int debug = 0;
}
+
String original = Utility.fromHex(emojiHex, 4, " ");
+ if (original.contains("💏")) {
+ if (false) {
+ System.out.println(original + "\t" + Utility.hex(original));
+ }
+ }
+
String type = it.next();
if (type.startsWith("fully-qualified")) {
allRgi.add(original);
@@ -131,7 +141,7 @@
if (!emojiToOrder.containsKey(minimal)) {
putUnique(emojiToOrder, minimal, emojiToOrder.size()*100L);
}
- //
+ //
// majorPlusMinorToEmoji.put(Pair.of(majorOrder, minorOrder), minimal);
boolean singleton = CharSequences.getSingleCodePoint(minimal) != Integer.MAX_VALUE;
@@ -172,8 +182,8 @@
private static <K, V> void putUnique(Map<K, V> map, K key, V value) {
V oldValue = map.put(key, value);
if (oldValue != null) {
- throw new ICUException("Attempt to change value of " + map
- + " for " + key
+ throw new ICUException("Attempt to change value of " + map
+ + " for " + key
+ " from " + oldValue
+ " to " + value
);
@@ -196,9 +206,10 @@
{"arrow", "→ ↓ ↑ ← ↔ ↕ ⇆ ⇅"},
{"alphanum", "© ® ℗ ™ µ"},
{"geometric", "▼ ▶ ▲ ◀ ● ○ ◯ ◊"},
- {"math", "× ÷ √ ∞ ∆ ∇ ⁻ ¹ ² ³ ≡ ∈ ⊂ ∩ ∪ °"},
- {"punctuation", "– — » « • · § † ‡"},
- {"currency", "€ £ ¥ ₹ ₽"},
+ {"math", "× ÷ √ ∞ ∆ ∇ ⁻ ¹ ² ³ ≡ ∈ ⊂ ∩ ∪ ° + ± − = ≈ ≠ > < ≤ ≥ ¬ | ~"},
+ {"punctuation", "§ † ‡ \\u0020 , 、 ، ; : ؛ ! ¡ ? ¿ ؟ ¶ ※ / \\ & # % ‰ ′ ″ ‴ @ * ♪ ♭ ♯ ` ´ ^ ¨ ‐ ― _ - – — • · . … 。 ‧ ・ ‘ ’ ‚ ' “ ” „ » « ( ) [ ] { } 〔 〕 〈 〉 《 》 「 」 『 』 〖 〗 【 】"},
+ {"currency", "€ £ ¥ ₹ ₽ $ ¢ ฿ ₪ ₺ ₫ ₱ ₩ ₡ ₦ ₮ ৳ ₴ ₸ ₲ ₵ ៛ ₭ ֏ ₥ ₾ ₼ ₿ ؋"},
+ {"other-symbol", "‾‽‸⁂↚↛↮↙↜↝↞↟↠↡↢↣↤↥↦↧↨↫↬↭↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇇⇈⇉⇊⇋⇌⇐⇍⇑⇒⇏⇓⇔⇎⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇵∀∂∃∅∉∋∎∏∑≮≯∓∕⁄∗∘∙∝∟∠∣∥∧∫∬∮∴∵∶∷∼∽∾≃≅≌≒≖≣≦≧≪≫≬≳≺≻⊁⊃⊆⊇⊕⊖⊗⊘⊙⊚⊛⊞⊟⊥⊮⊰⊱⋭⊶⊹⊿⋁⋂⋃⋅⋆⋈⋒⋘⋙⋮⋯⋰⋱■□▢▣▤▥▦▧▨▩▬▭▮▰△▴▵▷▸▹►▻▽▾▿◁◂◃◄◅◆◇◈◉◌◍◎◐◑◒◓◔◕◖◗◘◙◜◝◞◟◠◡◢◣◤◥◦◳◷◻◽◿⨧⨯⨼⩣⩽⪍⪚⪺₢₣₤₰₳₶₷₨﷼"},
};
// get the maximum suborder for each subcategory
Map<String, Long> subcategoryToMaxSuborder = new HashMap<>();
@@ -216,13 +227,17 @@
}
}
if (DEBUG) System.out.println(subcategoryToMaxSuborder);
- Splitter spaceSplitter = Splitter.on(' ').omitEmptyStrings();
Map<String,Long> _EXTRA_SYMBOL_ORDER = new LinkedHashMap<>();
for (String[] row : data) {
final String subcategory = row[0];
- final String spaceDelimitedStringList = row[1];
+ final String characters = row[1];
- List<String> items = spaceSplitter.splitToList(spaceDelimitedStringList);
+ List<String> items = new ArrayList<>();
+ for (int cp : With.codePointArray(characters)) {
+ if (cp != ' ') {
+ items.add(With.fromCodePoint(cp));
+ }
+ }
final UnicodeSet uset = new UnicodeSet().addAll(items);
if (uset.containsSome(EXTRA_SYMBOL_MINOR_CATEGORIES.keySet())) {
throw new IllegalArgumentException("Duplicate values in " + EXTRA_SYMBOL_MINOR_CATEGORIES);
@@ -245,7 +260,7 @@
if (minorCat == null) {
minorCat = EXTRA_SYMBOL_MINOR_CATEGORIES.get(emoji);
if (minorCat == null) {
- throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
+ throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
+ ". Update emoji-test.txt to latest, and adjust PathHeader.. functionMap.put(\"minor\", ...");
}
}
@@ -261,7 +276,7 @@
if (result == null) {
result = EXTRA_SYMBOL_ORDER.get(emoji);
if (result == null) {
- throw new InternalCldrException("No Order found for " + emoji
+ throw new InternalCldrException("No Order found for " + emoji
+ ". Update emoji-test.txt to latest, and adjust PathHeader.. functionMap.put(\"minor\", ...");
}
}
@@ -271,7 +286,7 @@
public static long getEmojiMinorOrder(String minor) {
Long result = minorToOrder.get(minor);
if (result == null) {
- throw new InternalCldrException("No minor category (aka subgroup) found for " + minor
+ throw new InternalCldrException("No minor category (aka subgroup) found for " + minor
+ ". Update emoji-test.txt to latest, and adjust PathHeader.. functionMap.put(\"minor\", ...");
}
return result;
@@ -283,7 +298,7 @@
if (EXTRA_SYMBOL_MINOR_CATEGORIES.containsKey(emoji)) {
majorCat = "Symbols";
} else {
- throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
+ throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji
+ ". Update emoji-test.txt to latest, and adjust PathHeader.. functionMap.put(\"major\", ...");
}
}
@@ -304,6 +319,12 @@
return ImmutableSet.copyOf(result);
}
+ public static UnicodeSet getEmojiInMinorCategoriesWithExtras(String minorCategory) {
+ return new UnicodeSet(emojiToMinorCategory.getSet(minorCategory))
+ .addAll(EXTRA_SYMBOL_MINOR_CATEGORIES.getSet(minorCategory))
+ .freeze();
+ }
+
public static UnicodeSet getNonConstructed() {
return nonConstructed;
}
diff --git a/tools/java/org/unicode/cldr/util/EmojiConstants.java b/tools/java/org/unicode/cldr/util/EmojiConstants.java
index dc1630c..f8c784a 100644
--- a/tools/java/org/unicode/cldr/util/EmojiConstants.java
+++ b/tools/java/org/unicode/cldr/util/EmojiConstants.java
@@ -22,7 +22,7 @@
.add(EmojiConstants.fromCodePoints(JOINER,0x1F9B0))
.add(EmojiConstants.fromCodePoints(JOINER,0x1F9B1))
.add(EmojiConstants.fromCodePoints(JOINER,0x1F9B2))
- .add(EmojiConstants.fromCodePoints(JOINER,0x1F9B3))
+ .add(EmojiConstants.fromCodePoints(JOINER,0x1F9B3))
.freeze();
public static final String KISS = "💋";
@@ -37,21 +37,21 @@
public static final String JOINER_MALE_SIGN = JOINER_STRING + MALE_SIGN;
public static final String JOINER_FEMALE_SIGN = JOINER_STRING + FEMALE_SIGN;
public static final UnicodeSet HAIR_EXPLICIT = new UnicodeSet("[🧔 👱]").freeze();
-
+
public static final ListTypeLength COMPOSED_NAME_LIST = ListTypeLength.UNIT_SHORT;
//public static final UnicodeSet MODIFIERS_GENDER_SIGNS = new UnicodeSet(0x1F3FB, 0x1F3FF).add(MALE_SIGN).add(FEMALE_SIGN).freeze();
public static String getFlagCode(String s) {
return String.valueOf((char) (s.codePointAt(0) - FIRST_REGIONAL + 'A')) + (char) (s.codePointAt(2) - FIRST_REGIONAL + 'A');
}
-
+
public static String getEmojiFromRegionCodes(String chars) {
return new StringBuilder()
.appendCodePoint(chars.codePointAt(0) + FIRST_REGIONAL - 'A')
.appendCodePoint(chars.codePointAt(1) + FIRST_REGIONAL - 'A')
.toString();
}
-
+
public static final int TAG_BASE = 0xE0000;
public static final int TAG_TERM_CHAR = 0xE007F;
diff --git a/tools/java/org/unicode/cldr/util/EnumNames.java b/tools/java/org/unicode/cldr/util/EnumNames.java
index 60e83bd..a0ef1d7 100644
--- a/tools/java/org/unicode/cldr/util/EnumNames.java
+++ b/tools/java/org/unicode/cldr/util/EnumNames.java
@@ -6,8 +6,8 @@
import java.util.Map;
public class EnumNames<T extends Enum<?>> {
- private Map<String, T> namesToEnum = new HashMap<String, T>();
- private ArrayList<String> enumToPreferredName = new ArrayList<String>();
+ private Map<String, T> namesToEnum = new HashMap<>();
+ private ArrayList<String> enumToPreferredName = new ArrayList<>();
public void add(T enumItem, String... alternateNames) {
final String name = enumItem.name();
diff --git a/tools/java/org/unicode/cldr/util/EscapingUtilities.java b/tools/java/org/unicode/cldr/util/EscapingUtilities.java
index 161a116..a5763b2 100644
--- a/tools/java/org/unicode/cldr/util/EscapingUtilities.java
+++ b/tools/java/org/unicode/cldr/util/EscapingUtilities.java
@@ -6,7 +6,7 @@
import com.ibm.icu.text.UnicodeSet;
public class EscapingUtilities {
- public static UnicodeSet OK_TO_NOT_QUOTE = (UnicodeSet) new UnicodeSet("[!(-*,-\\:A-Z_a-z~]").freeze();
+ public static UnicodeSet OK_TO_NOT_QUOTE = new UnicodeSet("[!(-*,-\\:A-Z_a-z~]").freeze();
public static String urlEscape(String path) {
try {
diff --git a/tools/java/org/unicode/cldr/util/ExtractCollationRules.java b/tools/java/org/unicode/cldr/util/ExtractCollationRules.java
index b0c11b1..b616bc8 100644
--- a/tools/java/org/unicode/cldr/util/ExtractCollationRules.java
+++ b/tools/java/org/unicode/cldr/util/ExtractCollationRules.java
@@ -17,7 +17,7 @@
import com.ibm.icu.text.UnicodeSet;
public class ExtractCollationRules {
- Map<String, String> type_rules = new TreeMap<String, String>();
+ Map<String, String> type_rules = new TreeMap<>();
StringBuffer rules = new StringBuffer();
public ExtractCollationRules set(CLDRFile file) {
@@ -134,7 +134,7 @@
}
public String getRules(Object key) {
- return (String) type_rules.get(key);
+ return type_rules.get(key);
}
static StringBuffer quoteOperandBuffer = new StringBuffer(); // faster
diff --git a/tools/java/org/unicode/cldr/util/Factory.java b/tools/java/org/unicode/cldr/util/Factory.java
index 4355130..6cb38b6 100644
--- a/tools/java/org/unicode/cldr/util/Factory.java
+++ b/tools/java/org/unicode/cldr/util/Factory.java
@@ -31,6 +31,7 @@
* @deprecated
* @return the first directory
*/
+ @Deprecated
public String getSourceDirectory() {
return getSourceDirectories()[0].getAbsolutePath();
}
@@ -62,7 +63,7 @@
*/
public enum SourceTreeType {
common, seed, other
- };
+ }
/**
* Returns the source tree type of either an XML file or its parent directory.
@@ -88,7 +89,7 @@
public enum DirectoryType {
main, supplemental, bcp47, casing, collation, dtd, rbnf, segments, transforms, other
- };
+ }
public static final DirectoryType getDirectoryType(File fileOrDir) {
if (fileOrDir == null) return null;
@@ -152,7 +153,7 @@
* @return
*/
protected ResolvingSource makeResolvingSource(String localeID, DraftStatus madeWithMinimalDraftStatus) {
- List<XMLSource> sourceList = new ArrayList<XMLSource>();
+ List<XMLSource> sourceList = new ArrayList<>();
String curLocale = localeID;
while (curLocale != null) {
if (DEBUG_FACTORY) {
@@ -212,7 +213,7 @@
* Get a set of the available language locales (according to isLanguage).
*/
public Set<String> getAvailableLanguages() {
- Set<String> result = new TreeSet<String>();
+ Set<String> result = new TreeSet<>();
for (Iterator<String> it = handleGetAvailable().iterator(); it.hasNext();) {
String s = it.next();
if (XPathParts.isLanguage(s)) result.add(s);
@@ -227,7 +228,7 @@
* if false, then parent itself will match
*/
public Set<String> getAvailableWithParent(String parent, boolean isProper) {
- Set<String> result = new TreeSet<String>();
+ Set<String> result = new TreeSet<>();
for (Iterator<String> it = handleGetAvailable().iterator(); it.hasNext();) {
String s = it.next();
@@ -273,6 +274,7 @@
/**
* These factory implementations don't do any caching.
*/
+ @Override
public Set<CLDRLocale> subLocalesOf(CLDRLocale forLocale) {
return calculateSubLocalesOf(forLocale, getAvailableCLDRLocales());
}
@@ -294,7 +296,7 @@
* @return
*/
public Set<CLDRLocale> calculateSubLocalesOf(CLDRLocale locale, Set<CLDRLocale> available) {
- Set<CLDRLocale> sub = new TreeSet<CLDRLocale>();
+ Set<CLDRLocale> sub = new TreeSet<>();
for (CLDRLocale l : available) {
if (l.getParent() == locale) {
sub.add(l);
diff --git a/tools/java/org/unicode/cldr/util/FileProcessor.java b/tools/java/org/unicode/cldr/util/FileProcessor.java
index 24e1288..43fb6d7 100644
--- a/tools/java/org/unicode/cldr/util/FileProcessor.java
+++ b/tools/java/org/unicode/cldr/util/FileProcessor.java
@@ -38,10 +38,11 @@
public FileProcessor process(Class<?> classLocation, String fileName) {
try {
+ System.err.println("# Reading config file " + fileName);
BufferedReader in = FileReaders.openFile(classLocation, fileName);
return process(in, fileName);
} catch (Exception e) {
- throw (RuntimeException) new IllegalArgumentException(lineCount + ":\t" + 0).initCause(e);
+ throw (RuntimeException) new IllegalArgumentException(lineCount + ":\t" + 0 + " - while reading" + fileName).initCause(e);
}
}
diff --git a/tools/java/org/unicode/cldr/util/FileReaders.java b/tools/java/org/unicode/cldr/util/FileReaders.java
index 029cbc5..198eae2 100644
--- a/tools/java/org/unicode/cldr/util/FileReaders.java
+++ b/tools/java/org/unicode/cldr/util/FileReaders.java
@@ -45,15 +45,15 @@
return bufferedReader;
} catch (Exception e) {
String className = class1 == null ? null : class1.getCanonicalName();
- String canonicalName = null;
+ String normalizedPath = null;
try {
String relativeFileName = FileReaders.getRelativeFileName(class1, "../util/");
- canonicalName = new File(relativeFileName).getCanonicalPath();
+ normalizedPath = PathUtilities.getNormalizedPathString(relativeFileName);
} catch (Exception e1) {
throw new IllegalArgumentException("Couldn't open file: " + file + "; relative to class: "
+ className, e);
}
- throw new IllegalArgumentException("Couldn't open file " + file + "; in path " + canonicalName + "; relative to class: "
+ throw new IllegalArgumentException("Couldn't open file " + file + "; in path " + normalizedPath + "; relative to class: "
+ className, e);
}
}
@@ -81,16 +81,16 @@
throw new IllegalArgumentException("File not found: " + resourceString);
}
}
-
-
+
+
public static class ReadLineSimpleIterator implements SimpleIterator<String> {
final BufferedReader bufferedReader;
-
+
public ReadLineSimpleIterator(BufferedReader bufferedReader) {
super();
this.bufferedReader = bufferedReader;
}
-
+
@Override
public String next() {
try {
@@ -100,4 +100,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tools/java/org/unicode/cldr/util/FindDTDOrder.java b/tools/java/org/unicode/cldr/util/FindDTDOrder.java
index cfbffd5..5497aa8 100644
--- a/tools/java/org/unicode/cldr/util/FindDTDOrder.java
+++ b/tools/java/org/unicode/cldr/util/FindDTDOrder.java
@@ -36,6 +36,7 @@
/**
* @deprecated
*/
+@Deprecated
public class FindDTDOrder implements DeclHandler, ContentHandler, ErrorHandler {
static final boolean SHOW_PROGRESS = CldrUtility.getProperty("verbose", false);
static final boolean SHOW_ALL = CldrUtility.getProperty("show_all", false);
@@ -70,7 +71,7 @@
if (DEBUG) {
System.out.println("Opening " + file.getCanonicalFile());
}
- File dtd = new File(file.getCanonicalPath() + "/../" + "../../common/dtd/ldml.dtd");
+ File dtd = new File(PathUtilities.getNormalizedPathString(file) + "/../" + "../../common/dtd/ldml.dtd");
if (DEBUG) {
System.out.println("Opening " + dtd.getCanonicalFile());
}
@@ -85,7 +86,7 @@
throw new IllegalArgumentException("just testing");
}
is = new InputSource(fis);
- is.setSystemId(file.getCanonicalPath() + "/../");
+ is.setSystemId(PathUtilities.getNormalizedPathString(file) + "/../");
xmlReader.parse(is);
fis.close();
@@ -99,14 +100,14 @@
fis = new FileInputStream(filename);
is = new InputSource(fis);
- is.setSystemId(file.getCanonicalPath() + "/../");
+ is.setSystemId(PathUtilities.getNormalizedPathString(file) + "/../");
xmlReader.parse(is);
fis.close();
// Then Attributes
- List<String> rawDtdAttributeOrder = Collections.unmodifiableList(new ArrayList<String>(me.attributeSet));
+ List<String> rawDtdAttributeOrder = Collections.unmodifiableList(new ArrayList<>(me.attributeSet));
List<String> cldrFileAttributeOrder = CLDRFile.getAttributeOrder();
- LinkedHashSet<String> modifiedDtdOrder = new LinkedHashSet<String>(cldrFileAttributeOrder);
+ LinkedHashSet<String> modifiedDtdOrder = new LinkedHashSet<>(cldrFileAttributeOrder);
// add items, keeping the ordering stable
modifiedDtdOrder.retainAll(rawDtdAttributeOrder); // remove any superfluous stuff
modifiedDtdOrder.addAll(rawDtdAttributeOrder);
@@ -116,7 +117,7 @@
modifiedDtdOrder.addAll(me.getCommonAttributes());
// now make a list for comparison
- List<String> dtdAttributeOrder = new ArrayList<String>(modifiedDtdOrder);
+ List<String> dtdAttributeOrder = new ArrayList<>(modifiedDtdOrder);
// fix to and from
dtdAttributeOrder.remove("from");
@@ -140,7 +141,7 @@
System.out.println(CldrUtility.LINE_SEPARATOR + "======== Start Attributes to Elements (unblocked) "
+ CldrUtility.LINE_SEPARATOR);
for (String attribute : attributeToElements.keySet()) {
- Set<String> filtered = new TreeSet<String>();
+ Set<String> filtered = new TreeSet<>();
for (String element : attributeToElements.getAll(attribute)) {
if (!isBlocked(element)) {
filtered.add(element);
@@ -203,7 +204,7 @@
// we make a new list, since otherwise the iteration fails in recursion (because of the modification)
// if this were performance-sensitive we'd do it differently
- ArrayList<String> newParents = new ArrayList<String>(parents);
+ ArrayList<String> newParents = new ArrayList<>(parents);
newParents.add(current);
for (String child : children) {
@@ -218,7 +219,7 @@
Set elementOrderings = new LinkedHashSet(); // set of orderings
- Set<String> allDefinedElements = new LinkedHashSet<String>();
+ Set<String> allDefinedElements = new LinkedHashSet<>();
boolean showReason = false;
@@ -231,14 +232,14 @@
log = new PrintWriter(System.out);
}
- private List<String> orderingList = new ArrayList<String>();
+ private List<String> orderingList = new ArrayList<>();
public void checkData() {
// verify that the ordering is the consistent for all child elements
// do this by building an ordering from the lists.
// The first item has no greater item in any set. So find an item that is
// only first
- MergeLists<String> mergeLists = new MergeLists<String>(new TreeSet<String>(new UTF16.StringComparator(true,
+ MergeLists<String> mergeLists = new MergeLists<>(new TreeSet<>(new UTF16.StringComparator(true,
false, 0)))
.add(Arrays.asList("ldml"))
.addAll(elementOrderings); //
@@ -296,7 +297,7 @@
// System.out.println("New code2: " + CldrUtility.breakLines(CldrUtility.join(result, " "), sep,
// FIRST_LETTER_CHANGE.matcher(""), 80));
- Set<String> missing = new TreeSet<String>(allDefinedElements);
+ Set<String> missing = new TreeSet<>(allDefinedElements);
missing.removeAll(orderingList);
orderingList.addAll(missing);
@@ -534,15 +535,16 @@
// return true;
// }
- static final Set<String> ELEMENT_SKIP_LIST = new HashSet<String>(Arrays.asList(new String[] {
+ static final Set<String> ELEMENT_SKIP_LIST = new HashSet<>(Arrays.asList(new String[] {
"collation", "base", "settings", "suppress_contractions", "optimize",
"rules", "reset", "context", "p", "pc", "s", "sc", "t", "tc",
"i", "ic", "extend", "x" }));
- static final Set<String> SUBELEMENT_SKIP_LIST = new HashSet<String>(Arrays
+ static final Set<String> SUBELEMENT_SKIP_LIST = new HashSet<>(Arrays
.asList(new String[] { "PCDATA", "EMPTY", "ANY" }));
// refine later; right now, doesn't handle multiple elements well.
+ @Override
public void elementDecl(String name, String model) throws SAXException {
// if (ELEMENT_SKIP_LIST.contains(name)) return;
if (name.indexOf("contractions") >= 0
@@ -554,7 +556,7 @@
log.println("Element\t" + name + "\t" + model);
}
String[] list = model.split("[^-_A-Z0-9a-z]+");
- List<String> mc = new ArrayList<String>();
+ List<String> mc = new ArrayList<>();
/*
* if (name.equals("currency")) { mc.add("alias"); mc.add("symbol");
* mc.add("pattern"); }
@@ -584,7 +586,7 @@
}
}
if (recordingAttributeElements) {
- Set<String> children = new TreeSet<String>(mc);
+ Set<String> children = new TreeSet<>(mc);
children.remove("alias");
children.remove("special");
children.remove("cp");
@@ -606,24 +608,25 @@
// if (SHOW_PROGRESS) log.println();
}
- Set<String> skipCommon = new LinkedHashSet<String>(Arrays.asList(new String[] { "validSubLocales",
+ Set<String> skipCommon = new LinkedHashSet<>(Arrays.asList(new String[] { "validSubLocales",
"standard", "references",
"alt", "draft",
}));
- Set<String> attributeSet = new TreeSet<String>();
+ Set<String> attributeSet = new TreeSet<>();
{
attributeSet.add("_q");
attributeSet.addAll(skipCommon);
}
List<String> attributeList;
- Map<String, Set<String>> attribEquiv = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> attribEquiv = new TreeMap<>();
Relation<String, String> attributeToElements = Relation.of(new TreeMap<String, Set<String>>(),
TreeSet.class);
private XEquivalenceClass attributeEquivalents;
+ @Override
public void attributeDecl(String eName, String aName, String type,
String mode, String value) throws SAXException {
if (SHOW_ALL)
@@ -636,7 +639,7 @@
attributeSet.add(aName);
Set<String> l = attribEquiv.get(eName);
if (l == null)
- attribEquiv.put(eName, l = new TreeSet<String>());
+ attribEquiv.put(eName, l = new TreeSet<>());
l.add(aName);
}
if (recordingAttributeElements) {
@@ -644,6 +647,7 @@
}
}
+ @Override
public void internalEntityDecl(String name, String value) throws SAXException {
if (SHOW_ALL)
log.println("internalEntityDecl");
@@ -651,6 +655,7 @@
// "\t" + value);
}
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId)
throws SAXException {
if (SHOW_ALL)
@@ -664,6 +669,7 @@
*
* @see org.xml.sax.ContentHandler#endDocument()
*/
+ @Override
public void endDocument() throws SAXException {
if (SHOW_ALL)
log.println("endDocument");
@@ -674,6 +680,7 @@
*
* @see org.xml.sax.ContentHandler#startDocument()
*/
+ @Override
public void startDocument() throws SAXException {
if (SHOW_ALL)
log.println("startDocument");
@@ -684,6 +691,7 @@
*
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (SHOW_ALL)
log.println("characters");
@@ -694,6 +702,7 @@
*
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
+ @Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
if (SHOW_ALL)
@@ -705,6 +714,7 @@
*
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
+ @Override
public void endPrefixMapping(String prefix) throws SAXException {
if (SHOW_ALL)
log.println("endPrefixMapping");
@@ -715,6 +725,7 @@
*
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
+ @Override
public void skippedEntity(String name) throws SAXException {
if (SHOW_ALL)
log.println("skippedEntity");
@@ -725,6 +736,7 @@
*
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
+ @Override
public void setDocumentLocator(Locator locator) {
if (SHOW_ALL)
log.println("setDocumentLocator");
@@ -736,6 +748,7 @@
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
* java.lang.String)
*/
+ @Override
public void processingInstruction(String target, String data)
throws SAXException {
if (SHOW_ALL)
@@ -748,6 +761,7 @@
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
* java.lang.String)
*/
+ @Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
if (SHOW_ALL)
log.println("startPrefixMapping");
@@ -759,6 +773,7 @@
* @see org.xml.sax.ContentHandler#endElement(java.lang.String,
* java.lang.String, java.lang.String)
*/
+ @Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (SHOW_ALL)
@@ -771,6 +786,7 @@
* @see org.xml.sax.ContentHandler#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
+ @Override
public void startElement(String namespaceURI, String localName, String qName,
Attributes atts) throws SAXException {
if (SHOW_ALL)
@@ -782,6 +798,7 @@
*
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
+ @Override
public void error(SAXParseException exception) throws SAXException {
if (SHOW_ALL)
log.println("error");
@@ -793,6 +810,7 @@
*
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
if (SHOW_ALL)
log.println("fatalError");
@@ -804,6 +822,7 @@
*
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
+ @Override
public void warning(SAXParseException exception) throws SAXException {
if (SHOW_ALL)
log.println("warning");
diff --git a/tools/java/org/unicode/cldr/util/GrammarDerivation.java b/tools/java/org/unicode/cldr/util/GrammarDerivation.java
new file mode 100644
index 0000000..66fa301
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/GrammarDerivation.java
@@ -0,0 +1,85 @@
+package org.unicode.cldr.util;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.ibm.icu.util.Freezable;
+
+public class GrammarDerivation implements Freezable<GrammarDerivation>{
+
+ public enum CompoundUnitStructure {per, times, power, prefix}
+
+ public class Values {
+ public final String value0;
+ public final String value1;
+
+ public Values(String... values) {
+ super();
+ this.value0 = values[0];
+ this.value1 = values.length == 2 ? values[0] : null;
+ }
+ @Override
+ public String toString() {
+ final ToStringHelper temp = MoreObjects.toStringHelper(getClass()).add("value0", value0);
+ if (value1 != null) {
+ temp.add("value1", value1);
+ }
+ return temp.toString();
+ }
+
+ }
+
+ private Map<GrammaticalFeature, Map<CompoundUnitStructure, Values>> data = new TreeMap<>();
+
+ public void add(String featureStr, String structureStr, String... values) {
+ GrammaticalFeature feature = GrammaticalFeature.fromName(featureStr);
+ CompoundUnitStructure structure = CompoundUnitStructure.valueOf(structureStr);
+ Map<CompoundUnitStructure, Values> structureToValues = data.get(feature);
+ if (structureToValues == null) {
+ data.put(feature, structureToValues = new TreeMap<>());
+ }
+ structureToValues.put(structure, new Values(values));
+ }
+
+ public Values get(GrammaticalFeature feature, CompoundUnitStructure structure) {
+ Map<CompoundUnitStructure, Values> structureToValues = data.get(feature);
+ if (structureToValues == null) {
+ return null;
+ }
+ return structureToValues.get(structure);
+ }
+
+
+ @Override
+ public boolean isFrozen() {
+ return data instanceof TreeMap;
+ }
+
+ @Override
+ public GrammarDerivation freeze() {
+ if (!isFrozen()) {
+ data = CldrUtility.protectCollection(data);
+ }
+ return this;
+ }
+
+ @Override
+ public GrammarDerivation cloneAsThawed() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).add("data", data).toString();
+ }
+}
diff --git a/tools/java/org/unicode/cldr/util/GrammarInfo.java b/tools/java/org/unicode/cldr/util/GrammarInfo.java
new file mode 100644
index 0000000..0c2172d
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/GrammarInfo.java
@@ -0,0 +1,437 @@
+package org.unicode.cldr.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.ibm.icu.util.Freezable;
+import com.ibm.icu.util.Output;
+
+/**
+ * Get the info from supplemental data, eg CLDRConfig.getInstance().getSupplementalDataInfo().getGrammarInfo("fr"); Use hasGrammarInfo() to see which locales have it.
+ * @author markdavis
+ *
+ */
+public class GrammarInfo implements Freezable<GrammarInfo>{
+
+ public enum GrammaticalTarget {nominal}
+
+ public enum GrammaticalFeature {
+ grammaticalNumber("plural", "Ⓟ", "other"),
+ grammaticalCase("case", "Ⓒ", "nominative"),
+ grammaticalDefiniteness("definiteness", "Ⓓ", "indefinite"),
+ grammaticalGender("gender", "Ⓖ", "neuter");
+
+ private final String shortName;
+ private final String symbol;
+ private final String defaultValue;
+
+ public static final Pattern PATH_HAS_FEATURE = Pattern.compile("\\[@(count|case|gender|definiteness)=");
+
+ GrammaticalFeature(String shortName, String symbol, String defaultValue) {
+ this.shortName = shortName;
+ this.symbol = symbol;
+ this.defaultValue = defaultValue;
+ }
+ public String getShortName() {
+ return shortName;
+ }
+ public CharSequence getSymbol() {
+ return symbol;
+ }
+ public String getDefault(Collection<String> values) {
+ return this == grammaticalGender && values != null && !values.contains("neuter") ? "masculine" : defaultValue;
+ }
+ public static Matcher pathHasFeature(String path) {
+ Matcher result = PATH_HAS_FEATURE.matcher(path);
+ return result.find() ? result : null;
+ }
+ static final Map<String, GrammaticalFeature> shortNameToEnum =
+ ImmutableMap.copyOf(Arrays.asList(GrammaticalFeature.values())
+ .stream()
+ .collect(Collectors.toMap(e -> e.shortName, e -> e)));
+
+ public static GrammaticalFeature fromName(String name) {
+ GrammaticalFeature result = shortNameToEnum.get(name);
+ return result != null ? result : valueOf(name);
+ }
+ }
+
+ public enum GrammaticalScope {general, units}
+
+ private Map<GrammaticalTarget, Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>>> targetToFeatureToUsageToValues = new TreeMap<>();
+ private boolean frozen = false;
+
+ public void add(GrammaticalTarget target, GrammaticalFeature feature, GrammaticalScope usage, String value) {
+ Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> featureToUsageToValues = targetToFeatureToUsageToValues.get(target);
+ if (featureToUsageToValues == null) {
+ targetToFeatureToUsageToValues.put(target, featureToUsageToValues = new TreeMap<>());
+ }
+ if (feature != null) {
+ Map<GrammaticalScope,Set<String>> usageToValues = featureToUsageToValues.get(feature);
+ if (usageToValues == null) {
+ featureToUsageToValues.put(feature, usageToValues = new TreeMap<>());
+ }
+ Set<String> values = usageToValues.get(usage);
+ if (values == null) {
+ usageToValues.put(usage, values = new TreeSet<>());
+ }
+ if (value != null) {
+ values.add(value);
+ } else {
+ int debug = 0;
+ }
+ }
+ }
+
+ public void add(GrammaticalTarget target, GrammaticalFeature feature, GrammaticalScope usage, Collection<String> valueSet) {
+ Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> featureToUsageToValues = targetToFeatureToUsageToValues.get(target);
+ if (featureToUsageToValues == null) {
+ targetToFeatureToUsageToValues.put(target, featureToUsageToValues = new TreeMap<>());
+ }
+ if (feature != null) {
+ Map<GrammaticalScope,Set<String>> usageToValues = featureToUsageToValues.get(feature);
+ if (usageToValues == null) {
+ featureToUsageToValues.put(feature, usageToValues = new TreeMap<>());
+ }
+ Set<String> values = usageToValues.get(usage);
+ if (values == null) {
+ usageToValues.put(usage, values = new TreeSet<>());
+ }
+ values.addAll(valueSet);
+ }
+ }
+
+
+ /**
+ * Note: when there is known to be no features, the featureRaw will be null
+ */
+ public void add(String targetsRaw, String featureRaw, String usagesRaw, String valuesRaw) {
+ for (String targetString : SupplementalDataInfo.split_space.split(targetsRaw)) {
+ GrammaticalTarget target = GrammaticalTarget.valueOf(targetString);
+ if (featureRaw == null) {
+ add(target, null, null, (String)null);
+ } else {
+ final GrammaticalFeature feature = GrammaticalFeature.valueOf(featureRaw);
+
+ List<String> usages = usagesRaw == null ? Collections.singletonList(GrammaticalScope.general.toString()) : SupplementalDataInfo.split_space.splitToList(usagesRaw);
+
+ List<String> values = valuesRaw == null ? Collections.emptyList() : SupplementalDataInfo.split_space.splitToList(valuesRaw);
+ for (String usageRaw : usages) {
+ GrammaticalScope usage = GrammaticalScope.valueOf(usageRaw);
+ add(target, feature, usage, values);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isFrozen() {
+ return frozen;
+ }
+
+ @Override
+ public GrammarInfo freeze() {
+ if (!frozen) {
+ Map<GrammaticalTarget, Map<GrammaticalFeature, Map<GrammaticalScope, Set<String>>>> temp = CldrUtility.protectCollection(targetToFeatureToUsageToValues);
+ if (!temp.equals(targetToFeatureToUsageToValues)) {
+ throw new IllegalArgumentException();
+ }
+ targetToFeatureToUsageToValues = temp;
+ frozen = true;
+ }
+ return this;
+ }
+
+ @Override
+ public GrammarInfo cloneAsThawed() {
+ GrammarInfo result = new GrammarInfo();
+ this.forEach3((t,f,u,v) -> result.add(t,f,u,v));
+ return result;
+ }
+
+ static interface Handler4<T,F,U,V> {
+ void apply(T t, F f, U u, V v);
+ }
+
+ public void forEach(Handler4<GrammaticalTarget, GrammaticalFeature, GrammaticalScope, String> handler) {
+ for (Entry<GrammaticalTarget, Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>>> entry1 : targetToFeatureToUsageToValues.entrySet()) {
+ GrammaticalTarget target = entry1.getKey();
+ final Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> featureToUsageToValues = entry1.getValue();
+ if (featureToUsageToValues.isEmpty()) {
+ handler.apply(target, null, null, null);
+ } else
+ for (Entry<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> entry2 : featureToUsageToValues.entrySet()) {
+ GrammaticalFeature feature = entry2.getKey();
+ for (Entry<GrammaticalScope, Set<String>> entry3 : entry2.getValue().entrySet()) {
+ final GrammaticalScope usage = entry3.getKey();
+ for (String value : entry3.getValue()) {
+ handler.apply(target, feature, usage, value);
+ }
+ }
+ }
+ }
+ }
+
+ static interface Handler3<T,F,U, V> {
+ void apply(T t, F f, U u, V v);
+ }
+
+ public void forEach3(Handler3<GrammaticalTarget, GrammaticalFeature, GrammaticalScope, Collection<String>> handler) {
+ for (Entry<GrammaticalTarget, Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>>> entry1 : targetToFeatureToUsageToValues.entrySet()) {
+ GrammaticalTarget target = entry1.getKey();
+ final Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> featureToUsageToValues = entry1.getValue();
+ if (featureToUsageToValues.isEmpty()) {
+ handler.apply(target, null, null, null);
+ } else
+ for (Entry<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> entry2 : featureToUsageToValues.entrySet()) {
+ GrammaticalFeature feature = entry2.getKey();
+ for (Entry<GrammaticalScope, Set<String>> entry3 : entry2.getValue().entrySet()) {
+ final GrammaticalScope usage = entry3.getKey();
+ final Collection<String> values = entry3.getValue();
+ handler.apply(target, feature, usage, values);
+ }
+ }
+ }
+ }
+
+ /** Returns null if there is no known information. Otherwise returns the information for the locale (which may be empty if there are no variants) */
+ public Collection<String> get(GrammaticalTarget target, GrammaticalFeature feature, GrammaticalScope usage) {
+ Map<GrammaticalFeature, Map<GrammaticalScope,Set<String>>> featureToUsageToValues = targetToFeatureToUsageToValues.get(target);
+ if (featureToUsageToValues == null) {
+ return Collections.emptySet();
+ }
+ Map<GrammaticalScope,Set<String>> usageToValues = featureToUsageToValues.get(feature);
+ if (usageToValues == null) {
+ return Collections.emptySet();
+ }
+ Collection<String> result = usageToValues.get(usage);
+ return result == null
+ ? usageToValues.get(GrammaticalScope.general)
+ : result;
+ }
+
+ public boolean hasInfo(GrammaticalTarget target) {
+ return targetToFeatureToUsageToValues.containsKey(target);
+ }
+
+ @Override
+ public String toString() {
+ return toString("\n");
+ }
+ public String toString(String lineSep) {
+ StringBuilder result = new StringBuilder();
+ this.forEach3((t,f,u, v) ->
+ {
+ result.append(lineSep);
+ result.append("{" + (t == null ? "" : t.toString()) + "}"
+ + "\t{" + (f == null ? "" : f.toString()) + "}"
+ + "\t{" + (u == null ? "" : u.toString()) + "}"
+ + "\t{" + (v == null ? "" : Joiner.on(' ').join(v)) + "}");
+ });
+ return result.toString();
+ }
+
+ static public String getGrammaticalInfoAttributes(GrammarInfo grammarInfo, UnitPathType pathType, String plural, String gender, String caseVariant) {
+ String grammaticalAttributes = "";
+ if (pathType.features.contains(GrammaticalFeature.grammaticalNumber)) { // count is special
+ grammaticalAttributes += "[@count=\"" + (plural == null ? "other" : plural) + "\"]";
+ }
+ if (grammarInfo != null && gender != null
+ && pathType.features.contains(GrammaticalFeature.grammaticalGender)
+ ) {
+ Collection<String> genders = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+ if (!gender.equals(GrammaticalFeature.grammaticalGender.getDefault(genders))) {
+ grammaticalAttributes += "[@gender=\"" + gender + "\"]";
+ }
+ }
+ if (grammarInfo != null && caseVariant != null
+ && pathType.features.contains(GrammaticalFeature.grammaticalCase)
+ && !caseVariant.equals(GrammaticalFeature.grammaticalCase.getDefault(null))) {
+ grammaticalAttributes += "[@case=\"" + caseVariant + "\"]";
+ }
+ return grammaticalAttributes;
+ }
+
+ public static final ImmutableMultimap<String,PluralInfo.Count> NON_COMPUTABLE_PLURALS = ImmutableListMultimap.of(
+ "pl", PluralInfo.Count.one,
+ "pl", PluralInfo.Count.other,
+ "ru", PluralInfo.Count.one,
+ "ru", PluralInfo.Count.other);
+ /**
+ * TODO: change this to be data-file driven
+ */
+ public static final Set<String> SEED_LOCALES = ImmutableSet.of("pl", "ru", "da", "de", "nb", "sv", "hi", "id", "es", "fr", "it", "nl", "pt", "en", "ja", "th", "vi", "zh", "zh_TW", "ko", "yue");
+
+ /**
+ * TODO: change this to be data-file driven
+ */
+ public static final Set<String> SPECIAL_TRANSLATION_UNITS = ImmutableSet.of(
+ // new in v38
+ "mass-grain",
+ "volume-dessert-spoon",
+ "volume-dessert-spoon-imperial",
+ "volume-drop",
+ "volume-dram",
+ "volume-jigger",
+ "volume-pinch",
+ "volume-quart-imperial",
+ // "volume-pint-imperial",
+
+ "acceleration-meter-per-square-second", "area-acre", "area-hectare",
+ "area-square-centimeter", "area-square-foot", "area-square-kilometer", "area-square-mile", "concentr-percent", "consumption-mile-per-gallon",
+ "consumption-mile-per-gallon-imperial", "duration-day", "duration-hour", "duration-minute", "duration-month", "duration-second", "duration-week",
+ "duration-year", "energy-foodcalorie", "energy-kilocalorie", "length-centimeter", "length-foot", "length-inch", "length-kilometer", "length-meter",
+ "length-mile", "length-millimeter", "length-parsec", "length-picometer", "length-solar-radius", "length-yard", "light-solar-luminosity", "mass-dalton",
+ "mass-earth-mass", "mass-milligram", "mass-solar-mass", "pressure-kilopascal", "speed-kilometer-per-hour", "speed-meter-per-second", "speed-mile-per-hour",
+ "temperature-celsius", "temperature-fahrenheit", "temperature-generic", "temperature-kelvin", "acceleration-g-force", "consumption-liter-per-100-kilometer",
+ "mass-gram", "mass-kilogram", "mass-ounce", "mass-pound", "volume-centiliter", "volume-cubic-centimeter", "volume-cubic-foot", "volume-cubic-mile",
+ "volume-cup", "volume-deciliter", "volume-fluid-ounce", "volume-fluid-ounce-imperial", "volume-gallon", "volume-gallon", "volume-gallon-imperial",
+ "volume-liter", "volume-milliliter", "volume-pint", "volume-quart", "volume-tablespoon", "volume-teaspoon");
+ // compounds
+ // "kilogram-per-cubic-meter", "kilometer-per-liter", "concentr-gram-per-mole", "speed-mile-per-second", "volumetricflow-cubic-foot-per-second",
+ // "volumetricflow-cubic-meter-per-second", "gram-per-cubic-centimeter",
+
+
+ public void getSourceCaseAndPlural(String locale, String gender, String value, String desiredCase, String desiredPlural,
+ Output<String> sourceCase, Output<String> sourcePlural) {
+ switch(locale) {
+ case "pl":
+ getSourceCaseAndPluralPolish(gender, value, desiredCase, desiredPlural, sourceCase, sourcePlural);
+ break;
+ case "ru":
+ getSourceCaseAndPluralRussian(gender, value, desiredCase, desiredPlural, sourceCase, sourcePlural);
+ break;
+ default:
+ throw new UnsupportedOperationException(locale);
+ }
+ }
+
+ /** Russian rules for paucal (few) and fractional (other)
+ * <pre>
+ * plural = other
+ * Nominative ⇒ genitive singular
+ * Accusative + masculine ⇒ genitive singular
+ * All other combinations of gender + case ⇒ same-case, plural
+ *
+ * Other
+ * genitive singular
+ *
+ * Plurals:
+ * one,
+ * few (2~4),
+ * many, = plural
+ * other (where other is 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0)
+ * </pre>
+ */
+ private void getSourceCaseAndPluralRussian(String gender, String value,
+ String desiredCase, String desiredPlural,
+ Output<String> sourceCase, Output<String> sourcePlural) {
+ switch (desiredPlural) {
+ case "few":
+ // default source
+ sourceCase.value = desiredCase;
+ sourcePlural.value = "many";
+ // special cases
+ switch (desiredCase) {
+ case "nominative":
+ sourceCase.value = "genitive";
+ sourcePlural.value = "one";
+ break;
+ case "accusative":
+ switch (gender) {
+ case "masculine":
+ sourceCase.value = "genitive";
+ sourcePlural.value = "one";
+ break;
+ }
+ break;
+ }
+ case "other":
+ sourceCase.value = "genitive";
+ sourcePlural.value = "one";
+ return;
+ }
+ }
+
+ /** Polish rules
+ * <pre>
+ * plural = few
+ *
+ * neuter + ending in -um + (nominative, accusative) ⇒ vocative plural
+ * Feminine||neuter + (nominative, accusative) ⇒ genitive singular
+ * Animate||inanimate + (nominative, accusative) ⇒ vocative plural
+ * Personal + nominative ⇒ vocative plural
+ * Personal + accusative ⇒ genitive plural
+ * All other combinations of gender + case ⇒ same-case, plural
+ *
+ * plural = other
+ * genitive singular
+ *
+ * Plurals:
+ * one,
+ * few (2~4),
+ * many, = plural
+ * other (where other is 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0)
+ * </pre>
+ */
+ private void getSourceCaseAndPluralPolish(String gender, String value,
+ String desiredCase, String desiredPlural,
+ Output<String> sourceCase, Output<String> sourcePlural) {
+ switch (desiredPlural) {
+ case "few":
+ // default
+ sourceCase.value = desiredCase;
+ sourcePlural.value = "many";
+ // special cases
+ boolean isNominative = false;
+ switch (desiredCase) {
+ case "nominative":
+ isNominative = true;
+ case "vocative":
+ case "accusative":
+ switch (gender) {
+ case "neuter":
+ if (value.endsWith("um")) {
+ sourceCase.value = "vocative";
+ break;
+ }
+ // otherwise fall thorugh to feminine
+ case "feminine":
+ sourceCase.value = "nominative";
+ sourcePlural.value = "few";
+ break;
+ case "animate":
+ case "inanimate":
+ sourceCase.value = "vocative";
+ break;
+ case "personal":
+ sourceCase.value = isNominative ? "vocative" : "genitive";
+ break;
+ }
+ break;
+ }
+ return;
+ case "other":
+ sourceCase.value = "genitive";
+ sourcePlural.value = "one";
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/ICUServiceBuilder.java b/tools/java/org/unicode/cldr/util/ICUServiceBuilder.java
index df610be..2873444 100644
--- a/tools/java/org/unicode/cldr/util/ICUServiceBuilder.java
+++ b/tools/java/org/unicode/cldr/util/ICUServiceBuilder.java
@@ -33,7 +33,7 @@
public static Currency NO_CURRENCY = Currency.getInstance("XXX");
private CLDRFile cldrFile;
private CLDRFile collationFile;
- private static Map<CLDRLocale, ICUServiceBuilder> ISBMap = new HashMap<CLDRLocale, ICUServiceBuilder>();
+ private static Map<CLDRLocale, ICUServiceBuilder> ISBMap = new HashMap<>();
private static TimeZone utc = TimeZone.getTimeZone("GMT");
private static DateFormat iso = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", ULocale.ENGLISH);
@@ -54,11 +54,11 @@
return iso.parse(date);
}
- private Map<String, SimpleDateFormat> cacheDateFormats = new HashMap<String, SimpleDateFormat>();
- private Map<String, DateFormatSymbols> cacheDateFormatSymbols = new HashMap<String, DateFormatSymbols>();
- private Map<String, NumberFormat> cacheNumberFormats = new HashMap<String, NumberFormat>();
- private Map<String, DecimalFormatSymbols> cacheDecimalFormatSymbols = new HashMap<String, DecimalFormatSymbols>();
- private Map<String, RuleBasedCollator> cacheRuleBasedCollators = new HashMap<String, RuleBasedCollator>();
+ private Map<String, SimpleDateFormat> cacheDateFormats = new HashMap<>();
+ private Map<String, DateFormatSymbols> cacheDateFormatSymbols = new HashMap<>();
+ private Map<String, NumberFormat> cacheNumberFormats = new HashMap<>();
+ private Map<String, DecimalFormatSymbols> cacheDecimalFormatSymbols = new HashMap<>();
+ private Map<String, RuleBasedCollator> cacheRuleBasedCollators = new HashMap<>();
private SupplementalDataInfo supplementalData;
@@ -130,7 +130,7 @@
}
public RuleBasedCollator getRuleBasedCollator(String type) throws Exception {
- RuleBasedCollator col = (RuleBasedCollator) cacheRuleBasedCollators.get(type);
+ RuleBasedCollator col = cacheRuleBasedCollators.get(type);
if (col == null) {
col = _getRuleBasedCollator(type);
cacheRuleBasedCollators.put(type, col);
@@ -182,7 +182,7 @@
public SimpleDateFormat getDateFormat(String calendar, int dateIndex, int timeIndex, String numbersOverride) {
String key = cldrFile.getLocaleID() + "," + calendar + "," + dateIndex + "," + timeIndex;
- SimpleDateFormat result = (SimpleDateFormat) cacheDateFormats.get(key);
+ SimpleDateFormat result = cacheDateFormats.get(key);
if (result != null) return (SimpleDateFormat) result.clone();
String pattern = getPattern(calendar, dateIndex, timeIndex);
@@ -195,7 +195,7 @@
public SimpleDateFormat getDateFormat(String calendar, String pattern, String numbersOverride) {
String key = cldrFile.getLocaleID() + "," + calendar + ",," + pattern + ",,," + numbersOverride;
- SimpleDateFormat result = (SimpleDateFormat) cacheDateFormats.get(key);
+ SimpleDateFormat result = cacheDateFormats.get(key);
if (result != null) return (SimpleDateFormat) result.clone();
result = getFullFormat(calendar, pattern, numbersOverride);
cacheDateFormats.put(key, result);
@@ -282,7 +282,7 @@
int minEras = (calendar.equals("chinese") || calendar.equals("dangi")) ? 0 : 1;
List<String> temp = getArray(prefix + "eras/eraAbbr/era[@type=\"", 0, null, "\"]", minEras);
- formatData.setEras(last = (String[]) temp.toArray(new String[temp.size()]));
+ formatData.setEras(last = temp.toArray(new String[temp.size()]));
if (minEras != 0) checkFound(last);
// if (temp.size() < 2 && notGregorian) {
// if (gregorianBackup == null) gregorianBackup = _getDateFormatSymbols("gregorian");
@@ -290,7 +290,7 @@
// }
temp = getArray(prefix + "eras/eraNames/era[@type=\"", 0, null, "\"]", minEras);
- formatData.setEraNames(last = (String[]) temp.toArray(new String[temp.size()]));
+ formatData.setEraNames(last = temp.toArray(new String[temp.size()]));
if (minEras != 0) checkFound(last);
// if (temp.size() < 2 && notGregorian) {
// if (gregorianBackup == null) gregorianBackup = _getDateFormatSymbols("gregorian");
@@ -437,7 +437,7 @@
final int arrayCount = isDay ? 7 : type.equals("month") ? 12 : 4;
List<String> temp = getArray(prefix, isDay ? 0 : 1, isDay ? Days : null, postfix, arrayCount);
if (isDay) temp.add(0, "");
- String[] result = (String[]) temp.toArray(new String[temp.size()]);
+ String[] result = temp.toArray(new String[temp.size()]);
checkFound(result);
return result;
}
@@ -445,7 +445,7 @@
static final Matcher gregorianMonthsMatcher = PatternCache.get(".*gregorian.*months.*").matcher("");
private List<String> getArray(String prefix, int firstIndex, String[] itemNames, String postfix, int minimumSize) {
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
String lastType;
for (int i = firstIndex;; ++i) {
lastType = itemNames != null && i < itemNames.length ? itemNames[i] : String.valueOf(i);
@@ -459,10 +459,6 @@
throw new RuntimeException("Internal Error: ICUServiceBuilder.getArray():" + cldrFile.getLocaleID() + " "
+ prefix + lastType + postfix + " - result.size=" + result.size() + ", less than acceptable minimum "
+ minimumSize);
- // Collection s = CollectionUtilities.addAll(cldrFile.iterator(prefix), new
- // TreeSet());//cldrFile.keySet(".*gregorian.*months.*", );
- // String item = cldrFile.getWinningValueWithBailey(prefix + lastType + postfix);
- // throw new IllegalArgumentException("Can't find enough items");
}
/*
* <months>
@@ -495,6 +491,7 @@
this.roundingIncrement = currencyNumberInfo.getRoundingIncrement();
}
+ @Override
public String getName(ULocale locale,
int nameStyle,
boolean[] isChoiceFormat) {
@@ -529,10 +526,12 @@
* @return the non-negative rounding increment, or 0.0 if none
* @stable ICU 2.2
*/
+ @Override
public double getRoundingIncrement() {
return roundingIncrement;
}
+ @Override
public int getDefaultFractionDigits() {
return fractDigits;
}
@@ -592,7 +591,7 @@
public NumberFormat getGenericNumberFormat(String ns) {
// CLDRFile cldrFile = cldrFactory.make(localeID, true);
- NumberFormat result = (NumberFormat) cacheNumberFormats.get(cldrFile.getLocaleID() + "@numbers=" + ns);
+ NumberFormat result = cacheNumberFormats.get(cldrFile.getLocaleID() + "@numbers=" + ns);
if (result == null) {
ULocale ulocale = new ULocale(cldrFile.getLocaleID() + "@numbers=" + ns);
result = NumberFormat.getInstance(ulocale);
@@ -747,7 +746,7 @@
private DecimalFormatSymbols _getDecimalFormatSymbols(String numberSystem) {
String key = (numberSystem == null) ? cldrFile.getLocaleID() : cldrFile.getLocaleID() + "@numbers="
+ numberSystem;
- DecimalFormatSymbols symbols = (DecimalFormatSymbols) cacheDecimalFormatSymbols.get(key);
+ DecimalFormatSymbols symbols = cacheDecimalFormatSymbols.get(key);
if (symbols != null) {
return (DecimalFormatSymbols) symbols.clone();
}
@@ -865,6 +864,7 @@
public enum Context {
format, stand_alone;
+ @Override
public String toString() {
return name().replace('_', '-');
}
diff --git a/tools/java/org/unicode/cldr/util/IntMap.java b/tools/java/org/unicode/cldr/util/IntMap.java
index 6ae159e..77c1a41 100644
--- a/tools/java/org/unicode/cldr/util/IntMap.java
+++ b/tools/java/org/unicode/cldr/util/IntMap.java
@@ -40,6 +40,7 @@
public abstract int approximateStorage();
+ @Override
public String toString() {
return getValueMap().toString();
}
@@ -53,10 +54,12 @@
this.intToValue = intToValue;
}
+ @Override
public T get(int index) {
return intToValue[index];
}
+ @Override
public Map<T, Integer> getValueMap(Map<T, Integer> output) {
for (int i = 0; i < intToValue.length; ++i) {
output.put(intToValue[i], i);
@@ -64,6 +67,7 @@
return output;
}
+ @Override
public int approximateStorage() {
int size = OBJECT_OVERHEAD;
for (T item : intToValue) {
@@ -75,9 +79,10 @@
}
public static class BasicIntMapFactory<T> implements IntMapFactory<T> {
+ @Override
@SuppressWarnings("unchecked")
public BasicIntMap<T> make(Collection<T> values) {
- return new BasicIntMap<T>((T[]) new ArrayList<T>(new HashSet<T>(values)).toArray());
+ return new BasicIntMap<>((T[]) new ArrayList<>(new HashSet<>(values)).toArray());
}
}
@@ -97,6 +102,7 @@
this.intToValue = intToValue;
}
+ @Override
public String get(int index) {
// the packedIndex stores the string as an index in the top 24 bits, and length in the bottom 8.
int packedIndex = intToValue[index];
@@ -105,6 +111,7 @@
return data.substring(dataIndex, dataIndex + len);
}
+ @Override
public Map<String, Integer> getValueMap(Map<String, Integer> output) {
for (int i = 0; i < intToValue.length; ++i) {
output.put(get(i), i);
@@ -112,6 +119,7 @@
return output;
}
+ @Override
public int approximateStorage() {
int size = OBJECT_OVERHEAD + POINTER_OVERHEAD * 2;
size += data.length() * 2 + STRING_OVERHEAD;
@@ -121,6 +129,7 @@
}
public static final Comparator<String> LONGEST_FIRST_COMPARATOR = new Comparator<String>() {
+ @Override
public int compare(String a, String b) {
return a.length() > b.length() ? -1
: a.length() < b.length() ? 1
@@ -129,9 +138,10 @@
};
public static class CompactStringIntMapFactory implements IntMapFactory<String> {
+ @Override
public CompactStringIntMap make(Collection<String> values) {
// first sort, longest first
- Set<String> sorted = new TreeSet<String>(LONGEST_FIRST_COMPARATOR);
+ Set<String> sorted = new TreeSet<>(LONGEST_FIRST_COMPARATOR);
sorted.addAll(values);
StringBuilder data = new StringBuilder();
diff --git a/tools/java/org/unicode/cldr/util/Iso639Data.java b/tools/java/org/unicode/cldr/util/Iso639Data.java
index 7533b12..f7582f7 100644
--- a/tools/java/org/unicode/cldr/util/Iso639Data.java
+++ b/tools/java/org/unicode/cldr/util/Iso639Data.java
@@ -30,7 +30,7 @@
static Relation<String, String> toNames;
static Relation<String, String> toRetirements;
-
+
static Map<String, String> toChangeTo;
static Map<String, Scope> toScope;
@@ -97,7 +97,7 @@
}
return Scope.valueOf(input); // to get exception
}
- };
+ }
/**
* <h3><a NAME="L"></a>Living languages</h3>
@@ -130,7 +130,7 @@
*/
public enum Type {
Ancient, Constructed, Extinct, Historical, Living, Special, Collection, Unknown
- };
+ }
/**
* This indicates the source of the language subtag.
@@ -140,7 +140,7 @@
*/
public enum Source {
ISO_639_1, ISO_639_2, ISO_639_3, BCP47, CLDR
- };
+ }
public static String getVersion() {
return version;
@@ -269,7 +269,7 @@
*/
enum IsoColumn {
Id, Part2B, Part2T, Part1, Scope, Type, Ref_Name
- };
+ }
/**
* Id char(3) NOT NULL, -- The three-letter 639-3 identifier Print_Name
@@ -279,7 +279,7 @@
*/
enum IsoNamesColumn {
Id, Print_Name, Inverted_Name
- };
+ }
private static void getData() {
try {
@@ -289,18 +289,18 @@
in = CldrUtility.getUTF8Data("iso-639-3.tab");
SplitToArray tabs = new SplitToArray(Splitter.on('\t').trimResults());
- toAlpha3 = new HashMap<String, String>();
- fromAlpha3 = new HashMap<String, String>();
- toBiblio3 = new HashMap<String, String>();
- fromBiblio3 = new HashMap<String, String>();
- toScope = new HashMap<String, Scope>();
- toType = new HashMap<String, Type>();
+ toAlpha3 = new HashMap<>();
+ fromAlpha3 = new HashMap<>();
+ toBiblio3 = new HashMap<>();
+ fromBiblio3 = new HashMap<>();
+ toScope = new HashMap<>();
+ toType = new HashMap<>();
toNames = Relation.of(new TreeMap<String, Set<String>>(), LinkedHashSet.class);
toRetirements = Relation.of(new TreeMap<String, Set<String>>(), LinkedHashSet.class);
- toChangeTo = new TreeMap<String, String>();
+ toChangeTo = new TreeMap<>();
macro_encompassed = Relation.of(new TreeMap<String, Set<String>>(), LinkedHashSet.class);
- encompassed_macro = new HashMap<String, String>();
- toSource = new HashMap<String, Source>();
+ encompassed_macro = new HashMap<>();
+ toSource = new HashMap<>();
toSource.put("sh", Source.ISO_639_1); // add deprecated language
int count = 0; // line count for debugging
@@ -469,7 +469,7 @@
}
in.close();
- Map<String, String> toHeirarchyTemp = new TreeMap<String, String>();
+ Map<String, String> toHeirarchyTemp = new TreeMap<>();
in = CldrUtility.getUTF8Data("external/Iso639-5.html");
String lastCode = null;
int column = 0;
@@ -563,7 +563,7 @@
in.close();
Pattern SPLIT_HEIRARCHY = PatternCache.get("\\s*:\\s*");
- toHeirarchy = new TreeMap<String, List<String>>();
+ toHeirarchy = new TreeMap<>();
// for (String code : toHeirarchyTemp.keySet()) {
// System.out.println(code + " => " + toHeirarchyTemp.get(code));
// }
@@ -643,7 +643,7 @@
public static Set<String> getEncompassed() {
return encompassed_macro.keySet();
}
-
+
public static String getChangeTo(String subtag) {
return getChangeToMap().get(subtag);
}
diff --git a/tools/java/org/unicode/cldr/util/IsoCurrencyParser.java b/tools/java/org/unicode/cldr/util/IsoCurrencyParser.java
index aac26bb..4ea6ade 100644
--- a/tools/java/org/unicode/cldr/util/IsoCurrencyParser.java
+++ b/tools/java/org/unicode/cldr/util/IsoCurrencyParser.java
@@ -94,8 +94,8 @@
.put("EUROPEAN MONETARY CO-OPERATION FUND (EMCF)", "ZZ")
.build();
- static Map<String, String> iso4217CountryToCountryCode = new TreeMap<String, String>();
- static Set<String> exceptionList = new LinkedHashSet<String>();
+ static Map<String, String> iso4217CountryToCountryCode = new TreeMap<>();
+ static Set<String> exceptionList = new LinkedHashSet<>();
static {
StandardCodes sc = StandardCodes.make();
Set<String> countries = sc.getAvailableCodes("territory");
@@ -138,11 +138,13 @@
return minor_unit;
}
+ @Override
public String toString() {
return String.format("[%s,\t%s [%s],\t%d]", name, countryCode,
StandardCodes.make().getData("territory", countryCode), numericCode);
}
+ @Override
public int compareTo(Object o) {
Data other = (Data) o;
int result;
@@ -213,7 +215,7 @@
// we can remove these as well.
// SVC - El Salvador Colon - not used anymore ( uses USD instead )
// ZWL - Last Zimbabwe Dollar - abandoned due to hyper-inflation.
- Set<String> KNOWN_BAD_ISO_DATA_CODES = new TreeSet<String>(Arrays.asList("SVC", "ZWL"));
+ Set<String> KNOWN_BAD_ISO_DATA_CODES = new TreeSet<>(Arrays.asList("SVC", "ZWL"));
String country_code;
String currency_name;
String alphabetic_code;
@@ -226,6 +228,7 @@
public void cleanup() {
}
+ @Override
public void handlePathValue(String path, String value) {
try {
XPathParts parts = XPathParts.getFrozenInstance(path);
diff --git a/tools/java/org/unicode/cldr/util/IsoRegionData.java b/tools/java/org/unicode/cldr/util/IsoRegionData.java
index b370dcb..a6eccdf 100644
--- a/tools/java/org/unicode/cldr/util/IsoRegionData.java
+++ b/tools/java/org/unicode/cldr/util/IsoRegionData.java
@@ -11,17 +11,17 @@
import java.util.Set;
import java.util.TreeSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.ICUUncheckedIOException;
public class IsoRegionData {
- static Map<String, String> _numeric = new HashMap<String, String>();
- static Map<String, String> _alpha3 = new HashMap<String, String>();
- static Map<String, String> _fips10 = new HashMap<String, String>();
- static Map<String, String> _internet = new HashMap<String, String>();
- static Set<String> other_internet = new TreeSet<String>();
- static Set<String> available = new HashSet<String>();
+ static Map<String, String> _numeric = new HashMap<>();
+ static Map<String, String> _alpha3 = new HashMap<>();
+ static Map<String, String> _fips10 = new HashMap<>();
+ static Map<String, String> _internet = new HashMap<>();
+ static Set<String> other_internet = new TreeSet<>();
+ static Set<String> available = new HashSet<>();
static final UnicodeSet NMTOKEN = new UnicodeSet(
"[\\-.0-\\:A-Z_a-z\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u037D\\u037F-\\u1FFF\\u200C\\u200D\\u203F\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\U00010000-\\U000EFFFF]")
@@ -66,7 +66,7 @@
}
codes.close();
- Set<String> errors = new LinkedHashSet<String>();
+ Set<String> errors = new LinkedHashSet<>();
codes = CldrUtility.getUTF8Data("territory_codes.txt");
while (true) {
String line = codes.readLine();
@@ -90,14 +90,14 @@
String internet = values[3];
if (internet != null) {
internet = internet.toUpperCase();
- LinkedHashSet<String> internetStrings = new LinkedHashSet<String>(
+ LinkedHashSet<String> internetStrings = new LinkedHashSet<>(
Arrays.asList(internet.split("/")));
if (!other_internet.containsAll(internetStrings)) {
errors.addAll(internetStrings);
errors.removeAll(other_internet);
}
other_internet.removeAll(internetStrings);
- internet = CollectionUtilities.join(internetStrings, " ");
+ internet = Joiner.on(" ").join(internetStrings);
}
String fips10 = values[4];
_numeric.put(alpha2, numeric);
@@ -112,7 +112,7 @@
} catch (IOException e) {
throw new ICUUncheckedIOException(e);
}
- _internet.put("ZZ", CollectionUtilities.join(other_internet, " "));
+ _internet.put("ZZ", Joiner.on(" ").join(other_internet));
other_internet = Collections.unmodifiableSet(other_internet);
diff --git a/tools/java/org/unicode/cldr/util/LDMLUtilities.java b/tools/java/org/unicode/cldr/util/LDMLUtilities.java
index 6ecc56a..02c8660 100644
--- a/tools/java/org/unicode/cldr/util/LDMLUtilities.java
+++ b/tools/java/org/unicode/cldr/util/LDMLUtilities.java
@@ -811,7 +811,7 @@
StringBuffer xp1 = new StringBuffer();
StringBuffer xp2 = new StringBuffer();
int l1 = xp1.length(), l2 = xp2.length();
- Map<String, Object> map = new HashMap<String, Object>();
+ Map<String, Object> map = new HashMap<>();
if (n2 == null || n2.length == 0) {
Node[] na = new Node[n1.length];
for (int i = 0; i < n1.length; i++) {
@@ -878,7 +878,7 @@
* continue;
*/
// initialize the stack for every alias!
- stack = new HashMap<String, String>();
+ stack = new HashMap<>();
if (node == null) {
System.err.println("list.item(" + i + ") returned null!. The list reports it's length as: "
+ array.length);
@@ -1316,7 +1316,7 @@
NodeList list = parent.getChildNodes();
int length = list.getLength();
- List<Node> al = new ArrayList<Node>();
+ List<Node> al = new ArrayList<>();
for (int i = 0; i < length; i++) {
Node item = list.item(i);
if (item.getNodeType() != Node.ELEMENT_NODE) {
@@ -1853,6 +1853,7 @@
// Local class: cheap non-printing ErrorHandler
// This is used to suppress validation warnings
ErrorHandler nullHandler = new ErrorHandler() {
+ @Override
public void warning(SAXParseException e) throws SAXException {
int col = e.getColumnNumber();
String msg = (filename2 + ":" + e.getLineNumber()
@@ -1865,6 +1866,7 @@
}
}
+ @Override
public void error(SAXParseException e) throws SAXException {
int col = e.getColumnNumber();
String msg = (filename2 + ":" + e.getLineNumber()
@@ -1876,6 +1878,7 @@
}
}
+ @Override
public void fatalError(SAXParseException e) throws SAXException {
throw e;
}
@@ -1959,15 +1962,7 @@
}
File f = new File(filename);
- String tmp = null;
- try {
- // This normally gives a better path
- tmp = f.getCanonicalPath();
- } catch (IOException ioe) {
- // But this can be used as a backup, for cases
- // where the file does not exist, etc.
- tmp = f.getAbsolutePath();
- }
+ String tmp = PathUtilities.getNormalizedPathString(f);
// URLs must explicitly use only forward slashes
if (File.separatorChar == '\\') {
@@ -2228,6 +2223,7 @@
private static void setNamespace(XPath xpath, String string) {
if (string.contains("special/icu:")) {
xpath.setNamespaceContext(new javax.xml.namespace.NamespaceContext() {
+ @Override
public String getNamespaceURI(String prefix) {
if (prefix.equals("icu")) {
return "http://www.icu-project.org";
@@ -2235,10 +2231,12 @@
return null;
}
+ @Override
public String getPrefix(String namespaceURI) {
return null;
}
+ @Override
public Iterator<String> getPrefixes(String namespaceURI) {
return null;
}
diff --git a/tools/java/org/unicode/cldr/util/LanguageGroup.java b/tools/java/org/unicode/cldr/util/LanguageGroup.java
index aa10e8a..ad00cec 100644
--- a/tools/java/org/unicode/cldr/util/LanguageGroup.java
+++ b/tools/java/org/unicode/cldr/util/LanguageGroup.java
@@ -9,13 +9,15 @@
import org.unicode.cldr.util.ChainedMap.M3;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.util.ULocale;
public enum LanguageGroup {
- root("und"), germanic("gem"), celtic("cel"), romance("roa"), slavic("sla"), baltic("bat"), indic("inc"), other_indo("ine_001"), dravidian("dra"), uralic(
- "urj"), cjk("und_Hani"), sino_tibetan("sit"), tai("tai"), austronesian("map"), turkic("trk"), afroasiatic(
- "afa"), austroasiatic("aav"), niger_congo("nic"), east_sudanic("sdv"), songhay("son"), american("und_019"), art("art"), other("und_001");
+ root("und"), germanic("gem"), celtic("cel"), romance("roa"), slavic("sla"), baltic("bat"),
+ indic("inc"), iranian("ira"), other_indo("ine_001"), caucasian("cau"), dravidian("dra"),
+ uralic("urj"), cjk("und_Hani"), sino_tibetan("sit"), tai("tai"), austronesian("map"),
+ turkic("trk"), afroasiatic("afa"), austroasiatic("aav"), niger_congo("nic"),
+ east_sudanic("sdv"), songhay("son"), american("und_019"), art("art"), other("und_001");
public final String iso;
@@ -35,7 +37,6 @@
if (map.put(loc, group) != null) {
throw new IllegalArgumentException("duplicate: " + s + ", " + group);
}
- ;
GROUP_LANGUAGE.put(group, loc, count);
++count;
}
@@ -45,38 +46,42 @@
LinkedHashMap<ULocale, LanguageGroup> temp = new LinkedHashMap<>();
LANGUAGE_GROUP = Collections.unmodifiableMap(temp);
add(temp, root, "root");
- add(temp, germanic, "en", "fy", "nl", "af", "de", "gsw", "wae", "ksh", "lb", "sv", "da", "nb", "nn", "fo", "is", "yi");
+ add(temp, germanic, "en", "fy", "nl", "af", "de", "gsw", "wae", "ksh", "lb", "sv", "da",
+ "nb", "nn", "fo", "is", "yi", "nds");
add(temp, celtic, "ga", "gd", "cy", "gv", "kw", "br");
- add(temp, romance, "fr", "pt", "gl", "es", "ca", "ast", "it", "rm", "ro");
- add(temp, slavic, "pl", "cs", "sk", "sl", "hr", "bs", "mk", "sr", "bg", "ru", "be", "uk");
- add(temp, baltic, "lt", "lv");
- add(temp, other_indo, "el", "hy", "sq", "fa", "ps", "os");
- add(temp, indic, "ur", "hi", "gu", "sd", "bn", "as", "ccp", "or", "mr", "ne", "pa", "si");
+ add(temp, romance, "fr", "pt", "gl", "es", "ca", "ast", "it", "rm", "ro", "fur", "an",
+ "co", "oc", "sc", "scn", "wa");
+ add(temp, slavic, "pl", "cs", "sk", "sl", "hr", "bs", "mk", "sr", "bg", "ru", "be", "uk",
+ "dsb", "hsb", "cu", "szl");
+ add(temp, baltic, "lt", "lv", "prg");
+ add(temp, indic, "ur", "hi", "gu", "sd", "bn", "as", "ccp", "or", "mr", "ne", "pa", "si",
+ "kok", "ks", "mai", "doi", "dv", "sa", "trw");
+ add(temp, iranian, "fa", "ps", "ku", "os", "ckb", "lrc", "mzn", "tg", "bgn", "sdh");
+ add(temp, other_indo, "el", "hy", "sq");
add(temp, dravidian, "ta", "te", "ml", "kn");
add(temp, cjk, "zh", "yue", "ja", "ko");
- add(temp, turkic, "tr", "az", "tk", "kk", "ky", "uz", "ug");
- add(temp, uralic, "hu", "fi", "et", "se", "smn");
- add(temp, afroasiatic, "ar", "mt", "he", "om", "so", "ha", "am", "tzm", "zgh");
- add(temp, tai, "th", "lo");
- add(temp, austronesian, "id", "ms", "jv", "fil", "haw");
- add(temp, austroasiatic, "vi", "km");
- add(temp, niger_congo, "sw", "swc", "yo", "ig", "ff", "sn", "zu");
- add(temp, other, "ka", "eu", "mn", "naq");
- add(temp, sino_tibetan, "my");
- add(temp, afroasiatic, "aa", "kab", "shi", "ssy", "ti");
- add(temp, american, "chr", "kl", "lkt", "qu");
- add(temp, art, "eo", "vo", "ia");
- add(temp, austronesian, "mg", "to");
+ add(temp, turkic, "tr", "az", "tk", "kk", "ky", "uz", "ug", "sah", "tt", "ba", "cv");
+ add(temp, uralic, "hu", "fi", "et", "se", "smn", "myv", "sma", "smj", "sms");
+ add(temp, afroasiatic, "ar", "mt", "he", "om", "so", "ha", "am", "tzm", "zgh", "aa", "kab",
+ "shi", "ssy", "ti", "byn", "gez", "sid", "syr", "tig", "wal");
+ add(temp, tai, "th", "lo", "blt");
+ add(temp, austronesian, "id", "ms", "jv", "fil", "haw", "mg", "to", "ceb", "mi", "su",
+ "trv");
+ add(temp, austroasiatic, "vi", "km", "sat");
+ add(temp, niger_congo, "sw", "swc", "yo", "ig", "ff", "sn", "zu", "wo", "xh", "agq", "ak",
+ "asa", "bas", "bem", "bez", "bm", "cgg", "dua", "dyo", "ebu", "ee", "ewo", "guz",
+ "jgo", "kam", "ki", "kkj", "ksb", "ksf", "lag", "lg", "ln", "lu", "luy", "mua", "nd",
+ "nnh", "nr", "nyn", "rn", "rof", "rw", "sbp", "sg", "ss", "tn", "ts", "vai", "ve",
+ "dav", "jmc", "kde", "mer", "mgh", "mgo", "nmg", "nso", "rwk", "seh", "vun", "xog",
+ "yav", "bss", "cch", "gaa", "kaj", "kcg", "ken", "kpe", "nqo", "ny", "st");
+ add(temp, american, "chr", "kl", "lkt", "qu", "arn", "cad", "cic", "gn", "iu", "moh",
+ "mus", "nv", "osa", "quc", "nci");
add(temp, east_sudanic, "luo", "mas", "nus", "saq", "teo", "kln");
- add(temp, indic, "kok", "ks");
- add(temp, niger_congo, "agq", "ak", "asa", "bas", "bem", "bez", "bm", "cgg", "dua", "dyo", "ebu", "ee", "ewo", "guz", "jgo", "kam", "ki", "kkj", "ksb",
- "ksf", "lag", "lg", "ln", "lu", "luy", "mua", "nd", "nnh", "nr", "nyn", "rn", "rof", "rw", "sbp", "sg", "ss", "tn", "ts", "vai", "ve", "dav",
- "jmc", "kde", "mer", "mgh", "mgo", "nmg", "nso", "rwk", "seh", "vun", "xog", "yav");
- add(temp, romance, "fur", "kea", "mfe");
- add(temp, sino_tibetan, "bo", "brx", "dz", "ii");
- add(temp, slavic, "dsb", "hsb");
+ add(temp, sino_tibetan, "my", "bo", "brx", "dz", "ii", "mni");
add(temp, songhay, "dje", "khq", "ses", "twq");
- add(temp, turkic, "sah");
+ add(temp, caucasian, "ka", "ce");
+ add(temp, other, "eu", "mn", "naq", "pcm", "kea", "mfe", "wbp");
+ add(temp, art, "eo", "vo", "ia", "io", "jbo");
//GROUP_LANGUAGE.freeze();
}
@@ -129,7 +134,7 @@
Set<ULocale> locales = LanguageGroup.getLocales(languageGroup);
String englishName = languageGroup.getName(english);
System.out.print("\t\t<languageGroup id=\"" + languageGroup.iso
- + "\" code=\"" + CollectionUtilities.join(locales, ", ")
+ + "\" code=\"" + Joiner.on(", ").join(locales)
+ "\"/>\t<!-- " + englishName + " -->\n");
}
System.out.print("\t</languageGroups>"
diff --git a/tools/java/org/unicode/cldr/util/LanguageInfo.java b/tools/java/org/unicode/cldr/util/LanguageInfo.java
index b5c2978..6175fc6 100644
--- a/tools/java/org/unicode/cldr/util/LanguageInfo.java
+++ b/tools/java/org/unicode/cldr/util/LanguageInfo.java
@@ -20,7 +20,7 @@
public enum CldrDir {
base, main, seed
- };
+ }
private int literatePopulation;
private Relation<OfficialStatus, String> statusToRegions = Relation.of(new EnumMap<OfficialStatus, Set<String>>(OfficialStatus.class), TreeSet.class);
@@ -68,7 +68,7 @@
static final Map<String, LanguageInfo> languageCodeToInfo;
static {
- TreeMap<String, LanguageInfo> temp = new TreeMap<String, LanguageInfo>();
+ TreeMap<String, LanguageInfo> temp = new TreeMap<>();
// get population/official status
LanguageTagParser ltp = new LanguageTagParser();
for (String territory : SDI.getTerritoriesWithPopulationData()) {
diff --git a/tools/java/org/unicode/cldr/util/LanguageTagCanonicalizer.java b/tools/java/org/unicode/cldr/util/LanguageTagCanonicalizer.java
index 8577f66..f76b801 100644
--- a/tools/java/org/unicode/cldr/util/LanguageTagCanonicalizer.java
+++ b/tools/java/org/unicode/cldr/util/LanguageTagCanonicalizer.java
@@ -50,7 +50,11 @@
* <br>TODO: map invalid language tags to <unknown>, eg ZZ; drop invalid U or T extensions, convert ICU locale extensions to BCP47
*/
// TODO, handle variants
+ @Override
public synchronized String transform(String locale) {
+ return transform (locale, OutputOption.ICU_LCVARIANT);
+ }
+ public synchronized String transform(String locale, OutputOption oo) {
ltp1.set(locale);
copyFields2(LanguageTagField.language, getReplacement(LanguageTagField.language, LanguageTagField.language.get(ltp1), locale));
@@ -61,7 +65,7 @@
List<String> originalVariants = ltp1.getVariants();
if (originalVariants.size() != 0) {
- Set<String> newVariants = new TreeSet<String>();
+ Set<String> newVariants = new TreeSet<>();
for (String item : originalVariants) {
String replacement = getReplacement(LanguageTagField.variant, item, locale);
if (replacement == null) {
@@ -74,13 +78,13 @@
}
ltp1.setVariants(newVariants);
}
- final String result = ltp1.toString();
+ final String result = ltp1.toString(oo);
if ("und".equals(ltp1.getLanguage())) return result;
if (likely == null) {
return result;
}
// TODO: make more efficient, since likely will do the parsing again.
- String likelyMin = likely.minimize(result);
+ String likelyMin = likely.minimize(result, oo);
return likelyMin == null ? result : likelyMin;
}
@@ -173,7 +177,7 @@
List<String> originalVariants = ltp1.getVariants();
if (originalVariants.size() != 0) {
- Set<String> newVariants = new TreeSet<String>();
+ Set<String> newVariants = new TreeSet<>();
for (String item : originalVariants) {
String replacement = getReplacement(LanguageTagField.variant, item, locale);
if (replacement == null) {
@@ -185,6 +189,6 @@
}
}
ltp1.setVariants(newVariants);
- }
+ }
}
}
diff --git a/tools/java/org/unicode/cldr/util/LanguageTagParser.java b/tools/java/org/unicode/cldr/util/LanguageTagParser.java
index fc96458..87abda3 100644
--- a/tools/java/org/unicode/cldr/util/LanguageTagParser.java
+++ b/tools/java/org/unicode/cldr/util/LanguageTagParser.java
@@ -32,7 +32,6 @@
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Row.R2;
import com.ibm.icu.text.UnicodeSet;
@@ -57,7 +56,7 @@
return o1.charAt(0) == 't' ? 0 : 2;
case 2:
return o1.charAt(1) <= '9' ? 1 : 3;
- default:
+ default:
throw new IllegalArgumentException();
}
}
@@ -92,10 +91,10 @@
}
/**
- * @return Returns the grandfathered flag
+ * @return True if the language tag is marked as “Type: grandfathered” in BCP 47.
*/
- public boolean isGrandfathered() {
- return grandfathered;
+ public boolean isLegacy() {
+ return legacy;
}
/**
@@ -158,7 +157,7 @@
* @return Returns each of the language-script tags in the collection.
*/
public static Set<String> getLanguageAndScript(Collection<String> in, Set<String> output) {
- if (output == null) output = new TreeSet<String>();
+ if (output == null) output = new TreeSet<>();
LanguageTagParser lparser = new LanguageTagParser();
for (Iterator<String> it = in.iterator(); it.hasNext();) {
output.add(lparser.set(it.next()).getLanguageScript());
@@ -169,13 +168,13 @@
// private fields
private String original;
- private boolean grandfathered = false;
+ private boolean legacy = false;
private String language;
private String script;
private String region;
- private Set<String> variants = new TreeSet<String>();
- private Map<String, List<String>> extensions = new TreeMap<String, List<String>>(); // use tree map
- private Map<String, List<String>> localeExtensions = new TreeMap<String, List<String>>(EXTENSION_ORDER);
+ private Set<String> variants = new TreeSet<>();
+ private Map<String, List<String>> extensions = new TreeMap<>(); // use tree map
+ private Map<String, List<String>> localeExtensions = new TreeMap<>(EXTENSION_ORDER);
private static final UnicodeSet ALPHA = new UnicodeSet("[a-zA-Z]").freeze();
private static final UnicodeSet DIGIT = new UnicodeSet("[0-9]").freeze();
@@ -184,7 +183,7 @@
private static final UnicodeSet X = new UnicodeSet("[xX]").freeze();
private static final UnicodeSet ALPHA_MINUS_X = new UnicodeSet(ALPHA).removeAll(X).freeze();
private static StandardCodes standardCodes = StandardCodes.make();
- private static final Set<String> grandfatheredCodes = standardCodes.getAvailableCodes("grandfathered");
+ private static final Set<String> legacyCodes = standardCodes.getAvailableCodes("legacy");
private static final String separator = "-_"; // '-' alone for 3066bis language tags
private static final UnicodeSet SEPARATORS = new UnicodeSet().addAll(separator).freeze();
private static final Splitter SPLIT_BAR = Splitter.on(CharMatcher.anyOf(separator));
@@ -216,7 +215,7 @@
// clear everything out
language = region = script = "";
- grandfathered = false;
+ legacy = false;
variants.clear();
extensions.clear();
localeExtensions.clear();
@@ -233,7 +232,7 @@
}
List<String> valueList = SPLIT_BAR.splitToList(value);
switch(key.length()) {
- case 1:
+ case 1:
extensions.put(key, valueList);
break;
case 2:
@@ -247,10 +246,9 @@
languageTag = languageTag.substring(0, atPosition);
}
- // first test for grandfathered
- if (grandfatheredCodes.contains(languageTag)) {
+ if (legacyCodes.contains(languageTag)) {
language = languageTag;
- grandfathered = true;
+ legacy = true;
return this;
}
@@ -328,7 +326,7 @@
* @return true iff the language tag validates
*/
public boolean isValid() {
- if (grandfathered) return true; // don't need further checking, since we already did so when parsing
+ if (legacy) return true; // don't need further checking, since we already did so when parsing
if (!validates(language, "language")) return false;
if (!validates(script, "script")) return false;
if (!validates(region, "territory")) return false;
@@ -425,8 +423,8 @@
if (subtag.length() < minLength) {
return subtag;
}
- if (takesSubkeys
- && subtag.length() == 2
+ if (takesSubkeys
+ && subtag.length() == 2
&& (!firstT || isTKey(subtag))) { // start new key-value pair
if (!result.isEmpty() || base.length() != 1) { // don't add empty t- or u-
localeExtensions.put(base, ImmutableList.copyOf(result));
@@ -490,7 +488,7 @@
}
public enum OutputOption {
- ICU('_'), BCP47('-');
+ ICU('_'), ICU_LCVARIANT('_'), BCP47('-');
final char separator;
final Joiner joiner;
@@ -511,6 +509,7 @@
}
}
+ @Override
public String toString() {
return toString(OutputOption.ICU);
}
@@ -631,7 +630,7 @@
public static boolean isTKey(String key) {
return key.length() == 2 && key.charAt(1) < 'a';
}
-
+
public boolean hasT() {
for (String key : localeExtensions.keySet()) {
if (key.equals("t") || isTKey(key)) {
@@ -654,7 +653,7 @@
public enum Fields {
LANGUAGE, SCRIPT, REGION, VARIANTS
- };
+ }
public static Set<Fields> LANGUAGE_SCRIPT = Collections.unmodifiableSet(EnumSet.of(Fields.LANGUAGE, Fields.SCRIPT));
public static Set<Fields> LANGUAGE_REGION = Collections.unmodifiableSet(EnumSet.of(Fields.LANGUAGE, Fields.REGION));
@@ -753,7 +752,7 @@
this.separator = separator;
this.separator2 = separator2;
}
- };
+ }
public String toString(Format format) {
StringBuilder result = new StringBuilder();
@@ -801,7 +800,7 @@
private void appendField(Format format, StringBuilder result, String fieldName, Collection<String> fieldValues) {
if (!fieldValues.isEmpty()) {
- appendField(format, result, fieldName, CollectionUtilities.join(fieldValues, ","));
+ appendField(format, result, fieldName, Joiner.on(",").join(fieldValues));
}
}
@@ -829,35 +828,42 @@
if (!haveT) {
result.append(format.separator).append('t');
if (haveTLang) { // empty is illegal, but just in case
- result.append(format.separator).append(CollectionUtilities.join(tLang, format.separator));
+ result.append(format.separator).append(
+ Joiner.on(format.separator).join(tLang));
haveTLang = false;
}
haveT = true;
}
- appendFieldKey(format, result, entry.getKey(), CollectionUtilities.join(entry.getValue(), format.separator));
+ appendFieldKey(format, result, entry.getKey(),
+ Joiner.on(format.separator).join(entry.getValue()));
} else {
if (!haveU) {
result2.append(format.separator).append('u');
if (haveUSpecial) { // not yet valid, but just in case
- result2.append(format.separator).append(CollectionUtilities.join(uSpecial, format.separator));
+ result2.append(format.separator).append(
+ Joiner.on(format.separator).join(uSpecial));
haveUSpecial = false;
}
haveU = true;
}
- appendFieldKey(format, result2, entry.getKey(), CollectionUtilities.join(entry.getValue(), format.separator));
+ appendFieldKey(format, result2, entry.getKey(),
+ Joiner.on(format.separator).join(entry.getValue()));
}
}
if (haveTLang) {
- result.append(format.separator).append('t').append(format.separator).append(CollectionUtilities.join(tLang, format.separator));
+ result.append(format.separator).append('t').append(format.separator).append(
+ Joiner.on(format.separator).join(tLang));
}
if (haveUSpecial) {
- result2.append(format.separator).append('u').append(format.separator).append(CollectionUtilities.join(uSpecial, format.separator));
+ result2.append(format.separator).append('u').append(format.separator).append(
+ Joiner.on(format.separator).join(uSpecial));
}
result.append(result2); // put in right order
} else {
for (Entry<String, List<String>> entry : fieldValues.entrySet()) {
if (match == null || match.contains(entry.getKey())) {
- appendFieldKey(format, result, entry.getKey(), CollectionUtilities.join(entry.getValue(), format.separator));
+ appendFieldKey(format, result, entry.getKey(),
+ Joiner.on(format.separator).join(entry.getValue()));
}
}
}
diff --git a/tools/java/org/unicode/cldr/util/LenientDateParser.java b/tools/java/org/unicode/cldr/util/LenientDateParser.java
index fa6cb7f..b134b42 100644
--- a/tools/java/org/unicode/cldr/util/LenientDateParser.java
+++ b/tools/java/org/unicode/cldr/util/LenientDateParser.java
@@ -24,7 +24,6 @@
import org.unicode.cldr.util.Dictionary.Matcher.Status;
import org.unicode.cldr.util.LenientDateParser.Token.Type;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.OlsonTimeZone;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UCharacter;
@@ -62,7 +61,7 @@
static final DecimalFormat threeDigits = new DecimalFormat("000");
static final DecimalFormat twoDigits = new DecimalFormat("00");
- public static final Set<Integer> allOffsets = new TreeSet<Integer>();
+ public static final Set<Integer> allOffsets = new TreeSet<>();
static {
TimeZone GMT = TimeZone.getTimeZone("Etc/GMT");
@@ -79,8 +78,8 @@
}
}
- private static final UnicodeSet disallowedInSeparator = (UnicodeSet) new UnicodeSet("[:alphabetic:]").freeze();
- private static final UnicodeSet IGNORABLE = (UnicodeSet) new UnicodeSet("[,[:whitespace:]]").freeze();
+ private static final UnicodeSet disallowedInSeparator = new UnicodeSet("[:alphabetic:]").freeze();
+ private static final UnicodeSet IGNORABLE = new UnicodeSet("[,[:whitespace:]]").freeze();
private static final EnumSet<Type> dateTypes = EnumSet.of(Type.DAY, Type.MONTH, Type.YEAR, Type.WEEKDAY, Type.ERA);
private static final EnumSet<Type> timeTypes = EnumSet.of(Type.HOUR, Type.MINUTE, Type.SECOND, Type.AMPM,
Type.TIMEZONE);
@@ -92,7 +91,7 @@
static final Date january15 = new Date(thisYear, 0, 15, 0, 0, 0);
public class Parser {
- final List<Token> tokens = new ArrayList<Token>();
+ final List<Token> tokens = new ArrayList<>();
final SoFar haveSoFar = new SoFar();
Token previous;
final BreakIterator breakIterator;
@@ -283,7 +282,7 @@
// TODO look at the separators
// now get the integers
- Set<Type> ordering = new LinkedHashSet<Type>();
+ Set<Type> ordering = new LinkedHashSet<>();
ordering.addAll(haveStringMonth ? dateOrdering.yd : dateOrdering.ymd);
ordering.addAll(integerTimeTypes);
@@ -400,8 +399,8 @@
if (firstType != null) {
// skip
} else {
- boolean hasDate = CollectionUtilities.containsSome(dateTypes, set);
- boolean hasTime = CollectionUtilities.containsSome(timeTypes, set);
+ boolean hasDate = !Collections.disjoint(dateTypes, set);
+ boolean hasTime = !Collections.disjoint(timeTypes, set);
if (hasDate != hasTime) {
firstType = hasDate ? Type.YEAR : Type.HOUR;
}
@@ -496,7 +495,7 @@
}
return UNKNOWN;
}
- };
+ }
private final int value;
private final Type type;
@@ -590,6 +589,7 @@
return allowsBefore;
}
+ @Override
public String toString() {
return "{" + getType() + ":" + getIntValue() + "/" + toShortString(allowsBefore) + "/"
+ toShortString(allowsAfter) + "}";
@@ -662,6 +662,7 @@
return true;
}
+ @Override
public Type getType() {
return revisedType == null ? super.getType() : revisedType;
}
@@ -670,6 +671,7 @@
return allowsAt;
}
+ @Override
public String toString() {
return "{" + getType() + ":" + getIntValue() + "/" + toShortString(allowsAt) + "}";
}
@@ -702,7 +704,7 @@
// Matcher<String> matcher = converter.getDictionary().getMatcher();
// later, cache this dictionary
- Map<CharSequence, Token> map = DEBUG ? new TreeMap<CharSequence, Token>() : new HashMap<CharSequence, Token>();
+ Map<CharSequence, Token> map = DEBUG ? new TreeMap<>() : new HashMap<>();
DateFormatSymbols symbols = new DateFormatSymbols(locale);
// load the data
loadArray(map, symbols.getAmPmStrings(), Type.AMPM);
@@ -722,7 +724,7 @@
Calendar temp = Calendar.getInstance();
String[] zoneFormats = { "z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV" };
- List<SimpleDateFormat> zoneFormatList = new ArrayList<SimpleDateFormat>();
+ List<SimpleDateFormat> zoneFormatList = new ArrayList<>();
for (String zoneFormat : zoneFormats) {
zoneFormatList.add(new SimpleDateFormat(zoneFormat, locale));
}
@@ -791,8 +793,8 @@
// get separators from formats
// we walk through to see what can come before or after a separator, accumulating them all together
FormatParser formatParser = new FormatParser();
- Map<String, EnumSet<Type>> beforeTypes = new HashMap<String, EnumSet<Type>>();
- Map<String, EnumSet<Type>> afterTypes = new HashMap<String, EnumSet<Type>>();
+ Map<String, EnumSet<Type>> beforeTypes = new HashMap<>();
+ Map<String, EnumSet<Type>> afterTypes = new HashMap<>();
EnumSet<Type> nonDateTypes = EnumSet.allOf(Type.class);
nonDateTypes.removeAll(dateTypes);
EnumSet<Type> nonTimeTypes = EnumSet.allOf(Type.class);
@@ -809,7 +811,7 @@
add(beforeTypes, " ", timeTypes);
add(afterTypes, " ", timeTypes);
- Set<String> allSeparators = new HashSet<String>(beforeTypes.keySet());
+ Set<String> allSeparators = new HashSet<>(beforeTypes.keySet());
allSeparators.addAll(afterTypes.keySet());
for (String item : allSeparators) {
loadItem(map, item, beforeTypes.get(item), afterTypes.get(item));
@@ -891,12 +893,12 @@
static {
Set<String> canonicalZones = supplementalData.getCanonicalZones();
// get all the CLDR IDs
- Set<String> allCLDRZones = new TreeSet<String>(canonicalZones);
+ Set<String> allCLDRZones = new TreeSet<>(canonicalZones);
for (String canonicalZone : canonicalZones) {
allCLDRZones.addAll(supplementalData.getZone_aliases(canonicalZone));
}
// get all the ICU IDs
- Set<String> allIcuZones = new TreeSet<String>();
+ Set<String> allIcuZones = new TreeSet<>();
for (String canonicalZone : TimeZone.getAvailableIDs()) {
allIcuZones.add(canonicalZone);
for (int i = 0; i < TimeZone.countEquivalentIDs(canonicalZone); ++i) {
@@ -928,14 +930,14 @@
}
// add missing Etc zones
- canonicalZones = new TreeSet<String>(supplementalData.getCanonicalZones());
+ canonicalZones = new TreeSet<>(supplementalData.getCanonicalZones());
Set<String> zones = getAllGmtZones();
zones.removeAll(canonicalZones);
System.out.println("Missing GMT Zones: " + zones);
canonicalZones.addAll(zones);
canonicalZones = Collections.unmodifiableSet(canonicalZones);
- List<String> values = new ArrayList<String>();
+ List<String> values = new ArrayList<>();
for (String id : canonicalZones) { // TimeZone.getAvailableIDs() has extraneous values
values.add(id);
}
@@ -944,7 +946,7 @@
}
private static Set<String> getFirstMinusSecond(Set<String> first, Set<String> second) {
- Set<String> difference = new TreeSet<String>(first);
+ Set<String> difference = new TreeSet<>(first);
difference.removeAll(second);
return difference;
}
@@ -954,8 +956,8 @@
*/
static class BestTimeZone implements Comparator<String> {
// TODO replace by HashMap once done debugging
- Map<String, Integer> regionToRank = new TreeMap<String, Integer>();
- Map<String, Map<String, Integer>> regionToZoneToRank = new TreeMap<String, Map<String, Integer>>();
+ Map<String, Integer> regionToRank = new TreeMap<>();
+ Map<String, Map<String, Integer>> regionToZoneToRank = new TreeMap<>();
public BestTimeZone(ULocale locale) {
// build the two maps that we'll use later.
@@ -1002,7 +1004,7 @@
private void addRank(String region2, String zone) {
Map<String, Integer> zoneToRank = regionToZoneToRank.get(region2);
- if (zoneToRank == null) regionToZoneToRank.put(region2, zoneToRank = new TreeMap<String, Integer>());
+ if (zoneToRank == null) regionToZoneToRank.put(region2, zoneToRank = new TreeMap<>());
if (!zoneToRank.containsKey(zone)) {
zoneToRank.put(zone, zoneToRank.size()); // earlier is better.
}
@@ -1033,6 +1035,7 @@
return count;
}
+ @Override
public int compare(String z1, String z2) {
// Etc/GMT.* is lower
if (z1.startsWith("Etc/GMT")) {
@@ -1098,10 +1101,10 @@
int comparison = w1.compareTo(w2);
return comparison;
}
- };
+ }
private static LinkedHashSet<String> getIcuEquivalentZones(String zoneID) {
- LinkedHashSet<String> result = new LinkedHashSet<String>();
+ LinkedHashSet<String> result = new LinkedHashSet<>();
final int count = TimeZone.countEquivalentIDs(zoneID);
for (int i = 0; i < count; ++i) {
result.add(TimeZone.getEquivalentID(zoneID, i));
@@ -1123,7 +1126,7 @@
}
formatParser.set(pattern);
List<Object> list = formatParser.getItems();
- List<Type> temp = new ArrayList<Type>();
+ List<Type> temp = new ArrayList<>();
for (int i = 0; i < list.size(); ++i) {
Object item = list.get(i);
if (item instanceof String) {
@@ -1215,7 +1218,7 @@
}
}
- private static final UnicodeSet DIGITS = (UnicodeSet) new UnicodeSet("[:nd:]").freeze();
+ private static final UnicodeSet DIGITS = new UnicodeSet("[:nd:]").freeze();
private static void loadItem(Map<CharSequence, Token> map, String item, int i, Type type) {
map.put(item, new Token(i, type));
@@ -1245,7 +1248,7 @@
*/
public static Set<String> getAllGmtZones() {
- Set<Integer> offsets = new TreeSet<Integer>();
+ Set<Integer> offsets = new TreeSet<>();
for (String tzid : supplementalData.getCanonicalZones()) {
TimeZone zone = TimeZone.getTimeZone(tzid);
for (long date = startDate; date < endDate; date = getTransitionAfter(
@@ -1253,7 +1256,7 @@
offsets.add(zone.getOffset(date));
}
}
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
for (int offset : offsets) {
String zone = "Etc/GMT";
if (offset != 0) {
diff --git a/tools/java/org/unicode/cldr/util/Level.java b/tools/java/org/unicode/cldr/util/Level.java
index 4c3c3ef..98a1b68 100644
--- a/tools/java/org/unicode/cldr/util/Level.java
+++ b/tools/java/org/unicode/cldr/util/Level.java
@@ -20,7 +20,7 @@
COMPREHENSIVE(100, "G0", 2);
public static final Set<Level> CORE_TO_MODERN = ImmutableSet.of(CORE, BASIC, MODERATE, MODERN);
-
+
@Deprecated
public static final Level POSIX = BASIC;
@Deprecated
@@ -69,6 +69,7 @@
}
}
+ @Override
public String toString() {
return this.name().toLowerCase();
}
diff --git a/tools/java/org/unicode/cldr/util/LocaleIDParser.java b/tools/java/org/unicode/cldr/util/LocaleIDParser.java
index 17b2e30..564284f 100644
--- a/tools/java/org/unicode/cldr/util/LocaleIDParser.java
+++ b/tools/java/org/unicode/cldr/util/LocaleIDParser.java
@@ -40,7 +40,7 @@
}
public static Set<String> getLanguageScript(Collection<String> in, Set<String> output) {
- if (output == null) output = new TreeSet<String>();
+ if (output == null) output = new TreeSet<>();
LocaleIDParser lparser = new LocaleIDParser();
for (Iterator<String> it = in.iterator(); it.hasNext();) {
output.add(lparser.set(it.next()).getLanguageScript());
@@ -66,7 +66,7 @@
* @return Returns the variants.
*/
public String[] getVariants() {
- return (String[]) variants.clone();
+ return variants.clone();
}
// TODO, update to RFC3066
@@ -97,7 +97,7 @@
region = pieces[i++];
if (i >= pieces.length) return this;
}
- List<String> al = new ArrayList<String>();
+ List<String> al = new ArrayList<>();
while (i < pieces.length && pieces[i].length() > 0) {
al.add(pieces[i++]);
}
@@ -193,7 +193,7 @@
}
public LocaleIDParser setVariants(String[] variants) {
- this.variants = (String[]) variants.clone();
+ this.variants = variants.clone();
return this;
}
@@ -220,7 +220,7 @@
String parentID = getParent(localeID);
String prefix = (parentID == null || "root".equals(parentID)) ? "" : parentID + "_";
- Set<String> siblings = new TreeSet<String>();
+ Set<String> siblings = new TreeSet<>();
for (String id : set) {
if (id.startsWith(prefix) && set(id).getLevels().equals(myLevel)) {
siblings.add(id);
@@ -230,6 +230,7 @@
return siblings;
}
+ @Override
public String toString() {
StringBuffer result = new StringBuffer(language);
if (script.length() != 0) result.append('_').append(script);
diff --git a/tools/java/org/unicode/cldr/util/LocaleStringProvider.java b/tools/java/org/unicode/cldr/util/LocaleStringProvider.java
new file mode 100644
index 0000000..21be94e
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/LocaleStringProvider.java
@@ -0,0 +1,9 @@
+package org.unicode.cldr.util;
+
+import org.unicode.cldr.util.CLDRFile.Status;
+
+public interface LocaleStringProvider {
+ public String getStringValue(String xpath);
+ public String getLocaleID();
+ public String getSourceLocaleID(String xpath, Status status);
+}
diff --git a/tools/java/org/unicode/cldr/util/LogicalGrouping.java b/tools/java/org/unicode/cldr/util/LogicalGrouping.java
index ec1b803..481a773 100644
--- a/tools/java/org/unicode/cldr/util/LogicalGrouping.java
+++ b/tools/java/org/unicode/cldr/util/LogicalGrouping.java
@@ -1,5 +1,7 @@
package org.unicode.cldr.util;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -7,6 +9,9 @@
import java.util.concurrent.ConcurrentHashMap;
import org.unicode.cldr.util.DayPeriodInfo.DayPeriod;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalScope;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalTarget;
import org.unicode.cldr.util.PluralRulesUtil.KeywordStatus;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
@@ -17,9 +22,12 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.util.Output;
public class LogicalGrouping {
+ static final SupplementalDataInfo supplementalData = CLDRConfig.getInstance().getSupplementalDataInfo();
+
public static final ImmutableSet<String> metazonesDSTSet = ImmutableSet.of(
"Acre", "Africa_Western", "Alaska", "Almaty", "Amazon",
"America_Central", "America_Eastern", "America_Mountain", "America_Pacific", "Anadyr", "Apia",
@@ -52,14 +60,14 @@
/**
* Cache from locale and path (<Pair<String, String>), to logical group (Set<String>)
*/
- private static ConcurrentHashMap<Pair<String, String>, Set<String>> cacheLocaleAndPathToLogicalGroup = new ConcurrentHashMap<Pair<String, String>, Set<String>>();
+ private static ConcurrentHashMap<Pair<String, String>, Set<String>> cacheLocaleAndPathToLogicalGroup = new ConcurrentHashMap<>();
/**
* Statistics on occurrences of types of logical groups, for performance testing, debugging.
* GET_TYPE_COUNTS should be false for production to maximize performance.
*/
public static final boolean GET_TYPE_COUNTS = false;
- public static final ConcurrentHashMap<String, Long> typeCount = GET_TYPE_COUNTS ? new ConcurrentHashMap<String, Long>() : null;
+ public static final ConcurrentHashMap<String, Long> typeCount = GET_TYPE_COUNTS ? new ConcurrentHashMap<>() : null;
/**
* GET_TYPE_FROM_PARTS is more elegant when true, but performance is a little faster when it's false.
@@ -69,8 +77,9 @@
/**
* Return a sorted set of paths that are in the same logical set as the given path
- *
* @param path the distinguishing xpath
+ * @param pathType TODO
+ *
* @return the set of paths, or null (to be treated as equivalent to empty set)
*
* For example, given the path
@@ -83,14 +92,14 @@
* //ldml/dates/calendars/calendar[@type="gregorian"]/quarters/quarterContext[@type="format"]/quarterWidth[@type="abbreviated"]/quarter[@type="2"]
* //ldml/dates/calendars/calendar[@type="gregorian"]/quarters/quarterContext[@type="format"]/quarterWidth[@type="abbreviated"]/quarter[@type="3"]
* //ldml/dates/calendars/calendar[@type="gregorian"]/quarters/quarterContext[@type="format"]/quarterWidth[@type="abbreviated"]/quarter[@type="4"]
- *
+ *
* Caches: Most of the calculations are independent of the locale, and can be cached on a static basis.
* The paths that are locale-dependent are /dayPeriods and @count. Those can be computed on a per-locale basis;
* and cached (they are shared across a number of locales).
*
* Reference: https://unicode.org/cldr/trac/ticket/11854
*/
- public static Set<String> getPaths(CLDRFile cldrFile, String path) {
+ public static Set<String> getPaths(CLDRFile cldrFile, String path, Output<PathType> pathTypeOut) {
if (path == null) {
return null; // return null for null path
// return new TreeSet<String>(); // return empty set for null path
@@ -98,7 +107,7 @@
XPathParts parts = null;
PathType pathType = null;
if (GET_TYPE_FROM_PARTS) {
- parts = XPathParts.getInstance(path); // can't always be frozen, some addPath do setAttribute
+ parts = XPathParts.getFrozenInstance(path);
pathType = PathType.getPathTypeFromParts(parts);
} else {
/*
@@ -106,9 +115,12 @@
*/
pathType = PathType.getPathTypeFromPath(path);
}
-
+ if (pathTypeOut != null) {
+ pathTypeOut.value = pathType;
+ }
+
if (GET_TYPE_COUNTS) {
- typeCount.compute(pathType.toString(), (k, v) -> (v == null) ? 1 : v + 1);
+ typeCount.compute(pathType.toString(), (k, v) -> (v == null) ? 1 : v + 1);
}
if (pathType == PathType.SINGLETON) {
@@ -116,22 +128,24 @@
* Skip cache for PathType.SINGLETON and simply return a set of one.
* TODO: should we ever return null instead of singleton here?
*/
- Set<String> set = new TreeSet<String>();
+ Set<String> set = new TreeSet<>();
set.add(path);
return set;
}
if (!GET_TYPE_FROM_PARTS) {
- parts = XPathParts.getInstance(path);
+ parts = XPathParts.getFrozenInstance(path).cloneAsThawed();
+ } else {
+ parts = parts.cloneAsThawed();
}
if (PathType.isLocaleDependent(pathType)) {
String locale = cldrFile.getLocaleID();
- Pair<String, String> key = new Pair<String, String>(locale, path);
+ Pair<String, String> key = new Pair<>(locale, path);
if (cacheLocaleAndPathToLogicalGroup.containsKey(key)) {
- return new TreeSet<String>(cacheLocaleAndPathToLogicalGroup.get(key));
+ return new TreeSet<>(cacheLocaleAndPathToLogicalGroup.get(key));
}
- Set<String> set = new TreeSet<String>();
+ Set<String> set = new TreeSet<>();
pathType.addPaths(set, cldrFile, path, parts);
cacheLocaleAndPathToLogicalGroup.put(key, set);
return set;
@@ -140,21 +154,23 @@
* All other paths are locale-independent.
*/
if (cachePathToLogicalGroup.containsKey(path)) {
- return new TreeSet<String>(cachePathToLogicalGroup.get(path));
+ return new TreeSet<>(cachePathToLogicalGroup.get(path));
}
- Set<String> set = new TreeSet<String>();
+ Set<String> set = new TreeSet<>();
pathType.addPaths(set, cldrFile, path, parts);
cachePathToLogicalGroup.putAll(path, set);
return set;
}
}
+ public static Set<String> getPaths(CLDRFile cldrFile, String path) {
+ return getPaths(cldrFile, path, null);
+ }
+
/**
* Returns the plural info for a given locale.
*/
private static PluralInfo getPluralInfo(CLDRFile cldrFile) {
- SupplementalDataInfo supplementalData = SupplementalDataInfo.getInstance(
- cldrFile.getSupplementalDirectory());
return supplementalData.getPlurals(PluralType.cardinal,
cldrFile.getLocaleID());
}
@@ -166,7 +182,7 @@
* that it belongs to.
*/
public static boolean isOptional(CLDRFile cldrFile, String path) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path);
if (parts.containsElement("relative")) {
String fieldType = parts.findAttributeValue("field", "type");
@@ -180,12 +196,26 @@
// fully by paths with count="(0|1)", which are always optional themselves.
if (!path.contains("[@count=")) return false;
String pluralType = parts.getAttributeValue(-1, "count");
- if (pluralType.equals("0") || pluralType.equals("1")) return true;
- if (!pluralType.equals("zero") && !pluralType.equals("one")) return false;
+ switch (pluralType) {
+ case "0": case "1":
+ return true;
+ case "zero": case "one":
+ break; // continue
+ case "many": // special case for french
+ String localeId = cldrFile.getLocaleID();
+ if (localeId.startsWith("fr")
+ && (localeId.length() == 2 || localeId.charAt(2) == '_')) {
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+ parts = parts.cloneAsThawed();
PluralRules pluralRules = getPluralInfo(cldrFile).getPluralRules();
parts.setAttribute(-1, "count", "0");
- Set<Double> explicits = new HashSet<Double>();
+ Set<Double> explicits = new HashSet<>();
if (cldrFile.isHere(parts.toString())) {
explicits.add(0.0);
}
@@ -204,11 +234,11 @@
}
return false;
}
-
+
/**
* Path types for logical groupings
*/
- private enum PathType {
+ public enum PathType {
SINGLETON { // no logical groups for singleton paths
@Override
@SuppressWarnings("unused")
@@ -232,7 +262,7 @@
@Override
@SuppressWarnings("unused")
void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts) {
- String dayName = parts.size() > 7 ? parts.getAttributeValue(7, "type") : null;
+ String dayName = parts.size() > 7 ? parts.getAttributeValue(7, "type") : null;
// This is just a quick check to make sure the path is good.
if (dayName != null && days.contains(dayName)) {
for (String str : days) {
@@ -255,7 +285,6 @@
set.add(parts.toString());
}
} else {
- SupplementalDataInfo supplementalData = SupplementalDataInfo.getInstance(cldrFile.getSupplementalDirectory());
DayPeriodInfo.Type dayPeriodContext = DayPeriodInfo.Type.fromString(parts.findAttributeValue("dayPeriodContext", "type"));
DayPeriodInfo dpi = supplementalData.getDayPeriods(dayPeriodContext, cldrFile.getLocaleID());
List<DayPeriod> dayPeriods = dpi.getPeriods();
@@ -338,7 +367,7 @@
String decimalFormatLengthType = parts.size() > 3 ? parts.getAttributeValue(3, "type") : null;
String decimalFormatPatternType = parts.size() > 5 ? parts.getAttributeValue(5, "type") : null;
if (decimalFormatLengthType != null && decimalFormatPatternType != null &&
- compactDecimalFormatLengths.contains(decimalFormatLengthType)) {
+ compactDecimalFormatLengths.contains(decimalFormatLengthType)) {
int numZeroes = decimalFormatPatternType.length() - 1;
int baseZeroes = (numZeroes / 3) * 3;
for (int i = 0; i < 3; i++) {
@@ -354,21 +383,93 @@
}
},
COUNT {
- @Override
- @SuppressWarnings("unused")
- void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts) {
- PluralInfo pluralInfo = getPluralInfo(cldrFile);
- Set<Count> pluralTypes = pluralInfo.getCounts();
- String lastElement = parts.getElement(-1);
- for (Count count : pluralTypes) {
- parts.setAttribute(lastElement, "count", count.toString());
- set.add(parts.toString());
- }
- }
- };
+ @Override
+ @SuppressWarnings("unused")
+ void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts) {
+ addCaseOnly(set, cldrFile, parts);
+ }
+ },
+ COUNT_CASE {
+ @Override
+ @SuppressWarnings("unused")
+ void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts) {
+ if (!GrammarInfo.SEED_LOCALES.contains(cldrFile.getLocaleID())) {
+ addCaseOnly(set, cldrFile, parts);
+ return;
+ }
+ GrammarInfo grammarInfo = supplementalData.getGrammarInfo(cldrFile.getLocaleID());
+ if (grammarInfo == null
+ || (parts.getElement(3).equals("unitLength")
+ && GrammarInfo.SPECIAL_TRANSLATION_UNITS.contains(parts.getAttributeValue(3, "type")))) {
+ addCaseOnly(set, cldrFile, parts);
+ return;
+ }
+ Set<Count> pluralTypes = getPluralInfo(cldrFile).getCounts();
+ Collection<String> rawCases = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+ setGrammarAttributes(set, parts, pluralTypes, rawCases, null);
+
+ }
+ },
+ COUNT_CASE_GENDER {
+ @Override
+ @SuppressWarnings("unused")
+ void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts) {
+ if (!GrammarInfo.SEED_LOCALES.contains(cldrFile.getLocaleID())) {
+ addCaseOnly(set, cldrFile, parts);
+ return;
+ }
+ GrammarInfo grammarInfo = supplementalData.getGrammarInfo(cldrFile.getLocaleID());
+ if (grammarInfo == null) {
+ addCaseOnly(set, cldrFile, parts);
+ return;
+ }
+ Set<Count> pluralTypes = getPluralInfo(cldrFile).getCounts();
+ Collection<String> rawCases = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalCase, GrammaticalScope.units);
+ Collection<String> rawGenders = grammarInfo.get(GrammaticalTarget.nominal, GrammaticalFeature.grammaticalGender, GrammaticalScope.units);
+ setGrammarAttributes(set, parts, pluralTypes, rawCases, rawGenders);
+ }
+ }
+
+ ;
abstract void addPaths(Set<String> set, CLDRFile cldrFile, String path, XPathParts parts);
+ public void addCaseOnly(Set<String> set, CLDRFile cldrFile, XPathParts parts) {
+ Set<Count> pluralTypes = getPluralInfo(cldrFile).getCounts();
+ for (Count count : pluralTypes) {
+ parts.setAttribute(-1, "count", count.toString());
+ set.add(parts.toString());
+ }
+ }
+
+ public void setGrammarAttributes(Set<String> set, XPathParts parts, Set<Count> pluralTypes, Collection<String> rawCases, Collection<String> rawGenders) {
+ final String defaultGender = GrammaticalFeature.grammaticalGender.getDefault(rawGenders);
+ final String defaultCase = GrammaticalFeature.grammaticalCase.getDefault(rawCases);
+
+ if (rawCases == null || rawCases.isEmpty()) {
+ rawCases = Collections.singleton(defaultCase);
+ }
+ if (rawGenders == null || rawGenders.isEmpty()) {
+ rawGenders = Collections.singleton(defaultGender);
+ }
+ for (String gender : rawGenders) {
+ if (gender.equals(defaultGender)) {
+ gender = null;
+ }
+ for (String case1 : rawCases) {
+ if (case1.equals(defaultCase)) {
+ case1 = null;
+ }
+ for (Count count : pluralTypes) {
+ parts.setAttribute(-1, "gender", gender);
+ parts.setAttribute(-1, "count", count.toString());
+ parts.setAttribute(-1, "case", case1);
+ set.add(parts.toString());
+ }
+ }
+ }
+ }
+
/**
* Is the given PathType locale-dependent (for caching)?
*
@@ -379,7 +480,7 @@
/*
* The paths that are locale-dependent are @count and /dayPeriods.
*/
- return (pathType == COUNT || pathType == DAY_PERIODS);
+ return (pathType == COUNT || pathType == DAY_PERIODS || pathType.equals(COUNT_CASE) || pathType.equals(COUNT_CASE_GENDER));
}
/**
@@ -389,12 +490,12 @@
* @return the PathType
*
* Note: it would be more elegant and cleaner, but slower, if we used XPathParts to
- * determine the PathType. We avoid that since XPathParts.set is a performance hot spot.
+ * determine the PathType. We avoid that since XPathParts.set is a performance hot spot. (NOTE: don't know if the preceding is true anymore.)
*/
- private static PathType getPathTypeFromPath(String path) {
+ public static PathType getPathTypeFromPath(String path) {
/*
* Would changing the order of these tests ever change the return value?
- * Assume it could if in doubt.
+ * Assume it could if in doubt.
*/
if (path.indexOf("/metazone") > 0) {
return PathType.METAZONE;
@@ -420,6 +521,14 @@
if (path.indexOf("/decimalFormatLength") > 0) {
return PathType.DECIMAL_FORMAT_LENGTH;
}
+ if (path.indexOf("/unitLength[@type=\"long\"]") > 0) {
+ if (path.indexOf("compoundUnitPattern1") > 0) {
+ return PathType.COUNT_CASE_GENDER;
+ }
+ if (path.indexOf("/unitPattern[") > 0) {
+ return PathType.COUNT_CASE;
+ }
+ }
if (path.indexOf("[@count=") > 0) {
return PathType.COUNT;
}
@@ -431,11 +540,16 @@
*
* @param parts the XPathParts
* @return the PathType
+ * @deprecated
*/
+ @Deprecated
private static PathType getPathTypeFromParts(XPathParts parts) {
+ if (true) {
+ throw new UnsupportedOperationException("Code not updated. We may want to try using XPathParts in a future optimization, so leaving for now.");
+ }
/*
* Would changing the order of these tests ever change the return value?
- * Assume it could if in doubt.
+ * Assume it could if in doubt.
*/
if (parts.containsElement("metazone")) {
return PathType.METAZONE;
diff --git a/tools/java/org/unicode/cldr/util/LsrvCanonicalizer.java b/tools/java/org/unicode/cldr/util/LsrvCanonicalizer.java
new file mode 100644
index 0000000..aa97c15
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/LsrvCanonicalizer.java
@@ -0,0 +1,541 @@
+package org.unicode.cldr.util;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.unicode.cldr.util.StandardCodes.LstrType;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
+import com.ibm.icu.impl.Row.R2;
+
+/**
+ * Provides Unicode Language Identifier canonicalization for use in testing.
+ * The implementation is designed to be simple, and is not at all optimized for production use.
+ * It is used to verify the correctness of the specification algorithm,
+ * sanity-check the supplementalMetadata.xml alias data,
+ * and generate test files for use by implementations.
+ */
+public class LsrvCanonicalizer {
+
+ public static final Set<LstrType> LSRV = ImmutableSet.of(LstrType.language, LstrType.script, LstrType.region, LstrType.variant);
+ public static final Joiner UNDERBAR_JOINER = Joiner.on('_');
+
+ /**
+ * A representation of a Unicode Language Identifier in a format that makes it simple to process.
+ * The LSRV fields are represented as multimaps, though the LSR fields restricted to have only have 0 or 1 element.
+ */
+ public static class XLanguageTag {
+ final Multimap<LstrType, String> data;
+
+ private XLanguageTag(Multimap<LstrType, String> result) {
+ data = ImmutableMultimap.copyOf(result);
+ }
+ public Set<LstrType> keys() {
+ return data.keySet();
+ }
+ public Collection<String> get(LstrType lstrType) {
+ return data.get(lstrType);
+ }
+ public String toLocaleString() {
+ StringBuilder buffer = new StringBuilder();
+ final Collection<String> region = data.get(LstrType.language);
+ if (!region.isEmpty()) {
+ buffer.append(UNDERBAR_JOINER.join(region));
+ } else {
+ buffer.append("und");
+ }
+ addItem(buffer, LstrType.script, "", "_", UNDERBAR_JOINER);
+ addItem(buffer, LstrType.region, "", "_", UNDERBAR_JOINER);
+ addItem(buffer, LstrType.variant, "", "_", UNDERBAR_JOINER);
+
+ return buffer.toString();
+ }
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+ addItem(buffer, LstrType.language, "", "L:", UNDERBAR_JOINER);
+ addItem(buffer, LstrType.script, ";", "S:", UNDERBAR_JOINER);
+ addItem(buffer, LstrType.region, ";", "R:", UNDERBAR_JOINER);
+ addItem(buffer, LstrType.variant, ";", "V:", UNDERBAR_JOINER);
+ return buffer.toString();
+ }
+
+ public void addItem(StringBuilder buffer, LstrType lstrType, String separator, String prefix, final Joiner dashJoiner) {
+ final Collection<String> region = data.get(lstrType);
+ if (!region.isEmpty()) {
+ if (buffer.length() > 0) {
+ buffer.append(separator);
+ }
+ buffer.append(prefix).append(dashJoiner.join(region));
+ }
+ }
+
+ public static XLanguageTag fromTag(LstrType lstrType, String tag) {
+ Multimap<LstrType,String> result = TreeMultimap.create();
+ LanguageTagParser source = new LanguageTagParser();
+ final boolean isLanguage = lstrType == LstrType.language;
+ String prefix = isLanguage ? "" : "und_";
+ try {
+ source.set(prefix + tag);
+ } catch (Exception e) {
+ return null; // skip ill-formed for now
+// if (lstrType == LstrType.region && tag.length() == 3) {
+// //result.put(LstrType.language, "und");
+// result.put(LstrType.region, tag);
+// } else {
+// result.put(LstrType.language, tag);
+// }
+// //System.out.println("ILLEGAL SOURCE\t" + lstrType + ":\t" + tag + " ⇒ " + result); // for debugging
+// return new XLanguageTag(result);
+ }
+ if (!source.getLanguage().isEmpty()
+ && !source.getLanguage().contains("und")) {
+ result.put(LstrType.language, source.getLanguage());
+ }
+ if (!source.getScript().isEmpty()) {
+ result.put(LstrType.script, source.getScript());
+ }
+ if (!source.getRegion().isEmpty()) {
+ result.put(LstrType.region, source.getRegion());
+ }
+ if (!source.getVariants().isEmpty()) {
+ result.putAll(LstrType.variant, source.getVariants());
+ }
+ return new XLanguageTag(result);
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return data.equals(((XLanguageTag)obj).data);
+ }
+ @Override
+ public int hashCode() {
+ return data.hashCode();
+ }
+ public XLanguageTag set(LstrType lstrType, String string) {
+ Multimap<LstrType,String> result = TreeMultimap.create(data);
+ if (lstrType != LstrType.variant) {
+ result.removeAll(lstrType);
+ }
+ result.put(lstrType, string);
+ return new XLanguageTag(result);
+ }
+
+ /**
+ * containsAll is used in matching a ReplacementRule.<br>
+ * It is here instead of on ReplacementRule so we can use in the denormalization utility used in testing.
+ */
+ public boolean containsAll(XLanguageTag type) {
+ for (LstrType lstrType : LSRV) {
+ final Collection<String> sources = get(lstrType);
+ final Collection<String> types = type.get(lstrType);
+ if (!sources.containsAll(types)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Once a rule matches, this actually does the replacement.<br>
+ * It is here instead of on ReplacementRule so we can use it in the denormalization utility used in testing.
+ */
+ public XLanguageTag replacePartsFrom(XLanguageTag typeParts, XLanguageTag replacementParts) {
+ Multimap<LstrType,String> result = TreeMultimap.create();
+ for (LstrType lstrType : LSRV) {
+ Collection<String> sources = get(lstrType);
+ Collection<String> types = typeParts.get(lstrType);
+ Collection<String> replacements = replacementParts.get(lstrType);
+ result.putAll(lstrType, sources);
+ if (!types.isEmpty() && !replacements.isEmpty()) {
+ removeAll(result, lstrType, types);
+ result.putAll(lstrType, replacements);
+ } else if (!types.isEmpty() && replacements.isEmpty()) {
+ removeAll(result, lstrType, types);
+ } else if (types.isEmpty() && !replacements.isEmpty()) {
+ if (sources.isEmpty()) {
+ result.putAll(lstrType, replacements);
+ }
+ } else {
+ // otherwise both empty, skip
+ }
+ }
+ return new XLanguageTag(result);
+ }
+ }
+
+ /**
+ * A representation of the alias data for Unicode Language Identifiers in the supplementalMetadata.txt file.
+ */
+
+ public static class ReplacementRule implements Comparable<ReplacementRule> {
+ private final XLanguageTag typeParts;
+ final XLanguageTag replacementParts;
+ final List<XLanguageTag> secondaryReplacementSet; // TODO, using this information in special cases to impute the best language according to LDML
+ final String reason;
+ final boolean regular;
+
+ private ReplacementRule(LstrType lstrType, String type, XLanguageTag typeParts, XLanguageTag replacementParts,
+ List<XLanguageTag> secondaryReplacementSet, String reason) {
+ this.typeParts = typeParts;
+ this.replacementParts = replacementParts;
+ this.secondaryReplacementSet = secondaryReplacementSet;
+ this.reason = reason;
+ this.regular = typeParts.keys().equals(replacementParts.keys()) &&
+ typeParts.get(LstrType.variant).size() == replacementParts.get(LstrType.variant).size();
+ }
+
+ static ReplacementRule from(LstrType lstrType, String type, List<String> replacement, String reason) {
+ XLanguageTag typeParts = XLanguageTag.fromTag(lstrType, type);
+ if (typeParts == null) {
+ return null; // skip ill-formed for now
+ }
+ XLanguageTag replacementParts = XLanguageTag.fromTag(lstrType, replacement.get(0));
+ if (replacementParts == null) {
+ return null; // skip ill-formed for now
+ }
+ List<XLanguageTag> secondaryReplacementSet = new ArrayList<>();
+ for (int i = 1; i < replacement.size(); ++i) {
+ secondaryReplacementSet.add(XLanguageTag.fromTag(lstrType, replacement.get(i)));
+ }
+ return new ReplacementRule(lstrType, type, typeParts, replacementParts, secondaryReplacementSet, reason);
+ }
+
+ @Override
+ public int compareTo(ReplacementRule o) {
+ return ComparisonChain.start()
+ .compare(-getType().keys().size(), -o.getType().keys().size()) // sort most keys first
+ .compare(getType().toString(), o.getType().toString())
+ .result();
+ }
+ @Override
+ public boolean equals(Object obj) {
+ return compareTo((ReplacementRule) obj) == 0;
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(getType());
+ }
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("type", getType())
+ .add("replacement", replacementParts)
+ .toString();
+ }
+ public XLanguageTag getType() {
+ return typeParts;
+ }
+ public XLanguageTag getReplacement() {
+ return replacementParts;
+ }
+ }
+
+ /**
+ * Utility to remove multiple items from Multimap
+ */
+ public static <K,V> Multimap<K, V> removeAll(Multimap<K, V> result, K key, Iterable<V> value) {
+ for (V type : value) {
+ result.remove(key, type);
+ }
+ return result;
+ }
+
+ private Set<ReplacementRule> rules = new TreeSet<>();
+ private Multimap<LstrType, String> inType = TreeMultimap.create();
+ private Map<LstrType, String> irrelevant = new TreeMap<>();
+
+ private void add(ReplacementRule replacementRule) {
+ getRules().add(replacementRule);
+ }
+
+ /**
+ * Canonicalize a Unicode Language Identifier (LSRV - language, script, region, variants)
+ * @param lstrType This is a special flag used to indicate which supplementalMetadata alias type the languageTag is from.
+ * That determines whether to extend the type and replacement to be full LSRVs if they are partial, by adding "und_", for example.
+ * @param languageTag May be partial, if the lstrType is not LstrType.language.
+ */
+ public String canonicalize(LstrType lstrType, String languageTag) {
+ XLanguageTag newTag = canonicalizeToX(XLanguageTag.fromTag(lstrType, languageTag), null);
+ return newTag.toString();
+ }
+
+ /**
+ * Canonicalize a Unicode Language Identifier (LSRV - language, script, region, variants) in the XLanguageTag format.
+ * Also returns the rules used in the canonicalization.<br>
+ * NOT OPTIMIZED: just uses a linear search for simplicity; production code would use more efficient mechanisms
+ */
+ public XLanguageTag canonicalizeToX(XLanguageTag fromTag, List<ReplacementRule> rulesUsed) {
+ if (rulesUsed != null) {
+ rulesUsed.clear();
+ }
+ XLanguageTag newTag = fromTag;
+ startAtTheTop:
+ while (true) {
+ for (ReplacementRule rule : getRules()) {
+ if (newTag.containsAll(rule.getType())) {
+ XLanguageTag temp = newTag.replacePartsFrom(rule.getType(), rule.getReplacement());
+ if (!temp.equals(newTag)) {
+ newTag = temp;
+ if (rulesUsed != null) {
+ rulesUsed.add(rule);
+ }
+ continue startAtTheTop;
+ }
+ }
+ }
+ return newTag;
+ }
+ }
+
+ /**
+ * Decanonicalize a Unicode Language Identifier (LSRV - language, script, region, variants) in the XLanguageTag format.
+ * Also returns the rules used in the canonicalization. Used in test case generation
+ * NOT OPTIMIZED: just for testing
+ */
+ public Set<XLanguageTag> decanonicalizeToX(XLanguageTag fromTag) {
+ Set<XLanguageTag> result = new HashSet<>();
+ result.add(fromTag);
+ Set<XLanguageTag> intermediate = new HashSet<>();
+ while (true) {
+ for (ReplacementRule rule : getRules()) {
+ if (!rule.getType().get(LstrType.variant).isEmpty()) {
+ continue;
+ }
+ for (XLanguageTag newTag : result) {
+ if (newTag.containsAll(rule.getReplacement())) { // reverse normal order
+ XLanguageTag changed = newTag.replacePartsFrom(rule.getReplacement(), rule.getType()); // reverse normal order
+ if (!intermediate.contains(changed)
+ && !result.contains(changed)) {
+ intermediate.add(changed);
+ }
+ }
+ }
+ }
+ if (intermediate.isEmpty()) {
+ result.remove(fromTag);
+ return result;
+ }
+ result.addAll(intermediate);
+ intermediate.clear();
+ }
+ }
+
+
+ /**
+ * Utility for getting a filtered list of rules, mostly useful in debugging.
+ */
+ public List<ReplacementRule> filter(LstrType lstrType, String value) {
+ List<ReplacementRule> result = new ArrayList<>();
+ for (ReplacementRule rule : getRules()) {
+ final Collection<String> items = rule.getType().get(lstrType);
+ if (value == null && !items.isEmpty()
+ || value != null && items.contains(value)) {
+ result.add(rule);
+ }
+ }
+ return result;
+ }
+
+ public static final LsrvCanonicalizer getInstance() {
+ return SINGLETON;
+ }
+ private static final LsrvCanonicalizer SINGLETON = load();
+
+ private static LsrvCanonicalizer load() {
+ SupplementalDataInfo SDI = CLDRConfig.getInstance().getSupplementalDataInfo();
+ Map<String, Map<String, R2<List<String>, String>>> aliases = SDI.getLocaleAliasInfo();
+ // type -> tag -> , like "language" -> "sh" -> <{"sr_Latn"}, reason>
+
+ LsrvCanonicalizer rrs = new LsrvCanonicalizer();
+ for (Entry<String, Map<String, R2<List<String>, String>>> typeTagReplacement : aliases.entrySet()) {
+ String type = typeTagReplacement.getKey();
+ if (type.contains("-")) {
+ throw new IllegalArgumentException("Bad format for alias: should have _ instead of -.");
+ }
+ LstrType lstrType = LstrType.fromString(type);
+ if (!LSRV.contains(lstrType)) {
+ continue;
+ }
+ for (Entry<String, R2<List<String>, String>> tagReplacementReason : typeTagReplacement.getValue().entrySet()) {
+ String tag = tagReplacementReason.getKey();
+ if (tag.contains("-")) {
+ throw new IllegalArgumentException("Bad format for alias: should have _ instead of -.");
+ }
+ List<String> replacement = tagReplacementReason.getValue().get0();
+ if (replacement == null) {
+ System.out.println("No replacement: " + tagReplacementReason);
+ continue;
+ }
+ String reason = tagReplacementReason.getValue().get1();
+ final ReplacementRule replacementRule = ReplacementRule.from(lstrType, tag, replacement, reason);
+ if (replacementRule == null) {
+ // System.out.println("No rule: " + tagReplacementReason);
+ continue;
+ }
+ rrs.add(replacementRule);
+ }
+ }
+ rrs.rules = ImmutableSet.copyOf(rrs.rules);
+ for (ReplacementRule rule : rrs.rules) {
+ XLanguageTag type = rule.getType();
+ XLanguageTag replacement = rule.getReplacement();
+ for (LstrType lstrType : LsrvCanonicalizer.LSRV) {
+ rrs.inType.putAll(lstrType, type.get(lstrType));
+ rrs.inType.putAll(lstrType, replacement.get(lstrType));
+ }
+ }
+ rrs.inType = ImmutableMultimap.copyOf(rrs.inType);
+
+ for (LstrType lstrType : LsrvCanonicalizer.LSRV) {
+ Set<String> all = new LinkedHashSet<>(Validity.getInstance().getStatusToCodes(lstrType).get(Validity.Status.regular));
+ all.removeAll(rrs.inType.get(lstrType));
+ if (lstrType == LstrType.variant && all.contains("fonipa")) {
+ rrs.irrelevant.put(lstrType, "fonipa");
+ } else {
+ rrs.irrelevant.put(lstrType, all.iterator().next());
+ }
+ }
+ rrs.irrelevant = ImmutableMap.copyOf(rrs.irrelevant);
+ return rrs;
+ }
+
+ /**
+ * Returns the set of all the Replacement rules in the canonicalizer.
+ */
+ public Set<ReplacementRule> getRules() {
+ return rules;
+ }
+
+ /**
+ * Types of test data
+ */
+ public enum TestDataTypes {explicit, fromAliases, decanonicalized, withIrrelevants}
+
+ /**
+ * Returns test data for the rules, used to generate test data files.
+ * @param testDataTypes if null, returns all the data; otherwise the specified set.
+ * @return
+ */
+ public Map<TestDataTypes,Map<String, String>> getTestData(Set<TestDataTypes> testDataTypes) {
+ Map<TestDataTypes,Map<String, String>> result = new TreeMap<>();
+
+ if (testDataTypes == null) {
+ testDataTypes = EnumSet.allOf(TestDataTypes.class);
+ }
+ Set<String> allToTest = new TreeSet<>();
+ if (testDataTypes.contains(TestDataTypes.explicit)) {
+ Map<String, String> testData2 = new TreeMap<>();
+ String[][] tests = {
+ {"hye_arevmda", "hyw"},
+ {"art_lojban", "jbo"},
+ {"en_arevela", "en"},
+ {"hy_arevela", "hy"},
+ {"en_arevmda_arevela", "en"},
+ {"hy_arevmda", "hyw"},
+ {"hy_arevmda_arevela", "hyw"},
+ {"en_lojban", "en"},
+ {"en_US_polytoni", "en_US_polyton"},
+ {"en_US_heploc", "en_US_alalc97"},
+ {"en_US_aaland", "en_US"},
+ {"en_aaland", "en_AX"},
+ {"no_nynorsk_bokmal", "nb"},
+ {"no_bokmal_nynorsk", "nb"},
+ {"zh_guoyu_hakka_xiang", "hak"},
+ {"zh_hakka_xiang", "hak"},
+ };
+ for (String row[] : tests) {
+ String toTest = row[0];
+ String expected = row[1];
+ testData2.put(toTest, expected);
+ }
+ allToTest.addAll(testData2.keySet());
+ result.put(TestDataTypes.explicit, ImmutableMap.copyOf(testData2));
+ }
+
+ if (testDataTypes.contains(TestDataTypes.fromAliases)) {
+ Map<String, String> testData2 = new TreeMap<>();
+ for (ReplacementRule rule : getRules()) {
+ String toTest = rule.getType().toLocaleString();
+ String expected = rule.getReplacement().toLocaleString();
+ if (!allToTest.contains(toTest)) {
+ testData2.put(toTest,expected);
+ }
+ }
+ allToTest.addAll(testData2.keySet());
+ result.put(TestDataTypes.fromAliases, ImmutableMap.copyOf(testData2));
+ }
+
+ if (testDataTypes.contains(TestDataTypes.decanonicalized)) {
+ Map<String, String> testData2 = new TreeMap<>();
+ for (String testItem: allToTest) {
+ for (XLanguageTag decon : decanonicalizeToX(XLanguageTag.fromTag(LstrType.language, testItem))) {
+ XLanguageTag newTag = canonicalizeToX(decon, null);
+ final String toTest = decon.toLocaleString();
+ if (!allToTest.contains(toTest)) {
+ testData2.put(toTest, newTag.toLocaleString());
+ }
+ }
+ }
+ allToTest.addAll(testData2.keySet());
+ result.put(TestDataTypes.decanonicalized, ImmutableMap.copyOf(testData2));
+ }
+
+ if (testDataTypes.contains(TestDataTypes.withIrrelevants)) {
+ Map<String, String> testData2 = new TreeMap<>();
+ for (String testItem: allToTest) {
+ XLanguageTag fluffedUp = fluff(XLanguageTag.fromTag(LstrType.language, testItem), irrelevant);
+ XLanguageTag newTag = canonicalizeToX(fluffedUp, null);
+ final String toTest = fluffedUp.toLocaleString();
+ if (!allToTest.contains(toTest)) {
+ testData2.put(toTest, newTag.toLocaleString());
+ }
+ }
+ allToTest.addAll(testData2.keySet());
+ result.put(TestDataTypes.withIrrelevants, ImmutableMap.copyOf(testData2));
+ }
+
+ result = ImmutableMap.copyOf(result);
+ return result;
+ }
+
+ private static XLanguageTag fluff(XLanguageTag type, Map<LstrType, String> toAddIfMissing) {
+ XLanguageTag newTag = type;
+ for (LstrType lstrType : LsrvCanonicalizer.LSRV) {
+ if (type.get(lstrType).isEmpty() || lstrType == LstrType.variant) {
+ newTag = newTag.set(lstrType, toAddIfMissing.get(lstrType));
+ }
+ }
+ return newTag;
+ }
+
+ /**
+ * Returns all the fields used in the type attribute of the alias rule.
+ */
+ public Collection<String> getInType(LstrType language) {
+ return inType.get(language);
+ }
+
+ /**
+ * Returns some sample fields that do not appear in the type attribute of the alias rule, used for testing.
+ */
+ public String getIrrelevantField(LstrType language) {
+ return irrelevant.get(language);
+ }
+
+}
diff --git a/tools/java/org/unicode/cldr/util/MapComparator.java b/tools/java/org/unicode/cldr/util/MapComparator.java
index 538a42d..0095413 100644
--- a/tools/java/org/unicode/cldr/util/MapComparator.java
+++ b/tools/java/org/unicode/cldr/util/MapComparator.java
@@ -28,8 +28,8 @@
{
uca.setNumericCollation(true);
}
- private Map<K, Integer> ordering = new TreeMap<K, Integer>(); // maps from name to rank
- private List<K> rankToName = new ArrayList<K>();
+ private Map<K, Integer> ordering = new TreeMap<>(); // maps from name to rank
+ private List<K> rankToName = new ArrayList<>();
private boolean errorOnMissing = true;
private volatile boolean locked = false;
private int before = 1;
@@ -121,6 +121,7 @@
private static final UnicodeSet numbers = new UnicodeSet("[\\-0-9.]").freeze();
+ @Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compare(K a, K b) {
if (false && (a.equals("lines") || b.equals("lines"))) {
@@ -192,6 +193,7 @@
return ((Comparable) a).compareTo(b);
}
+ @Override
public String toString() {
StringBuffer buffer = new StringBuffer();
boolean isFirst = true;
@@ -211,6 +213,7 @@
*
* @see com.ibm.icu.dev.test.util.Freezeble
*/
+ @Override
public boolean isFrozen() {
return locked;
}
@@ -220,6 +223,7 @@
*
* @see com.ibm.icu.dev.test.util.Freezeble
*/
+ @Override
public MapComparator<K> freeze() {
locked = true;
return this;
@@ -230,6 +234,7 @@
*
* @see com.ibm.icu.dev.test.util.Freezeble
*/
+ @Override
@SuppressWarnings("unchecked")
public MapComparator<K> cloneAsThawed() {
try {
@@ -242,7 +247,7 @@
throw new InternalError("should never happen");
}
}
-
+
public int getOrdering(K item) {
Integer result = ordering.get(item);
return result == null ? -1 : result;
diff --git a/tools/java/org/unicode/cldr/util/MatchValue.java b/tools/java/org/unicode/cldr/util/MatchValue.java
index 6a54b68..758524b 100644
--- a/tools/java/org/unicode/cldr/util/MatchValue.java
+++ b/tools/java/org/unicode/cldr/util/MatchValue.java
@@ -1,7 +1,7 @@
package org.unicode.cldr.util;
import java.text.ParseException;
-import java.util.ArrayList;
+import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
@@ -23,7 +23,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R2;
@@ -34,10 +33,16 @@
import com.ibm.icu.util.VersionInfo;
public abstract class MatchValue implements Predicate<String> {
+ public static final String DEFAULT_SAMPLE = "❓";
+
@Override
public abstract boolean is(String item);
public abstract String getName();
+ public String getSample() {
+ return DEFAULT_SAMPLE;
+ }
+
@Override
public String toString() {
return getName();
@@ -60,13 +65,13 @@
case "set":
result = SetMatchValue.of(subargument);
break;
- case "validity":
+ case "validity":
result = ValidityMatchValue.of(subargument);
break;
- case "bcp47":
+ case "bcp47":
result = Bcp47MatchValue.of(subargument);
break;
- case "range":
+ case "range":
result = RangeMatchValue.of(subargument);
break;
case "literal":
@@ -90,7 +95,7 @@
case "unicodeset":
result = UnicodeSpanMatchValue.of(subargument);
break;
- default:
+ default:
throw new IllegalArgumentException("Illegal/Unimplemented match type: " + originalArg);
}
if (!originalArg.equals(result.getName())) {
@@ -125,16 +130,21 @@
return false;
}
return lang.is(ltp.getLanguage())
- && (ltp.getScript().isEmpty()
+ && (ltp.getScript().isEmpty()
|| script.is(ltp.getScript()))
- && (ltp.getRegion().isEmpty()
+ && (ltp.getRegion().isEmpty()
|| region.is(ltp.getRegion()))
- && (ltp.getVariants().isEmpty()
+ && (ltp.getVariants().isEmpty()
|| and(variant,ltp.getVariants()))
&& ltp.getExtensions().isEmpty()
&& ltp.getLocaleExtensions().isEmpty()
;
- }
+ }
+
+ @Override
+ public String getSample() {
+ return "de";
+ }
}
// TODO remove these if possible — ticket/10120
@@ -222,8 +232,8 @@
@Override
public String getName() {
- return "validity/"
- + (shortId ? "short-" : "") + type.toString()
+ return "validity/"
+ + (shortId ? "short-" : "") + type.toString()
+ (enumParser.isAll(statuses) ? "" : "/" + enumParser.format(statuses));
}
@@ -254,7 +264,7 @@
if (shortId) {
typeName = typeName.substring(6);
}
- LstrType type = LstrType.valueOf(typeName);
+ LstrType type = LstrType.fromString(typeName);
return new ValidityMatchValue(type, statuses, shortId);
}
@@ -262,21 +272,21 @@
public boolean is(String item) {
// TODO handle deprecated
switch(type) {
- case script:
+ case script:
if (SCRIPT_HACK.contains(item)) {
- return true;
+ return true;
}
break;
- case variant:
+ case variant:
if (VARIANT_HACK.contains(item)) {
- return true;
+ return true;
}
- item = item.toLowerCase(Locale.ROOT);
+ item = item.toLowerCase(Locale.ROOT);
break;
- case language:
- item = item.equals("root") ? "und" : item;
+ case language:
+ item = item.equals("root") ? "und" : item;
break;
- case unit:
+ case unit:
if (shortId) {
if (shortCodeToStatus == null) { // lazy evaluation to avoid circular dependencies
Map<String, Status> _shortCodeToStatus = new TreeMap<>();
@@ -301,6 +311,11 @@
final Status status = Validity.getInstance().getCodeToStatus(type).get(item);
return status != null && statuses.contains(status);
}
+
+ @Override
+ public String getSample() {
+ return Validity.getInstance().getCodeToStatus(type).keySet().iterator().next();
+ }
}
static public class Bcp47MatchValue extends MatchValue {
@@ -399,6 +414,12 @@
valid.addAll(aliases);
}
}
+ @Override
+ public String getSample() {
+ is("X"); // force load data
+ return valid == null ? "XX"
+ : valid.iterator().next();
+ }
}
static final Splitter RANGE = Splitter.on('~').trimResults();
@@ -441,6 +462,10 @@
}
return start <= value && value <= end;
}
+ @Override
+ public String getSample() {
+ return String.valueOf((int)(start + end)/2);
+ }
}
static final Splitter LIST = Splitter.on(", ").trimResults();
@@ -451,7 +476,7 @@
@Override
public String getName() {
- return "literal/" + CollectionUtilities.join(items, ", ");
+ return "literal/" + Joiner.on(", ").join(items);
}
private LiteralMatchValue(String key) {
@@ -466,6 +491,11 @@
public boolean is(String item) {
return items.contains(item);
}
+
+ @Override
+ public String getSample() {
+ return items.iterator().next();
+ }
}
static public class RegexMatchValue extends MatchValue {
@@ -588,6 +618,11 @@
public boolean is(String items) {
return and(subtest,SPACE_SPLITTER.split(items));
}
+
+ @Override
+ public String getSample() {
+ return subtest.getSample();
+ }
}
static final Splitter BARS_SPLITTER = Splitter.on("||").omitEmptyStrings();
@@ -596,12 +631,12 @@
final List<MatchValue> subtests;
private OrMatchValue(Iterator<MatchValue> iterator) {
- this.subtests = ImmutableList.copyOf(CollectionUtilities.addAll(iterator, new ArrayList<>()));
+ this.subtests = ImmutableList.copyOf(iterator);
}
@Override
public String getName() {
- return "or/"+ CollectionUtilities.join(subtests, "||");
+ return "or/"+ Joiner.on("||").join(subtests);
}
public static OrMatchValue of(String key) {
@@ -621,13 +656,25 @@
}
return false;
}
+ @Override
+ public String getSample() {
+ for (MatchValue subtest : subtests) {
+ String result = subtest.getSample();
+ if (!result.equals(DEFAULT_SAMPLE)) {
+ return result;
+ }
+ }
+ return DEFAULT_SAMPLE;
+ }
}
static public class TimeMatchValue extends MatchValue {
+ final String sample;
final SimpleDateFormat formatter;
public TimeMatchValue(String key) {
formatter = new SimpleDateFormat(key,ULocale.ROOT);
+ sample = formatter.format(new Date());
}
@Override
@@ -648,13 +695,19 @@
return false;
}
}
+ @Override
+ public String getSample() {
+ return sample;
+ }
}
static public class UnicodeSpanMatchValue extends MatchValue {
+ final String sample;
final UnicodeSet uset;
public UnicodeSpanMatchValue(String key) {
uset = new UnicodeSet(key);
+ sample = new StringBuilder().appendCodePoint(uset.getRangeStart(0)).toString();
}
@Override
@@ -670,6 +723,11 @@
public boolean is(String item) {
return uset.span(item, SpanCondition.CONTAINED) == item.length();
}
+
+ @Override
+ public String getSample() {
+ return sample;
+ }
}
}
diff --git a/tools/java/org/unicode/cldr/util/MergeLists.java b/tools/java/org/unicode/cldr/util/MergeLists.java
index e63a1f9..0b26860 100644
--- a/tools/java/org/unicode/cldr/util/MergeLists.java
+++ b/tools/java/org/unicode/cldr/util/MergeLists.java
@@ -12,7 +12,7 @@
public class MergeLists<T> {
- Collection<Collection<T>> source = new ArrayList<Collection<T>>();
+ Collection<Collection<T>> source = new ArrayList<>();
Set<T> orderedWorkingSet;
public MergeLists() {
@@ -27,7 +27,7 @@
if (orderedItems.size() == 0) { // skip empties
return this;
}
- final LinkedHashSet<T> linkedHashSet = new LinkedHashSet<T>(orderedItems);
+ final LinkedHashSet<T> linkedHashSet = new LinkedHashSet<>(orderedItems);
if (linkedHashSet.size() != orderedItems.size()) {
throw new IllegalArgumentException("Multiple items in ordering!");
}
@@ -48,7 +48,7 @@
}
public List<T> merge() {
- List<T> result = new ArrayList<T>();
+ List<T> result = new ArrayList<>();
for (Collection<T> sublist : source) {
orderedWorkingSet.addAll(sublist);
@@ -58,11 +58,11 @@
// this is slower, but puts things into as much of the order specified as possible
// could be optimized further, but we don't care that much
- Set<T> first = new LinkedHashSet<T>();
+ Set<T> first = new LinkedHashSet<>();
while (orderedWorkingSet.size() != 0) {
getFirsts(first);
if (first.size() == 0) {
- Map<T, Collection<T>> reasons = new LinkedHashMap<T, Collection<T>>();
+ Map<T, Collection<T>> reasons = new LinkedHashMap<>();
getFirsts(first, reasons);
throw new IllegalArgumentException(
"Inconsistent requested ordering: cannot merge if we have [...A...B...] and [...B...A...]: "
@@ -78,7 +78,7 @@
}
public static <T> boolean hasConsistentOrder(Collection<T> a, Collection<T> b) {
- LinkedHashSet<T> remainder = new LinkedHashSet<T>(a);
+ LinkedHashSet<T> remainder = new LinkedHashSet<>(a);
remainder.retainAll(b);
if (remainder.size() == 0) {
return true;
diff --git a/tools/java/org/unicode/cldr/util/MultiComparator.java b/tools/java/org/unicode/cldr/util/MultiComparator.java
index 14319ae..6f4b8d4 100644
--- a/tools/java/org/unicode/cldr/util/MultiComparator.java
+++ b/tools/java/org/unicode/cldr/util/MultiComparator.java
@@ -17,10 +17,11 @@
}
/* Lexigraphic compare. Returns the first difference
- * @return zero if equal. Otherwise +/- (i+1)
+ * @return zero if equal. Otherwise +/- (i+1)
* where i is the index of the first comparator finding a difference
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
+ @Override
public int compare(T arg0, T arg1) {
for (int i = 0; i < comparators.length; ++i) {
int result = comparators[i].compare(arg0, arg1);
diff --git a/tools/java/org/unicode/cldr/util/Organization.java b/tools/java/org/unicode/cldr/util/Organization.java
index f5fc148..0ba6fb8 100644
--- a/tools/java/org/unicode/cldr/util/Organization.java
+++ b/tools/java/org/unicode/cldr/util/Organization.java
@@ -43,6 +43,7 @@
openoffice_org("Open Office"),
oracle("Oracle", "sun", "Sun Micro"),
pakistan("Pakistan"),
+ rodakych("Rodakych", "Nigerian Pidgin"),
rumantscha("Lia Rumantscha"),
sil("SIL", "SIL International"),
srilanka("Sri Lanka ICTA", "Sri Lanka"),
@@ -68,7 +69,7 @@
static Map<String, Organization> OrganizationNameMap;
static {
- OrganizationNameMap = new HashMap<String, Organization>();
+ OrganizationNameMap = new HashMap<>();
for (Organization x : values()) {
OrganizationNameMap.put(x.displayName.toLowerCase().replace('-', '_').replace('.', '_'), x);
for (String name : x.names) {
diff --git a/tools/java/org/unicode/cldr/util/Pair.java b/tools/java/org/unicode/cldr/util/Pair.java
index 975e432..9b76c7e 100644
--- a/tools/java/org/unicode/cldr/util/Pair.java
+++ b/tools/java/org/unicode/cldr/util/Pair.java
@@ -22,7 +22,7 @@
private boolean frozen;
public static <T extends Comparable<T>, U extends Comparable<U>> Pair<T, U> of(T arg0, U arg1) {
- return new Pair<T, U>(arg0, arg1);
+ return new Pair<>(arg0, arg1);
}
public static <T extends Comparable<T>, U extends Comparable<U>> Pair<T, U> ofFrozen(T arg0, U arg1) {
@@ -67,10 +67,12 @@
public Pair() {
}
+ @Override
public int hashCode() {
return Utility.checkHash(first) * 37 + Utility.checkHash(second);
}
+ @Override
public boolean equals(Object other) {
try {
Pair<?, ?> that = (Pair<?, ?>) other;
@@ -80,12 +82,14 @@
}
}
+ @Override
public int compareTo(Pair<T, U> that) {
int trial = Utility.checkCompare(first, that.first);
if (trial != 0) return trial;
return Utility.checkCompare(second, that.second);
}
+ @Override
public Object clone() {
if (frozen) return this;
try {
@@ -95,20 +99,24 @@
}
}
+ @Override
public String toString() {
return '(' + (first == null ? "null" : first.toString())
+ ',' + (second == null ? "null" : second.toString()) + ')';
}
+ @Override
public boolean isFrozen() {
return frozen;
}
+ @Override
public Pair<T, U> freeze() {
frozen = true;
return this;
}
+ @Override
public Object cloneAsThawed() {
try {
Pair<?, ?> result = (Pair<?, ?>) super.clone();
diff --git a/tools/java/org/unicode/cldr/util/PathChecker.java b/tools/java/org/unicode/cldr/util/PathChecker.java
new file mode 100644
index 0000000..3bfc816
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/PathChecker.java
@@ -0,0 +1,102 @@
+package org.unicode.cldr.util;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.unicode.cldr.util.DtdData.ValueStatus;
+
+import com.ibm.icu.impl.Row;
+import com.ibm.icu.impl.Row.R3;
+
+/**
+ * Checks that an {element,attribute,attributeValue} tuple is valid, caching the results.
+ */
+public class PathChecker {
+ // caches for speed
+ private static final Map<XPathParts, Boolean> seen = new ConcurrentHashMap<>();
+ private static Map<DtdType, Map<String,Map<String,Map<String,ValueStatus>>>> seenEAV = new ConcurrentHashMap<>();
+
+ /**
+ * Returns true if the path is ok. The detailed errors (if any) are set only the first time the path is seen!
+ */
+ public boolean checkPath(String path) {
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ return checkPath(parts, null);
+ }
+
+ /**
+ * Returns true if the path is ok. The detailed errors (if any) are set only the first time the path is seen!
+ */
+
+ public boolean checkPath(String path, Map<Row.R3<String,String,String>, ValueStatus> errors) {
+ XPathParts parts = XPathParts.getFrozenInstance(path);
+ return checkPath(parts, errors);
+ }
+
+ /**
+ * Returns true if the path is ok. The detailed errors (if any) are set only the first time the path is seen!
+ */
+ public boolean checkPath(XPathParts parts, Map<Row.R3<String, String, String>, ValueStatus> errors) {
+ Boolean seenAlready = seen.get(parts);
+ if (seenAlready != null) {
+ return seenAlready;
+ }
+ DtdData dtdData = parts.getDtdData();
+ boolean ok = true;
+ if (errors != null) {
+ errors.clear();
+ }
+
+ for (int elementIndex = 0; elementIndex < parts.size(); ++elementIndex) {
+ String element = parts.getElement(elementIndex);
+ for (Entry<String, String> entry : parts.getAttributes(elementIndex).entrySet()) {
+ String attribute = entry.getKey();
+ String attrValue = entry.getValue();
+ ok &= checkAttribute(dtdData, element, attribute, attrValue, errors);
+ }
+ }
+ seen.put(parts, ok);
+ return ok;
+ }
+
+ private boolean checkAttribute(DtdData dtdData, String element, String attribute, String attrValue, Map<R3<String, String, String>, ValueStatus> errors) {
+ // check if we've seen the EAV yet
+ // we don't need to synchronize because a miss isn't serious
+ Map<String, Map<String, Map<String, ValueStatus>>> elementToAttrToAttrValueToStatus = seenEAV.get(dtdData.dtdType);
+ if (elementToAttrToAttrValueToStatus == null) {
+ Map<String, Map<String, Map<String, ValueStatus>>> subAlready = seenEAV.putIfAbsent(dtdData.dtdType, elementToAttrToAttrValueToStatus = new ConcurrentHashMap<>());
+ if (subAlready != null) {
+ elementToAttrToAttrValueToStatus = subAlready; // discards empty map
+ }
+ }
+ Map<String, Map<String, ValueStatus>> attrToAttrValueToStatus = elementToAttrToAttrValueToStatus.get(element);
+ if (attrToAttrValueToStatus == null) {
+ Map<String, Map<String, ValueStatus>> subAlready = elementToAttrToAttrValueToStatus.putIfAbsent(element, attrToAttrValueToStatus = new ConcurrentHashMap<>());
+ if (subAlready != null) {
+ attrToAttrValueToStatus = subAlready; // discards empty map
+ }
+ }
+ Map<String, ValueStatus> attrValueToStatus = attrToAttrValueToStatus.get(attribute);
+ if (attrValueToStatus == null) {
+ Map<String, ValueStatus> setAlready = attrToAttrValueToStatus.putIfAbsent(attribute, attrValueToStatus = new ConcurrentHashMap<>());
+ if (setAlready != null) {
+ attrValueToStatus = setAlready; // discards empty map
+ }
+ }
+ ValueStatus valueStatus = attrValueToStatus.get(attrValue);
+ if (valueStatus == null) {
+ valueStatus = dtdData.getValueStatus(element, attribute, attrValue);
+ if (valueStatus != ValueStatus.valid) {
+ // Set breakpoint here for debugging (referenced from http://cldr.unicode.org/development/testattributevalues)
+ dtdData.getValueStatus(element, attribute, attrValue);
+ }
+ attrValueToStatus.putIfAbsent(attrValue, valueStatus);
+ }
+
+ if (errors != null && valueStatus != ValueStatus.valid) {
+ errors.put(Row.of(element, attribute, attrValue), valueStatus);
+ }
+ return valueStatus != null;
+ }
+}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/PathDescription.java b/tools/java/org/unicode/cldr/util/PathDescription.java
index 65bb743..34bb50d 100644
--- a/tools/java/org/unicode/cldr/util/PathDescription.java
+++ b/tools/java/org/unicode/cldr/util/PathDescription.java
@@ -24,7 +24,7 @@
}
// BE sure to sync with the list in xmbSkip!
- public static final Set<String> EXTRA_LANGUAGES = new TreeSet<String>(
+ public static final Set<String> EXTRA_LANGUAGES = new TreeSet<>(
Arrays
.asList(
"ach|af|ak|ak|am|ar|az|be|bem|bg|bh|bn|br|bs|ca|chr|ckb|co|crs|cs|cy|da|de|de_AT|de_CH|ee|el|en|en_AU|en_CA|en_GB|en_US|eo|es|es_419|es_ES|et|eu|fa|fi|fil|fo|fr|fr_CA|fr_CH|fy|ga|gaa|gd|gl|gn|gsw|gu|ha|haw|he|hi|hr|ht|hu|hy|ia|id|ig|io|is|it|ja|jv|ka|kg|kk|km|kn|ko|kri|ku|ky|la|lg|ln|lo|loz|lt|lua|lv|mfe|mg|mi|mk|ml|mn|mr|ms|mt|my|nb|ne|nl|nl_BE|nn|nso|ny|nyn|oc|om|or|pa|pcm|pl|ps|pt|pt_BR|pt_PT|qu|rm|rn|ro|ro|ro_MD|ru|rw|sd|si|sk|sl|sn|so|sq|sr|sr_Latn|sr_ME|st|su|sv|sw|ta|te|tg|th|ti|tk|tlh|tn|to|tr|tt|tum|ug|uk|und|ur|uz|vi|wo|xh|yi|yo|zh|zh_Hans|zh_Hant|zh_HK|zu|zxx"
@@ -51,7 +51,7 @@
private Matcher metazoneMatcher = METAZONE_PATTERN.matcher("");
private String starredPathOutput;
- private Output<String[]> pathArguments = new Output<String[]>();
+ private Output<String[]> pathArguments = new Output<>();
private EnumSet<Status> status = EnumSet.noneOf(Status.class);
public static final String MISSING_DESCRIPTION = "Before translating, please see http://cldr.org/translation.";
@@ -62,8 +62,8 @@
Map<String, List<Set<String>>> starredPaths,
ErrorHandling errorHandling) {
this.english = english;
- this.extras = extras == null ? new HashMap<String, String>() : extras;
- this.starredPaths = starredPaths == null ? new HashMap<String, List<Set<String>>>() : starredPaths;
+ this.extras = extras == null ? new HashMap<>() : extras;
+ this.starredPaths = starredPaths == null ? new HashMap<>() : starredPaths;
allMetazones = supplementalDataInfo.getAllMetazones();
this.errorHandling = errorHandling;
}
@@ -160,7 +160,7 @@
length = length.equals("long") ? "" : "abbreviated ";
code = code + ", " + length + daylightType + " form";
} else if (type.equals("timezone")) {
- String country = (String) ZONE2COUNTRY.get(code);
+ String country = ZONE2COUNTRY.get(code);
int lastSlash = code.lastIndexOf('/');
String codeName = lastSlash < 0 ? code : code.substring(lastSlash + 1).replace('_', ' ');
@@ -240,7 +240,7 @@
private List<String> addStarredInfo(Map<String, List<Set<String>>> starredPaths, String path) {
Matcher starAttributeMatcher = STAR_ATTRIBUTE_PATTERN.matcher(path);
StringBuilder starredPath = new StringBuilder();
- List<String> attributes = new ArrayList<String>();
+ List<String> attributes = new ArrayList<>();
int lastEnd = 0;
while (starAttributeMatcher.find()) {
int start = starAttributeMatcher.start(1);
@@ -257,12 +257,12 @@
List<Set<String>> attributeList = starredPaths.get(starredPathString);
if (attributeList == null) {
- starredPaths.put(starredPathString, attributeList = new ArrayList<Set<String>>());
+ starredPaths.put(starredPathString, attributeList = new ArrayList<>());
}
int i = 0;
for (String attribute : attributes) {
if (attributeList.size() <= i) {
- TreeSet<String> subset = new TreeSet<String>();
+ TreeSet<String> subset = new TreeSet<>();
subset.add(attribute);
attributeList.add(subset);
} else {
diff --git a/tools/java/org/unicode/cldr/util/PathHeader.java b/tools/java/org/unicode/cldr/util/PathHeader.java
index 2568d4c..5bbabf7 100644
--- a/tools/java/org/unicode/cldr/util/PathHeader.java
+++ b/tools/java/org/unicode/cldr/util/PathHeader.java
@@ -25,7 +25,6 @@
import org.unicode.cldr.util.With.SimpleIterator;
import com.google.common.base.Splitter;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
import com.ibm.icu.lang.UCharacter;
@@ -78,7 +77,7 @@
LTR_ALWAYS
}
- private static EnumNames<SectionId> SectionIdNames = new EnumNames<SectionId>();
+ private static EnumNames<SectionId> SectionIdNames = new EnumNames<>();
/**
* The Section for a path. Don't change these without committee buy-in. The
@@ -97,12 +96,13 @@
return SectionIdNames.forString(name);
}
+ @Override
public String toString() {
return SectionIdNames.toString(this);
}
}
- private static EnumNames<PageId> PageIdNames = new EnumNames<PageId>();
+ private static EnumNames<PageId> PageIdNames = new EnumNames<>();
private static Relation<SectionId, PageId> SectionIdToPageIds = Relation.of(new TreeMap<SectionId, Set<PageId>>(),
TreeSet.class);
@@ -143,7 +143,7 @@
public enum PageId {
Alphabetic_Information(SectionId.Core_Data, "Alphabetic Information"),
Numbering_Systems(SectionId.Core_Data, "Numbering Systems"),
- LinguisticElements(SectionId.Core_Data, "Linguistic Elements"),
+ LinguisticElements(SectionId.Core_Data, "Linguistic Elements"),
Locale_Name_Patterns(SectionId.Locale_Display_Names, "Locale Name Patterns"),
Languages_A_D(SectionId.Locale_Display_Names, "Languages (A-D)"),
@@ -161,7 +161,7 @@
T_Oceania( SectionId.Locale_Display_Names, "Territories (Oceania)"),
Locale_Variants(SectionId.Locale_Display_Names, "Locale Variants"),
Keys( SectionId.Locale_Display_Names),
-
+
Fields(SectionId.DateTime),
Gregorian(SectionId.DateTime),
Generic( SectionId.DateTime),
@@ -177,7 +177,7 @@
Japanese(SectionId.DateTime),
Persian( SectionId.DateTime),
Minguo(SectionId.DateTime),
-
+
Timezone_Display_Patterns(SectionId.Timezones, "Timezone Display Patterns"),
NAmerica(SectionId.Timezones, "North America"),
SAmerica( SectionId.Timezones, "South America"),
@@ -194,13 +194,12 @@
Oceania(SectionId.Timezones),
UnknownT( SectionId.Timezones, "Unknown Region"),
Overrides(SectionId.Timezones),
-
+
Symbols( SectionId.Numbers),
- MinimalPairs(SectionId.Numbers, "Minimal Pairs"),
Number_Formatting_Patterns( SectionId.Numbers, "Number Formatting Patterns"),
Compact_Decimal_Formatting( SectionId.Numbers, "Compact Decimal Formatting"),
Compact_Decimal_Formatting_Other( SectionId.Numbers, "Compact Decimal Formatting (Other Numbering Systems)"),
-
+
Measurement_Systems( SectionId.Units, "Measurement Systems"),
Duration( SectionId.Units),
Graphics( SectionId.Units),
@@ -216,18 +215,20 @@
Coordinates( SectionId.Units),
OtherUnits( SectionId.Units, "Other Units"),
CompoundUnits( SectionId.Units, "Compound Units"),
+
+
Displaying_Lists( SectionId.Misc, "Displaying Lists"),
-
+ MinimalPairs(SectionId.Misc, "Minimal Pairs"),
Transforms( SectionId.Misc),
-
+
Identity( SectionId.Special),
Version( SectionId.Special),
Suppress( SectionId.Special),
Deprecated( SectionId.Special),
Unknown( SectionId.Special),
-
+
C_NAmerica( SectionId.Currencies, "North America (C)"),
- //need to add (C) to differentiate from Timezone territories
+ //need to add (C) to differentiate from Timezone territories
C_SAmerica(SectionId.Currencies, "South America (C)"),
C_NWEurope(SectionId.Currencies, "Northern/Western Europe"),
C_SEEurope(SectionId.Currencies, "Southern/Eastern Europe"),
@@ -244,11 +245,11 @@
C_Oceania(SectionId.Currencies, "Oceania (C)"),
C_Unknown(SectionId.Currencies, "Unknown Region (C)"),
- // BCP47
+ // BCP47
u_Extension(SectionId.BCP47),
t_Extension(SectionId.BCP47),
- // Supplemental
+ // Supplemental
Alias(SectionId.Supplemental),
IdValidity(SectionId.Supplemental),
Locale(SectionId.Supplemental),
@@ -277,10 +278,10 @@
RBNF( SectionId.Supplemental),
Segmentation(SectionId.Supplemental),
DayPeriod(SectionId.Supplemental),
-
+
Category(SectionId.Characters),
- // [Smileys, People, Animals & Nature, Food & Drink, Travel & Places, Activities, Objects, Symbols, Flags]
+ // [Smileys, People, Animals & Nature, Food & Drink, Travel & Places, Activities, Objects, Symbols, Flags]
Smileys(SectionId.Characters, "Smileys & Emotion"),
People(SectionId.Characters, "People & Body"),
Animals_Nature(SectionId.Characters, "Animals & Nature"),
@@ -321,6 +322,7 @@
*
* @return a page ID, such as 'Languages'
*/
+ @Override
public String toString() {
return PageIdNames.toString(this);
}
@@ -365,7 +367,7 @@
static final Map<String, String> metazoneToContinent = supplementalDataInfo
.getMetazoneToContinentMap();
static final StandardCodes standardCode = StandardCodes.make();
- static final Map<String, String> metazoneToPageTerritory = new HashMap<String, String>();
+ static final Map<String, String> metazoneToPageTerritory = new HashMap<>();
static {
Map<String, Map<String, String>> metazoneToRegionToZone = supplementalDataInfo.getMetazoneToRegionToZone();
for (Entry<String, Map<String, String>> metazoneEntry : metazoneToRegionToZone.entrySet()) {
@@ -424,16 +426,15 @@
}
/**
- * Return a factory for use in creating the headers. This should be cached.
- * The calls are thread-safe. The englishFile sets a static for now; after
- * the first time, null can be passed.
+ * Return a factory for use in creating the headers. This is cached after first use.
+ * The calls are thread-safe. Null gets the default (CLDRConfig) english file.
*
* @param englishFile
*/
public static Factory getFactory(CLDRFile englishFile) {
if (factorySingleton == null) {
if (englishFile == null) {
- throw new IllegalArgumentException("English CLDRFile must not be null");
+ englishFile = CLDRConfig.getInstance().getEnglish();
}
if (!englishFile.getLocaleID().equals(ULocale.ENGLISH.getBaseName())) {
throw new IllegalArgumentException("PathHeader's CLDRFile must be '" +
@@ -443,17 +444,18 @@
}
return factorySingleton;
}
-
+
/**
* Convenience method for common case. See {{@link #getFactory(CLDRFile)}}
*/
public static Factory getFactory() {
- return getFactory(CLDRConfig.getInstance().getEnglish());
+ return getFactory(null);
}
/**
* @deprecated
*/
+ @Deprecated
public String getSection() {
return sectionId.toString();
}
@@ -465,6 +467,7 @@
/**
* @deprecated
*/
+ @Deprecated
public String getPage() {
return pageId.toString();
}
@@ -611,24 +614,24 @@
PathHeader.class,
"data/PathHeader.txt");
// synchronized with lookup
- static final Output<String[]> args = new Output<String[]>();
+ static final Output<String[]> args = new Output<>();
// synchronized with lookup
- static final Counter<RawData> counter = new Counter<RawData>();
+ static final Counter<RawData> counter = new Counter<>();
// synchronized with lookup
- static final Map<RawData, String> samples = new HashMap<RawData, String>();
+ static final Map<RawData, String> samples = new HashMap<>();
// synchronized with lookup
static long order;
static SubstringOrder suborder;
- static final Map<String, PathHeader> cache = new HashMap<String, PathHeader>();
+ static final Map<String, PathHeader> cache = new HashMap<>();
// synchronized with cache
- static final Map<SectionId, Map<PageId, SectionPage>> sectionToPageToSectionPage = new EnumMap<SectionId, Map<PageId, SectionPage>>(
+ static final Map<SectionId, Map<PageId, SectionPage>> sectionToPageToSectionPage = new EnumMap<>(
SectionId.class);
static final Relation<SectionPage, String> sectionPageToPaths = Relation
.of(new TreeMap<SectionPage, Set<String>>(),
HashSet.class);
private static CLDRFile englishFile;
- private Set<String> matchersFound = new HashSet<String>();
+ private Set<String> matchersFound = new HashSet<>();
/**
* Create a factory for creating PathHeaders.
@@ -675,6 +678,7 @@
/**
* Return the PathHeader for a given path. Thread-safe.
*/
+ @Override
public PathHeader transform(String path) {
return fromPath(path, null);
}
@@ -713,7 +717,7 @@
throw new IllegalArgumentException();
}
}
- Output<Finder> matcherFound = new Output<Finder>();
+ Output<Finder> matcherFound = new Output<>();
RawData data = lookup.get(cleanPath, null, args, matcherFound, failures);
if (data == null) {
return null;
@@ -745,7 +749,7 @@
Map<PageId, SectionPage> pageToPathHeaders = sectionToPageToSectionPage
.get(result.sectionId);
if (pageToPathHeaders == null) {
- sectionToPageToSectionPage.put(result.sectionId, pageToPathHeaders = new EnumMap<PageId, SectionPage>(PageId.class));
+ sectionToPageToSectionPage.put(result.sectionId, pageToPathHeaders = new EnumMap<>(PageId.class));
}
SectionPage sectionPage = pageToPathHeaders.get(result.pageId);
if (sectionPage == null) {
@@ -802,6 +806,10 @@
public int hashCode() {
return sectionId.hashCode() ^ pageId.hashCode();
}
+ @Override
+ public String toString() {
+ return sectionId + " > " + pageId;
+ }
}
/**
@@ -822,7 +830,7 @@
* @target a collection where the paths are to be returned.
*/
public static Set<String> getCachedPaths(SectionId sectionId, PageId page) {
- Set<String> target = new HashSet<String>();
+ Set<String> target = new HashSet<>();
synchronized (cache) {
Map<PageId, SectionPage> pageToSectionPage = sectionToPageToSectionPage
.get(sectionId);
@@ -865,13 +873,14 @@
*
* @deprecated Use getSectionIdsToPageIds
*/
+ @Deprecated
public static LinkedHashMap<String, Set<String>> getSectionsToPages() {
- LinkedHashMap<String, Set<String>> sectionsToPages = new LinkedHashMap<String, Set<String>>();
+ LinkedHashMap<String, Set<String>> sectionsToPages = new LinkedHashMap<>();
for (PageId pageId : PageId.values()) {
String sectionId2 = pageId.getSectionId().toString();
Set<String> pages = sectionsToPages.get(sectionId2);
if (pages == null) {
- sectionsToPages.put(sectionId2, pages = new LinkedHashSet<String>());
+ sectionsToPages.put(sectionId2, pages = new LinkedHashSet<>());
}
pages.add(pageId.toString());
}
@@ -919,7 +928,7 @@
}
private static class ChronologicalOrder {
- private Map<String, Integer> map = new HashMap<String, Integer>();
+ private Map<String, Integer> map = new HashMap<>();
private String item;
private int order;
private ChronologicalOrder toClear;
@@ -1011,6 +1020,7 @@
*
* @deprecated
*/
+ @Deprecated
public class CounterData extends Row.R4<String, RawData, String, String> {
public CounterData(String a, RawData b, String c) {
super(a, b, c == null ? "no sample" : c, c == null ? "no sample" : fromPath(c)
@@ -1023,9 +1033,10 @@
*
* @deprecated
*/
+ @Deprecated
public Counter<CounterData> getInternalCounter() {
synchronized (lookup) {
- Counter<CounterData> result = new Counter<CounterData>();
+ Counter<CounterData> result = new Counter<>();
for (Map.Entry<Finder, RawData> foo : lookup) {
Finder finder = foo.getKey();
RawData data = foo.getValue();
@@ -1036,7 +1047,7 @@
}
}
- static Map<String, Transform<String, String>> functionMap = new HashMap<String, Transform<String, String>>();
+ static Map<String, Transform<String, String>> functionMap = new HashMap<>();
static String[] months = { "Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
@@ -1060,6 +1071,7 @@
// To change the order of items within a section or heading, set
// order/suborder to be the relative position of the current item.
functionMap.put("month", new Transform<String, String>() {
+ @Override
public String transform(String source) {
int m = Integer.parseInt(source);
order = m;
@@ -1067,12 +1079,14 @@
}
});
functionMap.put("count", new Transform<String, String>() {
+ @Override
public String transform(String source) {
suborder = new SubstringOrder(source);
return source;
}
});
functionMap.put("count2", new Transform<String, String>() {
+ @Override
public String transform(String source) {
int pos = source.indexOf('-');
source = pos + source.substring(pos);
@@ -1082,6 +1096,7 @@
}
});
functionMap.put("currencySymbol", new Transform<String, String>() {
+ @Override
public String transform(String source) {
order = 901;
if (source.endsWith("narrow")) {
@@ -1094,6 +1109,7 @@
}
});
functionMap.put("unitCount", new Transform<String, String>() {
+ @Override
public String transform(String source) {
String[] unitLengths = { "long", "short", "narrow" };
int pos = 9;
@@ -1109,6 +1125,7 @@
}
});
functionMap.put("day", new Transform<String, String>() {
+ @Override
public String transform(String source) {
int m = days.indexOf(source);
order = m;
@@ -1116,6 +1133,7 @@
}
});
functionMap.put("dayPeriod", new Transform<String, String>() {
+ @Override
public String transform(String source) {
try {
order = dayPeriods.getNumericOrder(source);
@@ -1136,6 +1154,7 @@
.put("iso8601", "ISO 8601")
.freeze();
+ @Override
public String transform(String source) {
String result = fixNames.get(source);
return result != null ? result : UCharacter.toTitleCase(source, null);
@@ -1143,6 +1162,7 @@
});
functionMap.put("calField", new Transform<String, String>() {
+ @Override
public String transform(String source) {
String[] fields = source.split(":", 3);
order = 0;
@@ -1226,11 +1246,13 @@
});
functionMap.put("titlecase", new Transform<String, String>() {
+ @Override
public String transform(String source) {
return UCharacter.toTitleCase(source, null);
}
});
functionMap.put("categoryFromScript", new Transform<String, String>() {
+ @Override
public String transform(String source) {
String script = hyphenSplitter.split(source);
Info info = ScriptMetadata.getInfo(script);
@@ -1249,6 +1271,7 @@
.put("cf", "Currency Format")
.freeze();
+ @Override
public String transform(String source) {
String fixedName = fixNames.get(source);
return fixedName != null ? fixedName : source;
@@ -1258,6 +1281,7 @@
char[] languageRangeStartPoints = { 'A', 'E', 'K', 'O', 'T' };
char[] languageRangeEndPoints = { 'D', 'J', 'N', 'S', 'Z' };
+ @Override
public String transform(String source0) {
char firstLetter = getEnglishFirstLetter(source0).charAt(0);
for (int i = 0; i < languageRangeStartPoints.length; i++) {
@@ -1270,11 +1294,13 @@
}
});
functionMap.put("firstLetter", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
return getEnglishFirstLetter(source0);
}
});
functionMap.put("languageSort", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
String languageOnlyPart;
int underscorePos = source0.indexOf("_");
@@ -1288,6 +1314,7 @@
}
});
functionMap.put("scriptFromLanguage", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
String language = hyphenSplitter.split(source0);
String script = likelySubtags.getLikelyScript(language);
@@ -1302,6 +1329,7 @@
});
functionMap.put("categoryFromTerritory",
catFromTerritory = new Transform<String, String>() {
+ @Override
public String transform(String source) {
String territory = getSubdivisionsTerritory(source, null);
String container = Containment.getContainer(territory);
@@ -1310,8 +1338,9 @@
}
});
functionMap.put("territorySection", new Transform<String, String>() {
- final Set<String> specialRegions = new HashSet<String>(Arrays.asList("EZ", "EU", "QO", "UN", "ZZ"));
+ final Set<String> specialRegions = new HashSet<>(Arrays.asList("EZ", "EU", "QO", "UN", "ZZ"));
+ @Override
public String transform(String source0) {
// support subdivisions
String theTerritory = getSubdivisionsTerritory(source0, null);
@@ -1327,7 +1356,7 @@
switch (theContinent) { // was Integer.valueOf
case "019": // Americas - For the territorySection, we just group North America & South America
final String subcontinent = Containment.getSubcontinent(theTerritory);
- theSubContinent = subcontinent.equals("005") ? "005" : "003"; // was Integer.valueOf(subcontinent) == 5
+ theSubContinent = subcontinent.equals("005") ? "005" : "003"; // was Integer.valueOf(subcontinent) == 5
return "Territories (" + englishFile.getName(CLDRFile.TERRITORY_NAME, theSubContinent) + ")";
case "001":
case "ZZ":
@@ -1339,6 +1368,7 @@
});
functionMap.put("categoryFromTimezone",
catFromTimezone = new Transform<String, String>() {
+ @Override
public String transform(String source0) {
String territory = Containment.getRegionFromZone(source0);
if (territory == null) {
@@ -1348,8 +1378,9 @@
}
});
functionMap.put("timeZonePage", new Transform<String, String>() {
- Set<String> singlePageTerritories = new HashSet<String>(Arrays.asList("AQ", "RU", "ZZ"));
+ Set<String> singlePageTerritories = new HashSet<>(Arrays.asList("AQ", "RU", "ZZ"));
+ @Override
public String transform(String source0) {
String theTerritory = Containment.getRegionFromZone(source0);
if (theTerritory == null || theTerritory == "001") {
@@ -1381,6 +1412,7 @@
});
functionMap.put("timezoneSorting", new Transform<String, String>() {
+ @Override
public String transform(String source) {
final List<String> codeValues = Arrays.asList(
"generic-long",
@@ -1399,6 +1431,7 @@
});
functionMap.put("tzdpField", new Transform<String, String>() {
+ @Override
public String transform(String source) {
Map<String, String> fieldNames = Builder.with(new HashMap<String, String>())
.put("regionFormat", "Region Format - Generic")
@@ -1429,6 +1462,7 @@
}
});
functionMap.put("unit", new Transform<String, String>() {
+ @Override
public String transform(String source) {
int m = unitOrder.indexOf(source);
order = m;
@@ -1438,6 +1472,7 @@
functionMap.put("numericSort", new Transform<String, String>() {
// Probably only works well for small values, like -5 through +4.
+ @Override
public String transform(String source) {
Integer pos = Integer.valueOf(source) + 5;
suborder = new SubstringOrder(pos.toString());
@@ -1447,6 +1482,7 @@
functionMap.put("metazone", new Transform<String, String>() {
+ @Override
public String transform(String source) {
if (PathHeader.UNIFORM_CONTINENTS) {
String container = getMetazonePageTerritory(source);
@@ -1526,11 +1562,12 @@
final Map<String, String> currencyToTerritoryOverrides = CldrUtility.asMap(ctto);
final Map<String, String> subContinentToContinent = CldrUtility.asMap(sctc);
- final Set<String> fundCurrencies = new HashSet<String>(Arrays.asList("CHE", "CHW", "CLF", "COU", "ECV", "MXV", "USN", "USS", "UYI", "XEU", "ZAL"));
- final Set<String> offshoreCurrencies = new HashSet<String>(Arrays.asList("CNH"));
+ final Set<String> fundCurrencies = new HashSet<>(Arrays.asList("CHE", "CHW", "CLF", "COU", "ECV", "MXV", "USN", "USS", "UYI", "XEU", "ZAL"));
+ final Set<String> offshoreCurrencies = new HashSet<>(Arrays.asList("CNH"));
// TODO: Put this into supplementalDataInfo ?
functionMap.put("categoryFromCurrency", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
String tenderOrNot = "";
String territory = likelySubtags.getLikelyTerritoryFromCurrency(source0);
@@ -1562,6 +1599,7 @@
}
});
functionMap.put("continentFromCurrency", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
String subContinent;
String territory = likelySubtags.getLikelyTerritoryFromCurrency(source0);
@@ -1583,6 +1621,7 @@
}
});
functionMap.put("numberingSystem", new Transform<String, String>() {
+ @Override
public String transform(String source0) {
if ("latn".equals(source0)) {
return "";
@@ -1617,6 +1656,7 @@
};
+ @Override
public String transform(String source) {
order = getIndex(source, datefield);
return source;
@@ -1659,6 +1699,7 @@
"Saturday", "Saturday Short", "Saturday Narrow",
};
+ @Override
public String transform(String source) {
order = getIndex(source, relativeDateField) + 100;
return "Relative " + longNames[getIndex(source, relativeDateField)];
@@ -1667,11 +1708,13 @@
// Sorts numberSystem items (except for decimal formats).
functionMap.put("number", new Transform<String, String>() {
private final String[] symbols = { "decimal", "group",
- "plusSign", "minusSign", "percentSign", "perMille",
+ "plusSign", "minusSign", "approximatelySign",
+ "percentSign", "perMille",
"exponential", "superscriptingExponent",
"infinity", "nan", "list", "currencies"
};
+ @Override
public String transform(String source) {
String[] parts = source.split("-");
order = getIndex(parts[0], symbols);
@@ -1683,6 +1726,7 @@
}
});
functionMap.put("numberFormat", new Transform<String, String>() {
+ @Override
public String transform(String source) {
final List<String> fieldOrder = Arrays.asList(
"standard-decimal",
@@ -1702,6 +1746,7 @@
});
functionMap.put("localePattern", new Transform<String, String>() {
+ @Override
public String transform(String source) {
// Put localeKeyTypePattern behind localePattern and
// localeSeparator.
@@ -1775,7 +1820,7 @@
});
/**
* Use the ordering of the emoji in getEmojiToOrder rather than alphabetic,
- * since the collator data won't be ready until the candidates are final.
+ * since the collator data won't be ready until the candidates are final.
*/
functionMap.put("emoji", new Transform<String, String>() {
@Override
@@ -1806,7 +1851,8 @@
} else {
languageOnlyPart = s;
}
- return englishFile.getName(CLDRFile.LANGUAGE_NAME, languageOnlyPart).substring(0, 1).toUpperCase();
+ final String name = englishFile.getName(CLDRFile.LANGUAGE_NAME, languageOnlyPart);
+ return name == null ? "?" : name.substring(0, 1).toUpperCase();
}
static class HyphenSplitter {
@@ -1848,7 +1894,7 @@
return input;
}
int functionEnd = input.indexOf('(', functionStart);
- int argEnd = input.indexOf(')', functionEnd);
+ int argEnd = input.indexOf(')', functionEnd+2); // we must insert at least one character
Transform<String, String> func = functionMap.get(input.substring(functionStart + 1,
functionEnd));
final String arg = input.substring(functionEnd + 1, argEnd);
@@ -1871,7 +1917,8 @@
*/
public Set<String> pathsForFile(CLDRFile file) {
// make sure we cache all the path headers
- Set<String> filePaths = CollectionUtilities.addAll(file.fullIterable().iterator(), new HashSet<String>());
+ HashSet<String> filePaths = new HashSet<>();
+ file.fullIterable().forEach(filePaths::add);
for (String path : filePaths) {
try {
fromPath(path); // call to make sure cached
@@ -1887,7 +1934,7 @@
* @return
*/
public Set<String> getUnmatchedRegexes() {
- Map<String, RawData> outputUnmatched = new LinkedHashMap<String, RawData>();
+ Map<String, RawData> outputUnmatched = new LinkedHashMap<>();
lookup.getUnmatchedPatterns(matchersFound, outputUnmatched);
return outputUnmatched.keySet();
}
@@ -1957,11 +2004,11 @@
if (n == -1) return "";
return str.substring(0, n + 1);
}
-
+
public static String getUrlForLocalePath(String locale, String path) {
return getUrl(SURVEY_URL, locale, path);
}
-
+
public String getUrlForLocalePath(String locale) {
return getUrl(SURVEY_URL, locale, originalPath);
}
@@ -1978,6 +2025,7 @@
* @param subsection
* @return
*/
+ @Deprecated
public static String getPageUrl(String baseUrl, String locale, PageId subsection) {
return trimLast(baseUrl) + "v#/" + locale + "/" + subsection + "/";
}
@@ -1994,6 +2042,7 @@
* @param path
* @return
*/
+ @Deprecated
public static String getLinkedView(String baseUrl, String localeId, String path) {
// String value = file.getStringValue(path);
// if (value == null) {
diff --git a/tools/java/org/unicode/cldr/util/PathStarrer.java b/tools/java/org/unicode/cldr/util/PathStarrer.java
index 0f63ef4..a72e650 100644
--- a/tools/java/org/unicode/cldr/util/PathStarrer.java
+++ b/tools/java/org/unicode/cldr/util/PathStarrer.java
@@ -7,7 +7,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.Transform;
@@ -20,7 +20,7 @@
public static final String STAR_PATTERN = "([^\"]*+)";
private String starredPathString;
- private final List<String> attributes = new ArrayList<String>();
+ private final List<String> attributes = new ArrayList<>();
private final List<String> protectedAttributes = Collections.unmodifiableList(attributes);
private String substitutionPattern = STAR_PATTERN;
@@ -28,7 +28,7 @@
private final StringBuilder starredPathOld = new StringBuilder();
public String set(String path) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed();
return set(parts, Collections.<String> emptySet());
}
@@ -75,7 +75,7 @@
}
public String getAttributesString(String separator) {
- return CollectionUtilities.join(attributes, separator);
+ return Joiner.on(separator).join(attributes);
}
public String getResult() {
diff --git a/tools/java/org/unicode/cldr/util/PathUtilities.java b/tools/java/org/unicode/cldr/util/PathUtilities.java
index 79d7320..e2f237d 100644
--- a/tools/java/org/unicode/cldr/util/PathUtilities.java
+++ b/tools/java/org/unicode/cldr/util/PathUtilities.java
@@ -1,328 +1,101 @@
package org.unicode.cldr.util;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.unicode.cldr.icu.LDMLConstants;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
/**
- * @deprecated
+ * Recommended utility methods for normalizing paths used throughout the CLDR
+ * libraries.
+ *
+ * <p>The methods in this class are used to normalize file and directory paths
+ * such that resulting paths are:
+ * <ul>
+ * <li>Absolute with respect to the current working directory (if relative).
+ * <li>Normalized with respect to "upward" parent path segments.
+ * </ul>
+ *
+ * <p>For example if the current directory is {@code "/home/user/work/cldr"}:
+ * <pre>{@code
+ * // Append to current directory.
+ * getNormalizedPathString("foo/bar") == "/home/user/work/cldr/foo/bar"
+ * // Resolve parent path segments.
+ * getNormalizedPathString("../bar") == "/home/user/work/bar"
+ * // Retain (but normalize) absolute paths.
+ * getNormalizedPathString("/tmp/foo/../bar") == "/tmp/bar"
+ * }</pre>
+ *
+ * <p>Note that it is very important to realize that this is NOT the same as
+ * obtaining the "canonical" path (e.g. via {@link File#getCanonicalPath()}
+ * since the methods in this class <em>do not follow symbolic links</em>.
+ *
+ * <p>This is important because in some build systems (e.g. Bazel), file
+ * hierarchies are created by mapping files using symbolic links, and there's
+ * no necessary reason that the canonical file path preserves the same relative
+ * relationship between files.
+ *
+ * <p>For example Bazel uses a content addressed file cache, so every file used
+ * at build time has a canonical path of something like:
+ * <pre>{@code
+ * /tmp/build/cache/<hex-formatted-content-fingerprint>
+ * }</pre>
+ *
+ * <p>These files are them mapped (via symbolic links) to a hierarchy such as:
+ * <pre>{@code
+ * /<buid-root>/common/supplemental/plurals.xml
+ * /<buid-root>/common/supplemental/pluralRanges.xml
+ * ...
+ * /<buid-root>/common/dtd/ldmlSupplemental.dtd
+ * }</pre>
+ *
+ * <p>When the XML files are parsed by the CLDR library, the DTD file is found
+ * via the relative path {@code "../../common/dtd/ldmlSupplemental.dtd}.
+ *
+ * <p>If the canonical path for these XML files were given to the XML parser, it
+ * would attempt to resolve the DTD file location as:
+ * <pre>{@code
+ * /tmp/build/cache/<hex-formatted-content-fingerprint>/../../common/dtd/ldmlSupplemental.dtd
+ * }</pre>
+ * which is just:
+ * <pre>{@code
+ * /tmp/build/common/dtd/ldmlSupplemental.dtd
+ * }</pre>
+ * which will obviously not work.
+ *
+ * <p>Over time the CLDR libraries should transition to using {@link Path}
+ * instances (in favour of {@link File} or strings) when handling file paths and
+ * hopefully some of these methods can eventually be deprecated and removed.
*/
-public class PathUtilities {
-
- // ===== types of data and menu names
- public static final String LOCALEDISPLAYNAMES = "//ldml/localeDisplayNames/";
- /**
- * All of the data items under LOCALEDISPLAYNAMES (menu items)
- */
- public static final String LOCALEDISPLAYNAMES_ITEMS[] = { LDMLConstants.LANGUAGES,
- LDMLConstants.SCRIPTS, LDMLConstants.TERRITORIES, LDMLConstants.VARIANTS, LDMLConstants.KEYS,
- LDMLConstants.TYPES, PathUtilities.CURRENCIES, PathUtilities.TIMEZONES,
- PathUtilities.CODEPATTERNS, PathUtilities.MEASNAMES };
- public static final String OTHER_CALENDARS_XPATH = "//ldml/dates/calendars/calendar";
-
- public static final String LOCALEDISPLAYPATTERN_XPATH = LOCALEDISPLAYNAMES
- + LDMLConstants.LOCALEDISPLAYPATTERN;
- public static final String NUMBERSCURRENCIES = LDMLConstants.NUMBERS + "/"
- + PathUtilities.CURRENCIES;
- public static final String CURRENCIES = "currencies";
- public static final String TIMEZONES = "timezones";
- public static final String METAZONES = "metazones";
- public static String xOTHER = "misc";
- public static final String CODEPATTERNS = "codePatterns";
- public static final String MEASNAMES = "measurementSystemNames";
-
- public static String xpathToMenu(String path) {
- String theMenu = null;
- if (path.startsWith(LOCALEDISPLAYNAMES)) {
- for (int i = 0; i < LOCALEDISPLAYNAMES_ITEMS.length; i++) {
- if (path.startsWith(LOCALEDISPLAYNAMES
- + LOCALEDISPLAYNAMES_ITEMS[i])) {
- theMenu = LOCALEDISPLAYNAMES_ITEMS[i];
- }
- }
- if (path.startsWith(LOCALEDISPLAYPATTERN_XPATH)) {
- theMenu = LDMLConstants.LOCALEDISPLAYPATTERN;
- }
- // } else if(path.startsWith(GREGO_XPATH)) {
- // theMenu=GREGORIAN_CALENDAR;
- } else if (path.startsWith(OTHER_CALENDARS_XPATH)) {
- String items[] = getCalendarsItems();
- for (String which : items) {
- String CAL_XPATH = "//ldml/dates/calendars/calendar[@type=\"" + which + "\"]";
- if (path.startsWith(CAL_XPATH)) {
- theMenu = which;
- break;
- }
- }
- } else if (path.startsWith(LOCALEDISPLAYPATTERN_XPATH)) {
- theMenu = LDMLConstants.LOCALEDISPLAYPATTERN;
- } else if (path.startsWith("//ldml/" + NUMBERSCURRENCIES)) {
- theMenu = CURRENCIES;
- } else if (path.startsWith("//ldml/" + "dates/timeZoneNames/zone")) {
- theMenu = TIMEZONES;
- } else if (path.startsWith("//ldml/" + "units")) {
- theMenu = "units";
- } else if (path.startsWith("//ldml/" + "dates/timeZoneNames/metazone")) {
- theMenu = getMetazoneContinent(path);
- if (theMenu == null) {
- theMenu = METAZONES;
- }
- } else if (path.startsWith("//ldml/" + LDMLConstants.CHARACTERS + "/" + LDMLConstants.EXEMPLAR_CHARACTERS)) {
- theMenu = LDMLConstants.CHARACTERS;
- } else if (path.startsWith("//ldml/" + LDMLConstants.NUMBERS)) {
- theMenu = LDMLConstants.NUMBERS;
- } else if (path.startsWith("//ldml/" + LDMLConstants.REFERENCES)) {
- theMenu = LDMLConstants.REFERENCES;
- } else {
- theMenu = xOTHER;
- // other?
- }
- return theMenu;
+public final class PathUtilities {
+ /** Returns the normalized, absolute path string for the given path. */
+ public static String getNormalizedPathString(String first, String... rest) {
+ return getNormalizedPath(first, rest).toString();
}
- public static String[] getCalendarsItems() {
- // TODO : Make this data driven from supplementalMetaData ;
- // I couldn't get the xpath right....
- // CLDRFile mySupp = getFactory().make("supplementalMetaData",false);
- // String xpath =
- // "//supplementalData/metadata/validity/variable[@id=\"$calendar\"][@type=\"choice\"]";
- // String items = mySupp.getStringValue(xpath);
- // if ( items != null ) {
- // return (items.split(" "));
- // }
- // else {
-
- String defaultCalendarsItems = "gregorian buddhist coptic ethiopic chinese hebrew indian islamic japanese persian roc";
- return (defaultCalendarsItems.split(" "));
-
- // }
+ /** Returns the normalized, absolute path string of the given file. */
+ public static String getNormalizedPathString(File file) {
+ return getNormalizedPath(file).toString();
}
- public static String[] getMetazonesItems() {
- String defaultMetazonesItems = "Africa America Antarctica Asia Australia Europe Atlantic Indian Pacific";
- return (defaultMetazonesItems.split(" "));
+ /** Returns the normalized, absolute path string of the given path. */
+ public static String getNormalizedPathString(Path path) {
+ return getNormalizedPath(path).toString();
}
- private static Map<String, String> mzXpathToContinent = new HashMap<String, String>();
-
- private synchronized static String getMetazoneContinent(String xpath) {
- String continent = mzXpathToContinent.get(xpath);
- if (continent == null) {
- XPathParts parts = XPathParts.getFrozenInstance(xpath);
- String thisMetazone = parts.getAttributeValue(3, "type");
- continent = getMetazoneToContinentMap().get(thisMetazone);
- }
- return continent;
+ /** Returns the normalized, absolute path of the given path segments. */
+ public static Path getNormalizedPath(String first, String... rest) {
+ return getNormalizedPath(Paths.get(first, rest));
}
- static Map<String, String> mzToContinentMap = null;
-
- private static Map<String, String> getMetazoneToContinentMap() {
- if (mzToContinentMap == null) {
- System.err
- .println(
- "PathUtilities.java getMetazoneToContinentMap(): TODO: Get this data from supplemental data! http://unicode.org/cldr/trac/ticket/3761");
- HashMap<String, String> newMap = new HashMap<String, String>();
- for (int i = 0; i < mzToContinentStatic.length; i += 2) {
- newMap.put(mzToContinentStatic[i + 0], mzToContinentStatic[i + 1]);
- }
- mzToContinentMap = newMap;
- }
- return mzToContinentMap;
+ /** Returns the normalized, absolute path of the given file. */
+ public static Path getNormalizedPath(File file) {
+ return getNormalizedPath(Paths.get(file.getPath()));
}
- private static final String mzToContinentStatic[] = {
+ /** Returns the normalized, absolute path of the given path. */
+ public static Path getNormalizedPath(Path path) {
+ return path.toAbsolutePath().normalize();
+ }
- "Philippines", "Asia",
- "Gambier", "Pacific",
- "Ecuador", "America",
- "Kuybyshev", "Europe",
- "Europe_Western", "Atlantic",
- "Chile", "America",
- "Afghanistan", "Asia",
- "Pierre_Miquelon", "America",
- "Solomon", "Pacific",
- "Arabian", "Asia",
- "Krasnoyarsk", "Asia",
- "Vladivostok", "Asia",
- "Fiji", "Pacific",
- "Niue", "Pacific",
- "Marquesas", "Pacific",
- "Karachi", "Asia",
- "Aqtobe", "Asia",
- "Irish", "Europe",
- "Yakutsk", "Asia",
- "Galapagos", "Pacific",
- "Bangladesh", "Asia",
- "America_Pacific", "America",
- "Urumqi", "Asia",
- "Tahiti", "Pacific",
- "Samoa", "Pacific",
- "Uzbekistan", "Asia",
- "Turkey", "Europe",
- "Kyrgystan", "Asia",
- "Europe_Eastern", "Europe",
- "Casey", "Antarctica",
- "Lord_Howe", "Australia",
- "Kizilorda", "Asia",
- "Kashgar", "Asia",
- "Africa_Western", "Africa",
- "Macquarie", "Antarctica",
- "Wake", "Pacific",
- "Australia_Eastern", "Australia",
- "Guyana", "America",
- "Taipei", "Asia",
- "Samarkand", "Asia",
- "Mawson", "Antarctica",
- "Africa_Eastern", "Africa",
- "Guam", "Pacific",
- "Kazakhstan_Western", "Asia",
- "Aqtau", "Asia",
- "Cook", "Pacific",
- "Wallis", "Pacific",
- "Irkutsk", "Asia",
- "Africa_Southern", "Africa",
- "French_Guiana", "America",
- "Chatham", "Pacific",
- "Oral", "Asia",
- "Noronha", "America",
- "Paraguay", "America",
- "Moscow", "Europe",
- "Hong_Kong", "Asia",
- "Yerevan", "Asia",
- "Vostok", "Antarctica",
- "Rothera", "Antarctica",
- "Colombia", "America",
- "Newfoundland", "America",
- "Hawaii_Aleutian", "Pacific",
- "East_Timor", "Asia",
- "GMT", "Atlantic",
- "Indian_Ocean", "Indian",
- "Reunion", "Indian",
- "Vanuatu", "Pacific",
- "Malaysia", "Asia",
- "Kwajalein", "Pacific",
- "Line_Islands", "Pacific",
- "Shevchenko", "Asia",
- "Azores", "Atlantic",
- "Frunze", "Asia",
- "Greenland_Eastern", "America",
- "Hovd", "Asia",
- "Lanka", "Asia",
- "Almaty", "Asia",
- "Macau", "Asia",
- "Mongolia", "Asia",
- "Easter", "Pacific",
- "British", "Europe",
- "Korea", "Asia",
- "Papua_New_Guinea", "Pacific",
- "Bering", "America",
- "Cocos", "Indian",
- "Mauritius", "Indian",
- "Argentina", "America",
- "Tokelau", "Pacific",
- "America_Central", "America",
- "Alaska", "America",
- "Georgia", "Asia",
- "Choibalsan", "Asia",
- "Sakhalin", "Asia",
- "Anadyr", "Asia",
- "Dushanbe", "Asia",
- "Indonesia_Eastern", "Asia",
- "Japan", "Asia",
- "Omsk", "Asia",
- "Nauru", "Pacific",
- "Cuba", "America",
- "Iran", "Asia",
- "Sverdlovsk", "Asia",
- "Maldives", "Indian",
- "Europe_Central", "Europe",
- "Kamchatka", "Asia",
- "Tajikistan", "Asia",
- "Pitcairn", "Pacific",
- "Gilbert_Islands", "Pacific",
- "Novosibirsk", "Asia",
- "Brunei", "Asia",
- "Tonga", "Pacific",
- "Changbai", "Asia",
- "India", "Asia",
- "Indonesia_Western", "Asia",
- "Malaya", "Asia",
- "Dacca", "Asia",
- "Tashkent", "Asia",
- "New_Zealand", "Pacific",
- "Indonesia_Central", "Asia",
- "Myanmar", "Asia",
- "South_Georgia", "Atlantic",
- "Truk", "Pacific",
- "Pakistan", "Asia",
- "Borneo", "Asia",
- "DumontDUrville", "Antarctica",
- "Argentina_Western", "America",
- "Uruguay", "America",
- "Dutch_Guiana", "America",
- "Ponape", "Pacific",
- "Gulf", "Asia",
- "Aktyubinsk", "Asia",
- "America_Mountain", "America",
- "Dominican", "America",
- "North_Mariana", "Pacific",
- "Yukon", "America",
- "Armenia", "Asia",
- "Falkland", "Atlantic",
- "Tbilisi", "Asia",
- "Baku", "Asia",
- "Venezuela", "America",
- "Ashkhabad", "Asia",
- "Cape_Verde", "Atlantic",
- "Phoenix_Islands", "Pacific",
- "Brasilia", "America",
- "Marshall_Islands", "Pacific",
- "Volgograd", "Europe",
- "Yekaterinburg", "Asia",
- "Kosrae", "Pacific",
- "Tuvalu", "Pacific",
- "Africa_Central", "Africa",
- "Palau", "Pacific",
- "Alaska_Hawaii", "America",
- "Qyzylorda", "Asia",
- "Bhutan", "Asia",
- "Israel", "Asia",
- "America_Eastern", "America",
- "Nepal", "Asia",
- "Azerbaijan", "Asia",
- "Uralsk", "Asia",
- "Bolivia", "America",
- "Liberia", "Africa",
- "Turkmenistan", "Asia",
- "Davis", "Antarctica",
- "Norfolk", "Pacific",
- "Indochina", "Asia",
- "Peru", "America",
- "Acre", "America",
- "China", "Asia",
- "Chamorro", "Pacific",
- "Atlantic", "America",
- "Syowa", "Antarctica",
- "Africa_FarWestern", "Africa",
- "New_Caledonia", "Pacific",
- "Greenland_Western", "America",
- "Suriname", "America",
- "Seychelles", "Indian",
- "Christmas", "Indian",
- "Australia_CentralWestern", "Australia",
- "Greenland_Central", "America",
- "French_Southern", "Indian",
- "Australia_Central", "Australia",
- "Australia_Western", "Australia",
- "Magadan", "Asia",
- "Kazakhstan_Eastern", "Asia",
- "Goose_Bay", "America",
- "Singapore", "Asia",
- "Amazon", "America",
- "Long_Shu", "Asia",
- "Samara", "Europe",
- };
-
+ private PathUtilities() {}
}
diff --git a/tools/java/org/unicode/cldr/util/PatternPlaceholders.java b/tools/java/org/unicode/cldr/util/PatternPlaceholders.java
index 45fa69d..186673b 100644
--- a/tools/java/org/unicode/cldr/util/PatternPlaceholders.java
+++ b/tools/java/org/unicode/cldr/util/PatternPlaceholders.java
@@ -5,30 +5,43 @@
import java.util.Map;
import java.util.Map.Entry;
+import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
import org.unicode.cldr.tool.GenerateXMB;
import org.unicode.cldr.util.RegexLookup.Merger;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.ibm.icu.text.Transform;
public class PatternPlaceholders {
public enum PlaceholderStatus {
- DISALLOWED("No placeholders allowed."), //
- OPTIONAL("Zero or one placeholder allowed."), //
- MULTIPLE("Zero or more placeholders allowed."), //
- LOCALE_DEPENDENT( "Varies by locale."),
- REQUIRED("Placeholder required");
-
- final String message;
+ DISALLOWED("No placeholders allowed."),//
+ REQUIRED("Specific number of placeholders allowed."),//
+ LOCALE_DEPENDENT("Some placeholders may be omitted in certain locales"),//
+ MULTIPLE("May have multiple instances of the same placeholder, eg “{0} cats and {0} dogs”.")//
+ ;
+
+ private final String message;
private PlaceholderStatus(String message) {
this.message = message;
}
+ @Override
+ public String toString() {
+ return name() + ": " + message;
+ }
}
+ public static final ImmutableSet<Subtype> PLACEHOLDER_SUBTYPES = ImmutableSet.of(
+ Subtype.gapsInPlaceholderNumbers,
+ Subtype.duplicatePlaceholders,
+ Subtype.missingPlaceholders,
+ Subtype.extraPlaceholders);
+
private static class PlaceholderData {
PlaceholderStatus status = PlaceholderStatus.REQUIRED;
- Map<String, PlaceholderInfo> data = new LinkedHashMap<String, PlaceholderInfo>();
+ Map<String, PlaceholderInfo> data = new LinkedHashMap<>();
public void add(String id, String name, String example) {
PlaceholderInfo row = new PlaceholderInfo(name, example);
@@ -47,7 +60,7 @@
@Override
public String toString() {
- return name + " (" + example + ")";
+ return "{" + name + "}, e.g. “" + example + "”";
}
}
@@ -77,9 +90,6 @@
String[] parts = source.split("\\s*;\\s+");
for (String part : parts) {
switch (part) {
- case "optional":
- result.status = PlaceholderStatus.OPTIONAL;
- continue;
case "locale":
result.status = PlaceholderStatus.LOCALE_DEPENDENT;
continue;
@@ -137,7 +147,7 @@
public Map<String, PlaceholderInfo> get(String path) {
// TODO change the original map to be unmodifiable, to avoid this step. Need to add a "finalize" to the lookup.
final PlaceholderData map = patternPlaceholders.get(path);
- return map == null ? null : Collections.unmodifiableMap(map.data);
+ return map == null ? ImmutableMap.of() : Collections.unmodifiableMap(map.data);
}
public PlaceholderStatus getStatus(String path) {
diff --git a/tools/java/org/unicode/cldr/util/Pick.java b/tools/java/org/unicode/cldr/util/Pick.java
index b0b24ca..6c80fd8 100644
--- a/tools/java/org/unicode/cldr/util/Pick.java
+++ b/tools/java/org/unicode/cldr/util/Pick.java
@@ -108,7 +108,7 @@
static public Pick.Alternation or(int[] itemWeights, Object[] items) {
return new Alternation().or2(itemWeights, items);
}
-
+
static public Pick maybe(int percent, Object item) {
return new Repeat(0, 1, new int[]{100-percent, percent}, item);
//return Pick.or(1.0-percent, NOTHING).or2(percent, item);
@@ -116,7 +116,7 @@
static public Pick repeat(int minCount, int maxCount, int itemWeights, Object item) {
return new Repeat(minCount, maxCount, itemWeights, item);
}
-
+
static public Pick codePoint(String source) {
return new CodePoint(new UnicodeSet(source));
}
@@ -162,12 +162,14 @@
return this; // for chaining
}
+ @Override
protected void addTo(Target target) {
for (int i = 0; i < items.length; ++i) {
items[i].addTo(target);
}
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -184,6 +186,7 @@
private Sequence() {
}
+ @Override
public boolean match(String input, Position p) {
int originalIndex = p.index;
for (int i = 0; i < items.length; ++i) {
@@ -231,10 +234,12 @@
return this; // for chaining
}
+ @Override
protected void addTo(Target target) {
items[weightedIndex.toIndex(target.nextDouble())].addTo(target);
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -251,6 +256,7 @@
}
// take first matching option
+ @Override
public boolean match(String input, Position p) {
for (int i = 0; i < weightedIndex.weights.length; ++i) {
if (p.isFailure(this, i)) continue;
@@ -288,6 +294,7 @@
weightedIndex = new WeightedIndex(minCount).add(maxCount-minCount+1, 1);
}
*/
+ @Override
protected void addTo(Target target) {
//int count ;
for (int i = weightedIndex.toIndex(target.nextDouble()); i > 0; --i) {
@@ -295,6 +302,7 @@
}
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -305,6 +313,7 @@
}
// match longest, e.g. up to just before a failure
+ @Override
public boolean match(String input, Position p) {
//int bestMatch = p.index;
int count = 0;
@@ -332,10 +341,12 @@
this.source = source;
}
+ @Override
protected void addTo(Target target) {
target.append(source.charAt(pick(target.random, 0, source.size() - 1)));
}
+ @Override
public boolean match(String s, Position p) {
int cp = UTF16.charAt(s, p.index);
if (source.contains(cp)) {
@@ -346,6 +357,7 @@
return false;
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -368,6 +380,7 @@
private static final WeightedIndex choice = new WeightedIndex(0)
.add(new int[] { 10, 10, 100, 10 });
+ @Override
protected void addTo(Target target) {
// get contents into separate buffer
addBuffer.copyState(target);
@@ -382,7 +395,7 @@
int lastIndex = 0;
int newIndex = 0;
// the new length is a random value between old and new.
- int newLenLimit = (int) pick(target.random, lastValue.length(), newValue.length());
+ int newLenLimit = pick(target.random, lastValue.length(), newValue.length());
while (mergeBuffer.length() < newLenLimit
&& newIndex < newValue.length()
@@ -403,6 +416,7 @@
if (DEBUG) System.out.println("Result: " + newValue);
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -414,6 +428,7 @@
/* (non-Javadoc)
* @see Pick#match(java.lang.String, Pick.Position)
*/
+ @Override
public boolean match(String input, Position p) {
// TODO Auto-generated method stub
return false;
@@ -429,7 +444,7 @@
return newIndex + UTF16.getCharCount(cp);
}
- /*
+ /*
// quoted add
appendQuoted(target, addBuffer.toString(), quoteBuffer);
// fix buffers
@@ -445,16 +460,19 @@
super(item);
}
+ @Override
protected void addTo(Target target) {
target.quoter.setQuoting(true);
item.addTo(target);
target.quoter.setQuoting(false);
}
+ @Override
public boolean match(String s, Position p) {
return false;
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
String result = checkName(name, alreadySeen);
if (result.startsWith("$")) return result;
@@ -464,6 +482,7 @@
}
private static class Literal extends FinalPick {
+ @Override
public String toString() {
return name;
}
@@ -472,10 +491,12 @@
this.name = source;
}
+ @Override
protected void addTo(Target target) {
target.append(name);
}
+ @Override
public boolean match(String input, Position p) {
int len = name.length();
if (input.regionMatches(p.index, name, 0, len)) {
@@ -486,6 +507,7 @@
return false;
}
+ @Override
public String getInternal(int depth, Set alreadySeen) {
return "'" + name + "'";
}
@@ -503,6 +525,7 @@
}
}
+ @Override
public String toString() {
return "index; " + index
+ ", maxInt:" + maxInt
@@ -536,8 +559,8 @@
/*
public static final Pick NOTHING = new Nothing();
-
-
+
+
private static class Nothing extends FinalPick {
protected void addTo(Target target) {}
protected boolean match(String input, Position p) {
@@ -579,6 +602,7 @@
this.replacement = replacement;
}
+ @Override
public Pick handle(Pick a) {
if (toReplace.equals(a.name)) {
a = replacement;
@@ -588,6 +612,7 @@
}
abstract private static class FinalPick extends Pick {
+ @Override
public Pick visit(Visitor visitor) {
return visitor.handle(this);
}
@@ -600,6 +625,7 @@
this.item = item;
}
+ @Override
public Pick visit(Visitor visitor) {
Pick result = visitor.handle(this);
if (visitor.alreadyEntered(this)) return result;
@@ -637,6 +663,7 @@
}
}
+ @Override
public Pick visit(Visitor visitor) {
Pick result = visitor.handle(this);
if (visitor.alreadyEntered(this)) return result;
@@ -681,7 +708,7 @@
if (newWeights == null) newWeights = new int[] { 1 };
int oldLen = weights.length;
if (maxCount < newWeights.length) maxCount = newWeights.length;
- weights = (int[]) realloc(weights, weights.length + maxCount);
+ weights = realloc(weights, weights.length + maxCount);
System.arraycopy(newWeights, 0, weights, oldLen, newWeights.length);
int lastWeight = weights[oldLen + newWeights.length - 1];
for (int i = oldLen + newWeights.length; i < maxCount; ++i) {
@@ -708,6 +735,7 @@
return i + minCount;
}
+ @Override
public String toString() {
String result = "";
for (int i = 0; i < minCount; ++i) {
@@ -778,7 +806,7 @@
if (DEBUG) System.out.println("\"" + toAdd + "\"");
target.append(toAdd);
}
-
+
private static void appendQuoted(StringBuffer target, String toAdd, StringBuffer quoteBuffer) {
if (DEBUG) System.out.println("\"" + toAdd + "\"");
Utility.appendToRule(target, toAdd, false, false, quoteBuffer);
@@ -789,7 +817,7 @@
public abstract void handleString(String source, int start, int limit);
public abstract void handleSequence(String source, int start, int limit);
public abstract void handleAlternation(String source, int start, int limit);
-
+
}
*/
/*
@@ -798,22 +826,22 @@
public interface Spread {
public double spread(double value);
}
-
+
// give the weight for the high end.
// values are linearly scaled according to the weight.
static public class SimpleSpread implements Spread {
static final Spread FLAT = new SimpleSpread(1.0);
boolean flat = false;
double aa, bb, cc;
- public SimpleSpread(double maxWeight) {
+ public SimpleSpread(double maxWeight) {
if (maxWeight > 0.999 && maxWeight < 1.001) {
flat = true;
- } else {
+ } else {
double q = (maxWeight - 1.0);
aa = -1/q;
bb = 1/(q*q);
cc = (2.0+q)/q;
- }
+ }
}
public double spread(double value) {
if (flat) return value;
@@ -826,7 +854,7 @@
static public int pick(Spread spread, Random random, int start, int end) {
return start + (int)(spread.spread(random.nextDouble()) * (end + 1 - start));
}
-
+
*/
}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/PluralRanges.java b/tools/java/org/unicode/cldr/util/PluralRanges.java
index 839eefd..051159d 100644
--- a/tools/java/org/unicode/cldr/util/PluralRanges.java
+++ b/tools/java/org/unicode/cldr/util/PluralRanges.java
@@ -21,6 +21,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public static final class Matrix implements Comparable<Matrix>, Cloneable {
private byte[] data = new byte[Count.LENGTH * Count.LENGTH];
{
@@ -34,6 +35,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public void set(Count start, Count end, Count result) {
data[start.ordinal() * Count.LENGTH + end.ordinal()] = result == null ? (byte) -1 : (byte) result.ordinal();
}
@@ -43,6 +45,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public void setIfNew(Count start, Count end, Count result) {
byte old = data[start.ordinal() * Count.LENGTH + end.ordinal()];
if (old >= 0) {
@@ -57,6 +60,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public Count get(Count start, Count end) {
byte result = data[start.ordinal() * Count.LENGTH + end.ordinal()];
return result < 0 ? null : Count.VALUES.get(result);
@@ -67,6 +71,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public Count endSame(Count end) {
Count first = null;
for (Count start : Count.VALUES) {
@@ -90,6 +95,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public Count startSame(Count start, EnumSet<Count> endDone, Output<Boolean> emit) {
emit.value = false;
Count first = null;
@@ -168,6 +174,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public void add(Count rangeStart, Count rangeEnd, Count result) {
explicit[result.ordinal()] = true;
if (rangeStart == null) {
@@ -202,6 +209,7 @@
* @internal
* @deprecated
*/
+ @Deprecated
public static String showRange(Count start, Count end, Count result) {
String startEnd = "start=\"" + start + "\"" + Utility.repeat(" ", 5 - start.toString().length())
+ " end=\"" + end + "\"" + Utility.repeat(" ", 5 - end.toString().length());
@@ -240,13 +248,14 @@
* @internal
* @deprecated
*/
+ @Deprecated
public boolean isExplicitlySet(Count count) {
return explicit[count.ordinal()];
}
@Override
public boolean equals(Object other) {
- return other instanceof PluralRanges ? matrix.equals((PluralRanges) other) : false;
+ return other instanceof PluralRanges ? matrix.equals(other) : false;
}
@Override
diff --git a/tools/java/org/unicode/cldr/util/PluralRulesUtil.java b/tools/java/org/unicode/cldr/util/PluralRulesUtil.java
index 1ae273a..c13ba17 100644
--- a/tools/java/org/unicode/cldr/util/PluralRulesUtil.java
+++ b/tools/java/org/unicode/cldr/util/PluralRulesUtil.java
@@ -78,7 +78,7 @@
// Compute if the quick test is insufficient.
- HashSet<Double> subtractedSet = new HashSet<Double>(values);
+ HashSet<Double> subtractedSet = new HashSet<>(values);
for (Double explicit : explicits) {
// int rounded = (int) Math.round(explicit*1000000);
subtractedSet.remove(explicit - offset);
diff --git a/tools/java/org/unicode/cldr/util/PluralSamples.java b/tools/java/org/unicode/cldr/util/PluralSamples.java
index 3e62edf..07dc2f8 100644
--- a/tools/java/org/unicode/cldr/util/PluralSamples.java
+++ b/tools/java/org/unicode/cldr/util/PluralSamples.java
@@ -9,8 +9,9 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
public class PluralSamples {
- private static final Map<String, PluralSamples> cache = new ConcurrentHashMap<String, PluralSamples>();
- private final Map<Count, Double>[] samples = new Map[4]; // we do 1, 2, 3, and 4 decimals
+ private static final Map<String, PluralSamples> cache = new ConcurrentHashMap<>();
+ private static final int SAMPLE_SIZE = 4;
+ private final Map<Count, Double>[] samples = new Map[SAMPLE_SIZE]; // we do 1, 2, 3, and 4 decimals
public PluralSamples(String locale) {
SupplementalDataInfo info = SupplementalDataInfo.getInstance();
@@ -24,14 +25,14 @@
}
private Map<Count, Double> getValuesForDigits(PluralInfo pluralInfo, int total, int start, int end) {
- Map<Count, Double> set = new EnumMap<Count, Double>(Count.class);
+ Map<Count, Double> set = new EnumMap<>(Count.class);
// Cycle through digits
boolean favorPositive = start == 0;
if (favorPositive) {
++start;
}
for (int item = start; item < end; ++item) {
- double dItem = (double) item;
+ double dItem = item;
Count count = pluralInfo.getCount(dItem);
Double old = set.get(count);
if (old == null) {
@@ -89,6 +90,9 @@
* @return
*/
public Map<PluralInfo.Count, Double> getSamples(int digits) {
- return samples[digits - 1];
+ if (digits > 0 && digits <= SAMPLE_SIZE) {
+ return samples[digits - 1];
+ }
+ return null;
}
}
diff --git a/tools/java/org/unicode/cldr/util/PluralSnapshot.java b/tools/java/org/unicode/cldr/util/PluralSnapshot.java
index 84d779a..acf2c24 100644
--- a/tools/java/org/unicode/cldr/util/PluralSnapshot.java
+++ b/tools/java/org/unicode/cldr/util/PluralSnapshot.java
@@ -15,7 +15,7 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
import org.unicode.cldr.util.SupplementalDataInfo.PluralType;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.NumberFormat;
@@ -48,7 +48,7 @@
static final int LEN = 128;
- static Set<Double> zeroOne = new TreeSet<Double>();
+ static Set<Double> zeroOne = new TreeSet<>();
static {
zeroOne.add(0.0d);
zeroOne.add(1.0d);
@@ -77,7 +77,7 @@
private SnapshotInfo(PluralType pluralType, Integral integral) {
this.integral = integral;
SupplementalDataInfo supplementalDataInfo = SupplementalDataInfo.getInstance();
- Map<String, PluralSnapshot> rulesToSnapshot = new HashMap<String, PluralSnapshot>();
+ Map<String, PluralSnapshot> rulesToSnapshot = new HashMap<>();
for (String locale : supplementalDataInfo.getPluralLocales(pluralType)) {
PluralInfo plurals = supplementalDataInfo.getPlurals(pluralType, locale);
String rules = plurals.getRules();
@@ -91,6 +91,7 @@
}
}
+ @Override
public Iterator<Entry<PluralSnapshot, Set<String>>> iterator() {
return snapshotToLocales.keyValuesSet().iterator();
}
@@ -126,7 +127,7 @@
}
}
- private static final EnumMap<PluralType, EnumMap<Integral, SnapshotInfo>> SINGLETONS = new EnumMap<PluralType, EnumMap<Integral, SnapshotInfo>>(
+ private static final EnumMap<PluralType, EnumMap<Integral, SnapshotInfo>> SINGLETONS = new EnumMap<>(
PluralType.class);
static {
SINGLETONS.put(PluralType.cardinal, new EnumMap<Integral, SnapshotInfo>(Integral.class));
@@ -186,17 +187,20 @@
return 0;
}
+ @Override
public boolean equals(Object other) {
return compareTo((PluralSnapshot) other) == 0;
}
+ @Override
public int hashCode() {
return count; // brain dead but we don't care.
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
- result.append("Plurals: 0, 1, ").append(CollectionUtilities.join(not01, ", "));
+ result.append("Plurals: 0, 1, ").append(Joiner.on(", ").join(not01));
if (coveredBy01.size() != 0) {
result.append("\nCovered by {0,1}:\t").append(coveredBy01);
}
@@ -310,7 +314,7 @@
// lastCount = ss.count;
// lastCount01 = ss.count01;
// }
- Map<String, String> fullLocales = new TreeMap<String, String>();
+ Map<String, String> fullLocales = new TreeMap<>();
for (String localeId : locales) {
String name = english.getName(localeId);
fullLocales.put(name, localeId);
diff --git a/tools/java/org/unicode/cldr/util/PreferredAndAllowedHour.java b/tools/java/org/unicode/cldr/util/PreferredAndAllowedHour.java
index 59abc4c..c68df98 100644
--- a/tools/java/org/unicode/cldr/util/PreferredAndAllowedHour.java
+++ b/tools/java/org/unicode/cldr/util/PreferredAndAllowedHour.java
@@ -1,17 +1,21 @@
package org.unicode.cldr.util;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.LinkedHashSet;
-import java.util.List;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Comparators.lexicographical;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
-import com.ibm.icu.dev.util.CollectionUtilities;
public final class PreferredAndAllowedHour implements Comparable<PreferredAndAllowedHour> {
-
+ // DO NOT change enum item names, they are mapped directly from data values via "valueOf".
public enum HourStyle {
H, Hb(H), HB(H), k, h, hb(h), hB(h), K;
public final HourStyle base;
@@ -28,77 +32,77 @@
try {
HourStyle.valueOf(c);
return true;
- } catch (Exception e) {
+ } catch (IllegalArgumentException e) {
return false;
}
}
}
+ // For splitting the style ID string.
+ private static final Splitter SPACE_SPLITTER = Splitter.on(' ').trimResults();
+
+ // If this used "getter" method references it wouldn't need so much explicit generic typing.
+ private static final Comparator<PreferredAndAllowedHour> COMPARATOR =
+ Comparator.<PreferredAndAllowedHour, HourStyle>comparing(t -> t.preferred)
+ .thenComparing(t -> t.allowed, lexicographical(Comparator.<HourStyle>naturalOrder()));
+
public final HourStyle preferred;
- public final List<HourStyle> allowed;
+ /** Unique allowed styles, in the order they were specified during construction. */
+ public final ImmutableList<HourStyle> allowed;
- public PreferredAndAllowedHour(char preferred, Collection<Character> allowed) {
- this(HourStyle.valueOf(String.valueOf(preferred)), mungeSet(allowed));
+ /**
+ * Creates a PreferredAndAllowedHour instance with "allowed" styles derived from single
+ * character IDs in the given collection. Note that the iteration order of the allowed
+ * styles is retained.
+ *
+ * <p>This constructor is limiting, since some styles are identified by two character
+ * strings, which cannot be referenced via this constructor.
+ */
+ public PreferredAndAllowedHour(char preferred, Set<Character> allowed) {
+ this(String.valueOf(preferred), allowed.stream().map(String::valueOf));
}
- public PreferredAndAllowedHour(Collection<HourStyle> allowed) {
- this(allowed.iterator().next(), allowed);
+ /**
+ * Creates a PreferredAndAllowedHour instance with "allowed" styles derived from a space
+ * separated list of unique IDs. Note that the iteration order of the allowed styles is
+ * retained, since in some situations it is necessary that the preferred style should
+ * also be the first allowed style. The list of allowed style IDs must not contain
+ * duplicates.
+ */
+ public PreferredAndAllowedHour(String preferred, String allowedString) {
+ this(preferred, SPACE_SPLITTER.splitToList(allowedString).stream());
}
- public PreferredAndAllowedHour(HourStyle preferred, Collection<HourStyle> allowed) {
- if (preferred == null) {
- throw new NullPointerException();
- }
- if (!allowed.contains(preferred)) {
- throw new IllegalArgumentException("Allowed (" + allowed +
- ") must contain preferred(" + preferred +
- ")");
- }
- this.preferred = preferred;
- this.allowed = ImmutableList.copyOf(new LinkedHashSet<>(allowed));
- }
-
- public PreferredAndAllowedHour(String preferred2, String allowedString) {
- this(HourStyle.valueOf(preferred2), mungeOperands(allowedString));
- }
-
- private static EnumSet<HourStyle> mungeSet(Collection<Character> allowed) {
- EnumSet<HourStyle> temp = EnumSet.noneOf(HourStyle.class);
- for (char c : allowed) {
- temp.add(HourStyle.valueOf(String.valueOf(c)));
- }
- return temp;
- }
-
- static final Splitter SPACE_SPLITTER = Splitter.on(' ').trimResults();
-
- private static LinkedHashSet<HourStyle> mungeOperands(String allowedString) {
- LinkedHashSet<HourStyle> allowed = new LinkedHashSet<>();
- for (String s : SPACE_SPLITTER.split(allowedString)) {
- allowed.add(HourStyle.valueOf(s));
- }
- return allowed;
+ private PreferredAndAllowedHour(String preferredStyle, Stream<String> allowedStyles) {
+ this.preferred = checkNotNull(HourStyle.valueOf(preferredStyle));
+ this.allowed = allowedStyles.map(HourStyle::valueOf).collect(toImmutableList());
+ checkArgument(allowed.stream().distinct().count() == allowed.size(),
+ "Allowed (%s) must not contain duplicates", allowed);
+ // Note: In *some* cases the preferred style is required to be the first style in
+ // the allowed set, but not always (thus we cannot do a better check here).
+ // TODO: Figure out if we can enforce preferred == first(allowed) here.
+ checkArgument(allowed.contains(preferred),
+ "Allowed (%s) must contain preferred (%s)", allowed, preferred);
}
@Override
- public int compareTo(PreferredAndAllowedHour arg0) {
- int diff = preferred.compareTo(arg0.preferred);
- if (diff != 0) return diff;
- return CollectionUtilities.compare(allowed.iterator(), arg0.allowed.iterator());
+ public int compareTo(PreferredAndAllowedHour other) {
+ return COMPARATOR.compare(this, other);
}
@Override
public String toString() {
- return toString(Collections.singleton("?"));
+ return toString(ImmutableList.of("?"));
}
public String toString(Collection<String> regions) {
+ Joiner withSpaces = Joiner.on(" ");
return "<hours preferred=\""
+ preferred
+ "\" allowed=\""
- + CollectionUtilities.join(allowed, " ")
+ + withSpaces.join(allowed)
+ "\" regions=\""
- + CollectionUtilities.join(regions, " ")
+ + withSpaces.join(regions)
+ "\"/>";
}
diff --git a/tools/java/org/unicode/cldr/util/PrettyPath.java b/tools/java/org/unicode/cldr/util/PrettyPath.java
index 09b5168..30c61d0 100644
--- a/tools/java/org/unicode/cldr/util/PrettyPath.java
+++ b/tools/java/org/unicode/cldr/util/PrettyPath.java
@@ -20,6 +20,7 @@
* @deprecated
* TODO: what is supposed to replace PrettyPath? If no replacement is planned, make it no longer deprecated?
*/
+@Deprecated
public class PrettyPath {
private Transliterator prettyPathZoneTransform;
{
@@ -28,8 +29,8 @@
}
private Transliterator prettyPathTransform = CheckCLDR.getTransliteratorFromFile("ID", "prettyPath.txt");
- private Map<String, String> prettyPath_path = new HashMap<String, String>();
- private Map<String, String> path_prettyPath_sortable = new HashMap<String, String>();
+ private Map<String, String> prettyPath_path = new HashMap<>();
+ private Map<String, String> path_prettyPath_sortable = new HashMap<>();
private boolean showErrors;
/**
@@ -53,7 +54,7 @@
* @return pretty path
*/
public String getPrettyPath(String path, boolean sortable) {
- String prettyString = (String) path_prettyPath_sortable.get(path);
+ String prettyString = path_prettyPath_sortable.get(path);
if (path_prettyPath_sortable.get(path) == null) {
prettyString = prettyPathTransform.transliterate(path);
// some internal errors, shown here for debugging for now.
@@ -80,7 +81,7 @@
}
private void addBackmap(String prettyString, String path, Map<String, String> prettyPath_path_map) {
- String old = (String) prettyPath_path_map.get(prettyString);
+ String old = prettyPath_path_map.get(prettyString);
if (old != null) {
if (showErrors) System.out.println("Warning:\tFailed bijection, " + prettyString);
if (showErrors) System.out.println("Warning:\tPath1: " + path);
@@ -97,7 +98,7 @@
* @return
*/
public String getOriginal(String prettyPath) {
- return (String) prettyPath_path.get(prettyPath);
+ return prettyPath_path.get(prettyPath);
}
/**
diff --git a/tools/java/org/unicode/cldr/util/Quoter.java b/tools/java/org/unicode/cldr/util/Quoter.java
index 722e664..faac5e2 100644
--- a/tools/java/org/unicode/cldr/util/Quoter.java
+++ b/tools/java/org/unicode/cldr/util/Quoter.java
@@ -42,6 +42,7 @@
}
// warning, allows access to internals
+ @Override
public String toString() {
setQuoting(false); // finish quoting
return output.toString();
@@ -53,14 +54,16 @@
public static class RuleQuoter extends Quoter {
private StringBuffer quoteBuffer = new StringBuffer();
+ @Override
public void setQuoting(boolean value) {
if (quoting == value) return;
if (quoting) { // stop quoting
- Utility.appendToRule(output, (int) -1, true, false, quoteBuffer); // close previous quote
+ Utility.appendToRule(output, -1, true, false, quoteBuffer); // close previous quote
}
quoting = value;
}
+ @Override
public Quoter append(String s) {
if (DEBUG) System.out.println("\"" + s + "\"");
if (quoting) {
diff --git a/tools/java/org/unicode/cldr/util/Rational.java b/tools/java/org/unicode/cldr/util/Rational.java
index 88004e5..ad7171f 100644
--- a/tools/java/org/unicode/cldr/util/Rational.java
+++ b/tools/java/org/unicode/cldr/util/Rational.java
@@ -27,7 +27,7 @@
/**
* Very basic class for rational numbers. No attempt to optimize, since it will just
* be used for testing within CLDR.
- *
+ *
* @author markdavis
*
*/
@@ -37,7 +37,7 @@
public final BigInteger denominator;
// Constraints:
- // always stored in normalized form.
+ // always stored in normalized form.
// no common factor > 1 (reduced)
// denominator never negative
// if numerator is zero, denominator is 1 or 0
@@ -53,7 +53,7 @@
public static final Rational TEN = Rational.of(10, 1);
public static final Rational TENTH = TEN.reciprocal();
-
+
public static final char REPTEND_MARKER = '˙';
public static class RationalParser implements Freezable<RationalParser>{
@@ -71,12 +71,12 @@
throw new IllegalArgumentException("Can't reset constant " + id + " = " + value);
}
if (status != null) {
- constantStatus.put(id, status);
+ constantStatus.put(id, status);
}
return this;
}
- /*
+ /*
* input = comp (/ comp)?
* comp = comp2 (* comp2)*
* comp2 = digits (. digits)? | constant
@@ -277,8 +277,8 @@
public static Rational of(BigDecimal bigDecimal) {
// scale()
- // If zero or positive, the scale is the number of digits to the right of the decimal point.
- // If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.
+ // If zero or positive, the scale is the number of digits to the right of the decimal point.
+ // If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.
// For example, a scale of -3 means the unscaled value is multiplied by 1000.
final int scale = bigDecimal.scale();
final BigInteger unscaled = bigDecimal.unscaledValue();
@@ -312,8 +312,8 @@
final boolean denIsOne = newDenominator.equals(BigInteger.ONE);
switch (style) {
- case repeating:
- String result = toRepeating(30); // limit of 30 on the repeating length, so we don't get crazy
+ case repeating:
+ String result = toRepeating(30); // limit of 30 on the repeating length, so we don't get unreasonable
if (result != null) {
return result;
}
@@ -338,7 +338,7 @@
* Only for large/small numbers, eg:
* ≥ 1,000,000.0, => 1×10<sup>6</sup> — more than 6 trailing 0's
* ≤ 0.0000001 — more than 6 leading zeros
- *
+ *
* relevant BigDecimal APIs:
* 123.4567 scale: 4 bigint: 1234567
* 123456700 scale: 0 bigint: 123456700
@@ -382,7 +382,7 @@
/**
- * Goal is to be able to display rationals in a short but exact form, like 1,234,567/3 or 1.234567E21/3.
+ * Goal is to be able to display rationals in a short but exact form, like 1,234,567/3 or 1.234567E21/3.
* To do this, find the smallest denominator (excluding powers of 2 and 5), and modify the numerator in the same way.
* @param denominator TODO
* @param current
diff --git a/tools/java/org/unicode/cldr/util/RecordingCLDRFile.java b/tools/java/org/unicode/cldr/util/RecordingCLDRFile.java
new file mode 100644
index 0000000..8ba4a2d
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/RecordingCLDRFile.java
@@ -0,0 +1,54 @@
+package org.unicode.cldr.util;
+
+import java.util.HashSet;
+
+/**
+ * Like CLDRFile, with an added feature for recording the paths for which
+ * getStringValue, etc., are called.
+ *
+ * The first intended usage is for TestExampleDependencies, to identify all the paths on
+ * which a given example depends. Before calling ExampleGenerator.getExampleHtml, TestExampleDependencies
+ * calls clearRecordedPaths. After getting each example, TestExampleDependencies calls getRecordedPaths
+ * to get the set of all paths in this file that were accessed to generate the example.
+ */
+public class RecordingCLDRFile extends CLDRFile {
+ private HashSet<String> recordedPaths = new HashSet<>();
+
+ public RecordingCLDRFile(XMLSource dataSource) {
+ super(dataSource);
+ }
+
+ public RecordingCLDRFile(XMLSource dataSource, XMLSource... resolvingParents) {
+ super(dataSource, resolvingParents);
+ }
+
+ public void clearRecordedPaths() {
+ recordedPaths.clear();
+ }
+
+ public HashSet<String> getRecordedPaths() {
+ return recordedPaths;
+ }
+
+ @Override
+ public String getStringValue(String xpath) {
+ recordPath(xpath);
+ return super.getStringValue(xpath);
+ }
+
+ @Override
+ public String getWinningValue(String xpath) {
+ recordPath(xpath);
+ return super.getWinningValue(xpath);
+ }
+
+ @Override
+ public String getConstructedValue(String xpath) {
+ recordPath(xpath);
+ return super.getConstructedValue(xpath);
+ }
+
+ private void recordPath(String xpath) {
+ recordedPaths.add(xpath);
+ }
+}
diff --git a/tools/java/org/unicode/cldr/util/ReferenceStringSearch.java b/tools/java/org/unicode/cldr/util/ReferenceStringSearch.java
index 4bad166..d0a3382 100644
--- a/tools/java/org/unicode/cldr/util/ReferenceStringSearch.java
+++ b/tools/java/org/unicode/cldr/util/ReferenceStringSearch.java
@@ -66,6 +66,7 @@
public static class ExtendedRange {
int minStart, maxStart, minLimit, maxLimit;
+ @Override
public String toString() {
return minStart + ", " + maxStart + ", " + minLimit + ", " + maxLimit;
}
@@ -86,6 +87,7 @@
public int start;
public int limit;
+ @Override
public String toString() {
return start + ", " + limit;
}
@@ -164,7 +166,7 @@
public ReferenceStringSearch setKey(String key) {
this.key = key;
- ArrayList<Integer> keyBufferList = new ArrayList<Integer>();
+ ArrayList<Integer> keyBufferList = new ArrayList<>();
CollationElementIterator2 keyIterator = new CollationElementIterator2(collator).setText(key);
while (true) {
int collationElement = keyIterator.nextProcessed();
diff --git a/tools/java/org/unicode/cldr/util/RegexLogger.java b/tools/java/org/unicode/cldr/util/RegexLogger.java
index ae890f3..c3f9f24 100644
--- a/tools/java/org/unicode/cldr/util/RegexLogger.java
+++ b/tools/java/org/unicode/cldr/util/RegexLogger.java
@@ -164,10 +164,12 @@
}
+ @Override
public void log(Pattern pattern, String matchStr, boolean matched, LogType type, Class<?> cls) {
log(pattern.pattern(), matchStr, matched, type, cls);
}
+ @Override
public void log(String pattern, String matchStr, boolean matched, LogType type, Class<?> cls) {
log(pattern, matchStr, matched, 0, type, cls);
}
@@ -175,6 +177,7 @@
/**
* Get all entries
*/
+ @Override
public NavigableSet<PatternCountInterface> getEntries() {
return getEntries(1);
}
@@ -200,7 +203,7 @@
@Override
public NavigableSet<PatternCountInterface> getEntries(int minCount) {
- NavigableSet<PatternCountInterface> returned = (NavigableSet<PatternCountInterface>) Sets.newTreeSet(Collections.EMPTY_SET);
+ NavigableSet<PatternCountInterface> returned = Sets.newTreeSet(Collections.EMPTY_SET);
return returned;
}
}
@@ -297,6 +300,7 @@
super(minCount, c);
}
+ @Override
public void process(PatternStringWithBoolean item, Multiset<PatternStringWithBoolean> countSet) {
if (countSet.count(item) >= minCount) {
super.process(item, countSet);
@@ -361,6 +365,7 @@
this.callLocations);
}
+ @Override
public String getPattern() {
return pattern;
}
@@ -473,7 +478,12 @@
break;
}
if (current.startsWith("org.unicode.cldr.test.CheckCLDR") &&
- !lastClass.startsWith("org.unicode.cldr.test.CheckCLDR")) {
+ /*
+ * TODO: fix this function to avoid referencing lastClass when it is null.
+ * The condition lastClass == null here prevents compiler warning/error or possible NullPointerException,
+ * since lastClass is ALWAYS null here; but this is obviously not the best solution.
+ */
+ (lastClass == null || !lastClass.startsWith("org.unicode.cldr.test.CheckCLDR"))) {
lastClass = current;
// leave out
continue;
@@ -556,6 +566,7 @@
private final Multimap<PatternStringWithBoolean, String> occurrences = TreeMultimap.create();
private final IterableTransformer<String, String> transformer = new StringIterableTransformer();
+ @Override
public void log(String pattern, String matchStr, boolean matched, double time, LogType type, Class<?> cls) {
boolean isRegexFinder = findClassName("org.unicode.cldr.util.RegexLookup", 10);
PatternStringWithBoolean key = new PatternStringWithBoolean(pattern, isRegexFinder);
@@ -663,6 +674,7 @@
return ret;
}
+ @Override
public NavigableSet<PatternCountInterface> getEntries(final int minCount) {
CountSets c = new CountSets(matchedFindSet, failedFindSet, matchedMatchSet, failedMatchSet, occurrences);
final AddAllEntryProcessor processor = (minCount == 1) ? new AddAllEntryProcessor(minCount, c) : new EntryProcessor(minCount, c);
diff --git a/tools/java/org/unicode/cldr/util/RegexLookup.java b/tools/java/org/unicode/cldr/util/RegexLookup.java
index ecda0b4..9a4e51e 100644
--- a/tools/java/org/unicode/cldr/util/RegexLookup.java
+++ b/tools/java/org/unicode/cldr/util/RegexLookup.java
@@ -44,7 +44,7 @@
public enum LookupType {
STAR_PATTERN_LOOKUP, OPTIMIZED_DIRECTORY_PATTERN_LOOKUP, STANDARD
- };
+ }
private LookupType _lookupType;
@@ -73,14 +73,14 @@
switch (type) {
case STAR_PATTERN_LOOKUP:
// SPEntries = new StarPatternMap<T>();
- storage = new StarPatternMap<T>();
+ storage = new StarPatternMap<>();
break;
case OPTIMIZED_DIRECTORY_PATTERN_LOOKUP:
// RTEntries = new RegexTree<T>();
- storage = new RegexTree<T>();
+ storage = new RegexTree<>();
break;
default:
- MEntries = new LinkedHashMap<Finder, T>();
+ MEntries = new LinkedHashMap<>();
break;
}
}
@@ -130,6 +130,7 @@
* Call Matches on the pattern, returning additional information in the Info field,
* if it is non null
*/
+ @Override
public boolean matches(String item, Object context, Info info) {
synchronized (matcher) {
try {
@@ -166,6 +167,7 @@
* Call find() on the pattern, returning additional information in the info field,
* if it is non-null
*/
+ @Override
public boolean find(String item, Object context, Info info) {
synchronized (matcher) {
try {
@@ -181,6 +183,7 @@
}
}
+ @Override
public String toString() {
// Use pattern here, to avoid having to synchronize on matcher
return pattern.pattern();
@@ -258,8 +261,8 @@
@Override
public List<T> getAll(String pattern, Object context, List<Finder> matcherList, Output<String[]> firstInfo) {
- List<RTNode> list = new ArrayList<RTNode>();
- List<T> retList = new ArrayList<T>();
+ List<RTNode> list = new ArrayList<>();
+ List<T> retList = new ArrayList<>();
root.addToList(pattern, context, list);
Collections.sort(list, rankComparator);
@@ -289,8 +292,9 @@
return retList;
}
+ @Override
public T get(String pattern, Object context, Output<String[]> arguments, Output<Finder> matcherFound) {
- List<Finder> matcherList = new ArrayList<Finder>();
+ List<Finder> matcherList = new ArrayList<>();
Output<String[]> firstInfo = new Output<>();
List<T> matches = getAll(pattern, context, matcherList, firstInfo); //need to get whole list because we want value that was entered first
if (arguments != null) {
@@ -305,9 +309,10 @@
return (matches.size() > 0) ? matches.get(0) : null;
}
+ @Override
public Set<Entry<Finder, T>> entrySet() {
- LinkedHashMap<Finder, T> ret = new LinkedHashMap<Finder, T>();
- TreeSet<RTNode> s = new TreeSet<RTNode>(rankComparator);
+ LinkedHashMap<Finder, T> ret = new LinkedHashMap<>();
+ TreeSet<RTNode> s = new TreeSet<>(rankComparator);
root.addToEntrySet(s);
for (RTNode n : s) {
@@ -320,7 +325,7 @@
public class RTNode extends NodeBase<T> {
// Finder _finder;
// T _val;
- List<RTNode> _children = new ArrayList<RTNode>();
+ List<RTNode> _children = new ArrayList<>();
int _rank = -1; //rank -1 means the node was not inserted, but only used for structural purposes
//constructor for regular nodes with a Finder
@@ -498,6 +503,7 @@
}
}
+ @Override
public String toString() {
return toString("", new StringBuilder()).toString();
}
@@ -523,6 +529,7 @@
}
class RTNodeRankComparator implements Comparator<RTNode> {
+ @Override
public int compare(RTNode a, RTNode b) {
if (a == b) {
return 0;
@@ -540,6 +547,7 @@
}
}
+ @Override
public String toString() {
return root.toString();
}
@@ -550,21 +558,23 @@
private int _size = 0;
public StarPatternMap() {
- _spmap = new HashMap<String, List<SPNode>>();
+ _spmap = new HashMap<>();
// _size = 0;
}
+ @Override
public int size() {
return _size;
}
+ @Override
public void put(Finder pattern, T value) {
//System.out.println("pattern.toString() is => "+pattern.toString());
String starPattern = pathStarrer.transform2(pattern.toString().replaceAll("\\(\\[\\^\"\\]\\*\\)", "*"));
//System.out.println("Putting => "+starPattern);
List<SPNode> candidates = _spmap.get(starPattern);
if (candidates == null) {
- candidates = new ArrayList<SPNode>();
+ candidates = new ArrayList<>();
}
SPNode newNode = new SPNode(pattern, value);
candidates.add(newNode);
@@ -572,6 +582,7 @@
_size++;
}
+ @Override
public T get(Finder finder) {
String starPattern = pathStarrer.transform2(finder.toString());
List<SPNode> candidates = _spmap.get(starPattern);
@@ -586,9 +597,10 @@
return null;
}
+ @Override
public List<T> getAll(String pattern, Object context, List<Finder> matcherList, Output<String[]> firstInfo) {
- List<SPNode> list = new ArrayList<SPNode>();
- List<T> retList = new ArrayList<T>();
+ List<SPNode> list = new ArrayList<>();
+ List<T> retList = new ArrayList<>();
String starPattern = pathStarrer.transform2(pattern);
List<SPNode> candidates = _spmap.get(starPattern);
@@ -615,8 +627,9 @@
return retList;
}
+ @Override
public T get(String pattern, Object context, Output<String[]> arguments, Output<Finder> matcherFound) {
- List<Finder> matcherList = new ArrayList<Finder>();
+ List<Finder> matcherList = new ArrayList<>();
Output<String[]> firstInfo = new Output<>();
List<T> matches = getAll(pattern, context, matcherList, firstInfo); //need to get whole list because we want value that was entered first
if (arguments != null && firstInfo.value != null) {
@@ -629,8 +642,9 @@
return (matches.size() > 0) ? matches.get(0) : null;
}
+ @Override
public Set<Entry<Finder, T>> entrySet() {
- LinkedHashMap<Finder, T> ret = new LinkedHashMap<Finder, T>();
+ LinkedHashMap<Finder, T> ret = new LinkedHashMap<>();
for (Entry<String, List<SPNode>> entry : _spmap.entrySet()) {
List<SPNode> candidates = entry.getValue();
@@ -656,6 +670,7 @@
super(finder, val);
}
+ @Override
public String toString() {
return this._finder.toString();
}
@@ -681,6 +696,7 @@
}
public static Transform<String, RegexFinder> RegexFinderTransform = new Transform<String, RegexFinder>() {
+ @Override
public RegexFinder transform(String source) {
return new RegexFinder(source);
}
@@ -691,6 +707,7 @@
* with XPaths.
*/
public static Transform<String, RegexFinder> RegexFinderTransformPath = new Transform<String, RegexFinder>() {
+ @Override
public RegexFinder transform(String source) {
final String newSource = source.replace("[@", "\\[@");
return new RegexFinder(newSource.startsWith("//")
@@ -704,6 +721,7 @@
* To work better with XPaths.
*/
public static Transform<String, RegexFinder> RegexFinderTransformPath2 = new Transform<String, RegexFinder>() {
+ @Override
public RegexFinder transform(String source) {
final String newSource = source.replace("[@", "\\[@").replace('\'', '"');
return new RegexFinder(newSource.startsWith("//")
@@ -881,7 +899,7 @@
return null;
} else {
//slow but versatile implementation
- List<T> matches = new ArrayList<T>();
+ List<T> matches = new ArrayList<>();
for (Map.Entry<Finder, T> entry : MEntries.entrySet()) {
Finder matcher = entry.getKey();
Info firstInfo = new Info();
@@ -963,6 +981,7 @@
/**
* @deprecated Use {@link #of(LookupType,Transform)} instead
*/
+ @Deprecated
public static <T> RegexLookup<T> of(LookupType lookupType) {
return of(lookupType, RegexFinderTransform);
}
diff --git a/tools/java/org/unicode/cldr/util/SemiFileReader.java b/tools/java/org/unicode/cldr/util/SemiFileReader.java
index 9a8bce7..94d5919 100644
--- a/tools/java/org/unicode/cldr/util/SemiFileReader.java
+++ b/tools/java/org/unicode/cldr/util/SemiFileReader.java
@@ -7,6 +7,7 @@
protected abstract boolean handleLine(int lineCount, int start, int end, String[] items);
+ @Override
protected void handleEnd() {
}
diff --git a/tools/java/org/unicode/cldr/util/SetComparator.java b/tools/java/org/unicode/cldr/util/SetComparator.java
index c119139..77d5448 100644
--- a/tools/java/org/unicode/cldr/util/SetComparator.java
+++ b/tools/java/org/unicode/cldr/util/SetComparator.java
@@ -5,6 +5,7 @@
import java.util.Set;
public class SetComparator<T extends Comparable<T>> implements Comparator<Set<T>> {
+ @Override
public int compare(Set<T> o1, Set<T> o2) {
int size1 = o1.size();
int size2 = o2.size();
diff --git a/tools/java/org/unicode/cldr/util/SimpleDictionary.java b/tools/java/org/unicode/cldr/util/SimpleDictionary.java
index 3216f73..50fcc01 100644
--- a/tools/java/org/unicode/cldr/util/SimpleDictionary.java
+++ b/tools/java/org/unicode/cldr/util/SimpleDictionary.java
@@ -24,7 +24,7 @@
* @author markdavis
*/
public class SimpleDictionary<T> extends Dictionary<T> {
- private TreeMap<CharSequence, T> data = new TreeMap<CharSequence, T>();
+ private TreeMap<CharSequence, T> data = new TreeMap<>();
private Set<CharSequence> possibleMatchesBefore;
private Set<CharSequence> possibleMatchesAfter;
private Status finalStatus;
@@ -34,6 +34,7 @@
public static class SimpleDictionaryBuilder<T> implements DictionaryBuilder<T> {
+ @Override
public SimpleDictionary<T> make(Map<CharSequence, T> source) {
return new SimpleDictionary(source);
}
@@ -77,6 +78,7 @@
data.put(text, result);
}
+ @Override
public Iterator<Entry<CharSequence, T>> getMapping() {
return Collections.unmodifiableMap(data).entrySet().iterator();
}
@@ -168,6 +170,7 @@
return finalStatus = Status.PARTIAL;
}
+ @Override
public boolean nextUniquePartial() {
// we have already set the matchValue, so we don't need to reset here.
return matchCount == 1;
@@ -182,7 +185,7 @@
*/
private CharSequence filterToStartsWith(CharSequence probe) {
CharSequence result = null;
- possibleMatchesAfter = new TreeSet<CharSequence>();
+ possibleMatchesAfter = new TreeSet<>();
for (CharSequence item : possibleMatchesBefore) {
if (startsWith(item, probe)) {
if (result == null) {
diff --git a/tools/java/org/unicode/cldr/util/SimpleEquivalenceClass.java b/tools/java/org/unicode/cldr/util/SimpleEquivalenceClass.java
index 80005e6..4bf7319 100644
--- a/tools/java/org/unicode/cldr/util/SimpleEquivalenceClass.java
+++ b/tools/java/org/unicode/cldr/util/SimpleEquivalenceClass.java
@@ -61,14 +61,17 @@
}
}
+ @Override
public boolean hasNext() {
return it.hasNext();
}
+ @Override
public Object next() {
return it.next();
}
+ @Override
public void remove() {
throw new IllegalArgumentException("can't remove");
}
@@ -78,6 +81,7 @@
return new MyIterator(comp);
}
+ @Override
public String toString() {
return itemToSet.values().toString();
}
diff --git a/tools/java/org/unicode/cldr/util/SimpleFactory.java b/tools/java/org/unicode/cldr/util/SimpleFactory.java
index 4548019..fc04e5d 100644
--- a/tools/java/org/unicode/cldr/util/SimpleFactory.java
+++ b/tools/java/org/unicode/cldr/util/SimpleFactory.java
@@ -60,6 +60,8 @@
private static final boolean DEBUG_SIMPLEFACTORY = false;
+ private static final boolean USE_COMBINEDCACHE = false;
+
/**
* Simple class used as a key for the map that holds the CLDRFiles -only used in the new version of the code
* @author ribnitz
@@ -128,6 +130,7 @@
return true;
}
+ @Override
public String toString() {
return "[ LocaleName: " + localeName + " Resolved: " + resolved + " Draft status: " + draftStatus + " Directories: " + directories + " ]";
}
@@ -283,7 +286,7 @@
// private volatile CLDRFile result; // used in handleMake
private File sourceDirectories[];
- private Set<String> localeList = new TreeSet<String>();
+ private Set<String> localeList = new TreeSet<>();
private Cache<CLDRCacheKey, CLDRFile> combinedCache = null;
//private Map<CLDRCacheKey,CLDRFile> combinedCache= null;
// Collections.synchronizedMap(new LruMap<CLDRCacheKey, CLDRFile>(CACHE_LIMIT));
@@ -306,6 +309,7 @@
private SimpleFactory() {
}
+ @Override
public DraftStatus getMinimalDraftStatus() {
return minimalDraftStatus;
}
@@ -372,6 +376,8 @@
* @return
*/
public static Factory make(File sourceDirectory[], String matchString, DraftStatus minimalDraftStatus) {
+ // TODO change API to take list
+ sourceDirectory = filterOutNulls(sourceDirectory);
if (!CACHE_SIMPLE_FACTORIES) {
return new SimpleFactory(sourceDirectory, matchString, minimalDraftStatus);
}
@@ -419,6 +425,16 @@
}
}
+ private static File[] filterOutNulls(File[] sourceDirectory) {
+ List<File> result = new ArrayList<>();
+ for (File f : sourceDirectory) {
+ if (f != null) {
+ result.add(f);
+ }
+ }
+ return result.toArray(new File[result.size()]);
+ }
+
@SuppressWarnings("unchecked")
private SimpleFactory(File sourceDirectories[], String matchString, DraftStatus minimalDraftStatus) {
// initialize class based
@@ -462,6 +478,7 @@
return sb.toString();
}
+ @Override
protected Set<String> handleGetAvailable() {
return localeList;
}
@@ -484,6 +501,7 @@
* Make a CLDR file. The result is a locked file, so that it can be cached. If you want to modify it,
* use clone().
*/
+ @Override
@SuppressWarnings("unchecked")
public CLDRFile handleMake(String localeName, boolean resolved, DraftStatus minimalDraftStatus) {
@SuppressWarnings("rawtypes")
@@ -497,6 +515,27 @@
// changed from IllegalArgumentException, which does't let us filter exceptions.
throw new NoSourceDirectoryException(localeName);
}
+
+ // disabling SimpleFactory.combinedCache and only use XMLNormalizingLoader.cache to avoid double-caching
+ if (!USE_COMBINEDCACHE) {
+ CLDRFile result = null; // result of the lookup / generation
+ if (resolved) {
+ ResolvingSource makeResolvingSource;
+ try {
+ makeResolvingSource = makeResolvingSource(localeName, minimalDraftStatus);
+ } catch (Exception e) {
+ throw new ICUException("Couldn't make resolved CLDR file for " + localeName, e);
+ }
+ result = new CLDRFile(makeResolvingSource);
+ } else {
+ if (parentDirs != null) {
+ result = new CLDRFile(localeName, parentDirs, minimalDraftStatus);
+ result.freeze();
+ }
+ }
+ return result;
+ }
+
final Object cacheKey;
CLDRFile result; // result of the lookup / generation
if (USE_OLD_HANDLEMAKE_CODE) {
@@ -554,7 +593,8 @@
sb.append(minimalDraftStatus);
System.out.println(sb.toString());
}
- result = makeFile(localeName, parentDirs, minimalDraftStatus);
+ // result = makeFile(localeName, parentDirs, minimalDraftStatus);
+ result = new CLDRFile(localeName, parentDirs, minimalDraftStatus);
result.freeze();
}
}
diff --git a/tools/java/org/unicode/cldr/util/SimpleHtmlParser.java b/tools/java/org/unicode/cldr/util/SimpleHtmlParser.java
index cdde571..7a63985 100644
--- a/tools/java/org/unicode/cldr/util/SimpleHtmlParser.java
+++ b/tools/java/org/unicode/cldr/util/SimpleHtmlParser.java
@@ -69,11 +69,11 @@
* '<element>' contents '</element>'
*/
ELEMENT_CONTENT
- };
+ }
private enum State {
BASE, IN_ELEMENT, AFTER_ELEMENT, IN_CONTENT, IN_ATTRIBUTE, IN_ATTRIBUTE_CONTENT, IN_ATTRIBUTE_CONTENT1, IN_ATTRIBUTE_CONTENT2, ELEMENT_STOP, IN_QUOTE
- };
+ }
private Reader input;
diff --git a/tools/java/org/unicode/cldr/util/SimpleXMLSource.java b/tools/java/org/unicode/cldr/util/SimpleXMLSource.java
index 7fa5887..c213626 100644
--- a/tools/java/org/unicode/cldr/util/SimpleXMLSource.java
+++ b/tools/java/org/unicode/cldr/util/SimpleXMLSource.java
@@ -40,17 +40,19 @@
locked = true;
}
+ @Override
public String getValueAtDPath(String xpath) {
- return (String) xpath_value.get(xpath);
+ return xpath_value.get(xpath);
}
-
+
public String getValueAtDPathSkippingInheritanceMarker(String xpath) {
- String result = (String) xpath_value.get(xpath);
+ String result = xpath_value.get(xpath);
return CldrUtility.INHERITANCE_MARKER.equals(result) ? null : result;
}
+ @Override
public String getFullPathAtDPath(String xpath) {
- String result = (String) xpath_fullXPath.get(xpath);
+ String result = xpath_fullXPath.get(xpath);
if (result != null) return result;
if (xpath_value.get(xpath) != null) return xpath; // we don't store duplicates
// System.err.println("WARNING: "+getLocaleID()+": path not present in data: " + xpath);
@@ -58,10 +60,12 @@
return null; // throw new IllegalArgumentException("Path not present in data: " + xpath);
}
+ @Override
public Comments getXpathComments() {
return xpath_comments;
}
+ @Override
public void setXpathComments(Comments xpath_comments) {
this.xpath_comments = xpath_comments;
}
@@ -74,6 +78,7 @@
// xpath_fullXPath.put(distinguishingXPath, fixedPath[0]);
// }
// }
+ @Override
public void removeValueAtDPath(String distinguishingXPath) {
String oldValue = xpath_value.get(distinguishingXPath);
xpath_value.remove(distinguishingXPath);
@@ -81,15 +86,18 @@
updateValuePathMapping(distinguishingXPath, oldValue, null);
}
+ @Override
public Iterator<String> iterator() { // must be unmodifiable or locked
return Collections.unmodifiableSet(xpath_value.keySet()).iterator();
}
+ @Override
public XMLSource freeze() {
locked = true;
return this;
}
+ @Override
public XMLSource cloneAsThawed() {
SimpleXMLSource result = (SimpleXMLSource) super.cloneAsThawed();
result.xpath_comments = (Comments) result.xpath_comments.clone();
@@ -98,10 +106,12 @@
return result;
}
+ @Override
public void putFullPathAtDPath(String distinguishingXPath, String fullxpath) {
xpath_fullXPath.put(distinguishingXPath, fullxpath);
}
+ @Override
public void putValueAtDPath(String distinguishingXPath, String value) {
String oldValue = xpath_value.get(distinguishingXPath);
xpath_value.put(distinguishingXPath, value);
@@ -203,6 +213,7 @@
this.dtdVersionInfo = dtdVersionInfo;
}
+ @Override
public VersionInfo getDtdVersionInfo() {
return dtdVersionInfo;
}
diff --git a/tools/java/org/unicode/cldr/util/SortedBag.java b/tools/java/org/unicode/cldr/util/SortedBag.java
index 521fa9f..edec261 100644
--- a/tools/java/org/unicode/cldr/util/SortedBag.java
+++ b/tools/java/org/unicode/cldr/util/SortedBag.java
@@ -33,6 +33,7 @@
m = new TreeMap(c);
}
+ @Override
public boolean add(Object s) {
Set o = (Set) m.get(s);
if (o == null) {
@@ -44,6 +45,7 @@
return result;
}
+ @Override
public Iterator iterator() {
return new MyIterator();
}
@@ -64,10 +66,12 @@
return ((Set) m.get(mapIterator.next())).iterator();
}
+ @Override
public boolean hasNext() {
return setIterator.hasNext() || mapIterator.hasNext();
}
+ @Override
public Object next() {
if (!setIterator.hasNext()) {
setIterator = getSetIterator();
@@ -75,6 +79,7 @@
return setIterator.next();
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
@@ -83,28 +88,34 @@
/**
*
*/
+ @Override
public void clear() {
m.clear();
}
+ @Override
public int size() {
return size;
}
+ @Override
public boolean isEmpty() {
return size == 0;
}
+ @Override
public boolean contains(Object o) {
Set set = (Set) m.get(o);
if (set == null) return false;
return set.contains(o);
}
+ @Override
public Object[] toArray() {
return toArray(new Object[size]);
}
+ @Override
public Object[] toArray(Object[] a) {
int count = 0;
for (Iterator it = iterator(); it.hasNext();) {
@@ -116,6 +127,7 @@
/* (non-Javadoc)
* @see java.util.Collection#remove(java.lang.Object)
*/
+ @Override
public boolean remove(Object o) {
Set set = (Set) m.get(o);
if (set == null) return false;
@@ -125,6 +137,7 @@
return true;
}
+ @Override
public boolean containsAll(Collection c) {
for (Iterator it = c.iterator(); it.hasNext();) {
if (!contains(it.next())) return false;
@@ -132,6 +145,7 @@
return true;
}
+ @Override
public boolean addAll(Collection c) {
boolean result = false;
for (Iterator it = c.iterator(); it.hasNext();) {
@@ -140,6 +154,7 @@
return result;
}
+ @Override
public boolean removeAll(Collection c) {
boolean result = false;
for (Iterator it = c.iterator(); it.hasNext();) {
@@ -148,6 +163,7 @@
return result;
}
+ @Override
public boolean retainAll(Collection c) {
// WARNING: this may not work if the comparator does not distinguish
// all items that are equals().
diff --git a/tools/java/org/unicode/cldr/util/SpecialLocales.java b/tools/java/org/unicode/cldr/util/SpecialLocales.java
index 67261b4..9d2fe0d 100644
--- a/tools/java/org/unicode/cldr/util/SpecialLocales.java
+++ b/tools/java/org/unicode/cldr/util/SpecialLocales.java
@@ -11,6 +11,9 @@
import java.util.Set;
import java.util.TreeSet;
+import org.unicode.cldr.tool.CLDRFileTransformer;
+import org.unicode.cldr.tool.CLDRFileTransformer.LocaleTransform;
+
import com.ibm.icu.util.ICUUncheckedIOException;
/**
@@ -31,7 +34,7 @@
* Locale may be modified by user. Contents aren't part of CLDR release and may change.
*/
scratch
- };
+ }
/**
* Get the type of this locale
@@ -89,10 +92,10 @@
return singleton;
}
- private Map<CLDRLocale, Type> specials = new HashMap<CLDRLocale, Type>();
- private Map<Type, Set<CLDRLocale>> types = new HashMap<Type, Set<CLDRLocale>>();
- private Map<CLDRLocale, String> comments = new HashMap<CLDRLocale, String>();
- private Set<CLDRLocale> specialsWildcards = new HashSet<CLDRLocale>();
+ private Map<CLDRLocale, Type> specials = new HashMap<>();
+ private Map<Type, Set<CLDRLocale>> types = new HashMap<>();
+ private Map<CLDRLocale, String> comments = new HashMap<>();
+ private Set<CLDRLocale> specialsWildcards = new HashSet<>();
public Set<CLDRLocale> getByTypeInternal(Type t) {
return types.get(t);
@@ -125,6 +128,23 @@
* Internal constructor
*/
private SpecialLocales() {
+ // First, read the algorithmic locales.
+ for(final LocaleTransform lt : CLDRFileTransformer.LocaleTransform.values()) {
+ if(lt.getPolicyIfExisting() != CLDRFileTransformer.PolicyIfExisting.DISCARD) {
+ continue;
+ }
+ // Add each of these as if they were in SpecialLocales.txt
+ CLDRLocale inputLocale = CLDRLocale.getInstance(lt.getInputLocale());
+ CLDRLocale outputLocale = CLDRLocale.getInstance(lt.getOutputLocale());
+
+ // add as readonly
+ addToType(Type.readonly, outputLocale);
+
+ // add similar comment to SpecialLocales.txt
+ comments.put(outputLocale, "@"+outputLocale.getBaseName()+" is generated from @"+inputLocale.getBaseName() +
+ " via transliteration, and so @@ may not be edited directly. Edit @"+inputLocale.getBaseName()+" to make changes.");
+ }
+
// from StandardCodes.java
String line;
int ln = 0;
@@ -143,13 +163,13 @@
if (line.length() == 0)
continue;
List<String> stuff = CldrUtility.splitList(line, ';', true);
- String id = (String) stuff.get(0);
+ String id = stuff.get(0);
boolean includeSublocs = (id.endsWith(INCLUDE_SUBLOCALES));
if (includeSublocs) {
id = id.substring(0, id.length() - INCLUDE_SUBLOCALES.length());
}
- String type = (String) stuff.get(1);
- String comment = (String) stuff.get(2);
+ String type = stuff.get(1);
+ String comment = stuff.get(2);
Type t = null;
// verify that the locale is valid
@@ -168,13 +188,7 @@
+ line);
}
- Set<CLDRLocale> s = types.get(t);
- if (s == null) {
- s = new TreeSet<CLDRLocale>();
- types.put(t, s);
- }
- s.add(l);
- specials.put(l, t);
+ addToType(t, l);
if (includeSublocs) {
specialsWildcards.add(l);
}
@@ -195,4 +209,15 @@
types = Collections.unmodifiableMap(types);
}
+ private Set<CLDRLocale> addToType(Type t, CLDRLocale l) {
+ Set<CLDRLocale> s = types.get(t);
+ if (s == null) {
+ s = new TreeSet<>();
+ types.put(t, s);
+ }
+ s.add(l);
+ specials.put(l, t);
+ return s;
+ }
+
}
diff --git a/tools/java/org/unicode/cldr/util/SpreadSheet.java b/tools/java/org/unicode/cldr/util/SpreadSheet.java
index ae9ab93..1f32693 100644
--- a/tools/java/org/unicode/cldr/util/SpreadSheet.java
+++ b/tools/java/org/unicode/cldr/util/SpreadSheet.java
@@ -15,16 +15,19 @@
}
public static List<List<String>> convert(BufferedReader r) throws IOException {
- List<List<String>> result = new ArrayList<List<String>>();
+ List<List<String>> result = new ArrayList<>();
// boolean inQuote = false;
while (true) {
String line = r.readLine();
if (line == null) break;
+ if (line.startsWith("#")) {
+ continue;
+ }
if (DEBUG) {
System.out.println("Spreadsheet:\t" + line);
}
String[] parts = line.split("\t");
- List<String> row = new ArrayList<String>(parts.length);
+ List<String> row = new ArrayList<>(parts.length);
for (String part : parts) {
if (part.startsWith("\"") && part.endsWith("\"")) {
row.add(part.substring(1, part.length() - 1));
diff --git a/tools/java/org/unicode/cldr/util/StackTracker.java b/tools/java/org/unicode/cldr/util/StackTracker.java
index 18f4d96..7a026d5 100644
--- a/tools/java/org/unicode/cldr/util/StackTracker.java
+++ b/tools/java/org/unicode/cldr/util/StackTracker.java
@@ -33,7 +33,7 @@
*/
@CLDRTool(alias = "test.stacktracker", description = "Test for StackTracker", hidden = "test")
public class StackTracker implements Iterable<Object> {
- private Hashtable<Object, String> stacks = new Hashtable<Object, String>();
+ private Hashtable<Object, String> stacks = new Hashtable<>();
/**
* Add object (i.e. added to cache)
diff --git a/tools/java/org/unicode/cldr/util/StandardCodes.java b/tools/java/org/unicode/cldr/util/StandardCodes.java
index 85d2964..9952e71 100644
--- a/tools/java/org/unicode/cldr/util/StandardCodes.java
+++ b/tools/java/org/unicode/cldr/util/StandardCodes.java
@@ -48,7 +48,7 @@
public class StandardCodes {
public enum CodeType {
- language, script, territory, extlang, grandfathered, redundant, variant, currency, tzid;
+ language, script, territory, extlang, legacy, redundant, variant, currency, tzid;
public static CodeType from(String name) {
if ("region".equals(name)) {
return territory;
@@ -61,7 +61,7 @@
private static final Set<String> TypeStringSet;
static {
- LinkedHashSet<String> foo = new LinkedHashSet<String>();
+ LinkedHashSet<String> foo = new LinkedHashSet<>();
for (CodeType x : CodeType.values()) {
foo.add(x.toString());
}
@@ -74,18 +74,18 @@
private static StandardCodes singleton;
- private EnumMap<CodeType, Map<String, List<String>>> type_code_data = new EnumMap<CodeType, Map<String, List<String>>>(
+ private EnumMap<CodeType, Map<String, List<String>>> type_code_data = new EnumMap<>(
CodeType.class);
- private EnumMap<CodeType, Map<String, List<String>>> type_name_codes = new EnumMap<CodeType, Map<String, List<String>>>(
+ private EnumMap<CodeType, Map<String, List<String>>> type_name_codes = new EnumMap<>(
CodeType.class);
- private EnumMap<CodeType, Map<String, String>> type_code_preferred = new EnumMap<CodeType, Map<String, String>>(
+ private EnumMap<CodeType, Map<String, String>> type_code_preferred = new EnumMap<>(
CodeType.class);
- private Map<String, Set<String>> country_modernCurrency = new TreeMap<String, Set<String>>();
+ private Map<String, Set<String>> country_modernCurrency = new TreeMap<>();
- private Map<CodeType, Set<String>> goodCodes = new TreeMap<CodeType, Set<String>>();
+ private Map<CodeType, Set<String>> goodCodes = new TreeMap<>();
private static final boolean DEBUG = false;
@@ -177,7 +177,7 @@
// position 2.
if (data.size() < 3)
return null;
- String replacement = (String) data.get(2);
+ String replacement = data.get(2);
if (!replacement.equals("") && !replacement.equals("--"))
return replacement;
return null;
@@ -193,7 +193,7 @@
*/
@Deprecated
public List<String> getCodes(String type, String data) {
- return getCodes(CodeType.valueOf(type), data);
+ return getCodes(CodeType.from(type), data);
}
/**
@@ -212,7 +212,7 @@
*/
@Deprecated
public String getPreferred(String type, String code) {
- return getPreferred(CodeType.valueOf(type), code);
+ return getPreferred(CodeType.from(type), code);
}
/**
@@ -284,10 +284,10 @@
SupplementalDataInfo sd = SupplementalDataInfo.getInstance();
if (code_name == null)
return null;
- result = new TreeSet<String>(code_name.keySet());
+ result = new TreeSet<>(code_name.keySet());
switch (type) {
case currency:
- break; // nothing special
+ break; // nothing special
case language:
return sd.getCLDRLanguageCodes();
case script:
@@ -296,7 +296,7 @@
break; // nothing special
default:
for (Iterator<String> it = result.iterator(); it.hasNext();) {
- String code = (String) it.next();
+ String code = it.next();
if (code.equals("root") || code.equals("QO"))
continue;
List<String> data = getFullData(type, code);
@@ -323,7 +323,7 @@
public Set<String> getGoodCountries() {
synchronized (goodCodes) {
if (GOOD_COUNTRIES == null) {
- Set<String> temp = new LinkedHashSet<String>();
+ Set<String> temp = new LinkedHashSet<>();
for (String s : getGoodAvailableCodes(CodeType.territory)) {
if (isCountry(s)) {
temp.add(s);
@@ -342,8 +342,8 @@
return country_modernCurrency.get(countryCode);
}
- private EnumMap<Organization, Map<String, Level>> platform_locale_level = null;
- private EnumMap<Organization, Relation<Level, String>> platform_level_locale = null;
+ private Map<Organization, Map<String, Level>> platform_locale_level = null;
+ private Map<Organization, Relation<Level, String>> platform_level_locale = null;
private Map<String, Map<String, String>> platform_locale_levelString = null;
// /**
@@ -364,6 +364,7 @@
static Comparator caseless = new Comparator() {
+ @Override
public int compare(Object arg0, Object arg1) {
String s1 = (String) arg0;
String s2 = (String) arg1;
@@ -378,6 +379,7 @@
*
* @deprecated
*/
+ @Deprecated
public Map<Organization, Map<String, Level>> getLocaleTypes() {
synchronized (StandardCodes.class) {
if (platform_locale_level == null) {
@@ -492,7 +494,7 @@
}
public Set<String> getLocaleCoverageLocales(Organization organization, Set<Level> choice) {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
for (String locale : getLocaleCoverageLocales(organization)) {
if (choice.contains(getLocaleCoverageLevel(organization, locale))) {
result.add(locale);
@@ -503,7 +505,7 @@
private void loadPlatformLocaleStatus() {
LocaleIDParser parser = new LocaleIDParser();
- platform_locale_level = new EnumMap<Organization, Map<String, Level>>(Organization.class);
+ platform_locale_level = new EnumMap<>(Organization.class);
SupplementalDataInfo sd = SupplementalDataInfo.getInstance();
Set<String> defaultContentLocales = sd.getDefaultContentLocales();
String line;
@@ -531,7 +533,7 @@
}
// verify that the locale is valid BCP47
- String locale = (String) stuff.get(1);
+ String locale = stuff.get(1);
if (!locale.equals("*")) {
parser.set(locale);
String valid = validate(parser);
@@ -546,13 +548,13 @@
}
}
- Level status = Level.get((String) stuff.get(2));
+ Level status = Level.get(stuff.get(2));
if (status == Level.UNDETERMINED) {
System.out.println("Warning: Level unknown on: " + line);
}
Map<String, Level> locale_status = platform_locale_level.get(organization);
if (locale_status == null) {
- platform_locale_level.put(organization, locale_status = new TreeMap<String, Level>());
+ platform_locale_level.put(organization, locale_status = new TreeMap<>());
}
locale_status.put(locale, status);
if (!locale.equals("*")) {
@@ -577,7 +579,7 @@
String language = parser.getLanguage();
if (!language.equals(locale)) {
- Level languageLevel = (Level) locale_level.get(language);
+ Level languageLevel = locale_level.get(language);
if (languageLevel == null || languageLevel.compareTo(childLevel) < 0) {
locale_level.put(language, childLevel);
}
@@ -585,7 +587,7 @@
String oldLanguage = language;
language = parser.getLanguageScript();
if (!language.equals(oldLanguage)) {
- Level languageLevel = (Level) locale_level.get(language);
+ Level languageLevel = locale_level.get(language);
if (languageLevel == null || languageLevel.compareTo(childLevel) < 0) {
locale_level.put(language, childLevel);
}
@@ -593,10 +595,10 @@
}
}
// backwards compat hack
- platform_locale_levelString = new TreeMap<String, Map<String, String>>();
+ platform_locale_levelString = new TreeMap<>();
platform_level_locale = new EnumMap<>(Organization.class);
for (Organization platform : platform_locale_level.keySet()) {
- Map<String, String> locale_levelString = new TreeMap<String, String>();
+ Map<String, String> locale_levelString = new TreeMap<>();
platform_locale_levelString.put(platform.toString(), locale_levelString);
Map<String, Level> locale_level = platform_locale_level.get(platform);
for (String locale : locale_level.keySet()) {
@@ -670,7 +672,7 @@
// ========== PRIVATES ==========
private StandardCodes() {
- String[] files = { /* "lstreg.txt", */"ISO4217.txt" }; // , "TZID.txt"
+ String[] files = { "ISO4217.txt" }; // , "TZID.txt"
type_code_preferred.put(CodeType.tzid, new TreeMap<String, String>());
add(CodeType.language, "root", "Root");
String originalLine = null;
@@ -738,10 +740,10 @@
if (type.equals("currency")) {
// currency | TPE | Timor Escudo | TP | EAST TIMOR | O
if (data.get(3).equals("C")) {
- String country = (String) data.get(1);
+ String country = data.get(1);
Set<String> codes = country_modernCurrency.get(country);
if (codes == null) {
- country_modernCurrency.put(country, codes = new TreeSet<String>());
+ country_modernCurrency.put(country, codes = new TreeSet<>());
}
codes.add(code);
}
@@ -753,7 +755,7 @@
// ArrayList());
String preferred = null;
for (int i = 0; i < pieces.size(); ++i) {
- code = (String) pieces.get(i);
+ code = pieces.get(i);
add(type, code, data);
if (preferred == null)
preferred = code;
@@ -786,7 +788,7 @@
Map<String, Map<String, String>> m = languageRegistry.get(type);
for (String code : m.keySet()) {
Map<String, String> mm = m.get(code);
- List<String> data = new ArrayList<String>(0);
+ List<String> data = new ArrayList<>(0);
data.add(mm.get("Description"));
data.add(mm.get("Added"));
String pref = mm.get("Preferred-Value");
@@ -849,7 +851,7 @@
* @param string3
*/
private void add(CodeType type, String string2, String string3) {
- List<String> l = new ArrayList<String>();
+ List<String> l = new ArrayList<>();
l.add(string3);
add(type, string2, l);
}
@@ -858,10 +860,10 @@
// hack
if (type == CodeType.script) {
if (code.equals("Qaai")) {
- otherData = new ArrayList<String>(otherData);
+ otherData = new ArrayList<>(otherData);
otherData.set(0, "Inherited");
} else if (code.equals("Zyyy")) {
- otherData = new ArrayList<String>(otherData);
+ otherData = new ArrayList<>(otherData);
otherData.set(0, "Common");
}
}
@@ -873,7 +875,7 @@
// add to main list
Map<String, List<String>> code_data = getCodeData(type);
if (code_data == null) {
- code_data = new TreeMap<String, List<String>>();
+ code_data = new TreeMap<>();
type_code_data.put(type, code_data);
}
List<String> lastData = code_data.get(code);
@@ -886,12 +888,12 @@
// now add mapping from name to codes
Map<String, List<String>> name_codes = type_name_codes.get(type);
if (name_codes == null) {
- name_codes = new TreeMap<String, List<String>>();
+ name_codes = new TreeMap<>();
type_name_codes.put(type, name_codes);
}
List<String> codes = name_codes.get(name);
if (codes == null) {
- codes = new ArrayList<String>();
+ codes = new ArrayList<>();
name_codes.put(name, codes);
}
codes.add(code);
@@ -911,7 +913,7 @@
public Map<String, List<String>> getWorldBankInfo() {
if (WorldBankInfo == null) {
List<String> temp = fillFromCommaFile("WorldBankInfo.txt", false);
- WorldBankInfo = new HashMap<String, List<String>>();
+ WorldBankInfo = new HashMap<>();
for (String line : temp) {
List<String> row = CldrUtility.splitList(line, ';', true);
String key = row.get(0);
@@ -928,7 +930,7 @@
public Set<String> getMoribundLanguages() {
if (moribundLanguages == null) {
List<String> temp = fillFromCommaFile("moribund_languages.txt", true);
- moribundLanguages = new TreeSet<String>();
+ moribundLanguages = new TreeSet<>();
moribundLanguages.addAll(temp);
moribundLanguages = CldrUtility.protectCollection(moribundLanguages);
}
@@ -938,7 +940,7 @@
// produces a list of the 'clean' lines
private List<String> fillFromCommaFile(String filename, boolean trim) {
try {
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
String line;
BufferedReader lstreg = CldrUtility.getUTF8Data(filename);
while (true) {
@@ -1024,17 +1026,19 @@
static final String registryName = CldrUtility.getProperty("registry", "language-subtag-registry");
public enum LstrType {
- language("und", "zxx", "mul", "mis", "root"),
- script("Zzzz", "Zsym", "Zxxx", "Zmth"),
- region("ZZ"),
- variant(),
- extlang(true, false),
- grandfathered(true, false),
+ language("und", "zxx", "mul", "mis", "root"),
+ script("Zzzz", "Zsym", "Zxxx", "Zmth"),
+ region("ZZ"),
+ variant(),
+ extlang(true, false),
+ legacy(true, false),
redundant(true, false),
/** specialized codes for validity; TODO: rename LstrType **/
currency(false, true, "XXX"),
subdivision(false, true),
- unit(false, true);
+ unit(false, true),
+ usage(false, true),
+ zone(false, true);
public final Set<String> specials;
public final String unknown;
@@ -1056,7 +1060,7 @@
isUnicode = unicode;
}
- //
+ //
static final Pattern WELLFORMED = Pattern.compile("([0-9]{3}|[a-zA-Z]{2})[a-zA-Z0-9]{1,4}");
boolean isWellFormed(String candidate) {
@@ -1068,8 +1072,30 @@
}
}
+ /**
+ * Generate compatibility string, returning 'territory' instead of 'region', etc.
+ */
public String toCompatString() {
- return this == region ? "territory" : toString();
+ switch (this) {
+ case region: return "territory";
+ case legacy: return "language";
+ case redundant: return "language";
+ default: return toString();
+ }
+ }
+
+ /**
+ * Create LstrType from string, allowing the compat string 'territory'.
+ */
+ public static LstrType fromString(String rawType) {
+ try {
+ return valueOf(rawType);
+ } catch (IllegalArgumentException e) {
+ if ("territory".equals(rawType)) {
+ return region;
+ }
+ throw e;
+ }
}
}
@@ -1120,11 +1146,11 @@
}
private static void initLstr() {
- Map<LstrType, Map<String, Map<LstrField, String>>> result2 = new TreeMap<LstrType, Map<String, Map<LstrField, String>>>();
+ Map<LstrType, Map<String, Map<LstrField, String>>> result2 = new TreeMap<>();
int lineNumber = 1;
- Set<String> funnyTags = new TreeSet<String>();
+ Set<String> funnyTags = new TreeSet<>();
String line;
try {
BufferedReader lstreg = CldrUtility.getUTF8Data(registryName);
@@ -1180,9 +1206,11 @@
LstrField label = LstrField.from(line.substring(0, pos2));
String rest = line.substring(pos2 + 1).trim();
if (label == LstrField.Type) {
- subtagData = CldrUtility.get(result2, lastType = LstrType.valueOf(rest));
+ lastType = rest.equals("grandfathered") ?
+ LstrType.legacy : LstrType.fromString(rest);
+ subtagData = CldrUtility.get(result2, lastType);
if (subtagData == null) {
- result2.put(LstrType.valueOf(rest), subtagData = new TreeMap<String, Map<LstrField, String>>());
+ result2.put(lastType, subtagData = new TreeMap<>());
}
} else if (label == LstrField.Subtag
|| label == LstrField.Tag) {
@@ -1194,7 +1222,7 @@
endTag = lastTag.substring(pos + 2);
lastTag = lastTag.substring(0, pos);
}
- currentData = new TreeMap<LstrField, String>();
+ currentData = new TreeMap<>();
if (endTag == null) {
putSubtagData(lastTag, subtagData, currentData);
languageCount.add(lastType, 1);
@@ -1225,7 +1253,7 @@
// lastRest = translitCache.get(rest);
// }
lastRest = rest;
- String oldValue = (String) CldrUtility.get(currentData, lastLabel);
+ String oldValue = CldrUtility.get(currentData, lastLabel);
if (oldValue != null) {
lastRest = oldValue + DESCRIPTION_SEPARATOR + lastRest;
}
@@ -1243,15 +1271,15 @@
}
}
// copy raw
- Map<LstrType, Map<String, Map<LstrField, String>>> rawLstreg = new TreeMap<LstrType, Map<String, Map<LstrField, String>>>();
+ Map<LstrType, Map<String, Map<LstrField, String>>> rawLstreg = new TreeMap<>();
for (Entry<LstrType, Map<String, Map<LstrField, String>>> entry1 : result2.entrySet()) {
LstrType key1 = entry1.getKey();
- TreeMap<String, Map<LstrField, String>> raw1 = new TreeMap<String, Map<LstrField, String>>();
+ TreeMap<String, Map<LstrField, String>> raw1 = new TreeMap<>();
rawLstreg.put(key1, raw1);
for (Entry<String, Map<LstrField, String>> entry2 : entry1.getValue().entrySet()) {
String key2 = entry2.getKey();
final Map<LstrField, String> value2 = entry2.getValue();
- TreeMap<LstrField, String> raw2 = new TreeMap<LstrField, String>();
+ TreeMap<LstrField, String> raw2 = new TreeMap<>();
raw2.putAll(value2);
raw1.put(key2, raw2);
}
@@ -1260,11 +1288,11 @@
// add extras
for (int i = 0; i < extras.length; ++i) {
- Map<String, Map<LstrField, String>> subtagData = CldrUtility.get(result2, LstrType.valueOf(extras[i][0]));
+ Map<String, Map<LstrField, String>> subtagData = CldrUtility.get(result2, LstrType.fromString(extras[i][0]));
if (subtagData == null) {
- result2.put(LstrType.valueOf(extras[i][0]), subtagData = new TreeMap<String, Map<LstrField, String>>());
+ result2.put(LstrType.fromString(extras[i][0]), subtagData = new TreeMap<>());
}
- Map<LstrField, String> labelData = new TreeMap<LstrField, String>();
+ Map<LstrField, String> labelData = new TreeMap<>();
for (int j = 2; j < extras[i].length; j += 2) {
labelData.put(LstrField.from(extras[i][j]), extras[i][j + 1]);
}
@@ -1282,12 +1310,12 @@
subtagData.put(extras[i][1], labelData);
}
// build compatibility map
- Map<String, Map<String, Map<String, String>>> result = new LinkedHashMap<String, Map<String, Map<String, String>>>();
+ Map<String, Map<String, Map<String, String>>> result = new LinkedHashMap<>();
for (Entry<LstrType, Map<String, Map<LstrField, String>>> entry : result2.entrySet()) {
- Map<String, Map<String, String>> copy2 = new LinkedHashMap<String, Map<String, String>>();
+ Map<String, Map<String, String>> copy2 = new LinkedHashMap<>();
result.put(entry.getKey().toString(), copy2);
for (Entry<String, Map<LstrField, String>> entry2 : entry.getValue().entrySet()) {
- Map<String, String> copy3 = new LinkedHashMap<String, String>();
+ Map<String, String> copy3 = new LinkedHashMap<>();
copy2.put(entry2.getKey(), copy3);
for (Entry<LstrField, String> entry3 : entry2.getValue().entrySet()) {
copy3.put(entry3.getKey().toString(), entry3.getValue());
@@ -1310,7 +1338,7 @@
return subtagData.put(lastTag, currentData);
}
- static Counter<LstrType> languageCount = new Counter<LstrType>();
+ static Counter<LstrType> languageCount = new Counter<>();
public static Counter<LstrType> getLanguageCount() {
return languageCount;
@@ -1339,6 +1367,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, List<ZoneLine>> getZone_rules() {
return zoneParser.getZone_rules();
}
@@ -1346,6 +1375,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, List<String>> getZoneData() {
return zoneParser.getZoneData();
}
@@ -1353,6 +1383,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Set<String> getCanonicalTimeZones() {
return zoneParser.getZoneData().keySet();
}
@@ -1360,6 +1391,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, Set<String>> getCountryToZoneSet() {
return zoneParser.getCountryToZoneSet();
}
@@ -1367,6 +1399,7 @@
/**
* @deprecated
*/
+ @Deprecated
public List<String> getDeprecatedZoneIDs() {
return zoneParser.getDeprecatedZoneIDs();
}
@@ -1374,6 +1407,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Comparator<String> getTZIDComparator() {
return zoneParser.getTZIDComparator();
}
@@ -1381,6 +1415,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, Set<String>> getZoneLinkNew_OldSet() {
return zoneParser.getZoneLinkNew_OldSet();
}
@@ -1388,6 +1423,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, String> getZoneLinkold_new() {
return zoneParser.getZoneLinkold_new();
}
@@ -1395,6 +1431,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map getZoneRuleID_rules() {
return zoneParser.getZoneRuleID_rules();
}
@@ -1402,6 +1439,7 @@
/**
* @deprecated
*/
+ @Deprecated
public Map<String, String> getZoneToCounty() {
return zoneParser.getZoneToCounty();
}
@@ -1409,6 +1447,7 @@
/**
* @deprecated
*/
+ @Deprecated
public String getZoneVersion() {
return zoneParser.getVersion();
}
diff --git a/tools/java/org/unicode/cldr/util/StateDictionary.java b/tools/java/org/unicode/cldr/util/StateDictionary.java
index dd3d682..10e7b2d 100644
--- a/tools/java/org/unicode/cldr/util/StateDictionary.java
+++ b/tools/java/org/unicode/cldr/util/StateDictionary.java
@@ -67,6 +67,7 @@
return new StateMatcher();
}
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
// TreeSet<Row> rowSet = new TreeSet<Row>(builtRows);
@@ -74,9 +75,9 @@
result.append(row.toString()).append(CldrUtility.LINE_SEPARATOR);
}
Map<T, Integer> map = builtResults.getValueMap();
- Set<Pair<Integer, String>> sorted = new TreeSet<Pair<Integer, String>>();
+ Set<Pair<Integer, String>> sorted = new TreeSet<>();
for (T item : map.keySet()) {
- sorted.add(new Pair<Integer, String>(map.get(item), item.toString()));
+ sorted.add(new Pair<>(map.get(item), item.toString()));
}
for (Pair<Integer, String> pair : sorted) {
result.append(pair.getFirst()).append("*=").append(pair.getSecond()).append(CldrUtility.LINE_SEPARATOR);
@@ -84,6 +85,7 @@
return result.toString();
}
+ @Override
public Iterator<Entry<CharSequence, T>> getMapping() {
// TODO Optimize this to only return the items on demand
return new TextFetcher().getWords().entrySet().iterator();
@@ -132,7 +134,7 @@
Uniqueness hasUniqueValue = Uniqueness.UNKNOWN;
- final TreeMap<Byte, Cell> byteToCell = new TreeMap<Byte, Cell>();
+ final TreeMap<Byte, Cell> byteToCell = new TreeMap<>();
// keeps track of the number of cells with returns
transient int returnCount;
@@ -166,6 +168,7 @@
return result;
}
+ @Override
public int compareTo(Object o) {
Row other = (Row) o;
int result;
@@ -197,11 +200,12 @@
return referenceNumber - other.referenceNumber;
}
+ @Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("R" + getReferenceNumber() + hasUniqueValue.debugName() + "{");
boolean first = true;
- Set<Byte> sorted = new TreeSet<Byte>(unsignedByteComparator);
+ Set<Byte> sorted = new TreeSet<>(unsignedByteComparator);
sorted.addAll(byteToCell.keySet());
for (Byte key : sorted) {
if (first) {
@@ -258,6 +262,7 @@
return StateDictionary.addBytes(rowOffset, target, pos);
}
+ @Override
public String toString() {
String result = deltaResult == 0 ? "" : String.valueOf(deltaResult);
if (returns) {
@@ -310,6 +315,7 @@
private int partialMatchValue;
+ @Override
public Status next() {
if (SHOW_DEBUG) {
System.out.println("NEXT: " + this);
@@ -410,6 +416,7 @@
return matchIntValue;
}
+ @Override
public boolean nextUniquePartial() {
if (partialLastRow.hasUniqueValue == Uniqueness.UNIQUE) {
matchValue = builtResults.get(partialMatchValue);
@@ -427,6 +434,7 @@
static final Comparator<Byte> unsignedByteComparator = new Comparator<Byte>() {
+ @Override
public int compare(Byte o1, Byte o2) {
int b1 = o1 & 0xFF;
int b2 = o2 & 0xFF;
@@ -437,6 +445,7 @@
static final Comparator<Row> rowComparator = new Comparator<Row>() {
+ @Override
public int compare(Row row1, Row row2) {
if (row1 == row2) {
return 0;
@@ -497,7 +506,7 @@
private class TextFetcher {
- Map<CharSequence, T> result = new TreeMap<CharSequence, T>();
+ Map<CharSequence, T> result = new TreeMap<>();
byte[] soFar = new byte[builtMaxByteLength];
@@ -507,7 +516,7 @@
StringBuilder debugTreeView = new StringBuilder();
- private HashSet<Row> rowsSeen = new HashSet<Row>();
+ private HashSet<Row> rowsSeen = new HashSet<>();
public Map<CharSequence, T> getWords() {
result.clear();
@@ -517,7 +526,7 @@
public String debugShow() {
rowsSeen.clear();
- Counter<Integer> debugCounter = new Counter<Integer>();
+ Counter<Integer> debugCounter = new Counter<>();
getDebugWords(0, 0, builtBaseRow, Integer.MAX_VALUE);
for (Row row : builtRows) {
debugCounter.add(row.byteToCell.size(), 1);
@@ -543,7 +552,7 @@
rowsSeen.add(row);
}
// walk through the cells, display and recurse
- Set<Byte> sorted = new TreeSet<Byte>(unsignedByteComparator);
+ Set<Byte> sorted = new TreeSet<>(unsignedByteComparator);
sorted.addAll(row.byteToCell.keySet());
for (Byte key : sorted) {
Cell cell = row.byteToCell.get(key);
@@ -605,7 +614,7 @@
*
*/
public void flatten() {
- TreeSet<Row> s = new TreeSet<Row>(builtRows);
+ TreeSet<Row> s = new TreeSet<>(builtRows);
int count = 0;
int oldDepth = 999;
String oldCell = "";
diff --git a/tools/java/org/unicode/cldr/util/StateDictionaryBuilder.java b/tools/java/org/unicode/cldr/util/StateDictionaryBuilder.java
index 39b0fad..a8f18b0 100644
--- a/tools/java/org/unicode/cldr/util/StateDictionaryBuilder.java
+++ b/tools/java/org/unicode/cldr/util/StateDictionaryBuilder.java
@@ -46,7 +46,7 @@
// new ByteString(false); // new
// ByteString(true); //
- private IntMapFactory<T> intMapFactory = new BasicIntMapFactory<T>();
+ private IntMapFactory<T> intMapFactory = new BasicIntMapFactory<>();
/**
* Get/set the IntMapFactory used to store the values for T. The default is BasicIntMapFactory.
@@ -85,17 +85,18 @@
* @param source
* @return
*/
+ @Override
public StateDictionary<T> make(Map<CharSequence, T> source) {
// clear out state
buildingCurrentAddRow = null;
builtTotalBytes = builtTotalStrings = builtMaxByteLength = 0;
- builtRows = new ArrayList<Row>();
+ builtRows = new ArrayList<>();
builtBaseRow = makeRow();
builtResults = intMapFactory.make(source.values());
if (SHOW_SIZE) System.out.println("***VALUE STORAGE: " + builtResults.approximateStorage());
Map<T, Integer> valueToInt = builtResults.getValueMap();
- Map<byte[], Integer> sorted = new TreeMap<byte[], Integer>(SHORTER_BYTE_ARRAY_COMPARATOR);
+ Map<byte[], Integer> sorted = new TreeMap<>(SHORTER_BYTE_ARRAY_COMPARATOR);
for (CharSequence text : source.keySet()) {
sorted.put(byteConverter.toBytes(text), valueToInt.get(source.get(text)));
}
@@ -106,9 +107,9 @@
// now compact the rows
// first find out which rows are equivalent (recursively)
- Map<Row, Row> replacements = new HashMap<Row, Row>();
+ Map<Row, Row> replacements = new HashMap<>();
{
- Map<Row, Row> equivalents = new TreeMap<Row, Row>(StateDictionary.rowComparator);
+ Map<Row, Row> equivalents = new TreeMap<>(StateDictionary.rowComparator);
for (Row row : builtRows) {
Row cardinal = equivalents.get(row);
if (cardinal == null) {
@@ -131,7 +132,7 @@
}
}
// now compact the rows array
- ArrayList<Row> newRows = new ArrayList<Row>();
+ ArrayList<Row> newRows = new ArrayList<>();
for (Row row : builtRows) {
if (!replacements.containsKey(row)) {
newRows.add(row);
@@ -141,7 +142,7 @@
setUniqueValues(builtBaseRow);
builtRows = newRows;
if (SHOW_SIZE) System.out.println("***ROWS: " + builtRows.size());
- return new StateDictionary<T>(builtBaseRow, builtRows, builtResults, builtMaxByteLength, byteConverter);
+ return new StateDictionary<>(builtBaseRow, builtRows, builtResults, builtMaxByteLength, byteConverter);
}
private Row makeRow() {
@@ -237,6 +238,7 @@
static final Comparator<byte[]> SHORTER_BYTE_ARRAY_COMPARATOR = new Comparator<byte[]>() {
+ @Override
public int compare(byte[] o1, byte[] o2) {
int minLen = o1.length;
if (minLen > o2.length) {
diff --git a/tools/java/org/unicode/cldr/util/StringId.java b/tools/java/org/unicode/cldr/util/StringId.java
index d7e83f3..6f573c1 100644
--- a/tools/java/org/unicode/cldr/util/StringId.java
+++ b/tools/java/org/unicode/cldr/util/StringId.java
@@ -14,8 +14,8 @@
* @author markdavis
*/
public final class StringId {
- private static final Map<String, Long> STRING_TO_ID = new ConcurrentHashMap<String, Long>();
- private static final Map<Long, String> ID_TO_STRING = new ConcurrentHashMap<Long, String>();
+ private static final Map<String, Long> STRING_TO_ID = new ConcurrentHashMap<>();
+ private static final Map<Long, String> ID_TO_STRING = new ConcurrentHashMap<>();
private static final MessageDigest digest;
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final int RETRY_LIMIT = 9;
diff --git a/tools/java/org/unicode/cldr/util/StringRange.java b/tools/java/org/unicode/cldr/util/StringRange.java
index c846f73..36d5f8a 100644
--- a/tools/java/org/unicode/cldr/util/StringRange.java
+++ b/tools/java/org/unicode/cldr/util/StringRange.java
@@ -120,7 +120,6 @@
}
}
}
- ;
return ranges;
}
diff --git a/tools/java/org/unicode/cldr/util/StripUTF8BOMInputStream.java b/tools/java/org/unicode/cldr/util/StripUTF8BOMInputStream.java
index ee91116..eca3a4b 100644
--- a/tools/java/org/unicode/cldr/util/StripUTF8BOMInputStream.java
+++ b/tools/java/org/unicode/cldr/util/StripUTF8BOMInputStream.java
@@ -10,11 +10,11 @@
import java.io.IOException;
import java.io.InputStream;
-class StripUTF8BOMInputStream extends InputStream {
+public class StripUTF8BOMInputStream extends InputStream {
InputStream base;
- StripUTF8BOMInputStream(InputStream base) {
- this.base = base;
+ public StripUTF8BOMInputStream(InputStream base) {
+ this.base = InputStreamFactory.buffer(base);
}
boolean checkForUTF8BOM = true;
@@ -24,6 +24,7 @@
*
* @see java.io.InputStream#read()
*/
+ @Override
public int read() throws IOException {
int result = base.read();
if (!checkForUTF8BOM) return result;
@@ -37,4 +38,13 @@
return result;
}
+ @Override
+ public void close() throws IOException {
+ super.close();
+ if (base != null) {
+ base.close();
+ base = null;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/SupplementalDataInfo.java b/tools/java/org/unicode/cldr/util/SupplementalDataInfo.java
index 5b87847..f1056a7 100644
--- a/tools/java/org/unicode/cldr/util/SupplementalDataInfo.java
+++ b/tools/java/org/unicode/cldr/util/SupplementalDataInfo.java
@@ -1,7 +1,8 @@
package org.unicode.cldr.util;
+import static org.unicode.cldr.util.PathUtilities.getNormalizedPathString;
+
import java.io.File;
-import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -44,13 +45,13 @@
import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count;
import org.unicode.cldr.util.Validity.Status;
+import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
-import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.IterableComparator;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Row;
@@ -94,6 +95,8 @@
private static final StandardCodes sc = StandardCodes.make();
private static final String UNKNOWN_SCRIPT = "Zzzz";
+ public static final Splitter split_space = Splitter.on(' ').omitEmptyStrings();
+
// TODO add structure for items shown by TestSupplementalData to be missing
/*
* [calendarData/calendar,
@@ -136,7 +139,7 @@
public boolean isOfficial() {
return compareTo(OfficialStatus.official_regional) >= 0;
}
- };
+ }
/**
* Population data for different languages.
@@ -230,6 +233,7 @@
gdp += other.gdp;
}
+ @Override
public String toString() {
return MessageFormat
.format(
@@ -239,15 +243,18 @@
private boolean frozen;
+ @Override
public boolean isFrozen() {
return frozen;
}
+ @Override
public PopulationData freeze() {
frozen = true;
return this;
}
+ @Override
public PopulationData cloneAsThawed() {
throw new UnsupportedOperationException("not yet implemented");
}
@@ -284,7 +291,7 @@
com.ibm.icu.util.Freezable<BasicLanguageData> {
public enum Type {
primary, secondary
- };
+ }
private Type type = Type.primary;
@@ -365,13 +372,15 @@
+ (type == Type.primary ? "" : " alt=\"" + type + "\"") + "/>";
}
+ @Override
public String toString() {
return "[" + type
- + (scripts.isEmpty() ? "" : "; scripts=" + CollectionUtilities.join(scripts, " "))
- + (scripts.isEmpty() ? "" : "; territories=" + CollectionUtilities.join(territories, " "))
+ + (scripts.isEmpty() ? "" : "; scripts=" + Joiner.on(" ").join(scripts))
+ + (scripts.isEmpty() ? "" : "; territories=" + Joiner.on(" ").join(territories))
+ "]";
}
+ @Override
public int compareTo(BasicLanguageData o) {
int result;
if (0 != (result = type.compareTo(o.type)))
@@ -383,6 +392,7 @@
return 0;
}
+ @Override
public boolean equals(Object input) {
return compareTo((BasicLanguageData) input) == 0;
}
@@ -399,7 +409,7 @@
throw new IllegalArgumentException("Illegal Script: " + script);
}
if (scripts == Collections.EMPTY_SET) {
- scripts = new TreeSet<String>();
+ scripts = new TreeSet<>();
}
scripts.add(script);
return this;
@@ -411,7 +421,7 @@
throw new IllegalArgumentException("Illegal Territory: " + territory);
}
if (territories == Collections.EMPTY_SET) {
- territories = new TreeSet<String>();
+ territories = new TreeSet<>();
}
territories.add(territory);
return this;
@@ -419,10 +429,12 @@
boolean frozen = false;
+ @Override
public boolean isFrozen() {
return frozen;
}
+ @Override
public BasicLanguageData freeze() {
frozen = true;
if (scripts != Collections.EMPTY_SET) {
@@ -434,8 +446,12 @@
return this;
}
+ @Override
public BasicLanguageData cloneAsThawed() {
- throw new UnsupportedOperationException();
+ BasicLanguageData result = new BasicLanguageData();
+ result.scripts = new TreeSet<>(scripts);
+ result.territories = new TreeSet<>(territories);
+ return this;
}
public void addScripts(Set<String> scripts2) {
@@ -482,7 +498,7 @@
public static class NumberingSystemInfo {
public enum NumberingSystemType {
algorithmic, numeric, unknown
- };
+ }
public final String name;
public final NumberingSystemType type;
@@ -555,6 +571,7 @@
throw new IllegalArgumentException(e2);
}
+ @Override
public String toString() {
return "{" + formatDate(from)
+ ", "
@@ -618,12 +635,14 @@
return isLegalTender;
}
+ @Override
public int compareTo(CurrencyDateInfo o) {
int result = dateRange.compareTo(o.dateRange);
if (result != 0) return result;
return currency.compareTo(o.currency);
}
+ @Override
public String toString() {
return "{" + dateRange + ", " + currency + "}";
}
@@ -658,6 +677,7 @@
return metazone.compareTo(arg0.metazone);
}
+ @Override
public String toString() {
return "{" + dateRange + ", " + metazone + "}";
}
@@ -733,6 +753,7 @@
return errors;
}
+ @Override
public boolean equals(Object o) {
if (!(o instanceof TelephoneCodeInfo))
return false;
@@ -740,10 +761,12 @@
return tc.code.equals(code) && tc.start.equals(start) && tc.end.equals(end) && tc.alt.equals(alt);
}
+ @Override
public int hashCode() {
return 31 * code.hashCode() + start.hashCode() + end.hashCode() + alt.hashCode();
}
+ @Override
public int compareTo(TelephoneCodeInfo o) {
int result = code.compareTo(o.code);
if (result != 0) return result;
@@ -754,6 +777,7 @@
return alt.compareTo(o.alt);
}
+ @Override
public String toString() {
return "{" + code + ", " + formatDate(start) + ", " + formatDate(end) + ", " + alt + "}";
}
@@ -791,12 +815,13 @@
if (source == null) {
return null;
}
- Set<String> result = new HashSet<String>(Arrays.asList(NON_ASCII_LETTER.split(source)));
+ Set<String> result = new HashSet<>(Arrays.asList(NON_ASCII_LETTER.split(source)));
result.remove("");
inTerritorySetInternal = result;
return Collections.unmodifiableSet(result);
}
+ @Override
public int compareTo(CoverageLevelInfo o) {
if (value == o.value) {
return match.compareTo(o.match);
@@ -815,19 +840,21 @@
}
}
}
-
+
+ public enum RBNFGroup {SpelloutRules, OrdinalRules, NumberingSystemRules}
+
public static final String STAR = "*";
public static final Set<String> STAR_SET = Builder.with(new HashSet<String>()).add("*").freeze();
private VersionInfo cldrVersion;
- private Map<String, PopulationData> territoryToPopulationData = new TreeMap<String, PopulationData>();
+ private Map<String, PopulationData> territoryToPopulationData = new TreeMap<>();
- private Map<String, Map<String, PopulationData>> territoryToLanguageToPopulationData = new TreeMap<String, Map<String, PopulationData>>();
+ private Map<String, Map<String, PopulationData>> territoryToLanguageToPopulationData = new TreeMap<>();
- private Map<String, PopulationData> languageToPopulation = new TreeMap<String, PopulationData>();
+ private Map<String, PopulationData> languageToPopulation = new TreeMap<>();
- private Map<String, PopulationData> baseLanguageToPopulation = new TreeMap<String, PopulationData>();
+ private Map<String, PopulationData> baseLanguageToPopulation = new TreeMap<>();
private Relation<String, String> languageToScriptVariants = Relation.of(new TreeMap<String, Set<String>>(),
TreeSet.class);
@@ -838,10 +865,10 @@
transient private Relation<String, Pair<Boolean, Pair<Double, String>>> languageToTerritories2 = Relation
.of(new TreeMap<String, Set<Pair<Boolean, Pair<Double, String>>>>(), TreeSet.class);
- private Map<String, Map<BasicLanguageData.Type, BasicLanguageData>> languageToBasicLanguageData = new TreeMap<String, Map<BasicLanguageData.Type, BasicLanguageData>>();
+ private Map<String, Map<BasicLanguageData.Type, BasicLanguageData>> languageToBasicLanguageData = new TreeMap<>();
- private Set<String> allLanguages = new TreeSet<String>();
- final private List<String> approvalRequirements = new LinkedList<String>(); // xpath array
+ private Set<String> allLanguages = new TreeSet<>();
+ final private List<String> approvalRequirements = new LinkedList<>(); // xpath array
private Relation<String, String> containment = Relation.of(new LinkedHashMap<String, Set<String>>(),
LinkedHashSet.class);
@@ -854,28 +881,28 @@
private Relation<String, String> containerToSubdivision = Relation.of(new LinkedHashMap<String, Set<String>>(),
LinkedHashSet.class);
- private Map<String, CurrencyNumberInfo> currencyToCurrencyNumberInfo = new TreeMap<String, CurrencyNumberInfo>();
+ private Map<String, CurrencyNumberInfo> currencyToCurrencyNumberInfo = new TreeMap<>();
private Relation<String, CurrencyDateInfo> territoryToCurrencyDateInfo = Relation.of(
new TreeMap<String, Set<CurrencyDateInfo>>(), LinkedHashSet.class);
- private Map<String, Set<TelephoneCodeInfo>> territoryToTelephoneCodeInfo = new TreeMap<String, Set<TelephoneCodeInfo>>();
+ private Map<String, Set<TelephoneCodeInfo>> territoryToTelephoneCodeInfo = new TreeMap<>();
- private Set<String> multizone = new TreeSet<String>();
+ private Set<String> multizone = new TreeSet<>();
- private Map<String, String> zone_territory = new TreeMap<String, String>();
+ private Map<String, String> zone_territory = new TreeMap<>();
private Relation<String, String> zone_aliases = Relation
.of(new TreeMap<String, Set<String>>(), LinkedHashSet.class);
- private Map<String, Map<String, Map<String, String>>> typeToZoneToRegionToZone = new TreeMap<String, Map<String, Map<String, String>>>();
+ private Map<String, Map<String, Map<String, String>>> typeToZoneToRegionToZone = new TreeMap<>();
private Relation<String, MetaZoneRange> zoneToMetaZoneRanges = Relation.of(
new TreeMap<String, Set<MetaZoneRange>>(), TreeSet.class);
- private Map<String, String> metazoneContinentMap = new HashMap<String, String>();
- private Set<String> allMetazones = new TreeSet<String>();
+ private Map<String, String> metazoneContinentMap = new HashMap<>();
+ private Set<String> allMetazones = new TreeSet<>();
- private Map<String, String> alias_zone = new TreeMap<String, String>();
+ private Map<String, String> alias_zone = new TreeMap<>();
public Relation<String, Integer> numericTerritoryMapping = Relation.of(new HashMap<String, Set<Integer>>(),
HashSet.class);
@@ -886,41 +913,44 @@
public Relation<String, Integer> numericCurrencyCodeMapping = Relation.of(new HashMap<String, Set<Integer>>(),
HashSet.class);
- static Map<String, SupplementalDataInfo> directory_instance = new HashMap<String, SupplementalDataInfo>();
+ static Map<String, SupplementalDataInfo> directory_instance = new HashMap<>();
- public Map<String, Map<String, Row.R2<List<String>, String>>> typeToTagToReplacement = new TreeMap<String, Map<String, Row.R2<List<String>, String>>>();
+ public Map<String, Map<String, Row.R2<List<String>, String>>> typeToTagToReplacement = new TreeMap<>();
- Map<String, List<Row.R4<String, String, Integer, Boolean>>> languageMatch = new HashMap<String, List<Row.R4<String, String, Integer, Boolean>>>();
+ Map<String, List<Row.R4<String, String, Integer, Boolean>>> languageMatch = new HashMap<>();
public Relation<String, String> bcp47Key2Subtypes = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
public Relation<String, String> bcp47Extension2Keys = Relation
.of(new TreeMap<String, Set<String>>(), TreeSet.class);
public Relation<Row.R2<String, String>, String> bcp47Aliases = Relation.of(
new TreeMap<Row.R2<String, String>, Set<String>>(), LinkedHashSet.class);
- public Map<Row.R2<String, String>, String> bcp47Descriptions = new TreeMap<Row.R2<String, String>, String>();
- public Map<Row.R2<String, String>, String> bcp47Since = new TreeMap<Row.R2<String, String>, String>();
- public Map<Row.R2<String, String>, String> bcp47Preferred = new TreeMap<Row.R2<String, String>, String>();
- public Map<Row.R2<String, String>, String> bcp47Deprecated = new TreeMap<Row.R2<String, String>, String>();
- public Map<String, String> bcp47ValueType = new TreeMap<String, String>();
-
+ public Map<Row.R2<String, String>, String> bcp47Descriptions = new TreeMap<>();
+ public Map<Row.R2<String, String>, String> bcp47Since = new TreeMap<>();
+ public Map<Row.R2<String, String>, String> bcp47Preferred = new TreeMap<>();
+ public Map<Row.R2<String, String>, String> bcp47Deprecated = new TreeMap<>();
+ public Map<String, String> bcp47ValueType = new TreeMap<>();
- public Map<String, Row.R2<String, String>> validityInfo = new LinkedHashMap<String, Row.R2<String, String>>();
+
+ public Map<String, Row.R2<String, String>> validityInfo = new LinkedHashMap<>();
public Map<AttributeValidityInfo, String> attributeValidityInfo = new LinkedHashMap<>();
public Multimap<String, String> languageGroups = TreeMultimap.create();
-
- public RationalParser rationalParser = new RationalParser();
- public UnitConverter unitConverter = new UnitConverter(rationalParser);
-
- public UnitPreferences unitPreferences = new UnitPreferences();
+ public RationalParser rationalParser = new RationalParser();
+
+ private UnitConverter unitConverter = null;
+
+ private final UnitPreferences unitPreferences = new UnitPreferences();
+
+ public Map<String, GrammarInfo> grammarLocaleToTargetToFeatureToValues = new TreeMap<>();
+ public Map<String, GrammarDerivation> localeToGrammarDerivation = new TreeMap<>();
public enum MeasurementType {
measurementSystem, paperSize
}
- Map<MeasurementType, Map<String, String>> measurementData = new HashMap<MeasurementType, Map<String, String>>();
- Map<String, PreferredAndAllowedHour> timeData = new HashMap<String, PreferredAndAllowedHour>();
+ Map<MeasurementType, Map<String, String>> measurementData = new HashMap<>();
+ Map<String, PreferredAndAllowedHour> timeData = new HashMap<>();
public Relation<String, String> getAlpha3TerritoryMapping() {
return alpha3TerritoryMapping;
@@ -948,11 +978,7 @@
}
public static SupplementalDataInfo getInstance(File supplementalDirectory) {
- try {
- return getInstance(supplementalDirectory.getCanonicalPath());
- } catch (IOException e) {
- throw new ICUUncheckedIOException(e);
- }
+ return getInstance(getNormalizedPathString(supplementalDirectory));
}
static private SupplementalDataInfo defaultInstance = null;
@@ -960,6 +986,7 @@
* Which directory did we come from?
*/
final private File directory;
+ private Validity validity;
/**
* Get an instance chosen using setAsDefaultInstance(), otherwise return an instance using the default directory
@@ -992,18 +1019,13 @@
throw new IllegalArgumentException("Error: The string passed as a parameter resolves to the empty string.");
}
// canonicalize path
- String canonicalpath = null;
- try {
- canonicalpath = new File(supplementalDirectory).getCanonicalPath();
- } catch (IOException e) {
- throw new ICUUncheckedIOException(e);
- }
- SupplementalDataInfo instance = directory_instance.get(canonicalpath);
+ String normalizedPath = getNormalizedPathString(supplementalDirectory);
+ SupplementalDataInfo instance = directory_instance.get(normalizedPath);
if (instance != null) {
return instance;
}
// reaching here means we have not cached the entry
- File directory = new File(canonicalpath);
+ File directory = new File(normalizedPath);
instance = new SupplementalDataInfo(directory);
MyHandler myHandler = instance.new MyHandler();
XMLFileReader xfr = new XMLFileReader().setHandler(myHandler);
@@ -1026,10 +1048,7 @@
builder.addAll(files2);
for (File file : builder.get()) {
if (DEBUG) {
- try {
- System.out.println(file.getCanonicalPath());
- } catch (IOException e) {
- }
+ System.out.println(getNormalizedPathString(file));
}
String name = file.toString();
String shortName = file.getName();
@@ -1041,14 +1060,14 @@
}
// xfr = new XMLFileReader().setHandler(instance.new MyHandler());
- // .xfr.read(canonicalpath + "/supplementalMetadata.xml", -1, true);
+ // .xfr.read(normalizedPath + "/supplementalMetadata.xml", -1, true);
instance.makeStuffSafe();
// cache
// directory_instance.put(supplementalDirectory, instance);
- directory_instance.put(canonicalpath, instance);
- // if (!canonicalpath.equals(supplementalDirectory)) {
- // directory_instance.put(canonicalpath, instance);
+ directory_instance.put(normalizedPath, instance);
+ // if (!normalizedPath.equals(supplementalDirectory)) {
+ // directory_instance.put(normalizedPath, instance);
// }
return instance;
}
@@ -1060,7 +1079,8 @@
private SupplementalDataInfo(File directory) {
this.directory = directory;
- }; // hide
+ this.validity = Validity.getInstance(directory.toString() + "/../validity/");
+ } // hide
private void makeStuffSafe() {
// now make stuff safe
@@ -1152,7 +1172,7 @@
coverageLevels = Collections.unmodifiableSortedSet(coverageLevels);
measurementData = CldrUtility.protectCollection(measurementData);
-
+
final Map<String, R2<List<String>, String>> unitAliases = typeToTagToReplacement.get("unit");
if (unitAliases != null) { // don't load unless the information is there (for old releases);
unitConverter.addAliases(unitAliases);
@@ -1160,7 +1180,7 @@
unitConverter.freeze();
rationalParser.freeze();
unitPreferences.freeze();
-
+
timeData = CldrUtility.protectCollection(timeData);
validityInfo = CldrUtility.protectCollection(validityInfo);
@@ -1168,6 +1188,9 @@
parentLocales = Collections.unmodifiableMap(parentLocales);
languageGroups = ImmutableSetMultimap.copyOf(languageGroups);
+ grammarLocaleToTargetToFeatureToValues = CldrUtility.protectCollection(grammarLocaleToTargetToFeatureToValues);
+ localeToGrammarDerivation = CldrUtility.protectCollection(localeToGrammarDerivation);
+
ImmutableSet.Builder<String> newScripts = ImmutableSet.<String> builder();
Map<Validity.Status, Set<String>> scripts = Validity.getInstance().getStatusToCodes(LstrType.script);
for (Entry<Status, Set<String>> e : scripts.entrySet()) {
@@ -1202,6 +1225,7 @@
lastPluralLocales = "";
}
+ @Override
public void handlePathValue(String path, String value) {
try {
XPathParts parts = XPathParts.getFrozenInstance(path);
@@ -1251,7 +1275,7 @@
if (handleCurrencyData(level2, parts)) {
return;
}
- } else if ("metazoneInfo".equals(level2)) {
+ } else if ("metazoneInfo".equals(level2)) {
if (handleMetazoneInfo(level3, parts)) {
return;
}
@@ -1272,7 +1296,7 @@
} else if (level1.equals("references")) {
String type = parts.getAttributeValue(-1, "type");
String uri = parts.getAttributeValue(-1, "uri");
- references.put(type, new Pair<String, String>(uri, value).freeze());
+ references.put(type, new Pair<>(uri, value).freeze());
return;
} else if (level1.equals("likelySubtags")) {
handleLikelySubtags(parts);
@@ -1326,6 +1350,10 @@
if (handleLanguageGroups(value, parts)) {
return;
}
+ } else if (level1.contentEquals("grammaticalData")) {
+ if (handleGrammaticalData(value, parts)) {
+ return;
+ }
}
// capture elements we didn't look at, since we should cover everything.
@@ -1335,19 +1363,66 @@
if (!skippedElements.contains(skipKey)) {
skippedElements.add(skipKey);
}
- // System.out.println("Skipped Element: " + path);
+ //System.out.println("Skipped Element: " + path);
} catch (Exception e) {
throw (IllegalArgumentException) new IllegalArgumentException("Exception while processing path: "
+ path + ",\tvalue: " + value).initCause(e);
}
}
+ private boolean handleGrammaticalData(String value, XPathParts parts) {
+ /*
+ <!ATTLIST grammaticalFeatures targets NMTOKENS #REQUIRED >
+ <!ATTLIST grammaticalFeatures locales NMTOKENS #REQUIRED >
+ OR
+ <!ATTLIST grammaticalDerivations locales NMTOKENS #REQUIRED >
+ */
+
+ for (String locale : split_space.split(parts.getAttributeValue(2, "locales"))) {
+ switch (parts.getElement(2)) {
+ case "grammaticalFeatures":
+ GrammarInfo targetToFeatureToValues = grammarLocaleToTargetToFeatureToValues.get(locale);
+ if (targetToFeatureToValues == null) {
+ grammarLocaleToTargetToFeatureToValues.put(locale, targetToFeatureToValues = new GrammarInfo());
+ }
+ final String targets = parts.getAttributeValue(2, "targets");
+ if (parts.size() < 4) {
+ targetToFeatureToValues.add(targets, null, null, null); // special case "known no features"
+ } else {
+ targetToFeatureToValues.add(targets, parts.getElement(3), parts.getAttributeValue(3, "scope"), parts.getAttributeValue(3, "values"));
+ }
+ break;
+ case "grammaticalDerivations":
+ String feature = parts.getAttributeValue(3, "feature");
+ String structure = parts.getAttributeValue(3, "structure");
+ GrammarDerivation grammarCompoundDerivation = localeToGrammarDerivation.get(locale);
+ if (grammarCompoundDerivation == null) {
+ localeToGrammarDerivation.put(locale, grammarCompoundDerivation = new GrammarDerivation());
+ }
+
+ switch (parts.getElement(3)) {
+ case "deriveCompound":
+ grammarCompoundDerivation.add(feature, structure, parts.getAttributeValue(3, "value"));
+ break;
+ case "deriveComponent":
+ grammarCompoundDerivation.add(feature, structure, parts.getAttributeValue(3, "value0"), parts.getAttributeValue(3, "value1"));
+ break;
+ default:
+ throw new IllegalArgumentException("Structure not handled: " + parts);
+ }
+ break;
+ default: throw new IllegalArgumentException("Structure not handled: " + parts);
+ }
+ }
+ return true;
+ }
+
/*
* Handles
* <unitPreferences category="area" usage="_default">
*<unitPreference regions="001" draft="unconfirmed">square-centimeter</unitPreference>
- */
-
+ */
+
private boolean handleUnitPreferences(XPathParts parts, String value) {
String geq = parts.getAttributeValue(-1, "geq");
String small = parts.getAttributeValue(-2, "scope");
@@ -1381,14 +1456,14 @@
String territories = parts.getAttributeValue(-1, "territories");
Map<String, String> data = measurementData.get(measurementType);
if (data == null) {
- measurementData.put(measurementType, data = new HashMap<String, String>());
+ measurementData.put(measurementType, data = new HashMap<>());
}
for (String territory : territories.trim().split("\\s+")) {
data.put(territory, type);
}
return true;
}
-
+
private boolean handleUnitConstants(XPathParts parts) {
// <unitConstant constant="ft2m" value="0.3048"/>
@@ -1398,20 +1473,23 @@
rationalParser.addConstant(constant, value, status);
return true;
}
-
+
private boolean handleUnitQuantities(XPathParts parts) {
// <unitQuantity quantity='wave-number' baseUnit='reciprocal-meter'/>
final String baseUnit = parts.getAttributeValue(-1, "baseUnit");
final String quantity = parts.getAttributeValue(-1, "quantity");
final String status = parts.getAttributeValue(-1, "status");
+ if (unitConverter == null) {
+ unitConverter = new UnitConverter(rationalParser, validity);
+ }
unitConverter.addQuantityInfo(baseUnit, quantity, status);
return true;
}
private boolean handleUnitConversion(XPathParts parts) {
// <convertUnit source='acre' target='square-meter' factor='ft2m^2 * 43560'/>
-
+
final String source = parts.getAttributeValue(-1, "source");
final String target = parts.getAttributeValue(-1, "baseUnit");
// if (source.contentEquals(target)) {
@@ -1421,8 +1499,8 @@
String offset = parts.getAttributeValue(-1, "offset");
String systems = parts.getAttributeValue(-1, "systems");
unitConverter.addRaw(
- source, target,
- factor, offset,
+ source, target,
+ factor, offset,
systems);
return true;
}
@@ -1506,7 +1584,7 @@
if (subtypeDescription != null) {
bcp47Descriptions.put(key_subtype, subtypeDescription.replaceAll("\\s+", " "));
}
- if (subtypeDescription != null) {
+ if (subtypeSince != null) {
bcp47Since.put(key_subtype, subtypeSince);
}
if (subtypePreferred != null) {
@@ -1549,7 +1627,7 @@
case "languageMatch":
List<R4<String, String, Integer, Boolean>> matches = languageMatch.get(type);
if (matches == null) {
- languageMatch.put(type, matches = new ArrayList<R4<String, String, Integer, Boolean>>());
+ languageMatch.put(type, matches = new ArrayList<>());
}
String percent = parts.getAttributeValue(3, "percent");
String distance = parts.getAttributeValue(3, "distance");
@@ -1670,11 +1748,11 @@
Map<String, Map<String, String>> zoneToRegionToZone = typeToZoneToRegionToZone.get(maintype);
if (zoneToRegionToZone == null) {
typeToZoneToRegionToZone.put(maintype,
- zoneToRegionToZone = new TreeMap<String, Map<String, String>>());
+ zoneToRegionToZone = new TreeMap<>());
}
Map<String, String> regionToZone = zoneToRegionToZone.get(mzone);
if (regionToZone == null) {
- zoneToRegionToZone.put(mzone, regionToZone = new TreeMap<String, String>());
+ zoneToRegionToZone.put(mzone, regionToZone = new TreeMap<>());
}
if (region != null) {
regionToZone.put(region, zone);
@@ -1723,12 +1801,11 @@
if (parts.contains("defaultContent")) {
String defContent = parts.getAttributeValue(-1, "locales").trim();
String[] defLocales = defContent.split("\\s+");
- defaultContentLocales = Collections.unmodifiableSet(new TreeSet<String>(Arrays.asList(defLocales)));
+ defaultContentLocales = Collections.unmodifiableSet(new TreeSet<>(Arrays.asList(defLocales)));
return true;
}
if (level2.equals("alias")) {
// <alias>
- // <!-- grandfathered 3066 codes -->
// <languageAlias type="art-lojban" replacement="jbo"/> <!-- Lojban -->
String level3 = parts.getElement(3);
if (!level3.endsWith("Alias")) {
@@ -1738,17 +1815,17 @@
Map<String, R2<List<String>, String>> tagToReplacement = typeToTagToReplacement.get(level3);
if (tagToReplacement == null) {
typeToTagToReplacement.put(level3,
- tagToReplacement = new TreeMap<String, R2<List<String>, String>>());
+ tagToReplacement = new TreeMap<>());
}
final String replacement = parts.getAttributeValue(3, "replacement");
List<String> replacementList = null;
if (replacement != null) {
Set<String> builder = new LinkedHashSet<>();
for (String item : replacement.split("\\s+")) {
- String cleaned = SubdivisionNames.isOldSubdivisionCode(item)
+ String cleaned = SubdivisionNames.isOldSubdivisionCode(item)
? replacement.replace("-", "").toLowerCase(Locale.ROOT)
: item;
- builder.add(cleaned);
+ builder.add(cleaned);
}
replacementList = ImmutableList.copyOf(builder);
}
@@ -1848,7 +1925,7 @@
.get(territory);
if (territoryLanguageToPopulation == null) {
territoryToLanguageToPopulationData.put(territory,
- territoryLanguageToPopulation = new TreeMap<String, PopulationData>());
+ territoryLanguageToPopulation = new TreeMap<>());
}
OfficialStatus officialStatus = OfficialStatus.unknown;
String officialStatusString = languageInTerritoryAttributes.get("officialStatus");
@@ -1885,7 +1962,7 @@
// if (language.equals("en")) {
// System.out.println(territory + "\tnewData:\t" + newData + "\tdata:\t" + data);
// }
-
+
if (languageTagParser == null) {
languageTagParser = new LanguageTagParser();
}
@@ -1942,7 +2019,7 @@
Set<TelephoneCodeInfo> tcSet = territoryToTelephoneCodeInfo.get(terr);
if (tcSet == null) {
- tcSet = new LinkedHashSet<TelephoneCodeInfo>();
+ tcSet = new LinkedHashSet<>();
territoryToTelephoneCodeInfo.put(terr, tcSet);
}
tcSet.add(tcInfo);
@@ -1986,7 +2063,7 @@
// Reflecting submitted data, cldrbug #1013 -->
// <language type="ab" scripts="Cyrl" territories="GE"
// alt="secondary"/>
- String language = (String) parts.getAttributeValue(2, "type");
+ String language = parts.getAttributeValue(2, "type");
BasicLanguageData languageData = new BasicLanguageData();
languageData
.setType(parts.getAttributeValue(2, "alt") == null ? BasicLanguageData.Type.primary
@@ -1995,7 +2072,7 @@
.setTerritories(parts.getAttributeValue(2, "territories"));
Map<Type, BasicLanguageData> map = languageToBasicLanguageData.get(language);
if (map == null) {
- languageToBasicLanguageData.put(language, map = new EnumMap<Type, BasicLanguageData>(
+ languageToBasicLanguageData.put(language, map = new EnumMap<>(
BasicLanguageData.Type.class));
}
if (map.containsKey(languageData.type)) {
@@ -2050,22 +2127,22 @@
return attributeValue == null ? -1 : Integer.parseInt(attributeValue);
}
- Set<String> skippedElements = new TreeSet<String>();
+ Set<String> skippedElements = new TreeSet<>();
- private Map<String, Pair<String, String>> references = new TreeMap<String, Pair<String, String>>();
- private Map<String, String> likelySubtags = new TreeMap<String, String>();
+ private Map<String, Pair<String, String>> references = new TreeMap<>();
+ private Map<String, String> likelySubtags = new TreeMap<>();
// make public temporarily until we resolve.
- private SortedSet<CoverageLevelInfo> coverageLevels = new TreeSet<CoverageLevelInfo>();
- private Map<String, String> parentLocales = new HashMap<String, String>();
- private Map<String, List<String>> calendarPreferences = new HashMap<String, List<String>>();
- private Map<String, CoverageVariableInfo> localeSpecificVariables = new TreeMap<String, CoverageVariableInfo>();
+ private SortedSet<CoverageLevelInfo> coverageLevels = new TreeSet<>();
+ private Map<String, String> parentLocales = new HashMap<>();
+ private Map<String, List<String>> calendarPreferences = new HashMap<>();
+ private Map<String, CoverageVariableInfo> localeSpecificVariables = new TreeMap<>();
private VariableReplacer coverageVariables = new VariableReplacer();
- private Map<String, NumberingSystemInfo> numberingSystems = new HashMap<String, NumberingSystemInfo>();
- private Set<String> numericSystems = new TreeSet<String>();
+ private Map<String, NumberingSystemInfo> numberingSystems = new HashMap<>();
+ private Set<String> numericSystems = new TreeSet<>();
private Set<String> defaultContentLocales;
public Map<CLDRLocale, CLDRLocale> baseToDefaultContent; // wo -> wo_Arab_SN
public Map<CLDRLocale, CLDRLocale> defaultContentToBase; // wo_Arab_SN -> wo
- private Set<String> CLDRLanguageCodes = new TreeSet<String>();;
+ private Set<String> CLDRLanguageCodes = new TreeSet<>();
private Set<String> CLDRScriptCodes;
/**
@@ -2119,7 +2196,7 @@
if (map == null) {
throw new IllegalArgumentException("Bad language code: " + language);
}
- return new LinkedHashSet<BasicLanguageData>(map.values());
+ return new LinkedHashSet<>(map.values());
}
public Map<Type, BasicLanguageData> getBasicLanguageDataMap(String language) {
@@ -2211,7 +2288,7 @@
public Set<String> getSingleRegionZones() {
synchronized (this) {
if (singleRegionZones == null) {
- singleRegionZones = new HashSet<String>();
+ singleRegionZones = new HashSet<>();
SupplementalDataInfo supplementalData = this; // TODO: this?
Set<String> multizoneCountries = supplementalData.getMultizones();
for (String zone : supplementalData.getCanonicalZones()) {
@@ -2454,7 +2531,7 @@
}
//if it is not, add a new map with the coverage level, and remove the last map in the list (used most seldom) if the list is too large
- Map<String, Level> newMap = new ConcurrentHashMap<String, Level>();
+ Map<String, Level> newMap = new ConcurrentHashMap<>();
newMap.put(xpath, covLevel);
localeList.addFirst(new Node(loc, newMap));
@@ -2495,7 +2572,7 @@
public synchronized RegexLookup<Level> getCoverageLookup() {
if (coverageLookup == null) {
- RegexLookup<Level> lookup = new RegexLookup<Level>(RegexLookup.LookupType.STAR_PATTERN_LOOKUP);
+ RegexLookup<Level> lookup = new RegexLookup<>(RegexLookup.LookupType.STAR_PATTERN_LOOKUP);
Matcher variable = PatternCache.get("\\$\\{[A-Za-z][\\-A-Za-z]*\\}").matcher("");
@@ -2569,7 +2646,7 @@
// to certain territories
if (ci.inTerritory != null) {
if (ci.inTerritory.equals("EU")) {
- Set<String> containedTerritories = new HashSet<String>();
+ Set<String> containedTerritories = new HashSet<>();
containedTerritories.addAll(getContained(ci.inTerritory));
containedTerritories.retainAll(cvi.targetTerritories);
if (containedTerritories.isEmpty()) {
@@ -2622,7 +2699,7 @@
}
private Set<String> getTargetScripts(String language) {
- Set<String> targetScripts = new HashSet<String>();
+ Set<String> targetScripts = new HashSet<>();
try {
Set<BasicLanguageData> langData = getBasicLanguageData(language);
Iterator<BasicLanguageData> ldi = langData.iterator();
@@ -2644,7 +2721,7 @@
}
private Set<String> getTargetTerritories(String language) {
- Set<String> targetTerritories = new HashSet<String>();
+ Set<String> targetTerritories = new HashSet<>();
try {
Set<BasicLanguageData> langData = getBasicLanguageData(language);
Iterator<BasicLanguageData> ldi = langData.iterator();
@@ -2665,7 +2742,7 @@
}
private Set<String> getCalendars(Set<String> territories) {
- Set<String> targetCalendars = new HashSet<String>();
+ Set<String> targetCalendars = new HashSet<>();
Iterator<String> it = territories.iterator();
while (it.hasNext()) {
List<String> addCalendars = getCalendars(it.next());
@@ -2691,7 +2768,7 @@
}
public Set<String> getCurrentCurrencies(Set<String> territories, Date startsBefore, Date endsAfter) {
- Set<String> targetCurrencies = new HashSet<String>();
+ Set<String> targetCurrencies = new HashSet<>();
Iterator<String> it = territories.iterator();
while (it.hasNext()) {
Set<CurrencyDateInfo> targetCurrencyInfo = getCurrencyDateInfo(it.next());
@@ -2710,7 +2787,7 @@
}
private Set<String> getCurrentTimeZones(Set<String> territories) {
- Set<String> targetTimeZones = new HashSet<String>();
+ Set<String> targetTimeZones = new HashSet<>();
Iterator<String> it = territories.iterator();
while (it.hasNext()) {
String[] countryIDs = TimeZone.getAvailableIDs(it.next());
@@ -2722,7 +2799,7 @@
}
private Set<String> getTargetPlurals(String language) {
- Set<String> targetPlurals = new HashSet<String>();
+ Set<String> targetPlurals = new HashSet<>();
targetPlurals.addAll(getPlurals(PluralType.cardinal, language).getCanonicalKeywords());
// TODO: Kept 0 and 1 specifically until Mark figures out what to do with them.
// They should be removed once this is done.
@@ -2757,7 +2834,7 @@
if (localeAttrib == null || localeAttrib.equals(STAR) || localeAttrib.isEmpty()) {
locales = null; // no locale listed == '*'
} else {
- Set<CLDRLocale> localeList = new HashSet<CLDRLocale>();
+ Set<CLDRLocale> localeList = new HashSet<>();
String[] el = localeAttrib.split(" ");
for (int i = 0; i < el.length; i++) {
if (el[i].indexOf(":") == -1) { // Just a simple locale designation
@@ -2790,7 +2867,7 @@
final int requiredVotes;
public static List<ApprovalRequirementMatcher> buildAll(List<String> approvalRequirements) {
- List<ApprovalRequirementMatcher> newList = new LinkedList<ApprovalRequirementMatcher>();
+ List<ApprovalRequirementMatcher> newList = new LinkedList<>();
for (String xpath : approvalRequirements) {
newList.add(new ApprovalRequirementMatcher(xpath));
@@ -2976,22 +3053,22 @@
: standardType == PluralRules.PluralType.CARDINAL ? cardinal
: ordinal;
}
- };
+ }
private EnumMap<PluralType, Map<String, PluralInfo>> localeToPluralInfo2 = new EnumMap<>(PluralType.class);
{
localeToPluralInfo2.put(PluralType.cardinal, new LinkedHashMap<String, PluralInfo>());
localeToPluralInfo2.put(PluralType.ordinal, new LinkedHashMap<String, PluralInfo>());
}
- private Map<String, PluralRanges> localeToPluralRanges = new LinkedHashMap<String, PluralRanges>();
+ private Map<String, PluralRanges> localeToPluralRanges = new LinkedHashMap<>();
- private Map<DayPeriodInfo.Type, Map<String, DayPeriodInfo>> typeToLocaleToDayPeriodInfo = new EnumMap<DayPeriodInfo.Type, Map<String, DayPeriodInfo>>(
+ private Map<DayPeriodInfo.Type, Map<String, DayPeriodInfo>> typeToLocaleToDayPeriodInfo = new EnumMap<>(
DayPeriodInfo.Type.class);
- private Map<String, CoverageLevel2> localeToCoverageLevelInfo = new ConcurrentHashMap<String, CoverageLevel2>();
+ private Map<String, CoverageLevel2> localeToCoverageLevelInfo = new ConcurrentHashMap<>();
private CoverageCache coverageCache = new CoverageCache();
private transient String lastPluralLocales = "";
private transient PluralType lastPluralWasOrdinal = null;
- private transient Map<Count, String> lastPluralMap = new EnumMap<Count, String>(Count.class);
+ private transient Map<Count, String> lastPluralMap = new EnumMap<>(Count.class);
private transient String lastDayPeriodLocales = null;
private transient DayPeriodInfo.Type lastDayPeriodType = null;
private transient DayPeriodInfo.Builder dayPeriodBuilder = new DayPeriodInfo.Builder();
@@ -3078,7 +3155,7 @@
DayPeriodInfo temp = dayPeriodBuilder.finish(locales);
Map<String, DayPeriodInfo> locale2DPI = typeToLocaleToDayPeriodInfo.get(lastDayPeriodType);
if (locale2DPI == null) {
- typeToLocaleToDayPeriodInfo.put(lastDayPeriodType, locale2DPI = new LinkedHashMap<String, DayPeriodInfo>());
+ typeToLocaleToDayPeriodInfo.put(lastDayPeriodType, locale2DPI = new LinkedHashMap<>());
//System.out.println(lastDayPeriodType + ", " + locale2DPI);
}
for (String locale : locales) {
@@ -3167,8 +3244,9 @@
public static final SampleList EMPTY = new SampleList().freeze();
private UnicodeSet uset = new UnicodeSet();
- private List<FixedDecimal> fractions = new ArrayList<FixedDecimal>(0);
+ private List<FixedDecimal> fractions = new ArrayList<>(0);
+ @Override
public String toString() {
return toString(6, 3);
}
@@ -3273,8 +3351,8 @@
CountSampleList(PluralRules pluralRules, Set<Count> keywords, PluralType pluralType) {
// Create the integer counts
- countToIntegerSamples9999 = new EnumMap<Count, SampleList>(Count.class);
- countToDigitToIntegerSamples9999 = new EnumMap<Count, SampleList[]>(Count.class);
+ countToIntegerSamples9999 = new EnumMap<>(Count.class);
+ countToDigitToIntegerSamples9999 = new EnumMap<>(Count.class);
for (Count c : keywords) {
countToIntegerSamples9999.put(c, new SampleList());
SampleList[] row = new SampleList[5];
@@ -3376,7 +3454,7 @@
* @author markdavis
*/
public static class PluralInfo implements Comparable<PluralInfo> {
- static final Set<Double> explicits = new HashSet<Double>();
+ static final Set<Double> explicits = new HashSet<>();
static {
explicits.add(0.0d);
explicits.add(1.0d);
@@ -3405,7 +3483,7 @@
private final Map<Count, String> countToRule;
private PluralInfo(Map<Count, String> countToRule, PluralType pluralType) {
- EnumMap<Count, String> tempCountToRule = new EnumMap<Count, String>(Count.class);
+ EnumMap<Count, String> tempCountToRule = new EnumMap<>(Count.class);
tempCountToRule.putAll(countToRule);
this.countToRule = Collections.unmodifiableMap(tempCountToRule);
@@ -3448,8 +3526,8 @@
countSampleList = new CountSampleList(pluralRules, keywords, pluralType);
- Map<Count, Set<Double>> countToExampleSetRaw = new TreeMap<Count, Set<Double>>();
- Map<Integer, Count> exampleToCountRaw = new TreeMap<Integer, Count>();
+ Map<Count, Set<Double>> countToExampleSetRaw = new TreeMap<>();
+ Map<Integer, Count> exampleToCountRaw = new TreeMap<>();
Output<Map<Count, SampleList[]>> output = new Output();
@@ -3459,10 +3537,10 @@
// }
// now fix the longer examples
String otherFractionalExamples = "";
- List<Double> otherFractions = new ArrayList<Double>(0);
+ List<Double> otherFractions = new ArrayList<>(0);
// add fractional samples
- Map<Count, String> countToStringExampleRaw = new TreeMap<Count, String>();
+ Map<Count, String> countToStringExampleRaw = new TreeMap<>();
for (Count type : keywords) {
SampleList uset = countSampleList.get(type);
countToStringExampleRaw.put(type, uset.toString(5, 5));
@@ -3476,7 +3554,7 @@
// Currently a bit of a hack, we should enhance SampleList to make this easier
// and then use SampleList directly, see http://unicode.org/cldr/trac/ticket/9813
for (Count type : countToStringExampleRaw.keySet()) {
- Set<Double> doublesSet = new LinkedHashSet<Double>(0);
+ Set<Double> doublesSet = new LinkedHashSet<>(0);
String examples = countToStringExampleRaw.get(type);
if (examples == null) {
examples = "";
@@ -3497,7 +3575,7 @@
countToExampleSet = Collections.unmodifiableMap(countToExampleSetRaw);
countToStringExample = Collections.unmodifiableMap(countToStringExampleRaw);
exampleToCount = Collections.unmodifiableMap(exampleToCountRaw);
- Set<String> temp = new LinkedHashSet<String>();
+ Set<String> temp = new LinkedHashSet<>();
// String keyword = pluralRules.select(0.0d);
// double value = pluralRules.getUniqueKeywordValue(keyword);
// if (value == pluralRules.NO_UNIQUE_VALUE) {
@@ -3531,6 +3609,7 @@
canonicalKeywords = Collections.unmodifiableSet(temp);
}
+ @Override
public String toString() {
return countToExampleSet + "; " + exampleToCount + "; " + pluralRules;
}
@@ -3750,6 +3829,7 @@
/**
* @deprecated use {@link #getPlurals(PluralType)} instead
*/
+ @Deprecated
public Set<String> getPluralLocales() {
return getPluralLocales(PluralType.cardinal);
}
@@ -3773,6 +3853,7 @@
/**
* @deprecated use {@link #getPlurals(PluralType, String)} instead
*/
+ @Deprecated
public PluralInfo getPlurals(String locale) {
return getPlurals(locale, true);
}
@@ -3790,6 +3871,7 @@
/**
* @deprecated use {@link #getPlurals(PluralType, String, boolean)} instead.
*/
+ @Deprecated
public PluralInfo getPlurals(String locale, boolean allowRoot) {
return getPlurals(PluralType.cardinal, locale, allowRoot);
}
@@ -3873,8 +3955,18 @@
*/
public String getDefaultCurrency(String territory) {
- Set<CurrencyDateInfo> targetCurrencyInfo = getCurrencyDateInfo(territory);
String result = "XXX";
+ Set<CurrencyDateInfo> targetCurrencyInfo = getCurrencyDateInfo(territory);
+ if (targetCurrencyInfo == null) {
+ /*
+ * This happens during ConsoleCheckCLDR
+ * territory = "419"
+ * path = //ldml/numbers/currencyFormats[@numberSystem="latn"]/currencyFormatLength/currencyFormat[@type="accounting"]/pattern[@type="standard"]
+ * value = ¤#,##0.00
+ * Prevent NullPointerException
+ */
+ return result;
+ }
Date now = new Date();
for (CurrencyDateInfo cdi : targetCurrencyInfo) {
if (cdi.getStart().before(now) && cdi.getEnd().after(now) && cdi.isLegalTender()) {
@@ -3999,7 +4091,7 @@
}
- static Set<String> MainTimeZones;;
+ static Set<String> MainTimeZones;
/**
* Return canonical timezones
@@ -4009,7 +4101,7 @@
public Set<String> getCanonicalTimeZones() {
synchronized (SupplementalDataInfo.class) {
if (MainTimeZones == null) {
- MainTimeZones = new TreeSet<String>();
+ MainTimeZones = new TreeSet<>();
SupplementalDataInfo info = SupplementalDataInfo.getInstance();
for (Entry<R2<String, String>, Set<String>> entry : info.getBcp47Aliases().keyValuesSet()) {
R2<String, String> subtype_aliases = entry.getKey();
@@ -4053,7 +4145,7 @@
public boolean isDeprecated(DtdType type, String path) {
- XPathParts parts = XPathParts.getInstance(path);
+ XPathParts parts = XPathParts.getFrozenInstance(path);
for (int i = 0; i < parts.size(); ++i) {
String element = parts.getElement(i);
if (isDeprecated(type, element, "*", "*")) {
@@ -4097,9 +4189,9 @@
private synchronized void initCLDRLocaleBasedData() throws InternalError {
// This initialization depends on SDI being initialized.
if (defaultContentToBase == null) {
- Map<CLDRLocale, CLDRLocale> p2c = new TreeMap<CLDRLocale, CLDRLocale>();
- Map<CLDRLocale, CLDRLocale> c2p = new TreeMap<CLDRLocale, CLDRLocale>();
- TreeSet<CLDRLocale> tmpAllLocales = new TreeSet<CLDRLocale>();
+ Map<CLDRLocale, CLDRLocale> p2c = new TreeMap<>();
+ Map<CLDRLocale, CLDRLocale> c2p = new TreeMap<>();
+ TreeSet<CLDRLocale> tmpAllLocales = new TreeSet<>();
// copied from SupplementalData.java - CLDRLocale based
for (String l : defaultContentLocales) {
CLDRLocale child = CLDRLocale.getInstance(l);
@@ -4211,6 +4303,7 @@
}
public final static class LengthFirstComparator<T> implements Comparator<T> {
+ @Override
public int compare(T a, T b) {
String as = a.toString();
String bs = b.toString();
@@ -4231,9 +4324,9 @@
Set<String> dcl = sdi.getDefaultContentLocales();
Map<String, String> likely = sdi.getLikelySubtags();
- XEquivalenceClass<String, String> locales = new XEquivalenceClass<String, String>();
+ XEquivalenceClass<String, String> locales = new XEquivalenceClass<>();
LanguageTagParser ltp = new LanguageTagParser();
- Set<String> temp = new HashSet<String>();
+ Set<String> temp = new HashSet<>();
for (Entry<String, String> entry : likely.entrySet()) {
String source = entry.getKey();
if (source.startsWith("und")) {
@@ -4406,11 +4499,11 @@
public Multimap<String, String> getLanguageGroups() {
return languageGroups;
}
-
+
public UnitConverter getUnitConverter() {
return unitConverter;
}
-
+
public RationalParser getRationalParser() {
return rationalParser;
}
@@ -4418,4 +4511,55 @@
public UnitPreferences getUnitPreferences() {
return unitPreferences;
}
+
+ /**
+ * locales that have grammar info
+ */
+ public Set<String> hasGrammarInfo() {
+ return grammarLocaleToTargetToFeatureToValues.keySet();
+ }
+
+ /**
+ * Grammar info for locales, with inheritance
+ * @param seedOnly
+ * @return
+ */
+ public GrammarInfo getGrammarInfo(String locale) {
+ return getGrammarInfo(locale, false);
+ }
+
+ /**
+ * Special hack for v38; should drop seedOnly later.
+ * @param locale
+ * @param seedOnly
+ * @return
+ */
+ @Deprecated
+ public GrammarInfo getGrammarInfo(String locale, boolean seedOnly) {
+ for (;locale != null; locale = LocaleIDParser.getParent(locale)) {
+ if (seedOnly && !GrammarInfo.SEED_LOCALES.contains(locale)) {
+ continue;
+ }
+ GrammarInfo result = grammarLocaleToTargetToFeatureToValues.get(locale);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ public Set<String> hasGrammarDerivation() {
+ return localeToGrammarDerivation.keySet();
+ }
+
+
+ public GrammarDerivation getGrammarDerivation(String locale) {
+ for (;locale != null; locale = LocaleIDParser.getParent(locale)) {
+ GrammarDerivation result = localeToGrammarDerivation.get(locale);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/Tabber.java b/tools/java/org/unicode/cldr/util/Tabber.java
index a43baf4..e15c43f 100644
--- a/tools/java/org/unicode/cldr/util/Tabber.java
+++ b/tools/java/org/unicode/cldr/util/Tabber.java
@@ -60,6 +60,7 @@
private List stops = new ArrayList();
private List types = new ArrayList();
+ @Override
public Tabber clear() {
stops.clear();
types.clear();
@@ -67,6 +68,7 @@
return this;
}
+ @Override
public String toString() {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < stops.size(); ++i) {
@@ -93,6 +95,7 @@
/**
* Adds relative tab stop and how to align the text UP TO that stop
*/
+ @Override
public Tabber add(int fieldWidth, byte type) {
int last = getStop(stops.size() - 1);
stops.add(new Integer(last + fieldWidth));
@@ -112,6 +115,7 @@
return ((Integer) types.get(fieldNumber)).intValue();
}
+ @Override
public void process_field(int count, String source, int start, int limit, StringBuffer output) {
String piece = source.substring(start, limit);
int startPos = getStop(count - 1);
@@ -149,6 +153,7 @@
}
public static Tabber NULL_TABBER = new Tabber() {
+ @Override
public void process_field(int count, String source, int start, int limit, StringBuffer output) {
if (count > 0) output.append("\t");
output.append(source.substring(start, limit));
@@ -181,6 +186,7 @@
return this;
}
+ @Override
public void process_field(int count, String source, int start, int limit, StringBuffer output) {
output.append("<" + element);
String params = null;
diff --git a/tools/java/org/unicode/cldr/util/TempPrintWriter.java b/tools/java/org/unicode/cldr/util/TempPrintWriter.java
index 0a8aee7..b151f58 100644
--- a/tools/java/org/unicode/cldr/util/TempPrintWriter.java
+++ b/tools/java/org/unicode/cldr/util/TempPrintWriter.java
@@ -13,8 +13,8 @@
import com.ibm.icu.util.ICUUncheckedIOException;
/**
- * Simple utility to create a temporary file, write into it, then close it.
- * If the file differs from the old file (except for date), then it is deleted.
+ * Simple utility to create a temporary file, write into it, then close it.
+ * If the file differs from the old file (except for date), then it is deleted.
* Otherwise it replaces the target file. Moved from UnicodeTools.
* @author markdavis
*/
@@ -22,16 +22,17 @@
final PrintWriter tempPrintWriter;
final String tempName;
final String filename;
+ boolean noReplace = false;
-
+
public static TempPrintWriter openUTF8Writer(String filename) {
return new TempPrintWriter(new File(filename));
}
-
+
public static TempPrintWriter openUTF8Writer(String dir, String filename) {
return new TempPrintWriter(new File(dir, filename));
}
-
+
public TempPrintWriter(String dir, String filename) {
this(new File(dir, filename));
}
@@ -53,11 +54,19 @@
}
}
+ public void dontReplaceFile() {
+ noReplace = true;
+ }
+
@Override
public void close() {
tempPrintWriter.close();
try {
- replaceDifferentOrDelete(filename, tempName, false);
+ if (noReplace) {
+ new File(tempName).delete();
+ } else {
+ replaceDifferentOrDelete(filename, tempName, false);
+ }
} catch (IOException e) {
throw new ICUUncheckedIOException(e);
}
@@ -80,12 +89,12 @@
public void print(Object line) {
tempPrintWriter.print(line);
}
-
+
public void println() {
tempPrintWriter.println();
}
- /**
+ /**
* If contents(newFile) ≠ contents(oldFile), rename newFile to old. Otherwise delete newfile. Return true if replaced. *
*/
private static boolean replaceDifferentOrDelete(String oldFile, String newFile, boolean skipCopyright) throws IOException {
@@ -185,7 +194,7 @@
}
}
- /**
+ /**
* Returns -1 if strings are equal; otherwise the first position they are different at.
*/
public static int compare(String a, String b) {
diff --git a/tools/java/org/unicode/cldr/util/TestShimUtils.java b/tools/java/org/unicode/cldr/util/TestShimUtils.java
new file mode 100644
index 0000000..f8f90a9
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/TestShimUtils.java
@@ -0,0 +1,17 @@
+package org.unicode.cldr.util;
+
+/**
+ * Utilities for the TestShims
+ * should go away when we move to all junit tests.
+ * These are here so they can be shared between tools/java and tools/cldr-apps
+ */
+public class TestShimUtils {
+ public static String[] getArgs(Class<?> clazz, String defaultArgs) {
+ final String packageName = clazz.getPackage().getName();
+ final String propKey = packageName+".testArgs";
+ final String toSplit = System.getProperty(propKey, defaultArgs);
+ System.err.println(propKey+"="+toSplit);
+ final String s[] = toSplit.split(" "); // TODO: quoted strings, etc.
+ return s;
+ }
+}
diff --git a/tools/java/org/unicode/cldr/util/TestStateDictionaryBuilder.java b/tools/java/org/unicode/cldr/util/TestStateDictionaryBuilder.java
index 110a340..2f5a2a6 100644
--- a/tools/java/org/unicode/cldr/util/TestStateDictionaryBuilder.java
+++ b/tools/java/org/unicode/cldr/util/TestStateDictionaryBuilder.java
@@ -55,10 +55,10 @@
Dictionary<T> simpleDictionary;
Dictionary.Matcher<T> simpleMatcher;
- Map<CharSequence, T> baseMapping = new TreeMap<CharSequence, T>();
+ Map<CharSequence, T> baseMapping = new TreeMap<>();
- final StateDictionaryBuilder<T> stateDictionaryBuilder = new StateDictionaryBuilder<T>();
- final SimpleDictionaryBuilder<T> simpleDictionaryBuilder = new SimpleDictionaryBuilder<T>();
+ final StateDictionaryBuilder<T> stateDictionaryBuilder = new StateDictionaryBuilder<>();
+ final SimpleDictionaryBuilder<T> simpleDictionaryBuilder = new SimpleDictionaryBuilder<>();
// TODO: convert to TestFramework
public static void main(String[] args) {
@@ -235,7 +235,7 @@
"[[:assigned:] - [:ideographic:] - [:Co:] - [:Cs:]]"); // &
// [\\u0000-\\u0FFF]
int count = 0;
- Map<String, T> data = new TreeMap<String, T>();
+ Map<String, T> data = new TreeMap<>();
for (UnicodeSetIterator it = new UnicodeSetIterator(testSet); it.next();) {
String name = UCharacter.getExtendedName(it.codepoint);
if (name == null) {
@@ -283,7 +283,7 @@
if ((++count & 0xFF) == 0xFF) {
System.out.println(count + ":\t" + myText);
}
- crossCheck(new CharSourceWrapper<CharSequence>(myText));
+ crossCheck(new CharSourceWrapper<>(myText));
crossCheck("!" + myText);
crossCheck(myText + "!");
}
@@ -305,7 +305,7 @@
}
private void crossCheck(CharSequence myText) {
- crossCheck(new CharSourceWrapper<CharSequence>(myText));
+ crossCheck(new CharSourceWrapper<>(myText));
}
private void crossCheck(CharSource myText) {
@@ -411,10 +411,10 @@
System.out.println(" DIFFERENCE");
showWords("Simple", simpleMatcher, myText);
showWords("STATE", stateMatcher, myText);
- Set<String> simpleMinusState = new LinkedHashSet<String>(simpleResult);
+ Set<String> simpleMinusState = new LinkedHashSet<>(simpleResult);
simpleMinusState.removeAll(stateResult);
System.out.println("Simple-State" + simpleMinusState);
- Set<String> stateMinusSimple = new LinkedHashSet<String>(stateResult);
+ Set<String> stateMinusSimple = new LinkedHashSet<>(stateResult);
stateMinusSimple.removeAll(simpleResult);
System.out.println("State-Simple" + stateMinusSimple);
}
@@ -425,7 +425,7 @@
title = title.equals("") ? "" : "\tType: " + title;
// Walk through a strings and gather information about what we find
// according to the matcher
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
// Set the text to operate on
matcher.setText(myText);
boolean uniquePartial = false;
diff --git a/tools/java/org/unicode/cldr/util/TestUtilities.java b/tools/java/org/unicode/cldr/util/TestUtilities.java
index a339068..00e07a2 100644
--- a/tools/java/org/unicode/cldr/util/TestUtilities.java
+++ b/tools/java/org/unicode/cldr/util/TestUtilities.java
@@ -30,7 +30,7 @@
import org.unicode.cldr.test.ExampleGenerator;
import org.unicode.cldr.tool.GenerateAttributeList;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
@@ -55,7 +55,7 @@
enum State {
a, b, c;
public static State cc = c;
- };
+ }
String s;
@@ -166,8 +166,8 @@
private static void checkNumericTimezone() throws IOException {
String[] map_integer_zones = new String[1000];
StandardCodes sc = StandardCodes.make();
- Set<String> timezones = new TreeSet<String>(sc.getGoodAvailableCodes("tzid"));
- Map<String, Integer> map_timezone_integer = new TreeMap<String, Integer>();
+ Set<String> timezones = new TreeSet<>(sc.getGoodAvailableCodes("tzid"));
+ Map<String, Integer> map_timezone_integer = new TreeMap<>();
BufferedReader input = CldrUtility.getUTF8Data("timezone_numeric.txt");
int maxNumeric = -1;
Map<String, String> fixOld = sc.zoneParser.getZoneLinkold_new();
@@ -206,11 +206,11 @@
RuleBasedCollator eng = (RuleBasedCollator) Collator.getInstance();
eng.setNumericCollation(true);
- Set<String> extra = new TreeSet<String>(eng);
+ Set<String> extra = new TreeSet<>(eng);
extra.addAll(map_timezone_integer.keySet());
extra.removeAll(timezones);
System.out.println("Extra: " + extra);
- Set<String> needed = new TreeSet<String>(eng);
+ Set<String> needed = new TreeSet<>(eng);
needed.addAll(timezones);
needed.removeAll(map_timezone_integer.keySet());
System.out.println("Needed: " + needed);
@@ -218,7 +218,7 @@
// fill in the slots with the missing items
// make Etc/GMT go first
int numeric = 1;
- List<String> ordered = new ArrayList<String>(needed);
+ List<String> ordered = new ArrayList<>(needed);
// if (ordered.contains("Etc/GMT")) {
// ordered.remove("Etc/GMT");
// ordered.add(0,"Etc/GMT");
@@ -235,7 +235,7 @@
// print it out
Map<String, Set<String>> equiv = sc.zoneParser.getZoneLinkNew_OldSet();
- Set<String> old = new TreeSet<String>();
+ Set<String> old = new TreeSet<>();
for (int i = 1; i <= maxNumeric; ++i) {
Set<String> s = equiv.get(map_integer_zones[i]);
if (s != null) {
@@ -303,7 +303,7 @@
"comment",
// collation
"base", "settings", "suppress_contractions", "optimize", "rules" };
- String list = CollectionUtilities.join(elements, " ");
+ String list = String.join(" ", elements);
String prefix = "//supplementalData[@version=\"1.4\"]/metaData/";
meta.add(prefix + "elementOrder", list);
@@ -320,7 +320,7 @@
"validSubLocales", "standard", "references", "elements", "element", "attributes", "attribute",
// these are always at the end
"alt", "draft", };
- meta.add(prefix + "attributeOrder", CollectionUtilities.join(attOrder, " "));
+ meta.add(prefix + "attributeOrder", String.join(" ", attOrder));
String[] serialElements = new String[] { "variable", "comment",
"tRule",
@@ -329,7 +329,7 @@
"first_tertiary_ignorable", "last_tertiary_ignorable",
"first_secondary_ignorable", "last_secondary_ignorable", "first_primary_ignorable",
"last_primary_ignorable", "first_non_ignorable", "last_non_ignorable", "first_trailing", "last_trailing" };
- meta.add(prefix + "serialElements", CollectionUtilities.join(serialElements, " "));
+ meta.add(prefix + "serialElements", String.join(" ", serialElements));
/*
*
* <attributeValues elements="weekendStart weekendEnd" attributes="day"
@@ -356,33 +356,33 @@
Set<String>[] valueSets = attribute_valueSet.get(attribute);
for (int i = 0; i < 2; ++i) {
meta.add(prefix + "valid/attributeValues" + "[@elements=\"" + element + "\"]" + "[@attributes=\""
- + attribute + "\"]" + (i == 1 ? "[@x=\"true\"]" : ""), CollectionUtilities.join(
- valueSets[i], " "));
+ + attribute + "\"]" + (i == 1 ? "[@x=\"true\"]" : ""),
+ Joiner.on(" ").join(valueSets[i]));
}
}
}
String[] dayValueOrder = new String[] { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
meta.add(prefix + "valid/attributeValues[@order=\"given\"][@attributes=\"type\"][@elements=\"" + "day" + "\"]",
- CollectionUtilities.join(dayValueOrder, " "));
+ String.join(" ", dayValueOrder));
meta.add(prefix + "valid/attributeValues[@order=\"given\"][@attributes=\"" + "day" + "\"][@elements=\""
- + "firstDay weekendEnd weekendStart" + "\"]", CollectionUtilities.join(dayValueOrder, " "));
+ + "firstDay weekendEnd weekendStart" + "\"]", String.join(" ", dayValueOrder));
String[] widths = { "monthWidth", "dayWidth", "quarterWidth" };
String[] widthOrder = new String[] { "abbreviated", "narrow", "wide" };
meta.add(prefix + "valid/attributeValues[@order=\"given\"][@attributes=\"type\"][@elements=\""
- + CollectionUtilities.join(widths, " ") + "\"]", CollectionUtilities.join(widthOrder, " "));
+ + String.join(" ", widths) + "\"]", String.join(" ", widthOrder));
String[] formatLengths = { "dateFormatLength", "timeFormatLength", "dateTimeFormatLength",
"decimalFormatLength", "scientificFormatLength", "percentFormatLength", "currencyFormatLength" };
String[] lengthOrder = new String[] { "full", "long", "medium", "short" };
meta.add(prefix + "valid/attributeValues[@order=\"given\"][@attributes=\"type\"][@elements=\""
- + CollectionUtilities.join(formatLengths, " ") + "\"]", CollectionUtilities.join(lengthOrder, " "));
+ + String.join(" ", formatLengths) + "\"]", String.join(" ", lengthOrder));
String[] dateFieldOrder = new String[] { "era", "year", "month", "week", "day", "weekday", "dayperiod", "hour",
"minute", "second", "zone" };
meta.add(prefix + "valid/attributeValues[@order=\"given\"][@attributes=\"type\"][@elements=\"field\"]",
- CollectionUtilities.join(dateFieldOrder, " "));
+ String.join(" ", dateFieldOrder));
String[][] suppressData = { { "ldml", "version", "*" }, { "orientation", "characters", "left-to-right" },
{ "orientation", "lines", "top-to-bottom" }, { "weekendStart", "time", "00:00" },
@@ -412,19 +412,23 @@
static class MyHandler extends XMLFileReader.SimpleHandler {
+ @Override
public void handleAttributeDecl(String eName, String aName, String type, String mode, String value) {
System.out.println("eName: " + eName + ",\t aName: " + aName + ",\t type: " + type + ",\t mode: " + mode
+ ",\t value: " + value);
}
+ @Override
public void handleElementDecl(String name, String model) {
System.out.println("name: " + name + ",\t model: " + model);
}
+ @Override
public void handlePathValue(String path, String value) {
System.out.println("path: " + path + ",\t value: " + value);
}
+ @Override
public void handleComment(String path, String comment) {
System.out.println("path: " + path + ",\t comment: " + comment);
}
@@ -515,11 +519,11 @@
String oldType = type.equals("region") ? "territory" : type;
Set<String> allCodes = sc.getAvailableCodes(oldType);
- Set<String> temp = new TreeSet<String>(subtagData.keySet());
+ Set<String> temp = new TreeSet<>(subtagData.keySet());
temp.removeAll(allCodes);
System.out.println(type + "\t in new but not old\t" + temp);
- temp = new TreeSet<String>(allCodes);
+ temp = new TreeSet<>(allCodes);
temp.removeAll(subtagData.keySet());
System.out.println(type + "\t in old but not new\t" + temp);
}
@@ -564,9 +568,9 @@
Map<String, Map<String, String>> subtagData = m.get(type);
String oldType = type.equals("region") ? "territory" : type;
- String aliasType = oldType.equals("grandfathered") ? "language" : oldType;
- Set<String> allCodes = new TreeSet<String>();
- Set<String> deprecatedCodes = new TreeSet<String>();
+ String aliasType =oldType.equals("legacy") ? "language" : oldType;
+ Set<String> allCodes = new TreeSet<>();
+ Set<String> deprecatedCodes = new TreeSet<>();
for (Iterator<String> it2 = subtagData.keySet().iterator(); it2.hasNext();) {
String tag = it2.next();
@@ -585,7 +589,7 @@
}
// get old ones
Set<String> goodCodes = sc.getAvailableCodes(oldType);
- TreeSet<String> oldAndNotNew = new TreeSet<String>(goodCodes);
+ TreeSet<String> oldAndNotNew = new TreeSet<>(goodCodes);
oldAndNotNew.removeAll(allCodes);
oldAndNotNew.removeAll(deprecatedCodes);
for (Iterator<String> it2 = oldAndNotNew.iterator(); it2.hasNext();) {
@@ -595,7 +599,7 @@
System.out.println("\t\t\t<" + aliasType + "Alias type=\"" + tag + "\" replacement=\"" + preferred
+ "\"/> <!-- CLDR:" + sdata.get(0) + " -->");
}
- String allCodeString = CollectionUtilities.join(allCodes, " ");
+ String allCodeString = Joiner.on(" ").join(allCodes);
System.out
.println("\t\t\t<variable id=\"$" + oldType + "\" type=\"list\">" + allCodeString + "</variable>");
}
@@ -614,12 +618,12 @@
Factory mainCldrFactory = Factory.make(CLDRPaths.COMMON_DIRECTORY + "main" + File.separator, ".*");
Set<String> availableLocales = mainCldrFactory.getAvailable();
- Set<String> available = new TreeSet<String>();
+ Set<String> available = new TreeSet<>();
LocaleIDParser lip = new LocaleIDParser();
for (Iterator<String> it = availableLocales.iterator(); it.hasNext();) {
available.add(lip.set(it.next()).getLanguage());
}
- Set<String> langHack = new TreeSet<String>();
+ Set<String> langHack = new TreeSet<>();
for (int i = 0; i < language_territory_hack.length; ++i) {
String lang = language_territory_hack[i][0];
langHack.add(lang);
diff --git a/tools/java/org/unicode/cldr/util/Timer.java b/tools/java/org/unicode/cldr/util/Timer.java
index 0e91b34..ad4314b 100644
--- a/tools/java/org/unicode/cldr/util/Timer.java
+++ b/tools/java/org/unicode/cldr/util/Timer.java
@@ -41,6 +41,7 @@
return getDuration();
}
+ @Override
public String toString() {
return nf.format(getDuration() / NANOS_PER_SECOND) + "s";
}
diff --git a/tools/java/org/unicode/cldr/util/TimezoneFormatter.java b/tools/java/org/unicode/cldr/util/TimezoneFormatter.java
index f9f05ef..743e876 100644
--- a/tools/java/org/unicode/cldr/util/TimezoneFormatter.java
+++ b/tools/java/org/unicode/cldr/util/TimezoneFormatter.java
@@ -56,6 +56,7 @@
public enum Location {
GMT, LOCATION, NON_LOCATION;
+ @Override
public String toString() {
return this == GMT ? "gmt" : this == LOCATION ? "location" : "non-location";
}
@@ -67,6 +68,7 @@
return this == GENERIC ? "generic" : daylight ? "daylight" : "standard";
}
+ @Override
public String toString() {
return name().toLowerCase(Locale.ENGLISH);
}
@@ -74,6 +76,7 @@
public enum Length {
SHORT, LONG, OTHER;
+ @Override
public String toString() {
return this == SHORT ? "short" : this == LONG ? "long" : "other";
}
@@ -92,7 +95,7 @@
this.location = location;
this.length = length;
}
- };
+ }
// /**
// * Type parameter for formatting
@@ -173,9 +176,12 @@
String temp = desiredLocaleFile.getFullXPath("//ldml/dates/timeZoneNames/singleCountries");
if (temp != null) {
XPathParts xpp = XPathParts.getFrozenInstance(temp);
- singleCountriesList = (String) xpp.findAttributeValue("singleCountries", "list");
+ temp = xpp.findAttributeValue("singleCountries", "list");
+ if (temp != null) {
+ singleCountriesList = temp;
+ }
}
- singleCountriesSet = new TreeSet<String>(CldrUtility.splitList(singleCountriesList, ' '));
+ singleCountriesSet = new TreeSet<>(CldrUtility.splitList(singleCountriesList, ' '));
}
/**
@@ -526,10 +532,10 @@
private transient Matcher m = PatternCache.get("([-+])([0-9][0-9])([0-9][0-9])").matcher("");
private transient boolean parseInfoBuilt;
- private transient final Map<String, String> localizedCountry_countryCode = new HashMap<String, String>();
- private transient final Map<String, String> exemplar_zone = new HashMap<String, String>();
- private transient final Map<Object, Object> localizedExplicit_zone = new HashMap<Object, Object>();
- private transient final Map<String, String> country_zone = new HashMap<String, String>();
+ private transient final Map<String, String> localizedCountry_countryCode = new HashMap<>();
+ private transient final Map<String, String> exemplar_zone = new HashMap<>();
+ private transient final Map<Object, Object> localizedExplicit_zone = new HashMap<>();
+ private transient final Map<String, String> country_zone = new HashMap<>();
/**
* Returns zoneid. In case of an offset, returns "Etc/GMT+/-HH" or "Etc/GMT+/-HHmm".
@@ -624,13 +630,13 @@
// at this point, we don't really need the country, so ignore it
// the city could be the last field of a zone, or could be an exemplar city
// we have built the map so that both work
- return (String) exemplar_zone.get(city);
+ return exemplar_zone.get(city);
}
// see if the string is a localized country
- String countryCode = (String) localizedCountry_countryCode.get(inputText);
+ String countryCode = localizedCountry_countryCode.get(inputText);
if (countryCode == null) countryCode = country; // if not, try raw code
- return (String) country_zone.get(countryCode);
+ return country_zone.get(countryCode);
}
/**
@@ -656,8 +662,8 @@
// now add exemplar cities, AND pick up explicit strings, AND localized countries
String prefix = "//ldml/dates/timeZoneNames/zone[@type=\"";
String countryPrefix = "//ldml/localeDisplayNames/territories/territory[@type=\"";
- Map<String, Comparable> localizedNonWall = new HashMap<String, Comparable>();
- Set<String> skipDuplicates = new HashSet<String>();
+ Map<String, Comparable> localizedNonWall = new HashMap<>();
+ Set<String> skipDuplicates = new HashSet<>();
for (Iterator<String> it = desiredLocaleFile.iterator(); it.hasNext();) {
String path = it.next();
// dumb, simple implementation
@@ -715,7 +721,7 @@
if (tzids.length == 1) {
country_zone.put(key, tzids[0]);
} else {
- Set<String> set = new LinkedHashSet<String>(Arrays.asList(tzids)); // make modifyable
+ Set<String> set = new LinkedHashSet<>(Arrays.asList(tzids)); // make modifyable
set.retainAll(singleCountriesSet);
if (set.size() == 1) {
country_zone.put(key, set.iterator().next());
@@ -760,6 +766,7 @@
return this;
}
+ @Override
public Object parseObject(String source, ParsePosition pos) {
TimeZone foo;
CurrencyAmount fii;
@@ -767,6 +774,7 @@
return null;
}
+ @Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
// TODO Auto-generated method stub
return null;
diff --git a/tools/java/org/unicode/cldr/util/Tokenizer.java b/tools/java/org/unicode/cldr/util/Tokenizer.java
index f3a2964..a154087 100644
--- a/tools/java/org/unicode/cldr/util/Tokenizer.java
+++ b/tools/java/org/unicode/cldr/util/Tokenizer.java
@@ -130,7 +130,7 @@
int result = next();
System.out.println(toString(result, backedupBefore));
return result;
- }
+ }
*/
public int next() {
@@ -236,6 +236,7 @@
return buffer.toString();
}
+ @Override
public String toString() {
return source.substring(0, index) + "$$$" + source.substring(index);
}
@@ -304,6 +305,7 @@
/* (non-Javadoc)
* @see com.ibm.icu.text.SymbolTable#lookup(java.lang.String)
*/
+ @Override
public char[] lookup(String s) {
itemsLookedUp.add('$' + s);
return (char[]) contents.get(s);
@@ -312,6 +314,7 @@
/* (non-Javadoc)
* @see com.ibm.icu.text.SymbolTable#lookupMatcher(int)
*/
+ @Override
public UnicodeMatcher lookupMatcher(int ch) {
// TODO Auto-generated method stub
return null;
@@ -320,6 +323,7 @@
/* (non-Javadoc)
* @see com.ibm.icu.text.SymbolTable#parseReference(java.lang.String, java.text.ParsePosition, int)
*/
+ @Override
public String parseReference(String text, ParsePosition pos, int limit) {
int cp;
int start = pos.getIndex();
diff --git a/tools/java/org/unicode/cldr/util/Transformer.java b/tools/java/org/unicode/cldr/util/Transformer.java
index e8a895c..3cbe862 100644
--- a/tools/java/org/unicode/cldr/util/Transformer.java
+++ b/tools/java/org/unicode/cldr/util/Transformer.java
@@ -19,15 +19,15 @@
private V nextItem;
public static <S, V> Transformer<S, V> iterator(Transform<S, ? extends V> transform, Iterator<? extends S> iterator) {
- return new Transformer<S, V>(transform, iterator);
+ return new Transformer<>(transform, iterator);
}
public static <S, V> Transformer<S, V> iterator(Transform<S, ? extends V> transform, Iterable<? extends S> iterable) {
- return new Transformer<S, V>(transform, iterable.iterator());
+ return new Transformer<>(transform, iterable.iterator());
}
public static <S, V> Transformer<S, V> iterator(Transform<S, ? extends V> transform, S... items) {
- return new Transformer<S, V>(transform, Arrays.asList(items).iterator());
+ return new Transformer<>(transform, Arrays.asList(items).iterator());
}
public static <S, V> With<V> iterable(Transform<S, ? extends V> transform, Iterator<? extends S> iterator) {
diff --git a/tools/java/org/unicode/cldr/util/TransliteratorUtilities.java b/tools/java/org/unicode/cldr/util/TransliteratorUtilities.java
index 6a3de8f..6676d39 100644
--- a/tools/java/org/unicode/cldr/util/TransliteratorUtilities.java
+++ b/tools/java/org/unicode/cldr/util/TransliteratorUtilities.java
@@ -54,14 +54,14 @@
}
/**
- *
+ *
*/
public static String getFileContents(String dir, String filename) throws IOException {
//#if defined(FOUNDATION10) || defined(J2SE13)
//## BufferedReader br = TestUtil.openUTF8Reader(dir, filename);
//#else
BufferedReader br = FileUtilities.openUTF8Reader(dir, filename);
-//#endif
+//#endif
StringBuffer buffer = new StringBuffer();
while (true) {
String line = br.readLine();
@@ -99,39 +99,39 @@
"'' > ''' ; ";
/*
- The ampersand character (&) and the left angle bracket (<) MUST NOT appear
-
- in their literal form, except when used as markup delimiters, or within a
-
- comment, a processing instruction, or a CDATA section. If they are needed
-
- elsewhere, they MUST be escaped using either numeric character references or
-
- the strings "&" and "<" respectively. The right angle bracket (>) MAY
-
- be represented using the string ">", and MUST, for compatibility, be
-
- escaped using either ">" or a character reference when it appears in the string
-
+ The ampersand character (&) and the left angle bracket (<) MUST NOT appear
+
+ in their literal form, except when used as markup delimiters, or within a
+
+ comment, a processing instruction, or a CDATA section. If they are needed
+
+ elsewhere, they MUST be escaped using either numeric character references or
+
+ the strings "&" and "<" respectively. The right angle bracket (>) MAY
+
+ be represented using the string ">", and MUST, for compatibility, be
+
+ escaped using either ">" or a character reference when it appears in the string
+
"]]>" in content, when that string is not marking the end of a CDATA section.
-
- In the content of elements, character data is any string of characters which does
-
- not contain the start-delimiter of any markup and does not include the
-
- CDATA-section-close delimiter, "]]>". In a CDATA section, character data is
-
- any string of characters not including the CDATA-section-close delimiter,
-
+
+ In the content of elements, character data is any string of characters which does
+
+ not contain the start-delimiter of any markup and does not include the
+
+ CDATA-section-close delimiter, "]]>". In a CDATA section, character data is
+
+ any string of characters not including the CDATA-section-close delimiter,
+
"]]>".
-
- To allow attribute values to contain both single and double quotes, the
-
- apostrophe or single-quote character (') MAY be represented as "'", and
-
+
+ To allow attribute values to contain both single and double quotes, the
+
+ apostrophe or single-quote character (') MAY be represented as "'", and
+
the double-quote character (") as """.
-
-
+
+
*/
public static final Transliterator toXML = Transliterator.createFromRules(
diff --git a/tools/java/org/unicode/cldr/util/UExtension.java b/tools/java/org/unicode/cldr/util/UExtension.java
index eeb1592..b30f7d0 100644
--- a/tools/java/org/unicode/cldr/util/UExtension.java
+++ b/tools/java/org/unicode/cldr/util/UExtension.java
@@ -23,8 +23,8 @@
static Relation<String, String> validKeyTypes = data.getBcp47Keys();
private boolean validating = false;
- private SortedMap<String, List<String>> keyTypes = new TreeMap<String, List<String>>();
- private Set<String> attributes = new TreeSet<String>();
+ private SortedMap<String, List<String>> keyTypes = new TreeMap<>();
+ private Set<String> attributes = new TreeSet<>();
public Set<String> getKeys() {
return keyTypes.keySet();
@@ -82,7 +82,7 @@
if (list != null) {
throw new IllegalArgumentException("Multiple keys with same value: " + subtag);
}
- list = new ArrayList<String>();
+ list = new ArrayList<>();
keyTypes.put(key, list);
} else { // add subtype
if (key == null) {
@@ -114,6 +114,7 @@
return this;
}
+ @Override
public String toString() {
return "{attributes=" + attributes + ", keyTypes=" + keyTypes + "}";
}
diff --git a/tools/java/org/unicode/cldr/util/UnicodeRelation.java b/tools/java/org/unicode/cldr/util/UnicodeRelation.java
index 46270cf..070982b 100644
--- a/tools/java/org/unicode/cldr/util/UnicodeRelation.java
+++ b/tools/java/org/unicode/cldr/util/UnicodeRelation.java
@@ -25,13 +25,14 @@
public static SetMaker<Object> HASHSET_MAKER = new SetMaker<Object>() {
@Override
public Set<Object> make() {
- return new HashSet<Object>();
+ return new HashSet<>();
}
};
public static final SetMaker<Object> LINKED_HASHSET_MAKER = new SetMaker<Object>() {
+ @Override
public Set<Object> make() {
- return new LinkedHashSet<Object>();
+ return new LinkedHashSet<>();
}
};
@@ -73,7 +74,7 @@
}
public Set<T> get(String key) {
- return data.get((String) key);
+ return data.get(key);
}
public UnicodeSet getKeys(T value) {
diff --git a/tools/java/org/unicode/cldr/util/UnicodeSetPrettyPrinter.java b/tools/java/org/unicode/cldr/util/UnicodeSetPrettyPrinter.java
index bfe4743..a533a22 100644
--- a/tools/java/org/unicode/cldr/util/UnicodeSetPrettyPrinter.java
+++ b/tools/java/org/unicode/cldr/util/UnicodeSetPrettyPrinter.java
@@ -27,9 +27,9 @@
*/
public class UnicodeSetPrettyPrinter {
private static final StringComparator CODEPOINT_ORDER = new UTF16.StringComparator(true, false, 0);
- private static final UnicodeSet PATTERN_WHITESPACE = (UnicodeSet) new UnicodeSet("[[:Cn:][:Default_Ignorable_Code_Point:][:patternwhitespace:]]").freeze();
- private static final UnicodeSet SORT_AT_END = (UnicodeSet) new UnicodeSet("[[:Cn:][:Cs:][:Co:][:Ideographic:]]").freeze();
- private static final UnicodeSet QUOTED_SYNTAX = (UnicodeSet) new UnicodeSet("[\\[\\]\\-\\^\\&\\\\\\{\\}\\$\\:]").addAll(PATTERN_WHITESPACE).freeze();
+ private static final UnicodeSet PATTERN_WHITESPACE = new UnicodeSet("[[:Cn:][:Default_Ignorable_Code_Point:][:patternwhitespace:]]").freeze();
+ private static final UnicodeSet SORT_AT_END = new UnicodeSet("[[:Cn:][:Cs:][:Co:][:Ideographic:]]").freeze();
+ private static final UnicodeSet QUOTED_SYNTAX = new UnicodeSet("[\\[\\]\\-\\^\\&\\\\\\{\\}\\$\\:]").addAll(PATTERN_WHITESPACE).freeze();
private boolean first = true;
private StringBuffer target = new StringBuffer();
@@ -104,7 +104,7 @@
*/
public UnicodeSetPrettyPrinter setToQuote(UnicodeSet toQuote) {
if (toQuote != null) {
- toQuote = (UnicodeSet) toQuote.cloneAsThawed();
+ toQuote = toQuote.cloneAsThawed();
toQuote.addAll(PATTERN_WHITESPACE);
this.toQuote = toQuote;
}
@@ -120,7 +120,7 @@
first = true;
UnicodeSet putAtEnd = new UnicodeSet(uset).retainAll(SORT_AT_END); // remove all the unassigned gorp for now
// make sure that comparison separates all strings, even canonically equivalent ones
- TreeSet<String> orderedStrings = new TreeSet<String>(ordering);
+ TreeSet<String> orderedStrings = new TreeSet<>(ordering);
for (UnicodeSetIterator it = new UnicodeSetIterator(uset); it.nextRange();) {
if (it.codepoint == UnicodeSetIterator.IS_STRING) {
orderedStrings.add(it.string);
@@ -180,7 +180,7 @@
}
/**
- *
+ *
*/
private void addSpaceAsNeededBefore(String s) {
if (first) {
diff --git a/tools/java/org/unicode/cldr/util/UnicodeSets.java b/tools/java/org/unicode/cldr/util/UnicodeSets.java
index 483fbc8..9965248 100644
--- a/tools/java/org/unicode/cldr/util/UnicodeSets.java
+++ b/tools/java/org/unicode/cldr/util/UnicodeSets.java
@@ -10,7 +10,7 @@
final public class UnicodeSets {
/**
- * Return the strings that are redundant,
+ * Return the strings that are redundant,
* where all of the string's code points are already in the UnicodeSet.
* <br>Example: in [abc{ab}{ad}], {ab} is redundant, but {ad} is not.
* Also checks where a combination of the string's substrings are otherwise
diff --git a/tools/java/org/unicode/cldr/util/UnitConverter.java b/tools/java/org/unicode/cldr/util/UnitConverter.java
index 7deee14..7439dba 100644
--- a/tools/java/org/unicode/cldr/util/UnitConverter.java
+++ b/tools/java/org/unicode/cldr/util/UnitConverter.java
@@ -2,6 +2,7 @@
import java.math.BigInteger;
import java.math.MathContext;
+import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -14,9 +15,18 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.unicode.cldr.util.GrammarDerivation.CompoundUnitStructure;
+import org.unicode.cldr.util.GrammarDerivation.Values;
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
import org.unicode.cldr.util.Rational.FormatStyle;
import org.unicode.cldr.util.Rational.RationalParser;
+import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo;
+import org.unicode.cldr.util.Validity.Status;
import com.google.common.base.Splitter;
import com.google.common.collect.BiMap;
@@ -30,14 +40,22 @@
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import com.ibm.icu.impl.Row.R2;
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.Output;
+import com.ibm.icu.util.ULocale;
public class UnitConverter implements Freezable<UnitConverter> {
+ public static final Integer INTEGER_ONE = Integer.valueOf(1);
+
static final Splitter BAR_SPLITTER = Splitter.on('-');
static final Splitter SPACE_SPLITTER = Splitter.on(' ').trimResults().omitEmptyStrings();
+ public static final Set<String> HACK_SKIP_UNIT_NAMES = ImmutableSet.of("dot-per-centimeter", "dot-per-inch", "liter-per-100-kilometer", "millimeter-ofhg", "inch-ofhg");
+
+
final RationalParser rationalParser;
private Map<String,String> baseUnitToQuantity = new LinkedHashMap<>();
@@ -47,8 +65,12 @@
private Multimap<String, String> sourceToSystems = LinkedHashMultimap.create();
private Set<String> baseUnits;
private Multimap<String, Continuation> continuations = TreeMultimap.create();
- private MapComparator<String> quantityComparator;
+ private Comparator<String> quantityComparator;
+
private Map<String,String> fixDenormalized;
+ private ImmutableMap<String, UnitId> idToUnitId;
+
+ public final BiMap<String,String> SHORT_TO_LONG_ID;
private boolean frozen = false;
@@ -57,17 +79,17 @@
/** Warning: ordering is important; determines the normalized output */
public static final Set<String> BASE_UNITS = ImmutableSet.of(
"candela",
- "kilogram",
- "meter",
+ "kilogram",
+ "meter",
"second",
- "ampere",
+ "ampere",
"kelvin",
// non-SI
- "year",
- "bit",
- "item",
- "pixel",
- "em",
+ "year",
+ "bit",
+ "item",
+ "pixel",
+ "em",
"revolution",
"portion"
);
@@ -77,10 +99,19 @@
throw new IllegalArgumentException();
}
baseUnitToQuantity.put(baseUnit, quantity);
- baseUnitToStatus.put(baseUnit, quantity);
+ if (status != null) {
+ baseUnitToStatus.put(baseUnit, status);
+ }
quantityToSimpleUnits.put(quantity, baseUnit);
}
+ public static final Set<String> BASE_UNIT_PARTS = ImmutableSet.<String>builder()
+ .add("per").add("square").add("cubic").addAll(BASE_UNITS)
+ .build();
+
+ public static final Pattern PLACEHOLDER = Pattern.compile("[ \\u00A0\\u200E\\u200F\\u202F]*\\{0\\}[ \\u00A0\\u200E\\u200F\\u202F]*");
+ public static final boolean HACK = true;
+
@Override
public boolean isFrozen() {
return frozen;
@@ -93,7 +124,8 @@
rationalParser.freeze();
sourceToTargetInfo = ImmutableMap.copyOf(sourceToTargetInfo);
quantityToSimpleUnits = ImmutableMultimap.copyOf(quantityToSimpleUnits);
- sourceToSystems = ImmutableMultimap.copyOf(sourceToSystems);
+ quantityComparator = getQuantityComparator(baseUnitToQuantity, baseUnitToStatus);
+ sourceToSystems = ImmutableMultimap.copyOf(sourceToSystems);
// other fields are frozen earlier in processing
Builder<String> builder = ImmutableSet.<String>builder()
.addAll(BASE_UNITS);
@@ -103,6 +135,38 @@
baseUnits = builder.build();
continuations = ImmutableMultimap.copyOf(continuations);
targetInfoComparator = new TargetInfoComparator();
+
+ Map<String, UnitId> _idToUnitId = new TreeMap<>();
+ for (Entry<String, String> shortAndLongId : SHORT_TO_LONG_ID.entrySet()) {
+ String shortId = shortAndLongId.getKey();
+ String longId = shortAndLongId.getKey();
+ UnitId uid = createUnitId(shortId).freeze();
+ boolean doTest = false;
+ Output<Rational> deprefix = new Output<>();
+ for (Entry<String, Integer> entry : uid.numUnitsToPowers.entrySet()) {
+ final String unitPart = entry.getKey();
+ UnitConverter.stripPrefix(unitPart, deprefix );
+ if (!deprefix.value.equals(Rational.ONE) || !entry.getValue().equals(INTEGER_ONE)) {
+ doTest = true;
+ break;
+ }
+ }
+ if (!doTest) {
+ for (Entry<String, Integer> entry : uid.denUnitsToPowers.entrySet()) {
+ final String unitPart = entry.getKey();
+ UnitConverter.stripPrefix(unitPart, deprefix);
+ if (!deprefix.value.equals(Rational.ONE)) {
+ doTest = true;
+ break;
+ }
+ }
+ }
+ if (doTest) {
+ _idToUnitId.put(shortId, uid);
+ _idToUnitId.put(longId, uid);
+ }
+ }
+ idToUnitId = ImmutableMap.copyOf(_idToUnitId);
}
return this;
}
@@ -144,9 +208,9 @@
return toString("x");
}
public String toString(String unit) {
- return factor.toString(FormatStyle.simple)
+ return factor.toString(FormatStyle.simple)
+ " * " + unit
- + (offset.equals(Rational.ZERO) ? "" :
+ + (offset.equals(Rational.ZERO) ? "" :
(offset.compareTo(Rational.ZERO) < 0 ? " - " : " - ")
+ offset.abs().toString(FormatStyle.simple));
}
@@ -155,9 +219,9 @@
return toDecimal("x");
}
public String toDecimal(String unit) {
- return factor.toBigDecimal(MathContext.DECIMAL64)
+ return factor.toBigDecimal(MathContext.DECIMAL64)
+ " * " + unit
- + (offset.equals(Rational.ZERO) ? "" :
+ + (offset.equals(Rational.ZERO) ? "" :
(offset.compareTo(Rational.ZERO) < 0 ? " - " : " - ")
+ offset.toBigDecimal(MathContext.DECIMAL64).abs());
}
@@ -266,13 +330,22 @@
}
}
- public UnitConverter(RationalParser rationalParser) {
+ public UnitConverter(RationalParser rationalParser, Validity validity) {
this.rationalParser = rationalParser;
+ // we need to pass in the validity so it is for the same CLDR version as the converter
+ Set<String> VALID_UNITS = validity.getStatusToCodes(LstrType.unit).get(Status.regular);
+ Map<String,String> _SHORT_TO_LONG_ID = new LinkedHashMap<>();
+ for (String longUnit : VALID_UNITS) {
+ int dashPos = longUnit.indexOf('-');
+ String coreUnit = longUnit.substring(dashPos+1);
+ _SHORT_TO_LONG_ID.put(coreUnit, longUnit);
+ }
+ SHORT_TO_LONG_ID = ImmutableBiMap.copyOf(_SHORT_TO_LONG_ID);
}
public void addRaw(String source, String target, String factor, String offset, String systems) {
ConversionInfo info = new ConversionInfo(
- factor == null ? Rational.ONE : rationalParser.parse(factor),
+ factor == null ? Rational.ONE : rationalParser.parse(factor),
offset == null ? Rational.ZERO : rationalParser.parse(offset));
Map<String, String> args = new LinkedHashMap<>();
if (factor != null) {
@@ -339,12 +412,11 @@
}
}
- private void addToSourceToTarget(String source, String target, ConversionInfo info,
+ private void addToSourceToTarget(String source, String target, ConversionInfo info,
Map<String, String> inputParameters, String systems) {
if (sourceToTargetInfo.isEmpty()) {
baseUnitToQuantity = ImmutableBiMap.copyOf(baseUnitToQuantity);
baseUnitToStatus = ImmutableMap.copyOf(baseUnitToStatus);
- quantityComparator = new MapComparator<>(baseUnitToQuantity.values()).freeze();
} else if (sourceToTargetInfo.containsKey(source)) {
throw new IllegalArgumentException("Duplicate source: " + source + ", " + target);
}
@@ -359,6 +431,20 @@
}
}
+ private Comparator<String> getQuantityComparator(Map<String, String> baseUnitToQuantity2, Map<String, String> baseUnitToStatus2) {
+ // We want to sort all the quantities so that we have a natural ordering within compound units. So kilowatt-hour, not hour-kilowatt.
+ // For simple quantities, just use the ordering from baseUnitToStatus
+ MapComparator<String> simpleBaseUnitComparator = new MapComparator<>(baseUnitToStatus2.keySet()).freeze();
+ // For non-symbol quantities, use the ordering of the UnitIds
+ Map<UnitId, String> unitIdToQuantity = new TreeMap<>();
+ for (Entry<String, String> buq : baseUnitToQuantity2.entrySet()) {
+ UnitId uid = new UnitId(simpleBaseUnitComparator).add(continuations, buq.getKey(), true, 1).freeze();
+ unitIdToQuantity.put(uid, buq.getValue());
+ }
+ // System.out.println(Joiner.on("\n").join(unitIdToQuantity.values()));
+ return new MapComparator<>(unitIdToQuantity.values()).freeze();
+ }
+
public Set<String> canConvertBetween(String unit) {
TargetInfo targetInfo = sourceToTargetInfo.get(unit);
if (targetInfo == null) {
@@ -424,13 +510,13 @@
public ConversionInfo parseUnitId (String derivedUnit, Output<String> metricUnit, boolean showYourWork) {
metricUnit.value = null;
- UnitId outputUnit = new UnitId();
+ UnitId outputUnit = new UnitId(UNIT_COMPARATOR);
Rational numerator = Rational.ONE;
Rational denominator = Rational.ONE;
boolean inNumerator = true;
int power = 1;
- Output<Rational> deprefix = new Output<>();
+ Output<Rational> deprefix = new Output<>();
Rational offset = Rational.ZERO;
int countUnits = 0;
for (Iterator<String> it = Continuation.split(derivedUnit, continuations).iterator(); it.hasNext();) {
@@ -553,25 +639,26 @@
}
return o1.compareTo(o2);
}
- };
+ }
Comparator<String> UNIT_COMPARATOR = new UnitComparator();
- public static final Set<String> BASE_UNIT_PARTS = ImmutableSet.<String>builder()
- .add("per").add("square").add("cubic").addAll(BASE_UNITS)
- .build();
-
- /**
+ /**
* Only handles the canonical units; no kilo-, only normalized, etc.
* @author markdavis
*
*/
- public class UnitId implements Freezable<UnitId> {
- private Map<String, Integer> numUnitsToPowers = new TreeMap<>(UNIT_COMPARATOR);
- private Map<String, Integer> denUnitsToPowers = new TreeMap<>(UNIT_COMPARATOR);
+ public class UnitId implements Freezable<UnitId>, Comparable<UnitId> {
+ public Map<String, Integer> numUnitsToPowers;
+ public Map<String, Integer> denUnitsToPowers;
+ public EntrySetComparator<String, Integer> entrySetComparator;
private boolean frozen = false;
- private UnitId() {} //
+ private UnitId(Comparator<String> comparator) {
+ numUnitsToPowers = new TreeMap<>(comparator);
+ denUnitsToPowers = new TreeMap<>(comparator);
+ entrySetComparator = new EntrySetComparator<String, Integer>(comparator, Comparator.naturalOrder());
+ } //
private UnitId add(Multimap<String, Continuation> continuations, String compoundUnit, boolean groupInNumerator, int groupPower) {
if (frozen) {
@@ -585,7 +672,7 @@
case "square": power = 2; break;
case "cubic": power = 3; break;
case "per": inNumerator = false; break; // sticky, ignore multiples
- default:
+ default:
if (unitPart.startsWith("pow")) {
power = Integer.parseInt(unitPart.substring(3));
} else {
@@ -621,13 +708,13 @@
}
}
switch (power) {
- case 1:
+ case 1:
break;
- case 2:
+ case 2:
builder.append("square-"); break;
- case 3:
+ case 3:
builder.append("cubic-"); break;
- default:
+ default:
if (power > 3) {
builder.append("pow" + power + "-");
} else {
@@ -641,10 +728,166 @@
}
return builder.toString();
}
+
+ public String toString(LocaleStringProvider resolvedFile, String width, String _pluralCategory, String caseVariant, Multimap<UnitPathType, String> partsUsed, boolean maximal) {
+ if (partsUsed != null) {
+ partsUsed.clear();
+ }
+ String result = null;
+ String numerator = null;
+ String timesPattern = null;
+ String placeholderPattern = null;
+ Output<Integer> deprefix = new Output<>();
+
+ PlaceholderLocation placeholderPosition = PlaceholderLocation.missing;
+ Matcher placeholderMatcher = PLACEHOLDER.matcher("");
+ Output<String> unitPatternOut = new Output<>();
+
+ PluralInfo pluralInfo = CLDRConfig.getInstance().getSupplementalDataInfo().getPlurals(resolvedFile.getLocaleID());
+ PluralRules pluralRules = pluralInfo.getPluralRules();
+ String singularPluralCategory = pluralRules.select(1d);
+ final ULocale locale = new ULocale(resolvedFile.getLocaleID());
+ String fullPerPattern = null;
+ int negCount = 0;
+
+ for (int i = 1; i >= 0; --i) { // two passes, numerator then den.
+ boolean positivePass = i > 0;
+ if (!positivePass) {
+ switch(locale.toString()) {
+ case "de": caseVariant = "accusative"; break; // German pro rule
+ }
+ numerator = result; // from now on, result ::= denominator
+ result = null;
+ }
+
+ Map<String, Integer> target = positivePass ? numUnitsToPowers : denUnitsToPowers;
+ int unitsLeft = target.size();
+ for (Entry<String, Integer> entry : target.entrySet()) {
+ String possiblyPrefixedUnit = entry.getKey();
+ String unit = stripPrefixInt(possiblyPrefixedUnit, deprefix);
+ String genderVariant = UnitPathType.gender.getTrans(resolvedFile, "long", unit, null, null, null, partsUsed);
+
+ int power = entry.getValue();
+ unitsLeft--;
+ String pluralCategory = unitsLeft == 0 && positivePass ? _pluralCategory : singularPluralCategory;
+
+ if (!positivePass) {
+ if (maximal && 0 == negCount++) { // special case exact match for per form, and no previous result
+ if (true) {
+ throw new UnsupportedOperationException("not yet implemented fully");
+ }
+ String fullUnit;
+ switch(power) {
+ case 1: fullUnit = unit; break;
+ case 2: fullUnit = "square-" + unit; break;
+ case 3: fullUnit = "cubic-" + unit; break;
+ default: throw new IllegalArgumentException("powers > 3 not supported");
+ }
+ fullPerPattern = UnitPathType.perUnit.getTrans(resolvedFile, width, fullUnit, _pluralCategory, caseVariant, genderVariant, partsUsed);
+ // if there is a special form, we'll use it
+ if (fullPerPattern != null) {
+ continue;
+ }
+ }
+ }
+
+ // handle prefix, like kilo-
+ String prefixPattern = null;
+ if (deprefix.value != 1) {
+ prefixPattern = UnitPathType.prefix.getTrans(resolvedFile, width, "10p" + deprefix.value, _pluralCategory, caseVariant, genderVariant, partsUsed);
+ }
+
+ // get the core pattern. Detect and remove the the placeholder (and surrounding spaces)
+ String unitPattern = UnitPathType.unit.getTrans(resolvedFile, width, unit, pluralCategory, caseVariant, genderVariant, partsUsed);
+ if (unitPattern == null) {
+ return null; // unavailable
+ }
+ // we are set up for 2 kinds of placeholder patterns for units. {0}\s?stuff or stuff\s?{0}, or nothing(Eg Arabic)
+ placeholderPosition = extractUnit(placeholderMatcher, unitPattern, unitPatternOut);
+ if (placeholderPosition == PlaceholderLocation.middle) {
+ return null; // signal we can't handle, but shouldn't happen with well-formed data.
+ } else if (placeholderPosition != PlaceholderLocation.missing) {
+ unitPattern = unitPatternOut.value;
+ placeholderPattern = placeholderMatcher.group();
+ }
+
+ // we have all the pieces, so build it up
+ if (prefixPattern != null) {
+ unitPattern = combineLowercasing(locale, width, prefixPattern, unitPattern);
+ }
+
+ String powerPattern = null;
+ switch (power) {
+ case 1:
+ break;
+ case 2:
+ powerPattern = UnitPathType.power.getTrans(resolvedFile, width, "power2", pluralCategory, caseVariant, genderVariant, partsUsed);
+ break;
+ case 3:
+ powerPattern = UnitPathType.power.getTrans(resolvedFile, width, "power3", pluralCategory, caseVariant, genderVariant, partsUsed);
+ break;
+ default:
+ throw new IllegalArgumentException("No power pattern > 3: " + this);
+ }
+
+ if (powerPattern != null) {
+ unitPattern = combineLowercasing(locale, width, powerPattern, unitPattern);
+ }
+
+ if (result != null) {
+ if (timesPattern == null) {
+ timesPattern = getTimesPattern(resolvedFile, width);
+ }
+ result = MessageFormat.format(timesPattern, result, unitPattern);
+ } else {
+ result = unitPattern;
+ }
+ }
+ }
+
+ // if there is a fullPerPattern, then we use it instead of per pattern + first denominator element
+ if (fullPerPattern != null) {
+ if (numerator != null) {
+ numerator = MessageFormat.format(fullPerPattern, numerator);
+ } else {
+ numerator = fullPerPattern;
+ placeholderPattern = null;
+ }
+ if (result != null) {
+ if (timesPattern == null) {
+ timesPattern = getTimesPattern(resolvedFile, width);
+ }
+ numerator = MessageFormat.format(timesPattern, numerator, result);
+ }
+ result = numerator;
+ } else {
+ // glue the two parts together, if we have two of them
+ if (result == null) {
+ result = numerator;
+ } else {
+ String perPattern = UnitPathType.per.getTrans(resolvedFile, width, null, _pluralCategory, caseVariant, null, partsUsed);
+ if (numerator == null) {
+ result = MessageFormat.format(perPattern, "", result).trim();
+ } else {
+ result = MessageFormat.format(perPattern, numerator, result);
+ }
+ }
+ }
+ return addPlaceholder(result, placeholderPattern, placeholderPosition);
+ }
+
+ public String getTimesPattern(LocaleStringProvider resolvedFile, String width) { // TODO fix hack!
+ if (HACK && "en".equals(resolvedFile.getLocaleID())) {
+ return "{0}-{1}";
+ }
+ String timesPatternPath = "//ldml/units/unitLength[@type=\"" + width + "\"]/compoundUnit[@type=\"times\"]/compoundUnitPattern";
+ return resolvedFile.getStringValue(timesPatternPath);
+ }
+
@Override
public boolean equals(Object obj) {
UnitId other = (UnitId) obj;
- return numUnitsToPowers.equals(other.numUnitsToPowers)
+ return numUnitsToPowers.equals(other.numUnitsToPowers)
&& denUnitsToPowers.equals(other.denUnitsToPowers);
}
@Override
@@ -668,7 +911,7 @@
}
public UnitId resolve() {
- UnitId result = new UnitId();
+ UnitId result = new UnitId(UNIT_COMPARATOR);
result.numUnitsToPowers.putAll(numUnitsToPowers);
result.denUnitsToPowers.putAll(denUnitsToPowers);
for (Entry<String, Integer> entry : numUnitsToPowers.entrySet()) {
@@ -691,10 +934,174 @@
}
return result.freeze();
}
+
+ @Override
+ public int compareTo(UnitId o) {
+ int diff = compareEntrySets(numUnitsToPowers.entrySet(), o.numUnitsToPowers.entrySet(), entrySetComparator);
+ if (diff != 0) return diff;
+ return compareEntrySets(denUnitsToPowers.entrySet(), o.denUnitsToPowers.entrySet(), entrySetComparator);
+ }
+
+ /**
+ * Default rules
+ * Prefixes & powers: the gender of the whole is the same as the gender of the operand. In pseudocode:
+ gender(square, meter) = gender(meter)
+ gender(kilo, meter) = gender(meter)
+
+ * Per: the gender of the whole is the gender of the numerator. If there is no numerator, then the gender of the denominator
+ gender(gram per meter) = gender(gram)
+
+ * Times: the gender of the whole is the gender of the last operand
+ gender(gram-meter) = gender(gram)
+ * @param source
+ * @param partsUsed
+
+ * @return
+ * TODO: add parameter to short-circuit the lookup if the unit is not a compound.
+ */
+ public String getGender(CLDRFile resolvedFile, Output<String> source, Multimap<UnitPathType, String> partsUsed) {
+ // will not be empty
+
+ GrammarDerivation gd = null;
+ //Values power = gd.get(GrammaticalFeature.grammaticalGender, CompoundUnitStructure.power); no data available yet
+ //Values prefix = gd.get(GrammaticalFeature.grammaticalGender, CompoundUnitStructure.prefix);
+
+
+ Map<String,Integer> determiner;
+ if (numUnitsToPowers.isEmpty()) {
+ determiner = denUnitsToPowers;
+ } else if (denUnitsToPowers.isEmpty()) {
+ determiner = numUnitsToPowers;
+ } else {
+ if (gd == null) {
+ gd = SupplementalDataInfo.getInstance().getGrammarDerivation(resolvedFile.getLocaleID());
+ }
+ Values per = gd.get(GrammaticalFeature.grammaticalGender, CompoundUnitStructure.per);
+ boolean useFirst = per.value0.equals("0");
+ determiner = useFirst ? numUnitsToPowers // otherwise use numerator if possible
+ : denUnitsToPowers;
+ // TODO add test that the value is 0 or 1, so that if it fails we know to upgrade this code.
+ }
+
+ Entry<String, Integer> bestMeasure;
+ if (determiner.size() == 1) {
+ bestMeasure = determiner.entrySet().iterator().next();
+ } else {
+ if (gd == null) {
+ gd = SupplementalDataInfo.getInstance().getGrammarDerivation(resolvedFile.getLocaleID());
+ }
+ Values times = gd.get(GrammaticalFeature.grammaticalGender, CompoundUnitStructure.times);
+ boolean useFirst = times.value0.equals("0");
+ if (useFirst) {
+ bestMeasure = determiner.entrySet().iterator().next();
+ } else {
+ bestMeasure = null; // we know the determiner is not empty, but this makes the compiler
+ for (Entry<String, Integer> entry : determiner.entrySet()) {
+ bestMeasure = entry;
+ }
+ }
+ }
+ String strippedUnit = stripPrefixInt(bestMeasure.getKey(), null);
+ String gender = UnitPathType.gender.getTrans(resolvedFile, "long", strippedUnit, null, null, null, partsUsed);
+ if (gender != null && source != null) {
+ source.value = strippedUnit;
+ }
+ return gender;
+ }
+
}
+ public enum PlaceholderLocation {before, middle, after, missing}
+
+ public static String addPlaceholder(String result, String placeholderPattern, PlaceholderLocation placeholderPosition) {
+ return placeholderPattern == null ? result
+ : placeholderPosition == PlaceholderLocation.before ? placeholderPattern + result
+ : result + placeholderPattern;
+ }
+
+ /**
+ * Returns the location of the placeholder. Call placeholderMatcher.group() after calling this to get the placeholder.
+ * @param placeholderMatcher
+ * @param unitPattern
+ * @param unitPatternOut
+ * @param before
+ * @return
+ */
+ public static PlaceholderLocation extractUnit(Matcher placeholderMatcher, String unitPattern, Output<String> unitPatternOut) {
+ if (placeholderMatcher.reset(unitPattern).find()) {
+ if (placeholderMatcher.start() == 0) {
+ unitPatternOut.value = unitPattern.substring(placeholderMatcher.end());
+ return PlaceholderLocation.before;
+ } else if (placeholderMatcher.end() == unitPattern.length()) {
+ unitPatternOut.value = unitPattern.substring(0, placeholderMatcher.start());
+ return PlaceholderLocation.after;
+ } else {
+ unitPatternOut.value = unitPattern;
+ return PlaceholderLocation.middle;
+ }
+ } else {
+ unitPatternOut.value = unitPattern;
+ return PlaceholderLocation.missing;
+ }
+ }
+
+ public static String combineLowercasing(final ULocale locale, String width, String prefixPattern, String unitPattern) {
+ // catch special case, ZentiLiter
+ if (width.equals("long") && !prefixPattern.contains(" {") && !prefixPattern.contains(" {")) {
+ unitPattern = UCharacter.toLowerCase(locale, unitPattern);
+ }
+ unitPattern = MessageFormat.format(prefixPattern, unitPattern);
+ return unitPattern;
+ }
+
+ public static class EntrySetComparator<K extends Comparable<K>,V> implements Comparator<Entry<K, V>> {
+ Comparator<K> kComparator;
+ Comparator<V> vComparator;
+ public EntrySetComparator(Comparator<K> kComparator, Comparator<V> vComparator) {
+ this.kComparator = kComparator;
+ this.vComparator = vComparator;
+ }
+ @Override
+ public int compare(Entry<K, V> o1, Entry<K, V> o2) {
+ int diff = kComparator.compare(o1.getKey(), o2.getKey());
+ if (diff != 0) {
+ return diff;
+ }
+ diff = vComparator.compare(o1.getValue(), o2.getValue());
+ if (diff != 0) {
+ return diff;
+ }
+ return o1.getKey().compareTo(o2.getKey());
+ }
+ }
+
+ public static <K extends Comparable<K>, V extends Comparable<V>, T extends Entry<K, V>> int compareEntrySets(Collection<T> o1, Collection<T> o2, Comparator<T> comparator) {
+ Iterator<T> iterator1 = o1.iterator();
+ Iterator<T> iterator2 = o2.iterator();
+ while (true) {
+ if (!iterator1.hasNext()) {
+ return iterator2.hasNext() ? -1 : 0;
+ } else if (!iterator2.hasNext()) {
+ return 1;
+ }
+ T item1 = iterator1.next();
+ T item2 = iterator2.next();
+ int diff = comparator.compare(item1, item2);
+ if (diff != 0) {
+ return diff;
+ }
+ }
+ }
+
+ private ConcurrentHashMap<String, UnitId> UNIT_ID = new ConcurrentHashMap<>();
+ // TODO This is safe but should use regular cache
public final UnitId createUnitId(String unit) {
- return new UnitId().add(continuations, unit, true, 1).freeze();
+ UnitId result = UNIT_ID.get(unit);
+ if (result == null) {
+ result = new UnitId(UNIT_COMPARATOR).add(continuations, unit, true, 1).freeze();
+ UNIT_ID.put(unit, result);
+ }
+ return result;
}
public boolean isBaseUnit(String unit) {
@@ -710,54 +1117,78 @@
}
// TODO change to TRIE if the performance isn't good enough, or restructure with regex
- public static final ImmutableMap<String, Rational> PREFIXES = ImmutableMap.<String, Rational>builder()
- .put("yocto", Rational.pow10(-24))
- .put("zepto", Rational.pow10(-21))
- .put("atto", Rational.pow10(-18))
- .put("femto", Rational.pow10(-15))
- .put("pico", Rational.pow10(-12))
- .put("nano", Rational.pow10(-9))
- .put("micro", Rational.pow10(-6))
- .put("milli", Rational.pow10(-3))
- .put("centi", Rational.pow10(-2))
- .put("deci", Rational.pow10(-1))
- .put("deka", Rational.pow10(1))
- .put("hecto", Rational.pow10(2))
- .put("kilo", Rational.pow10(3))
- .put("mega", Rational.pow10(6))
- .put("giga", Rational.pow10(9))
- .put("tera", Rational.pow10(12))
- .put("peta", Rational.pow10(15))
- .put("exa", Rational.pow10(18))
- .put("zetta", Rational.pow10(21))
- .put("yotta", Rational.pow10(24))
+ public static final ImmutableMap<String, Integer> PREFIX_POWERS = ImmutableMap.<String, Integer>builder()
+ .put("yocto", -24)
+ .put("zepto", -21)
+ .put("atto", -18)
+ .put("femto", -15)
+ .put("pico", -12)
+ .put("nano", -9)
+ .put("micro", -6)
+ .put("milli", -3)
+ .put("centi", -2)
+ .put("deci", -1)
+ .put("deka", 1)
+ .put("hecto", 2)
+ .put("kilo", 3)
+ .put("mega", 6)
+ .put("giga", 9)
+ .put("tera", 12)
+ .put("peta", 15)
+ .put("exa", 18)
+ .put("zetta", 21)
+ .put("yotta", 24)
.build();
+ public static final ImmutableMap<String, Rational> PREFIXES;
+ static {
+ Map<String, Rational> temp = new LinkedHashMap<>();
+ for (Entry<String, Integer> entry : PREFIX_POWERS.entrySet()) {
+ temp.put(entry.getKey(), Rational.pow10(entry.getValue()));
+ }
+ PREFIXES = ImmutableMap.copyOf(temp);
+ }
+
static final Set<String> SKIP_PREFIX = ImmutableSet.of(
- "millimeter-ofhg",
+ "millimeter-ofhg",
"kilogram"
);
- /**
- * If there is no prefix, return the unit and Rational.ONE.
- * If there is a prefix return the unit (with prefix stripped) and the prefix factor
+ /**
+ * If there is no prefix, return the unit and ONE.
+ * If there is a prefix return the unit (with prefix stripped) and the prefix factor
* */
- private String stripPrefix(String unit, Output<Rational> deprefix) {
- deprefix.value = Rational.ONE;
+ private static <V> String stripPrefixCommon(String unit, Output<V> deprefix, Map<String, V> unitMap) {
if (SKIP_PREFIX.contains(unit)) {
return unit;
}
- for (Entry<String, Rational> entry : PREFIXES.entrySet()) {
+ for (Entry<String, V> entry : unitMap.entrySet()) {
String prefix = entry.getKey();
if (unit.startsWith(prefix)) {
- deprefix.value = entry.getValue();
+ if (deprefix != null) {
+ deprefix.value = entry.getValue();
+ }
return unit.substring(prefix.length());
}
}
return unit;
}
+ public static String stripPrefix(String unit, Output<Rational> deprefix) {
+ if (deprefix != null) {
+ deprefix.value = Rational.ONE;
+ }
+ return stripPrefixCommon(unit, deprefix, PREFIXES);
+ }
+
+ public static String stripPrefixInt(String unit, Output<Integer> deprefix) {
+ if (deprefix != null) {
+ deprefix.value = Integer.valueOf(1);
+ }
+ return stripPrefixCommon(unit, deprefix, PREFIX_POWERS);
+ }
+
public BiMap<String, String> getBaseUnitToQuantity() {
return (BiMap<String, String>) baseUnitToQuantity;
}
@@ -809,7 +1240,7 @@
}
public Map<String, TargetInfo> getInternalConversionData() {
- return sourceToTargetInfo;
+ return sourceToTargetInfo;
}
public Multimap<String, String> getSourceToSystems() {
@@ -829,18 +1260,18 @@
}
public static final Set<String> OTHER_SYSTEM = ImmutableSet.of(
- "g-force", "dalton", "calorie", "earth-radius",
- "solar-radius", "solar-radius", "astronomical-unit", "light-year", "parsec", "earth-mass",
- "solar-mass", "bit", "byte", "karat", "solar-luminosity", "ofhg", "atmosphere",
+ "g-force", "dalton", "calorie", "earth-radius",
+ "solar-radius", "solar-radius", "astronomical-unit", "light-year", "parsec", "earth-mass",
+ "solar-mass", "bit", "byte", "karat", "solar-luminosity", "ofhg", "atmosphere",
"pixel", "dot", "permillion", "permyriad", "permille", "percent", "karat", "portion",
"minute", "hour", "day", "day-person", "week", "week-person",
"year", "year-person", "decade", "month", "month-person", "century",
"arc-second", "arc-minute", "degree", "radian", "revolution",
- "electronvolt",
+ "electronvolt",
// quasi-metric
"dunam", "mile-scandinavian", "carat", "cup-metric", "pint-metric"
);
-
+
private void addSystems(Set<String> result, String subunit) {
Collection<String> systems = sourceToSystems.get(subunit);
if (!systems.isEmpty()) {
@@ -949,4 +1380,64 @@
public Set<String> getQuantities() {
return getBaseUnitToQuantity().inverse().keySet();
}
+
+ public enum UnitComplexity {simple, non_simple}
+
+ private ConcurrentHashMap<String, UnitComplexity> COMPLEXITY = new ConcurrentHashMap<>();
+ // TODO This is safe but should use regular cache
+
+ public UnitComplexity getComplexity (String longOrShortId){
+ UnitComplexity result = COMPLEXITY.get(longOrShortId);
+ if (result == null) {
+ String shortId;
+ String longId = getLongId(longOrShortId);
+ if (longId == null) {
+ longId = longOrShortId;
+ shortId = SHORT_TO_LONG_ID.inverse().get(longId);
+ } else {
+ shortId = longOrShortId;
+ }
+ UnitId uid = createUnitId(shortId);
+ result = UnitComplexity.simple;
+
+ if (uid.numUnitsToPowers.size() != 1 || !uid.denUnitsToPowers.isEmpty()) {
+ result = UnitComplexity.non_simple;
+ } else {
+ Output<Rational> deprefix = new Output<>();
+ for (Entry<String, Integer> entry : uid.numUnitsToPowers.entrySet()) {
+ final String unitPart = entry.getKey();
+ UnitConverter.stripPrefix(unitPart, deprefix );
+ if (!deprefix.value.equals(Rational.ONE) || !entry.getValue().equals(INTEGER_ONE)) {
+ result = UnitComplexity.non_simple;
+ break;
+ }
+ }
+ if (result == UnitComplexity.simple) {
+ for (Entry<String, Integer> entry : uid.denUnitsToPowers.entrySet()) {
+ final String unitPart = entry.getKey();
+ UnitConverter.stripPrefix(unitPart, deprefix);
+ if (!deprefix.value.equals(Rational.ONE)) {
+ result = UnitComplexity.non_simple;
+ break;
+ }
+ }
+ }
+ }
+ COMPLEXITY.put(shortId, result);
+ COMPLEXITY.put(longId, result);
+ }
+ return result;
+ }
+
+ public boolean isSimple(String x) {
+ return getComplexity(x) == UnitComplexity.simple;
+ }
+
+ public String getLongId(String shortUnitId) {
+ return CldrUtility.ifNull(SHORT_TO_LONG_ID.get(shortUnitId), shortUnitId);
+ }
+
+ public String getShortId(String longUnitId) {
+ return CldrUtility.ifNull(SHORT_TO_LONG_ID.inverse().get(longUnitId), longUnitId);
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/UnitPathType.java b/tools/java/org/unicode/cldr/util/UnitPathType.java
new file mode 100644
index 0000000..c491ef1
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/UnitPathType.java
@@ -0,0 +1,155 @@
+package org.unicode.cldr.util;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+
+public enum UnitPathType {
+ // we may add features over time
+ unit("kilometer", EnumSet.of(
+ GrammarInfo.GrammaticalFeature.grammaticalNumber,
+ GrammarInfo.GrammaticalFeature.grammaticalCase),
+ null),
+ perUnit("minute", null, null),
+ times(null, null, ImmutableMultimap.<String,String>builder()
+ .put("", "newton-meter")
+ .put("", "kilowatt-hour")
+ .build()),
+ per(null, null, ImmutableMultimap.<String,String>builder()
+ .put("", "meter-per-second")
+ .put("", "mile-per-gallon")
+ .build()),
+ prefix(null, null, ImmutableMultimap.<String,String>builder()
+ .put("10p2", "hectopascal")
+ .put("10p3", "kilometer")
+ .put("10p6", "megabyte")
+ .put("10p9", "gigahertz")
+ .put("10p12", "terabyte")
+ .put("10p15", "petabyte")
+ .put("10p-1", "deciliter")
+ .put("10p-2", "centimeter")
+ .put("10p-3", "milligram")
+ .put("10p-6", "microsecond")
+ .put("10p-9", "nanosecond")
+ .put("10p-12", "picometer")
+ .build()),
+ power("power2",
+ EnumSet.of(
+ GrammarInfo.GrammaticalFeature.grammaticalNumber,
+ GrammarInfo.GrammaticalFeature.grammaticalCase,
+ GrammarInfo.GrammaticalFeature.grammaticalGender),
+ ImmutableMultimap.<String,String>builder()
+ .put("power2", "square-meter")
+ .put("power2", "square-second")
+ .put("power3", "cubic-meter")
+ .put("power3", "cubic-second")
+ .build()),
+ duration(null, null, null),
+ gender(null,null, null),
+ coordinate(null, null, null),
+ displayName(null, null, null)
+ ;
+
+ public final Set<GrammaticalFeature> features;
+ public final Set<String> sampleShortUnitType;
+ public final ImmutableMultimap<String,String> sampleComposedShortUnitIds;
+
+ private UnitPathType(String sampleType, Set<GrammarInfo.GrammaticalFeature> features, ImmutableMultimap<String,String> sampleComposedLongUnits) {
+ this.sampleShortUnitType = Collections.singleton(sampleType);
+ this.sampleComposedShortUnitIds = sampleComposedLongUnits;
+ this.features = features == null ? Collections.emptySet() : ImmutableSet.copyOf(features);
+ }
+
+ public static UnitPathType getPathType(XPathParts parts) {
+ if (!parts.getElement(2).equals("unitLength")) {
+ return null;
+ }
+ switch (parts.getElement(-1)) {
+ case "compoundUnitPattern": return "times".equals(parts.getAttributeValue(-2, "type")) ? UnitPathType.times : UnitPathType.per;
+ case "unitPrefixPattern": return UnitPathType.prefix;
+ case "compoundUnitPattern1": return UnitPathType.power;
+ case "unitPattern": return UnitPathType.unit;
+ case "perUnitPattern": return UnitPathType.perUnit;
+ case "prefix": return UnitPathType.prefix;
+ case "gender": return UnitPathType.gender;
+ case "coordinateUnitPattern": return UnitPathType.coordinate;
+ case "durationUnit": return UnitPathType.duration;
+ case "alias": return null;
+ case "displayName": return UnitPathType.displayName;
+ }
+ throw new IllegalArgumentException("PathType: " + parts);
+ }
+
+ public String getTranslationPath(LocaleStringProvider resolvedFile, String width, String shortUnitId, String pluralCategory,
+ String caseVariant, String genderVariant) {
+ UnitPathType pathType = this;
+ final String pathPrefix = "//ldml/units/unitLength[@type=\"" + width + "\"]/";
+ String longUnitId;
+ GrammarInfo grammarInfo1;
+ UnitConverter uc = CLDRConfig.getInstance().getSupplementalDataInfo().getUnitConverter();
+
+ String grammaticalAttributes;
+ switch (pathType) {
+ case times:
+ return pathPrefix + "compoundUnit[@type=\"" + "times" + "\"]/compoundUnitPattern";
+ case per:
+ return pathPrefix + "compoundUnit[@type=\"" + "per" + "\"]/compoundUnitPattern";
+ case prefix:
+ longUnitId = CLDRConfig.getInstance().getSupplementalDataInfo().getUnitConverter().getLongId(shortUnitId);
+ return pathPrefix + "compoundUnit[@type=\"" + longUnitId + "\"]/unitPrefixPattern";
+ case power:
+ longUnitId = uc.getLongId(shortUnitId);
+ grammarInfo1 = CLDRConfig.getInstance().getSupplementalDataInfo().getGrammarInfo(resolvedFile.getLocaleID());
+ grammaticalAttributes = GrammarInfo.getGrammaticalInfoAttributes(grammarInfo1, pathType, pluralCategory, genderVariant, caseVariant);
+ return pathPrefix + "compoundUnit[@type=\"" + longUnitId + "\"]/compoundUnitPattern1" + grammaticalAttributes;
+ case unit:
+ longUnitId = uc.getLongId(shortUnitId);
+ grammarInfo1 = CLDRConfig.getInstance().getSupplementalDataInfo().getGrammarInfo(resolvedFile.getLocaleID());
+ grammaticalAttributes = GrammarInfo.getGrammaticalInfoAttributes(grammarInfo1, pathType, pluralCategory, genderVariant, caseVariant);
+ return pathPrefix + "unit[@type=\"" + longUnitId + "\"]/unitPattern" + grammaticalAttributes;
+ case displayName:
+ longUnitId = uc.getLongId(shortUnitId);
+ return pathPrefix + "unit[@type=\"" + longUnitId + "\"]/displayName";
+ case perUnit:
+ longUnitId = uc.getLongId(shortUnitId);
+ return pathPrefix + "unit[@type=\"" + longUnitId + "\"]/perUnitPattern";
+ case gender:
+ if (!width.equals("long")) {
+ throw new IllegalArgumentException("illegal width for gender: ");
+ }
+ longUnitId = uc.getLongId(shortUnitId);
+ return pathPrefix + "unit[@type=\"" + uc.getLongId(shortUnitId) + "\"]/gender";
+ case coordinate:
+ return pathPrefix + "coordinateUnit/coordinateUnitPattern[@type=\"" + shortUnitId + "\"]";
+ case duration:
+ return "//ldml/units/durationUnit[@type=\"" + shortUnitId + "\"]/durationUnitPattern";
+ }
+ throw new IllegalArgumentException("PathType: " + pathType);
+ }
+
+ public String getTrans(LocaleStringProvider resolvedFile, String width, String shortUnitId, String pluralCategory, String caseVariant, String genderVariant, Multimap<UnitPathType, String> partsUsed) {
+ UnitPathType pathType = this;
+ String path = pathType.getTranslationPath(resolvedFile, width, shortUnitId, pluralCategory, caseVariant, genderVariant);
+ String result = resolvedFile.getStringValue(path);
+ if (result == null) {
+ int debug = 0;
+ }
+
+ if (partsUsed != null) {
+ CLDRFile.Status status = new CLDRFile.Status();
+ String foundLocale = resolvedFile.getSourceLocaleID(path, status );
+ partsUsed.put(pathType,
+ (result != null ? "«" + result + "»": "∅")
+ + (foundLocale.equals(resolvedFile.getLocaleID()) ? "" : "\n\t\tactualLocale: " + foundLocale)
+ + (status.pathWhereFound.equals(path) ? "" : "\n\t\trequestPath: " + path + "\n\t\tactualPath: " + status.pathWhereFound)
+ );
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/UnitPreferences.java b/tools/java/org/unicode/cldr/util/UnitPreferences.java
index 91f228a..7b8ca8b 100644
--- a/tools/java/org/unicode/cldr/util/UnitPreferences.java
+++ b/tools/java/org/unicode/cldr/util/UnitPreferences.java
@@ -22,7 +22,7 @@
Set<String> usages = new TreeSet<>();
/**
- * Special class encapsulating
+ * Special class encapsulating
* @author markdavis
*
*/
@@ -56,6 +56,7 @@
public String toString(String baseUnit) {
return geq + (baseUnit == null ? "": " " + baseUnit) + ", " + unit + (skeleton.isEmpty() ? "" : ", " + skeleton);
}
+ @Override
public String toString() {
return toString(null);
}
diff --git a/tools/java/org/unicode/cldr/util/Units.java b/tools/java/org/unicode/cldr/util/Units.java
index ee6a7d8..80cc33d 100644
--- a/tools/java/org/unicode/cldr/util/Units.java
+++ b/tools/java/org/unicode/cldr/util/Units.java
@@ -1,16 +1,27 @@
package org.unicode.cldr.util;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
import java.util.regex.Pattern;
import org.unicode.cldr.test.ExampleGenerator;
+import org.unicode.cldr.util.StandardCodes.LstrType;
+import org.unicode.cldr.util.Validity.Status;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetSpanner;
public class Units {
-
+
private static final UnicodeSet WHITESPACE = new UnicodeSet("[:whitespace:]").freeze();
public static Pattern NO_SPACE_PREFIX = Pattern.compile("\\}" + ExampleGenerator.backgroundEndSymbol + "?\\p{L}|\\p{L}" + ExampleGenerator.backgroundStartSymbol + "?\\{");
@@ -30,7 +41,7 @@
}
// hack to fix casing
- if (lowercaseUnitIfNoSpaceInCompound
+ if (lowercaseUnitIfNoSpaceInCompound
&& NO_SPACE_PREFIX.matcher(compoundPattern).find()) {
modFormat = modFormat.replace(modUnit, modUnit.toLowerCase(Locale.ENGLISH));
}
@@ -40,4 +51,31 @@
static final UnicodeSetSpanner SPACE_SPANNER = new UnicodeSetSpanner(WHITESPACE);
+ public static final Map<String,String> CORE_TO_TYPE;
+ public static final Multimap<String,String> TYPE_TO_CORE;
+ public static final BiMap<String,String> LONG_TO_SHORT;
+
+ static {
+ Set<String> VALID_UNITS = Validity.getInstance().getStatusToCodes(LstrType.unit).get(Status.regular);
+
+ Map<String, String> coreToType = new TreeMap<>();
+ Multimap<String, String> typeToCore = TreeMultimap.create();
+ Map<String, String> longToShort = new TreeMap<>();
+ for (String s : VALID_UNITS) {
+ int dashPos = s.indexOf('-');
+ String unitType = s.substring(0,dashPos);
+ String coreUnit = s.substring(dashPos+1);
+ longToShort.put(s, coreUnit);
+ //coreUnit = converter.fixDenormalized(coreUnit);
+ coreToType.put(coreUnit, unitType);
+ typeToCore.put(unitType, coreUnit);
+ }
+ CORE_TO_TYPE = ImmutableMap.copyOf(coreToType);
+ TYPE_TO_CORE = ImmutableMultimap.copyOf(typeToCore);
+ LONG_TO_SHORT = ImmutableBiMap.copyOf(longToShort);
+ }
+
+ public static String getShort(String longUnit) {
+ return LONG_TO_SHORT.get(longUnit);
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/Unlocode.java b/tools/java/org/unicode/cldr/util/Unlocode.java
index d1f2df6..55cc0b1 100644
--- a/tools/java/org/unicode/cldr/util/Unlocode.java
+++ b/tools/java/org/unicode/cldr/util/Unlocode.java
@@ -20,7 +20,7 @@
import org.unicode.cldr.tool.ToolConfig;
import org.unicode.cldr.util.ChainedMap.M3;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.Transform;
import com.ibm.icu.text.Transliterator;
@@ -44,7 +44,7 @@
}
public Iso3166_2Data(Collection<String> names) {
- this.names = Collections.unmodifiableSet(new LinkedHashSet<String>(names));
+ this.names = Collections.unmodifiableSet(new LinkedHashSet<>(names));
}
@Override
@@ -54,7 +54,7 @@
@Override
public boolean equals(Object obj) {
- return names.equals((Iso3166_2Data) obj);
+ return names.equals(obj);
}
@Override
@@ -64,7 +64,7 @@
@Override
public Iso3166_2Data merge(Iso3166_2Data b) {
- LinkedHashSet<String> set = new LinkedHashSet<String>(names);
+ LinkedHashSet<String> set = new LinkedHashSet<>(names);
set.addAll(b.names);
return new Iso3166_2Data(set);
}
@@ -83,7 +83,7 @@
public LocodeData(String locode, Collection<String> names, String subdivision, float north, float east) {
this.locode = locode;
- this.names = Collections.unmodifiableSet(new LinkedHashSet<String>(names));
+ this.names = Collections.unmodifiableSet(new LinkedHashSet<>(names));
this.subdivision = subdivision;
this.north = north;
this.east = east;
@@ -123,7 +123,7 @@
&& subdivision.equals(other.subdivision)
&& north == other.north
&& east == other.east) {
- LinkedHashSet<String> set = new LinkedHashSet<String>(names);
+ LinkedHashSet<String> set = new LinkedHashSet<>(names);
set.addAll(other.names);
return new LocodeData(locode, set, subdivision, north, east);
}
@@ -132,9 +132,9 @@
}
- static Map<String, LocodeData> locodeToData = new HashMap<String, LocodeData>();
+ static Map<String, LocodeData> locodeToData = new HashMap<>();
static Relation<String, LocodeData> nameToLocodeData = Relation.of(new HashMap<String, Set<LocodeData>>(), HashSet.class);
- static Map<String, Iso3166_2Data> iso3166_2Data = new HashMap<String, Iso3166_2Data>();
+ static Map<String, Iso3166_2Data> iso3166_2Data = new HashMap<>();
static Relation<String, String> ERRORS = Relation.of(new TreeMap<String, Set<String>>(), TreeSet.class);
static {
@@ -294,7 +294,7 @@
"data/external/2013-1_UNLOCODE_CodeListPart" + file + ".csv",
LATIN1);
M3<String, String, Boolean> nameToAlternate = ChainedMap.of(new TreeMap<String, Object>(), new TreeMap<String, Object>(), Boolean.class);
- Output<String> tempOutput = new Output<String>();
+ Output<String> tempOutput = new Output<>();
String oldCountryCode = null;
while (true) {
@@ -467,19 +467,19 @@
public static void main(String[] args) throws IOException {
Relation<String, LocodeData> countryNameToCities = Relation.of(new TreeMap<String, Set<LocodeData>>(), TreeSet.class);
- Set<String> errors = new TreeSet<String>();
+ Set<String> errors = new TreeSet<>();
loadCitiesCapitals(countryNameToCities, errors);
loadCitiesOver1M(countryNameToCities, errors);
SupplementalDataInfo supp = ToolConfig.getToolInstance().getSupplementalDataInfo();
- Set<String> missing = new TreeSet<String>(
+ Set<String> missing = new TreeSet<>(
supp.getBcp47Keys().get("tz"));
- Set<String> already = new TreeSet<String>();
+ Set<String> already = new TreeSet<>();
for (Entry<String, LocodeData> entry : countryNameToCities.keyValueSet()) {
String countryName = entry.getKey();
LocodeData item = entry.getValue();
String firstName = item.names.iterator().next();
- LinkedHashSet<String> remainingNames = new LinkedHashSet<String>(item.names);
+ LinkedHashSet<String> remainingNames = new LinkedHashSet<>(item.names);
remainingNames.remove(firstName);
String lowerLocode = item.locode.toLowerCase(Locale.ENGLISH);
String info = countryName
@@ -497,7 +497,7 @@
+ "-->");
}
System.out.println();
- System.out.println(CollectionUtilities.join(errors, "\n"));
+ System.out.println(Joiner.on("\n").join(errors));
System.out.println();
showLocodes("In exemplars already:", already);
System.out.println();
@@ -513,7 +513,7 @@
// System.out.println((i++) + "\t" + s + "\t" + Unlocode.getIso3166_2Data(s));
// //if (i > 1000) break;
// }
- for (String s : new TreeSet<String>(Unlocode.getAvailable())) {
+ for (String s : new TreeSet<>(Unlocode.getAvailable())) {
if (!s.startsWith("GT")) {
continue;
}
@@ -536,8 +536,8 @@
}
public static void showLocodes(String title, Set<String> already) {
- Set<String> noData = new TreeSet<String>();
- Set<String> noData2 = new TreeSet<String>();
+ Set<String> noData = new TreeSet<>();
+ Set<String> noData2 = new TreeSet<>();
for (String locode : already) {
String upperLocode = locode.toUpperCase(Locale.ENGLISH);
String countryName = ULocale.getDisplayCountry("und-" + upperLocode.substring(0, 2), ULocale.ENGLISH);
@@ -638,14 +638,14 @@
return i;
}
- static final Set<String> noncountries = new HashSet<String>(Arrays.asList(
+ static final Set<String> noncountries = new HashSet<>(Arrays.asList(
"United States Virgin Islands", "Akrotiri and Dhekelia", "Easter Island", "Somaliland", "Northern Cyprus", "Nagorno-Karabakh Republic", "Abkhazia",
"Transnistria", "South Ossetia"));
static final Transform<String, String> REMOVE_ACCENTS = Transliterator.getInstance("nfd;[:mn:]remove");
static void add(String countryName, String subdivision, String cityName, Relation<String, LocodeData> countryNameToCities, Set<String> errors2) {
- String countryCode = CountryCodeConverter.getCodeFromName(countryName);
+ String countryCode = CountryCodeConverter.getCodeFromName(countryName, false);
if (countryCode == null) {
if (noncountries.contains(countryName)) {
return; // skip
@@ -665,7 +665,7 @@
if (locodeDatas == null) {
errors2.add("** No matching record for\t" + countryName + "\t" + countryCode + "\t" + cityName);
} else {
- Set<LocodeData> rem = new LinkedHashSet<LocodeData>();
+ Set<LocodeData> rem = new LinkedHashSet<>();
for (LocodeData x : locodeDatas) {
if (x.locode.startsWith(countryCode)) {
if (x.subdivision.equals(subdivision)) {
diff --git a/tools/java/org/unicode/cldr/util/Validity.java b/tools/java/org/unicode/cldr/util/Validity.java
index 50ea63d..55901f7 100644
--- a/tools/java/org/unicode/cldr/util/Validity.java
+++ b/tools/java/org/unicode/cldr/util/Validity.java
@@ -50,13 +50,14 @@
Map<LstrType, Map<Status, Set<String>>> data = new EnumMap<>(LstrType.class);
Map<LstrType, Map<String, Status>> codeToStatus = new EnumMap<>(LstrType.class);
final String basePath = validityDirectory;
+
for (String file : new File(basePath).list()) {
if (!file.endsWith(".xml")) {
continue;
}
LstrType type = null;
try {
- type = LstrType.valueOf(file.substring(0, file.length() - 4));
+ type = LstrType.fromString(file.substring(0, file.length() - 4));
} catch (Exception e) {
continue;
}
@@ -76,7 +77,7 @@
if (!"id".equals(parts.getElement(-1))) {
continue;
}
- LstrType typeAttr = LstrType.valueOf(parts.getAttributeValue(-1, "type"));
+ LstrType typeAttr = LstrType.fromString(parts.getAttributeValue(-1, "type"));
if (typeAttr != type) {
throw new IllegalArgumentException("Corrupt value for " + type);
}
@@ -101,14 +102,18 @@
}
}
}
+ if (data.keySet().size() < 5) {
+ throw new IllegalArgumentException("Bad directory for validity files");
+ }
typeToStatusToCodes = CldrUtility.protectCollectionX(data);
typeToCodeToStatus = CldrUtility.protectCollectionX(codeToStatus);
}
/**
- *
+ *
* @deprecated Use {@link #getStatusToCodes(LstrType)}
*/
+ @Deprecated
public Map<LstrType, Map<Status, Set<String>>> getData() {
return typeToStatusToCodes;
}
diff --git a/tools/java/org/unicode/cldr/util/ValuePathStatus.java b/tools/java/org/unicode/cldr/util/ValuePathStatus.java
index e495128..58e2112 100644
--- a/tools/java/org/unicode/cldr/util/ValuePathStatus.java
+++ b/tools/java/org/unicode/cldr/util/ValuePathStatus.java
@@ -24,6 +24,7 @@
}
public static Transform<String, ValuePathStatus.MissingOK> MISSING_STATUS_TRANSFORM = new Transform<String, ValuePathStatus.MissingOK>() {
+ @Override
public ValuePathStatus.MissingOK transform(String source) {
return ValuePathStatus.MissingOK.valueOf(source);
}
@@ -45,7 +46,7 @@
}
public static boolean isMissingOk(CLDRFile sourceFile, String path, boolean latin, boolean aliased) {
- Output<String[]> arguments = new Output<String[]>();
+ Output<String[]> arguments = new Output<>();
List<String> failures = null;
// if (path.startsWith("//ldml/characters/parseLenients")) {
// int debug = 0;
diff --git a/tools/java/org/unicode/cldr/util/VariantFolder.java b/tools/java/org/unicode/cldr/util/VariantFolder.java
index 7e4bb4e..e2a3c01 100644
--- a/tools/java/org/unicode/cldr/util/VariantFolder.java
+++ b/tools/java/org/unicode/cldr/util/VariantFolder.java
@@ -20,6 +20,7 @@
public static SetMaker mySetMaker = new SetMaker() {
Comparator c = new UTF16.StringComparator(true, false, 0);
Comparator bestIsLowest = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
String s1 = o1.toString();
String s2 = o2.toString();
@@ -43,6 +44,7 @@
};
+ @Override
public Set make() {
return new TreeSet(bestIsLowest);
}
@@ -80,6 +82,7 @@
}
}
+ @Override
public Set<String> getAlternates(String item, Set<String> output) {
output.add(item);
return equivalents.getEquivalences(item);
@@ -97,6 +100,7 @@
}
}
+ @Override
public Set<String> getAlternates(String item, Set<String> output) {
output.add(item);
return equivalents.getEquivalences(item);
@@ -117,6 +121,7 @@
}
}
+ @Override
public Set<String> getAlternates(String item, Set<String> output) {
output.add(item);
return equivalents.getEquivalences(item);
@@ -143,7 +148,7 @@
public Set<String> getClosure(String source) {
int stringLength = source.length();
if (stringLength == 0) {
- Set<String> result = new HashSet<String>();
+ Set<String> result = new HashSet<>();
result.add(source);
return result;
}
@@ -161,7 +166,7 @@
int limit = start + level + 1;
// System.out.println(start + ", " + limit);
// we first add any longer alternates
- Collection<String> current = combos[level][start] = new HashSet<String>();
+ Collection<String> current = combos[level][start] = new HashSet<>();
current.addAll(alternateFetcher.getAlternates(source.substring(start,
limit), new HashSet<String>()));
// then we add the cross product of shorter strings
diff --git a/tools/java/org/unicode/cldr/util/VerifyCompactNumbers.java b/tools/java/org/unicode/cldr/util/VerifyCompactNumbers.java
index 3383b45..4586aa6 100644
--- a/tools/java/org/unicode/cldr/util/VerifyCompactNumbers.java
+++ b/tools/java/org/unicode/cldr/util/VerifyCompactNumbers.java
@@ -37,7 +37,7 @@
private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance();
private static final String DIR = CLDRPaths.VERIFY_DIR + "numbers/";
-
+
final static Options myOptions = new Options();
enum MyOptions {
@@ -52,7 +52,7 @@
// later, look at DateTimeFormats to set up as an HTML table
- public static final Set<String> USES_GROUPS_OF_4 = new HashSet<String>(Arrays.asList("ko", "ja", "zh", "zh_Hant"));
+ public static final Set<String> USES_GROUPS_OF_4 = new HashSet<>(Arrays.asList("ko", "ja", "zh", "zh_Hant"));
/**
* Produce a set of static tables from the vxml data. Only a stopgap until the above is integrated into ST.
@@ -80,7 +80,7 @@
NumberFormat enf = NumberFormat.getIntegerInstance(ULocale.ENGLISH);
enf.setGroupingUsed(false);
- Set<String> availableLanguages = new TreeSet<String>(factory2.getAvailableLanguages());
+ Set<String> availableLanguages = new TreeSet<>(factory2.getAvailableLanguages());
if (Pattern.matches(filter, "pt_PT")) {
availableLanguages.add("pt_PT");
}
@@ -133,8 +133,8 @@
public static void showNumbers(CLDRFile cldrFile, boolean showCurrency,
String currencyCode, Appendable out, Factory factory) {
try {
- Set<String> debugCreationErrors = new LinkedHashSet<String>();
- Set<String> errors = new LinkedHashSet<String>();
+ Set<String> debugCreationErrors = new LinkedHashSet<>();
+ Set<String> errors = new LinkedHashSet<>();
String locale = cldrFile.getLocaleID();
TablePrinter tablePrinter1 = new TablePrinter()
@@ -160,12 +160,12 @@
}
// tablePrinter1.addColumn("View").setHeaderCell(true).setHeaderAttributes("class='dtf-th'").setCellAttributes("class='dtf-s'");
- ;
+
ULocale locale2 = new ULocale(locale);
ICUServiceBuilder builder = new ICUServiceBuilder().setCldrFile(cldrFile);
NumberFormat nf = builder.getNumberFormat(1);
-
+
// nf.setMaximumFractionDigits(0);
SupplementalDataInfo sdi = CLDR_CONFIG.getSupplementalDataInfo();
String[] debugOriginals = null;
@@ -240,12 +240,12 @@
+ "All of those you should be able to substitute for the numbers in the Minimal Pairs, "
+ "with an acceptable result. "
+ "If any would be incorrect, please "
- + "<a target='ticket' href='https://unicode.org/cldr/trac/newticket'>file a ticket</a>.</p>"
+ + "<a target='ticket' href='" + CLDRURLS.CLDR_NEWTICKET_URL + "'>file a ticket</a>.</p>"
+ "<p>For more details, see " +
"<a target='CLDR-ST-DOCS' href='http://cldr.unicode.org/index/cldr-spec/plural-rules'>Plural Rules</a>.</p>");
ShowPlurals showPlurals = new ShowPlurals(CLDR_CONFIG.getSupplementalDataInfo());
showPlurals.printPluralTable(cldrFile, locale, out, factory);
- showPlurals.appendBlanksForScrolling(out);
+ ShowPlurals.appendBlanksForScrolling(out);
showErrors(errors, out);
showErrors(debugCreationErrors, out);
} catch (IOException e) {
@@ -263,7 +263,7 @@
// we want to collect a sample of at least one sample for each plural category for each
// power of ten
PluralInfo pluralInfo = sdi.getPlurals(locale);
- Set<Double> samples = new TreeSet<Double>();
+ Set<Double> samples = new TreeSet<>();
samples.add(1.1d);
samples.add(1.5d);
samples.add(1100d);
@@ -299,7 +299,7 @@
// }
// samples.addAll(samples2);
- Set<Double> allSamples = new TreeSet<Double>();
+ Set<Double> allSamples = new TreeSet<>();
for (long i = 1; i <= 100000000000000L; i *= factor) {
for (Double sample : samples) {
double source = i * sample;
@@ -325,7 +325,7 @@
private static Set<Double> collectItems(PluralInfo pluralInfo, double start, double limit,
Set<Double> samples) {
// TODO optimize once we have all the keywords
- Map<String, Double> ones = new TreeMap<String, Double>();
+ Map<String, Double> ones = new TreeMap<>();
for (double i = start; i < limit; ++i) {
String cat = pluralInfo.getPluralRules().select(i);
if (ones.containsKey(cat)) {
diff --git a/tools/java/org/unicode/cldr/util/VerifyZones.java b/tools/java/org/unicode/cldr/util/VerifyZones.java
index 303a688..9b4b48d 100644
--- a/tools/java/org/unicode/cldr/util/VerifyZones.java
+++ b/tools/java/org/unicode/cldr/util/VerifyZones.java
@@ -73,19 +73,19 @@
private final static SupplementalDataInfo sdi = SupplementalDataInfo.getInstance();
private final static Map<String, Map<String, String>> metazoneToRegionToZone = sdi.getMetazoneToRegionToZone();
- private final static Set<MetazoneRow> rows = new TreeSet<MetazoneRow>();
- private final static Set<String> goldenZones = new HashSet<String>();
- private final static Map<String, Integer> countryToOrder = new HashMap<String, Integer>();
+ private final static Set<MetazoneRow> rows = new TreeSet<>();
+ private final static Set<String> goldenZones = new HashSet<>();
+ private final static Map<String, Integer> countryToOrder = new HashMap<>();
private final static List<Format> FORMAT_LIST = Arrays.asList(Format.VVVV, Format.vvvv, Format.v, Format.zzzz,
Format.z, Format.zzzz, Format.z);
static {
// find out which canonical zones are not in a metazone
- Map<String, String> nameToCountry = new TreeMap<String, String>();
+ Map<String, String> nameToCountry = new TreeMap<>();
String[] zones = TimeZone.getAvailableIDs();
- Set<String> zoneSet = new LinkedHashSet<String>();
- Set<String> noncanonical = new LinkedHashSet<String>();
+ Set<String> zoneSet = new LinkedHashSet<>();
+ Set<String> noncanonical = new LinkedHashSet<>();
for (String zone : zones) {
String countryCode = TimeZone.getRegion(zone);
String englishTerritory = ULocale.getDisplayCountry("und-" + countryCode, ULocale.ENGLISH);
@@ -113,7 +113,7 @@
showVennSets(metazones, metazoneToRegionToZone.keySet());
}
- Set<String> zonesInMetazones = new LinkedHashSet<String>();
+ Set<String> zonesInMetazones = new LinkedHashSet<>();
for (String metazone : metazones) {
//String container = PathHeader.getMetazonePageTerritory(metazone);
Map<String, String> regionToZone = metazoneToRegionToZone.get(metazone);
@@ -130,7 +130,7 @@
//System.out.println("Zones. A = canonical zones, B = zones in metazonesToRegionToZone");
//showVennSets(zoneSet, zonesInMetazones);
vennSets(zoneSet, zonesInMetazones);
- Set<String> found = new LinkedHashSet<String>();
+ Set<String> found = new LinkedHashSet<>();
for (String zone : zoneSet) {
Set<MetaZoneRange> metaZoneRanges = sdi.getMetaZoneRanges(zone);
if (metaZoneRanges == null) {
@@ -181,9 +181,9 @@
}
private static void showVennSets(Set<String> zoneSet, Set<String> zonesInMetazones) {
- Set<String> common = new LinkedHashSet<String>();
- Set<String> firstMinusSecond = new LinkedHashSet<String>();
- Set<String> secondMinusFirst = new LinkedHashSet<String>();
+ Set<String> common = new LinkedHashSet<>();
+ Set<String> firstMinusSecond = new LinkedHashSet<>();
+ Set<String> secondMinusFirst = new LinkedHashSet<>();
vennSets(zoneSet, zonesInMetazones, common, firstMinusSecond, secondMinusFirst);
if (!common.isEmpty()) System.out.println("A & B:\t" + common.size() + "\t" + common);
if (!firstMinusSecond.isEmpty()) System.out.println("A - B:\t" + firstMinusSecond.size() + "\t" + firstMinusSecond);
@@ -234,7 +234,7 @@
Factory factory2 = Factory.make(CLDRPaths.MAIN_DIRECTORY, filter);
CLDRFile englishCldrFile = factory2.make("en", true);
-
+
new File(DIR).mkdirs();
FileCopier.copy(ShowData.class, "verify-index.html", CLDRPaths.VERIFY_DIR, "index.html");
FileCopier.copy(ChartDelta.class, "index.css", CLDRPaths.VERIFY_DIR, "index.css");
diff --git a/tools/java/org/unicode/cldr/util/VettingViewer.java b/tools/java/org/unicode/cldr/util/VettingViewer.java
index 48f316f..7995b0c 100644
--- a/tools/java/org/unicode/cldr/util/VettingViewer.java
+++ b/tools/java/org/unicode/cldr/util/VettingViewer.java
@@ -69,7 +69,6 @@
private static final String TEST_PATH = "//ldml/localeDisplayNames/territories/territory[@type=\"SX\"]";
private static final double NANOSECS = 1000000000.0;
private static final boolean TESTING = CldrUtility.getProperty("TEST", false);
- private static final boolean SHOW_ALL = CldrUtility.getProperty("SHOW", true);
public static final Pattern ALT_PROPOSED = PatternCache.get("\\[@alt=\"[^\"]*proposed");
@@ -332,8 +331,8 @@
public static class DefaultErrorStatus implements ErrorChecker {
private CheckCLDR checkCldr;
- private HashMap<String, String> options = new HashMap<String, String>();
- private ArrayList<CheckStatus> result = new ArrayList<CheckStatus>();
+ private HashMap<String, String> options = new HashMap<>();
+ private ArrayList<CheckStatus> result = new ArrayList<>();
private CLDRFile cldrFile;
private Factory factory;
@@ -344,8 +343,8 @@
@Override
public Status initErrorStatus(CLDRFile cldrFile) {
this.cldrFile = cldrFile;
- options = new HashMap<String, String>();
- result = new ArrayList<CheckStatus>();
+ options = new HashMap<>();
+ result = new ArrayList<>();
checkCldr = CheckCLDR.getCheckAll(factory, ".*");
checkCldr.setCldrFileToCheck(cldrFile, options, result);
return Status.ok;
@@ -354,8 +353,8 @@
@Override
public List<CheckStatus> getErrorCheckStatus(String path, String value) {
String fullPath = cldrFile.getFullXPath(path);
- ArrayList<CheckStatus> result2 = new ArrayList<CheckStatus>();
- checkCldr.check(path, fullPath, value, options, result2);
+ ArrayList<CheckStatus> result2 = new ArrayList<>();
+ checkCldr.check(path, fullPath, value, new CheckCLDR.Options(options), result2);
return result2;
}
@@ -370,7 +369,7 @@
Status result0 = Status.ok;
StringBuilder errorMessage = new StringBuilder();
String fullPath = cldrFile.getFullXPath(path);
- checkCldr.check(path, fullPath, value, options, result);
+ checkCldr.check(path, fullPath, value, new CheckCLDR.Options(options), result);
for (CheckStatus checkStatus : result) {
final CheckCLDR cause = checkStatus.getCause();
/*
@@ -519,7 +518,7 @@
*
* Called only by writeVettingViewerOutput
*/
- public Relation<R2<SectionId, PageId>, WritingInfo> generateFileInfoReview(Appendable output, EnumSet<Choice> choices, String localeID, T user,
+ public Relation<R2<SectionId, PageId>, WritingInfo> generateFileInfoReview(EnumSet<Choice> choices, String localeID, T user,
Level usersLevel, boolean quick, CLDRFile sourceFile, CLDRFile baselineFile) {
// Gather the relevant paths
@@ -536,9 +535,9 @@
}
class FileInfo {
- Counter<Choice> problemCounter = new Counter<Choice>();
- Counter<Subtype> errorSubtypeCounter = new Counter<Subtype>();
- Counter<Subtype> warningSubtypeCounter = new Counter<Subtype>();
+ Counter<Choice> problemCounter = new Counter<>();
+ Counter<Subtype> errorSubtypeCounter = new Counter<>();
+ Counter<Subtype> warningSubtypeCounter = new Counter<>();
EnumSet<Choice> problems = EnumSet.noneOf(Choice.class);
public void addAll(FileInfo other) {
@@ -557,7 +556,7 @@
}
/**
- * Loop through paths for the Dashboard
+ * Loop through paths for the Dashboard or the Priority Items Summary
*
* @param sourceFile
* @param baselineFile
@@ -584,7 +583,7 @@
StringBuilder htmlMessage = new StringBuilder();
StringBuilder statusMessage = new StringBuilder();
EnumSet<Subtype> subtypes = EnumSet.noneOf(Subtype.class);
- Set<String> seenSoFar = new HashSet<String>();
+ Set<String> seenSoFar = new HashSet<>();
boolean latin = VettingViewer.isLatinScriptLocale(sourceFile);
CLDRFile baselineFileUnresolved = (baselineFile == null) ? null : baselineFile.getUnresolved();
for (String path : sourceFile.fullIterable()) {
@@ -639,7 +638,7 @@
boolean isMissing = (oldValue == null);
if (!SubmissionLocales.allowEvenIfLimited(localeID, path, isError, isMissing)) {
continue;
- };
+ }
}
if (!onlyRecordErrors && choices.contains(Choice.changedOldValue)) {
@@ -750,7 +749,7 @@
@Override
public boolean is(String localeId) {
- Output<LocaleCoverageType> output = new Output<LocaleCoverageType>();
+ Output<LocaleCoverageType> output = new Output<>();
// For admin - return true if SOME organization has explicit coverage for the locale
// TODO: Make admin pick up any locale that has a vote
if (org.equals(Organization.surveytool)) {
@@ -766,17 +765,16 @@
return desiredLevel == level && output.value == StandardCodes.LocaleCoverageType.explicit;
}
}
- };
+ }
- public void generateSummaryHtmlErrorTables(Appendable output, EnumSet<Choice> choices,
- Predicate<String> includeLocale, T organization) {
+ public void generateSummaryHtmlErrorTables(Appendable output, EnumSet<Choice> choices, T organization) {
+ String helpUrl = "http://cldr.unicode.org/translation/getting-started/vetting-view#TOC-Priority-Items";
try {
-
output
.append("<p>The following summarizes the Priority Items across locales, " +
"using the default coverage levels for your organization for each locale. " +
"Before using, please read the instructions at " +
- "<a target='CLDR_ST_DOCS' href='http://cldr.unicode.org/translation/vetting-summary'>Priority " +
+ "<a target='CLDR_ST_DOCS' href='" + helpUrl + "'>Priority " +
"Items Summary</a>.</p>\n");
StringBuilder headerRow = new StringBuilder();
@@ -821,7 +819,7 @@
private void writeSummaryTable(Appendable output, String header, Level desiredLevel,
EnumSet<Choice> choices, T organization) throws IOException {
- Map<String, String> sortedNames = new TreeMap<String, String>(Collator.getInstance());
+ Map<String, String> sortedNames = new TreeMap<>(Collator.getInstance());
// Gather the relevant paths
// Each one will be marked with the choice that it triggered.
@@ -850,7 +848,7 @@
output.append("<h2>Level: ").append(desiredLevel.toString()).append("</h2>");
output.append("<table class='tvs-table'>\n");
char lastChar = ' ';
- Map<String, FileInfo> localeNameToFileInfo = new TreeMap();
+ Map<String, FileInfo> localeNameToFileInfo = new TreeMap<>();
FileInfo totals = new FileInfo();
for (Entry<String, String> entry : sortedNames.entrySet()) {
@@ -907,7 +905,7 @@
Set<Subtype> sortedBySize = subtypeCounterTotals.getKeysetSortedByCount(false);
// header
- writeDetailHeader(subtypeCounterTotals, sortedBySize, output);
+ writeDetailHeader(sortedBySize, output);
// items
for (Entry<String, FileInfo> entry : localeNameToFileInfo.entrySet()) {
@@ -931,7 +929,7 @@
}
// subtotals
- writeDetailHeader(subtypeCounterTotals, sortedBySize, output);
+ writeDetailHeader(sortedBySize, output);
output.append("<tr>").append(TH_AND_STYLES).append("<i>Total</i>").append("</th>").append(TH_AND_STYLES).append("</th>");
for (Subtype subtype : sortedBySize) {
long count = subtypeCounterTotals.get(subtype);
@@ -944,7 +942,7 @@
output.append("</table>");
}
- private void writeDetailHeader(Counter<Subtype> subtypeCounterTotals, Set<Subtype> sortedBySize, Appendable output) throws IOException {
+ private void writeDetailHeader(Set<Subtype> sortedBySize, Appendable output) throws IOException {
output.append("<tr>")
.append(TH_AND_STYLES).append("Name").append("</th>")
.append(TH_AND_STYLES).append("ID").append("</th>");
@@ -1015,11 +1013,11 @@
{az_IR, az_Arab, az_Arab_IR} => az_IR, az_Arab(_IR)
*/
public static String gatherCodes(Set<String> contents) {
- Set<Set<String>> source = new LinkedHashSet<Set<String>>();
+ Set<Set<String>> source = new LinkedHashSet<>();
for (String s : contents) {
- source.add(new LinkedHashSet<String>(Arrays.asList(s.split("_"))));
+ source.add(new LinkedHashSet<>(Arrays.asList(s.split("_"))));
}
- Set<Set<String>> oldSource = new LinkedHashSet<Set<String>>();
+ Set<Set<String>> oldSource = new LinkedHashSet<>();
do {
// exchange source/target
@@ -1061,7 +1059,7 @@
}
private static Set<String> combine(Set<String> last, Set<String> ss) {
- LinkedHashSet<String> result = new LinkedHashSet<String>();
+ LinkedHashSet<String> result = new LinkedHashSet<>();
for (String s : ss) {
if (last.contains(s)) {
result.add(s);
@@ -1099,7 +1097,7 @@
String value = sourceFile.getStringValue(path);
Status status = new Status();
sourceFile.getSourceLocaleID(path, status);
- boolean isAliased = path.equals(status.pathWhereFound);
+ boolean isAliased = !path.equals(status.pathWhereFound); // this was path.equals, which would be incorrect!
if (value == null) {
result = ValuePathStatus.isMissingOk(sourceFile, path, latin, isAliased) ? MissingStatus.MISSING_OK : MissingStatus.ABSENT;
@@ -1116,8 +1114,8 @@
*/
if (localeFound.equals("root") || localeFound.equals(XMLSource.CODE_FALLBACK_ID)) {
result = ValuePathStatus.isMissingOk(sourceFile, path, latin, isAliased)
- || sourceFile.getLocaleID().equals("en")
- ? MissingStatus.ROOT_OK
+ || sourceFile.getLocaleID().equals("en")
+ ? MissingStatus.ROOT_OK
: MissingStatus.ABSENT;
} else if (isAliased) {
result = MissingStatus.ALIASED;
@@ -1418,10 +1416,9 @@
* @param localeId
* @param user
* @param usersLevel
- * @param nonVettingPhase
*/
public ArrayList<String> getErrorOnPath(EnumSet<Choice> choices, String localeID, T user,
- Level usersLevel, boolean nonVettingPhase, String path) {
+ Level usersLevel, String path) {
// Gather the relevant paths
// each one will be marked with the choice that it triggered.
@@ -1441,7 +1438,7 @@
EnumSet<Choice> errors = new FileInfo().getFileInfo(sourceFile, baselineFile, sorted, choices, localeID, user, usersLevel,
false, path).problems;
- ArrayList<String> out = new ArrayList<String>();
+ ArrayList<String> out = new ArrayList<>();
for (Object error : errors.toArray()) {
out.add(((Choice) error).buttonLabel);
}
@@ -1528,7 +1525,7 @@
missingCounter.clear();
boolean latin = VettingViewer.isLatinScriptLocale(file);
- CoverageLevel2 coverageLevel2 = CoverageLevel2.getInstance(file.getLocaleID());
+ CoverageLevel2 coverageLevel2 = CoverageLevel2.getInstance(SupplementalDataInfo.getInstance(), file.getLocaleID());
for (String path : allPaths) {
@@ -1581,11 +1578,11 @@
enum MyOptions {
repeat(null, null, "Repeat indefinitely"),
- filter(".*", ".*", "Filter files"),
- locale(".*", "af", "Single locale for testing"),
+ filter(".*", ".*", "Filter files"),
+ locale(".*", "af", "Single locale for testing"),
source(".*", CLDRPaths.MAIN_DIRECTORY + "," + CLDRPaths.ANNOTATIONS_DIRECTORY, // CldrUtility.TMP2_DIRECTORY + "/vxml/common/main"
- "if summary, creates filtered version (eg -d main): does a find in the name, which is of the form dir/file"),
- verbose(null, null, "verbose debugging messages"),
+ "if summary, creates filtered version (eg -d main): does a find in the name, which is of the form dir/file"),
+ verbose(null, null, "verbose debugging messages"),
output(".*", CLDRPaths.GEN_DIRECTORY + "vetting/", "filter the raw files (non-summary, mostly for debugging)"),;
// boilerplate
final Option option;
@@ -1609,8 +1606,6 @@
for (String s : DIRECTORIES) {
fileDirectories[i++] = new File(s);
}
- final String lastMain = CLDRPaths.LAST_RELEASE_DIRECTORY;
- //final String lastMain = CLDRPaths.ARCHIVE_DIRECTORY + "/common/main";
do {
Timer timer = new Timer();
@@ -1626,6 +1621,8 @@
UsersChoice<Organization> usersChoice = new UsersChoice<Organization>() {
// Fake values for now
+ @Override
+ @SuppressWarnings("unused")
public String getWinningValueForUsersOrganization(CLDRFile cldrFile, String path, Organization user) {
if (path.contains("USD")) {
return "&dummy ‘losing’ value";
@@ -1634,6 +1631,7 @@
}
// Fake values for now
+ @Override
public VoteStatus getStatusForUsersOrganization(CLDRFile cldrFile, String path, Organization user) {
String usersValue = getWinningValueForUsersOrganization(cldrFile, path, user);
String winningValue = cldrFile.getWinningValue(path);
@@ -1656,7 +1654,7 @@
// The Options should come from a GUI; from each you can get a long
// description and a button label.
// Assuming user can be identified by an int
- VettingViewer<Organization> tableView = new VettingViewer<Organization>(supplementalDataInfo, cldrFactory,
+ VettingViewer<Organization> tableView = new VettingViewer<>(supplementalDataInfo, cldrFactory,
usersChoice, "Winning Proposed");
// here are per-view parameters
@@ -1685,11 +1683,10 @@
} while (repeat);
}
- public enum CodeChoice {
+ private enum CodeChoice {
/** For the normal (locale) view of data **/
newCode,
- // /** @deprecated **/
- // oldCode,
+
/** For a summary view of data **/
summary
}
@@ -1752,12 +1749,9 @@
case newCode:
tableView.generateHtmlErrorTables(out, choiceSet, localeStringID, organization, usersLevel, false);
break;
- // case oldCode:
- // tableView.generateHtmlErrorTablesOld(out, choiceSet, localeStringID, userNumericID, usersLevel, SHOW_ALL);
- // break;
case summary:
//System.out.println(tableView.getName("zh_Hant_HK"));
- tableView.generateSummaryHtmlErrorTables(out, choiceSet, null, organization);
+ tableView.generateSummaryHtmlErrorTables(out, choiceSet, organization);
break;
}
out.println("</body>\n</html>\n");
diff --git a/tools/java/org/unicode/cldr/util/VoteResolver.java b/tools/java/org/unicode/cldr/util/VoteResolver.java
index 1ced88b..b3d7a42 100644
--- a/tools/java/org/unicode/cldr/util/VoteResolver.java
+++ b/tools/java/org/unicode/cldr/util/VoteResolver.java
@@ -26,7 +26,6 @@
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
-import com.ibm.icu.impl.Relation;
import com.ibm.icu.text.Collator;
import com.ibm.icu.util.ULocale;
@@ -69,10 +68,11 @@
public class VoteResolver<T> {
private static final boolean DEBUG = false;
- /*
+ /**
* A placeholder for winningValue when it would otherwise be null.
+ * It must match NO_WINNING_VALUE in the client JavaScript code.
*/
- private static String ERROR_NO_WINNING_VALUE = "error-no-winning-value";
+ private static String NO_WINNING_VALUE = "no-winning-value";
/**
* The status levels according to the committee, in ascending order
@@ -81,12 +81,12 @@
* A checkmark means it’s approved and is slated to be used. A cross means it’s a missing value.
* Green/orange check: The item has enough votes to be used in CLDR.
* Red/orange/black X: The item does not have enough votes to be used in CLDR, by most implementations (or is completely missing).
- * Reference: http://cldr.unicode.org/index/survey-tool/guide
- *
+ * Reference: http://cldr.unicode.org/translation/getting-started/guide
+ *
* New January, 2019: When the item is inherited, i.e., winningValue is INHERITANCE_MARKER (↑↑↑),
* then orange/red X are replaced by orange/red up-arrow. That change is made only on the client.
* Reference: https://unicode.org/cldr/trac/ticket/11103
- *
+ *
* Status.approved: approved.png = green check
* Status.contributed: contributed.png = orange check
* Status.provisional: provisional.png = orange X (or inherited_provisional.png orange up-arrow if inherited)
@@ -255,7 +255,7 @@
admin.voteCountMenu = ImmutableSet.of(vetter.votes, admin.votes); /* Not LOCKING_VOTES; see canVoteWithCount */
tc.voteCountMenu = ImmutableSet.of(vetter.votes, tc.votes, PERMANENT_VOTES);
}
- };
+ }
/**
* Internal class for voter information. It is public for testing only
@@ -264,7 +264,7 @@
private Organization organization;
private Level level;
private String name;
- private Set<String> locales = new TreeSet<String>();
+ private Set<String> locales = new TreeSet<>();
public VoterInfo(Organization organization, Level level, String name, Set<String> locales) {
this.setOrganization(organization);
@@ -282,6 +282,7 @@
public VoterInfo() {
}
+ @Override
public String toString() {
return "{" + getName() + ", " + getLevel() + ", " + getOrganization() + "}";
}
@@ -359,13 +360,14 @@
/**
* Add, but only to bring up to the maximum value.
*/
+ @Override
public MaxCounter<T> add(T obj, long countValue, long time) {
long value = getCount(obj);
if ((value <= countValue)) {
super.add(obj, countValue - value, time); // only add the difference!
}
return this;
- };
+ }
}
/**
@@ -373,10 +375,10 @@
*/
private static class OrganizationToValueAndVote<T> {
private final Map<Organization, MaxCounter<T>> orgToVotes = new EnumMap<>(Organization.class);
- private final Counter<T> totalVotes = new Counter<T>();
+ private final Counter<T> totalVotes = new Counter<>();
private final Map<Organization, Integer> orgToMax = new EnumMap<>(Organization.class);
- private final Counter<T> totals = new Counter<T>(true);
- private Map<String, Long> nameTime = new LinkedHashMap<String, Long>();
+ private final Counter<T> totals = new Counter<>(true);
+ private Map<String, Long> nameTime = new LinkedHashMap<>();
// map an organization to what it voted for.
private final Map<Organization, T> orgToAdd = new EnumMap<>(Organization.class);
private T baileyValue;
@@ -427,7 +429,7 @@
* @param value
* @param voter
* @param withVotes optionally, vote at a non-typical voting level. May not exceed voter's maximum allowed level. null = use default level.
- * @param date
+ * @param date
*/
public void add(T value, int voter, Integer withVotes, Date date) {
final VoterInfo info = getVoterToInfo().get(voter);
@@ -447,7 +449,7 @@
* @param value
* @param info
* @param votes
- * @param date
+ * @param date
* @see #add(Object, int, Integer)
*/
private void addInternal(T value, final VoterInfo info, final int votes, Date time) {
@@ -485,8 +487,8 @@
* Return the overall vote for each organization. It is the max for each value.
* When the organization is conflicted (the top two values have the same vote), the organization is also added
* to disputed.
- *
- * @param conflictedOrganizations if not null, to be filled in with the set of conflicted organizations.
+ *
+ * @param conflictedOrganizations if not null, to be filled in with the set of conflicted organizations.
*/
public Counter<T> getTotals(EnumSet<Organization> conflictedOrganizations) {
if (conflictedOrganizations != null) {
@@ -522,6 +524,10 @@
}
}
// This is deprecated, but preserve it until the method is removed.
+ /*
+ * TODO: explain the above comment, and follow through. What is deprecated (orgToAdd, or getOrgVote)?
+ * Preserve until which method is removed (getOrgVote)?
+ */
orgToAdd.put(org, value);
// We add the max vote for each of the organizations choices
@@ -576,8 +582,6 @@
public int getOrgCount(T winningValue) {
int orgCount = 0;
for (Map.Entry<Organization, MaxCounter<T>> entry : orgToVotes.entrySet()) {
-// for (Organization org : orgToVotes.keySet()) {
-// Counter<T> counter = orgToVotes.get(org);
Counter<T> counter = entry.getValue();
long count = counter.getCount(winningValue);
if (count > 0) {
@@ -590,30 +594,29 @@
public int getBestPossibleVote() {
int total = 0;
for (Map.Entry<Organization, Integer> entry : orgToMax.entrySet()) {
- // for (Organization org : orgToMax.keySet()) {
-// total += orgToMax.get(org);
total += entry.getValue();
}
return total;
}
+ @Override
public String toString() {
String orgToVotesString = "";
for (Entry<Organization, MaxCounter<T>> entry : orgToVotes.entrySet()) {
-// for (Organization org : orgToVotes.keySet()) {
-// Counter<T> counter = orgToVotes.get(org);
Counter<T> counter = entry.getValue();
if (counter.size() != 0) {
if (orgToVotesString.length() != 0) {
orgToVotesString += ", ";
}
Organization org = entry.getKey();
- orgToVotesString += org + "=" + counter;
+ orgToVotesString += org.toString() + "=" + counter.toString();
}
}
EnumSet<Organization> conflicted = EnumSet.noneOf(Organization.class);
- return "{orgToVotes: " + orgToVotesString + ", totals: " + getTotals(conflicted) + ", conflicted: "
- + conflicted + "}";
+ return "{orgToVotes: " + orgToVotesString
+ + ", totals: " + getTotals(conflicted)
+ + ", conflicted: " + conflicted.toString()
+ + "}";
}
/**
@@ -623,6 +626,7 @@
* @return
* @deprecated
*/
+ @Deprecated
public T getOrgVote(Organization org) {
return orgToAdd.get(org);
}
@@ -632,14 +636,11 @@
}
public Map<T, Long> getOrgToVotes(Organization org) {
- Map<T, Long> result = new LinkedHashMap<T, Long>();
+ Map<T, Long> result = new LinkedHashMap<>();
MaxCounter<T> counter = orgToVotes.get(org);
for (T item : counter) {
result.put(item, counter.getCount(item));
}
- // Skip the System.out.println here normally, it clutters the logs.
- // See https://unicode.org/cldr/trac/ticket/10295
- // System.out.println("getOrgToVotes : " + org.displayName + " : " + result.toString());
return result;
}
}
@@ -658,13 +659,13 @@
private T winningValue;
private T oValue; // optimal value; winning if better approval status than old
private T nValue; // next to optimal value
- private List<T> valuesWithSameVotes = new ArrayList<T>();
+ private List<T> valuesWithSameVotes = new ArrayList<>();
private Counter<T> totals = null;
private Status winningStatus;
private EnumSet<Organization> conflictedOrganizations = EnumSet
.noneOf(Organization.class);
- private OrganizationToValueAndVote<T> organizationToValueAndVote = new OrganizationToValueAndVote<T>();
+ private OrganizationToValueAndVote<T> organizationToValueAndVote = new OrganizationToValueAndVote<>();
private T trunkValue;
private Status trunkStatus;
@@ -685,6 +686,7 @@
private final Comparator<T> ucaCollator = new Comparator<T>() {
Collator col = Collator.getInstance(ULocale.ENGLISH);
+ @Override
public int compare(T o1, T o2) {
return col.compare(String.valueOf(o1), String.valueOf(o2));
}
@@ -701,7 +703,7 @@
*
* @param trunkValue the trunk value
* @param trunkStatus the trunk status
- *
+ *
* TODO: consider renaming: setTrunk to setBaseline; getTrunkValue to getBaselineValue; getTrunkStatus to getBaselineStatus
*/
public void setTrunk(T trunkValue, Status trunkStatus) {
@@ -798,7 +800,9 @@
* @param value
* @param voter
* @param withVotes override to lower the user's voting permission. May be null for default.
- * @param date
+ * @param date
+ *
+ * Called by getResolverInternal
*/
public void add(T value, int voter, Integer withVotes, Date date) {
if (resolved) {
@@ -817,7 +821,8 @@
* @param value
* @param voter
* @param withVotes override to lower the user's voting permission. May be null for default.
-
+ *
+ * Called only for TestUtilities, not used in Survey Tool.
*/
public void add(T value, int voter, Integer withVotes) {
if (resolved) {
@@ -829,13 +834,18 @@
}
/**
+ * Used only in add(value, voter) for making a pseudo-Date
+ */
+ private int maxcounter = 100;
+
+ /**
* Call once for each voter for a value. If there are no voters for an item, then call add(value);
*
* @param value
* @param voter
+ *
+ * Called by ConsoleCheckCLDR and TestUtilities; not used in SurveyTool.
*/
- int maxcounter = 100;
-
public void add(T value, int voter) {
Date date = new Date(++maxcounter);
add(value, voter, null, date);
@@ -846,6 +856,8 @@
*
* @param value
* @param voter
+ *
+ * Called by getResolverInternal for the baseline (trunk) value; also called for ConsoleCheckCLDR.
*/
public void add(T value) {
if (resolved) {
@@ -854,7 +866,7 @@
values.add(value);
}
- private Set<T> values = new TreeSet<T>(ucaCollator);
+ private Set<T> values = new TreeSet<>(ucaCollator);
private final Comparator<T> votesThenUcaCollator = new Comparator<T>() {
Collator col = Collator.getInstance(ULocale.ENGLISH);
@@ -867,6 +879,7 @@
*
* Return negative to favor o1, positive to favor o2.
*/
+ @Override
public int compare(T o1, T o2) {
long v1 = organizationToValueAndVote.totalVotes.get(o1);
long v2 = organizationToValueAndVote.totalVotes.get(o2);
@@ -889,8 +902,8 @@
/**
* Resolve the votes. Resolution entails counting votes and setting
- * members for this VoteResolver, including winningStatus, winningValue,
- * and many others.
+ * members for this VoteResolver, including winningStatus, winningValue,
+ * and many others.
*/
private void resolveVotes() {
resolved = true;
@@ -902,10 +915,10 @@
if (DEBUG) {
System.out.println("sortedValues :" + sortedValues.toString());
}
-
+
/*
* If there are no (unconflicted) votes, return baseline (trunk) if not null,
- * else INHERITANCE_MARKER if baileySet, else ERROR_NO_WINNING_VALUE.
+ * else INHERITANCE_MARKER if baileySet, else NO_WINNING_VALUE.
* Avoid setting winningValue to null. VoteResolver should be fully in charge of vote resolution.
* Note: formerly if trunkValue was null here, winningValue was set to null, such
* as for http://localhost:8080/cldr-apps/v#/aa/Numbering_Systems/7b8ee7884f773afa
@@ -924,18 +937,20 @@
/*
* TODO: When can this still happen? See https://unicode.org/cldr/trac/ticket/11299 "Example C".
* Also http://localhost:8080/cldr-apps/v#/en_CA/Gregorian/
+ * -- also http://localhost:8080/cldr-apps/v#/aa/Languages_A_D/
+ * xpath //ldml/localeDisplayNames/languages/language[@type="zh_Hans"][@alt="long"]
* See also checkDataRowConsistency in DataSection.java.
*/
- winningValue = (T) ERROR_NO_WINNING_VALUE;
+ winningValue = (T) NO_WINNING_VALUE;
winningStatus = Status.missing;
}
- valuesWithSameVotes.add(winningValue); // may be null
+ valuesWithSameVotes.add(winningValue);
return;
}
if (values.size() == 0) {
throw new IllegalArgumentException("No values added to resolver");
}
-
+
/*
* Copy what is in the the totals field of this VoteResolver for all the
* values in sortedValues. This local variable voteCount may be used
@@ -963,7 +978,7 @@
* Perform the actual resolution.
*/
long weights[] = setBestNextAndSameVoteValues(sortedValues, voteCount);
-
+
oValue = winningValue;
winningStatus = computeStatus(weights[0], weights[1], trunkStatus);
@@ -988,7 +1003,7 @@
* @return the HashMap
*/
private HashMap<T, Long> makeVoteCountMap(Set<T> sortedValues) {
- HashMap<T, Long> map = new HashMap<T, Long>();
+ HashMap<T, Long> map = new HashMap<>();
for (T value : sortedValues) {
map.put(value, totals.getCount(value));
}
@@ -1011,7 +1026,7 @@
*
* @param sortedValues the set of sorted values, possibly to be modified
* @param voteCount the hash giving the vote count for each value, possibly to be modified
- *
+ *
* Reference: https://unicode.org/cldr/trac/ticket/11299
*/
private void combineInheritanceWithBaileyForVoting(Set<T> sortedValues, HashMap<T, Long> voteCount) {
@@ -1041,7 +1056,7 @@
/*
* Sort again, and omit skipValue
*/
- List<T> list = new ArrayList<T>(sortedValues);
+ List<T> list = new ArrayList<>(sortedValues);
Collator col = Collator.getInstance(ULocale.ENGLISH);
Collections.sort(list, (v1, v2) -> {
long c1 = (voteCount != null) ? voteCount.get(v1) : totals.getCount(v1);
@@ -1056,7 +1071,7 @@
if (!value.equals(skipValue)) {
sortedValues.add(value);
}
- }
+ }
}
/**
@@ -1075,7 +1090,7 @@
*
* @param sortedValues the set of sorted values
* @param voteCount the hash giving the vote count for each value in sortedValues
- *
+ *
* public for unit testing, see TestAnnotationVotes.java
*/
public void adjustAnnotationVoteCounts(Set<T> sortedValues, HashMap<T, Long> voteCount) {
@@ -1086,7 +1101,7 @@
HashMap<T, Long> compMap = makeAnnotationComponentMap(sortedValues, voteCount);
// Save a copy of the "raw" vote count before adjustment, since it's needed by promoteSuperiorAnnotationSuperset.
- HashMap<T, Long> rawVoteCount = new HashMap<T, Long>(voteCount);
+ HashMap<T, Long> rawVoteCount = new HashMap<>(voteCount);
// Calculate new counts for original values, based on components.
calculateNewCountsBasedOnAnnotationComponents(sortedValues, voteCount, compMap);
@@ -1100,14 +1115,14 @@
/**
* Make a hash that maps individual annotation components to cumulative vote counts.
- *
+ *
* For example, 3 votes for "a|b" and 2 votes for "a|c" makes 5 votes for "a", 3 for "b", and 2 for "c".
- *
+ *
* @param sortedValues the set of sorted values
* @param voteCount the hash giving the vote count for each value in sortedValues
*/
private HashMap<T, Long> makeAnnotationComponentMap(Set<T> sortedValues, HashMap<T, Long> voteCount) {
- HashMap<T, Long> compMap = new HashMap<T, Long>();
+ HashMap<T, Long> compMap = new HashMap<>();
for (T value : sortedValues) {
Long count = voteCount.get(value);
List<T> comps = splitAnnotationIntoComponentsList(value);
@@ -1127,11 +1142,11 @@
}
}
return compMap;
- }
+ }
/**
* Calculate new counts for original values, based on annotation components.
- *
+ *
* Find the total votes for each component (e.g., "b" in "b|c"). As the "modified"
* vote for the set, use the geometric mean of the components in the set.
*
@@ -1164,12 +1179,12 @@
/**
* Split an annotation into a list of components.
- *
+ *
* For example, split "happy | joyful" into ["happy", "joyful"].
- *
+ *
* @param value the value like "happy | joyful"
* @return the list like ["happy", "joyful"]
- *
+ *
* Called by makeAnnotationComponentMap and calculateNewCountsBasedOnAnnotationComponents.
* Short, but needs encapsulation, should be consistent with similar code in DisplayAndInputProcessor.java.
*/
@@ -1179,14 +1194,14 @@
/**
* Re-sort the set of values to match the adjusted vote counts based on annotation components.
- *
+ *
* Resolve ties using ULocale.ENGLISH collation for consistency with votesThenUcaCollator.
- *
+ *
* @param sortedValues the set of sorted values, maybe no longer sorted the way we want
* @param voteCount the hash giving the adjusted vote count for each value in sortedValues
*/
private void resortValuesBasedOnAdjustedVoteCounts(Set<T> sortedValues, HashMap<T, Long> voteCount) {
- List<T> list = new ArrayList<T>(sortedValues);
+ List<T> list = new ArrayList<>(sortedValues);
Collator col = Collator.getInstance(ULocale.ENGLISH);
Collections.sort(list, (v1, v2) -> {
long c1 = voteCount.get(v1), c2 = voteCount.get(v2);
@@ -1219,7 +1234,7 @@
* purpose of requiring at least one non-guest vote.
*
* If any other "superior" supersets exist, promote to second place the one with the next most raw votes.
- *
+ *
* Accomplish promotion by increasing vote counts in the voteCount hash.
*
* @param sortedValues the set of sorted values
@@ -1228,7 +1243,7 @@
* @param rawVoteCount the vote count for each value in sortedValues BEFORE calculateNewCountsBasedOnAnnotationComponents;
* rawVoteCount is not changed by this function
*
- * Reference: https://unicode.org/cldr/trac/ticket/10973
+ * Reference: https://unicode.org/cldr/trac/ticket/10973
*/
private void promoteSuperiorAnnotationSuperset(Set<T> sortedValues, HashMap<T, Long> voteCount, HashMap<T, Long> rawVoteCount) {
final long requiredGap = 2;
@@ -1240,14 +1255,14 @@
if (oldWinner == null) {
oldWinner = value;
oldWinnerRawCount = rawVoteCount.get(value);
- oldWinnerComps = new LinkedHashSet<T>(splitAnnotationIntoComponentsList(value));
+ oldWinnerComps = new LinkedHashSet<>(splitAnnotationIntoComponentsList(value));
} else {
- Set<T> comps = new LinkedHashSet<T>(splitAnnotationIntoComponentsList(value));
+ Set<T> comps = new LinkedHashSet<>(splitAnnotationIntoComponentsList(value));
if (comps.size() <= CheckWidths.MAX_COMPONENTS_PER_ANNOTATION &&
comps.containsAll(oldWinnerComps) &&
rawVoteCount.get(value) >= oldWinnerRawCount + requiredGap) {
if (superiorSupersets == null) {
- superiorSupersets = new LinkedHashSet<T>();
+ superiorSupersets = new LinkedHashSet<>();
}
superiorSupersets.add(value);
}
@@ -1275,7 +1290,7 @@
* Given a nonempty list of sorted values, and a hash with their vote counts, set these members
* of this VoteResolver:
* winningValue, nValue, valuesWithSameVotes (which is empty when this function is called).
- *
+ *
* @param sortedValues the set of sorted values
* @param voteCount the hash giving the vote count for each value
* @return an array of two longs, the weights for the best and next-best values.
@@ -1322,7 +1337,7 @@
/**
* Compute the status for the winning value.
- *
+ *
* @param weight1 the weight (vote count) for the best value
* @param weight2 the weight (vote count) for the next-best value
* @param oldStatus the old status (trunkStatus)
@@ -1407,6 +1422,7 @@
/**
* @deprecated
*/
+ @Deprecated
public T getNextToWinningValue() {
return getNValue();
}
@@ -1428,7 +1444,7 @@
if (!resolved) {
resolveVotes();
}
- return new ArrayList<T>(valuesWithSameVotes);
+ return new ArrayList<>(valuesWithSameVotes);
}
public EnumSet<Organization> getConflictedOrganizations() {
@@ -1456,9 +1472,16 @@
return organizationToValueAndVote.getNameTime();
}
+ /**
+ * Get a String representation of this VoteResolver.
+ * This is sent to the client as "voteResolver.raw" and is used only for debugging.
+ *
+ * Compare SurveyAjax.JSONWriter.wrap(VoteResolver<String>) which creates the data
+ * actually used by the client.
+ */
+ @Override
public String toString() {
return "{"
- + "test: {" + "randomTest }, "
+ "bailey: " + (organizationToValueAndVote.baileySet ? ("“" + organizationToValueAndVote.baileyValue + "” ") : "none ")
+ "trunk: {" + trunkValue + ", " + trunkStatus + "}, "
+ organizationToValueAndVote
@@ -1470,28 +1493,6 @@
+ "}";
}
- public static Map<String, Map<Organization, Relation<Level, Integer>>> getLocaleToVetters() {
- Map<String, Map<Organization, Relation<Level, Integer>>> result = new TreeMap<String, Map<Organization, Relation<Level, Integer>>>();
- for (int voter : getVoterToInfo().keySet()) {
- VoterInfo info = getVoterToInfo().get(voter);
- if (info.getLevel() == Level.locked) {
- continue;
- }
- for (String locale : info.getLocales()) {
- Map<Organization, Relation<Level, Integer>> orgToVoter = result.get(locale);
- if (orgToVoter == null) {
- result.put(locale, orgToVoter = new TreeMap<Organization, Relation<Level, Integer>>());
- }
- Relation<Level, Integer> rel = orgToVoter.get(info.getOrganization());
- if (rel == null) {
- orgToVoter.put(info.getOrganization(), rel = Relation.of(new TreeMap<Level, Set<Integer>>(), TreeSet.class));
- }
- rel.put(info.getLevel(), voter);
- }
- }
- return result;
- }
-
private static Map<Integer, VoterInfo> getVoterToInfo() {
synchronized (VoteResolver.class) {
return voterToInfo;
@@ -1537,7 +1538,7 @@
private static synchronized void computeMaxVotes() {
// compute the localeToOrganizationToMaxVote
- localeToOrganizationToMaxVote = new TreeMap<String, Map<Organization, Level>>();
+ localeToOrganizationToMaxVote = new TreeMap<>();
for (int voter : getVoterToInfo().keySet()) {
VoterInfo info = getVoterToInfo().get(voter);
if (info.getLevel() == Level.tc || info.getLevel() == Level.locked) {
@@ -1548,7 +1549,7 @@
Map<Organization, Level> organizationToMaxVote = localeToOrganizationToMaxVote.get(locale);
if (organizationToMaxVote == null) {
localeToOrganizationToMaxVote.put(locale,
- organizationToMaxVote = new TreeMap<Organization, Level>());
+ organizationToMaxVote = new TreeMap<>());
}
Level maxVote = organizationToMaxVote.get(info.getOrganization());
if (maxVote == null || info.getLevel().compareTo(maxVote) > 0) {
@@ -1594,13 +1595,14 @@
all, userId, mainType, n, levelType, localeType, localeId;
String get(Matcher matcher) {
return matcher.group(this.ordinal());
- };
+ }
}
private static final boolean DEBUG_HANDLER = false;
- Map<Integer, VoterInfo> testVoterToInfo = new TreeMap<Integer, VoterInfo>();
+ Map<Integer, VoterInfo> testVoterToInfo = new TreeMap<>();
Matcher matcher = userPathMatcher.matcher("");
+ @Override
public void handlePathValue(String path, String value) {
if (DEBUG_HANDLER)
System.out.println(path + "\t" + value);
@@ -1651,8 +1653,9 @@
static class XPathTableHandler extends XMLFileReader.SimpleHandler {
Matcher matcher = Pattern.compile("id=\"([0-9]+)\"").matcher("");
- Map<Integer, String> pathIdToPath = new HashMap<Integer, String>();
+ Map<Integer, String> pathIdToPath = new HashMap<>();
+ @Override
public void handlePathValue(String path, String value) {
// <xpathTable host="tintin.local" date="Tue Apr 29 14:34:32 PDT 2008" count="18266" >
// <xpath
@@ -1677,14 +1680,15 @@
public enum Type {
proposal, optimal
- };
+ }
public static class CandidateInfo {
public Status oldStatus;
public Type surveyType;
public Status surveyStatus;
- public Set<Integer> voters = new TreeSet<Integer>();
+ public Set<Integer> voters = new TreeSet<>();
+ @Override
public String toString() {
StringBuilder voterString = new StringBuilder("{");
for (int voter : voters) {
@@ -1721,8 +1725,9 @@
* A base path has a set of candidates. Each candidate has various items of information.
*/
static class VotesHandler extends XMLFileReader.SimpleHandler {
- Map<Integer, Map<Integer, CandidateInfo>> basepathToInfo = new TreeMap<Integer, Map<Integer, CandidateInfo>>();
+ Map<Integer, Map<Integer, CandidateInfo>> basepathToInfo = new TreeMap<>();
+ @Override
public void handlePathValue(String path, String value) {
try {
XPathParts parts = XPathParts.getFrozenInstance(path);
@@ -1733,7 +1738,7 @@
int baseId = Integer.parseInt(parts.getAttributeValue(1, "baseXpath"));
Map<Integer, CandidateInfo> info = basepathToInfo.get(baseId);
if (info == null) {
- basepathToInfo.put(baseId, info = new TreeMap<Integer, CandidateInfo>());
+ basepathToInfo.put(baseId, info = new TreeMap<>());
}
int itemId = Integer.parseInt(parts.getAttributeValue(2, "xpath"));
CandidateInfo candidateInfo = info.get(itemId);
@@ -1773,7 +1778,7 @@
}
public static Map<Organization, Level> getOrganizationToMaxVote(Set<Integer> voters) {
- Map<Organization, Level> orgToMaxVoteHere = new TreeMap<Organization, Level>();
+ Map<Organization, Level> orgToMaxVoteHere = new TreeMap<>();
for (int voter : voters) {
VoterInfo info = getInfoForVoter(voter);
if (info == null) {
@@ -1799,6 +1804,7 @@
this.voter = voter;
}
+ @Override
public String toString() {
return "Unknown voter: " + voter;
}
@@ -1831,7 +1837,7 @@
if (!resolved) {
resolveVotes();
}
- Map<T, Long> result = new LinkedHashMap<T, Long>();
+ Map<T, Long> result = new LinkedHashMap<>();
if (winningValue != null && !totals.containsKey(winningValue)) {
result.put(winningValue, 0L);
}
diff --git a/tools/java/org/unicode/cldr/util/WikiSubdivisionLanguages.java b/tools/java/org/unicode/cldr/util/WikiSubdivisionLanguages.java
index 32701c6..0a67ab4 100644
--- a/tools/java/org/unicode/cldr/util/WikiSubdivisionLanguages.java
+++ b/tools/java/org/unicode/cldr/util/WikiSubdivisionLanguages.java
@@ -343,7 +343,7 @@
R2<List<String>, String> replacement = SUBDIVISION_ALIASES.get(type);
if (replacement != null) {
String fullPath = oldFileSubdivisions.getFullXPath(path);
- XPathParts parts2 = XPathParts.getInstance(fullPath);
+ XPathParts parts2 = XPathParts.getFrozenInstance(fullPath).cloneAsThawed();
for (String replacementType : replacement.get0()) {
parts2.setAttribute(-1, "type", replacementType);
toRemove.add(path);
diff --git a/tools/java/org/unicode/cldr/util/WikipediaOfficialLanguages.java b/tools/java/org/unicode/cldr/util/WikipediaOfficialLanguages.java
index 1541107..866d711 100644
--- a/tools/java/org/unicode/cldr/util/WikipediaOfficialLanguages.java
+++ b/tools/java/org/unicode/cldr/util/WikipediaOfficialLanguages.java
@@ -69,9 +69,9 @@
//"British Antarctic Territory",
"British Indian Ocean Territory", "British Virgin Islands", "Cayman Islands", "Falkland Islands", "Gibraltar",
"Montserrat", "Pitcairn Islands", "Saint Helena", "Ascension Island", "Tristan da Cunha")) {
- String region = CountryCodeConverter.getCodeFromName(s);
+ String region = CountryCodeConverter.getCodeFromName(s, false);
if (region == null) {
- System.out.println("Couldn't parse region: <" + s + ">");
+ System.err.println("Couldn't parse region: <" + s + ">");
} else {
REPLACE_REGIONS.put("United Kingdom and overseas territories", region);
}
@@ -79,9 +79,9 @@
for (String s : Arrays.asList("French Guiana", "French Polynesia", "Guadeloupe", "Martinique",
"Mayotte", "New Caledonia", "Réunion", "Saint Barthélemy", "Saint Martin", "Saint Pierre and Miquelon",
"Wallis and Futuna")) {
- String region = CountryCodeConverter.getCodeFromName(s);
+ String region = CountryCodeConverter.getCodeFromName(s, false);
if (region == null) {
- System.out.println("Couldn't parse region: <" + s + ">");
+ System.err.println("Couldn't parse region: <" + s + ">");
} else {
REPLACE_REGIONS.put("France and overseas departments and territories", region);
}
@@ -111,12 +111,12 @@
continue;
}
- String region = CountryCodeConverter.getCodeFromName(items[0]);
+ String region = CountryCodeConverter.getCodeFromName(items[0], false);
if (region == null) {
- System.out.println(++count + " Couldn't parse region: <" + items[0] + "> in line: " + line);
+ System.err.println(++count + " Couldn't parse region: <" + items[0] + "> in line: " + line);
regionSet = Collections.emptySet();
} else {
- regionSet = new HashSet<String>();
+ regionSet = new HashSet<>();
regionSet.add(region);
}
} else if (line.contains("[edit]") || line.trim().isEmpty()) {
@@ -188,13 +188,13 @@
}
comments = comments.substring(inLen);
- Set<String> result = new HashSet<String>();
+ Set<String> result = new HashSet<>();
String[] parts = comments.split("(,?\\s+and|,|;)\\s+");
for (String part : parts) {
if (part.isEmpty() || part.equals("de facto")) {
continue;
}
- String region = CountryCodeConverter.getCodeFromName(part);
+ String region = CountryCodeConverter.getCodeFromName(part, false);
if (region == null) {
System.err.println("* Can't convert " + region + " in " + part);
} else {
@@ -227,11 +227,11 @@
Set<String> locales = sc.getLocaleCoverageLocales("google"); // for now, restrict this
System.out.println("Cc\tCountry\tLc\tLanguage Name\tWiki status (heuristic)\tCLDR status\t\tWiki notes");
- Set<String> seen = new HashSet<String>();
+ Set<String> seen = new HashSet<>();
for (String region : getRegions()) {
//boolean regionShown = false;
Set<String> cldrLanguagesRaw = supplementalDataInfo.getLanguagesForTerritoryWithPopulationData(region);
- Map<String, PopulationData> cldrLanguageInfo = new HashMap<String, PopulationData>();
+ Map<String, PopulationData> cldrLanguageInfo = new HashMap<>();
for (String s : cldrLanguagesRaw) {
if (s.contains("_")) {
PopulationData sInfo = supplementalDataInfo.getLanguageAndTerritoryPopulationData(s, region);
@@ -250,7 +250,7 @@
OfficialStatus cldrStatus = sInfo == null ? OfficialStatus.unknown : sInfo.getOfficialStatus();
if (!areCompatible(info.status, cldrStatus)) {
System.out.print(region + "\t" + english.getName(CLDRFile.TERRITORY_NAME, region));
- ;
+
System.out.println("\t" + info.language
+ "\t" + english.getName(info.language)
+ "\t" + info.status
@@ -265,7 +265,7 @@
OfficialStatus officialStatus = sInfo.getOfficialStatus();
if (OfficialStatus.unknown != officialStatus) {
System.out.print(region + "\t" + english.getName(CLDRFile.TERRITORY_NAME, region));
- ;
+
System.out.println("\t" + r2
+ "\t" + english.getName(r2)
+ "\t" + "CLDR-ONLY"
diff --git a/tools/java/org/unicode/cldr/util/With.java b/tools/java/org/unicode/cldr/util/With.java
index 1be610b..86f7b16 100644
--- a/tools/java/org/unicode/cldr/util/With.java
+++ b/tools/java/org/unicode/cldr/util/With.java
@@ -33,7 +33,7 @@
* @param <V>
*/
public final class With<V> implements Iterable<V>, Iterator<V> {
- List<Iterator<V>> iterators = new ArrayList<Iterator<V>>();
+ List<Iterator<V>> iterators = new ArrayList<>();
int current;
/**
@@ -180,6 +180,27 @@
}
/**
+ * Create a string from a list of code points; the inverse of codePointArray.
+ * @param codePoints
+ * @return string
+ */
+ public static String fromCodePoint(int... codePoints) {
+ switch (codePoints.length) {
+ case 0: return "";
+ case 1: {
+ return String.valueOf(Character.toChars(codePoints[0]));
+ }
+ default: {
+ StringBuilder b = new StringBuilder();
+ for (int cp : codePoints) {
+ b.appendCodePoint(cp);
+ }
+ return b.toString();
+ }
+ }
+ }
+
+ /**
* An alterative to With.in(CharSequence) that is better when it is likely that only a portion of the text will be
* looked at,
* such as when an iterator over codepoints is aborted partway.
@@ -285,7 +306,7 @@
@SuppressWarnings("unchecked")
public With<V> and(SimpleIterator<V>... iterators) {
for (SimpleIterator<V> iterator : iterators) {
- this.iterators.add(new ToIterator<V>(iterator));
+ this.iterators.add(new ToIterator<>(iterator));
}
return this;
}
@@ -299,7 +320,7 @@
public With<V> andCodePoints(CharSequence... sources) {
for (CharSequence charSequence : sources) {
this.iterators
- .add((Iterator<V>) new ToIterator<CharSequence>(new CharSequenceSimpleIterator(charSequence)));
+ .add((Iterator<V>) new ToIterator<>(new CharSequenceSimpleIterator(charSequence)));
}
return this;
}
@@ -327,15 +348,15 @@
}
public static <T> Iterator<T> toIterator(SimpleIterator<T> simple) {
- return new ToIterator<T>(simple);
+ return new ToIterator<>(simple);
}
public static <T> Iterable<T> toIterable(SimpleIterator<T> simple) {
- return new ToIterator<T>(simple);
+ return new ToIterator<>(simple);
}
public static <T> ToSimpleIterator<T> toSimpleIterator(Iterator<T> iterator) {
- return new ToSimpleIterator<T>(iterator);
+ return new ToSimpleIterator<>(iterator);
}
private static class ToIterator<T> implements Iterator<T>, Iterable<T> {
diff --git a/tools/java/org/unicode/cldr/util/XChoiceFormat.java b/tools/java/org/unicode/cldr/util/XChoiceFormat.java
index 359114c..ea19090 100644
--- a/tools/java/org/unicode/cldr/util/XChoiceFormat.java
+++ b/tools/java/org/unicode/cldr/util/XChoiceFormat.java
@@ -66,7 +66,7 @@
return true; // CN
}
}
- };
+ }
private Condition[] conditions;
diff --git a/tools/java/org/unicode/cldr/util/XEquivalenceClass.java b/tools/java/org/unicode/cldr/util/XEquivalenceClass.java
index fbad432..2ad6316 100644
--- a/tools/java/org/unicode/cldr/util/XEquivalenceClass.java
+++ b/tools/java/org/unicode/cldr/util/XEquivalenceClass.java
@@ -26,7 +26,7 @@
// quick test
static public void main(String[] args) {
- XEquivalenceClass<String, Integer> foo1 = new XEquivalenceClass<String, Integer>(1);
+ XEquivalenceClass<String, Integer> foo1 = new XEquivalenceClass<>(1);
String[][] tests = { { "b", "a1" }, { "b", "c" }, { "a1", "c" }, { "d", "e" }, { "e", "f" }, { "c", "d" } };
for (int i = 0; i < tests.length; ++i) {
System.out.println("Adding: " + tests[i][0] + ", " + tests[i][1]);
@@ -149,7 +149,7 @@
}
/**
- *
+ *
*/
private void addReason(T a, T b, R reason) {
Map<T, Set<R>> obj_reasons = obj_obj_reasons.get(a);
@@ -175,7 +175,7 @@
public Set<T> getEquivalences(T a) {
Set<T> aPartitionSet = toPartitionSet.get(a);
if (aPartitionSet == null) { // manufacture an equivalence
- aPartitionSet = new HashSet<T>();
+ aPartitionSet = new HashSet<>();
aPartitionSet.add(a);
}
return Collections.unmodifiableSet(aPartitionSet);
@@ -186,7 +186,7 @@
}
public Set<Set<T>> getEquivalenceSets() {
- Set<Set<T>> result = new HashSet<Set<T>>();
+ Set<Set<T>> result = new HashSet<>();
for (T item : toPartitionSet.keySet()) {
Set<T> partition = toPartitionSet.get(item);
result.add(Collections.unmodifiableSet(partition));
@@ -206,7 +206,7 @@
}
/**
- * Gets a sample object in the equivalence set for a.
+ * Gets a sample object in the equivalence set for a.
*
*/
public T getSample(T a) {
@@ -229,7 +229,7 @@
}
/**
- * gets the set of all the samples, one from each equivalence class.
+ * gets the set of all the samples, one from each equivalence class.
*
*/
public Set<T> getSamples() {
@@ -244,6 +244,7 @@
return result;
}
+ @Override
public Iterator<T> iterator() {
return getSamples().iterator();
}
@@ -257,6 +258,7 @@
this.result = result;
}
+ @Override
public String toString() {
return reasons + (result == null ? "" : ARROW + result);
}
@@ -284,13 +286,13 @@
// see if they connect
if (aPartitionSet == null || bPartitionSet == null || aPartitionSet != bPartitionSet || a.equals(b)) return null;
- ArrayList<Linkage<T, R>> list = new ArrayList<Linkage<T, R>>();
+ ArrayList<Linkage<T, R>> list = new ArrayList<>();
list.add(new Linkage(null, a));
- ArrayList<ArrayList<Linkage<T, R>>> lists = new ArrayList<ArrayList<Linkage<T, R>>>();
+ ArrayList<ArrayList<Linkage<T, R>>> lists = new ArrayList<>();
lists.add(list);
// this will contain the results
- Set<T> sawLastTime = new HashSet<T>();
+ Set<T> sawLastTime = new HashSet<>();
sawLastTime.add(a);
// each time, we extend each lists by one (adding multiple other lists)
@@ -327,6 +329,7 @@
/**
* For debugging.
*/
+ @Override
public String toString() {
return getEquivalenceSets().toString();
}
diff --git a/tools/java/org/unicode/cldr/util/XEquivalenceMap.java b/tools/java/org/unicode/cldr/util/XEquivalenceMap.java
index ab32ba7..2cf861a 100644
--- a/tools/java/org/unicode/cldr/util/XEquivalenceMap.java
+++ b/tools/java/org/unicode/cldr/util/XEquivalenceMap.java
@@ -23,10 +23,10 @@
*/
public class XEquivalenceMap<K, V, R> implements Iterable<Set<K>> {
- Map<K, Row.R2<V, Set<R>>> source_target_reasons = new HashMap<K, Row.R2<V, Set<R>>>();
+ Map<K, Row.R2<V, Set<R>>> source_target_reasons = new HashMap<>();
Map<V, Set<K>> target_sourceSet;
- Map<K, Set<K>> source_Set = new HashMap<K, Set<K>>(); // not really needed: could go source-target-sourceset
+ Map<K, Set<K>> source_Set = new HashMap<>(); // not really needed: could go source-target-sourceset
public XEquivalenceMap() {
this(new HashMap<V, Set<K>>());
@@ -50,7 +50,7 @@
public XEquivalenceMap add(K source, V target, R reason) {
R2<V, Set<R>> target_reasons = source_target_reasons.get(source);
if (target_reasons == null) {
- Set<R> reasons = new HashSet<R>();
+ Set<R> reasons = new HashSet<>();
if (reason != null) {
reasons.add(reason);
}
@@ -70,7 +70,7 @@
}
Set<K> s = target_sourceSet.get(target);
- if (s == null) target_sourceSet.put(target, s = new HashSet<K>());
+ if (s == null) target_sourceSet.put(target, s = new HashSet<>());
s.add(source);
source_Set.put(source, s);
return this;
@@ -83,7 +83,7 @@
}
public boolean areEquivalent(K source1, K source2) {
- Set<K> s = (Set) source_Set.get(source1);
+ Set<K> s = source_Set.get(source1);
if (s == null) return false;
return s.contains(source2);
}
@@ -101,6 +101,7 @@
return Collections.unmodifiableSet(s);
}
+ @Override
public Iterator<Set<K>> iterator() {
return UnmodifiableIterator.from(target_sourceSet.values());
}
@@ -118,7 +119,7 @@
private Iterator<T> source;
public static <T> UnmodifiableIterator<T> from(Iterator<T> source) {
- UnmodifiableIterator<T> result = new UnmodifiableIterator<T>();
+ UnmodifiableIterator<T> result = new UnmodifiableIterator<>();
result.source = source;
return result;
}
@@ -127,14 +128,17 @@
return from(source.iterator());
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
+ @Override
public boolean hasNext() {
return source.hasNext();
}
+ @Override
public T next() {
return source.next();
}
diff --git a/tools/java/org/unicode/cldr/util/XListFormatter.java b/tools/java/org/unicode/cldr/util/XListFormatter.java
index a89308d..0da0719 100644
--- a/tools/java/org/unicode/cldr/util/XListFormatter.java
+++ b/tools/java/org/unicode/cldr/util/XListFormatter.java
@@ -13,21 +13,21 @@
import com.ibm.icu.text.UTF16;
public class XListFormatter {
-
+
public enum ListTypeLength {
- AND_WIDE(""),
- AND_SHORT("[@type=\"standard-short\"]"),
- AND_NARROW("[@type=\"standard-narrow\"]"),
- OR_WIDE("[@type=\"or\"]"),
- OR_SHORT("[@type=\"or-short\"]"),
- OR_NARROW("[@type=\"or-narrow\"]"),
- UNIT_WIDE("[@type=\"unit\"]"),
- UNIT_SHORT("[@type=\"unit-short\"]"),
+ AND_WIDE(""),
+ AND_SHORT("[@type=\"standard-short\"]"),
+ AND_NARROW("[@type=\"standard-narrow\"]"),
+ OR_WIDE("[@type=\"or\"]"),
+ OR_SHORT("[@type=\"or-short\"]"),
+ OR_NARROW("[@type=\"or-narrow\"]"),
+ UNIT_WIDE("[@type=\"unit\"]"),
+ UNIT_SHORT("[@type=\"unit-short\"]"),
UNIT_NARROW("[@type=\"unit-narrow\"]")
;
public static final ListTypeLength NORMAL = AND_WIDE;
-
+
final String typeString;
static final Map<String, ListTypeLength> stringToEnum;
@@ -55,9 +55,9 @@
+ "/listPatternPart[@type=\"{0}\"]";
}
}
-
+
private ListFormatter listFormatter;
-
+
public XListFormatter(CLDRFile cldrFile, ListTypeLength listTypeLength) {
SimpleFormatter listPathFormat = SimpleFormatter.compile(listTypeLength.getPath());
String doublePattern = cldrFile.getWinningValue(listPathFormat.format("2"));
@@ -66,7 +66,7 @@
String endPattern = cldrFile.getWinningValue(listPathFormat.format("end"));
listFormatter = new ListFormatter(doublePattern, startPattern, middlePattern, endPattern);
}
-
+
public String format(Object... items) {
return listFormatter.format(items);
}
@@ -74,7 +74,7 @@
public String format(Collection<?> items) {
return listFormatter.format(items);
}
-
+
public String formatCodePoints(String items) {
List<String> source = new ArrayList<>();
for (int sourceInt : CharSequences.codePoints(items)) { // TODO add utility in CharSequences
diff --git a/tools/java/org/unicode/cldr/util/XMLFileReader.java b/tools/java/org/unicode/cldr/util/XMLFileReader.java
index 0ba6688..43f3fea 100644
--- a/tools/java/org/unicode/cldr/util/XMLFileReader.java
+++ b/tools/java/org/unicode/cldr/util/XMLFileReader.java
@@ -56,22 +56,22 @@
public static class SimpleHandler {
public void handlePathValue(String path, String value) {
- };
+ }
public void handleComment(String path, String comment) {
- };
+ }
public void handleElementDecl(String name, String model) {
- };
+ }
public void handleAttributeDecl(String eName, String aName, String type, String mode, String value) {
- };
+ }
public void handleEndDtd() {
}
public void handleStartDtd(String name, String publicId, String systemId) {
- };
+ }
}
public XMLFileReader setHandler(SimpleHandler simpleHandler) {
@@ -92,7 +92,7 @@
*/
public XMLFileReader read(String fileName, int handlers, boolean validating) {
try (InputStream fis0 = new FileInputStream(fileName);
- InputStream fis = new FilterBomInputStream(fis0);
+ InputStream fis = new StripUTF8BOMInputStream(fis0);
) {
return read(fileName, fis, handlers, validating);
} catch (IOException e) {
@@ -200,52 +200,64 @@
if (SHOW_ALL) Log.logln("startDocument");
}
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (SHOW_ALL) Log.logln("characters");
}
+ @Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
throws SAXException {
if (SHOW_ALL) Log.logln("startElement");
}
+ @Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if (SHOW_ALL) Log.logln("endElement");
}
+ @Override
public void startDTD(String name, String publicId, String systemId) throws SAXException {
if (SHOW_ALL) Log.logln("startDTD");
}
+ @Override
public void endDTD() throws SAXException {
if (SHOW_ALL) Log.logln("endDTD");
}
+ @Override
public void comment(char[] ch, int start, int length) throws SAXException {
if (SHOW_ALL) Log.logln(" comment " + new String(ch, start, length));
}
+ @Override
public void elementDecl(String name, String model) throws SAXException {
if (SHOW_ALL) Log.logln("elementDecl");
}
+ @Override
public void attributeDecl(String eName, String aName, String type, String mode, String value)
throws SAXException {
if (SHOW_ALL) Log.logln("attributeDecl");
- }
+ }
+ @Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
if (SHOW_ALL) Log.logln("ignorableWhitespace length: " + length);
}
+ @Override
public void endDocument() throws SAXException {
if (SHOW_ALL) Log.logln("endDocument");
}
+ @Override
public void internalEntityDecl(String name, String value) throws SAXException {
if (SHOW_ALL) Log.logln("Internal Entity\t" + name + "\t" + value);
}
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
if (SHOW_ALL) Log.logln("Internal Entity\t" + name + "\t" + publicId + "\t" + systemId);
}
@@ -256,11 +268,13 @@
+ ", " + systemId);
}
+ @Override
public void processingInstruction(String target, String data)
throws SAXException {
if (SHOW_ALL) Log.logln("processingInstruction: " + target + ", " + data);
}
+ @Override
public void skippedEntity(String name)
throws SAXException {
if (SHOW_ALL) Log.logln("skippedEntity: " + name);
@@ -274,31 +288,38 @@
+ ", " + notationName);
}
+ @Override
public void setDocumentLocator(Locator locator) {
if (SHOW_ALL) Log.logln("setDocumentLocator Locator " + locator);
}
+ @Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
if (SHOW_ALL) Log.logln("startPrefixMapping prefix: " + prefix +
", uri: " + uri);
}
+ @Override
public void endPrefixMapping(String prefix) throws SAXException {
if (SHOW_ALL) Log.logln("endPrefixMapping prefix: " + prefix);
}
+ @Override
public void startEntity(String name) throws SAXException {
if (SHOW_ALL) Log.logln("startEntity name: " + name);
}
+ @Override
public void endEntity(String name) throws SAXException {
if (SHOW_ALL) Log.logln("endEntity name: " + name);
}
+ @Override
public void startCDATA() throws SAXException {
if (SHOW_ALL) Log.logln("startCDATA");
}
+ @Override
public void endCDATA() throws SAXException {
if (SHOW_ALL) Log.logln("endCDATA");
}
@@ -308,6 +329,7 @@
*
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
+ @Override
public void error(SAXParseException exception) throws SAXException {
if (SHOW_ALL) Log.logln("error: " + showSAX(exception));
throw exception;
@@ -318,6 +340,7 @@
*
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
+ @Override
public void fatalError(SAXParseException exception) throws SAXException {
if (SHOW_ALL) Log.logln("fatalError: " + showSAX(exception));
throw exception;
@@ -328,6 +351,7 @@
*
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
+ @Override
public void warning(SAXParseException exception) throws SAXException {
if (SHOW_ALL) Log.logln("warning: " + showSAX(exception));
throw exception;
@@ -338,7 +362,7 @@
public class MyContentHandler extends LoggingHandler {
StringBuffer chars = new StringBuffer();
StringBuffer commentChars = new StringBuffer();
- Stack<String> startElements = new Stack<String>();
+ Stack<String> startElements = new Stack<>();
StringBuffer tempPath = new StringBuffer();
boolean lastIsStart = false;
@@ -350,10 +374,12 @@
return this;
}
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (lastIsStart) chars.append(ch, start, length);
}
+ @Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
throws SAXException {
tempPath.setLength(0);
@@ -366,8 +392,9 @@
lastIsStart = true;
}
+ @Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
- String startElement = (String) startElements.pop();
+ String startElement = startElements.pop();
if (lastIsStart) {
// System.out.println(startElement + ":" + chars);
simpleHandler.handlePathValue(startElement, chars.toString());
@@ -376,6 +403,7 @@
lastIsStart = false;
}
+ @Override
public void startDTD(String name, String publicId, String systemId) throws SAXException {
if (SHOW_ALL) Log.logln("startDTD name: " + name
+ ", publicId: " + publicId
@@ -383,22 +411,26 @@
simpleHandler.handleStartDtd(name, publicId, systemId);
}
+ @Override
public void endDTD() throws SAXException {
if (SHOW_ALL) Log.logln("endDTD");
simpleHandler.handleEndDtd();
}
+ @Override
public void comment(char[] ch, int start, int length) throws SAXException {
if (SHOW_ALL) Log.logln(" comment " + new String(ch, start, length));
commentChars.append(ch, start, length);
- simpleHandler.handleComment((String) startElements.peek(), commentChars.toString());
+ simpleHandler.handleComment(startElements.peek(), commentChars.toString());
commentChars.setLength(0);
}
+ @Override
public void elementDecl(String name, String model) throws SAXException {
simpleHandler.handleElementDecl(name, model);
}
+ @Override
public void attributeDecl(String eName, String aName, String type, String mode, String value)
throws SAXException {
simpleHandler.handleAttributeDecl(eName, aName, type, mode, value);
@@ -453,6 +485,7 @@
static final class DebuggingInputStream extends InputStream {
InputStream contents;
+ @Override
public void close() throws IOException {
contents.close();
}
@@ -461,6 +494,7 @@
contents = fis;
}
+ @Override
public int read() throws IOException {
int x = contents.read();
System.out.println(Integer.toHexString(x) + ",");
@@ -468,37 +502,40 @@
}
}
- public static final class FilterBomInputStream extends InputStream {
- InputStream contents;
- boolean first = true;
-
- public void close() throws IOException {
- contents.close();
- }
-
- public FilterBomInputStream(InputStream fis) {
- contents = fis;
- }
-
- public int read() throws IOException {
- int x = contents.read();
- if (first) {
- first = false;
- // 0xEF,0xBB,0xBF
- // SKIP bom
- if (x == 0xEF) {
- int y = contents.read();
- if (y == 0xBB) {
- int z = contents.read();
- if (z == 0xBF) {
- x = contents.read();
- }
- }
- }
- }
- return x;
- }
- }
+// class StripUTF8BOMInputStream does the same thing
+// public static final class FilterBomInputStream extends InputStream {
+// InputStream contents;
+// boolean first = true;
+//
+// @Override
+// public void close() throws IOException {
+// contents.close();
+// }
+//
+// public FilterBomInputStream(InputStream fis) {
+// contents = fis;
+// }
+//
+// @Override
+// public int read() throws IOException {
+// int x = contents.read();
+// if (first) {
+// first = false;
+// // 0xEF,0xBB,0xBF
+// // SKIP bom
+// if (x == 0xEF) {
+// int y = contents.read();
+// if (y == 0xBB) {
+// int z = contents.read();
+// if (z == 0xBF) {
+// x = contents.read();
+// }
+// }
+// }
+// }
+// return x;
+// }
+// }
public static List<Pair<String, String>> loadPathValues(String filename, List<Pair<String, String>> data, boolean validating) {
return loadPathValues(filename, data, validating, false);
@@ -537,7 +574,7 @@
public PathValueListHandler(List<Pair<String, String>> data, boolean full, Function<String, String> valueFilter) {
super();
- this.data = data != null ? data : new ArrayList<Pair<String, String>>();
+ this.data = data != null ? data : new ArrayList<>();
this.full = full;
this.valueFilter = valueFilter;
}
diff --git a/tools/java/org/unicode/cldr/util/XMLNormalizingLoader.java b/tools/java/org/unicode/cldr/util/XMLNormalizingLoader.java
new file mode 100644
index 0000000..2d169d0
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/XMLNormalizingLoader.java
@@ -0,0 +1,678 @@
+package org.unicode.cldr.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.unicode.cldr.util.CLDRFile.DraftStatus;
+import org.unicode.cldr.util.XMLFileReader.AllHandler;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.text.UnicodeSet;
+import com.ibm.icu.util.ICUUncheckedIOException;
+import com.ibm.icu.util.VersionInfo;
+
+/**
+ * Loading Normalized XMLSource
+ */
+public class XMLNormalizingLoader{
+
+ private static final int CACHE_LIMIT = 700;
+ private static LoadingCache<XMLSourceCacheKey, XMLSource> cache = CacheBuilder.newBuilder()
+ .maximumSize(CACHE_LIMIT)
+ .softValues() // will garbage-collected in LRU manner in response to memory demand
+ .build(
+ new CacheLoader<XMLSourceCacheKey, XMLSource>() {
+ @Override
+ public XMLSource load(XMLSourceCacheKey key) {
+ return makeXMLSource(key);
+ }
+ });
+
+ private static final boolean LOG_PROGRESS = false;
+ private static final boolean DEBUG = false;
+ enum SupplementalStatus {
+ NEVER_SET, IS_SUMPPLEMENTAL, NOT_SUPPLEMENTAL
+ };
+
+ private static class XMLSourceCacheKey {
+ private final String localeId;
+ private final Set<File> dirs;
+ private final DraftStatus minimalDraftStatus;
+ private final int hashCode;
+ public XMLSourceCacheKey(String localeId, List<File> dirs, DraftStatus minimalDraftStatus) {
+ this.localeId = localeId;
+ // Parameter check: the directory/file supplied must be non-null and readable.
+ if (dirs == null || dirs.isEmpty()) {
+ throw new ICUUncheckedIOException("Attempt to create a XMLSourceCacheKey with a null directory, please supply a non-null one.");
+ }
+ ImmutableSet.Builder<File> _dirs = ImmutableSet.builder();
+ for (File dir : dirs) {
+ if (!dir.canRead()) {
+ throw new ICUUncheckedIOException("The directory specified, " + dir.getPath() + ", cannot be read");
+ }
+ _dirs.add(dir);
+ }
+ this.dirs = _dirs.build();
+ this.minimalDraftStatus = minimalDraftStatus;
+ this.hashCode = Objects.hash(this.localeId, this.dirs, this.minimalDraftStatus);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ XMLSourceCacheKey other = (XMLSourceCacheKey) obj;
+ if(hashCode != other.hashCode) {
+ return false;
+ }
+ if (!Objects.equals(dirs, other.dirs)) {
+ return false;
+ }
+ if (minimalDraftStatus != other.minimalDraftStatus) {
+ return false;
+ }
+ if (!Objects.equals(localeId, other.localeId)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public static XMLSource getFrozenInstance(String localeId, List<File> dirs, DraftStatus minimalDraftStatus) {
+ XMLSourceCacheKey key = new XMLSourceCacheKey(localeId, dirs, minimalDraftStatus);
+ return cache.getUnchecked(key);
+ }
+
+ private static XMLSource makeXMLSource(XMLSourceCacheKey key) {
+ XMLSource source = null;
+ if (key.dirs.size() == 1) {
+ File file = new File(key.dirs.iterator().next(), key.localeId + ".xml");
+ source = loadXMLFile(file, key.localeId, key.minimalDraftStatus);
+ source.freeze();
+ return source;
+ }
+
+ // if contains more than one file, make XMLSource from each file and then combine them to a combined XMLSource,
+ // so that can cache single file XMLSource as well as combined XMLSource
+ List<XMLSource> list = new ArrayList<>();
+ List<File> dirList = new ArrayList<>();
+ for (File dir: key.dirs) {
+ dirList.clear();
+ dirList.add(dir);
+ XMLSourceCacheKey singleKey = new XMLSourceCacheKey(key.localeId, dirList, key.minimalDraftStatus);
+ XMLSource singleSource = cache.getUnchecked(singleKey);
+ list.add(singleSource);
+ }
+
+ source = list.get(0).cloneAsThawed();
+ for (int i = 1; i < list.size(); i++) {
+ XMLSource other = list.get(i);
+ source.putAll(other, 0); // 0 --> merge_keep_mine
+ source.getXpathComments().joinAll(other.getXpathComments());
+ }
+ source.freeze();
+ return source;
+ }
+
+ public static XMLSource loadXMLFile(File f, String localeId, DraftStatus minimalDraftStatus) {
+ // use try-with-resources statement
+ try (
+ InputStream fis = new StripUTF8BOMInputStream(new FileInputStream(f));
+ InputStreamReader reader = new InputStreamReader(fis, Charset.forName("UTF-8"))
+ ) {
+ String fullFileName = f.getCanonicalPath();
+ XMLSource source = new SimpleXMLSource(localeId);
+ XMLNormalizingHandler XML_HANDLER = new XMLNormalizingHandler(source, minimalDraftStatus);
+ XMLFileReader.read(fullFileName, reader, -1, true, XML_HANDLER);
+ if (XML_HANDLER.supplementalStatus == SupplementalStatus.NEVER_SET) {
+ throw new IllegalArgumentException("root of file must be either ldml or supplementalData");
+ }
+ source.setNonInheriting(XML_HANDLER.supplementalStatus == SupplementalStatus.NOT_SUPPLEMENTAL);
+ if (XML_HANDLER.overrideCount > 0) {
+ throw new IllegalArgumentException("Internal problems: either data file has duplicate path, or" +
+ " CLDRFile.isDistinguishing() or CLDRFile.isOrdered() need updating: "
+ + XML_HANDLER.overrideCount
+ + "; The exact problems are printed on the console above.");
+ }
+ return source;
+ } catch (IOException e) {
+ throw new ICUUncheckedIOException("Cannot read the file " + f, e);
+ }
+ }
+
+ private static class XMLNormalizingHandler implements AllHandler {
+ private DraftStatus minimalDraftStatus;
+ private static final boolean SHOW_START_END = false;
+ private int commentStackIndex;
+ private boolean justPopped = false;
+ private String lastChars = "";
+ private StringBuilder currentFullXPathSb = new StringBuilder("/");
+ private String comment = null;
+ private Map<String, String> attributeOrder;
+ private DtdData dtdData;
+ private XMLSource source;
+ private String lastActiveLeafNode;
+ private String lastLeafNode;
+ private SupplementalStatus supplementalStatus = SupplementalStatus.NEVER_SET;
+ private final static int MAX_DEPTH = 30; // just make deep enough to handle any CLDR file.
+ // orderedCounter, orderedString, and level logically form a single class that allows adding elements, but never removed.
+ private int[] orderedCounter = new int[MAX_DEPTH];
+ private String[] orderedString = new String[MAX_DEPTH];
+ private int level = 0;
+ private int overrideCount = 0;
+ // Types which changed from 'type' to 'choice', but not in supplemental data.
+ private static final Set<String> CHANGED_TYPES = new HashSet<>(Arrays.asList(new String[] {
+ "abbreviationFallback",
+ "default", "mapping", "measurementSystem", "preferenceOrdering" }));
+ private static final Pattern DRAFT_PATTERN = PatternCache.get("\\[@draft=\"([^\"]*)\"\\]");
+ private static final Pattern WHITESPACE_WITH_LF = PatternCache.get("\\s*\\u000a\\s*");
+ private Matcher draftMatcher = DRAFT_PATTERN.matcher("");
+ private Matcher whitespaceWithLf = WHITESPACE_WITH_LF.matcher("");
+ private static final UnicodeSet CONTROLS = new UnicodeSet("[:cc:]").freeze();
+ private static final UnicodeSet WHITESPACE = new UnicodeSet("[:whitespace:]").freeze();
+
+ XMLNormalizingHandler(XMLSource source, DraftStatus minimalDraftStatus) {
+ this.source = source;
+ this.minimalDraftStatus = minimalDraftStatus;
+ }
+
+ private String show(Attributes attributes) {
+ if (attributes == null) return "null";
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < attributes.getLength(); ++i) {
+ String attribute = attributes.getQName(i);
+ String value = attributes.getValue(i);
+ result.append( "[@" + attribute + "=\"" + value + "\"]"); // TODO quote the value??
+ }
+ return result.toString();
+ }
+
+ private void push(String qName, Attributes attributes) {
+ Log.logln(LOG_PROGRESS, "push\t" + qName + "\t" + show(attributes));
+ ++level;
+ if (!qName.equals(orderedString[level])) {
+ orderedString[level] = qName;
+ }
+ if (lastChars.length() != 0) {
+ if (WHITESPACE.containsAll(lastChars))
+ lastChars = "";
+ else
+ throw new IllegalArgumentException("Must not have mixed content: " + qName + ", "
+ + show(attributes) + ", Content: " + lastChars);
+ }
+
+ currentFullXPathSb.append("/" + qName);
+ if (dtdData.isOrdered(qName)) {
+ currentFullXPathSb.append(orderingAttribute());
+ }
+ if (attributes.getLength() > 0) {
+ attributeOrder.clear();
+ for (int i = 0; i < attributes.getLength(); ++i) {
+ String attribute = attributes.getQName(i);
+ String value = attributes.getValue(i);
+
+ if (attribute.equals("cldrVersion")
+ && (qName.equals("version"))) {
+ ((SimpleXMLSource) source).setDtdVersionInfo(VersionInfo.getInstance(value));
+ } else {
+ putAndFixDeprecatedAttribute(qName, attribute, value);
+ }
+ }
+ for (Entry<String, String> entry : attributeOrder.entrySet()) {
+ String attribute = entry.getKey();
+ String value = entry.getValue();
+ String both = "[@" + attribute + "=\"" + value + "\"]"; // TODO quote the value??
+ currentFullXPathSb.append(both);
+ }
+ }
+ if (comment != null) {
+ String currentFullXPath = currentFullXPathSb.toString();
+ if (currentFullXPath.equals("//ldml") || currentFullXPath.equals("//supplementalData")) {
+ source.setInitialComment(comment);
+ } else {
+ source.addComment(currentFullXPath, comment, XPathParts.Comments.CommentType.PREBLOCK);
+ }
+ comment = null;
+ }
+ justPopped = false;
+ lastActiveLeafNode = null;
+ Log.logln(LOG_PROGRESS, "currentFullXPath\t" + currentFullXPathSb.toString());
+ }
+
+
+ private String orderingAttribute() {
+ return "[@_q=\"" + (orderedCounter[level]++) + "\"]";
+ }
+
+ private void putAndFixDeprecatedAttribute(String element, String attribute, String value) {
+ if (attribute.equals("draft")) {
+ if (value.equals("true")) {
+ value = "approved";
+ }
+ else if (value.equals("false")) {
+ value = "unconfirmed";
+ }
+ } else if (attribute.equals("type")) {
+ if (CHANGED_TYPES.contains(element) && supplementalStatus!= SupplementalStatus.NOT_SUPPLEMENTAL) { // measurementSystem for example did not
+ // change from 'type' to 'choice'.
+ attribute = "choice";
+ }
+ }
+
+ attributeOrder.put(attribute, value);
+ }
+
+ /**
+ * Adds a parsed XPath to the CLDRFile.
+ *
+ * @param fullXPath
+ * @param value
+ */
+ private void addPath(String fullXPath, String value) {
+ String former = source.getValueAtPath(fullXPath);
+ if (former != null) {
+ String formerPath = source.getFullXPath(fullXPath);
+ if (!former.equals(value) || !fullXPath.equals(formerPath)) {
+ if (!fullXPath.startsWith("//ldml/identity/version") && !fullXPath.startsWith("//ldml/identity/generation")) {
+ warnOnOverride(former, formerPath);
+ }
+ }
+ }
+ value = trimWhitespaceSpecial(value);
+ source.add(fullXPath, value);
+ }
+
+ private void pop(String qName) {
+ Log.logln(LOG_PROGRESS, "pop\t" + qName);
+ --level;
+ String currentFullXPath = currentFullXPathSb.toString();
+ if (!lastChars.isEmpty() || justPopped == false) {
+ boolean acceptItem = minimalDraftStatus == DraftStatus.unconfirmed;
+ if (!acceptItem) {
+ if (draftMatcher.reset(currentFullXPath).find()) {
+ DraftStatus foundStatus = DraftStatus.valueOf(draftMatcher.group(1));
+ if (minimalDraftStatus.compareTo(foundStatus) <= 0) {
+ // what we found is greater than or equal to our status
+ acceptItem = true;
+ }
+ } else {
+ acceptItem = true; // if not found, then the draft status is approved, so it is always ok
+ }
+ }
+ if (acceptItem) {
+ // Change any deprecated orientation attributes into values
+ // for backwards compatibility.
+ boolean skipAdd = false;
+ if (currentFullXPath.startsWith("//ldml/layout/orientation")) {
+ XPathParts parts = XPathParts.getFrozenInstance(currentFullXPath);
+ String value = parts.getAttributeValue(-1, "characters");
+ if (value != null) {
+ addPath("//ldml/layout/orientation/characterOrder", value);
+ skipAdd = true;
+ }
+ value = parts.getAttributeValue(-1, "lines");
+ if (value != null) {
+ addPath("//ldml/layout/orientation/lineOrder", value);
+ skipAdd = true;
+ }
+ }
+ if (!skipAdd) {
+ addPath(currentFullXPath, lastChars);
+ }
+ lastLeafNode = lastActiveLeafNode = currentFullXPath;
+ }
+ lastChars = "";
+ } else {
+ Log.logln(LOG_PROGRESS && lastActiveLeafNode != null, "pop: zeroing last leafNode: "
+ + lastActiveLeafNode);
+ lastActiveLeafNode = null;
+ if (comment != null) {
+ source.addComment(lastLeafNode, comment, XPathParts.Comments.CommentType.POSTBLOCK);
+ comment = null;
+ }
+ }
+ currentFullXPathSb.setLength(0);
+ currentFullXPathSb.append(stripAfter(currentFullXPath, qName));
+ justPopped = true;
+ }
+
+ /**
+ * Trim leading whitespace if there is a linefeed among them, then the same with trailing.
+ *
+ * @param source
+ * @return
+ */
+ private String trimWhitespaceSpecial(String source) {
+ if (DEBUG && CONTROLS.containsSome(source)) {
+ System.out.println("*** " + source);
+ }
+ if (!source.contains("\n")) {
+ return source;
+ }
+ source = whitespaceWithLf.reset(source).replaceAll("\n");
+ return source;
+ }
+
+ private void warnOnOverride(String former, String formerPath) {
+ String distinguishing = CLDRFile.getDistinguishingXPath(formerPath, null);
+ System.out.println("\tERROR in " + source.getLocaleID()
+ + ";\toverriding old value <" + former + "> at path " + distinguishing +
+ "\twith\t<" + lastChars + ">" +
+ CldrUtility.LINE_SEPARATOR + "\told fullpath: " + formerPath +
+ CldrUtility.LINE_SEPARATOR + "\tnew fullpath: " + currentFullXPathSb.toString());
+ overrideCount += 1;
+ }
+
+ private static String stripAfter(String input, String qName) {
+ int pos = findLastSlash(input);
+ if (qName != null) {
+ // assert input.substring(pos+1).startsWith(qName);
+ if (!input.substring(pos + 1).startsWith(qName)) {
+ throw new IllegalArgumentException("Internal Error: should never get here.");
+ }
+ }
+ return input.substring(0, pos);
+ }
+
+ private static int findLastSlash(String input) {
+ int braceStack = 0;
+ char inQuote = 0;
+ for (int i = input.length() - 1; i >= 0; --i) {
+ char ch = input.charAt(i);
+ switch (ch) {
+ case '\'': // treat single and double quotes in same way
+ case '"':
+ if (inQuote == 0) {
+ inQuote = ch;
+ } else if (inQuote == ch) {
+ inQuote = 0; // come out of quote
+ }
+ break;
+ case '/':
+ if (inQuote == 0 && braceStack == 0) {
+ return i;
+ }
+ break;
+ case '[':
+ if (inQuote == 0) {
+ --braceStack;
+ }
+ break;
+ case ']':
+ if (inQuote == 0) {
+ ++braceStack;
+ }
+ break;
+ }
+ }
+ return -1;
+ }
+
+ // SAX items we need to catch
+
+ @Override
+ public void startElement(
+ String uri,
+ String localName,
+ String qName,
+ Attributes attributes)
+ throws SAXException {
+ Log.logln(LOG_PROGRESS || SHOW_START_END, "startElement uri\t" + uri
+ + "\tlocalName " + localName
+ + "\tqName " + qName
+ + "\tattributes " + show(attributes));
+ try {
+ if (supplementalStatus == SupplementalStatus.NEVER_SET) { // set by first element
+ attributeOrder = new TreeMap<>(
+ // HACK for ldmlIcu
+ dtdData.dtdType == DtdType.ldml
+ ? CLDRFile.getAttributeOrdering()
+ : dtdData.getAttributeComparator());
+ supplementalStatus = source.getXMLNormalizingDtdType() == DtdType.ldml ?
+ SupplementalStatus.IS_SUMPPLEMENTAL : SupplementalStatus.NOT_SUPPLEMENTAL;
+ }
+ push(qName, attributes);
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ Log.logln(LOG_PROGRESS || SHOW_START_END, "endElement uri\t" + uri + "\tlocalName " + localName
+ + "\tqName " + qName);
+ try {
+ pop(qName);
+ } catch (RuntimeException e) {
+ throw e;
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ try {
+ String value = new String(ch, start, length);
+ Log.logln(LOG_PROGRESS, "characters:\t" + value);
+ // we will strip leading and trailing line separators in another place.
+ // if (value.indexOf(XML_LINESEPARATOR) >= 0) {
+ // value = value.replace(XML_LINESEPARATOR, '\u0020');
+ // }
+ lastChars += value;
+ justPopped = false;
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Override
+ public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ Log.logln(LOG_PROGRESS, "startDTD name: " + name
+ + ", publicId: " + publicId
+ + ", systemId: " + systemId);
+ commentStackIndex++;
+ source.setXMLNormalizingDtdType(DtdType.valueOf(name));
+ dtdData = DtdData.getInstance(source.getXMLNormalizingDtdType());
+ }
+
+ @Override
+ public void endDTD() throws SAXException {
+ Log.logln(LOG_PROGRESS, "endDTD");
+ commentStackIndex--;
+ }
+
+ @Override
+ public void comment(char[] ch, int start, int length) throws SAXException {
+ final String string = new String(ch, start, length);
+ Log.logln(LOG_PROGRESS, commentStackIndex + " comment " + string);
+ try {
+ if (commentStackIndex != 0) return;
+ String comment0 = trimWhitespaceSpecial(string).trim();
+ if (lastActiveLeafNode != null) {
+ source.addComment(lastActiveLeafNode, comment0, XPathParts.Comments.CommentType.LINE);
+ } else {
+ comment = (comment == null ? comment0 : comment + XPathParts.NEWLINE + comment0);
+ }
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Override
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ if (LOG_PROGRESS)
+ Log.logln(LOG_PROGRESS,
+ "ignorableWhitespace length: " + length + ": " + Utility.hex(new String(ch, start, length)));
+ for (int i = start; i < start + length; ++i) {
+ if (ch[i] == '\n') {
+ Log.logln(LOG_PROGRESS && lastActiveLeafNode != null, "\\n: zeroing last leafNode: "
+ + lastActiveLeafNode);
+ lastActiveLeafNode = null;
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void startDocument() throws SAXException {
+ Log.logln(LOG_PROGRESS, "startDocument");
+ commentStackIndex = 0; // initialize
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ Log.logln(LOG_PROGRESS, "endDocument");
+ try {
+ if (comment != null) {
+ source.addComment(null, comment, XPathParts.Comments.CommentType.LINE);
+ }
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ // ==== The following are just for debugging =====
+
+ @Override
+ public void elementDecl(String name, String model) throws SAXException {
+ Log.logln(LOG_PROGRESS, "Attribute\t" + name + "\t" + model);
+ }
+
+ @Override
+ public void attributeDecl(String eName, String aName, String type, String mode, String value)
+ throws SAXException {
+ Log.logln(LOG_PROGRESS, "Attribute\t" + eName + "\t" + aName + "\t" + type + "\t" + mode + "\t" + value);
+ }
+
+ @Override
+ public void internalEntityDecl(String name, String value) throws SAXException {
+ Log.logln(LOG_PROGRESS, "Internal Entity\t" + name + "\t" + value);
+ }
+
+ @Override
+ public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
+ Log.logln(LOG_PROGRESS, "Internal Entity\t" + name + "\t" + publicId + "\t" + systemId);
+ }
+
+ @Override
+ public void processingInstruction(String target, String data)
+ throws SAXException {
+ Log.logln(LOG_PROGRESS, "processingInstruction: " + target + ", " + data);
+ }
+
+ @Override
+ public void skippedEntity(String name)
+ throws SAXException {
+ Log.logln(LOG_PROGRESS, "skippedEntity: " + name);
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ Log.logln(LOG_PROGRESS, "setDocumentLocator Locator " + locator);
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ Log.logln(LOG_PROGRESS, "startPrefixMapping prefix: " + prefix +
+ ", uri: " + uri);
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ Log.logln(LOG_PROGRESS, "endPrefixMapping prefix: " + prefix);
+ }
+
+ @Override
+ public void startEntity(String name) throws SAXException {
+ Log.logln(LOG_PROGRESS, "startEntity name: " + name);
+ }
+
+ @Override
+ public void endEntity(String name) throws SAXException {
+ Log.logln(LOG_PROGRESS, "endEntity name: " + name);
+ }
+
+ @Override
+ public void startCDATA() throws SAXException {
+ Log.logln(LOG_PROGRESS, "startCDATA");
+ }
+
+ @Override
+ public void endCDATA() throws SAXException {
+ Log.logln(LOG_PROGRESS, "endCDATA");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ */
+ @Override
+ public void error(SAXParseException exception) throws SAXException {
+ Log.logln(LOG_PROGRESS || true, "error: " + XMLFileReader.showSAX(exception));
+ throw exception;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+ */
+ @Override
+ public void fatalError(SAXParseException exception) throws SAXException {
+ Log.logln(LOG_PROGRESS, "fatalError: " + XMLFileReader.showSAX(exception));
+ throw exception;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ */
+ @Override
+ public void warning(SAXParseException exception) throws SAXException {
+ Log.logln(LOG_PROGRESS, "warning: " + XMLFileReader.showSAX(exception));
+ throw exception;
+ }
+ }
+}
diff --git a/tools/java/org/unicode/cldr/util/XMLSource.java b/tools/java/org/unicode/cldr/util/XMLSource.java
index ac9591b..579d446 100644
--- a/tools/java/org/unicode/cldr/util/XMLSource.java
+++ b/tools/java/org/unicode/cldr/util/XMLSource.java
@@ -7,6 +7,7 @@
package org.unicode.cldr.util;
+import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -25,8 +26,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.unicode.cldr.util.CLDRFile.DraftStatus;
import org.unicode.cldr.util.XPathParts.Comments;
+import com.google.common.collect.Iterators;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.Output;
@@ -42,7 +45,7 @@
public static final String ROOT_ID = "root";
public static final boolean USE_PARTS_IN_ALIAS = false;
private static final String TRACE_INDENT = " "; // "\t"
- private static Map<String, String> allowDuplicates = new HashMap<String, String>();
+ private static Map<String, String> allowDuplicates = new HashMap<>();
private String localeID;
private boolean nonInheriting;
@@ -72,7 +75,7 @@
}
// Listeners are stored using weak references so that they can be garbage collected.
- private List<WeakReference<Listener>> listeners = new ArrayList<WeakReference<Listener>>();
+ private List<WeakReference<Listener>> listeners = new ArrayList<>();
public String getLocaleID() {
return localeID;
@@ -149,6 +152,7 @@
return parts.containsAttribute("draft");
}
+ @Override
public boolean isFrozen() {
return locked;
}
@@ -303,6 +307,7 @@
return oldPath;
}
+ @Override
public String toString() {
return
// "oldLocaleID: " + oldLocaleID + ", " +
@@ -421,7 +426,7 @@
* return aliasMap the new map
*/
private TreeMap<String, String> loadAliases() {
- TreeMap<String, String> aliasMap = new TreeMap<String, String>();
+ TreeMap<String, String> aliasMap = new TreeMap<>();
for (String path : this) {
if (!Alias.isAliasPath(path)) {
continue;
@@ -445,17 +450,17 @@
}
// Aliases are only ever found in root.
Map<String, String> aliases = getAliases();
- Map<String, List<String>> reverse = new HashMap<String, List<String>>();
+ Map<String, List<String>> reverse = new HashMap<>();
for (Map.Entry<String, String> entry : aliases.entrySet()) {
List<String> list = reverse.get(entry.getValue());
if (list == null) {
- list = new ArrayList<String>();
+ list = new ArrayList<>();
reverse.put(entry.getValue(), list);
}
list.add(entry.getKey());
}
// Sort map.
- LinkedHashMap<String, List<String>> reverseAliasMap = new LinkedHashMap<String, List<String>>(new TreeMap<String, List<String>>(reverse));
+ LinkedHashMap<String, List<String>> reverseAliasMap = new LinkedHashMap<>(new TreeMap<>(reverse));
if (cachingIsEnabled) {
reverseAliasCache = reverseAliasMap;
}
@@ -612,6 +617,7 @@
/**
* @return an iterator over the distinguished paths
*/
+ @Override
abstract public Iterator<String> iterator();
/**
@@ -620,12 +626,12 @@
*/
public Iterator<String> iterator(String prefix) {
if (prefix == null || prefix.length() == 0) return iterator();
- return new com.ibm.icu.dev.util.CollectionUtilities.PrefixIterator().set(iterator(), prefix);
+ return Iterators.filter(iterator(), s -> s.startsWith(prefix));
}
public Iterator<String> iterator(Matcher pathFilter) {
if (pathFilter == null) return iterator();
- return new com.ibm.icu.dev.util.CollectionUtilities.RegexIterator().set(iterator(), pathFilter);
+ return Iterators.filter(iterator(), s -> pathFilter.reset(s).matches());
}
/**
@@ -647,6 +653,7 @@
/**
* SUBCLASSING: must be overridden
*/
+ @Override
public XMLSource cloneAsThawed() {
try {
XMLSource result = (XMLSource) super.clone();
@@ -660,6 +667,7 @@
/**
* for debugging only
*/
+ @Override
public String toString() {
StringBuffer result = new StringBuffer();
for (Iterator<String> it = iterator(); it.hasNext();) {
@@ -712,10 +720,12 @@
private XMLSource currentSource;
private LinkedHashMap<String, XMLSource> sources;
+ @Override
public boolean isResolving() {
return true;
}
+ @Override
public XMLSource getUnresolving() {
return sources.get(getLocaleID());
}
@@ -726,10 +736,11 @@
* then the parent for //ldml/xyz/.../uvw/abc/.../def/
* is source, and the path to search for is really: //ldml/xyz/.../uvw/path/abc/.../def/
*/
- public static final boolean TRACE_VALUE = CldrUtility.getProperty("TRACE_VALUE", false);;
+ public static final boolean TRACE_VALUE = CldrUtility.getProperty("TRACE_VALUE", false);
// Map<String,String> getValueAtDPathCache = new HashMap();
+ @Override
public String getValueAtDPath(String xpath) {
if (DEBUG_PATH != null && DEBUG_PATH.matcher(xpath).find()) {
System.out.println("Getting value for Path: " + xpath);
@@ -783,8 +794,9 @@
// }
// }
- Map<String, String> getFullPathAtDPathCache = new HashMap<String, String>();
+ Map<String, String> getFullPathAtDPathCache = new HashMap<>();
+ @Override
public String getFullPathAtDPath(String xpath) {
String result = currentSource.getFullPathAtDPath(xpath);
if (result != null) {
@@ -837,7 +849,7 @@
// find the differences, and add them into xpath
// we do this by walking through each element, adding the corresponding attribute values.
// we add attributes FROM THE END, in case the lengths are different!
- XPathParts xpathParts = XPathParts.getInstance(xpath); // not frozen, for putAttributeValue
+ XPathParts xpathParts = XPathParts.getFrozenInstance(xpath).cloneAsThawed(); // not frozen, for putAttributeValue
XPathParts fullPathWhereFoundParts = XPathParts.getFrozenInstance(fullPathWhereFound);
XPathParts pathWhereFoundParts = XPathParts.getFrozenInstance(fullStatus.pathWhereFound);
int offset = xpathParts.size() - pathWhereFoundParts.size();
@@ -866,7 +878,7 @@
/**
* Return the "George Bailey" value, i.e., the value that would obtain if the value didn't exist (in the first source).
* Often the Bailey value comes from the parent locale (such as "fr") of a sublocale (such as "fr_CA").
- * Sometimes the Bailey value comes from an alias which may be a different path in the same locale.
+ * Sometimes the Bailey value comes from an alias which may be a different path in the same locale.
*
* @param xpath the given path
* @param pathWhereFound if not null, to be filled in with the path where found
@@ -901,7 +913,7 @@
* Can't use the same cache for skipInheritanceMarker true and false.
* Could use two caches, or add skipInheritanceMarker to the key (append 'T' or 'F' to xpath).
* The situation is complicated by use of getSourceLocaleIDCache also in valueChanged.
- *
+ *
* There is no caching problem with skipFirst, since that is always false here -- though
* getBaileyValue could use a cache if there was one for skipFirst true.
*
@@ -933,7 +945,7 @@
return result;
}
- private transient Map<String, AliasLocation> getSourceLocaleIDCache = new WeakHashMap<String, AliasLocation>();
+ private transient Map<String, AliasLocation> getSourceLocaleIDCache = new WeakHashMap<>();
/**
* Get the source locale ID for the given path, for this ResolvingSource.
@@ -955,7 +967,7 @@
* @param status if not null, to have status.pathWhereFound filled in
* @param skipInheritanceMarker if true, skip sources in which value is INHERITANCE_MARKER
* @return the localeID, as a string
- */
+ */
@Override
public String getSourceLocaleIdExtended(String distinguishedXPath, CLDRFile.Status status, boolean skipInheritanceMarker) {
AliasLocation fullStatus = getCachedFullStatus(distinguishedXPath, skipInheritanceMarker);
@@ -989,7 +1001,7 @@
* For other callers, we stick with skipInheritanceMarker true for now, to retain
* the behavior before the skipInheritanceMarker parameter was added, but we should be alert for the
* possibility that skipInheritanceMarker should be false in some other cases
- *
+ *
* References: https://unicode.org/cldr/trac/ticket/11765
* https://unicode.org/cldr/trac/ticket/11720
* https://unicode.org/cldr/trac/ticket/11103
@@ -1023,7 +1035,7 @@
xpath.substring(possibleSubpath.length());
}
}
-
+
// alts are special; they act like there is a root alias to the path without the alt.
if (aliasedPath == null && xpath.contains("[@alt=")) {
aliasedPath = XPathParts.getPathWithoutAlt(xpath);
@@ -1062,7 +1074,7 @@
static final boolean TRACE_FILL = CldrUtility.getProperty("TRACE_FILL", false);
static final String DEBUG_PATH_STRING = CldrUtility.getProperty("DEBUG_PATH", null);
static final Pattern DEBUG_PATH = DEBUG_PATH_STRING == null ? null : PatternCache.get(DEBUG_PATH_STRING);
- static final boolean SKIP_FALLBACKID = CldrUtility.getProperty("SKIP_FALLBACKID", false);;
+ static final boolean SKIP_FALLBACKID = CldrUtility.getProperty("SKIP_FALLBACKID", false);
static final int MAX_LEVEL = 40; /* Throw an error if it goes past this. */
@@ -1106,10 +1118,10 @@
* @return
*/
private Set<String> findNonAliasedPaths() {
- HashSet<String> paths = new HashSet<String>();
+ HashSet<String> paths = new HashSet<>();
// Get all XMLSources used during resolution.
- List<XMLSource> sourceList = new ArrayList<XMLSource>(sources.values());
+ List<XMLSource> sourceList = new ArrayList<>(sources.values());
if (!SKIP_FALLBACKID) {
sourceList.add(constructedItems);
}
@@ -1131,7 +1143,7 @@
* @return the new set of paths
*/
private Set<String> getDirectAliases(String[] paths) {
- HashSet<String> newPaths = new HashSet<String>();
+ HashSet<String> newPaths = new HashSet<>();
// Keep track of the current path index: since it's sorted, we
// never have to backtrack.
int pathIndex = 0;
@@ -1174,6 +1186,7 @@
/**
* @return an iterator over all the xpaths in this XMLSource.
*/
+ @Override
public Iterator<String> iterator() {
return getCachedKeySet().iterator();
}
@@ -1188,26 +1201,32 @@
return cachedKeySet;
}
+ @Override
public void putFullPathAtDPath(String distinguishingXPath, String fullxpath) {
throw new UnsupportedOperationException("Resolved CLDRFiles are read-only");
}
+ @Override
public void putValueAtDPath(String distinguishingXPath, String value) {
throw new UnsupportedOperationException("Resolved CLDRFiles are read-only");
}
+ @Override
public Comments getXpathComments() {
return currentSource.getXpathComments();
}
+ @Override
public void setXpathComments(Comments path) {
throw new UnsupportedOperationException("Resolved CLDRFiles are read-only");
}
+ @Override
public void removeValueAtDPath(String xpath) {
throw new UnsupportedOperationException("Resolved CLDRFiles are read-only");
}
+ @Override
public XMLSource freeze() {
return this; // No-op. ResolvingSource is already read-only.
}
@@ -1248,7 +1267,7 @@
throw new IllegalArgumentException("Last element should be root");
}
currentSource = sourceList.get(0); // Convenience variable
- sources = new LinkedHashMap<String, XMLSource>();
+ sources = new LinkedHashMap<>();
for (XMLSource source : sourceList) {
sources.put(source.getLocaleID(), source);
}
@@ -1260,6 +1279,7 @@
}
}
+ @Override
public String getLocaleID() {
return currentSource.getLocaleID();
}
@@ -1427,7 +1447,7 @@
String value = code;
if (typeNo == CLDRFile.TZ_EXEMPLAR) { // skip single-zone countries
if (SKIP_SINGLEZONES) {
- String country = (String) zone_countries.get(code);
+ String country = zone_countries.get(code);
Set<String> s = countries_zoneSet.get(country);
if (s != null && s.size() == 1) continue;
}
@@ -1450,16 +1470,16 @@
// "false");
// }
- String[] extraCodes = {
- "ar_001",
- "de_AT", "de_CH",
+ String[] extraCodes = {
+ "ar_001",
+ "de_AT", "de_CH",
"en_AU", "en_CA", "en_GB", "en_US", "es_419", "es_ES", "es_MX",
- "fa_AF", "fr_CA", "fr_CH", "frc",
- "lou",
- "nds_NL", "nl_BE",
- "pt_BR", "pt_PT",
- "ro_MD",
- "sw_CD",
+ "fa_AF", "fr_CA", "fr_CH", "frc",
+ "lou",
+ "nds_NL", "nl_BE",
+ "pt_BR", "pt_PT",
+ "ro_MD",
+ "sw_CD",
"zh_Hans", "zh_Hant"
};
for (String extraCode : extraCodes) {
@@ -1469,7 +1489,9 @@
addFallbackCode(CLDRFile.LANGUAGE_NAME, "en_GB", "en_GB", "short");
addFallbackCode(CLDRFile.LANGUAGE_NAME, "en_US", "en_US", "short");
addFallbackCode(CLDRFile.LANGUAGE_NAME, "az", "az", "short");
-
+
+ addFallbackCode(CLDRFile.LANGUAGE_NAME, "ckb", "ckb", "menu");
+ addFallbackCode(CLDRFile.LANGUAGE_NAME, "ckb", "ckb", "variant");
addFallbackCode(CLDRFile.LANGUAGE_NAME, "yue", "yue", "menu");
addFallbackCode(CLDRFile.LANGUAGE_NAME, "zh", "zh", "menu");
addFallbackCode(CLDRFile.LANGUAGE_NAME, "zh_Hans", "zh", "long");
@@ -1576,10 +1598,10 @@
// clear yet how much further caching would speed this up.
// Add all non-aliased paths with the specified value.
- List<XMLSource> children = new ArrayList<XMLSource>();
- Set<String> filteredPaths = new HashSet<String>();
+ List<XMLSource> children = new ArrayList<>();
+ Set<String> filteredPaths = new HashSet<>();
for (XMLSource source : sources.values()) {
- Set<String> pathsWithValue = new HashSet<String>();
+ Set<String> pathsWithValue = new HashSet<>();
source.getPathsWithValue(valueToMatch, pathPrefix, pathsWithValue);
// Don't add a path with the value if it is overridden by a child locale.
for (String pathWithValue : pathsWithValue) {
@@ -1592,8 +1614,8 @@
// Find all paths that alias to the specified value, then filter by
// path prefix.
- Set<String> aliases = new HashSet<String>();
- Set<String> oldAliases = new HashSet<String>(filteredPaths);
+ Set<String> aliases = new HashSet<>();
+ Set<String> oldAliases = new HashSet<>(filteredPaths);
Set<String> newAliases;
do {
String[] sortedPaths = new String[oldAliases.size()];
@@ -1608,11 +1630,11 @@
String norm = null;
for (String alias : aliases) {
if (alias.startsWith(pathPrefix)) {
- if (norm == null) {
+ if (norm == null && valueToMatch != null) {
norm = SimpleXMLSource.normalize(valueToMatch);
}
String value = getValueAtDPath(alias);
- if (SimpleXMLSource.normalize(value).equals(norm)) {
+ if (value != null && SimpleXMLSource.normalize(value).equals(norm)) {
filteredPaths.add(alias);
}
}
@@ -1666,19 +1688,16 @@
* Adds a listener to this XML source.
*/
public void addListener(Listener listener) {
- listeners.add(new WeakReference<Listener>(listener));
+ listeners.add(new WeakReference<>(listener));
}
/**
- * Notifies all listeners that a change has occurred. This method should be
- * called by the XMLSource being updated after any change
- * (usually in putValueAtDPath() and removeValueAtDPath()).
- * This should only be called by XMLSource / CLDRFile
+ * Notifies all listeners that the winning value for the given path has changed.
*
* @param xpath
* the xpath where the change occurred.
*/
- protected void notifyListeners(String xpath) {
+ public void notifyListeners(String xpath) {
int i = 0;
while (i < listeners.size()) {
Listener listener = listeners.get(i).get();
@@ -1730,4 +1749,83 @@
}
return null;
}
+
+ /**
+ * XMLNormalizingDtdType is set in XMLNormalizingHandler loading XML process
+ */
+ private DtdType XMLNormalizingDtdType;
+ private static final boolean LOG_PROGRESS = false;
+
+ public DtdType getXMLNormalizingDtdType() {
+ return this.XMLNormalizingDtdType;
+ }
+
+ public void setXMLNormalizingDtdType(DtdType dtdType) {
+ this.XMLNormalizingDtdType = dtdType;
+ }
+
+ /**
+ * Sets the initial comment, replacing everything that was there
+ * Use in XMLNormalizingHandler only
+ */
+ public XMLSource setInitialComment(String comment) {
+ if (locked) throw new UnsupportedOperationException("Attempt to modify locked object");
+ Log.logln(LOG_PROGRESS, "SET initial Comment: \t" + comment);
+ this.getXpathComments().setInitialComment(comment);
+ return this;
+ }
+
+ /**
+ * Use in XMLNormalizingHandler only
+ */
+ public XMLSource addComment(String xpath, String comment, Comments.CommentType type) {
+ if (locked) throw new UnsupportedOperationException("Attempt to modify locked object");
+ Log.logln(LOG_PROGRESS, "ADDING Comment: \t" + type + "\t" + xpath + " \t" + comment);
+ if (xpath == null || xpath.length() == 0) {
+ this.getXpathComments().setFinalComment(
+ CldrUtility.joinWithSeparation(this.getXpathComments().getFinalComment(), XPathParts.NEWLINE,
+ comment));
+ } else {
+ xpath = CLDRFile.getDistinguishingXPath(xpath, null);
+ this.getXpathComments().addComment(type, xpath, comment);
+ }
+ return this;
+ }
+
+ /**
+ * Use in XMLNormalizingHandler only
+ */
+ public String getFullXPath(String xpath) {
+ if (xpath == null) {
+ throw new NullPointerException("Null distinguishing xpath");
+ }
+ String result = this.getFullPath(xpath);
+ return result != null ? result : xpath; // we can't add any non-distinguishing values if there is nothing there.
+ }
+
+ /**
+ * Add a new element to a XMLSource
+ * Use in XMLNormalizingHandler only
+ */
+ public XMLSource add(String currentFullXPath, String value) {
+ if (locked) throw new UnsupportedOperationException("Attempt to modify locked object");
+ Log.logln(LOG_PROGRESS, "ADDING: \t" + currentFullXPath + " \t" + value + "\t" + currentFullXPath);
+ try {
+ this.putValueAtPath(currentFullXPath, value);
+ } catch (RuntimeException e) {
+ throw new IllegalArgumentException("failed adding " + currentFullXPath + ",\t" + value, e);
+ }
+ return this;
+ }
+
+ /**
+ * Get frozen normalized XMLSource
+ * @param localeId
+ * @param dirs
+ * @param minimalDraftStatus
+ * @return XMLSource
+ */
+ public static XMLSource getFrozenInstance(String localeId, List<File> dirs, DraftStatus minimalDraftStatus) {
+ return XMLNormalizingLoader.getFrozenInstance(localeId, dirs, minimalDraftStatus);
+ }
}
diff --git a/tools/java/org/unicode/cldr/util/XMLValidator.java b/tools/java/org/unicode/cldr/util/XMLValidator.java
index 9e284a0..c155ee2 100644
--- a/tools/java/org/unicode/cldr/util/XMLValidator.java
+++ b/tools/java/org/unicode/cldr/util/XMLValidator.java
@@ -90,7 +90,7 @@
}
})) {
if (!quiet) System.out.println("Processing file " + s.getPath());
- new fileParserThread(s.getCanonicalPath()).run();
+ new fileParserThread(PathUtilities.getNormalizedPathString(s)).run();
}
}
@@ -134,15 +134,7 @@
return filename;
File f = new File(filename);
- String tmp = null;
- try {
- // This normally gives a better path
- tmp = f.getCanonicalPath();
- } catch (IOException ioe) {
- // But this can be used as a backup, for cases
- // where the file does not exist, etc.
- tmp = f.getAbsolutePath();
- }
+ String tmp = PathUtilities.getNormalizedPathString(f);
// URLs must explicitly use only forward slashes
if (File.separatorChar == '\\') {
@@ -166,6 +158,7 @@
filename = _filename;
}
+ @Override
public void run() {
// Force filerefs to be URI's if needed: note this is independent of any
// other files
@@ -209,11 +202,13 @@
// This is used to suppress validation warnings
final String filename2 = filename;
ErrorHandler nullHandler = new ErrorHandler() {
+ @Override
public void warning(SAXParseException e) throws SAXException {
System.err.println(filename2 + ": Warning: " + e.getMessage());
}
+ @Override
public void error(SAXParseException e) throws SAXException {
int col = e.getColumnNumber();
System.err.println(filename2 + ":" + e.getLineNumber() + (col >= 0 ? ":" + col : "")
@@ -221,6 +216,7 @@
+ " is not valid because " + e.getMessage());
}
+ @Override
public void fatalError(SAXParseException e) throws SAXException {
System.err.println(filename2 + ": ERROR ");
throw e;
diff --git a/tools/java/org/unicode/cldr/util/XPathParts.java b/tools/java/org/unicode/cldr/util/XPathParts.java
index db4a2ed..90d1741 100644
--- a/tools/java/org/unicode/cldr/util/XPathParts.java
+++ b/tools/java/org/unicode/cldr/util/XPathParts.java
@@ -21,6 +21,8 @@
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.ibm.icu.impl.Utility;
@@ -35,16 +37,16 @@
* Each Element object has an "element" string such as "ldml", "characters", or "exemplarCharacters",
* plus attributes such as a Map from key "type" to value "auxiliary".
*/
-public final class XPathParts implements Freezable<XPathParts> {
+public final class XPathParts implements Freezable<XPathParts>, Comparable<XPathParts> {
private static final boolean DEBUGGING = false;
private volatile boolean frozen = false;
- private List<Element> elements = new ArrayList<Element>();
+ private List<Element> elements = new ArrayList<>();
private DtdData dtdData = null;
- private static final Map<String, XPathParts> cache = new ConcurrentHashMap<String, XPathParts>();
+ private static final Map<String, XPathParts> cache = new ConcurrentHashMap<>();
/**
* Construct a new empty XPathParts object.
@@ -181,7 +183,7 @@
LINE, PREBLOCK, POSTBLOCK
}
- private EnumMap<CommentType, Map<String, String>> comments = new EnumMap<CommentType, Map<String, String>>(
+ private EnumMap<CommentType, Map<String, String>> comments = new EnumMap<>(
CommentType.class);
public Comments() {
@@ -210,7 +212,7 @@
}
public List<String> extractCommentsWithoutBase() {
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (CommentType style : CommentType.values()) {
for (Iterator<String> it = comments.get(style).keySet().iterator(); it.hasNext();) {
String key = it.next();
@@ -222,11 +224,12 @@
return result;
}
+ @Override
public Object clone() {
try {
Comments result = (Comments) super.clone();
for (CommentType c : CommentType.values()) {
- result.comments.put(c, new HashMap<String, String>(comments.get(c)));
+ result.comments.put(c, new HashMap<>(comments.get(c)));
}
return result;
} catch (CloneNotSupportedException e) {
@@ -438,7 +441,18 @@
}
public void putAttributeValue(int elementIndex, String attribute, String value) {
- elements.get(elementIndex >= 0 ? elementIndex : elementIndex + size()).putAttribute(attribute, value);
+ elementIndex = elementIndex >= 0 ? elementIndex : elementIndex + size();
+ Map<String, String> ea = elements.get(elementIndex).attributes;
+ if (value == null && (ea == null || !ea.containsKey(attribute))) {
+ return;
+ }
+ if (value != null && ea != null && value.equals(ea.get(attribute))) {
+ return;
+ }
+ makeElementsMutable();
+ makeElementMutable(elementIndex);
+ // make mutable may change elements.get(elementIndex), so we have to use elements.get(elementIndex) after calling
+ elements.get(elementIndex).putAttribute(attribute, value);
}
/**
@@ -461,7 +475,7 @@
if (attributes == null) {
return null;
}
- return (String) attributes.get(attributeName);
+ return attributes.get(attributeName);
}
/**
@@ -486,10 +500,34 @@
dtdData = null;
}
}
+ makeElementsMutable();
elements.add(new Element(element));
return this;
}
+ public void makeElementsMutable() {
+ if (frozen) {
+ throw new UnsupportedOperationException("Can't modify frozen object.");
+ }
+
+ if (elements instanceof ImmutableList) {
+ elements = new ArrayList<>(elements);
+ }
+ }
+
+ public void makeElementMutable(int elementIndex) {
+ if (frozen) {
+ throw new UnsupportedOperationException("Can't modify frozen object.");
+ }
+
+ Element e = elements.get(elementIndex);
+ Map<String, String> ea = e.attributes;
+ if (ea == null || ea instanceof ImmutableMap) {
+ elements.set(elementIndex, e.cloneAsThawed());
+ }
+ }
+
+
/**
* Varargs version of addElement.
* Usage: xpp.addElements("ldml","localeDisplayNames")
@@ -507,8 +545,7 @@
* Add an attribute/value pair to the current last element.
*/
public XPathParts addAttribute(String attribute, String value) {
- Element e = elements.get(elements.size() - 1);
- e.putAttribute(attribute, value);
+ putAttributeValue(elements.size() - 1, attribute, value);
return this;
}
@@ -517,7 +554,7 @@
}
public XPathParts removeAttribute(int elementIndex, String attributeName) {
- elements.get(elementIndex >= 0 ? elementIndex : elementIndex + size()).putAttribute(attributeName, null);
+ putAttributeValue(elementIndex, attributeName, null);
return this;
}
@@ -526,7 +563,15 @@
}
public XPathParts removeAttributes(int elementIndex, Collection<String> attributeNames) {
- elements.get(elementIndex >= 0 ? elementIndex : elementIndex + size()).removeAttributes(attributeNames);
+ elementIndex = elementIndex >= 0 ? elementIndex : elementIndex + size();
+ Map<String, String> ea = elements.get(elementIndex).attributes;
+ if (ea == null || attributeNames == null || attributeNames.isEmpty() || Collections.disjoint(attributeNames, ea.keySet())) {
+ return this;
+ }
+ makeElementsMutable();
+ makeElementMutable(elementIndex);
+ // make mutable may change elements.get(elementIndex), so we have to use elements.get(elementIndex) after calling
+ elements.get(elementIndex).removeAttributes(attributeNames);
return this;
}
@@ -631,6 +676,7 @@
/**
* boilerplate
*/
+ @Override
public String toString() {
return toString(elements.size());
}
@@ -667,6 +713,7 @@
/**
* boilerplate
*/
+ @Override
public boolean equals(Object other) {
try {
XPathParts that = (XPathParts) other;
@@ -682,9 +729,16 @@
}
}
+ @Override
+ public int compareTo(XPathParts that) {
+ return dtdData.getDtdComparator().xpathComparator(this, that);
+ }
+
+
/**
* boilerplate
*/
+ @Override
public int hashCode() {
int result = elements.size();
for (int i = 0; i < elements.size(); ++i) {
@@ -702,8 +756,7 @@
public static final int XPATH_STYLE = 0, XML_OPEN = 1, XML_CLOSE = 2, XML_NO_VALUE = 3;
public static final String NEWLINE = "\n";
- private final class Element implements Cloneable, Freezable<Element> {
- private volatile boolean frozen;
+ private final class Element {
private final String element;
private Map<String, String> attributes; // = new TreeMap(AttributeComparator);
@@ -716,22 +769,15 @@
}
public Element(String element, Map<String, String> attributes) {
- this.frozen = false;
this.element = element.intern(); // allow fast comparison
if (attributes == null) {
this.attributes = null;
} else {
- this.attributes = new TreeMap<String, String>(getAttributeComparator());
+ this.attributes = new TreeMap<>(getAttributeComparator());
this.attributes.putAll(attributes);
}
}
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return frozen ? this
- : new Element(element, attributes);
- }
-
/**
* Add the given attribute, value pair to this Element object; or,
* if value is null, remove the attribute.
@@ -741,9 +787,6 @@
*/
public void putAttribute(String attribute, String value) {
attribute = attribute.intern(); // allow fast comparison
- if (frozen) {
- throw new UnsupportedOperationException("Can't modify frozen object.");
- }
if (value == null) {
if (attributes != null) {
attributes.remove(attribute);
@@ -753,7 +796,7 @@
}
} else {
if (attributes == null) {
- attributes = new TreeMap<String, String>(getAttributeComparator());
+ attributes = new TreeMap<>(getAttributeComparator());
}
attributes.put(attribute, value);
}
@@ -765,9 +808,6 @@
* @param attributeNames
*/
private void removeAttributes(Collection<String> attributeNames) {
- if (frozen) {
- throw new UnsupportedOperationException("Can't modify frozen object.");
- }
if (attributeNames == null) {
return;
}
@@ -779,6 +819,7 @@
}
}
+ @Override
public String toString() {
throw new IllegalArgumentException("Don't use");
}
@@ -864,7 +905,7 @@
* @param attribute
* @param value
* @return true to skip, else false
- *
+ *
* Called only by writeAttributes
*
* Assume suppressionMap isn't null.
@@ -887,6 +928,7 @@
return skip;
}
+ @Override
public boolean equals(Object other) {
if (other == null) {
return false;
@@ -903,6 +945,7 @@
}
}
+ @Override
public int hashCode() {
return element.hashCode() * 37 + (attributes == null ? 0 : attributes.hashCode());
}
@@ -920,9 +963,9 @@
private Map<String, String> getAttributes() {
if (attributes == null) {
- return Collections.emptyMap();
+ return ImmutableMap.of();
}
- return Collections.unmodifiableMap(attributes);
+ return ImmutableMap.copyOf(attributes);
}
private String getAttributeValue(String attribute) {
@@ -932,22 +975,14 @@
return attributes.get(attribute);
}
- @Override
- public boolean isFrozen() {
- return frozen;
- }
-
- @Override
- public Element freeze() {
- if (!frozen) {
- attributes = attributes == null ? null
- : Collections.unmodifiableMap(attributes);
- frozen = true;
+ public Element makeImmutable() {
+ if (attributes != null && !(attributes instanceof ImmutableMap)) {
+ attributes = ImmutableMap.copyOf(attributes);
}
+
return this;
}
- @Override
public Element cloneAsThawed() {
return new Element(element, attributes);
}
@@ -975,7 +1010,7 @@
* Get the MapComparator for this XPathParts.
*
* @return the MapComparator, or null
- *
+ *
* Called by the Element constructor, and by putAttribute
*/
private MapComparator<String> getAttributeComparator() {
@@ -1020,33 +1055,35 @@
if (frozen) {
throw new UnsupportedOperationException("Can't modify frozen Element");
}
+ makeElementsMutable();
elements.remove(elements.size() - 1);
return this;
}
/**
* Replace the elements of this XPathParts with clones of the elements of the given other XPathParts
- *
+ *
* @param parts the given other XPathParts (not modified)
* @return this XPathParts (modified)
*
* Called by XPathParts.replace and CldrItem.split.
*/
- public XPathParts set(XPathParts parts) {
- if (frozen) {
- throw new UnsupportedOperationException("Can't modify frozen Element");
- }
- try {
- dtdData = parts.dtdData;
- elements.clear();
- for (Element element : parts.elements) {
- elements.add((Element) element.clone());
- }
- return this;
- } catch (CloneNotSupportedException e) {
- throw (InternalError) new InternalError().initCause(e);
- }
- }
+// If this is restored, it will need to be modified.
+// public XPathParts set(XPathParts parts) {
+// if (frozen) {
+// throw new UnsupportedOperationException("Can't modify frozen Element");
+// }
+// try {
+// dtdData = parts.dtdData;
+// elements.clear();
+// for (Element element : parts.elements) {
+// elements.add((Element) element.clone());
+// }
+// return this;
+// } catch (CloneNotSupportedException e) {
+// throw (InternalError) new InternalError().initCause(e);
+// }
+// }
/**
* Replace up to i with parts
@@ -1054,18 +1091,19 @@
* @param i
* @param parts
*/
- public XPathParts replace(int i, XPathParts parts) {
- if (frozen) {
- throw new UnsupportedOperationException("Can't modify frozen Element");
- }
- List<Element> temp = elements;
- elements = new ArrayList<Element>();
- set(parts);
- for (; i < temp.size(); ++i) {
- elements.add(temp.get(i));
- }
- return this;
- }
+// If this is restored, it will need to be modified.
+// public XPathParts replace(int i, XPathParts parts) {
+// if (frozen) {
+// throw new UnsupportedOperationException("Can't modify frozen Element");
+// }
+// List<Element> temp = elements;
+// elements = new ArrayList<>();
+// set(parts);
+// for (; i < temp.size(); ++i) {
+// elements.add(temp.get(i));
+// }
+// return this;
+// }
/**
* Utility to write a comment.
@@ -1156,7 +1194,7 @@
*/
public XPathParts setAttribute(String elementName, String attributeName, String attributeValue) {
int index = findElement(elementName);
- elements.get(index).putAttribute(attributeName, attributeValue);
+ putAttributeValue(index, attributeName, attributeValue);
return this;
}
@@ -1176,11 +1214,11 @@
if (pos < 0) break;
if (pos > 0 && attributeValue.charAt(pos - 1) == '-') --pos; // backup for "...-proposed"
if (pos == 0) {
- element.putAttribute(attribute, null);
+ putAttributeValue(i, attribute, null);
break;
}
attributeValue = attributeValue.substring(0, pos); // strip it off
- element.putAttribute(attribute, attributeValue);
+ putAttributeValue(i, attribute, attributeValue);
break; // there is only one alt!
}
}
@@ -1188,6 +1226,7 @@
}
public XPathParts setElement(int elementIndex, String newElement) {
+ makeElementsMutable();
if (elementIndex < 0) {
elementIndex += size();
}
@@ -1197,6 +1236,7 @@
}
public XPathParts removeElement(int elementIndex) {
+ makeElementsMutable();
elements.remove(elementIndex >= 0 ? elementIndex : elementIndex + size());
return this;
}
@@ -1211,9 +1251,9 @@
return null;
}
- public void setAttribute(int elementIndex, String attributeName, String attributeValue) {
- Element element = elements.get(elementIndex >= 0 ? elementIndex : elementIndex + size());
- element.putAttribute(attributeName, attributeValue);
+ public XPathParts setAttribute(int elementIndex, String attributeName, String attributeValue) {
+ putAttributeValue(elementIndex, attributeName, attributeValue);
+ return this;
}
@Override
@@ -1227,9 +1267,9 @@
// ensure that it can't be modified. Later we can fix all the call sites to check frozen.
List<Element> temp = new ArrayList<>(elements.size());
for (Element element : elements) {
- temp.add(element.freeze());
+ temp.add(element.makeImmutable());
}
- elements = Collections.unmodifiableList(temp);
+ elements = ImmutableList.copyOf(temp);
frozen = true;
}
return this;
@@ -1243,9 +1283,13 @@
* Reference: https://unicode.org/cldr/trac/ticket/12007
*/
xppClone.dtdData = this.dtdData;
- for (Element e : this.elements) {
- xppClone.elements.add(e.cloneAsThawed());
- }
+ if (!frozen) {
+ for (Element e : this.elements) {
+ xppClone.elements.add(e.cloneAsThawed());
+ }
+ } else {
+ xppClone.elements = this.elements;
+ }
return xppClone;
}
@@ -1258,10 +1302,6 @@
return result;
}
- public static XPathParts getInstance(String path) {
- return getFrozenInstance(path).cloneAsThawed();
- }
-
public DtdData getDtdData() {
return dtdData;
}
@@ -1287,7 +1327,7 @@
continue;
}
if (ueMap == null) {
- ueMap = new TreeMap<String, String>();
+ ueMap = new TreeMap<>();
}
ueMap.put(k, entry.getValue());
}
@@ -1296,15 +1336,15 @@
}
public static String getPathWithoutAlt(String xpath) {
- XPathParts xpp = getInstance(xpath);
+ XPathParts xpp = getFrozenInstance(xpath).cloneAsThawed();
xpp.removeAttribute("alt");
return xpp.toString();
}
private XPathParts removeAttribute(String attribute) {
for (int i = 0; i < elements.size(); ++i) {
- elements.get(i).putAttribute(attribute, null);
+ putAttributeValue(i, attribute, null);
}
- return this;
+ return this;
}
}
diff --git a/tools/java/org/unicode/cldr/util/ZoneFormats.java b/tools/java/org/unicode/cldr/util/ZoneFormats.java
index 7301c96..e41aef6 100644
--- a/tools/java/org/unicode/cldr/util/ZoneFormats.java
+++ b/tools/java/org/unicode/cldr/util/ZoneFormats.java
@@ -15,6 +15,7 @@
public enum Length {
LONG, SHORT;
+ @Override
public String toString() {
return name().toLowerCase(Locale.ENGLISH);
}
diff --git a/tools/java/org/unicode/cldr/util/ZoneInflections.java b/tools/java/org/unicode/cldr/util/ZoneInflections.java
index 24de380..03e5ed2 100644
--- a/tools/java/org/unicode/cldr/util/ZoneInflections.java
+++ b/tools/java/org/unicode/cldr/util/ZoneInflections.java
@@ -54,7 +54,7 @@
private int maxOffset;
// ordered most recently first
- List<InflectionPoint> inflectionPoints = new ArrayList<InflectionPoint>();
+ List<InflectionPoint> inflectionPoints = new ArrayList<>();
public int getMaxOffset() {
return maxOffset;
@@ -88,6 +88,7 @@
return (int) maxSoFar;
}
+ @Override
public String toString() {
return inflectionPoints.toString();
}
@@ -147,7 +148,7 @@
mostRecentDateTime.value = get(0).utcDateTime;
return 1;
}
- ZoneInflections that = (ZoneInflections) other;
+ ZoneInflections that = other;
int minLength = inflectionPoints.size();
if (minLength < that.inflectionPoints.size())
minLength = that.inflectionPoints.size();
@@ -177,7 +178,7 @@
}
InflectionPoint get(int i) {
- return (InflectionPoint) inflectionPoints.get(i);
+ return inflectionPoints.get(i);
}
int size() {
@@ -186,6 +187,7 @@
private transient OutputLong temp = new OutputLong(0);
+ @Override
public int compareTo(ZoneInflections o) {
return compareTo(o, temp);
}
@@ -197,9 +199,10 @@
public int offset;
+ @Override
public String toString() {
return ICUServiceBuilder.isoDateFormat(new Date(utcDateTime)) + ";"
- + formatHours((int) offset);
+ + formatHours(offset);
}
public InflectionPoint(long utcDateTime, int offset) {
@@ -213,6 +216,7 @@
* offset != that.offset) { return Math.max(utcDateTime, that.utcDateTime); }
* return NONE; }
*/
+ @Override
public int compareTo(InflectionPoint that) {
if (utcDateTime < that.utcDateTime)
return -1;
@@ -245,6 +249,7 @@
this.value = value;
}
+ @Override
public int compareTo(Object o) {
OutputLong that = (OutputLong) o;
return value < that.value ? -1 : value > that.value ? 1 : 0;
@@ -261,7 +266,7 @@
* @return
*/
public List<InflectionPoint> getInflectionPoints(long start, long end) {
- List<InflectionPoint> results = new ArrayList<InflectionPoint>();
+ List<InflectionPoint> results = new ArrayList<>();
for (InflectionPoint inflectionPoint : inflectionPoints) {
if (inflectionPoint.utcDateTime <= start) {
results.add(new InflectionPoint(start, inflectionPoint.offset));
diff --git a/tools/java/org/unicode/cldr/util/ZoneParser.java b/tools/java/org/unicode/cldr/util/ZoneParser.java
index e087ae3..73a4f2d 100644
--- a/tools/java/org/unicode/cldr/util/ZoneParser.java
+++ b/tools/java/org/unicode/cldr/util/ZoneParser.java
@@ -66,16 +66,16 @@
*
*/
private void make_zone_to_country() {
- zone_to_country = new TreeMap<String, String>(TZIDComparator);
- country_to_zoneSet = new TreeMap<String, Set<String>>();
+ zone_to_country = new TreeMap<>(TZIDComparator);
+ country_to_zoneSet = new TreeMap<>();
// Map aliasMap = getAliasMap();
Map<String, List<String>> zoneData = getZoneData();
for (String zone : zoneData.keySet()) {
- String country = (String) zoneData.get(zone).get(2);
+ String country = zoneData.get(zone).get(2);
zone_to_country.put(zone, country);
Set<String> s = country_to_zoneSet.get(country);
if (s == null)
- country_to_zoneSet.put(country, s = new TreeSet<String>());
+ country_to_zoneSet.put(country, s = new TreeSet<>());
s.add(zone);
}
/*
@@ -117,7 +117,7 @@
Map<String, List<String>> zoneData;
- Set<String> skippedAliases = new TreeSet<String>();
+ Set<String> skippedAliases = new TreeSet<>();
/*
* # This file contains a table with the following columns: # 1. ISO 3166
@@ -184,6 +184,7 @@
return result;
}
+ @Override
public String toString() {
return BoilerplateUtilities.toStringHelper(this);
}
@@ -235,10 +236,12 @@
throw new IllegalArgumentException();
}
+ @Override
public String toString() {
return BoilerplateUtilities.toStringHelper(this);
}
+ @Override
public int compareTo(Object other) {
return toString().compareTo(other.toString());
}
@@ -336,16 +339,16 @@
*/
public static class RuleLine {
- public static Set<String> types = new TreeSet<String>();
- public static Set<Day> days = new TreeSet<Day>();
- static Set<Integer> saves = new TreeSet<Integer>();
+ public static Set<String> types = new TreeSet<>();
+ public static Set<Day> days = new TreeSet<>();
+ static Set<Integer> saves = new TreeSet<>();
RuleLine(List<String> l) {
fromYear = parseYear(l.get(0), 0);
toYear = parseYear(l.get(1), fromYear);
type = l.get(2);
if (type.equals("-")) type = null;
- month = 1 + findStartsWith((String) l.get(3), months, false);
+ month = 1 + findStartsWith(l.get(3), months, false);
day = new Day(l.get(4));
time = new Time(l.get(5));
save = Time.parseSeconds(l.get(6), true);
@@ -355,6 +358,7 @@
days.add(day);
}
+ @Override
public String toString() {
return BoilerplateUtilities.toStringHelper(this);
}
@@ -433,17 +437,17 @@
* continuation.
*/
public static class ZoneLine {
- public static Set<Day> untilDays = new TreeSet<Day>();
- public static Set<String> rulesSaves = new TreeSet<String>();
+ public static Set<Day> untilDays = new TreeSet<>();
+ public static Set<String> rulesSaves = new TreeSet<>();
ZoneLine(List<String> l) {
gmtOff = Time.parseSeconds(l.get(0), true);
- rulesSave = (String) l.get(1);
+ rulesSave = l.get(1);
if (rulesSave.equals("-"))
rulesSave = "0";
else if (rulesSave.charAt(0) < 'A') rulesSave = "" + Time.parseSeconds(rulesSave, false);
- format = (String) l.get(2);
+ format = l.get(2);
switch (l.size()) {
case 7:
untilTime = new Time(l.get(6)); // fall through
@@ -451,7 +455,7 @@
untilDay = new Day(l.get(5)); // fall through
untilDays.add(untilDay);
case 5:
- untilMonth = 1 + findStartsWith((String) l.get(4), months, false); // fall through
+ untilMonth = 1 + findStartsWith(l.get(4), months, false); // fall through
case 4:
untilYear = parseYear(l.get(3), Integer.MAX_VALUE); // fall through
case 3:
@@ -462,6 +466,7 @@
rulesSaves.add(rulesSave);
}
+ @Override
public String toString() {
return BoilerplateUtilities.toStringHelper(this);
}
@@ -487,13 +492,13 @@
public static final int FIELD_COUNT_UNTIL = 7; // excluding Zone, Name
}
- Map<String, List<RuleLine>> ruleID_rules = new TreeMap<String, List<RuleLine>>();
+ Map<String, List<RuleLine>> ruleID_rules = new TreeMap<>();
- Map<String, List<ZoneLine>> zone_rules = new TreeMap<String, List<ZoneLine>>();
+ Map<String, List<ZoneLine>> zone_rules = new TreeMap<>();
- Map<String, String> linkold_new = new TreeMap<String, String>();
+ Map<String, String> linkold_new = new TreeMap<>();
- Map<String, Set<String>> linkNew_oldSet = new TreeMap<String, Set<String>>();
+ Map<String, Set<String>> linkNew_oldSet = new TreeMap<>();
public class Transition {
public long date;
@@ -543,6 +548,7 @@
private Comparator<String> TZIDComparator = new Comparator<String>() {
Map<String, List<String>> data = getZoneData();
+ @Override
public int compare(String s1, String s2) {
List<String> data1 = data.get(s1);
if (data1 == null)
@@ -553,8 +559,8 @@
int result;
// country
- String country1 = (String) data1.get(2);
- String country2 = (String) data2.get(2);
+ String country1 = data1.get(2);
+ String country2 = data2.get(2);
if ((result = country1.compareTo(country2)) != 0)
return result;
@@ -573,7 +579,7 @@
}
};
- public static MapComparator<String> regionalCompare = new MapComparator<String>();
+ public static MapComparator<String> regionalCompare = new MapComparator<>();
static {
regionalCompare.add("America");
regionalCompare.add("Atlantic");
@@ -590,16 +596,16 @@
private static String[] TZFiles = { "africa", "antarctica", "asia",
"australasia", "backward", "etcetera", "europe", "northamerica",
- "pacificnew", "southamerica", "systemv" };
+ "southamerica" };
private static Map<String, String> FIX_UNSTABLE_TZIDS;
- private static Set<String> SKIP_LINKS = new HashSet<String>(Arrays.asList(
+ private static Set<String> SKIP_LINKS = new HashSet<>(Arrays.asList(
new String[] {
"America/Montreal", "America/Toronto",
"America/Santa_Isabel", "America/Tijuana" }));
- private static Set<String> PREFERRED_BASES = new HashSet<String>(Arrays.asList(new String[] { "Europe/London" }));
+ private static Set<String> PREFERRED_BASES = new HashSet<>(Arrays.asList(new String[] { "Europe/London" }));
private static String[][] ADD_ZONE_ALIASES_DATA = {
{ "Etc/UCT", "Etc/UTC" },
@@ -639,6 +645,7 @@
{ "America/Argentina/Cordoba", "America/Cordoba" },
{ "America/Argentina/Jujuy", "America/Jujuy" },
{ "America/Argentina/Mendoza", "America/Mendoza" },
+ { "America/Nuuk", "America/Godthab" },
{ "America/Kentucky/Louisville", "America/Louisville" },
{ "America/Indiana/Indianapolis", "America/Indianapolis" },
{ "Africa/Asmara", "Africa/Asmera" },
@@ -671,7 +678,7 @@
// String deg = "([+-][0-9]+)";//
String deg = "([+-])([0-9][0-9][0-9]?)([0-9][0-9])([0-9][0-9])?";//
Matcher m = PatternCache.get(deg + deg).matcher("");
- zoneData = new TreeMap<String, List<String>>();
+ zoneData = new TreeMap<>();
BufferedReader in = CldrUtility.getUTF8Data("zone.tab");
while (true) {
String line = in.readLine();
@@ -711,7 +718,7 @@
in.close();
// add Etcs
for (int i = -14; i <= 12; ++i) {
- List<String> pieces = new ArrayList<String>();
+ List<String> pieces = new ArrayList<>();
int latitude = 0;
int longitude = i * 15;
if (longitude <= -180) {
@@ -726,7 +733,7 @@
pieces);
}
// add Unknown / UTC
- List<String> pieces = new ArrayList<String>();
+ List<String> pieces = new ArrayList<>();
pieces.add(new Double(0).toString()); // lat
pieces.add(new Double(0).toString()); // long
pieces.add(StandardCodes.NO_COUNTRY); // country
@@ -737,7 +744,7 @@
// now get links
Pattern whitespace = PatternCache.get("\\s+");
- XEquivalenceClass<String, String> linkedItems = new XEquivalenceClass<String, String>("None");
+ XEquivalenceClass<String, String> linkedItems = new XEquivalenceClass<>("None");
for (int i = 0; i < TZFiles.length; ++i) {
in = CldrUtility.getUTF8Data(TZFiles[i]);
String zoneID = null;
@@ -757,22 +764,22 @@
continue;
String[] items = whitespace.split(line);
if (zoneID != null || items[0].equals("Zone")) {
- List<String> l = new ArrayList<String>();
+ List<String> l = new ArrayList<>();
l.addAll(Arrays.asList(items));
// Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01
// 0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
if (zoneID == null) {
l.remove(0); // "Zone"
- zoneID = (String) l.get(0);
- String ntzid = (String) FIX_UNSTABLE_TZIDS.get(zoneID);
+ zoneID = l.get(0);
+ String ntzid = FIX_UNSTABLE_TZIDS.get(zoneID);
if (ntzid != null)
zoneID = ntzid;
l.remove(0);
}
List<ZoneLine> zoneRules = zone_rules.get(zoneID);
if (zoneRules == null) {
- zoneRules = new ArrayList<ZoneLine>();
+ zoneRules = new ArrayList<>();
zone_rules.put(zoneID, zoneRules);
}
@@ -796,10 +803,10 @@
String ruleID = items[1];
List<RuleLine> ruleList = ruleID_rules.get(ruleID);
if (ruleList == null) {
- ruleList = new ArrayList<RuleLine>();
+ ruleList = new ArrayList<>();
ruleID_rules.put(ruleID, ruleList);
}
- List<String> l = new ArrayList<String>();
+ List<String> l = new ArrayList<>();
l.addAll(Arrays.asList(items));
l.remove(0);
l.remove(0);
@@ -845,7 +852,7 @@
// if any contains one, make it the primary
// if any contains zero, problem!
for (Set<String> equivalents : linkedItems.getEquivalenceSets()) {
- Set<String> canonicals = new TreeSet<String>(equivalents);
+ Set<String> canonicals = new TreeSet<>(equivalents);
canonicals.retainAll(isCanonical);
if (canonicals.size() == 0)
throw new IllegalArgumentException("No canonicals in: " + equivalents);
@@ -856,7 +863,7 @@
.println("\t*Don't* put these into the same equivalence class: "
+ canonicals);
}
- Set<String> remainder = new TreeSet<String>(equivalents);
+ Set<String> remainder = new TreeSet<>(equivalents);
remainder.removeAll(isCanonical);
if (remainder.size() != 0) {
if (DEBUG) {
@@ -871,7 +878,7 @@
// get the item that we want to hang all the aliases off of.
// normally this is the first (alphabetically) one, but
// it may be overridden with PREFERRED_BASES
- Set<String> preferredItems = new HashSet<String>(PREFERRED_BASES);
+ Set<String> preferredItems = new HashSet<>(PREFERRED_BASES);
preferredItems.retainAll(canonicals);
if (preferredItems.size() > 0) {
newOne = preferredItems.iterator().next();
@@ -923,7 +930,7 @@
String newZone = linkold_new.get(oldZone);
Set<String> s = linkNew_oldSet.get(newZone);
if (s == null)
- linkNew_oldSet.put(newZone, s = new HashSet<String>());
+ linkNew_oldSet.put(newZone, s = new HashSet<>());
s.add(oldZone);
}
diff --git a/tools/java/org/unicode/cldr/util/data/Locales.txt b/tools/java/org/unicode/cldr/util/data/Locales.txt
index 4f82d3a..8d5c6aa 100644
--- a/tools/java/org/unicode/cldr/util/data/Locales.txt
+++ b/tools/java/org/unicode/cldr/util/data/Locales.txt
@@ -305,10 +305,15 @@
Google ; sat ; basic ; Santali (Olck script)
Google ; kok ; basic ; Konkani
Google ; su ; basic ; Sundanese (script TBD)
-Google ; gn ; basic ; Guarani (Bengali script)
+# Google ; gn ; basic ; Guarani (Bengali script)
Google ; sd_Deva ; basic ; Sindhi (Devanagari script)
Google ; mai ; basic ; Maithili (Devanagari script)
+Google ; nn ; Moderate ; Nynorsk
+Google ; sa ; basic ; Sanskrit
+Google ; doi ; basic ; Dogri
+#Google ; nv ; basic ; Navajo
+
#Google Tier TR
Google ; es_US ; modern ; TR Spanish (United States)
Google ; es_MX ; modern ; TR Spanish (Mexico)
@@ -445,6 +450,10 @@
Apple ; ug ; basic
Apple ; yi ; basic
+Apple ; sa ; basic ; Sanskrit
+Apple ; doi ; basic ; Dogri
+#Apple ; nv ; basic ; Navajo
+
Adobe ; ar ; basic
Adobe ; az ; basic
Adobe ; be ; moderate
@@ -636,11 +645,15 @@
Cldr ; sat ; basic ; Santali (Olck script)
Cldr ; kok ; basic ; Konkani
Cldr ; su ; basic ; Sundanese (script TBD)
-Cldr ; gn ; basic ; Guarani (Bengali script)
+# Cldr ; gn ; basic ; Guarani (Bengali script)
Cldr ; sd_Deva ; basic ; Sindhi (Devanagari script)
-Cldr ; cad ; basic ; Caddo
+# Cldr ; cad ; basic ; Caddo
Cldr ; pcm ; basic ; Nigerian Pidgin
+Cldr ; nn ; Moderate ; Nynorsk
+Cldr ; sa ; basic ; Sanskrit
+Cldr ; doi ; basic ; Dogri
+#Cldr ; nv ; basic ; Navajo
Bangor_Univ ; cy ; modern ; Welsh
Bangor_Univ ; * ; moderate ; All others
@@ -811,6 +824,12 @@
Microsoft ; wo ; basic
Microsoft ; yo ; basic
+Microsoft ; nn ; Moderate ; Nynorsk
+Microsoft ; sa ; basic ; Sanskrit
+Microsoft ; doi ; basic ; Dogri
+#Microsoft ; nv ; basic ; Navajo
+
+
Pakistan ; ur ; modern ; Urdu
Pakistan ; * ; modern ; All others
@@ -886,3 +905,6 @@
Facebook ; pt_PT ; modern
Mozilla ; en ; modern
+
+Rodakych ; pcm ; modern ; Nigerian Pidgin
+Rodakych ; * ; moderate ; All Others
diff --git a/tools/java/org/unicode/cldr/util/data/PathDescription.txt b/tools/java/org/unicode/cldr/util/data/PathDescription.txt
index 0e4df8f..2b2ff5b 100644
--- a/tools/java/org/unicode/cldr/util/data/PathDescription.txt
+++ b/tools/java/org/unicode/cldr/util/data/PathDescription.txt
@@ -103,6 +103,8 @@
^//ldml/numbers/minimalPairs/ordinalMinimalPairs\[@ordinal="([^"]*)"] ; Minimal pairs for ordinals. For more information, please see http://cldr.org/translation/getting-started/plurals#TOC-Minimal-Pairs.
^//ldml/numbers/minimalPairs/pluralMinimalPairs\[@count="([^"]*)"] ; Minimal pairs for plurals (cardinals). For more information, please see http://cldr.org/translation/getting-started/plurals#TOC-Minimal-Pairs.
+^//ldml/numbers/minimalPairs/caseMinimalPairs\[@case="([^"]*)"] ; Minimal pairs for cases used in the language. For more information, please see http://cldr.unicode.org/translation/grammatical-inflection.
+^//ldml/numbers/minimalPairs/genderMinimalPairs\[@gender="([^"]*)"] ; Minimal pairs for genders. For more information, please see http://cldr.unicode.org/translation/grammatical-inflection .
^//ldml/numbers/([a-z]*)Formats(\[@numberSystem="([^"]*)"])?/\1FormatLength/\1Format\[@type="standard"]/pattern\[@type="standard"]$ ; Special pattern used to compose {1} numbers. Note: before translating, be sure to read http://cldr.org/translation/numbers-currency/number-patterns.
^//ldml/numbers/currencyFormats\[@numberSystem="([^"]*)"]/currencyFormatLength/currencyFormat\[@type="accounting"]/pattern ; Special pattern used to compose currency values for accounting purposes. Note: before translating, be sure to read http://cldr.org/translation/numbers-currency/number-patterns.
diff --git a/tools/java/org/unicode/cldr/util/data/PathHeader.txt b/tools/java/org/unicode/cldr/util/data/PathHeader.txt
index ece6edc..5ba0133 100644
--- a/tools/java/org/unicode/cldr/util/data/PathHeader.txt
+++ b/tools/java/org/unicode/cldr/util/data/PathHeader.txt
@@ -90,6 +90,8 @@
//ldml/dates/calendars/calendar[@type="gregorian"]/dayPeriods/dayPeriodContext[@type="%A"]/dayPeriodWidth[@type="%A"]/dayPeriod[@type="%A"] ; DateTime ; &calendar(gregorian) ; &calField(DayPeriods:$2:$1) ; &dayPeriod($3)
//ldml/dates/calendars/calendar[@type="%A"]/dayPeriods/dayPeriodContext[@type="%A"]/dayPeriodWidth[@type="%A"]/dayPeriod[@type="%A"] ; Special ; Suppress ; &calendar($1) ; &calField(DayPeriods:$3:$2)-&dayPeriod($4) ; HIDE
+//ldml/dates/calendars/calendar[@type="%N"]/dateFormats/dateFormatLength[@type="%A"]/dateFormat[@type="%A"]/pattern[@type="%A"][@count="%A"] ; DateTime ; &calendar($1) ; &calField(Formats:Standard:date) ; $2-$5 ; LTR_ALWAYS
+//ldml/dates/calendars/calendar[@type="%A"]/dateFormats/dateFormatLength[@type="%A"]/dateFormat[@type="%A"]/pattern[@type="%A"][@count="%A"] ; Special ; Suppress ; &calendar($1) ; &calField(Formats:Standard:date)-$2 ; HIDE
//ldml/dates/calendars/calendar[@type="%N"]/dateFormats/dateFormatLength[@type="%A"]/dateFormat[@type="%A"]/pattern[@type="%A"] ; DateTime ; &calendar($1) ; &calField(Formats:Standard:date) ; $2 ; LTR_ALWAYS
//ldml/dates/calendars/calendar[@type="%A"]/dateFormats/dateFormatLength[@type="%A"]/dateFormat[@type="%A"]/pattern[@type="%A"] ; Special ; Suppress ; &calendar($1) ; &calField(Formats:Standard:date)-$2 ; HIDE
@@ -107,6 +109,7 @@
//ldml/dates/calendars/calendar[@type="chinese"]/dateTimeFormats/availableFormats/dateFormatItem[@id="(E*[Hms]%a)"] ; DateTime ; &calendar(chinese); &calField(Formats:Flexible:time24) ; $1 ; LTR_ALWAYS
//ldml/dates/calendars/calendar[@type="gregorian"]/dateTimeFormats/availableFormats/dateFormatItem[@id="%A"][@count="%A"] ; DateTime ; &calendar(gregorian); &calField(Formats:Flexible:date) ; $1-$2 ; LTR_ALWAYS
//ldml/dates/calendars/calendar[@type="%N"]/dateTimeFormats/availableFormats/dateFormatItem[@id="(?![^"]*[hHms])%A"] ; DateTime ; &calendar($1); &calField(Formats:Flexible:date) ; $2 ; LTR_ALWAYS
+//ldml/dates/calendars/calendar[@type="%A"]/dateTimeFormats/availableFormats/dateFormatItem[@id="%A"][@count="%A"] ; Special ; Suppress ; &calendar($1); &calField(Formats:Flexible:date)-$2-$3 ; HIDE
//ldml/dates/calendars/calendar[@type="%A"]/dateTimeFormats/availableFormats/dateFormatItem[@id="%A"] ; Special ; Suppress ; &calendar($1); &calField(Formats:Flexible:date)-$2 ; HIDE
//ldml/dates/calendars/calendar[@type="gregorian"]/dateTimeFormats/appendItems/appendItem[@request="(Timezone)"] ; DateTime ; &calendar(gregorian) ; &calField(Formats:Flexible:Append) ; $1 ; LTR_ALWAYS
@@ -148,9 +151,6 @@
//ldml/numbers/currencyFormats[@numberSystem="%A"]/unitPattern[@count="%A"] ; Numbers ; Number Formatting Patterns ; Currency Unit Patterns &numberingSystem($1) ; &count(currencies-$2) ; LTR_ALWAYS
//ldml/numbers/miscPatterns[@numberSystem="%A"]/pattern[@type=\"%A\"] ; Numbers ; Number Formatting Patterns ; Miscellaneous Patterns &numberingSystem($1) ; $2 ; LTR_ALWAYS
-//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal=\"%A\"] ; Numbers ; Minimal Pairs ; Ordinal ; $1 ; LTR_ALWAYS
-//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"%A\"] ; Numbers ; Minimal Pairs ; Plural ; $1 ; LTR_ALWAYS
-
//ldml/numbers/(currency)Formats[@numberSystem="latn"]/%EFormatLength[@type="(short)"]/%EFormat[@type="%A"]/pattern[@type="%A"][@count="%A"] ; Numbers ; Compact Decimal Formatting ; Short Currency &numberingSystem(latn); &count2($6-digits-$3-$7)
//ldml/numbers/(currency)Formats[@numberSystem="%A"]/%EFormatLength[@type="(short)"]/%EFormat[@type="%A"]/pattern[@type="%A"][@count="%A"] ; Numbers ; Compact Decimal Formatting (Other Numbering Systems) ; Short Currency &numberingSystem($2) ; &count2($7-digits-$4-$8) ; HIDE
//ldml/numbers/%EFormats[@numberSystem="latn"]/%EFormatLength[@type="(long)"]/%EFormat[@type="%A"]/pattern[@type="%A"][@count="%A"] ; Numbers ; Compact Decimal Formatting ; Long Formats &numberingSystem(latn) ; &count2($6-digits-$3-$7)
@@ -160,8 +160,8 @@
### Currencies
-//ldml/numbers/currencies/currency[@type="%A"]/displayName$ ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; &count($1-name)
//ldml/numbers/currencies/currency[@type="%A"]/displayName[@count="%A"] ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; &count($1-name-$2)
+//ldml/numbers/currencies/currency[@type="%A"]/displayName$ ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; &count($1-name)
//ldml/numbers/currencies/currency[@type="%A"]/symbol$ ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; ¤cySymbol($1-symbol)
//ldml/numbers/currencies/currency[@type="%A"]/symbol[@alt="narrow"] ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; ¤cySymbol($1-symbol-narrow)
//ldml/numbers/currencies/currency[@type="%A"]/symbol[@alt="variant"] ; Currencies ; &continentFromCurrency($1) ; &categoryFromCurrency($1) ; ¤cySymbol($1-symbol-variant)
@@ -175,61 +175,90 @@
//ldml/localeDisplayNames/measurementSystemNames/measurementSystemName[@type="%A"] ; Units ; Measurement Systems ; null ; $1
//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/displayName ; Units ; Duration ; &datefield($2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/unitPattern[@count="%A"] ; Units ; Duration ; &datefield($2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/gender ; Units ; Duration ; &datefield($2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Duration ; &datefield($2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/unitPattern[@count="%A"] ; Units ; Duration ; &datefield($2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="duration-%A"]/perUnitPattern ; Units ; Duration ; &datefield($2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/displayName ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/unitPattern[@count="%A"] ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/gender ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/unitPattern[@count="%A"] ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="graphics-%A"]/perUnitPattern ; Units ; Graphics ; &unit(length-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/displayName ; Units ; Length ; &unit(length-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/unitPattern[@count="%A"] ; Units ; Length ; &unit(length-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/gender ; Units ; Length ; &unit(length-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Length ; &unit(length-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/unitPattern[@count="%A"] ; Units ; Length ; &unit(length-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="length-%A"]/perUnitPattern ; Units ; Length ; &unit(length-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/displayName ; Units ; Area ; &unit(area-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/unitPattern[@count="%A"] ; Units ; Area ; &unit(area-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/gender ; Units ; Area ; &unit(area-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Area ; &unit(area-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/unitPattern[@count="%A"] ; Units ; Area ; &unit(area-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="area-%A"]/perUnitPattern ; Units ; Area ; &unit(area-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/displayName ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/unitPattern[@count="%A"] ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/gender ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/unitPattern[@count="%A"] ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="volume-%A"]/perUnitPattern ; Units ; Volume ; &unit(volume-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/displayName ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/unitPattern[@count="%A"] ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/gender ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-$4-$5)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/unitPattern[@count="%A"] ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-$4-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="%V-%A"]/perUnitPattern ; Units ; Speed and Acceleration ; &unit($2-$3) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/displayName ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/unitPattern[@count="%A"] ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/gender ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/unitPattern[@count="%A"] ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="mass-%A"]/perUnitPattern ; Units ; Mass and Weight ; &unit(mass-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/displayName ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/unitPattern[@count="%A"] ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/gender ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-$4-$5)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/unitPattern[@count="%A"] ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-$4-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="%X-%A"]/perUnitPattern ; Units ; Energy and Power ; &unit($2-$3) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/displayName ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/unitPattern[@count="%A"] ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/gender ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-$4-$5)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/unitPattern[@count="%A"] ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-$4-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="%F-%A"]/perUnitPattern ; Units ; Electrical and Frequency ; &unit($2-$3) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/displayName ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/unitPattern[@count="%A"] ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/gender ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-$4-$5)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/unitPattern[@count="%A"] ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-$4-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="%W-%A"]/perUnitPattern ; Units ; Weather ; &unit($2-$3) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/displayName ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/unitPattern[@count="%A"] ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/gender ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/unitPattern[@count="%A"] ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="digital-%A"]/perUnitPattern ; Units ; Digital ; &unit(digital-$2) ; &unitCount($1-per)
//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/displayName ; Units ; Other Units ; &unit($2) ; &unitCount($1-displayName)
-//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/unitPattern[@count="%A"] ; Units ; Other Units ; &unit($2) ; &unitCount($1-$3)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/gender ; Units ; Other Units ; &unit($2) ; &unitCount($1-gender)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/unitPattern[@count="%A"][@case="%A"] ; Units ; Other Units ; &unit($2) ; &unitCount($1-$3-$4)
+//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/unitPattern[@count="%A"] ; Units ; Other Units ; &unit($2) ; &unitCount($1-$3-nominative)
//ldml/units/unitLength[@type="%L"]/unit[@type="%A"]/perUnitPattern ; Units ; Other Units ; &unit($2) ; &unitCount($1-per)
# Warning: the longer match must come first
-//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1[@count="%A"] ; Units ; Compound Units ; $2 ; &unitCount($1-$3)
-//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1 ; Units ; Compound Units ; $2 ; $1
+//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1[@count="%A"][@gender="%A"][@case="%A"] ; Units ; Compound Units ; $2 ; &unitCount($1-$3-$5-$4)
+//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1[@count="%A"][@case="%A"] ; Units ; Compound Units ; $2 ; &unitCount($1-$3-$4-dgender)
+//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1[@count="%A"][@gender="%A"] ; Units ; Compound Units ; $2 ; &unitCount($1-$3-nominative-$4)
+//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1[@count="%A"] ; Units ; Compound Units ; $2 ; &unitCount($1-$3-nominative-dgender)
+//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern1 ; Special ; Suppress ; compound-UnitPattern1-$2 ; &unitCount($1) ; HIDE
+
//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/compoundUnitPattern ; Units ; Compound Units ; $2 ; $1
//ldml/units/unitLength[@type="%L"]/compoundUnit[@type="%A"]/unitPrefixPattern ; Units ; Compound Units ; $2 ; $1
//ldml/units/durationUnit[@type="(hms|hm|ms)"] ; Units ; Duration ; Duration Patterns ; $1
//ldml/units/unitLength[@type="%L"]/coordinateUnit/displayName ; Units ; Coordinates ; all ; &unitCount($1-displayName)
+//ldml/units/unitLength[@type="%L"]/coordinateUnit/gender ; Units ; Coordinates ; all ; &unitCount($1-gender)
//ldml/units/unitLength[@type="%L"]/coordinateUnit/coordinateUnitPattern[@type="%A"] ; Units ; Coordinates ; $2 ; &unitCount($1)
### Miscellaneous
@@ -246,9 +275,10 @@
//ldml/localeDisplayNames/transformNames/transformName[@type="%A"] ; Misc ; Transforms ; null ; $1
-//ldml/typographicNames/axisName[@type="%A"] ; Characters ; Typography ; Axis ; $1
-//ldml/typographicNames/styleName[@type="%A"][@subtype="%A"] ; Characters ; Typography; Style ; $1-$2
-//ldml/typographicNames/featureName[@type="%A"] ; Characters ; Typography ; Feature ; $1
+//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal=\"%A\"] ; Misc ; Minimal Pairs ; Ordinal ; $1 ; LTR_ALWAYS
+//ldml/numbers/minimalPairs/pluralMinimalPairs[@count=\"%A\"] ; Misc ; Minimal Pairs ; Plural ; $1 ; LTR_ALWAYS
+//ldml/numbers/minimalPairs/caseMinimalPairs[@case=\"%A\"] ; Misc ; Minimal Pairs ; Case ; $1 ; LTR_ALWAYS
+//ldml/numbers/minimalPairs/genderMinimalPairs[@gender=\"%A\"] ; Misc ; Minimal Pairs ; Gender ; $1 ; LTR_ALWAYS
#Emoji, etc.
@@ -262,6 +292,11 @@
//ldml/annotations/annotation[@cp="%A"][@type="tts"] ; Characters ; &major($1) ; &minor($1) ; &emoji($1 -name)
//ldml/annotations/annotation[@cp="%A"] ; Characters ; &major($1) ; &minor($1) ; &emoji($1 –keywords)
+//ldml/typographicNames/axisName[@type="%A"] ; Characters ; Typography ; Axis ; $1
+//ldml/typographicNames/styleName[@type="%A"][@subtype="%A"] ; Characters ; Typography; Style ; $1-$2
+//ldml/typographicNames/featureName[@type="%A"] ; Characters ; Typography ; Feature ; $1
+
+
#OLD
//ldml/annotations/annotation_[@cp="%A"]/_tts ; Characters ; Annotation ; $1 ; TTS ; HIDE
@@ -312,6 +347,8 @@
//ldml/dates/calendars/calendar[@type="%A"]/fields/field[@type="%A"]/%E[@type="%A"] ; Special ; Deprecated ; $1 ; $1-$2-$3-$4 ; HIDE
//ldml/dates/calendars/calendar[@type="%A"]/fields/field[@type="%A"] ; Special ; Deprecated ; $1 ; $1-$2 ; HIDE
+//ldml/metadata/casingData/casingItem[@type="%A"]; Special ; Suppress ; Casing ; $1 ; HIDE
+
# Ultimate fallback (Error)
//ldml/%S/(.*) ; Special ; Unknown ; $1 ; $2 ; DEPRECATED
//ldml/(.*) ; Special ; Unknown ; Unknown ; $2 ; DEPRECATED
@@ -361,6 +398,7 @@
//supplementalData/transforms/transform[@source="%A"][@target="%A"][@direction="%A"]/%E ; Supplemental ; Transform ; &transform($3,$1,$2) ; $4 ; HIDE
//supplementalData/transforms/transform[@source="%A"][@target="%A"][@variant="%A"][@direction="%A"]/%E ; Supplemental ; Transform ; &transform($4,$1,$2,$3) ; $5 ; HIDE
+//supplementalData/transforms/transform[@source="%A"][@target="%A"] ; Supplemental ; Transform ; &transform("?",$1,$2) ; ? ; HIDE
//supplementalData/territoryInfo/territory[@type="%A"]/languagePopulation[@type="%A"]/_%E ; Supplemental ; LanguageInfo ; $1/$2 ; $3 ; HIDE
//supplementalData/territoryInfo/territory[@type="%A"]/_%E ; Supplemental ; TerritoryInfo ; $1 ; $2 ; HIDE
@@ -421,10 +459,17 @@
//supplementalData/dayPeriodRuleSet[@type="%A"]/dayPeriodRules[@locales="%A"]/dayPeriodRule[@type="%A"]/_%E ; Supplemental ; DayPeriod ; $1-$2 ; $3-$4 ; HIDE
//supplementalData/dayPeriodRuleSet/dayPeriodRules[@locales="%A"]/dayPeriodRule[@type="%A"]/_%E ; Supplemental ; DayPeriod ; $1 ; $2-$3 ; HIDE
+//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalCase[@scope="%A"]/_values ; Supplemental ; Grammar ; Case ; $1-$2-$3 ; HIDE
+//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalDefiniteness[@scope="%A"]/_values ; Supplemental ; Grammar ; Definiteness ; $1-$2-$3 ; HIDE
+//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalGender[@scope="%A"]/_values ; Supplemental ; Grammar ; Gender ; $1-$2-$3 ; HIDE
+
//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalCase/_values ; Supplemental ; Grammar ; Case ; $1-$2 ; HIDE
//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalDefiniteness/_values ; Supplemental ; Grammar ; Definiteness ; $1-$2 ; HIDE
//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalGender/_values ; Supplemental ; Grammar ; Gender ; $1-$2 ; HIDE
-//supplementalData/grammaticalData/grammaticalFeatures[@targets="%A"][@locales="%A"]/grammaticalState/_values ; Supplemental ; Grammar ; State ; $1-$2 ; HIDE
+
+//supplementalData/grammaticalData/grammaticalDerivations[@locales="%A"]/deriveCompound[@feature="%A"][@structure="%A"]/_value ; Supplemental ; Grammar ; deriveCompound ; $1-$2-$3 ; HIDE
+//supplementalData/grammaticalData/grammaticalDerivations[@locales="%A"]/deriveComponent[@feature="%A"][@structure="%A"]/_value0 ; Supplemental ; Grammar ; deriveComponent ; $1-$2-$3-arg0 ; HIDE
+//supplementalData/grammaticalData/grammaticalDerivations[@locales="%A"]/deriveComponent[@feature="%A"][@structure="%A"]/_value1 ; Supplemental ; Grammar ; deriveComponent ; $1-$2-$3-arg1 ; HIDE
//supplementalData/unitPreferenceData/unitPreferences[@category="%A"][@usage="%A"]/unitPreference_[@regions="%A"][@geq="%A"]/_skeleton ; Supplemental ; Units ; $1/$2 ; $3:$4-skeleton ; HIDE
//supplementalData/unitPreferenceData/unitPreferences[@category="%A"][@usage="%A"]/unitPreference_[@regions="%A"]/_skeleton ; Supplemental ; Units ; $1/$2 ; $3-skeleton ; HIDE
diff --git a/tools/java/org/unicode/cldr/util/data/Placeholders.txt b/tools/java/org/unicode/cldr/util/data/Placeholders.txt
index 98bf568..c21e628 100644
--- a/tools/java/org/unicode/cldr/util/data/Placeholders.txt
+++ b/tools/java/org/unicode/cldr/util/data/Placeholders.txt
@@ -1,10 +1,9 @@
#Remember to quote any [ character!
# The default is DISALLOWED for anything not in this file.
-# The default for everything in this file is REQUIRED.
-# That default is overridden if the line has as the X parameter: locale, optional, or multiple.
-# optional: there may or may not be a placeholder.
-# locale: there is a count= or ordinal=, so the value is subject to the locale.
-# multiple: there may be one or more placeholders (normally only in minimalPairs)
+# The default for everything in this file is REQUIRED, meaning that the number of placeholders has to match the number in the final field.
+# That default is overridden if the line has as the X parameter: locale or multiple.
+# locale: there is a count= or ordinal=, so the value is subject to the locale; may be zero or one.
+# multiple: there may be zero or more placeholders (normally only in count or ordinal minimalPairs)
%A = [^"]*+
%L = (long|short|narrow)
@@ -209,7 +208,9 @@
^//ldml/numbers/miscPatterns\[@numberSystem="%A"]/pattern\[@type=\"%A\"] ; {0}=NUMBER 3
^//ldml/numbers/minimalPairs/ordinalMinimalPairs[@ordinal="%A"] ; multiple ; {0}=COUNT 3
-^//ldml/numbers/minimalPairs/pluralMinimalPairs[@count="%A"] ; multiple ; {0}=COUNT 3
+^//ldml/numbers/minimalPairs/pluralMinimalPairs[@count="%A"] ; multiple ; {0}=COUNT 3
+^//ldml/numbers/minimalPairs/caseMinimalPairs[@case="%A"] ; {0}=CASE ‹noun phrase in this case›
+^//ldml/numbers/minimalPairs/genderMinimalPairs[@gender="%A"] ; {0}=GENDER ‹noun phrase in this gender›
# Warning: the longer match must come first
^//ldml/units/unitLength\[@type="%L"]/compoundUnit\[@type="%A"]/compoundUnitPattern1 ; {0}=POWER UNIT meters
diff --git a/tools/java/org/unicode/cldr/util/data/SpecialLocales.txt b/tools/java/org/unicode/cldr/util/data/SpecialLocales.txt
index f851594..d308c00 100644
--- a/tools/java/org/unicode/cldr/util/data/SpecialLocales.txt
+++ b/tools/java/org/unicode/cldr/util/data/SpecialLocales.txt
@@ -12,12 +12,14 @@
#
# comment is freeform text and may be presented to end users. Use the form " @de_CH " to refer to the locale de_CH
# and "@@" to refer to the actual locale (in the case of * wildcards)
+#
+# Note: Also, see CLDRFileTransformer.java which has the algorithmic locales defined
+# such as sr_Latn, etc. Those are no longer listed here.
+#
root ; readonly ; The Root locale is maintained by the CLDR-TC and may not be modified in the SurveyTool. Please file a ticket to make changes.
en ; readonly ; The English locale is maintained by the CLDR-TC and may not be modified in the SurveyTool. Please file a ticket to make changes.
en_ZZ ; readonly ; The en_ZZ locale is used for display purposes in the SurveyTool and may not be modified in the SurveyTool. Please file a ticket to make changes.
-sr_Latn* ; readonly ; @sr_Latn is generated from @sr_Cyrl via transliteration, and so @@ may not be edited directly. Edit @sr_Cyrl to make changes.
-yo_BJ* ; readonly ; @yo_BJ is generated from @yo via transliteration, and so @@ may not be edited directly. Edit @yo to make changes.
und ; scratch ; This locale is for testing purposes, it does not have any valid content.
und_ZZ ; scratch ; This locale is for testing purposes, it does not have any valid content.
diff --git a/tools/java/org/unicode/cldr/util/data/africa b/tools/java/org/unicode/cldr/util/data/africa
index 4028b0d..9f95f1b 100644
--- a/tools/java/org/unicode/cldr/util/data/africa
+++ b/tools/java/org/unicode/cldr/util/data/africa
@@ -64,7 +64,7 @@
# Corrections are welcome.
# Algeria
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Algeria 1916 only - Jun 14 23:00s 1:00 S
Rule Algeria 1916 1919 - Oct Sun>=1 23:00s 0 -
Rule Algeria 1917 only - Mar 24 23:00s 1:00 S
@@ -87,10 +87,9 @@
Rule Algeria 1978 only - Sep 22 3:00 0 -
Rule Algeria 1980 only - Apr 25 0:00 1:00 S
Rule Algeria 1980 only - Oct 31 2:00 0 -
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01
+# See Europe/Paris for PMT-related transitions.
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 16
0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
0:00 Algeria WE%sT 1940 Feb 25 2:00
1:00 Algeria CE%sT 1946 Oct 7
@@ -124,7 +123,7 @@
# For now, ignore that and follow the 1911-05-26 Portuguese decree
# (see Europe/Lisbon).
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Atlantic/Cape_Verde -1:34:04 - LMT 1912 Jan 01 2:00u # Praia
-2:00 - -02 1942 Sep
-2:00 1:00 -01 1945 Oct 15
@@ -135,7 +134,7 @@
# See Africa/Lagos.
# Chad
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena
1:00 - WAT 1979 Oct 14
1:00 1:00 WAST 1980 Mar 8
@@ -151,7 +150,7 @@
# See Africa/Lagos.
# Côte d'Ivoire / Ivory Coast
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Abidjan -0:16:08 - LMT 1912
0:00 - GMT
Link Africa/Abidjan Africa/Bamako # Mali
@@ -176,7 +175,7 @@
# Egypt was mean noon at the Great Pyramid, 2:04:30.5, but apparently this
# did not apply to Cairo, Alexandria, or Port Said.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Egypt 1940 only - Jul 15 0:00 1:00 S
Rule Egypt 1940 only - Oct 1 0:00 0 -
Rule Egypt 1941 only - Apr 15 0:00 1:00 S
@@ -356,7 +355,7 @@
Rule Egypt 2014 only - Jul 31 24:00 1:00 S
Rule Egypt 2014 only - Sep lastThu 24:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Cairo 2:05:09 - LMT 1900 Oct
2:00 Egypt EE%sT
@@ -411,10 +410,10 @@
# now Ghana observed different DST regimes in different years. For
# lack of better info, use Shanks except treat the minus sign as a
# typo, and assume DST started in 1920 not 1936.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Ghana 1920 1942 - Sep 1 0:00 0:20 -
Rule Ghana 1920 1942 - Dec 31 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Accra -0:00:52 - LMT 1918
0:00 Ghana GMT/+0020
@@ -428,13 +427,13 @@
# evidently confusing the date of the Portuguese decree
# (see Europe/Lisbon) with the date that it took effect.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Bissau -1:02:20 - LMT 1912 Jan 1 1:00u
-1:00 - -01 1975
0:00 - GMT
# Kenya
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Nairobi 2:27:16 - LMT 1928 Jul
3:00 - EAT 1930
2:30 - +0230 1940
@@ -469,7 +468,7 @@
# Use the abbreviation "MMT" before 1972, as the more-accurate numeric
# abbreviation "-004430" would be one byte over the POSIX limit.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Monrovia -0:43:08 - LMT 1882
-0:43:08 - MMT 1919 Mar # Monrovia Mean Time
-0:44:30 - MMT 1972 Jan 7 # approximately MMT
@@ -501,7 +500,7 @@
# From Paul Eggert (2013-10-25):
# For now, assume they're reverting to the pre-2012 rules of permanent UT +02.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Libya 1951 only - Oct 14 2:00 1:00 S
Rule Libya 1952 only - Jan 1 0:00 0 -
Rule Libya 1953 only - Oct 9 2:00 1:00 S
@@ -519,7 +518,7 @@
Rule Libya 1997 only - Oct 4 0:00 0 -
Rule Libya 2013 only - Mar lastFri 1:00 1:00 S
Rule Libya 2013 only - Oct lastFri 2:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Tripoli 0:52:44 - LMT 1920
1:00 Libya CE%sT 1959
2:00 - EET 1982
@@ -624,12 +623,12 @@
# "The trial ended on March 29, 2009, when the clocks moved back by one hour
# at 2am (or 02:00) local time..."
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Mauritius 1982 only - Oct 10 0:00 1:00 -
Rule Mauritius 1983 only - Mar 21 0:00 0 -
Rule Mauritius 2008 only - Oct lastSun 2:00 1:00 -
Rule Mauritius 2009 only - Mar lastSun 2:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis
4:00 Mauritius +04/+05
# Agalega Is, Rodriguez
@@ -860,20 +859,45 @@
# the week end after.... The government does not announce yet the decision
# about this temporary change. But it s 99% sure that it will be the case,
# as in previous years. An unofficial survey was done these days, showing
-# that 64% of asked peopke are ok for moving from +1 to +0 during Ramadan.
+# that 64% of asked people are ok for moving from +1 to +0 during Ramadan.
# https://leconomiste.com/article/1035870-enquete-l-economiste-sunergia-64-des-marocains-plebiscitent-le-gmt-pendant-ramadan
+
+# From Naoufal Semlali (2019-04-16):
+# Morocco will be on GMT starting from Sunday, May 5th 2019 at 3am.
+# The switch to GMT+1 will occur on Sunday, June 9th 2019 at 2am....
+# http://fr.le360.ma/societe/voici-la-date-du-retour-a-lheure-legale-au-maroc-188222
+
+# From Semlali Naoufal (2020-04-14):
+# Following the announcement by the Moroccan government, the switch to
+# GMT time will take place on Sunday, April 19, 2020 from 3 a.m. and
+# the return to GMT+1 time will take place on Sunday, May 31, 2020 at 2 a.m....
+# https://maroc-diplomatique.net/maroc-le-retour-a-lheure-gmt-est-prevu-dimanche-prochain/
+# http://aujourdhui.ma/actualite/gmt1-retour-a-lheure-normale-dimanche-prochain-1
#
-# From Paul Eggert (2018-11-01):
-# For now, guess that Morocco will fall back at 03:00 the last Sunday
-# before Ramadan, and spring forward at 02:00 the first Sunday after
-# Ramadan, as this has been the practice since 2012. To implement this,
-# transition dates for 2019 through 2037 were determined by running the
-# following program under GNU Emacs 26.1.
+# From Milamber (2020-05-31)
+# In Morocco (where I live), the end of Ramadan (Arabic month) is followed by
+# the Eid al-Fitr, and concretely it's 1 or 2 day offs for the people (with
+# traditional visiting of family, big lunches/dinners, etc.). So for this
+# year the astronomical calculations don't include the following 2 days off in
+# the calc. These 2 days fall in a Sunday/Monday, so it's not acceptable by
+# people to have a time shift during these 2 days off. Perhaps you can modify
+# the (predicted) rules for next years: if the end of Ramadan is a (probable)
+# Friday or Saturday (and so the 2 days off are on a weekend), the next time
+# shift will be the next weekend.
+#
+# From Paul Eggert (2020-05-31):
+# For now, guess that in the future Morocco will fall back at 03:00
+# the last Sunday before Ramadan, and spring forward at 02:00 the
+# first Sunday after two days after Ramadan. To implement this,
+# transition dates and times for 2019 through 2087 were determined by
+# running the following program under GNU Emacs 26.3. (This algorithm
+# also produces the correct transition dates for 2016 through 2018,
+# though the times differ due to Morocco's time zone change in 2018.)
# (let ((islamic-year 1440))
# (require 'cal-islam)
-# (while (< islamic-year 1460)
+# (while (< islamic-year 1511)
# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
-# (b (calendar-islamic-to-absolute (list 10 1 islamic-year)))
+# (b (+ 2 (calendar-islamic-to-absolute (list 10 1 islamic-year))))
# (sunday 0))
# (while (/= sunday (mod (setq a (1- a)) 7)))
# (while (/= sunday (mod b 7))
@@ -888,7 +912,7 @@
# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
# (setq islamic-year (+ 1 islamic-year))))
-# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Morocco 1939 only - Sep 12 0:00 1:00 -
Rule Morocco 1939 only - Nov 19 0:00 0 -
Rule Morocco 1940 only - Feb 25 0:00 1:00 -
@@ -933,13 +957,13 @@
Rule Morocco 2019 only - May 5 3:00 0 -
Rule Morocco 2019 only - Jun 9 2:00 1:00 -
Rule Morocco 2020 only - Apr 19 3:00 0 -
-Rule Morocco 2020 only - May 24 2:00 1:00 -
+Rule Morocco 2020 only - May 31 2:00 1:00 -
Rule Morocco 2021 only - Apr 11 3:00 0 -
Rule Morocco 2021 only - May 16 2:00 1:00 -
Rule Morocco 2022 only - Mar 27 3:00 0 -
Rule Morocco 2022 only - May 8 2:00 1:00 -
Rule Morocco 2023 only - Mar 19 3:00 0 -
-Rule Morocco 2023 only - Apr 23 2:00 1:00 -
+Rule Morocco 2023 only - Apr 30 2:00 1:00 -
Rule Morocco 2024 only - Mar 10 3:00 0 -
Rule Morocco 2024 only - Apr 14 2:00 1:00 -
Rule Morocco 2025 only - Feb 23 3:00 0 -
@@ -949,13 +973,13 @@
Rule Morocco 2027 only - Feb 7 3:00 0 -
Rule Morocco 2027 only - Mar 14 2:00 1:00 -
Rule Morocco 2028 only - Jan 23 3:00 0 -
-Rule Morocco 2028 only - Feb 27 2:00 1:00 -
+Rule Morocco 2028 only - Mar 5 2:00 1:00 -
Rule Morocco 2029 only - Jan 14 3:00 0 -
Rule Morocco 2029 only - Feb 18 2:00 1:00 -
Rule Morocco 2029 only - Dec 30 3:00 0 -
Rule Morocco 2030 only - Feb 10 2:00 1:00 -
Rule Morocco 2030 only - Dec 22 3:00 0 -
-Rule Morocco 2031 only - Jan 26 2:00 1:00 -
+Rule Morocco 2031 only - Feb 2 2:00 1:00 -
Rule Morocco 2031 only - Dec 14 3:00 0 -
Rule Morocco 2032 only - Jan 18 2:00 1:00 -
Rule Morocco 2032 only - Nov 28 3:00 0 -
@@ -965,13 +989,119 @@
Rule Morocco 2034 only - Nov 5 3:00 0 -
Rule Morocco 2034 only - Dec 17 2:00 1:00 -
Rule Morocco 2035 only - Oct 28 3:00 0 -
-Rule Morocco 2035 only - Dec 2 2:00 1:00 -
+Rule Morocco 2035 only - Dec 9 2:00 1:00 -
Rule Morocco 2036 only - Oct 19 3:00 0 -
Rule Morocco 2036 only - Nov 23 2:00 1:00 -
Rule Morocco 2037 only - Oct 4 3:00 0 -
Rule Morocco 2037 only - Nov 15 2:00 1:00 -
+Rule Morocco 2038 only - Sep 26 3:00 0 -
+Rule Morocco 2038 only - Nov 7 2:00 1:00 -
+Rule Morocco 2039 only - Sep 18 3:00 0 -
+Rule Morocco 2039 only - Oct 23 2:00 1:00 -
+Rule Morocco 2040 only - Sep 2 3:00 0 -
+Rule Morocco 2040 only - Oct 14 2:00 1:00 -
+Rule Morocco 2041 only - Aug 25 3:00 0 -
+Rule Morocco 2041 only - Sep 29 2:00 1:00 -
+Rule Morocco 2042 only - Aug 10 3:00 0 -
+Rule Morocco 2042 only - Sep 21 2:00 1:00 -
+Rule Morocco 2043 only - Aug 2 3:00 0 -
+Rule Morocco 2043 only - Sep 13 2:00 1:00 -
+Rule Morocco 2044 only - Jul 24 3:00 0 -
+Rule Morocco 2044 only - Aug 28 2:00 1:00 -
+Rule Morocco 2045 only - Jul 9 3:00 0 -
+Rule Morocco 2045 only - Aug 20 2:00 1:00 -
+Rule Morocco 2046 only - Jul 1 3:00 0 -
+Rule Morocco 2046 only - Aug 12 2:00 1:00 -
+Rule Morocco 2047 only - Jun 23 3:00 0 -
+Rule Morocco 2047 only - Jul 28 2:00 1:00 -
+Rule Morocco 2048 only - Jun 7 3:00 0 -
+Rule Morocco 2048 only - Jul 19 2:00 1:00 -
+Rule Morocco 2049 only - May 30 3:00 0 -
+Rule Morocco 2049 only - Jul 4 2:00 1:00 -
+Rule Morocco 2050 only - May 15 3:00 0 -
+Rule Morocco 2050 only - Jun 26 2:00 1:00 -
+Rule Morocco 2051 only - May 7 3:00 0 -
+Rule Morocco 2051 only - Jun 18 2:00 1:00 -
+Rule Morocco 2052 only - Apr 28 3:00 0 -
+Rule Morocco 2052 only - Jun 2 2:00 1:00 -
+Rule Morocco 2053 only - Apr 13 3:00 0 -
+Rule Morocco 2053 only - May 25 2:00 1:00 -
+Rule Morocco 2054 only - Apr 5 3:00 0 -
+Rule Morocco 2054 only - May 17 2:00 1:00 -
+Rule Morocco 2055 only - Mar 28 3:00 0 -
+Rule Morocco 2055 only - May 2 2:00 1:00 -
+Rule Morocco 2056 only - Mar 12 3:00 0 -
+Rule Morocco 2056 only - Apr 23 2:00 1:00 -
+Rule Morocco 2057 only - Mar 4 3:00 0 -
+Rule Morocco 2057 only - Apr 8 2:00 1:00 -
+Rule Morocco 2058 only - Feb 17 3:00 0 -
+Rule Morocco 2058 only - Mar 31 2:00 1:00 -
+Rule Morocco 2059 only - Feb 9 3:00 0 -
+Rule Morocco 2059 only - Mar 23 2:00 1:00 -
+Rule Morocco 2060 only - Feb 1 3:00 0 -
+Rule Morocco 2060 only - Mar 7 2:00 1:00 -
+Rule Morocco 2061 only - Jan 16 3:00 0 -
+Rule Morocco 2061 only - Feb 27 2:00 1:00 -
+Rule Morocco 2062 only - Jan 8 3:00 0 -
+Rule Morocco 2062 only - Feb 19 2:00 1:00 -
+Rule Morocco 2062 only - Dec 31 3:00 0 -
+Rule Morocco 2063 only - Feb 4 2:00 1:00 -
+Rule Morocco 2063 only - Dec 16 3:00 0 -
+Rule Morocco 2064 only - Jan 27 2:00 1:00 -
+Rule Morocco 2064 only - Dec 7 3:00 0 -
+Rule Morocco 2065 only - Jan 11 2:00 1:00 -
+Rule Morocco 2065 only - Nov 22 3:00 0 -
+Rule Morocco 2066 only - Jan 3 2:00 1:00 -
+Rule Morocco 2066 only - Nov 14 3:00 0 -
+Rule Morocco 2066 only - Dec 26 2:00 1:00 -
+Rule Morocco 2067 only - Nov 6 3:00 0 -
+Rule Morocco 2067 only - Dec 11 2:00 1:00 -
+Rule Morocco 2068 only - Oct 21 3:00 0 -
+Rule Morocco 2068 only - Dec 2 2:00 1:00 -
+Rule Morocco 2069 only - Oct 13 3:00 0 -
+Rule Morocco 2069 only - Nov 24 2:00 1:00 -
+Rule Morocco 2070 only - Oct 5 3:00 0 -
+Rule Morocco 2070 only - Nov 9 2:00 1:00 -
+Rule Morocco 2071 only - Sep 20 3:00 0 -
+Rule Morocco 2071 only - Nov 1 2:00 1:00 -
+Rule Morocco 2072 only - Sep 11 3:00 0 -
+Rule Morocco 2072 only - Oct 16 2:00 1:00 -
+Rule Morocco 2073 only - Aug 27 3:00 0 -
+Rule Morocco 2073 only - Oct 8 2:00 1:00 -
+Rule Morocco 2074 only - Aug 19 3:00 0 -
+Rule Morocco 2074 only - Sep 30 2:00 1:00 -
+Rule Morocco 2075 only - Aug 11 3:00 0 -
+Rule Morocco 2075 only - Sep 15 2:00 1:00 -
+Rule Morocco 2076 only - Jul 26 3:00 0 -
+Rule Morocco 2076 only - Sep 6 2:00 1:00 -
+Rule Morocco 2077 only - Jul 18 3:00 0 -
+Rule Morocco 2077 only - Aug 29 2:00 1:00 -
+Rule Morocco 2078 only - Jul 10 3:00 0 -
+Rule Morocco 2078 only - Aug 14 2:00 1:00 -
+Rule Morocco 2079 only - Jun 25 3:00 0 -
+Rule Morocco 2079 only - Aug 6 2:00 1:00 -
+Rule Morocco 2080 only - Jun 16 3:00 0 -
+Rule Morocco 2080 only - Jul 21 2:00 1:00 -
+Rule Morocco 2081 only - Jun 1 3:00 0 -
+Rule Morocco 2081 only - Jul 13 2:00 1:00 -
+Rule Morocco 2082 only - May 24 3:00 0 -
+Rule Morocco 2082 only - Jul 5 2:00 1:00 -
+Rule Morocco 2083 only - May 16 3:00 0 -
+Rule Morocco 2083 only - Jun 20 2:00 1:00 -
+Rule Morocco 2084 only - Apr 30 3:00 0 -
+Rule Morocco 2084 only - Jun 11 2:00 1:00 -
+Rule Morocco 2085 only - Apr 22 3:00 0 -
+Rule Morocco 2085 only - Jun 3 2:00 1:00 -
+Rule Morocco 2086 only - Apr 14 3:00 0 -
+Rule Morocco 2086 only - May 19 2:00 1:00 -
+Rule Morocco 2087 only - Mar 30 3:00 0 -
+Rule Morocco 2087 only - May 11 2:00 1:00 -
+# For dates after the somewhat-arbitrary cutoff of 2087, assume that
+# Morocco will no longer observe DST. At some point this table will
+# need to be extended, though quite possibly Morocco will change the
+# rules first.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26
0:00 Morocco +00/+01 1984 Mar 16
1:00 - +01 1986
@@ -1001,7 +1131,7 @@
# https://dre.pt/pdf1sdip/1911/05/12500/23132313.pdf
# merely made it official?
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Maputo 2:10:20 - LMT 1903 Mar
2:00 - CAT
Link Africa/Maputo Africa/Blantyre # Malawi
@@ -1062,18 +1192,18 @@
# Use plain "WAT" and "CAT" for the time zone abbreviations, to be compatible
# with Namibia's neighbors.
-# RULE NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Vanguard section, for zic and other parsers that support negative DST.
#Rule Namibia 1994 only - Mar 21 0:00 -1:00 WAT
#Rule Namibia 1994 2017 - Sep Sun>=1 2:00 0 CAT
#Rule Namibia 1995 2017 - Apr Sun>=1 2:00 -1:00 WAT
-# Rearguard section, for parsers that do not support negative DST.
+# Rearguard section, for parsers lacking negative DST; see ziguard.awk.
Rule Namibia 1994 only - Mar 21 0:00 0 WAT
Rule Namibia 1994 2017 - Sep Sun>=1 2:00 1:00 CAT
Rule Namibia 1995 2017 - Apr Sun>=1 2:00 0 WAT
# End of rearguard section.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8
1:30 - +0130 1903 Mar
2:00 - SAST 1942 Sep 20 2:00
@@ -1081,7 +1211,7 @@
2:00 - SAST 1990 Mar 21 # independence
# Vanguard section, for zic and other parsers that support negative DST.
# 2:00 Namibia %s
-# Rearguard section, for parsers that do not support negative DST.
+# Rearguard section, for parsers lacking negative DST; see ziguard.awk.
2:00 - CAT 1994 Mar 21 0:00
# From Paul Eggert (2017-04-07):
# The official date of the 2017 rule change was 2017-10-24. See:
@@ -1094,7 +1224,7 @@
# See Africa/Lagos.
# Nigeria
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Lagos 0:13:36 - LMT 1919 Sep
1:00 - WAT
Link Africa/Lagos Africa/Bangui # Central African Republic
@@ -1108,7 +1238,7 @@
Link Africa/Lagos Africa/Porto-Novo # Benin
# Réunion
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # Saint-Denis
4:00 - +04
#
@@ -1168,7 +1298,7 @@
# See Africa/Abidjan.
# Seychelles
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Mahe 3:41:48 - LMT 1906 Jun # Victoria
4:00 - +04
# From Paul Eggert (2001-05-30):
@@ -1185,10 +1315,10 @@
# See Africa/Nairobi.
# South Africa
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule SA 1942 1943 - Sep Sun>=15 2:00 1:00 -
Rule SA 1943 1944 - Mar Sun>=15 2:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8
1:30 - SAST 1903 Mar
2:00 SA SAST
@@ -1218,19 +1348,19 @@
# Abdalla of NTC, archived at:
# https://mm.icann.org/pipermail/tz/2017-October/025333.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Sudan 1970 only - May 1 0:00 1:00 S
Rule Sudan 1970 1985 - Oct 15 0:00 0 -
Rule Sudan 1971 only - Apr 30 0:00 1:00 S
Rule Sudan 1972 1985 - Apr lastSun 0:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Khartoum 2:10:08 - LMT 1931
2:00 Sudan CA%sT 2000 Jan 15 12:00
3:00 - EAT 2017 Nov 1
2:00 - CAT
# South Sudan
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Juba 2:06:28 - LMT 1931
2:00 Sudan CA%sT 2000 Jan 15 12:00
3:00 - EAT
@@ -1306,7 +1436,7 @@
# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Tunisia 1939 only - Apr 15 23:00s 1:00 S
Rule Tunisia 1939 only - Nov 18 23:00s 0 -
Rule Tunisia 1940 only - Feb 25 23:00s 1:00 S
@@ -1333,10 +1463,8 @@
Rule Tunisia 2006 2008 - Mar lastSun 2:00s 1:00 S
Rule Tunisia 2006 2008 - Oct lastSun 2:00s 0 -
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# See Europe/Paris for PMT-related transitions.
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Africa/Tunis 0:40:44 - LMT 1881 May 12
0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
1:00 Tunisia CE%sT
diff --git a/tools/java/org/unicode/cldr/util/data/antarctica b/tools/java/org/unicode/cldr/util/data/antarctica
index 1dd9b00..ed750a8 100644
--- a/tools/java/org/unicode/cldr/util/data/antarctica
+++ b/tools/java/org/unicode/cldr/util/data/antarctica
@@ -13,7 +13,7 @@
# for information.
# Unless otherwise specified, we have no time zone information.
-# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
+# FORMAT is '-00' and STDOFF is 0 for locations while uninhabited.
# Argentina - year-round bases
# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
@@ -70,15 +70,30 @@
# Australian Antarctica Division informed us that Casey changed time
# zone to UTC+11 in "the morning of 22nd October 2016".
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Antarctica/Casey 0 - -00 1969
- 8:00 - +08 2009 Oct 18 2:00
+# From Steffen Thorsen (2020-10-02, as corrected):
+# Based on information we have received from the Australian Antarctic
+# Division, Casey station and Macquarie Island station will move to Tasmanian
+# daylight savings time on Sunday 4 October. This will take effect from 0001
+# hrs on Sunday 4 October 2020 and will mean Casey and Macquarie Island will
+# be on the same time zone as Hobart. Some past dates too for this 3 hour
+# time change back and forth between UTC+8 and UTC+11 for Casey:
+# - 2018 Oct 7 4:00 - 2019 Mar 17 3:00 - 2019 Oct 4 3:00 - 2020 Mar 8 3:00
+# and now - 2020 Oct 4 0:01
+
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Antarctica/Casey 0 - -00 1969
+ 8:00 - +08 2009 Oct 18 2:00
11:00 - +11 2010 Mar 5 2:00
- 8:00 - +08 2011 Oct 28 2:00
+ 8:00 - +08 2011 Oct 28 2:00
11:00 - +11 2012 Feb 21 17:00u
- 8:00 - +08 2016 Oct 22
+ 8:00 - +08 2016 Oct 22
11:00 - +11 2018 Mar 11 4:00
- 8:00 - +08
+ 8:00 - +08 2018 Oct 7 4:00
+ 11:00 - +11 2019 Mar 17 3:00
+ 8:00 - +08 2019 Oct 4 3:00
+ 11:00 - +11 2020 Mar 8 3:00
+ 8:00 - +08 2020 Oct 4 0:01
+ 11:00 - +11
Zone Antarctica/Davis 0 - -00 1957 Jan 13
7:00 - +07 1964 Nov
0 - -00 1969 Feb
@@ -142,7 +157,7 @@
# St Paul Island - near Amsterdam, uninhabited
# fishing stations operated variously 1819/1931
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
5:00 - +05
#
@@ -153,7 +168,7 @@
# Another base at Port-Martin, 50km east, began operation in 1947.
# It was destroyed by fire on 1952-01-14.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/DumontDUrville 0 - -00 1947
10:00 - +10 1952 Jan 14
0 - -00 1956 Nov
@@ -181,7 +196,7 @@
# Syowa station, which is the first antarctic station of Japan,
# was established on 1957-01-29. Since Syowa station is still the main
# station of Japan, it's appropriate for the principal location.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/Syowa 0 - -00 1957 Jan 29
3:00 - +03
# See:
@@ -224,14 +239,14 @@
# suggested by Bengt-Inge Larsson comment them out for now, and approximate
# with only UTC and CEST. Uncomment them when 2014b is more prevalent.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
#Rule Troll 2005 max - Mar 1 1:00u 1:00 +01
Rule Troll 2005 max - Mar lastSun 1:00u 2:00 +02
#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 +01
#Rule Troll 2004 max - Nov 7 1:00u 0:00 +00
# Remove the following line when uncommenting the above '#Rule' lines.
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 +00
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/Troll 0 - -00 2005 Feb 12
0:00 Troll %s
@@ -305,7 +320,7 @@
# From Paul Eggert (2002-10-22)
# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/Rothera 0 - -00 1976 Dec 1
-3:00 - -03
diff --git a/tools/java/org/unicode/cldr/util/data/asia b/tools/java/org/unicode/cldr/util/data/asia
index 90a6d0a..dd23b10 100644
--- a/tools/java/org/unicode/cldr/util/data/asia
+++ b/tools/java/org/unicode/cldr/util/data/asia
@@ -8,7 +8,7 @@
# [email protected] for general use in the future). For more, please see
# the file CONTRIBUTING in the tz distribution.
-# From Paul Eggert (2018-06-19):
+# From Paul Eggert (2019-07-11):
#
# Unless otherwise specified, the source for data through 1990 is:
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@@ -47,13 +47,13 @@
# 7:00 WIB west Indonesia (Waktu Indonesia Barat)
# 8:00 WITA central Indonesia (Waktu Indonesia Tengah)
# 8:00 CST China
-# 8:00 PST PDT* Philippine Standard Time
+# 8:00 HKT HKST Hong Kong (HKWT* for Winter Time in late 1941)
+# 8:00 PST PDT* Philippines
# 8:30 KST KDT Korea when at +0830
# 9:00 WIT east Indonesia (Waktu Indonesia Timur)
# 9:00 JST JDT Japan
# 9:00 KST KDT Korea when at +09
-# 9:30 ACST Australian Central Standard Time
-# *I invented the abbreviation PDT; see "Philippines" below.
+# *I invented the abbreviations HKWT and PDT; see below.
# Otherwise, these tables typically use numeric abbreviations like +03
# and +0330 for integer hour and minute UT offsets. Although earlier
# editions invented alphabetic time zone abbreviations for every
@@ -70,7 +70,7 @@
###############################################################################
# These rules are stolen from the 'europe' file.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EUAsia 1981 max - Mar lastSun 1:00u 1:00 S
Rule EUAsia 1979 1995 - Sep lastSun 1:00u 0 -
Rule EUAsia 1996 max - Oct lastSun 1:00u 0 -
@@ -84,7 +84,7 @@
Rule RussiaAsia 1996 2010 - Oct lastSun 2:00s 0 -
# Afghanistan
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Kabul 4:36:48 - LMT 1890
4:00 - +04 1945
4:30 - +0430
@@ -114,10 +114,10 @@
# or
# (brief)
# http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Armenia 2011 only - Mar lastSun 2:00s 1:00 -
Rule Armenia 2011 only - Oct lastSun 2:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2
3:00 - +03 1957 Mar
4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
@@ -140,10 +140,10 @@
# http://vestnikkavkaza.net/news/Azerbaijani-Cabinet-of-Ministers-cancels-daylight-saving-time.html
# http://en.apa.az/xeber_azerbaijan_abolishes_daylight_savings_ti_240862.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Azer 1997 2015 - Mar lastSun 4:00 1:00 -
Rule Azer 1997 2015 - Oct lastSun 5:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Baku 3:19:24 - LMT 1924 May 2
3:00 - +03 1957 Mar
4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
@@ -227,11 +227,11 @@
# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Dhaka 2009 only - Jun 19 23:00 1:00 -
Rule Dhaka 2009 only - Dec 31 24:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Dhaka 6:01:40 - LMT 1890
5:53:20 - HMT 1941 Oct # Howrah Mean Time?
6:30 - +0630 1942 May 15
@@ -241,7 +241,7 @@
6:00 Dhaka +06/+07
# Bhutan
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Thimphu 5:58:36 - LMT 1947 Aug 15 # or Thimbu
5:30 - +0530 1987 Oct
6:00 - +06
@@ -252,13 +252,13 @@
# We have no information as to when standard time was introduced;
# assume it occurred in 1907, the same year as Mauritius (which
# then contained the Chagos Archipelago).
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Chagos 4:49:40 - LMT 1907
5:00 - +05 1996
6:00 - +06
# Brunei
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan
7:30 - +0730 1933
8:00 - +08
@@ -273,7 +273,7 @@
# of Greenwich." This refers to the period before Burma's transition to +0630,
# a transition for which Shanks is the only source.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Yangon 6:24:47 - LMT 1880 # or Rangoon
6:24:47 - RMT 1920 # Rangoon local time
6:30 - +0630 1942 May
@@ -286,6 +286,27 @@
# China
+# From Phake Nick (2020-04-15):
+# According to this news report:
+# http://news.sina.com.cn/c/2004-09-01/19524201403.shtml
+# on April 11, 1919, newspaper in Shanghai said clocks in Shanghai will spring
+# forward for an hour starting from midnight of that Saturday. The report did
+# not mention what happened in Shanghai thereafter, but it mentioned that a
+# similar trial in Tianjin which ended at October 1st as citizens are told to
+# recede the clock on September 30 from 12:00pm to 11:00pm. The trial at
+# Tianjin got terminated in 1920.
+#
+# From Paul Eggert (2020-04-15):
+# The Returns of Trade and Trade Reports, page 711, says "Daylight saving was
+# given a trial during the year, and from the 12th April to the 1st October
+# the clocks were all set one hour ahead of sun time. Though the scheme was
+# generally esteemed a success, it was announced early in 1920 that it would
+# not be repeated."
+#
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+Rule Shang 1919 only - Apr 12 24:00 1:00 D
+Rule Shang 1919 only - Sep 30 24:00 0 S
+
# From Paul Eggert (2018-10-02):
# The following comes from Table 1 of:
# Li Yu. Research on the daylight saving movement in 1940s Shanghai.
@@ -294,8 +315,91 @@
# The table lists dates only; I am guessing 00:00 and 24:00 transition times.
# Also, the table lists the planned end of DST in 1949, but the corresponding
# zone line cuts this off on May 28, when the Communists took power.
+
+# From Phake Nick (2020-04-15):
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# For the history of time in Shanghai between 1940-1942, the situation is
+# actually slightly more complex than the table [below].... At the time,
+# there were three different authorities in Shanghai, including Shanghai
+# International Settlement, a settlement established by western countries with
+# its own westernized form of government, Shanghai French Concession, similar
+# to the international settlement but is controlled by French, and then the
+# rest of the city of Shanghai, which have already been controlled by Japanese
+# force through a puppet local government (Wang Jingwei regime). It was
+# additionally complicated by the circumstances that, according to the 1940s
+# Shanghai summer time essay cited in the database, some
+# departments/businesses/people in the Shanghai city itself during that time
+# period, refused to change their clock and instead only changed their opening
+# hours.
+#
+# For example, as quoted in the article, in 1940, other than the authority
+# itself, power, tram, bus companies, cinema, department stores, and other
+# public service organizations have all decided to follow the summer time and
+# spring forward the clock. On the other hand, the custom office refused to
+# spring forward the clock because of worry on mechanical wear to the physical
+# clock, postal office refused to spring forward because of disruption to
+# business and log-keeping, although they did changed their office hour to
+# match rest of the city. So is travel agents, and also weather
+# observatory. It is said both time standards had their own supporters in the
+# city at the time, those who prefer new time standard would have moved their
+# clock while those who prefer the old time standard would keep their clock
+# unchange, and there were different clocks that use different time standard
+# in the city at the time for people who use different time standard to adjust
+# their clock to their preferred time.
+#
+# a. For the 1940 May 31 spring forward, the essay claim that it was
+# coordinared between the international settlement authority and the French
+# concession authority and have gathered support from Hong Kong and Xiamen,
+# that it would spring forward an hour from May 31 "midnight", and the essay
+# claim "Hong Kong government implemented the spring forward in the same time
+# on the same date as Shanghai".
+#
+# b. For the 1940 fall back, it was said that they initially intended to do
+# so on September 30 00:59 at night, however they postponed it to October 12
+# after discussion with relevant parties. However schools restored to the
+# original schedule ten days earlier.
+#
+# c. For the 1941 spring forward, it is said to start from March 15
+# "following the previous year's method", and in addition to that the essay
+# cited an announcement in 1941 from the Wang regime which said the Special
+# City of Shanghai under Wang regime control will follow the DST rule set by
+# the Settlements, irrespective of the original DST plan announced by the Wang
+# regime for other area under its control(April 1 to September 30). (no idea
+# to situation before that announcement)
+#
+# d. For the 1941 fall back, it was said that the fall back would occurs at
+# the end of September (A newspaper headline cited by the essay, published on
+# October 1, 1941, have the headlines which said "French Concession would
+# rewind to the old clock this morning), but it ultimately didn't happen due
+# to disagreement between the international settlement authority and the
+# French concession authority, and the fall back ultimately occurred on
+# November 1.
+#
+# e. In 1941 December, Japan have officially started war with the United
+# States and the United Kingdom, and in Shanghai they have marched into the
+# international settlement, taken over its control
+#
+# f. For the 1942 spring forward, the essay said that the spring forward
+# started on January 31. It said this time the custom office and postal
+# department will also change their clocks, unlike before.
+#
+# g. The essay itself didn't cover any specific changes thereafter until the
+# end of the war, it quoted a November 1942 command from the government of the
+# Wang regime, which claim the daylight saving time applies year round during
+# the war. However, the essay ambiguously said the period is "February 1 to
+# September 30", which I don't really understand what is the meaning of such
+# period in the context of year round implementation here.. More researches
+# might be needed to show exactly what happened during that period of time.
+
+# From Phake Nick (2020-04-15):
+# According to a Japanese tour bus pamphlet in Nanjing area believed to be
+# from around year 1941: http://www.tt-museum.jp/tairiku_0280_nan1941.html ,
+# the schedule listed was in the format of Japanese time. Which indicate some
+# use of the Japanese time (instead of syncing by DST) might have occurred in
+# the Yangtze river delta area during that period of time although the scope
+# of such use will need to be investigated to determine.
+#
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Shang 1940 only - Jun 1 0:00 1:00 D
Rule Shang 1940 only - Oct 12 24:00 0 S
Rule Shang 1941 only - Mar 15 0:00 1:00 D
@@ -358,7 +462,7 @@
# to begin on 17 April.
# http://data.people.com.cn/pic/101p/1988/04/1988041201.jpg
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule PRC 1986 only - May 4 2:00 1:00 D
Rule PRC 1986 1991 - Sep Sun>=11 2:00 0 S
Rule PRC 1987 1991 - Apr Sun>=11 2:00 1:00 D
@@ -561,7 +665,7 @@
# that the sort of users who prefer Asia/Urumqi now typically ignored the
# +08 mandate back then.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Beijing time, used throughout China; represented by Shanghai.
Zone Asia/Shanghai 8:05:43 - LMT 1901
8:00 Shang C%sT 1949 May 28
@@ -572,7 +676,7 @@
6:00 - +06
-# Hong Kong (Xianggang)
+# Hong Kong
# Milne gives 7:36:41.7; round this.
@@ -582,9 +686,7 @@
# it is not [an] observatory, but the official meteorological agency of HK,
# and also serves as the official timing agency), there are some missing
# and incorrect rules. Although the exact switch over time is missing, I
-# think 3:30 is correct. The official DST record for Hong Kong can be
-# obtained from
-# http://www.hko.gov.hk/gts/time/Summertime.htm
+# think 3:30 is correct.
# From Phake Nick (2018-10-27):
# According to Singaporean newspaper
@@ -652,14 +754,53 @@
# https://i.imgur.com/05KkvtC.png
# * 1941-09-30, Hong Kong Daily Press, Winter Time Warning.
# https://i.imgur.com/dge4kFJ.png
-# Also, the Liberation day of Hong Kong after WWII which British rule
-# over the territory resumed was August 30, 1945, which I think should
-# be the termination date for the use of JST in the territory....
-# From Paul Eggert (2018-11-17):
+# From Paul Eggert (2019-07-11):
+# "Hong Kong winter time" is considered to be daylight saving.
+# "Hong Kong had adopted daylight saving on June 15 as a wartime measure,
+# clocks moving forward one hour until October 1, when they would be put back
+# by just half an hour for 'Hong Kong Winter time', so that daylight saving
+# operated year round." -- Low Z. The longest day: when wartime Hong Kong
+# introduced daylight saving. South China Morning Post. 2019-06-28.
+# https://www.scmp.com/magazines/post-magazine/short-reads/article/3016281/longest-day-when-wartime-hong-kong-introduced
+
+# From P Chan (2018-12-31):
+# * According to the Hong Kong Daylight-Saving Regulations, 1941, the
+# 1941 spring-forward transition was at 03:00.
+# http://sunzi.lib.hku.hk/hkgro/view/g1941/304271.pdf
+# http://sunzi.lib.hku.hk/hkgro/view/g1941/305516.pdf
+# * According to some articles from South China Morning Post, +08 was
+# resumed on 1945-11-18 at 02:00.
+# https://i.imgur.com/M2IsZ3c.png
+# https://i.imgur.com/iOPqrVo.png
+# https://i.imgur.com/fffcGDs.png
+# * Some newspapers ... said the 1946 spring-forward transition was on
+# 04-21 at 00:00. The Kung Sheung Evening News 1946-04-20 (Chinese)
+# https://i.imgur.com/ZSzent0.png
+# https://mmis.hkpl.gov.hk///c/portal/cover?c=QF757YsWv5%2FH7zGe%2FKF%2BFLYsuqGhRBfe p.4
+# The Kung Sheung Daily News 1946-04-21 (Chinese)
+# https://i.imgur.com/7ecmRlcm.png
+# https://mmis.hkpl.gov.hk///c/portal/cover?c=QF757YsWv5%2BQBGt1%2BwUj5qG2GqtwR3Wh p.4
+# * According to the Summer Time Ordinance (1946), the fallback
+# transitions between 1946 and 1952 were at 03:30 Standard Time (+08)
+# http://oelawhk.lib.hku.hk/archive/files/bb74b06a74d5294620a15de560ab33c6.pdf
+# * Some other laws and regulations related to DST from 1953 to 1979
+# Summer Time Ordinance 1953
+# https://i.imgur.com/IOlJMav.jpg
+# Summer Time (Amendment) Ordinance 1965
+# https://i.imgur.com/8rofeLa.jpg
+# Interpretation and General Clauses Ordinance (1966)
+# https://i.imgur.com/joy3msj.jpg
+# Emergency (Summer Time) Regulation 1973 <https://i.imgur.com/OpRWrKz.jpg>
+# Interpretation and General Clauses (Amendment) Ordinance 1977
+# https://i.imgur.com/RaNqnc4.jpg
+# Resolution of the Legislative Council passed on 9 May 1979
+# https://www.legco.gov.hk/yr78-79/english/lc_sitg/hansard/h790509.pdf#page=39
+
+# From Paul Eggert (2020-04-15):
# Here are the dates given at
-# https://www.hko.gov.hk/gts/time/Summertime.htm
-# as of 2014-06-19:
+# https://www.hko.gov.hk/en/gts/time/Summertime.htm
+# as of 2020-02-10:
# Year Period
# 1941 15 Jun to 30 Sep
# 1942 Whole year
@@ -667,7 +808,7 @@
# 1944 Whole year
# 1945 Whole year
# 1946 20 Apr to 1 Dec
-# 1947 13 Apr to 30 Dec
+# 1947 13 Apr to 30 Nov
# 1948 2 May to 31 Oct
# 1949 3 Apr to 30 Oct
# 1950 2 Apr to 29 Oct
@@ -704,36 +845,28 @@
# The page does not give times of day for transitions,
# or dates for the 1942 and 1945 transitions.
# The Japanese occupation of Hong Kong began 1941-12-25.
-# The Japanese surrender of Hong Kong was signed 1945-09-16; see:
-# Heaver S. The days after the Pacific war ended: unsettling times
-# in Hong Kong. Post Magazine. 2016-06-13.
-# https://www.scmp.com/magazines/post-magazine/article/1852990/days-after-pacific-war-ended-unsettling-times-hong-kong
-# For lack of anything better, use start of those days as the
-# transition times.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule HK 1946 only - Apr 20 3:30 1:00 S
-Rule HK 1946 only - Dec 1 3:30 0 -
-Rule HK 1947 only - Apr 13 3:30 1:00 S
-Rule HK 1947 only - Dec 30 3:30 0 -
-Rule HK 1948 only - May 2 3:30 1:00 S
-Rule HK 1948 1951 - Oct lastSun 3:30 0 -
-Rule HK 1952 1953 - Nov Sun>=1 3:30 0 -
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+Rule HK 1946 only - Apr 21 0:00 1:00 S
+Rule HK 1946 only - Dec 1 3:30s 0 -
+Rule HK 1947 only - Apr 13 3:30s 1:00 S
+Rule HK 1947 only - Nov 30 3:30s 0 -
+Rule HK 1948 only - May 2 3:30s 1:00 S
+Rule HK 1948 1952 - Oct Sun>=28 3:30s 0 -
Rule HK 1949 1953 - Apr Sun>=1 3:30 1:00 S
+Rule HK 1953 1964 - Oct Sun>=31 3:30 0 -
Rule HK 1954 1964 - Mar Sun>=18 3:30 1:00 S
-Rule HK 1954 only - Oct 31 3:30 0 -
-Rule HK 1955 1964 - Nov Sun>=1 3:30 0 -
Rule HK 1965 1976 - Apr Sun>=16 3:30 1:00 S
Rule HK 1965 1976 - Oct Sun>=16 3:30 0 -
Rule HK 1973 only - Dec 30 3:30 1:00 S
-Rule HK 1979 only - May Sun>=8 3:30 1:00 S
-Rule HK 1979 only - Oct Sun>=16 3:30 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Rule HK 1979 only - May 13 3:30 1:00 S
+Rule HK 1979 only - Oct 21 3:30 0 -
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 0:36:42
- 8:00 - HKT 1941 Jun 15 3:30
+ 8:00 - HKT 1941 Jun 15 3:00
8:00 1:00 HKST 1941 Oct 1 4:00
- 8:30 - HKT 1941 Dec 25
- 9:00 - JST 1945 Sep 16
+ 8:00 0:30 HKWT 1941 Dec 25
+ 9:00 - JST 1945 Nov 18 2:00
8:00 HK HK%sT
###############################################################################
@@ -840,7 +973,7 @@
# until 1945-09-21 at 01:00, overriding Shanks & Pottenger.
# Likewise, use Yu-Cheng Chuang's data for DST in Taiwan.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Taiwan 1946 only - May 15 0:00 1:00 D
Rule Taiwan 1946 only - Oct 1 0:00 0 S
Rule Taiwan 1947 only - Apr 15 0:00 1:00 D
@@ -857,7 +990,7 @@
Rule Taiwan 1979 only - Jul 1 0:00 1:00 D
Rule Taiwan 1979 only - Oct 1 0:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Taipei or Taibei or T'ai-pei
Zone Asia/Taipei 8:06:00 - LMT 1896 Jan 1
8:00 - CST 1937 Oct 1
@@ -966,7 +1099,7 @@
# The 1904 decree says that Macau changed from the meridian of
# Fortaleza do Monte, presumably the basis for the 7:34:10 for LMT.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Macau 1942 1943 - Apr 30 23:00 1:00 -
Rule Macau 1942 only - Nov 17 23:00 0 -
Rule Macau 1943 only - Sep 30 23:00 0 S
@@ -995,7 +1128,7 @@
Rule Macau 1979 only - May 13 03:30 1:00 D
Rule Macau 1979 only - Oct Sun>=16 03:30 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Macau 7:34:10 - LMT 1904 Oct 30
8:00 - CST 1941 Dec 21 23:00
9:00 Macau +09/+10 1945 Sep 30 24:00
@@ -1024,7 +1157,7 @@
# Cyprus to remain united in time. Cyprus Mail 2017-10-17.
# https://cyprus-mail.com/2017/10/17/cyprus-remain-united-time/
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Cyprus 1975 only - Apr 13 0:00 1:00 S
Rule Cyprus 1975 only - Oct 12 0:00 0 -
Rule Cyprus 1976 only - May 15 0:00 1:00 S
@@ -1034,7 +1167,7 @@
Rule Cyprus 1978 only - Oct 2 0:00 0 -
Rule Cyprus 1979 1997 - Sep lastSun 0:00 0 -
Rule Cyprus 1981 1998 - Mar lastSun 0:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14
2:00 Cyprus EE%sT 1998 Sep
2:00 EUAsia EE%sT
@@ -1083,7 +1216,7 @@
# Byalokoz 1919 says Georgia was 2:59:11.
# Go with Byalokoz.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Tbilisi 2:59:11 - LMT 1880
2:59:11 - TBMT 1924 May 2 # Tbilisi Mean Time
3:00 - +03 1957 Mar
@@ -1120,7 +1253,7 @@
# which will be permanent, with no seasonal adjustment, will happen at
# midnight on Saturday, September 16.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Dili 8:22:20 - LMT 1912 Jan 1
8:00 - +08 1942 Feb 21 23:00
9:00 - +09 1976 May 3
@@ -1186,7 +1319,7 @@
# time for 1870-1941. Shanks is our only (and dubious) source for the
# 1941-1945 data.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata
5:53:20 - HMT 1870 # Howrah Mean Time?
5:21:10 - MMT 1906 Jan 1 # Madras local time
@@ -1238,7 +1371,7 @@
# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time)
# WIT - +09 - Waktu Indonesia Timur (Indonesia eastern time)
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Java, Sumatra
Zone Asia/Jakarta 7:07:12 - LMT 1867 Aug 10
# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
@@ -1314,9 +1447,9 @@
# I used the following code in GNU Emacs 26.1 to generate the "Rule Iran"
# lines from 2008 through 2087. Emacs 26.1 uses Ed Reingold's
# cal-persia implementation of Birashk's approximation, which in the
-# 2008-2087 range disagrees with the the astronomical Persian calendar
-# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058),
-# so the following code special-case those years. See Table 15.1, page 264, of:
+# 2008-2087 range disagrees with the astronomical Persian calendar
+# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058), so
+# the following code special-cases those years. See Table 15.1, page 264, of:
# Edward M. Reingold and Nachum Dershowitz, Calendrical Calculations:
# The Ultimate Edition, Cambridge University Press (2018).
# https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition
@@ -1401,7 +1534,7 @@
# be changed back to its previous state on the 24 hours of the
# thirtieth day of Shahrivar.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Iran 1978 1980 - Mar 20 24:00 1:00 -
Rule Iran 1978 only - Oct 20 24:00 0 -
Rule Iran 1979 only - Sep 18 24:00 0 -
@@ -1510,7 +1643,7 @@
Rule Iran 2088 max - Mar 20 24:00 1:00 -
Rule Iran 2088 max - Sep 20 24:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Tehran 3:25:44 - LMT 1916
3:25:44 - TMT 1946 # Tehran Mean Time
3:30 - +0330 1977 Nov
@@ -1543,7 +1676,7 @@
# We have published a short article in English about the change:
# https://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Iraq 1982 only - May 1 0:00 1:00 -
Rule Iraq 1982 1984 - Oct 1 0:00 0 -
Rule Iraq 1983 only - Mar 31 0:00 1:00 -
@@ -1555,7 +1688,7 @@
#
Rule Iraq 1991 2007 - Apr 1 3:00s 1:00 -
Rule Iraq 1991 2007 - Oct 1 3:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Baghdad 2:57:40 - LMT 1890
2:57:36 - BMT 1918 # Baghdad Mean Time?
3:00 - +03 1982 May
@@ -1566,6 +1699,10 @@
# Israel
+# For more info about the motivation for DST in Israel, see:
+# Barak Y. Israel's Daylight Saving Time controversy. Israel Affairs.
+# 2020-08-11. https://doi.org/10.1080/13537121.2020.1806564
+
# From Ephraim Silverberg (2001-01-11):
#
# I coined "IST/IDT" circa 1988. Until then there were three
@@ -1587,7 +1724,7 @@
# family is from India).
# From Shanks & Pottenger:
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 1940 only - Jun 1 0:00 1:00 D
Rule Zion 1942 1944 - Nov 1 0:00 0 S
Rule Zion 1943 only - Apr 1 2:00 1:00 D
@@ -1622,7 +1759,7 @@
Rule Zion 1975 only - Aug 31 0:00 0 S
# From Alois Treindl (2019-03-06):
-# http://www.moin.gov.il/Documents/שעון קיץ/clock-50-years-7-2014.pdf
+# http://www.moin.gov.il/Documents/שעון%20קיץ/clock-50-years-7-2014.pdf
# From Isaac Starkman (2019-03-06):
# Summer time was in that period in 1980 and 1984, see
# https://www.ynet.co.il/articles/0,7340,L-3951073,00.html
@@ -1679,7 +1816,7 @@
# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 1989 only - Apr 30 0:00 1:00 D
Rule Zion 1989 only - Sep 3 0:00 0 S
Rule Zion 1990 only - Mar 25 0:00 1:00 D
@@ -1695,7 +1832,7 @@
# Ministry of Interior, Jerusalem, Israel. The spokeswoman can be reached by
# calling the office directly at 972-2-6701447 or 972-2-6701448.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 1994 only - Apr 1 0:00 1:00 D
Rule Zion 1994 only - Aug 28 0:00 0 S
Rule Zion 1995 only - Mar 31 0:00 1:00 D
@@ -1715,7 +1852,7 @@
#
# where YYYY is the relevant year.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 1996 only - Mar 15 0:00 1:00 D
Rule Zion 1996 only - Sep 16 0:00 0 S
Rule Zion 1997 only - Mar 21 0:00 1:00 D
@@ -1738,7 +1875,7 @@
#
# ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 2000 only - Apr 14 2:00 1:00 D
Rule Zion 2000 only - Oct 6 1:00 0 S
Rule Zion 2001 only - Apr 9 1:00 1:00 D
@@ -1760,32 +1897,15 @@
#
# ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2005+beyond.ps
-# From Paul Eggert (2012-10-26):
-# I used Ephraim Silverberg's dst-israel.el program
-# <ftp://ftp.cs.huji.ac.il/pub/tz/software/dst-israel.el> (2005-02-20)
-# along with Ed Reingold's cal-hebrew in GNU Emacs 21.4,
-# to generate the transitions from 2005 through 2012.
-# (I replaced "lastFri" with "Fri>=26" by hand.)
-# The spring transitions all correspond to the following Rule:
-#
-# Rule Zion 2005 2012 - Mar Fri>=26 2:00 1:00 D
-#
-# but older zic implementations (e.g., Solaris 8) do not support
-# "Fri>=26" to mean April 1 in years like 2005, so for now we list the
-# springtime transitions explicitly.
-
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Zion 2005 only - Apr 1 2:00 1:00 D
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+Rule Zion 2005 2012 - Apr Fri<=1 2:00 1:00 D
Rule Zion 2005 only - Oct 9 2:00 0 S
-Rule Zion 2006 2010 - Mar Fri>=26 2:00 1:00 D
Rule Zion 2006 only - Oct 1 2:00 0 S
Rule Zion 2007 only - Sep 16 2:00 0 S
Rule Zion 2008 only - Oct 5 2:00 0 S
Rule Zion 2009 only - Sep 27 2:00 0 S
Rule Zion 2010 only - Sep 12 2:00 0 S
-Rule Zion 2011 only - Apr 1 2:00 1:00 D
Rule Zion 2011 only - Oct 2 2:00 0 S
-Rule Zion 2012 only - Mar Fri>=26 2:00 1:00 D
Rule Zion 2012 only - Sep 23 2:00 0 S
# From Ephraim Silverberg (2013-06-27):
@@ -1797,11 +1917,11 @@
# As of 2013, DST starts at 02:00 on the Friday before the last Sunday
# in March. DST ends at 02:00 on the last Sunday of October.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Zion 2013 max - Mar Fri>=23 2:00 1:00 D
Rule Zion 2013 max - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Jerusalem 2:20:54 - LMT 1880
2:20:40 - JMT 1918 # Jerusalem Mean Time?
2:00 Zion I%sT
@@ -1814,6 +1934,47 @@
# '9:00' and 'JST' is from Guy Harris.
+# From Paul Eggert (2020-01-19):
+# Starting in the 7th century, Japan generally followed an ancient Chinese
+# timekeeping system that divided night and day into six hours each,
+# with hour length depending on season. In 1873 the government
+# started requiring the use of a Western style 24-hour clock. See:
+# Yulia Frumer, "Making Time: Astronomical Time Measurement in Tokugawa Japan"
+# <https://www.worldcat.org/oclc/1043907065>. As the tzdb code and
+# data support only 24-hour clocks, its tables model timestamps before
+# 1873 using Western-style local mean time.
+
+# From Hideyuki Suzuki (1998-11-09):
+# 'Tokyo' usually stands for the former location of Tokyo Astronomical
+# Observatory: 139° 44' 40.90" E (9h 18m 58.727s), 35° 39' 16.0" N.
+# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
+# edited by National Astronomical Observatory of Japan....
+# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
+# The law is enacted on 1886-07-07.
+
+# From Hideyuki Suzuki (1998-11-16):
+# The ordinance No. 51 (1886) established "standard time" in Japan,
+# which stands for the time on 135° E.
+# In the ordinance No. 167 (1895), "standard time" was renamed to "central
+# standard time". And the same ordinance also established "western standard
+# time", which stands for the time on 120° E.... But "western standard
+# time" was abolished in the ordinance No. 529 (1937). In the ordinance No.
+# 167, there is no mention regarding for what place western standard time is
+# standard....
+#
+# I wrote "ordinance" above, but I don't know how to translate.
+# In Japanese it's "chokurei", which means ordinance from emperor.
+
+# From Yu-Cheng Chuang (2013-07-12):
+# ...the Meiji Emperor announced Ordinance No. 167 of Meiji Year 28 "The clause
+# about standard time" ... The adoption began from Jan 1, 1896.
+# https://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時)
+#
+# ...the Showa Emperor announced Ordinance No. 529 of Showa Year 12 ... which
+# means the whole Japan territory, including later occupations, adopt Japan
+# Central Time (UT+9). The adoption began on Oct 1, 1937.
+# https://ja.wikisource.org/wiki/明治二十八年勅令第百六十七號標準時ニ關スル件中改正ノ件
+
# From Paul Eggert (1995-03-06):
# Today's _Asahi Evening News_ (page 4) reports that Japan had
# daylight saving between 1948 and 1951, but "the system was discontinued
@@ -1856,44 +2017,13 @@
# do in any POSIX or C platform. The "25:00" assumes zic from 2007 or later,
# which should be safe now.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Japan 1948 only - May Sat>=1 24:00 1:00 D
Rule Japan 1948 1951 - Sep Sun>=9 1:00 0 S
Rule Japan 1949 only - Apr Sat>=1 24:00 1:00 D
Rule Japan 1950 1951 - May Sat>=1 24:00 1:00 D
-# From Hideyuki Suzuki (1998-11-09):
-# 'Tokyo' usually stands for the former location of Tokyo Astronomical
-# Observatory: 139° 44' 40.90" E (9h 18m 58.727s), 35° 39' 16.0" N.
-# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
-# edited by National Astronomical Observatory of Japan....
-# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
-# The law is enacted on 1886-07-07.
-
-# From Hideyuki Suzuki (1998-11-16):
-# The ordinance No. 51 (1886) established "standard time" in Japan,
-# which stands for the time on 135° E.
-# In the ordinance No. 167 (1895), "standard time" was renamed to "central
-# standard time". And the same ordinance also established "western standard
-# time", which stands for the time on 120° E.... But "western standard
-# time" was abolished in the ordinance No. 529 (1937). In the ordinance No.
-# 167, there is no mention regarding for what place western standard time is
-# standard....
-#
-# I wrote "ordinance" above, but I don't know how to translate.
-# In Japanese it's "chokurei", which means ordinance from emperor.
-
-# From Yu-Cheng Chuang (2013-07-12):
-# ...the Meiji Emperor announced Ordinance No. 167 of Meiji Year 28 "The clause
-# about standard time" ... The adoption began from Jan 1, 1896.
-# https://ja.wikisource.org/wiki/標準時ニ關スル件_(公布時)
-#
-# ...the Showa Emperor announced Ordinance No. 529 of Showa Year 12 ... which
-# means the whole Japan territory, including later occupations, adopt Japan
-# Central Time (UT+9). The adoption began on Oct 1, 1937.
-# https://ja.wikisource.org/wiki/明治二十八年勅令第百六十七號標準時ニ關スル件中改正ノ件
-
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Tokyo 9:18:59 - LMT 1887 Dec 31 15:00u
9:00 Japan J%sT
# Since 1938, all Japanese possessions have been like Asia/Tokyo,
@@ -1964,7 +2094,7 @@
# From Paul Eggert (2013-12-11):
# As Steffen suggested, consider the past 21-month experiment to be DST.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Jordan 1973 only - Jun 6 0:00 1:00 S
Rule Jordan 1973 1975 - Oct 1 0:00 0 -
Rule Jordan 1974 1977 - May 1 0:00 1:00 S
@@ -1996,7 +2126,7 @@
Rule Jordan 2013 only - Dec 20 0:00 0 -
Rule Jordan 2014 max - Mar lastThu 24:00 1:00 S
Rule Jordan 2014 max - Oct lastFri 0:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Amman 2:23:44 - LMT 1931
2:00 Jordan EE%sT
@@ -2037,8 +2167,8 @@
# text.
#
# According to Izvestia newspaper No. 68 (23334) from 1991-03-20
-# (page 6; available at http://libinfo.org/newsr/newsr2574.djvu via
-# http://libinfo.org/index.php?id=58564) on 1991-03-31 at 2:00 during
+# -- page 6; available at http://libinfo.org/newsr/newsr2574.djvu via
+# http://libinfo.org/index.php?id=58564 -- on 1991-03-31 at 2:00 during
# transition to "summer" time:
# Republic of Georgia, Latvian SSR, Lithuanian SSR, SSR Moldova,
# Estonian SSR; Komi ASSR; Kaliningrad oblast; Nenets autonomous okrug
@@ -2054,7 +2184,7 @@
# Apparently there were last minute changes. Apparently Kazakh act No. 170
# was one of such changes.
#
-# https://ru.wikipedia.org/wiki/Декретное время
+# https://ru.wikipedia.org/wiki/Декретное_время
# claims that Sovetskaya Rossiya newspaper on 1991-03-29 published that
# Nenets autonomous okrug, Komi and Kazakhstan (excluding Uralsk oblast)
# were to not move clocks and Uralsk oblast was to move clocks
@@ -2193,7 +2323,7 @@
# UTC+6 to UTC+5 effective December 21st, 2018. The legal document is
# located here: http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
#
# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA,
@@ -2290,12 +2420,12 @@
# Our government cancels daylight saving time 6th of August 2005.
# From 2005-08-12 our GMT-offset is +6, w/o any daylight saving.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Kyrgyz 1992 1996 - Apr Sun>=7 0:00s 1:00 -
Rule Kyrgyz 1992 1996 - Sep lastSun 0:00 0 -
Rule Kyrgyz 1997 2005 - Mar lastSun 2:30 1:00 -
Rule Kyrgyz 1997 2004 - Oct lastSun 2:30 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2
5:00 - +05 1930 Jun 21
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
@@ -2346,7 +2476,7 @@
# follow and continued to use GMT+9:00 for interoperability.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule ROK 1948 only - Jun 1 0:00 1:00 D
Rule ROK 1948 only - Sep 12 24:00 0 S
Rule ROK 1949 only - Apr 3 0:00 1:00 D
@@ -2410,11 +2540,11 @@
# The BBC reported that the transition was from 23:30 to 24:00 today.
# https://www.bbc.com/news/world-asia-44010705
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1
8:30 - KST 1912 Jan 1
9:00 - JST 1945 Sep 8
- 9:00 - KST 1954 Mar 21
+ 9:00 ROK K%sT 1954 Mar 21
8:30 ROK K%sT 1961 Aug 10
9:00 ROK K%sT
Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1
@@ -2434,7 +2564,7 @@
# Lebanon
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Lebanon 1920 only - Mar 28 0:00 1:00 S
Rule Lebanon 1920 only - Oct 25 0:00 0 -
Rule Lebanon 1921 only - Apr 3 0:00 1:00 S
@@ -2459,19 +2589,19 @@
Rule Lebanon 1993 max - Mar lastSun 0:00 1:00 S
Rule Lebanon 1993 1998 - Sep lastSun 0:00 0 -
Rule Lebanon 1999 max - Oct lastSun 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Beirut 2:22:00 - LMT 1880
2:00 Lebanon EE%sT
# Malaysia
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule NBorneo 1935 1941 - Sep 14 0:00 0:20 -
Rule NBorneo 1935 1941 - Dec 14 0:00 0 -
#
# peninsular Malaysia
# taken from Mok Ly Yng (2003-10-30)
# http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Kuala_Lumpur 6:46:46 - LMT 1901 Jan 1
6:55:25 - SMT 1905 Jun 1 # Singapore M.T.
7:00 - +07 1933 Jan 1
@@ -2485,7 +2615,7 @@
# From Paul Eggert (2014-08-12):
# The data entries here are mostly from Shanks & Pottenger, but the 1942, 1945
# and 1982 transition dates are from Mok Ly Yng.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Kuching 7:21:20 - LMT 1926 Mar
7:30 - +0730 1933
8:00 NBorneo +08/+0820 1942 Feb 16
@@ -2493,7 +2623,7 @@
8:00 - +08
# Maldives
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Maldives 4:54:00 - LMT 1880 # Malé
4:54:00 - MMT 1960 # Malé Mean Time
5:00 - +05
@@ -2609,7 +2739,7 @@
# September daylight saving time ends. Source:
# http://zasag.mn/news/view/8969
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Mongol 1983 1984 - Apr 1 0:00 1:00 -
Rule Mongol 1983 only - Oct 1 0:00 0 -
# Shanks & Pottenger and IATA SSIM say 1990s switches occurred at 00:00,
@@ -2636,7 +2766,7 @@
Rule Mongol 2015 2016 - Mar lastSat 2:00 1:00 -
Rule Mongol 2015 2016 - Sep lastSat 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta
Zone Asia/Hovd 6:06:36 - LMT 1905 Aug
6:00 - +06 1978
@@ -2654,7 +2784,7 @@
8:00 Mongol +08/+09
# Nepal
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Kathmandu 5:41:16 - LMT 1920
5:30 - +0530 1986
5:45 - +0545
@@ -2797,14 +2927,14 @@
# "People laud PM's announcement to end DST"
# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Pakistan 2002 only - Apr Sun>=2 0:00 1:00 S
Rule Pakistan 2002 only - Oct Sun>=2 0:00 0 -
Rule Pakistan 2008 only - Jun 1 0:00 1:00 S
Rule Pakistan 2008 2009 - Nov 1 0:00 0 -
Rule Pakistan 2009 only - Apr 15 0:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Karachi 4:28:12 - LMT 1907
5:30 - +0530 1942 Sep
5:30 1:00 +0630 1945 Oct 15
@@ -3072,34 +3202,34 @@
# [T]he Palestinian cabinet decision (Mar 8th 2016) published on
# http://www.palestinecabinet.gov.ps/WebSite/Upload/Decree/GOV_17/16032016134830.pdf
# states that summer time will end on Oct 29th at 01:00.
-#
-# From Tim Parenti (2016-10-19):
-# Predict fall transitions on October's last Saturday at 01:00 from now on.
-# This is consistent with the 2016 transition as well as our spring
-# predictions.
-#
-# From Paul Eggert (2016-10-19):
-# It's also consistent with predictions in the following URLs today:
-# https://www.timeanddate.com/time/change/gaza-strip/gaza
-# https://www.timeanddate.com/time/change/west-bank/hebron
# From Sharef Mustafa (2018-03-16):
-# Palestine summer time will start on Mar 24th 2018 by advancing the
-# clock by 60 minutes as per Palestinian cabinet decision published on
-# the official website, though the decree did not specify the exact
-# time of the time shift.
+# Palestine summer time will start on Mar 24th 2018 ...
# http://www.palestinecabinet.gov.ps/Website/AR/NDecrees/ViewFile.ashx?ID=e7a42ab7-ee23-435a-b9c8-a4f7e81f3817
# From Even Scharning (2019-03-23):
-# DST in Palestine will start on 30 March this year, not 23 March as the time
-# zone database predicted.
-# https://ramallah.news/post/123610
+# http://pnn.ps/news/401130
+# http://palweather.ps/ar/node/50136.html
#
-# From Tim Parenti (2019-03-23):
-# Combining this with the rules observed since 2016, adjust our spring
-# transition guess to Mar Sat>=24.
+# From Sharif Mustafa (2019-03-26):
+# The Palestinian cabinet announced today that the switch to DST will
+# be on Fri Mar 29th 2019 by advancing the clock by 60 minutes.
+# http://palestinecabinet.gov.ps/Website/AR/NDecrees/ViewFile.ashx?ID=e54e9ea1-50ee-4137-84df-0d6c78da259b
+#
+# From Even Scharning (2019-04-10):
+# Our source in Palestine said it happened Friday 29 at 00:00 local time....
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Sharef Mustafa (2019-10-18):
+# Palestine summer time will end on midnight Oct 26th 2019 ...
+# http://www.palestinecabinet.gov.ps/website/ar/ViewDetails?ID=43948
+#
+# From Paul Eggert (2019-04-10):
+# For now, guess spring-ahead transitions are March's last Friday at 00:00.
+#
+# From Tim Parenti (2016-10-19):
+# Predict fall transitions on October's last Saturday at 01:00 from now on.
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 -
Rule EgyptAsia 1958 only - May 1 0:00 1:00 S
@@ -3128,10 +3258,11 @@
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
-Rule Palestine 2016 max - Mar Sat>=24 1:00 1:00 S
+Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S
Rule Palestine 2016 max - Oct lastSat 1:00 0 -
+Rule Palestine 2019 max - Mar lastFri 0:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
2:00 Zion EET/EEST 1948 May 15
2:00 EgyptAsia EE%sT 1967 Jun 5
@@ -3198,14 +3329,14 @@
# influence of the sources. There is no current abbreviation for DST,
# so use "PDT", the usual American style.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Phil 1936 only - Nov 1 0:00 1:00 D
Rule Phil 1937 only - Feb 1 0:00 0 S
Rule Phil 1954 only - Apr 12 0:00 1:00 D
Rule Phil 1954 only - Jul 1 0:00 0 S
Rule Phil 1978 only - Mar 22 0:00 1:00 D
Rule Phil 1978 only - Sep 21 0:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Manila -15:56:00 - LMT 1844 Dec 31
8:04:00 - LMT 1899 May 11
8:00 Phil P%sT 1942 May
@@ -3213,7 +3344,7 @@
8:00 Phil P%sT
# Qatar
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha
4:00 - +04 1972 Jun
3:00 - +03
@@ -3261,7 +3392,7 @@
# the country. Presumably this is documenting airline time. Ignore this,
# as it's before our 1970 cutoff.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14
3:00 - +03
Link Asia/Riyadh Asia/Aden # Yemen
@@ -3270,7 +3401,7 @@
# Singapore
# taken from Mok Ly Yng (2003-10-30)
# http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1
6:55:25 - SMT 1905 Jun 1 # Singapore M.T.
7:00 - +07 1933 Jan 1
@@ -3334,7 +3465,7 @@
# even worse. For now, let's use a numeric abbreviation; we can
# switch to "SLST" if it catches on.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Colombo 5:19:24 - LMT 1880
5:19:32 - MMT 1906 # Moratuwa Mean Time
5:30 - +0530 1942 Jan 5
@@ -3346,7 +3477,7 @@
5:30 - +0530
# Syria
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Syria 1920 1923 - Apr Sun>=15 2:00 1:00 S
Rule Syria 1920 1923 - Oct Sun>=1 2:00 0 -
Rule Syria 1962 only - Apr 29 2:00 1:00 S
@@ -3504,13 +3635,13 @@
Rule Syria 2012 max - Mar lastFri 0:00 1:00 S
Rule Syria 2009 max - Oct lastFri 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
2:00 Syria EE%sT
# Tajikistan
# From Shanks & Pottenger.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2
5:00 - +05 1930 Jun 21
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
@@ -3518,7 +3649,7 @@
5:00 - +05
# Thailand
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Bangkok 6:42:04 - LMT 1880
6:42:04 - BMT 1920 Apr # Bangkok Mean Time
7:00 - +07
@@ -3527,7 +3658,7 @@
# Turkmenistan
# From Shanks & Pottenger.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad
4:00 - +04 1930 Jun 21
5:00 RussiaAsia +05/+06 1991 Mar 31 2:00
@@ -3535,14 +3666,14 @@
5:00 - +05
# United Arab Emirates
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Dubai 3:41:12 - LMT 1920
4:00 - +04
Link Asia/Dubai Asia/Muscat # Oman
# Uzbekistan
# Byalokoz 1919 says Uzbekistan was 4:27:53.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2
4:00 - +04 1930 Jun 21
5:00 - +05 1981 Apr 1
@@ -3590,7 +3721,7 @@
# and in South Vietnam in particular (after 1954):
# To 07:00 on 1911-05-01.
# To 08:00 on 1942-12-31 at 23:00.
-# To 09:00 in 1945-03-14 at 23:00.
+# To 09:00 on 1945-03-14 at 23:00.
# To 07:00 on 1945-09-02 in Vietnam.
# To 08:00 on 1947-04-01 in French-controlled Indochina.
# To 07:00 on 1955-07-01 in South Vietnam.
@@ -3608,7 +3739,7 @@
# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
# NXB Thuận Hoá, Huế, 1995.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jul 1
7:06:30 - PLMT 1911 May 1 # Phù Liễn MT
7:00 - +07 1942 Dec 31 23:00
diff --git a/tools/java/org/unicode/cldr/util/data/australasia b/tools/java/org/unicode/cldr/util/data/australasia
index dfe73d3..a8886ff 100644
--- a/tools/java/org/unicode/cldr/util/data/australasia
+++ b/tools/java/org/unicode/cldr/util/data/australasia
@@ -13,7 +13,7 @@
# Please see the notes below for the controversy about "EST" versus "AEST" etc.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Aus 1917 only - Jan 1 0:01 1:00 D
Rule Aus 1917 only - Mar 25 2:00 0 S
Rule Aus 1942 only - Jan 1 2:00 1:00 D
@@ -25,14 +25,14 @@
# says W Australia didn't use DST in 1943/1944. Ignore Whitman's claim that
# 1944/1945 was just like 1943/1944.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Northern Territory
Zone Australia/Darwin 8:43:20 - LMT 1895 Feb
9:00 - ACST 1899 May
9:30 Aus AC%sT
# Western Australia
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AW 1974 only - Oct lastSun 2:00s 1:00 D
Rule AW 1975 only - Mar Sun>=1 2:00s 0 S
Rule AW 1983 only - Oct lastSun 2:00s 1:00 D
@@ -70,7 +70,7 @@
# applies to all of the Whitsundays.
# http://www.australia.gov.au/about-australia/australian-story/austn-islands
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AQ 1971 only - Oct lastSun 2:00s 1:00 D
Rule AQ 1972 only - Feb lastSun 2:00s 0 S
Rule AQ 1989 1991 - Oct lastSun 2:00s 1:00 D
@@ -86,7 +86,7 @@
10:00 Holiday AE%sT
# South Australia
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AS 1971 1985 - Oct lastSun 2:00s 1:00 D
Rule AS 1986 only - Oct 19 2:00s 1:00 D
Rule AS 1987 2007 - Oct lastSun 2:00s 1:00 D
@@ -102,7 +102,7 @@
Rule AS 2007 only - Mar lastSun 2:00s 0 S
Rule AS 2008 max - Apr Sun>=1 2:00s 0 S
Rule AS 2008 max - Oct Sun>=1 2:00s 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Australia/Adelaide 9:14:20 - LMT 1895 Feb
9:00 - ACST 1899 May
9:30 Aus AC%sT 1971
@@ -114,7 +114,7 @@
# http://www.bom.gov.au/climate/averages/tables/dst_times.shtml
# says King Island didn't observe DST from WWII until late 1971.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AT 1967 only - Oct Sun>=1 2:00s 1:00 D
Rule AT 1968 only - Mar lastSun 2:00s 0 S
Rule AT 1968 1985 - Oct lastSun 2:00s 1:00 D
@@ -134,7 +134,7 @@
Rule AT 2006 only - Apr Sun>=1 2:00s 0 S
Rule AT 2007 only - Mar lastSun 2:00s 0 S
Rule AT 2008 max - Apr Sun>=1 2:00s 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Australia/Hobart 9:49:16 - LMT 1895 Sep
10:00 - AEST 1916 Oct 1 2:00
10:00 1:00 AEDT 1917 Feb
@@ -147,7 +147,7 @@
10:00 AT AE%sT
# Victoria
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AV 1971 1985 - Oct lastSun 2:00s 1:00 D
Rule AV 1972 only - Feb lastSun 2:00s 0 S
Rule AV 1973 1985 - Mar Sun>=1 2:00s 0 S
@@ -162,13 +162,13 @@
Rule AV 2007 only - Mar lastSun 2:00s 0 S
Rule AV 2008 max - Apr Sun>=1 2:00s 0 S
Rule AV 2008 max - Oct Sun>=1 2:00s 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Australia/Melbourne 9:39:52 - LMT 1895 Feb
10:00 Aus AE%sT 1971
10:00 AV AE%sT
# New South Wales
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule AN 1971 1985 - Oct lastSun 2:00s 1:00 D
Rule AN 1972 only - Feb 27 2:00s 0 S
Rule AN 1973 1981 - Mar Sun>=1 2:00s 0 S
@@ -185,7 +185,7 @@
Rule AN 2007 only - Mar lastSun 2:00s 0 S
Rule AN 2008 max - Apr Sun>=1 2:00s 0 S
Rule AN 2008 max - Oct Sun>=1 2:00s 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Australia/Sydney 10:04:52 - LMT 1895 Feb
10:00 Aus AE%sT 1971
10:00 AN AE%sT
@@ -197,7 +197,7 @@
9:30 AS AC%sT
# Lord Howe Island
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule LH 1981 1984 - Oct lastSun 2:00 1:00 -
Rule LH 1982 1985 - Mar Sun>=1 2:00 0 -
Rule LH 1985 only - Oct lastSun 2:00 0:30 -
@@ -252,18 +252,19 @@
10:00 Aus AE%sT 1919 Apr 1 0:00s
0 - -00 1948 Mar 25
10:00 Aus AE%sT 1967
- 10:00 AT AE%sT 2010 Apr 4 3:00
- 11:00 - +11
+ 10:00 AT AE%sT 2010
+ 10:00 1:00 AEDT 2011
+ 10:00 AT AE%sT
# Christmas
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Christmas 7:02:52 - LMT 1895 Feb
7:00 - +07
# Cocos (Keeling) Is
# These islands were ruled by the Ross family from about 1830 to 1978.
# We don't know when standard time was introduced; for now, we guess 1900.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Indian/Cocos 6:27:40 - LMT 1900
6:30 - +0630
@@ -367,15 +368,20 @@
# From Raymond Kumar (2018-07-13):
# http://www.fijitimes.com/government-approves-2018-daylight-saving/
# ... The daylight saving period will end at 3am on Sunday January 13, 2019.
-#
-# From Paul Eggert (2018-07-15):
-# For now, guess DST from 02:00 the first Sunday in November to 03:00
-# the first Sunday on or after January 13. January transitions reportedly
-# depend on when school terms start. Although the guess is ad hoc, it matches
-# transitions since late 2014 and seems more likely to match future
-# practice than guessing no DST.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Paul Eggert (2019-08-06):
+# Today Raymond Kumar reported the Government of Fiji Gazette Supplement No. 27
+# (2019-08-02) said that Fiji observes DST "commencing at 2.00 am on
+# Sunday, 10 November 2019 and ending at 3.00 am on Sunday, 12 January 2020."
+# For now, guess DST from 02:00 the second Sunday in November to 03:00
+# the first Sunday on or after January 12. January transitions reportedly
+# depend on when school terms start. Although the guess is ad hoc, it matches
+# transitions planned this year and seems more likely to match future practice
+# than guessing no DST.
+# From Michael Deckers (2019-08-06):
+# https://www.laws.gov.fj/LawsAsMade/downloadfile/848
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 -
Rule Fiji 1999 2000 - Feb lastSun 3:00 0 -
Rule Fiji 2009 only - Nov 29 2:00 1:00 -
@@ -384,14 +390,15 @@
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 -
Rule Fiji 2014 only - Jan Sun>=18 2:00 0 -
-Rule Fiji 2014 max - Nov Sun>=1 2:00 1:00 -
-Rule Fiji 2015 max - Jan Sun>=13 3:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Rule Fiji 2014 2018 - Nov Sun>=1 2:00 1:00 -
+Rule Fiji 2015 max - Jan Sun>=12 3:00 0 -
+Rule Fiji 2019 max - Nov Sun>=8 2:00 1:00 -
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva
12:00 Fiji +12/+13
# French Polynesia
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct # Rikitea
-9:00 - -09
Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct
@@ -403,7 +410,7 @@
# Guam
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# http://guamlegislature.com/Public_Laws_5th/PL05-025.pdf
# http://documents.guam.gov/wp-content/uploads/E.O.-59-7-Guam-Daylight-Savings-Time-May-6-1959.pdf
Rule Guam 1959 only - Jun 27 2:00 1:00 D
@@ -434,7 +441,7 @@
# http://documents.guam.gov/wp-content/uploads/E.O.-77-18-Guam-Standard-Time.pdf
Rule Guam 1977 only - Aug 28 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Guam -14:21:00 - LMT 1844 Dec 31
9:39:00 - LMT 1901 # Agana
10:00 - GST 1941 Dec 10 # Guam
@@ -444,7 +451,7 @@
Link Pacific/Guam Pacific/Saipan # N Mariana Is
# Kiribati
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki
12:00 - +12
Zone Pacific/Enderbury -11:24:20 - LMT 1901
@@ -460,7 +467,7 @@
# See Pacific/Guam.
# Marshall Is
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Majuro 11:24:48 - LMT 1901
11:00 - +11 1914 Oct
9:00 - +09 1919 Feb 1
@@ -478,7 +485,7 @@
12:00 - +12
# Micronesia
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Chuuk -13:52:52 - LMT 1844 Dec 31
10:07:08 - LMT 1901
10:00 - +10 1914 Oct
@@ -506,7 +513,7 @@
11:00 - +11
# Nauru
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe
11:30 - +1130 1942 Aug 29
9:00 - +09 1945 Sep 8
@@ -514,13 +521,13 @@
12:00 - +12
# New Caledonia
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule NC 1977 1978 - Dec Sun>=1 0:00 1:00 -
Rule NC 1978 1979 - Feb 27 0:00 0 -
Rule NC 1996 only - Dec 1 2:00s 1:00 -
# Shanks & Pottenger say the following was at 2:00; go with IATA.
Rule NC 1997 only - Mar 2 2:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Noumea 11:05:48 - LMT 1912 Jan 13 # Nouméa
11:00 NC +11/+12
@@ -529,7 +536,7 @@
# New Zealand
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule NZ 1927 only - Nov 6 2:00 1:00 S
Rule NZ 1928 only - Mar 4 2:00 0 M
Rule NZ 1928 1933 - Oct Sun>=8 2:00 0:30 S
@@ -559,7 +566,7 @@
Rule Chatham 2007 max - Sep lastSun 2:45s 1:00 -
Rule NZ 2008 max - Apr Sun>=1 2:00s 0 S
Rule Chatham 2008 max - Apr Sun>=1 2:45s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Auckland 11:39:04 - LMT 1868 Nov 2
11:30 NZ NZ%sT 1946 Jan 1
12:00 NZ NZ%sT
@@ -581,11 +588,11 @@
# Cook Is
# From Shanks & Pottenger:
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Cook 1978 only - Nov 12 0:00 0:30 -
Rule Cook 1979 1991 - Mar Sun>=1 0:00 0 -
Rule Cook 1979 1990 - Oct lastSun 0:00 0:30 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Rarotonga -10:39:04 - LMT 1901 # Avarua
-10:30 - -1030 1978 Nov 12
-10:00 Cook -10/-0930
@@ -594,29 +601,30 @@
# Niue
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Niue -11:19:40 - LMT 1901 # Alofi
-11:20 - -1120 1951
-11:30 - -1130 1978 Oct 1
-11:00 - -11
# Norfolk
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Norfolk 11:11:52 - LMT 1901 # Kingston
11:12 - +1112 1951
- 11:30 - +1130 1974 Oct 27 02:00
- 11:30 1:00 +1230 1975 Mar 2 02:00
- 11:30 - +1130 2015 Oct 4 02:00
- 11:00 - +11
+ 11:30 - +1130 1974 Oct 27 02:00s
+ 11:30 1:00 +1230 1975 Mar 2 02:00s
+ 11:30 - +1130 2015 Oct 4 02:00s
+ 11:00 - +11 2019 Jul
+ 11:00 AN +11/+12
# Palau (Belau)
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Palau -15:02:04 - LMT 1844 Dec 31 # Koror
8:57:56 - LMT 1901
9:00 - +09
# Papua New Guinea
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Port_Moresby 9:48:40 - LMT 1880
9:48:32 - PMMT 1895 # Port Moresby Mean Time
10:00 - +10
@@ -646,7 +654,7 @@
11:00 - +11
# Pitcairn
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Pitcairn -8:40:20 - LMT 1901 # Adamstown
-8:30 - -0830 1998 Apr 27 0:00
-8:00 - -08
@@ -725,13 +733,13 @@
# That web page currently lists transitions for 2012/3 and 2013/4.
# Assume the pattern instituted in 2012 will continue indefinitely.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule WS 2010 only - Sep lastSun 0:00 1 -
Rule WS 2011 only - Apr Sat>=1 4:00 0 -
Rule WS 2011 only - Sep lastSat 3:00 1 -
Rule WS 2012 max - Apr Sun>=1 4:00 0 -
Rule WS 2012 max - Sep lastSun 3:00 1 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Apia 12:33:04 - LMT 1892 Jul 5
-11:26:56 - LMT 1911
-11:30 - -1130 1950
@@ -740,7 +748,7 @@
# Solomon Is
# excludes Bougainville, for which see Papua New Guinea
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara
11:00 - +11
@@ -763,27 +771,27 @@
# was "11 hours slow on G.M.T." Go with Thorsen and assume Shanks & Pottenger
# are off by an hour starting in 1901.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Fakaofo -11:24:56 - LMT 1901
-11:00 - -11 2011 Dec 30
13:00 - +13
# Tonga
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Tonga 1999 only - Oct 7 2:00s 1:00 -
Rule Tonga 2000 only - Mar 19 2:00s 0 -
Rule Tonga 2000 2001 - Nov Sun>=1 2:00 1:00 -
Rule Tonga 2001 2002 - Jan lastSun 2:00 0 -
Rule Tonga 2016 only - Nov Sun>=1 2:00 1:00 -
Rule Tonga 2017 only - Jan Sun>=15 3:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Tongatapu 12:19:20 - LMT 1901
12:20 - +1220 1941
13:00 - +13 1999
13:00 Tonga +13/+14
# Tuvalu
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Funafuti 11:56:52 - LMT 1901
12:00 - +12
@@ -844,25 +852,25 @@
# uninhabited since World War II; was probably like Pacific/Kiritimati
# Wake
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Wake 11:06:28 - LMT 1901
12:00 - +12
# Vanuatu
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Vanuatu 1983 only - Sep 25 0:00 1:00 -
Rule Vanuatu 1984 1991 - Mar Sun>=23 0:00 0 -
Rule Vanuatu 1984 only - Oct 23 0:00 1:00 -
Rule Vanuatu 1985 1991 - Sep Sun>=23 0:00 1:00 -
Rule Vanuatu 1992 1993 - Jan Sun>=23 0:00 0 -
Rule Vanuatu 1992 only - Oct Sun>=23 0:00 1:00 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila
11:00 Vanuatu +11/+12
# Wallis and Futuna
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Wallis 12:15:20 - LMT 1901
12:00 - +12
@@ -1248,6 +1256,22 @@
# in WA or its introduction in SA had anything to do with the genesis
# of this time zone. My hunch is that it's been around since well
# before 1975. I remember seeing it noted on road maps decades ago.
+#
+# From Gilmore Davidson (2019-04-08):
+# https://www.abc.net.au/news/2019-04-08/this-remote-stretch-of-desert-has-its-own-custom-time-zone/10981000
+# ... include[s] a rough description of the geographical boundaries...
+# "The time zone exists for about 340 kilometres and takes in the tiny
+# roadhouse communities of Cocklebiddy, Madura, Eucla and Border Village."
+# ... and an indication that the zone has definitely been in existence
+# since before the 1970 cut-off of the database ...
+# From Paul Eggert (2019-05-17):
+# That ABC Esperance story by Christien de Garis also says:
+# Although the Central Western Time Zone is not officially recognised (your
+# phones won't automatically change), there is a sign instructing you which
+# way to wind your clocks 45 minutes and scrawled underneath one of them in
+# Texta is the word: 'Why'?
+# "Good question," Mr Pike said.
+# "I don't even know that, and it's been going for over 50 years."
# From Paul Eggert (2006-12-15):
# For lack of better info, assume the tradition dates back to the
@@ -1566,6 +1590,42 @@
###############################################################################
+# Bonin (Ogasawara) Islands and Marcus Island (Minami-Tori-shima)
+
+# From Wakaba (2019-01-28) via Phake Nick:
+# National Diet Library of Japan has several reports by Japanese Government
+# officers that describe the time used in islands when they visited there.
+# According to them (and other sources such as newspapers), standard time UTC
+# + 10 (JST + 1) and DST UTC + 11 (JST + 2) was used until its return to Japan
+# at 1968-06-26 00:00 JST. The exact periods of DST are still unknown.
+# I guessed Guam, Mariana, and Bonin and Marcus districts might have
+# synchronized their DST periods, but reports imply they had their own
+# decisions, i.e. there were three or more different time zones....
+#
+# https://wiki.suikawiki.org/n/小笠原諸島の標準時
+
+# From Phake Nick (2019-02-12):
+# Because their last time change to return to Japanese time when they returned
+# to Japanese rule was right before 1970, ... per the current tz database
+# rule, the information doesn't warrant creation of a new timezone for Bonin
+# Islands itself and is thus as an anecdotal note for interest purpose only.
+# ... [The abovementioned link] described some special timekeeping phenomenon
+# regarding Marcus island, another remote island currently owned by Japanese
+# in the same administrative unit as Bonin Islands. Many reports claim that
+# the American coastal guard on the American quarter of the island use its own
+# coastal guard time, and most sources describe the time as UTC+11, being two
+# hours faster than JST used by some Japanese personnel on the island. Some
+# sites describe it as same as Wake Island/Guam time although it would be
+# incorrect to be same as Guam. And then in a few Japanese governmental
+# report from 1980s (from National Institute of Information and Communications
+# Technology) regarding the construction of VLBI facility on the Marcus
+# Island, it claimed that there are three time standards being used on the
+# island at the time which include not just JST (UTC+9) or [US]CG time
+# (UTC+11) but also a JMSDF time (UTC+10) (Japan Maritime Self-Defense
+# Force). Unfortunately there are no other sources that mentioned such time
+# and there are also no information on things like how the time was used.
+
+
# Fiji
# Howse writes (p 153) that in 1879 the British governor of Fiji
@@ -1823,12 +1883,21 @@
# ... at 12.30 am (by legal time in New South Wales) on 4 October 2015.
# http://www.norfolkisland.gov.nf/nia/MediaRelease/Media%20Release%20Norfolk%20Island%20Standard%20Time%20Change.pdf
-# From Paul Eggert (2015-09-23):
+# From Paul Eggert (2019-08-28):
# Transitions before 2015 are from timeanddate.com, which consulted
# the Norfolk Island Museum and the Australian Bureau of Meteorology's
# Norfolk Island station, and found no record of Norfolk observing DST
# other than in 1974/5. See:
# https://www.timeanddate.com/time/australia/norfolk-island.html
+# However, disagree with timeanddate about the 1975-03-02 transition;
+# timeanddate has 02:00 but 02:00s corresponds to what the NSW law said
+# (thanks to Michael Deckers).
+
+# Norfolk started observing Australian DST in spring 2019.
+# From Kyle Czech (2019-08-13):
+# https://www.legislation.gov.au/Details/F2018L01702
+# From Michael Deckers (2019-08-14):
+# https://www.legislation.gov.au/Details/F2019C00010
# Palau
# See commentary for Micronesia.
diff --git a/tools/java/org/unicode/cldr/util/data/backward b/tools/java/org/unicode/cldr/util/data/backward
index b4ae3cf..e13ae52 100644
--- a/tools/java/org/unicode/cldr/util/data/backward
+++ b/tools/java/org/unicode/cldr/util/data/backward
@@ -17,6 +17,7 @@
Link America/Argentina/Cordoba America/Cordoba
Link America/Tijuana America/Ensenada
Link America/Indiana/Indianapolis America/Fort_Wayne
+Link America/Nuuk America/Godthab
Link America/Indiana/Indianapolis America/Indianapolis
Link America/Argentina/Jujuy America/Jujuy
Link America/Indiana/Knox America/Knox_IN
diff --git a/tools/java/org/unicode/cldr/util/data/births/outdated.data b/tools/java/org/unicode/cldr/util/data/births/outdated.data
index bb0eee6..9231de8 100644
--- a/tools/java/org/unicode/cldr/util/data/births/outdated.data
+++ b/tools/java/org/unicode/cldr/util/data/births/outdated.data
Binary files differ
diff --git a/tools/java/org/unicode/cldr/util/data/births/outdatedEnglish.data b/tools/java/org/unicode/cldr/util/data/births/outdatedEnglish.data
index 4482857..2a9aa60 100644
--- a/tools/java/org/unicode/cldr/util/data/births/outdatedEnglish.data
+++ b/tools/java/org/unicode/cldr/util/data/births/outdatedEnglish.data
Binary files differ
diff --git a/tools/java/org/unicode/cldr/util/data/chart_messages.html b/tools/java/org/unicode/cldr/util/data/chart_messages.html
index 3e35449..a574ecc 100644
--- a/tools/java/org/unicode/cldr/util/data/chart_messages.html
+++ b/tools/java/org/unicode/cldr/util/data/chart_messages.html
@@ -122,7 +122,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b> <a
href="http://unicode.org/cldr/data/common/supplemental/supplementalData.xml">
@@ -185,7 +185,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b> <a
href="http://unicode.org/cldr/data/common/supplemental/supplementalData.xml">
@@ -249,7 +249,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b> <a
href="http://unicode.org/cldr/data/common/supplemental/supplementalData.xml">
@@ -272,7 +272,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>. However, such reports should be limited to cases
where the information here deviates from <a
href="http://unstats.un.org/unsd/methods/m49/m49regin.htm">UN
@@ -294,7 +294,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b>under <mapTimezones> in <a
href="http://unicode.org/cldr/data/common/supplemental/metaZones.xml">metaZones.xml</a>
@@ -332,7 +332,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b> <a
href="http://unicode.org/cldr/data/common/supplemental/characters.xml">characters.xml</a>
@@ -353,7 +353,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">
bug report</a>.</li>
<li><b>XML Source:</b> <a
href="http://unicode.org/cldr/data/common/supplemental/supplementalMetadata.xml">
@@ -397,7 +397,7 @@
<ul>
<li><b>Reporting Defects:</b> If you find errors or omissions
in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">bug
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">bug
report</a>.</li>
</ul>
</td>
@@ -432,7 +432,7 @@
and following.</li>
<li><b>Reporting Defects:</b> When you find errors or
omissions in this data, please report the information with a <a
- target="_blank" href="http://unicode.org/cldr/trac/newticket">bug
+ target="_blank" href="http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket">bug
report</a>. But first read "Reporting Defects" on <a
href="http://cldr.unicode.org/index/cldr-spec/plural-rules" target='spec'>Plural
Rules</a>.</li>
diff --git a/tools/java/org/unicode/cldr/util/data/codepointToIsoCurrencyCode.tsv b/tools/java/org/unicode/cldr/util/data/codepointToIsoCurrencyCode.tsv
new file mode 100644
index 0000000..e8c3ca3
--- /dev/null
+++ b/tools/java/org/unicode/cldr/util/data/codepointToIsoCurrencyCode.tsv
@@ -0,0 +1,28 @@
+#Char CCode Hex UnicodeName
+£ GBP U+00A3 POUND SIGN
+¤ XXX U+00A4 CURRENCY SIGN
+¥ JPY U+00A5 YEN SIGN
+֏ AMD U+058F ARMENIAN DRAM SIGN
+؋ AFN U+060B AFGHANI SIGN
+৳ BDT U+09F3 BENGALI RUPEE SIGN
+฿ THB U+0E3F THAI CURRENCY SYMBOL BAHT
+៛ KHR U+17DB KHMER CURRENCY SYMBOL RIEL
+₡ CRC U+20A1 COLON SIGN
+₦ NGN U+20A6 NAIRA SIGN
+₧ ESP U+20A7 PESETA SIGN
+₩ KRW U+20A9 WON SIGN
+₪ ILS U+20AA NEW SHEQEL SIGN
+₫ VND U+20AB DONG SIGN
+€ EUR U+20AC EURO SIGN
+₭ LAK U+20AD KIP SIGN
+₮ MNT U+20AE TUGRIK SIGN
+₱ PHP U+20B1 PESO SIGN
+₲ PYG U+20B2 GUARANI SIGN
+₴ UAH U+20B4 HRYVNIA SIGN
+₸ KZT U+20B8 TENGE SIGN
+₹ INR U+20B9 INDIAN RUPEE SIGN
+₼ AZN U+20BC MANAT SIGN
+₽ RUB U+20BD RUBLE SIGN
+₾ GEL U+20BE LARI SIGN
+₵ GHS U+20B5 CEDI SIGN
+₺ TRY U+20BA TURKISH LIRA SIGN
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/data/country_language_population_raw.txt b/tools/java/org/unicode/cldr/util/data/country_language_population_raw.txt
index 13a4893..f7877cb 100644
--- a/tools/java/org/unicode/cldr/util/data/country_language_population_raw.txt
+++ b/tools/java/org/unicode/cldr/util/data/country_language_population_raw.txt
@@ -1,4 +1,7 @@
-* CName CCode CPopulation CLiteracy CGdp OfficialStatus Language LCode LPopulation WritingPop References Notes
+# CName CCode CPopulation CLiteracy CGdp OfficialStatus Language LCode LPopulation WritingPop References Notes
+#######
+#WARNING: this file is in TSV format (for pasting from a spreadsheet); make sure you maintain tabs!
+#######
Afghanistan AF "34,940,837" 28% "69,450,000,000" official_regional Baluchi bal "233,000"
Afghanistan AF "34,940,837" 28% "69,450,000,000" Hazaragi haz 5.9%
Afghanistan AF "34,940,837" 28% "69,450,000,000" Kazakh (Arabic) kk_Arab "2,000" "http://en.wikipedia.org/wiki/Kazakh_language - the script is an assumption, needs a reference"
@@ -112,7 +115,7 @@
Brazil BR "208,846,892" 90% "3,248,000,000,000" Guajajára gub "17,500"
Brazil BR "208,846,892" 90% "3,248,000,000,000" Italian it "583,000"
Brazil BR "208,846,892" 90% "3,248,000,000,000" Japanese ja "443,000"
-Brazil BR "208,846,892" 90% "3,248,000,000,000" Kaingang kgp "20,900"
+Brazil BR "208,846,892" 90% "3,248,000,000,000" Kaingang kgp "50,000" http://www.portalkaingang.org/index_povo_1default.htm
Brazil BR "208,846,892" 90% "3,248,000,000,000" Korean ko "43,200"
Brazil BR "208,846,892" 90% "3,248,000,000,000" Nheengatu yrl "10,900"
Brazil BR "208,846,892" 90% "3,248,000,000,000" official Portuguese pt 91%
@@ -501,6 +504,7 @@
India IN "1,296,834,042" 63% "9,474,000,000,000" Hadothi hoj "1,060,000"
India IN "1,296,834,042" 63% "9,474,000,000,000" Haryanvi bgc "15,600,000" 55% http://en.wikipedia.org/wiki/Haryanvi http://www.indianetzone.com/7/haryanvi.htm little literature mostly folksongs; writers use std Hindi; claim of 55% literacy
India IN "1,296,834,042" 63% "9,474,000,000,000" official Hindi hi 41% "http://www.censusindia.net/ Figure for Hindi includes 2nd language users, India Census data."
+India IN "1,296,834,042" 63% "9,474,000,000,000" Hindi (Latn) hi_Latn 0.1% "No hard figures for this yet, so this is a placeholder figure."
India IN "1,296,834,042" 63% "9,474,000,000,000" Ho hoc "1,290,000" https://www.cia.gov/library/publications/the-world-factbook/geos/in.html
India IN "1,296,834,042" 63% "9,474,000,000,000" Kachhi kfr "968,000"
India IN "1,296,834,042" 63% "9,474,000,000,000" Kanauji bjj "7,200,000" 60%
@@ -738,7 +742,7 @@
Malaysia MY "31,809,660" 93% "933,300,000,000" Banjar bjn "5,000"
Malaysia MY "31,809,660" 93% "933,300,000,000" Buginese bug "25,200" http://www.joshuaproject.net/peopctry.php?rop3=101703&rog3=MY
Malaysia MY "31,809,660" 93% "933,300,000,000" Central Dusun dtp "177,000"
-Malaysia MY "31,809,660" 93% "933,300,000,000" Chinese (Traditional) zh_Hant 17%
+Malaysia MY "31,809,660" 93% "933,300,000,000" Chinese (Traditional) zh 17%
Malaysia MY "31,809,660" 93% "933,300,000,000" English en 21%
Malaysia MY "31,809,660" 93% "933,300,000,000" Iban iba "792,000"
Malaysia MY "31,809,660" 93% "933,300,000,000" Javanese jv "379,000"
@@ -956,6 +960,7 @@
Pakistan PK "207,862,518" 55% "1,061,000,000,000" Sindhi sd 12%
Pakistan PK "207,862,518" 55% "1,061,000,000,000" Southern Hindko hnd "855,000"
Pakistan PK "207,862,518" 55% "1,061,000,000,000" Tajik (Arabic) tg_Arab "684,000"
+Pakistan PK "207,862,518" 55% "1,061,000,000,000" Torwali trw "110,000"
Pakistan PK "207,862,518" 55% "1,061,000,000,000" official Urdu ur 95% http://en.wikipedia.org/wiki/Languages_of_Pakistan - More than 95% of Pakistanis can speak or understand Urdu as their second or third language
Pakistan PK "207,862,518" 55% "1,061,000,000,000" Wadiyara Koli kxp "239,000"
Pakistan PK "207,862,518" 55% "1,061,000,000,000" Western Balochi bgn "1,190,000" 5% http://www.ethnologue.com/language/bgn low literacy
diff --git a/tools/java/org/unicode/cldr/util/data/dl_iso_table_a1.xml b/tools/java/org/unicode/cldr/util/data/dl_iso_table_a1.xml
index 7e6059b..20be53b 100644
--- a/tools/java/org/unicode/cldr/util/data/dl_iso_table_a1.xml
+++ b/tools/java/org/unicode/cldr/util/data/dl_iso_table_a1.xml
@@ -531,6 +531,13 @@
<CcyMnrUnts>2</CcyMnrUnts>
</CcyNtry>
<CcyNtry>
+ <CtryNm>ESWATINI</CtryNm>
+ <CcyNm>Lilangeni</CcyNm>
+ <Ccy>SZL</Ccy>
+ <CcyNbr>748</CcyNbr>
+ <CcyMnrUnts>2</CcyMnrUnts>
+ </CcyNtry>
+ <CcyNtry>
<CtryNm>ETHIOPIA</CtryNm>
<CcyNm>Ethiopian Birr</CcyNm>
<Ccy>ETB</Ccy>
@@ -986,7 +993,7 @@
<CcyMnrUnts>2</CcyMnrUnts>
</CcyNtry>
<CcyNtry>
- <CtryNm>MACEDONIA (THE FORMER YUGOSLAV REPUBLIC OF)</CtryNm>
+ <CtryNm>NORTH MACEDONIA</CtryNm>
<CcyNm>Denar</CcyNm>
<Ccy>MKD</Ccy>
<CcyNbr>807</CcyNbr>
@@ -1589,13 +1596,6 @@
<CcyMnrUnts>2</CcyMnrUnts>
</CcyNtry>
<CcyNtry>
- <CtryNm>ESWATINI</CtryNm>
- <CcyNm>Lilangeni</CcyNm>
- <Ccy>SZL</Ccy>
- <CcyNbr>748</CcyNbr>
- <CcyMnrUnts>2</CcyMnrUnts>
- </CcyNtry>
- <CcyNtry>
<CtryNm>SWEDEN</CtryNm>
<CcyNm>Swedish Krona</CcyNm>
<Ccy>SEK</Ccy>
diff --git a/tools/java/org/unicode/cldr/util/data/dl_iso_table_a3.xml b/tools/java/org/unicode/cldr/util/data/dl_iso_table_a3.xml
index fdf3db5..32f6dd7 100644
--- a/tools/java/org/unicode/cldr/util/data/dl_iso_table_a3.xml
+++ b/tools/java/org/unicode/cldr/util/data/dl_iso_table_a3.xml
@@ -1041,7 +1041,7 @@
<CtryNm>YUGOSLAVIA</CtryNm>
<CcyNm>New Yugoslavian Dinar</CcyNm>
<Ccy>YUD</Ccy>
- <CcyNbr>891</CcyNbr>
+ <CcyNbr>890</CcyNbr>
<WthdrwlDt>1990-01</WthdrwlDt>
</HstrcCcyNtry>
<HstrcCcyNtry>
diff --git a/tools/java/org/unicode/cldr/util/data/emoji/emoji-test.txt b/tools/java/org/unicode/cldr/util/data/emoji/emoji-test.txt
index 9f8d343..d3c6d12 100644
--- a/tools/java/org/unicode/cldr/util/data/emoji/emoji-test.txt
+++ b/tools/java/org/unicode/cldr/util/data/emoji/emoji-test.txt
@@ -1,11 +1,11 @@
# emoji-test.txt
-# Date: 2020-01-21, 13:40:25 GMT
+# Date: 2020-09-12, 22:19:50 GMT
# © 2020 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# Emoji Keyboard/Display Test Data for UTS #51
-# Version: 13.0
+# Version: 13.1
#
# For documentation and usage, see http://www.unicode.org/reports/tr51
#
@@ -33,2736 +33,3158 @@
# group: Smileys & Emotion
# subgroup: face-smiling
-1F600 ; fully-qualified # 😀 E1.0 grinning face
-1F603 ; fully-qualified # 😃 E0.6 grinning face with big eyes
-1F604 ; fully-qualified # 😄 E0.6 grinning face with smiling eyes
-1F601 ; fully-qualified # 😁 E0.6 beaming face with smiling eyes
-1F606 ; fully-qualified # 😆 E0.6 grinning squinting face
-1F605 ; fully-qualified # 😅 E0.6 grinning face with sweat
-1F923 ; fully-qualified # 🤣 E3.0 rolling on the floor laughing
-1F602 ; fully-qualified # 😂 E0.6 face with tears of joy
-1F642 ; fully-qualified # 🙂 E1.0 slightly smiling face
-1F643 ; fully-qualified # 🙃 E1.0 upside-down face
-1F609 ; fully-qualified # 😉 E0.6 winking face
-1F60A ; fully-qualified # 😊 E0.6 smiling face with smiling eyes
-1F607 ; fully-qualified # 😇 E1.0 smiling face with halo
+1F600 ; fully-qualified # 😀 E1.0 grinning face
+1F603 ; fully-qualified # 😃 E0.6 grinning face with big eyes
+1F604 ; fully-qualified # 😄 E0.6 grinning face with smiling eyes
+1F601 ; fully-qualified # 😁 E0.6 beaming face with smiling eyes
+1F606 ; fully-qualified # 😆 E0.6 grinning squinting face
+1F605 ; fully-qualified # 😅 E0.6 grinning face with sweat
+1F923 ; fully-qualified # 🤣 E3.0 rolling on the floor laughing
+1F602 ; fully-qualified # 😂 E0.6 face with tears of joy
+1F642 ; fully-qualified # 🙂 E1.0 slightly smiling face
+1F643 ; fully-qualified # 🙃 E1.0 upside-down face
+1F609 ; fully-qualified # 😉 E0.6 winking face
+1F60A ; fully-qualified # 😊 E0.6 smiling face with smiling eyes
+1F607 ; fully-qualified # 😇 E1.0 smiling face with halo
# subgroup: face-affection
-1F970 ; fully-qualified # 🥰 E11.0 smiling face with hearts
-1F60D ; fully-qualified # 😍 E0.6 smiling face with heart-eyes
-1F929 ; fully-qualified # 🤩 E5.0 star-struck
-1F618 ; fully-qualified # 😘 E0.6 face blowing a kiss
-1F617 ; fully-qualified # 😗 E1.0 kissing face
-263A FE0F ; fully-qualified # ☺️ E0.6 smiling face
-263A ; unqualified # ☺ E0.6 smiling face
-1F61A ; fully-qualified # 😚 E0.6 kissing face with closed eyes
-1F619 ; fully-qualified # 😙 E1.0 kissing face with smiling eyes
-1F972 ; fully-qualified # 🥲 E13.0 smiling face with tear
+1F970 ; fully-qualified # 🥰 E11.0 smiling face with hearts
+1F60D ; fully-qualified # 😍 E0.6 smiling face with heart-eyes
+1F929 ; fully-qualified # 🤩 E5.0 star-struck
+1F618 ; fully-qualified # 😘 E0.6 face blowing a kiss
+1F617 ; fully-qualified # 😗 E1.0 kissing face
+263A FE0F ; fully-qualified # ☺️ E0.6 smiling face
+263A ; unqualified # ☺ E0.6 smiling face
+1F61A ; fully-qualified # 😚 E0.6 kissing face with closed eyes
+1F619 ; fully-qualified # 😙 E1.0 kissing face with smiling eyes
+1F972 ; fully-qualified # 🥲 E13.0 smiling face with tear
# subgroup: face-tongue
-1F60B ; fully-qualified # 😋 E0.6 face savoring food
-1F61B ; fully-qualified # 😛 E1.0 face with tongue
-1F61C ; fully-qualified # 😜 E0.6 winking face with tongue
-1F92A ; fully-qualified # 🤪 E5.0 zany face
-1F61D ; fully-qualified # 😝 E0.6 squinting face with tongue
-1F911 ; fully-qualified # 🤑 E1.0 money-mouth face
+1F60B ; fully-qualified # 😋 E0.6 face savoring food
+1F61B ; fully-qualified # 😛 E1.0 face with tongue
+1F61C ; fully-qualified # 😜 E0.6 winking face with tongue
+1F92A ; fully-qualified # 🤪 E5.0 zany face
+1F61D ; fully-qualified # 😝 E0.6 squinting face with tongue
+1F911 ; fully-qualified # 🤑 E1.0 money-mouth face
# subgroup: face-hand
-1F917 ; fully-qualified # 🤗 E1.0 hugging face
-1F92D ; fully-qualified # 🤭 E5.0 face with hand over mouth
-1F92B ; fully-qualified # 🤫 E5.0 shushing face
-1F914 ; fully-qualified # 🤔 E1.0 thinking face
+1F917 ; fully-qualified # 🤗 E1.0 hugging face
+1F92D ; fully-qualified # 🤭 E5.0 face with hand over mouth
+1F92B ; fully-qualified # 🤫 E5.0 shushing face
+1F914 ; fully-qualified # 🤔 E1.0 thinking face
# subgroup: face-neutral-skeptical
-1F910 ; fully-qualified # 🤐 E1.0 zipper-mouth face
-1F928 ; fully-qualified # 🤨 E5.0 face with raised eyebrow
-1F610 ; fully-qualified # 😐 E0.7 neutral face
-1F611 ; fully-qualified # 😑 E1.0 expressionless face
-1F636 ; fully-qualified # 😶 E1.0 face without mouth
-1F60F ; fully-qualified # 😏 E0.6 smirking face
-1F612 ; fully-qualified # 😒 E0.6 unamused face
-1F644 ; fully-qualified # 🙄 E1.0 face with rolling eyes
-1F62C ; fully-qualified # 😬 E1.0 grimacing face
-1F925 ; fully-qualified # 🤥 E3.0 lying face
+1F910 ; fully-qualified # 🤐 E1.0 zipper-mouth face
+1F928 ; fully-qualified # 🤨 E5.0 face with raised eyebrow
+1F610 ; fully-qualified # 😐 E0.7 neutral face
+1F611 ; fully-qualified # 😑 E1.0 expressionless face
+1F636 ; fully-qualified # 😶 E1.0 face without mouth
+1F636 200D 1F32B FE0F ; fully-qualified # 😶🌫️ E13.1 face in clouds
+1F636 200D 1F32B ; minimally-qualified # 😶🌫 E13.1 face in clouds
+1F60F ; fully-qualified # 😏 E0.6 smirking face
+1F612 ; fully-qualified # 😒 E0.6 unamused face
+1F644 ; fully-qualified # 🙄 E1.0 face with rolling eyes
+1F62C ; fully-qualified # 😬 E1.0 grimacing face
+1F62E 200D 1F4A8 ; fully-qualified # 😮💨 E13.1 face exhaling
+1F925 ; fully-qualified # 🤥 E3.0 lying face
# subgroup: face-sleepy
-1F60C ; fully-qualified # 😌 E0.6 relieved face
-1F614 ; fully-qualified # 😔 E0.6 pensive face
-1F62A ; fully-qualified # 😪 E0.6 sleepy face
-1F924 ; fully-qualified # 🤤 E3.0 drooling face
-1F634 ; fully-qualified # 😴 E1.0 sleeping face
+1F60C ; fully-qualified # 😌 E0.6 relieved face
+1F614 ; fully-qualified # 😔 E0.6 pensive face
+1F62A ; fully-qualified # 😪 E0.6 sleepy face
+1F924 ; fully-qualified # 🤤 E3.0 drooling face
+1F634 ; fully-qualified # 😴 E1.0 sleeping face
# subgroup: face-unwell
-1F637 ; fully-qualified # 😷 E0.6 face with medical mask
-1F912 ; fully-qualified # 🤒 E1.0 face with thermometer
-1F915 ; fully-qualified # 🤕 E1.0 face with head-bandage
-1F922 ; fully-qualified # 🤢 E3.0 nauseated face
-1F92E ; fully-qualified # 🤮 E5.0 face vomiting
-1F927 ; fully-qualified # 🤧 E3.0 sneezing face
-1F975 ; fully-qualified # 🥵 E11.0 hot face
-1F976 ; fully-qualified # 🥶 E11.0 cold face
-1F974 ; fully-qualified # 🥴 E11.0 woozy face
-1F635 ; fully-qualified # 😵 E0.6 dizzy face
-1F92F ; fully-qualified # 🤯 E5.0 exploding head
+1F637 ; fully-qualified # 😷 E0.6 face with medical mask
+1F912 ; fully-qualified # 🤒 E1.0 face with thermometer
+1F915 ; fully-qualified # 🤕 E1.0 face with head-bandage
+1F922 ; fully-qualified # 🤢 E3.0 nauseated face
+1F92E ; fully-qualified # 🤮 E5.0 face vomiting
+1F927 ; fully-qualified # 🤧 E3.0 sneezing face
+1F975 ; fully-qualified # 🥵 E11.0 hot face
+1F976 ; fully-qualified # 🥶 E11.0 cold face
+1F974 ; fully-qualified # 🥴 E11.0 woozy face
+1F635 ; fully-qualified # 😵 E0.6 knocked-out face
+1F635 200D 1F4AB ; fully-qualified # 😵💫 E13.1 face with spiral eyes
+1F92F ; fully-qualified # 🤯 E5.0 exploding head
# subgroup: face-hat
-1F920 ; fully-qualified # 🤠 E3.0 cowboy hat face
-1F973 ; fully-qualified # 🥳 E11.0 partying face
-1F978 ; fully-qualified # 🥸 E13.0 disguised face
+1F920 ; fully-qualified # 🤠 E3.0 cowboy hat face
+1F973 ; fully-qualified # 🥳 E11.0 partying face
+1F978 ; fully-qualified # 🥸 E13.0 disguised face
# subgroup: face-glasses
-1F60E ; fully-qualified # 😎 E1.0 smiling face with sunglasses
-1F913 ; fully-qualified # 🤓 E1.0 nerd face
-1F9D0 ; fully-qualified # 🧐 E5.0 face with monocle
+1F60E ; fully-qualified # 😎 E1.0 smiling face with sunglasses
+1F913 ; fully-qualified # 🤓 E1.0 nerd face
+1F9D0 ; fully-qualified # 🧐 E5.0 face with monocle
# subgroup: face-concerned
-1F615 ; fully-qualified # 😕 E1.0 confused face
-1F61F ; fully-qualified # 😟 E1.0 worried face
-1F641 ; fully-qualified # 🙁 E1.0 slightly frowning face
-2639 FE0F ; fully-qualified # ☹️ E0.7 frowning face
-2639 ; unqualified # ☹ E0.7 frowning face
-1F62E ; fully-qualified # 😮 E1.0 face with open mouth
-1F62F ; fully-qualified # 😯 E1.0 hushed face
-1F632 ; fully-qualified # 😲 E0.6 astonished face
-1F633 ; fully-qualified # 😳 E0.6 flushed face
-1F97A ; fully-qualified # 🥺 E11.0 pleading face
-1F626 ; fully-qualified # 😦 E1.0 frowning face with open mouth
-1F627 ; fully-qualified # 😧 E1.0 anguished face
-1F628 ; fully-qualified # 😨 E0.6 fearful face
-1F630 ; fully-qualified # 😰 E0.6 anxious face with sweat
-1F625 ; fully-qualified # 😥 E0.6 sad but relieved face
-1F622 ; fully-qualified # 😢 E0.6 crying face
-1F62D ; fully-qualified # 😭 E0.6 loudly crying face
-1F631 ; fully-qualified # 😱 E0.6 face screaming in fear
-1F616 ; fully-qualified # 😖 E0.6 confounded face
-1F623 ; fully-qualified # 😣 E0.6 persevering face
-1F61E ; fully-qualified # 😞 E0.6 disappointed face
-1F613 ; fully-qualified # 😓 E0.6 downcast face with sweat
-1F629 ; fully-qualified # 😩 E0.6 weary face
-1F62B ; fully-qualified # 😫 E0.6 tired face
-1F971 ; fully-qualified # 🥱 E12.0 yawning face
+1F615 ; fully-qualified # 😕 E1.0 confused face
+1F61F ; fully-qualified # 😟 E1.0 worried face
+1F641 ; fully-qualified # 🙁 E1.0 slightly frowning face
+2639 FE0F ; fully-qualified # ☹️ E0.7 frowning face
+2639 ; unqualified # ☹ E0.7 frowning face
+1F62E ; fully-qualified # 😮 E1.0 face with open mouth
+1F62F ; fully-qualified # 😯 E1.0 hushed face
+1F632 ; fully-qualified # 😲 E0.6 astonished face
+1F633 ; fully-qualified # 😳 E0.6 flushed face
+1F97A ; fully-qualified # 🥺 E11.0 pleading face
+1F626 ; fully-qualified # 😦 E1.0 frowning face with open mouth
+1F627 ; fully-qualified # 😧 E1.0 anguished face
+1F628 ; fully-qualified # 😨 E0.6 fearful face
+1F630 ; fully-qualified # 😰 E0.6 anxious face with sweat
+1F625 ; fully-qualified # 😥 E0.6 sad but relieved face
+1F622 ; fully-qualified # 😢 E0.6 crying face
+1F62D ; fully-qualified # 😭 E0.6 loudly crying face
+1F631 ; fully-qualified # 😱 E0.6 face screaming in fear
+1F616 ; fully-qualified # 😖 E0.6 confounded face
+1F623 ; fully-qualified # 😣 E0.6 persevering face
+1F61E ; fully-qualified # 😞 E0.6 disappointed face
+1F613 ; fully-qualified # 😓 E0.6 downcast face with sweat
+1F629 ; fully-qualified # 😩 E0.6 weary face
+1F62B ; fully-qualified # 😫 E0.6 tired face
+1F971 ; fully-qualified # 🥱 E12.0 yawning face
# subgroup: face-negative
-1F624 ; fully-qualified # 😤 E0.6 face with steam from nose
-1F621 ; fully-qualified # 😡 E0.6 pouting face
-1F620 ; fully-qualified # 😠 E0.6 angry face
-1F92C ; fully-qualified # 🤬 E5.0 face with symbols on mouth
-1F608 ; fully-qualified # 😈 E1.0 smiling face with horns
-1F47F ; fully-qualified # 👿 E0.6 angry face with horns
-1F480 ; fully-qualified # 💀 E0.6 skull
-2620 FE0F ; fully-qualified # ☠️ E1.0 skull and crossbones
-2620 ; unqualified # ☠ E1.0 skull and crossbones
+1F624 ; fully-qualified # 😤 E0.6 face with steam from nose
+1F621 ; fully-qualified # 😡 E0.6 pouting face
+1F620 ; fully-qualified # 😠 E0.6 angry face
+1F92C ; fully-qualified # 🤬 E5.0 face with symbols on mouth
+1F608 ; fully-qualified # 😈 E1.0 smiling face with horns
+1F47F ; fully-qualified # 👿 E0.6 angry face with horns
+1F480 ; fully-qualified # 💀 E0.6 skull
+2620 FE0F ; fully-qualified # ☠️ E1.0 skull and crossbones
+2620 ; unqualified # ☠ E1.0 skull and crossbones
# subgroup: face-costume
-1F4A9 ; fully-qualified # 💩 E0.6 pile of poo
-1F921 ; fully-qualified # 🤡 E3.0 clown face
-1F479 ; fully-qualified # 👹 E0.6 ogre
-1F47A ; fully-qualified # 👺 E0.6 goblin
-1F47B ; fully-qualified # 👻 E0.6 ghost
-1F47D ; fully-qualified # 👽 E0.6 alien
-1F47E ; fully-qualified # 👾 E0.6 alien monster
-1F916 ; fully-qualified # 🤖 E1.0 robot
+1F4A9 ; fully-qualified # 💩 E0.6 pile of poo
+1F921 ; fully-qualified # 🤡 E3.0 clown face
+1F479 ; fully-qualified # 👹 E0.6 ogre
+1F47A ; fully-qualified # 👺 E0.6 goblin
+1F47B ; fully-qualified # 👻 E0.6 ghost
+1F47D ; fully-qualified # 👽 E0.6 alien
+1F47E ; fully-qualified # 👾 E0.6 alien monster
+1F916 ; fully-qualified # 🤖 E1.0 robot
# subgroup: cat-face
-1F63A ; fully-qualified # 😺 E0.6 grinning cat
-1F638 ; fully-qualified # 😸 E0.6 grinning cat with smiling eyes
-1F639 ; fully-qualified # 😹 E0.6 cat with tears of joy
-1F63B ; fully-qualified # 😻 E0.6 smiling cat with heart-eyes
-1F63C ; fully-qualified # 😼 E0.6 cat with wry smile
-1F63D ; fully-qualified # 😽 E0.6 kissing cat
-1F640 ; fully-qualified # 🙀 E0.6 weary cat
-1F63F ; fully-qualified # 😿 E0.6 crying cat
-1F63E ; fully-qualified # 😾 E0.6 pouting cat
+1F63A ; fully-qualified # 😺 E0.6 grinning cat
+1F638 ; fully-qualified # 😸 E0.6 grinning cat with smiling eyes
+1F639 ; fully-qualified # 😹 E0.6 cat with tears of joy
+1F63B ; fully-qualified # 😻 E0.6 smiling cat with heart-eyes
+1F63C ; fully-qualified # 😼 E0.6 cat with wry smile
+1F63D ; fully-qualified # 😽 E0.6 kissing cat
+1F640 ; fully-qualified # 🙀 E0.6 weary cat
+1F63F ; fully-qualified # 😿 E0.6 crying cat
+1F63E ; fully-qualified # 😾 E0.6 pouting cat
# subgroup: monkey-face
-1F648 ; fully-qualified # 🙈 E0.6 see-no-evil monkey
-1F649 ; fully-qualified # 🙉 E0.6 hear-no-evil monkey
-1F64A ; fully-qualified # 🙊 E0.6 speak-no-evil monkey
+1F648 ; fully-qualified # 🙈 E0.6 see-no-evil monkey
+1F649 ; fully-qualified # 🙉 E0.6 hear-no-evil monkey
+1F64A ; fully-qualified # 🙊 E0.6 speak-no-evil monkey
# subgroup: emotion
-1F48B ; fully-qualified # 💋 E0.6 kiss mark
-1F48C ; fully-qualified # 💌 E0.6 love letter
-1F498 ; fully-qualified # 💘 E0.6 heart with arrow
-1F49D ; fully-qualified # 💝 E0.6 heart with ribbon
-1F496 ; fully-qualified # 💖 E0.6 sparkling heart
-1F497 ; fully-qualified # 💗 E0.6 growing heart
-1F493 ; fully-qualified # 💓 E0.6 beating heart
-1F49E ; fully-qualified # 💞 E0.6 revolving hearts
-1F495 ; fully-qualified # 💕 E0.6 two hearts
-1F49F ; fully-qualified # 💟 E0.6 heart decoration
-2763 FE0F ; fully-qualified # ❣️ E1.0 heart exclamation
-2763 ; unqualified # ❣ E1.0 heart exclamation
-1F494 ; fully-qualified # 💔 E0.6 broken heart
-2764 FE0F ; fully-qualified # ❤️ E0.6 red heart
-2764 ; unqualified # ❤ E0.6 red heart
-1F9E1 ; fully-qualified # 🧡 E5.0 orange heart
-1F49B ; fully-qualified # 💛 E0.6 yellow heart
-1F49A ; fully-qualified # 💚 E0.6 green heart
-1F499 ; fully-qualified # 💙 E0.6 blue heart
-1F49C ; fully-qualified # 💜 E0.6 purple heart
-1F90E ; fully-qualified # 🤎 E12.0 brown heart
-1F5A4 ; fully-qualified # 🖤 E3.0 black heart
-1F90D ; fully-qualified # 🤍 E12.0 white heart
-1F4AF ; fully-qualified # 💯 E0.6 hundred points
-1F4A2 ; fully-qualified # 💢 E0.6 anger symbol
-1F4A5 ; fully-qualified # 💥 E0.6 collision
-1F4AB ; fully-qualified # 💫 E0.6 dizzy
-1F4A6 ; fully-qualified # 💦 E0.6 sweat droplets
-1F4A8 ; fully-qualified # 💨 E0.6 dashing away
-1F573 FE0F ; fully-qualified # 🕳️ E0.7 hole
-1F573 ; unqualified # 🕳 E0.7 hole
-1F4A3 ; fully-qualified # 💣 E0.6 bomb
-1F4AC ; fully-qualified # 💬 E0.6 speech balloon
-1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # 👁️🗨️ E2.0 eye in speech bubble
-1F441 200D 1F5E8 FE0F ; unqualified # 👁🗨️ E2.0 eye in speech bubble
-1F441 FE0F 200D 1F5E8 ; unqualified # 👁️🗨 E2.0 eye in speech bubble
-1F441 200D 1F5E8 ; unqualified # 👁🗨 E2.0 eye in speech bubble
-1F5E8 FE0F ; fully-qualified # 🗨️ E2.0 left speech bubble
-1F5E8 ; unqualified # 🗨 E2.0 left speech bubble
-1F5EF FE0F ; fully-qualified # 🗯️ E0.7 right anger bubble
-1F5EF ; unqualified # 🗯 E0.7 right anger bubble
-1F4AD ; fully-qualified # 💭 E1.0 thought balloon
-1F4A4 ; fully-qualified # 💤 E0.6 zzz
+1F48B ; fully-qualified # 💋 E0.6 kiss mark
+1F48C ; fully-qualified # 💌 E0.6 love letter
+1F498 ; fully-qualified # 💘 E0.6 heart with arrow
+1F49D ; fully-qualified # 💝 E0.6 heart with ribbon
+1F496 ; fully-qualified # 💖 E0.6 sparkling heart
+1F497 ; fully-qualified # 💗 E0.6 growing heart
+1F493 ; fully-qualified # 💓 E0.6 beating heart
+1F49E ; fully-qualified # 💞 E0.6 revolving hearts
+1F495 ; fully-qualified # 💕 E0.6 two hearts
+1F49F ; fully-qualified # 💟 E0.6 heart decoration
+2763 FE0F ; fully-qualified # ❣️ E1.0 heart exclamation
+2763 ; unqualified # ❣ E1.0 heart exclamation
+1F494 ; fully-qualified # 💔 E0.6 broken heart
+2764 FE0F 200D 1F525 ; fully-qualified # ❤️🔥 E13.1 heart on fire
+2764 200D 1F525 ; unqualified # ❤🔥 E13.1 heart on fire
+2764 FE0F 200D 1FA79 ; fully-qualified # ❤️🩹 E13.1 mending heart
+2764 200D 1FA79 ; unqualified # ❤🩹 E13.1 mending heart
+2764 FE0F ; fully-qualified # ❤️ E0.6 red heart
+2764 ; unqualified # ❤ E0.6 red heart
+1F9E1 ; fully-qualified # 🧡 E5.0 orange heart
+1F49B ; fully-qualified # 💛 E0.6 yellow heart
+1F49A ; fully-qualified # 💚 E0.6 green heart
+1F499 ; fully-qualified # 💙 E0.6 blue heart
+1F49C ; fully-qualified # 💜 E0.6 purple heart
+1F90E ; fully-qualified # 🤎 E12.0 brown heart
+1F5A4 ; fully-qualified # 🖤 E3.0 black heart
+1F90D ; fully-qualified # 🤍 E12.0 white heart
+1F4AF ; fully-qualified # 💯 E0.6 hundred points
+1F4A2 ; fully-qualified # 💢 E0.6 anger symbol
+1F4A5 ; fully-qualified # 💥 E0.6 collision
+1F4AB ; fully-qualified # 💫 E0.6 dizzy
+1F4A6 ; fully-qualified # 💦 E0.6 sweat droplets
+1F4A8 ; fully-qualified # 💨 E0.6 dashing away
+1F573 FE0F ; fully-qualified # 🕳️ E0.7 hole
+1F573 ; unqualified # 🕳 E0.7 hole
+1F4A3 ; fully-qualified # 💣 E0.6 bomb
+1F4AC ; fully-qualified # 💬 E0.6 speech balloon
+1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # 👁️🗨️ E2.0 eye in speech bubble
+1F441 200D 1F5E8 FE0F ; unqualified # 👁🗨️ E2.0 eye in speech bubble
+1F441 FE0F 200D 1F5E8 ; unqualified # 👁️🗨 E2.0 eye in speech bubble
+1F441 200D 1F5E8 ; unqualified # 👁🗨 E2.0 eye in speech bubble
+1F5E8 FE0F ; fully-qualified # 🗨️ E2.0 left speech bubble
+1F5E8 ; unqualified # 🗨 E2.0 left speech bubble
+1F5EF FE0F ; fully-qualified # 🗯️ E0.7 right anger bubble
+1F5EF ; unqualified # 🗯 E0.7 right anger bubble
+1F4AD ; fully-qualified # 💭 E1.0 thought balloon
+1F4A4 ; fully-qualified # 💤 E0.6 zzz
-# Smileys & Emotion subtotal: 162
-# Smileys & Emotion subtotal: 162 w/o modifiers
+# Smileys & Emotion subtotal: 170
+# Smileys & Emotion subtotal: 170 w/o modifiers
# group: People & Body
# subgroup: hand-fingers-open
-1F44B ; fully-qualified # 👋 E0.6 waving hand
-1F44B 1F3FB ; fully-qualified # 👋🏻 E1.0 waving hand: light skin tone
-1F44B 1F3FC ; fully-qualified # 👋🏼 E1.0 waving hand: medium-light skin tone
-1F44B 1F3FD ; fully-qualified # 👋🏽 E1.0 waving hand: medium skin tone
-1F44B 1F3FE ; fully-qualified # 👋🏾 E1.0 waving hand: medium-dark skin tone
-1F44B 1F3FF ; fully-qualified # 👋🏿 E1.0 waving hand: dark skin tone
-1F91A ; fully-qualified # 🤚 E3.0 raised back of hand
-1F91A 1F3FB ; fully-qualified # 🤚🏻 E3.0 raised back of hand: light skin tone
-1F91A 1F3FC ; fully-qualified # 🤚🏼 E3.0 raised back of hand: medium-light skin tone
-1F91A 1F3FD ; fully-qualified # 🤚🏽 E3.0 raised back of hand: medium skin tone
-1F91A 1F3FE ; fully-qualified # 🤚🏾 E3.0 raised back of hand: medium-dark skin tone
-1F91A 1F3FF ; fully-qualified # 🤚🏿 E3.0 raised back of hand: dark skin tone
-1F590 FE0F ; fully-qualified # 🖐️ E0.7 hand with fingers splayed
-1F590 ; unqualified # 🖐 E0.7 hand with fingers splayed
-1F590 1F3FB ; fully-qualified # 🖐🏻 E1.0 hand with fingers splayed: light skin tone
-1F590 1F3FC ; fully-qualified # 🖐🏼 E1.0 hand with fingers splayed: medium-light skin tone
-1F590 1F3FD ; fully-qualified # 🖐🏽 E1.0 hand with fingers splayed: medium skin tone
-1F590 1F3FE ; fully-qualified # 🖐🏾 E1.0 hand with fingers splayed: medium-dark skin tone
-1F590 1F3FF ; fully-qualified # 🖐🏿 E1.0 hand with fingers splayed: dark skin tone
-270B ; fully-qualified # ✋ E0.6 raised hand
-270B 1F3FB ; fully-qualified # ✋🏻 E1.0 raised hand: light skin tone
-270B 1F3FC ; fully-qualified # ✋🏼 E1.0 raised hand: medium-light skin tone
-270B 1F3FD ; fully-qualified # ✋🏽 E1.0 raised hand: medium skin tone
-270B 1F3FE ; fully-qualified # ✋🏾 E1.0 raised hand: medium-dark skin tone
-270B 1F3FF ; fully-qualified # ✋🏿 E1.0 raised hand: dark skin tone
-1F596 ; fully-qualified # 🖖 E1.0 vulcan salute
-1F596 1F3FB ; fully-qualified # 🖖🏻 E1.0 vulcan salute: light skin tone
-1F596 1F3FC ; fully-qualified # 🖖🏼 E1.0 vulcan salute: medium-light skin tone
-1F596 1F3FD ; fully-qualified # 🖖🏽 E1.0 vulcan salute: medium skin tone
-1F596 1F3FE ; fully-qualified # 🖖🏾 E1.0 vulcan salute: medium-dark skin tone
-1F596 1F3FF ; fully-qualified # 🖖🏿 E1.0 vulcan salute: dark skin tone
+1F44B ; fully-qualified # 👋 E0.6 waving hand
+1F44B 1F3FB ; fully-qualified # 👋🏻 E1.0 waving hand: light skin tone
+1F44B 1F3FC ; fully-qualified # 👋🏼 E1.0 waving hand: medium-light skin tone
+1F44B 1F3FD ; fully-qualified # 👋🏽 E1.0 waving hand: medium skin tone
+1F44B 1F3FE ; fully-qualified # 👋🏾 E1.0 waving hand: medium-dark skin tone
+1F44B 1F3FF ; fully-qualified # 👋🏿 E1.0 waving hand: dark skin tone
+1F91A ; fully-qualified # 🤚 E3.0 raised back of hand
+1F91A 1F3FB ; fully-qualified # 🤚🏻 E3.0 raised back of hand: light skin tone
+1F91A 1F3FC ; fully-qualified # 🤚🏼 E3.0 raised back of hand: medium-light skin tone
+1F91A 1F3FD ; fully-qualified # 🤚🏽 E3.0 raised back of hand: medium skin tone
+1F91A 1F3FE ; fully-qualified # 🤚🏾 E3.0 raised back of hand: medium-dark skin tone
+1F91A 1F3FF ; fully-qualified # 🤚🏿 E3.0 raised back of hand: dark skin tone
+1F590 FE0F ; fully-qualified # 🖐️ E0.7 hand with fingers splayed
+1F590 ; unqualified # 🖐 E0.7 hand with fingers splayed
+1F590 1F3FB ; fully-qualified # 🖐🏻 E1.0 hand with fingers splayed: light skin tone
+1F590 1F3FC ; fully-qualified # 🖐🏼 E1.0 hand with fingers splayed: medium-light skin tone
+1F590 1F3FD ; fully-qualified # 🖐🏽 E1.0 hand with fingers splayed: medium skin tone
+1F590 1F3FE ; fully-qualified # 🖐🏾 E1.0 hand with fingers splayed: medium-dark skin tone
+1F590 1F3FF ; fully-qualified # 🖐🏿 E1.0 hand with fingers splayed: dark skin tone
+270B ; fully-qualified # ✋ E0.6 raised hand
+270B 1F3FB ; fully-qualified # ✋🏻 E1.0 raised hand: light skin tone
+270B 1F3FC ; fully-qualified # ✋🏼 E1.0 raised hand: medium-light skin tone
+270B 1F3FD ; fully-qualified # ✋🏽 E1.0 raised hand: medium skin tone
+270B 1F3FE ; fully-qualified # ✋🏾 E1.0 raised hand: medium-dark skin tone
+270B 1F3FF ; fully-qualified # ✋🏿 E1.0 raised hand: dark skin tone
+1F596 ; fully-qualified # 🖖 E1.0 vulcan salute
+1F596 1F3FB ; fully-qualified # 🖖🏻 E1.0 vulcan salute: light skin tone
+1F596 1F3FC ; fully-qualified # 🖖🏼 E1.0 vulcan salute: medium-light skin tone
+1F596 1F3FD ; fully-qualified # 🖖🏽 E1.0 vulcan salute: medium skin tone
+1F596 1F3FE ; fully-qualified # 🖖🏾 E1.0 vulcan salute: medium-dark skin tone
+1F596 1F3FF ; fully-qualified # 🖖🏿 E1.0 vulcan salute: dark skin tone
# subgroup: hand-fingers-partial
-1F44C ; fully-qualified # 👌 E0.6 OK hand
-1F44C 1F3FB ; fully-qualified # 👌🏻 E1.0 OK hand: light skin tone
-1F44C 1F3FC ; fully-qualified # 👌🏼 E1.0 OK hand: medium-light skin tone
-1F44C 1F3FD ; fully-qualified # 👌🏽 E1.0 OK hand: medium skin tone
-1F44C 1F3FE ; fully-qualified # 👌🏾 E1.0 OK hand: medium-dark skin tone
-1F44C 1F3FF ; fully-qualified # 👌🏿 E1.0 OK hand: dark skin tone
-1F90C ; fully-qualified # 🤌 E13.0 pinched fingers
-1F90C 1F3FB ; fully-qualified # 🤌🏻 E13.0 pinched fingers: light skin tone
-1F90C 1F3FC ; fully-qualified # 🤌🏼 E13.0 pinched fingers: medium-light skin tone
-1F90C 1F3FD ; fully-qualified # 🤌🏽 E13.0 pinched fingers: medium skin tone
-1F90C 1F3FE ; fully-qualified # 🤌🏾 E13.0 pinched fingers: medium-dark skin tone
-1F90C 1F3FF ; fully-qualified # 🤌🏿 E13.0 pinched fingers: dark skin tone
-1F90F ; fully-qualified # 🤏 E12.0 pinching hand
-1F90F 1F3FB ; fully-qualified # 🤏🏻 E12.0 pinching hand: light skin tone
-1F90F 1F3FC ; fully-qualified # 🤏🏼 E12.0 pinching hand: medium-light skin tone
-1F90F 1F3FD ; fully-qualified # 🤏🏽 E12.0 pinching hand: medium skin tone
-1F90F 1F3FE ; fully-qualified # 🤏🏾 E12.0 pinching hand: medium-dark skin tone
-1F90F 1F3FF ; fully-qualified # 🤏🏿 E12.0 pinching hand: dark skin tone
-270C FE0F ; fully-qualified # ✌️ E0.6 victory hand
-270C ; unqualified # ✌ E0.6 victory hand
-270C 1F3FB ; fully-qualified # ✌🏻 E1.0 victory hand: light skin tone
-270C 1F3FC ; fully-qualified # ✌🏼 E1.0 victory hand: medium-light skin tone
-270C 1F3FD ; fully-qualified # ✌🏽 E1.0 victory hand: medium skin tone
-270C 1F3FE ; fully-qualified # ✌🏾 E1.0 victory hand: medium-dark skin tone
-270C 1F3FF ; fully-qualified # ✌🏿 E1.0 victory hand: dark skin tone
-1F91E ; fully-qualified # 🤞 E3.0 crossed fingers
-1F91E 1F3FB ; fully-qualified # 🤞🏻 E3.0 crossed fingers: light skin tone
-1F91E 1F3FC ; fully-qualified # 🤞🏼 E3.0 crossed fingers: medium-light skin tone
-1F91E 1F3FD ; fully-qualified # 🤞🏽 E3.0 crossed fingers: medium skin tone
-1F91E 1F3FE ; fully-qualified # 🤞🏾 E3.0 crossed fingers: medium-dark skin tone
-1F91E 1F3FF ; fully-qualified # 🤞🏿 E3.0 crossed fingers: dark skin tone
-1F91F ; fully-qualified # 🤟 E5.0 love-you gesture
-1F91F 1F3FB ; fully-qualified # 🤟🏻 E5.0 love-you gesture: light skin tone
-1F91F 1F3FC ; fully-qualified # 🤟🏼 E5.0 love-you gesture: medium-light skin tone
-1F91F 1F3FD ; fully-qualified # 🤟🏽 E5.0 love-you gesture: medium skin tone
-1F91F 1F3FE ; fully-qualified # 🤟🏾 E5.0 love-you gesture: medium-dark skin tone
-1F91F 1F3FF ; fully-qualified # 🤟🏿 E5.0 love-you gesture: dark skin tone
-1F918 ; fully-qualified # 🤘 E1.0 sign of the horns
-1F918 1F3FB ; fully-qualified # 🤘🏻 E1.0 sign of the horns: light skin tone
-1F918 1F3FC ; fully-qualified # 🤘🏼 E1.0 sign of the horns: medium-light skin tone
-1F918 1F3FD ; fully-qualified # 🤘🏽 E1.0 sign of the horns: medium skin tone
-1F918 1F3FE ; fully-qualified # 🤘🏾 E1.0 sign of the horns: medium-dark skin tone
-1F918 1F3FF ; fully-qualified # 🤘🏿 E1.0 sign of the horns: dark skin tone
-1F919 ; fully-qualified # 🤙 E3.0 call me hand
-1F919 1F3FB ; fully-qualified # 🤙🏻 E3.0 call me hand: light skin tone
-1F919 1F3FC ; fully-qualified # 🤙🏼 E3.0 call me hand: medium-light skin tone
-1F919 1F3FD ; fully-qualified # 🤙🏽 E3.0 call me hand: medium skin tone
-1F919 1F3FE ; fully-qualified # 🤙🏾 E3.0 call me hand: medium-dark skin tone
-1F919 1F3FF ; fully-qualified # 🤙🏿 E3.0 call me hand: dark skin tone
+1F44C ; fully-qualified # 👌 E0.6 OK hand
+1F44C 1F3FB ; fully-qualified # 👌🏻 E1.0 OK hand: light skin tone
+1F44C 1F3FC ; fully-qualified # 👌🏼 E1.0 OK hand: medium-light skin tone
+1F44C 1F3FD ; fully-qualified # 👌🏽 E1.0 OK hand: medium skin tone
+1F44C 1F3FE ; fully-qualified # 👌🏾 E1.0 OK hand: medium-dark skin tone
+1F44C 1F3FF ; fully-qualified # 👌🏿 E1.0 OK hand: dark skin tone
+1F90C ; fully-qualified # 🤌 E13.0 pinched fingers
+1F90C 1F3FB ; fully-qualified # 🤌🏻 E13.0 pinched fingers: light skin tone
+1F90C 1F3FC ; fully-qualified # 🤌🏼 E13.0 pinched fingers: medium-light skin tone
+1F90C 1F3FD ; fully-qualified # 🤌🏽 E13.0 pinched fingers: medium skin tone
+1F90C 1F3FE ; fully-qualified # 🤌🏾 E13.0 pinched fingers: medium-dark skin tone
+1F90C 1F3FF ; fully-qualified # 🤌🏿 E13.0 pinched fingers: dark skin tone
+1F90F ; fully-qualified # 🤏 E12.0 pinching hand
+1F90F 1F3FB ; fully-qualified # 🤏🏻 E12.0 pinching hand: light skin tone
+1F90F 1F3FC ; fully-qualified # 🤏🏼 E12.0 pinching hand: medium-light skin tone
+1F90F 1F3FD ; fully-qualified # 🤏🏽 E12.0 pinching hand: medium skin tone
+1F90F 1F3FE ; fully-qualified # 🤏🏾 E12.0 pinching hand: medium-dark skin tone
+1F90F 1F3FF ; fully-qualified # 🤏🏿 E12.0 pinching hand: dark skin tone
+270C FE0F ; fully-qualified # ✌️ E0.6 victory hand
+270C ; unqualified # ✌ E0.6 victory hand
+270C 1F3FB ; fully-qualified # ✌🏻 E1.0 victory hand: light skin tone
+270C 1F3FC ; fully-qualified # ✌🏼 E1.0 victory hand: medium-light skin tone
+270C 1F3FD ; fully-qualified # ✌🏽 E1.0 victory hand: medium skin tone
+270C 1F3FE ; fully-qualified # ✌🏾 E1.0 victory hand: medium-dark skin tone
+270C 1F3FF ; fully-qualified # ✌🏿 E1.0 victory hand: dark skin tone
+1F91E ; fully-qualified # 🤞 E3.0 crossed fingers
+1F91E 1F3FB ; fully-qualified # 🤞🏻 E3.0 crossed fingers: light skin tone
+1F91E 1F3FC ; fully-qualified # 🤞🏼 E3.0 crossed fingers: medium-light skin tone
+1F91E 1F3FD ; fully-qualified # 🤞🏽 E3.0 crossed fingers: medium skin tone
+1F91E 1F3FE ; fully-qualified # 🤞🏾 E3.0 crossed fingers: medium-dark skin tone
+1F91E 1F3FF ; fully-qualified # 🤞🏿 E3.0 crossed fingers: dark skin tone
+1F91F ; fully-qualified # 🤟 E5.0 love-you gesture
+1F91F 1F3FB ; fully-qualified # 🤟🏻 E5.0 love-you gesture: light skin tone
+1F91F 1F3FC ; fully-qualified # 🤟🏼 E5.0 love-you gesture: medium-light skin tone
+1F91F 1F3FD ; fully-qualified # 🤟🏽 E5.0 love-you gesture: medium skin tone
+1F91F 1F3FE ; fully-qualified # 🤟🏾 E5.0 love-you gesture: medium-dark skin tone
+1F91F 1F3FF ; fully-qualified # 🤟🏿 E5.0 love-you gesture: dark skin tone
+1F918 ; fully-qualified # 🤘 E1.0 sign of the horns
+1F918 1F3FB ; fully-qualified # 🤘🏻 E1.0 sign of the horns: light skin tone
+1F918 1F3FC ; fully-qualified # 🤘🏼 E1.0 sign of the horns: medium-light skin tone
+1F918 1F3FD ; fully-qualified # 🤘🏽 E1.0 sign of the horns: medium skin tone
+1F918 1F3FE ; fully-qualified # 🤘🏾 E1.0 sign of the horns: medium-dark skin tone
+1F918 1F3FF ; fully-qualified # 🤘🏿 E1.0 sign of the horns: dark skin tone
+1F919 ; fully-qualified # 🤙 E3.0 call me hand
+1F919 1F3FB ; fully-qualified # 🤙🏻 E3.0 call me hand: light skin tone
+1F919 1F3FC ; fully-qualified # 🤙🏼 E3.0 call me hand: medium-light skin tone
+1F919 1F3FD ; fully-qualified # 🤙🏽 E3.0 call me hand: medium skin tone
+1F919 1F3FE ; fully-qualified # 🤙🏾 E3.0 call me hand: medium-dark skin tone
+1F919 1F3FF ; fully-qualified # 🤙🏿 E3.0 call me hand: dark skin tone
# subgroup: hand-single-finger
-1F448 ; fully-qualified # 👈 E0.6 backhand index pointing left
-1F448 1F3FB ; fully-qualified # 👈🏻 E1.0 backhand index pointing left: light skin tone
-1F448 1F3FC ; fully-qualified # 👈🏼 E1.0 backhand index pointing left: medium-light skin tone
-1F448 1F3FD ; fully-qualified # 👈🏽 E1.0 backhand index pointing left: medium skin tone
-1F448 1F3FE ; fully-qualified # 👈🏾 E1.0 backhand index pointing left: medium-dark skin tone
-1F448 1F3FF ; fully-qualified # 👈🏿 E1.0 backhand index pointing left: dark skin tone
-1F449 ; fully-qualified # 👉 E0.6 backhand index pointing right
-1F449 1F3FB ; fully-qualified # 👉🏻 E1.0 backhand index pointing right: light skin tone
-1F449 1F3FC ; fully-qualified # 👉🏼 E1.0 backhand index pointing right: medium-light skin tone
-1F449 1F3FD ; fully-qualified # 👉🏽 E1.0 backhand index pointing right: medium skin tone
-1F449 1F3FE ; fully-qualified # 👉🏾 E1.0 backhand index pointing right: medium-dark skin tone
-1F449 1F3FF ; fully-qualified # 👉🏿 E1.0 backhand index pointing right: dark skin tone
-1F446 ; fully-qualified # 👆 E0.6 backhand index pointing up
-1F446 1F3FB ; fully-qualified # 👆🏻 E1.0 backhand index pointing up: light skin tone
-1F446 1F3FC ; fully-qualified # 👆🏼 E1.0 backhand index pointing up: medium-light skin tone
-1F446 1F3FD ; fully-qualified # 👆🏽 E1.0 backhand index pointing up: medium skin tone
-1F446 1F3FE ; fully-qualified # 👆🏾 E1.0 backhand index pointing up: medium-dark skin tone
-1F446 1F3FF ; fully-qualified # 👆🏿 E1.0 backhand index pointing up: dark skin tone
-1F595 ; fully-qualified # 🖕 E1.0 middle finger
-1F595 1F3FB ; fully-qualified # 🖕🏻 E1.0 middle finger: light skin tone
-1F595 1F3FC ; fully-qualified # 🖕🏼 E1.0 middle finger: medium-light skin tone
-1F595 1F3FD ; fully-qualified # 🖕🏽 E1.0 middle finger: medium skin tone
-1F595 1F3FE ; fully-qualified # 🖕🏾 E1.0 middle finger: medium-dark skin tone
-1F595 1F3FF ; fully-qualified # 🖕🏿 E1.0 middle finger: dark skin tone
-1F447 ; fully-qualified # 👇 E0.6 backhand index pointing down
-1F447 1F3FB ; fully-qualified # 👇🏻 E1.0 backhand index pointing down: light skin tone
-1F447 1F3FC ; fully-qualified # 👇🏼 E1.0 backhand index pointing down: medium-light skin tone
-1F447 1F3FD ; fully-qualified # 👇🏽 E1.0 backhand index pointing down: medium skin tone
-1F447 1F3FE ; fully-qualified # 👇🏾 E1.0 backhand index pointing down: medium-dark skin tone
-1F447 1F3FF ; fully-qualified # 👇🏿 E1.0 backhand index pointing down: dark skin tone
-261D FE0F ; fully-qualified # ☝️ E0.6 index pointing up
-261D ; unqualified # ☝ E0.6 index pointing up
-261D 1F3FB ; fully-qualified # ☝🏻 E1.0 index pointing up: light skin tone
-261D 1F3FC ; fully-qualified # ☝🏼 E1.0 index pointing up: medium-light skin tone
-261D 1F3FD ; fully-qualified # ☝🏽 E1.0 index pointing up: medium skin tone
-261D 1F3FE ; fully-qualified # ☝🏾 E1.0 index pointing up: medium-dark skin tone
-261D 1F3FF ; fully-qualified # ☝🏿 E1.0 index pointing up: dark skin tone
+1F448 ; fully-qualified # 👈 E0.6 backhand index pointing left
+1F448 1F3FB ; fully-qualified # 👈🏻 E1.0 backhand index pointing left: light skin tone
+1F448 1F3FC ; fully-qualified # 👈🏼 E1.0 backhand index pointing left: medium-light skin tone
+1F448 1F3FD ; fully-qualified # 👈🏽 E1.0 backhand index pointing left: medium skin tone
+1F448 1F3FE ; fully-qualified # 👈🏾 E1.0 backhand index pointing left: medium-dark skin tone
+1F448 1F3FF ; fully-qualified # 👈🏿 E1.0 backhand index pointing left: dark skin tone
+1F449 ; fully-qualified # 👉 E0.6 backhand index pointing right
+1F449 1F3FB ; fully-qualified # 👉🏻 E1.0 backhand index pointing right: light skin tone
+1F449 1F3FC ; fully-qualified # 👉🏼 E1.0 backhand index pointing right: medium-light skin tone
+1F449 1F3FD ; fully-qualified # 👉🏽 E1.0 backhand index pointing right: medium skin tone
+1F449 1F3FE ; fully-qualified # 👉🏾 E1.0 backhand index pointing right: medium-dark skin tone
+1F449 1F3FF ; fully-qualified # 👉🏿 E1.0 backhand index pointing right: dark skin tone
+1F446 ; fully-qualified # 👆 E0.6 backhand index pointing up
+1F446 1F3FB ; fully-qualified # 👆🏻 E1.0 backhand index pointing up: light skin tone
+1F446 1F3FC ; fully-qualified # 👆🏼 E1.0 backhand index pointing up: medium-light skin tone
+1F446 1F3FD ; fully-qualified # 👆🏽 E1.0 backhand index pointing up: medium skin tone
+1F446 1F3FE ; fully-qualified # 👆🏾 E1.0 backhand index pointing up: medium-dark skin tone
+1F446 1F3FF ; fully-qualified # 👆🏿 E1.0 backhand index pointing up: dark skin tone
+1F595 ; fully-qualified # 🖕 E1.0 middle finger
+1F595 1F3FB ; fully-qualified # 🖕🏻 E1.0 middle finger: light skin tone
+1F595 1F3FC ; fully-qualified # 🖕🏼 E1.0 middle finger: medium-light skin tone
+1F595 1F3FD ; fully-qualified # 🖕🏽 E1.0 middle finger: medium skin tone
+1F595 1F3FE ; fully-qualified # 🖕🏾 E1.0 middle finger: medium-dark skin tone
+1F595 1F3FF ; fully-qualified # 🖕🏿 E1.0 middle finger: dark skin tone
+1F447 ; fully-qualified # 👇 E0.6 backhand index pointing down
+1F447 1F3FB ; fully-qualified # 👇🏻 E1.0 backhand index pointing down: light skin tone
+1F447 1F3FC ; fully-qualified # 👇🏼 E1.0 backhand index pointing down: medium-light skin tone
+1F447 1F3FD ; fully-qualified # 👇🏽 E1.0 backhand index pointing down: medium skin tone
+1F447 1F3FE ; fully-qualified # 👇🏾 E1.0 backhand index pointing down: medium-dark skin tone
+1F447 1F3FF ; fully-qualified # 👇🏿 E1.0 backhand index pointing down: dark skin tone
+261D FE0F ; fully-qualified # ☝️ E0.6 index pointing up
+261D ; unqualified # ☝ E0.6 index pointing up
+261D 1F3FB ; fully-qualified # ☝🏻 E1.0 index pointing up: light skin tone
+261D 1F3FC ; fully-qualified # ☝🏼 E1.0 index pointing up: medium-light skin tone
+261D 1F3FD ; fully-qualified # ☝🏽 E1.0 index pointing up: medium skin tone
+261D 1F3FE ; fully-qualified # ☝🏾 E1.0 index pointing up: medium-dark skin tone
+261D 1F3FF ; fully-qualified # ☝🏿 E1.0 index pointing up: dark skin tone
# subgroup: hand-fingers-closed
-1F44D ; fully-qualified # 👍 E0.6 thumbs up
-1F44D 1F3FB ; fully-qualified # 👍🏻 E1.0 thumbs up: light skin tone
-1F44D 1F3FC ; fully-qualified # 👍🏼 E1.0 thumbs up: medium-light skin tone
-1F44D 1F3FD ; fully-qualified # 👍🏽 E1.0 thumbs up: medium skin tone
-1F44D 1F3FE ; fully-qualified # 👍🏾 E1.0 thumbs up: medium-dark skin tone
-1F44D 1F3FF ; fully-qualified # 👍🏿 E1.0 thumbs up: dark skin tone
-1F44E ; fully-qualified # 👎 E0.6 thumbs down
-1F44E 1F3FB ; fully-qualified # 👎🏻 E1.0 thumbs down: light skin tone
-1F44E 1F3FC ; fully-qualified # 👎🏼 E1.0 thumbs down: medium-light skin tone
-1F44E 1F3FD ; fully-qualified # 👎🏽 E1.0 thumbs down: medium skin tone
-1F44E 1F3FE ; fully-qualified # 👎🏾 E1.0 thumbs down: medium-dark skin tone
-1F44E 1F3FF ; fully-qualified # 👎🏿 E1.0 thumbs down: dark skin tone
-270A ; fully-qualified # ✊ E0.6 raised fist
-270A 1F3FB ; fully-qualified # ✊🏻 E1.0 raised fist: light skin tone
-270A 1F3FC ; fully-qualified # ✊🏼 E1.0 raised fist: medium-light skin tone
-270A 1F3FD ; fully-qualified # ✊🏽 E1.0 raised fist: medium skin tone
-270A 1F3FE ; fully-qualified # ✊🏾 E1.0 raised fist: medium-dark skin tone
-270A 1F3FF ; fully-qualified # ✊🏿 E1.0 raised fist: dark skin tone
-1F44A ; fully-qualified # 👊 E0.6 oncoming fist
-1F44A 1F3FB ; fully-qualified # 👊🏻 E1.0 oncoming fist: light skin tone
-1F44A 1F3FC ; fully-qualified # 👊🏼 E1.0 oncoming fist: medium-light skin tone
-1F44A 1F3FD ; fully-qualified # 👊🏽 E1.0 oncoming fist: medium skin tone
-1F44A 1F3FE ; fully-qualified # 👊🏾 E1.0 oncoming fist: medium-dark skin tone
-1F44A 1F3FF ; fully-qualified # 👊🏿 E1.0 oncoming fist: dark skin tone
-1F91B ; fully-qualified # 🤛 E3.0 left-facing fist
-1F91B 1F3FB ; fully-qualified # 🤛🏻 E3.0 left-facing fist: light skin tone
-1F91B 1F3FC ; fully-qualified # 🤛🏼 E3.0 left-facing fist: medium-light skin tone
-1F91B 1F3FD ; fully-qualified # 🤛🏽 E3.0 left-facing fist: medium skin tone
-1F91B 1F3FE ; fully-qualified # 🤛🏾 E3.0 left-facing fist: medium-dark skin tone
-1F91B 1F3FF ; fully-qualified # 🤛🏿 E3.0 left-facing fist: dark skin tone
-1F91C ; fully-qualified # 🤜 E3.0 right-facing fist
-1F91C 1F3FB ; fully-qualified # 🤜🏻 E3.0 right-facing fist: light skin tone
-1F91C 1F3FC ; fully-qualified # 🤜🏼 E3.0 right-facing fist: medium-light skin tone
-1F91C 1F3FD ; fully-qualified # 🤜🏽 E3.0 right-facing fist: medium skin tone
-1F91C 1F3FE ; fully-qualified # 🤜🏾 E3.0 right-facing fist: medium-dark skin tone
-1F91C 1F3FF ; fully-qualified # 🤜🏿 E3.0 right-facing fist: dark skin tone
+1F44D ; fully-qualified # 👍 E0.6 thumbs up
+1F44D 1F3FB ; fully-qualified # 👍🏻 E1.0 thumbs up: light skin tone
+1F44D 1F3FC ; fully-qualified # 👍🏼 E1.0 thumbs up: medium-light skin tone
+1F44D 1F3FD ; fully-qualified # 👍🏽 E1.0 thumbs up: medium skin tone
+1F44D 1F3FE ; fully-qualified # 👍🏾 E1.0 thumbs up: medium-dark skin tone
+1F44D 1F3FF ; fully-qualified # 👍🏿 E1.0 thumbs up: dark skin tone
+1F44E ; fully-qualified # 👎 E0.6 thumbs down
+1F44E 1F3FB ; fully-qualified # 👎🏻 E1.0 thumbs down: light skin tone
+1F44E 1F3FC ; fully-qualified # 👎🏼 E1.0 thumbs down: medium-light skin tone
+1F44E 1F3FD ; fully-qualified # 👎🏽 E1.0 thumbs down: medium skin tone
+1F44E 1F3FE ; fully-qualified # 👎🏾 E1.0 thumbs down: medium-dark skin tone
+1F44E 1F3FF ; fully-qualified # 👎🏿 E1.0 thumbs down: dark skin tone
+270A ; fully-qualified # ✊ E0.6 raised fist
+270A 1F3FB ; fully-qualified # ✊🏻 E1.0 raised fist: light skin tone
+270A 1F3FC ; fully-qualified # ✊🏼 E1.0 raised fist: medium-light skin tone
+270A 1F3FD ; fully-qualified # ✊🏽 E1.0 raised fist: medium skin tone
+270A 1F3FE ; fully-qualified # ✊🏾 E1.0 raised fist: medium-dark skin tone
+270A 1F3FF ; fully-qualified # ✊🏿 E1.0 raised fist: dark skin tone
+1F44A ; fully-qualified # 👊 E0.6 oncoming fist
+1F44A 1F3FB ; fully-qualified # 👊🏻 E1.0 oncoming fist: light skin tone
+1F44A 1F3FC ; fully-qualified # 👊🏼 E1.0 oncoming fist: medium-light skin tone
+1F44A 1F3FD ; fully-qualified # 👊🏽 E1.0 oncoming fist: medium skin tone
+1F44A 1F3FE ; fully-qualified # 👊🏾 E1.0 oncoming fist: medium-dark skin tone
+1F44A 1F3FF ; fully-qualified # 👊🏿 E1.0 oncoming fist: dark skin tone
+1F91B ; fully-qualified # 🤛 E3.0 left-facing fist
+1F91B 1F3FB ; fully-qualified # 🤛🏻 E3.0 left-facing fist: light skin tone
+1F91B 1F3FC ; fully-qualified # 🤛🏼 E3.0 left-facing fist: medium-light skin tone
+1F91B 1F3FD ; fully-qualified # 🤛🏽 E3.0 left-facing fist: medium skin tone
+1F91B 1F3FE ; fully-qualified # 🤛🏾 E3.0 left-facing fist: medium-dark skin tone
+1F91B 1F3FF ; fully-qualified # 🤛🏿 E3.0 left-facing fist: dark skin tone
+1F91C ; fully-qualified # 🤜 E3.0 right-facing fist
+1F91C 1F3FB ; fully-qualified # 🤜🏻 E3.0 right-facing fist: light skin tone
+1F91C 1F3FC ; fully-qualified # 🤜🏼 E3.0 right-facing fist: medium-light skin tone
+1F91C 1F3FD ; fully-qualified # 🤜🏽 E3.0 right-facing fist: medium skin tone
+1F91C 1F3FE ; fully-qualified # 🤜🏾 E3.0 right-facing fist: medium-dark skin tone
+1F91C 1F3FF ; fully-qualified # 🤜🏿 E3.0 right-facing fist: dark skin tone
# subgroup: hands
-1F44F ; fully-qualified # 👏 E0.6 clapping hands
-1F44F 1F3FB ; fully-qualified # 👏🏻 E1.0 clapping hands: light skin tone
-1F44F 1F3FC ; fully-qualified # 👏🏼 E1.0 clapping hands: medium-light skin tone
-1F44F 1F3FD ; fully-qualified # 👏🏽 E1.0 clapping hands: medium skin tone
-1F44F 1F3FE ; fully-qualified # 👏🏾 E1.0 clapping hands: medium-dark skin tone
-1F44F 1F3FF ; fully-qualified # 👏🏿 E1.0 clapping hands: dark skin tone
-1F64C ; fully-qualified # 🙌 E0.6 raising hands
-1F64C 1F3FB ; fully-qualified # 🙌🏻 E1.0 raising hands: light skin tone
-1F64C 1F3FC ; fully-qualified # 🙌🏼 E1.0 raising hands: medium-light skin tone
-1F64C 1F3FD ; fully-qualified # 🙌🏽 E1.0 raising hands: medium skin tone
-1F64C 1F3FE ; fully-qualified # 🙌🏾 E1.0 raising hands: medium-dark skin tone
-1F64C 1F3FF ; fully-qualified # 🙌🏿 E1.0 raising hands: dark skin tone
-1F450 ; fully-qualified # 👐 E0.6 open hands
-1F450 1F3FB ; fully-qualified # 👐🏻 E1.0 open hands: light skin tone
-1F450 1F3FC ; fully-qualified # 👐🏼 E1.0 open hands: medium-light skin tone
-1F450 1F3FD ; fully-qualified # 👐🏽 E1.0 open hands: medium skin tone
-1F450 1F3FE ; fully-qualified # 👐🏾 E1.0 open hands: medium-dark skin tone
-1F450 1F3FF ; fully-qualified # 👐🏿 E1.0 open hands: dark skin tone
-1F932 ; fully-qualified # 🤲 E5.0 palms up together
-1F932 1F3FB ; fully-qualified # 🤲🏻 E5.0 palms up together: light skin tone
-1F932 1F3FC ; fully-qualified # 🤲🏼 E5.0 palms up together: medium-light skin tone
-1F932 1F3FD ; fully-qualified # 🤲🏽 E5.0 palms up together: medium skin tone
-1F932 1F3FE ; fully-qualified # 🤲🏾 E5.0 palms up together: medium-dark skin tone
-1F932 1F3FF ; fully-qualified # 🤲🏿 E5.0 palms up together: dark skin tone
-1F91D ; fully-qualified # 🤝 E3.0 handshake
-1F64F ; fully-qualified # 🙏 E0.6 folded hands
-1F64F 1F3FB ; fully-qualified # 🙏🏻 E1.0 folded hands: light skin tone
-1F64F 1F3FC ; fully-qualified # 🙏🏼 E1.0 folded hands: medium-light skin tone
-1F64F 1F3FD ; fully-qualified # 🙏🏽 E1.0 folded hands: medium skin tone
-1F64F 1F3FE ; fully-qualified # 🙏🏾 E1.0 folded hands: medium-dark skin tone
-1F64F 1F3FF ; fully-qualified # 🙏🏿 E1.0 folded hands: dark skin tone
+1F44F ; fully-qualified # 👏 E0.6 clapping hands
+1F44F 1F3FB ; fully-qualified # 👏🏻 E1.0 clapping hands: light skin tone
+1F44F 1F3FC ; fully-qualified # 👏🏼 E1.0 clapping hands: medium-light skin tone
+1F44F 1F3FD ; fully-qualified # 👏🏽 E1.0 clapping hands: medium skin tone
+1F44F 1F3FE ; fully-qualified # 👏🏾 E1.0 clapping hands: medium-dark skin tone
+1F44F 1F3FF ; fully-qualified # 👏🏿 E1.0 clapping hands: dark skin tone
+1F64C ; fully-qualified # 🙌 E0.6 raising hands
+1F64C 1F3FB ; fully-qualified # 🙌🏻 E1.0 raising hands: light skin tone
+1F64C 1F3FC ; fully-qualified # 🙌🏼 E1.0 raising hands: medium-light skin tone
+1F64C 1F3FD ; fully-qualified # 🙌🏽 E1.0 raising hands: medium skin tone
+1F64C 1F3FE ; fully-qualified # 🙌🏾 E1.0 raising hands: medium-dark skin tone
+1F64C 1F3FF ; fully-qualified # 🙌🏿 E1.0 raising hands: dark skin tone
+1F450 ; fully-qualified # 👐 E0.6 open hands
+1F450 1F3FB ; fully-qualified # 👐🏻 E1.0 open hands: light skin tone
+1F450 1F3FC ; fully-qualified # 👐🏼 E1.0 open hands: medium-light skin tone
+1F450 1F3FD ; fully-qualified # 👐🏽 E1.0 open hands: medium skin tone
+1F450 1F3FE ; fully-qualified # 👐🏾 E1.0 open hands: medium-dark skin tone
+1F450 1F3FF ; fully-qualified # 👐🏿 E1.0 open hands: dark skin tone
+1F932 ; fully-qualified # 🤲 E5.0 palms up together
+1F932 1F3FB ; fully-qualified # 🤲🏻 E5.0 palms up together: light skin tone
+1F932 1F3FC ; fully-qualified # 🤲🏼 E5.0 palms up together: medium-light skin tone
+1F932 1F3FD ; fully-qualified # 🤲🏽 E5.0 palms up together: medium skin tone
+1F932 1F3FE ; fully-qualified # 🤲🏾 E5.0 palms up together: medium-dark skin tone
+1F932 1F3FF ; fully-qualified # 🤲🏿 E5.0 palms up together: dark skin tone
+1F91D ; fully-qualified # 🤝 E3.0 handshake
+1F64F ; fully-qualified # 🙏 E0.6 folded hands
+1F64F 1F3FB ; fully-qualified # 🙏🏻 E1.0 folded hands: light skin tone
+1F64F 1F3FC ; fully-qualified # 🙏🏼 E1.0 folded hands: medium-light skin tone
+1F64F 1F3FD ; fully-qualified # 🙏🏽 E1.0 folded hands: medium skin tone
+1F64F 1F3FE ; fully-qualified # 🙏🏾 E1.0 folded hands: medium-dark skin tone
+1F64F 1F3FF ; fully-qualified # 🙏🏿 E1.0 folded hands: dark skin tone
# subgroup: hand-prop
-270D FE0F ; fully-qualified # ✍️ E0.7 writing hand
-270D ; unqualified # ✍ E0.7 writing hand
-270D 1F3FB ; fully-qualified # ✍🏻 E1.0 writing hand: light skin tone
-270D 1F3FC ; fully-qualified # ✍🏼 E1.0 writing hand: medium-light skin tone
-270D 1F3FD ; fully-qualified # ✍🏽 E1.0 writing hand: medium skin tone
-270D 1F3FE ; fully-qualified # ✍🏾 E1.0 writing hand: medium-dark skin tone
-270D 1F3FF ; fully-qualified # ✍🏿 E1.0 writing hand: dark skin tone
-1F485 ; fully-qualified # 💅 E0.6 nail polish
-1F485 1F3FB ; fully-qualified # 💅🏻 E1.0 nail polish: light skin tone
-1F485 1F3FC ; fully-qualified # 💅🏼 E1.0 nail polish: medium-light skin tone
-1F485 1F3FD ; fully-qualified # 💅🏽 E1.0 nail polish: medium skin tone
-1F485 1F3FE ; fully-qualified # 💅🏾 E1.0 nail polish: medium-dark skin tone
-1F485 1F3FF ; fully-qualified # 💅🏿 E1.0 nail polish: dark skin tone
-1F933 ; fully-qualified # 🤳 E3.0 selfie
-1F933 1F3FB ; fully-qualified # 🤳🏻 E3.0 selfie: light skin tone
-1F933 1F3FC ; fully-qualified # 🤳🏼 E3.0 selfie: medium-light skin tone
-1F933 1F3FD ; fully-qualified # 🤳🏽 E3.0 selfie: medium skin tone
-1F933 1F3FE ; fully-qualified # 🤳🏾 E3.0 selfie: medium-dark skin tone
-1F933 1F3FF ; fully-qualified # 🤳🏿 E3.0 selfie: dark skin tone
+270D FE0F ; fully-qualified # ✍️ E0.7 writing hand
+270D ; unqualified # ✍ E0.7 writing hand
+270D 1F3FB ; fully-qualified # ✍🏻 E1.0 writing hand: light skin tone
+270D 1F3FC ; fully-qualified # ✍🏼 E1.0 writing hand: medium-light skin tone
+270D 1F3FD ; fully-qualified # ✍🏽 E1.0 writing hand: medium skin tone
+270D 1F3FE ; fully-qualified # ✍🏾 E1.0 writing hand: medium-dark skin tone
+270D 1F3FF ; fully-qualified # ✍🏿 E1.0 writing hand: dark skin tone
+1F485 ; fully-qualified # 💅 E0.6 nail polish
+1F485 1F3FB ; fully-qualified # 💅🏻 E1.0 nail polish: light skin tone
+1F485 1F3FC ; fully-qualified # 💅🏼 E1.0 nail polish: medium-light skin tone
+1F485 1F3FD ; fully-qualified # 💅🏽 E1.0 nail polish: medium skin tone
+1F485 1F3FE ; fully-qualified # 💅🏾 E1.0 nail polish: medium-dark skin tone
+1F485 1F3FF ; fully-qualified # 💅🏿 E1.0 nail polish: dark skin tone
+1F933 ; fully-qualified # 🤳 E3.0 selfie
+1F933 1F3FB ; fully-qualified # 🤳🏻 E3.0 selfie: light skin tone
+1F933 1F3FC ; fully-qualified # 🤳🏼 E3.0 selfie: medium-light skin tone
+1F933 1F3FD ; fully-qualified # 🤳🏽 E3.0 selfie: medium skin tone
+1F933 1F3FE ; fully-qualified # 🤳🏾 E3.0 selfie: medium-dark skin tone
+1F933 1F3FF ; fully-qualified # 🤳🏿 E3.0 selfie: dark skin tone
# subgroup: body-parts
-1F4AA ; fully-qualified # 💪 E0.6 flexed biceps
-1F4AA 1F3FB ; fully-qualified # 💪🏻 E1.0 flexed biceps: light skin tone
-1F4AA 1F3FC ; fully-qualified # 💪🏼 E1.0 flexed biceps: medium-light skin tone
-1F4AA 1F3FD ; fully-qualified # 💪🏽 E1.0 flexed biceps: medium skin tone
-1F4AA 1F3FE ; fully-qualified # 💪🏾 E1.0 flexed biceps: medium-dark skin tone
-1F4AA 1F3FF ; fully-qualified # 💪🏿 E1.0 flexed biceps: dark skin tone
-1F9BE ; fully-qualified # 🦾 E12.0 mechanical arm
-1F9BF ; fully-qualified # 🦿 E12.0 mechanical leg
-1F9B5 ; fully-qualified # 🦵 E11.0 leg
-1F9B5 1F3FB ; fully-qualified # 🦵🏻 E11.0 leg: light skin tone
-1F9B5 1F3FC ; fully-qualified # 🦵🏼 E11.0 leg: medium-light skin tone
-1F9B5 1F3FD ; fully-qualified # 🦵🏽 E11.0 leg: medium skin tone
-1F9B5 1F3FE ; fully-qualified # 🦵🏾 E11.0 leg: medium-dark skin tone
-1F9B5 1F3FF ; fully-qualified # 🦵🏿 E11.0 leg: dark skin tone
-1F9B6 ; fully-qualified # 🦶 E11.0 foot
-1F9B6 1F3FB ; fully-qualified # 🦶🏻 E11.0 foot: light skin tone
-1F9B6 1F3FC ; fully-qualified # 🦶🏼 E11.0 foot: medium-light skin tone
-1F9B6 1F3FD ; fully-qualified # 🦶🏽 E11.0 foot: medium skin tone
-1F9B6 1F3FE ; fully-qualified # 🦶🏾 E11.0 foot: medium-dark skin tone
-1F9B6 1F3FF ; fully-qualified # 🦶🏿 E11.0 foot: dark skin tone
-1F442 ; fully-qualified # 👂 E0.6 ear
-1F442 1F3FB ; fully-qualified # 👂🏻 E1.0 ear: light skin tone
-1F442 1F3FC ; fully-qualified # 👂🏼 E1.0 ear: medium-light skin tone
-1F442 1F3FD ; fully-qualified # 👂🏽 E1.0 ear: medium skin tone
-1F442 1F3FE ; fully-qualified # 👂🏾 E1.0 ear: medium-dark skin tone
-1F442 1F3FF ; fully-qualified # 👂🏿 E1.0 ear: dark skin tone
-1F9BB ; fully-qualified # 🦻 E12.0 ear with hearing aid
-1F9BB 1F3FB ; fully-qualified # 🦻🏻 E12.0 ear with hearing aid: light skin tone
-1F9BB 1F3FC ; fully-qualified # 🦻🏼 E12.0 ear with hearing aid: medium-light skin tone
-1F9BB 1F3FD ; fully-qualified # 🦻🏽 E12.0 ear with hearing aid: medium skin tone
-1F9BB 1F3FE ; fully-qualified # 🦻🏾 E12.0 ear with hearing aid: medium-dark skin tone
-1F9BB 1F3FF ; fully-qualified # 🦻🏿 E12.0 ear with hearing aid: dark skin tone
-1F443 ; fully-qualified # 👃 E0.6 nose
-1F443 1F3FB ; fully-qualified # 👃🏻 E1.0 nose: light skin tone
-1F443 1F3FC ; fully-qualified # 👃🏼 E1.0 nose: medium-light skin tone
-1F443 1F3FD ; fully-qualified # 👃🏽 E1.0 nose: medium skin tone
-1F443 1F3FE ; fully-qualified # 👃🏾 E1.0 nose: medium-dark skin tone
-1F443 1F3FF ; fully-qualified # 👃🏿 E1.0 nose: dark skin tone
-1F9E0 ; fully-qualified # 🧠 E5.0 brain
-1FAC0 ; fully-qualified # 🫀 E13.0 anatomical heart
-1FAC1 ; fully-qualified # 🫁 E13.0 lungs
-1F9B7 ; fully-qualified # 🦷 E11.0 tooth
-1F9B4 ; fully-qualified # 🦴 E11.0 bone
-1F440 ; fully-qualified # 👀 E0.6 eyes
-1F441 FE0F ; fully-qualified # 👁️ E0.7 eye
-1F441 ; unqualified # 👁 E0.7 eye
-1F445 ; fully-qualified # 👅 E0.6 tongue
-1F444 ; fully-qualified # 👄 E0.6 mouth
+1F4AA ; fully-qualified # 💪 E0.6 flexed biceps
+1F4AA 1F3FB ; fully-qualified # 💪🏻 E1.0 flexed biceps: light skin tone
+1F4AA 1F3FC ; fully-qualified # 💪🏼 E1.0 flexed biceps: medium-light skin tone
+1F4AA 1F3FD ; fully-qualified # 💪🏽 E1.0 flexed biceps: medium skin tone
+1F4AA 1F3FE ; fully-qualified # 💪🏾 E1.0 flexed biceps: medium-dark skin tone
+1F4AA 1F3FF ; fully-qualified # 💪🏿 E1.0 flexed biceps: dark skin tone
+1F9BE ; fully-qualified # 🦾 E12.0 mechanical arm
+1F9BF ; fully-qualified # 🦿 E12.0 mechanical leg
+1F9B5 ; fully-qualified # 🦵 E11.0 leg
+1F9B5 1F3FB ; fully-qualified # 🦵🏻 E11.0 leg: light skin tone
+1F9B5 1F3FC ; fully-qualified # 🦵🏼 E11.0 leg: medium-light skin tone
+1F9B5 1F3FD ; fully-qualified # 🦵🏽 E11.0 leg: medium skin tone
+1F9B5 1F3FE ; fully-qualified # 🦵🏾 E11.0 leg: medium-dark skin tone
+1F9B5 1F3FF ; fully-qualified # 🦵🏿 E11.0 leg: dark skin tone
+1F9B6 ; fully-qualified # 🦶 E11.0 foot
+1F9B6 1F3FB ; fully-qualified # 🦶🏻 E11.0 foot: light skin tone
+1F9B6 1F3FC ; fully-qualified # 🦶🏼 E11.0 foot: medium-light skin tone
+1F9B6 1F3FD ; fully-qualified # 🦶🏽 E11.0 foot: medium skin tone
+1F9B6 1F3FE ; fully-qualified # 🦶🏾 E11.0 foot: medium-dark skin tone
+1F9B6 1F3FF ; fully-qualified # 🦶🏿 E11.0 foot: dark skin tone
+1F442 ; fully-qualified # 👂 E0.6 ear
+1F442 1F3FB ; fully-qualified # 👂🏻 E1.0 ear: light skin tone
+1F442 1F3FC ; fully-qualified # 👂🏼 E1.0 ear: medium-light skin tone
+1F442 1F3FD ; fully-qualified # 👂🏽 E1.0 ear: medium skin tone
+1F442 1F3FE ; fully-qualified # 👂🏾 E1.0 ear: medium-dark skin tone
+1F442 1F3FF ; fully-qualified # 👂🏿 E1.0 ear: dark skin tone
+1F9BB ; fully-qualified # 🦻 E12.0 ear with hearing aid
+1F9BB 1F3FB ; fully-qualified # 🦻🏻 E12.0 ear with hearing aid: light skin tone
+1F9BB 1F3FC ; fully-qualified # 🦻🏼 E12.0 ear with hearing aid: medium-light skin tone
+1F9BB 1F3FD ; fully-qualified # 🦻🏽 E12.0 ear with hearing aid: medium skin tone
+1F9BB 1F3FE ; fully-qualified # 🦻🏾 E12.0 ear with hearing aid: medium-dark skin tone
+1F9BB 1F3FF ; fully-qualified # 🦻🏿 E12.0 ear with hearing aid: dark skin tone
+1F443 ; fully-qualified # 👃 E0.6 nose
+1F443 1F3FB ; fully-qualified # 👃🏻 E1.0 nose: light skin tone
+1F443 1F3FC ; fully-qualified # 👃🏼 E1.0 nose: medium-light skin tone
+1F443 1F3FD ; fully-qualified # 👃🏽 E1.0 nose: medium skin tone
+1F443 1F3FE ; fully-qualified # 👃🏾 E1.0 nose: medium-dark skin tone
+1F443 1F3FF ; fully-qualified # 👃🏿 E1.0 nose: dark skin tone
+1F9E0 ; fully-qualified # 🧠 E5.0 brain
+1FAC0 ; fully-qualified # 🫀 E13.0 anatomical heart
+1FAC1 ; fully-qualified # 🫁 E13.0 lungs
+1F9B7 ; fully-qualified # 🦷 E11.0 tooth
+1F9B4 ; fully-qualified # 🦴 E11.0 bone
+1F440 ; fully-qualified # 👀 E0.6 eyes
+1F441 FE0F ; fully-qualified # 👁️ E0.7 eye
+1F441 ; unqualified # 👁 E0.7 eye
+1F445 ; fully-qualified # 👅 E0.6 tongue
+1F444 ; fully-qualified # 👄 E0.6 mouth
# subgroup: person
-1F476 ; fully-qualified # 👶 E0.6 baby
-1F476 1F3FB ; fully-qualified # 👶🏻 E1.0 baby: light skin tone
-1F476 1F3FC ; fully-qualified # 👶🏼 E1.0 baby: medium-light skin tone
-1F476 1F3FD ; fully-qualified # 👶🏽 E1.0 baby: medium skin tone
-1F476 1F3FE ; fully-qualified # 👶🏾 E1.0 baby: medium-dark skin tone
-1F476 1F3FF ; fully-qualified # 👶🏿 E1.0 baby: dark skin tone
-1F9D2 ; fully-qualified # 🧒 E5.0 child
-1F9D2 1F3FB ; fully-qualified # 🧒🏻 E5.0 child: light skin tone
-1F9D2 1F3FC ; fully-qualified # 🧒🏼 E5.0 child: medium-light skin tone
-1F9D2 1F3FD ; fully-qualified # 🧒🏽 E5.0 child: medium skin tone
-1F9D2 1F3FE ; fully-qualified # 🧒🏾 E5.0 child: medium-dark skin tone
-1F9D2 1F3FF ; fully-qualified # 🧒🏿 E5.0 child: dark skin tone
-1F466 ; fully-qualified # 👦 E0.6 boy
-1F466 1F3FB ; fully-qualified # 👦🏻 E1.0 boy: light skin tone
-1F466 1F3FC ; fully-qualified # 👦🏼 E1.0 boy: medium-light skin tone
-1F466 1F3FD ; fully-qualified # 👦🏽 E1.0 boy: medium skin tone
-1F466 1F3FE ; fully-qualified # 👦🏾 E1.0 boy: medium-dark skin tone
-1F466 1F3FF ; fully-qualified # 👦🏿 E1.0 boy: dark skin tone
-1F467 ; fully-qualified # 👧 E0.6 girl
-1F467 1F3FB ; fully-qualified # 👧🏻 E1.0 girl: light skin tone
-1F467 1F3FC ; fully-qualified # 👧🏼 E1.0 girl: medium-light skin tone
-1F467 1F3FD ; fully-qualified # 👧🏽 E1.0 girl: medium skin tone
-1F467 1F3FE ; fully-qualified # 👧🏾 E1.0 girl: medium-dark skin tone
-1F467 1F3FF ; fully-qualified # 👧🏿 E1.0 girl: dark skin tone
-1F9D1 ; fully-qualified # 🧑 E5.0 person
-1F9D1 1F3FB ; fully-qualified # 🧑🏻 E5.0 person: light skin tone
-1F9D1 1F3FC ; fully-qualified # 🧑🏼 E5.0 person: medium-light skin tone
-1F9D1 1F3FD ; fully-qualified # 🧑🏽 E5.0 person: medium skin tone
-1F9D1 1F3FE ; fully-qualified # 🧑🏾 E5.0 person: medium-dark skin tone
-1F9D1 1F3FF ; fully-qualified # 🧑🏿 E5.0 person: dark skin tone
-1F471 ; fully-qualified # 👱 E0.6 person: blond hair
-1F471 1F3FB ; fully-qualified # 👱🏻 E1.0 person: light skin tone, blond hair
-1F471 1F3FC ; fully-qualified # 👱🏼 E1.0 person: medium-light skin tone, blond hair
-1F471 1F3FD ; fully-qualified # 👱🏽 E1.0 person: medium skin tone, blond hair
-1F471 1F3FE ; fully-qualified # 👱🏾 E1.0 person: medium-dark skin tone, blond hair
-1F471 1F3FF ; fully-qualified # 👱🏿 E1.0 person: dark skin tone, blond hair
-1F468 ; fully-qualified # 👨 E0.6 man
-1F468 1F3FB ; fully-qualified # 👨🏻 E1.0 man: light skin tone
-1F468 1F3FC ; fully-qualified # 👨🏼 E1.0 man: medium-light skin tone
-1F468 1F3FD ; fully-qualified # 👨🏽 E1.0 man: medium skin tone
-1F468 1F3FE ; fully-qualified # 👨🏾 E1.0 man: medium-dark skin tone
-1F468 1F3FF ; fully-qualified # 👨🏿 E1.0 man: dark skin tone
-1F9D4 ; fully-qualified # 🧔 E5.0 man: beard
-1F9D4 1F3FB ; fully-qualified # 🧔🏻 E5.0 man: light skin tone, beard
-1F9D4 1F3FC ; fully-qualified # 🧔🏼 E5.0 man: medium-light skin tone, beard
-1F9D4 1F3FD ; fully-qualified # 🧔🏽 E5.0 man: medium skin tone, beard
-1F9D4 1F3FE ; fully-qualified # 🧔🏾 E5.0 man: medium-dark skin tone, beard
-1F9D4 1F3FF ; fully-qualified # 🧔🏿 E5.0 man: dark skin tone, beard
-1F468 200D 1F9B0 ; fully-qualified # 👨🦰 E11.0 man: red hair
-1F468 1F3FB 200D 1F9B0 ; fully-qualified # 👨🏻🦰 E11.0 man: light skin tone, red hair
-1F468 1F3FC 200D 1F9B0 ; fully-qualified # 👨🏼🦰 E11.0 man: medium-light skin tone, red hair
-1F468 1F3FD 200D 1F9B0 ; fully-qualified # 👨🏽🦰 E11.0 man: medium skin tone, red hair
-1F468 1F3FE 200D 1F9B0 ; fully-qualified # 👨🏾🦰 E11.0 man: medium-dark skin tone, red hair
-1F468 1F3FF 200D 1F9B0 ; fully-qualified # 👨🏿🦰 E11.0 man: dark skin tone, red hair
-1F468 200D 1F9B1 ; fully-qualified # 👨🦱 E11.0 man: curly hair
-1F468 1F3FB 200D 1F9B1 ; fully-qualified # 👨🏻🦱 E11.0 man: light skin tone, curly hair
-1F468 1F3FC 200D 1F9B1 ; fully-qualified # 👨🏼🦱 E11.0 man: medium-light skin tone, curly hair
-1F468 1F3FD 200D 1F9B1 ; fully-qualified # 👨🏽🦱 E11.0 man: medium skin tone, curly hair
-1F468 1F3FE 200D 1F9B1 ; fully-qualified # 👨🏾🦱 E11.0 man: medium-dark skin tone, curly hair
-1F468 1F3FF 200D 1F9B1 ; fully-qualified # 👨🏿🦱 E11.0 man: dark skin tone, curly hair
-1F468 200D 1F9B3 ; fully-qualified # 👨🦳 E11.0 man: white hair
-1F468 1F3FB 200D 1F9B3 ; fully-qualified # 👨🏻🦳 E11.0 man: light skin tone, white hair
-1F468 1F3FC 200D 1F9B3 ; fully-qualified # 👨🏼🦳 E11.0 man: medium-light skin tone, white hair
-1F468 1F3FD 200D 1F9B3 ; fully-qualified # 👨🏽🦳 E11.0 man: medium skin tone, white hair
-1F468 1F3FE 200D 1F9B3 ; fully-qualified # 👨🏾🦳 E11.0 man: medium-dark skin tone, white hair
-1F468 1F3FF 200D 1F9B3 ; fully-qualified # 👨🏿🦳 E11.0 man: dark skin tone, white hair
-1F468 200D 1F9B2 ; fully-qualified # 👨🦲 E11.0 man: bald
-1F468 1F3FB 200D 1F9B2 ; fully-qualified # 👨🏻🦲 E11.0 man: light skin tone, bald
-1F468 1F3FC 200D 1F9B2 ; fully-qualified # 👨🏼🦲 E11.0 man: medium-light skin tone, bald
-1F468 1F3FD 200D 1F9B2 ; fully-qualified # 👨🏽🦲 E11.0 man: medium skin tone, bald
-1F468 1F3FE 200D 1F9B2 ; fully-qualified # 👨🏾🦲 E11.0 man: medium-dark skin tone, bald
-1F468 1F3FF 200D 1F9B2 ; fully-qualified # 👨🏿🦲 E11.0 man: dark skin tone, bald
-1F469 ; fully-qualified # 👩 E0.6 woman
-1F469 1F3FB ; fully-qualified # 👩🏻 E1.0 woman: light skin tone
-1F469 1F3FC ; fully-qualified # 👩🏼 E1.0 woman: medium-light skin tone
-1F469 1F3FD ; fully-qualified # 👩🏽 E1.0 woman: medium skin tone
-1F469 1F3FE ; fully-qualified # 👩🏾 E1.0 woman: medium-dark skin tone
-1F469 1F3FF ; fully-qualified # 👩🏿 E1.0 woman: dark skin tone
-1F469 200D 1F9B0 ; fully-qualified # 👩🦰 E11.0 woman: red hair
-1F469 1F3FB 200D 1F9B0 ; fully-qualified # 👩🏻🦰 E11.0 woman: light skin tone, red hair
-1F469 1F3FC 200D 1F9B0 ; fully-qualified # 👩🏼🦰 E11.0 woman: medium-light skin tone, red hair
-1F469 1F3FD 200D 1F9B0 ; fully-qualified # 👩🏽🦰 E11.0 woman: medium skin tone, red hair
-1F469 1F3FE 200D 1F9B0 ; fully-qualified # 👩🏾🦰 E11.0 woman: medium-dark skin tone, red hair
-1F469 1F3FF 200D 1F9B0 ; fully-qualified # 👩🏿🦰 E11.0 woman: dark skin tone, red hair
-1F9D1 200D 1F9B0 ; fully-qualified # 🧑🦰 E12.1 person: red hair
-1F9D1 1F3FB 200D 1F9B0 ; fully-qualified # 🧑🏻🦰 E12.1 person: light skin tone, red hair
-1F9D1 1F3FC 200D 1F9B0 ; fully-qualified # 🧑🏼🦰 E12.1 person: medium-light skin tone, red hair
-1F9D1 1F3FD 200D 1F9B0 ; fully-qualified # 🧑🏽🦰 E12.1 person: medium skin tone, red hair
-1F9D1 1F3FE 200D 1F9B0 ; fully-qualified # 🧑🏾🦰 E12.1 person: medium-dark skin tone, red hair
-1F9D1 1F3FF 200D 1F9B0 ; fully-qualified # 🧑🏿🦰 E12.1 person: dark skin tone, red hair
-1F469 200D 1F9B1 ; fully-qualified # 👩🦱 E11.0 woman: curly hair
-1F469 1F3FB 200D 1F9B1 ; fully-qualified # 👩🏻🦱 E11.0 woman: light skin tone, curly hair
-1F469 1F3FC 200D 1F9B1 ; fully-qualified # 👩🏼🦱 E11.0 woman: medium-light skin tone, curly hair
-1F469 1F3FD 200D 1F9B1 ; fully-qualified # 👩🏽🦱 E11.0 woman: medium skin tone, curly hair
-1F469 1F3FE 200D 1F9B1 ; fully-qualified # 👩🏾🦱 E11.0 woman: medium-dark skin tone, curly hair
-1F469 1F3FF 200D 1F9B1 ; fully-qualified # 👩🏿🦱 E11.0 woman: dark skin tone, curly hair
-1F9D1 200D 1F9B1 ; fully-qualified # 🧑🦱 E12.1 person: curly hair
-1F9D1 1F3FB 200D 1F9B1 ; fully-qualified # 🧑🏻🦱 E12.1 person: light skin tone, curly hair
-1F9D1 1F3FC 200D 1F9B1 ; fully-qualified # 🧑🏼🦱 E12.1 person: medium-light skin tone, curly hair
-1F9D1 1F3FD 200D 1F9B1 ; fully-qualified # 🧑🏽🦱 E12.1 person: medium skin tone, curly hair
-1F9D1 1F3FE 200D 1F9B1 ; fully-qualified # 🧑🏾🦱 E12.1 person: medium-dark skin tone, curly hair
-1F9D1 1F3FF 200D 1F9B1 ; fully-qualified # 🧑🏿🦱 E12.1 person: dark skin tone, curly hair
-1F469 200D 1F9B3 ; fully-qualified # 👩🦳 E11.0 woman: white hair
-1F469 1F3FB 200D 1F9B3 ; fully-qualified # 👩🏻🦳 E11.0 woman: light skin tone, white hair
-1F469 1F3FC 200D 1F9B3 ; fully-qualified # 👩🏼🦳 E11.0 woman: medium-light skin tone, white hair
-1F469 1F3FD 200D 1F9B3 ; fully-qualified # 👩🏽🦳 E11.0 woman: medium skin tone, white hair
-1F469 1F3FE 200D 1F9B3 ; fully-qualified # 👩🏾🦳 E11.0 woman: medium-dark skin tone, white hair
-1F469 1F3FF 200D 1F9B3 ; fully-qualified # 👩🏿🦳 E11.0 woman: dark skin tone, white hair
-1F9D1 200D 1F9B3 ; fully-qualified # 🧑🦳 E12.1 person: white hair
-1F9D1 1F3FB 200D 1F9B3 ; fully-qualified # 🧑🏻🦳 E12.1 person: light skin tone, white hair
-1F9D1 1F3FC 200D 1F9B3 ; fully-qualified # 🧑🏼🦳 E12.1 person: medium-light skin tone, white hair
-1F9D1 1F3FD 200D 1F9B3 ; fully-qualified # 🧑🏽🦳 E12.1 person: medium skin tone, white hair
-1F9D1 1F3FE 200D 1F9B3 ; fully-qualified # 🧑🏾🦳 E12.1 person: medium-dark skin tone, white hair
-1F9D1 1F3FF 200D 1F9B3 ; fully-qualified # 🧑🏿🦳 E12.1 person: dark skin tone, white hair
-1F469 200D 1F9B2 ; fully-qualified # 👩🦲 E11.0 woman: bald
-1F469 1F3FB 200D 1F9B2 ; fully-qualified # 👩🏻🦲 E11.0 woman: light skin tone, bald
-1F469 1F3FC 200D 1F9B2 ; fully-qualified # 👩🏼🦲 E11.0 woman: medium-light skin tone, bald
-1F469 1F3FD 200D 1F9B2 ; fully-qualified # 👩🏽🦲 E11.0 woman: medium skin tone, bald
-1F469 1F3FE 200D 1F9B2 ; fully-qualified # 👩🏾🦲 E11.0 woman: medium-dark skin tone, bald
-1F469 1F3FF 200D 1F9B2 ; fully-qualified # 👩🏿🦲 E11.0 woman: dark skin tone, bald
-1F9D1 200D 1F9B2 ; fully-qualified # 🧑🦲 E12.1 person: bald
-1F9D1 1F3FB 200D 1F9B2 ; fully-qualified # 🧑🏻🦲 E12.1 person: light skin tone, bald
-1F9D1 1F3FC 200D 1F9B2 ; fully-qualified # 🧑🏼🦲 E12.1 person: medium-light skin tone, bald
-1F9D1 1F3FD 200D 1F9B2 ; fully-qualified # 🧑🏽🦲 E12.1 person: medium skin tone, bald
-1F9D1 1F3FE 200D 1F9B2 ; fully-qualified # 🧑🏾🦲 E12.1 person: medium-dark skin tone, bald
-1F9D1 1F3FF 200D 1F9B2 ; fully-qualified # 🧑🏿🦲 E12.1 person: dark skin tone, bald
-1F471 200D 2640 FE0F ; fully-qualified # 👱♀️ E4.0 woman: blond hair
-1F471 200D 2640 ; minimally-qualified # 👱♀ E4.0 woman: blond hair
-1F471 1F3FB 200D 2640 FE0F ; fully-qualified # 👱🏻♀️ E4.0 woman: light skin tone, blond hair
-1F471 1F3FB 200D 2640 ; minimally-qualified # 👱🏻♀ E4.0 woman: light skin tone, blond hair
-1F471 1F3FC 200D 2640 FE0F ; fully-qualified # 👱🏼♀️ E4.0 woman: medium-light skin tone, blond hair
-1F471 1F3FC 200D 2640 ; minimally-qualified # 👱🏼♀ E4.0 woman: medium-light skin tone, blond hair
-1F471 1F3FD 200D 2640 FE0F ; fully-qualified # 👱🏽♀️ E4.0 woman: medium skin tone, blond hair
-1F471 1F3FD 200D 2640 ; minimally-qualified # 👱🏽♀ E4.0 woman: medium skin tone, blond hair
-1F471 1F3FE 200D 2640 FE0F ; fully-qualified # 👱🏾♀️ E4.0 woman: medium-dark skin tone, blond hair
-1F471 1F3FE 200D 2640 ; minimally-qualified # 👱🏾♀ E4.0 woman: medium-dark skin tone, blond hair
-1F471 1F3FF 200D 2640 FE0F ; fully-qualified # 👱🏿♀️ E4.0 woman: dark skin tone, blond hair
-1F471 1F3FF 200D 2640 ; minimally-qualified # 👱🏿♀ E4.0 woman: dark skin tone, blond hair
-1F471 200D 2642 FE0F ; fully-qualified # 👱♂️ E4.0 man: blond hair
-1F471 200D 2642 ; minimally-qualified # 👱♂ E4.0 man: blond hair
-1F471 1F3FB 200D 2642 FE0F ; fully-qualified # 👱🏻♂️ E4.0 man: light skin tone, blond hair
-1F471 1F3FB 200D 2642 ; minimally-qualified # 👱🏻♂ E4.0 man: light skin tone, blond hair
-1F471 1F3FC 200D 2642 FE0F ; fully-qualified # 👱🏼♂️ E4.0 man: medium-light skin tone, blond hair
-1F471 1F3FC 200D 2642 ; minimally-qualified # 👱🏼♂ E4.0 man: medium-light skin tone, blond hair
-1F471 1F3FD 200D 2642 FE0F ; fully-qualified # 👱🏽♂️ E4.0 man: medium skin tone, blond hair
-1F471 1F3FD 200D 2642 ; minimally-qualified # 👱🏽♂ E4.0 man: medium skin tone, blond hair
-1F471 1F3FE 200D 2642 FE0F ; fully-qualified # 👱🏾♂️ E4.0 man: medium-dark skin tone, blond hair
-1F471 1F3FE 200D 2642 ; minimally-qualified # 👱🏾♂ E4.0 man: medium-dark skin tone, blond hair
-1F471 1F3FF 200D 2642 FE0F ; fully-qualified # 👱🏿♂️ E4.0 man: dark skin tone, blond hair
-1F471 1F3FF 200D 2642 ; minimally-qualified # 👱🏿♂ E4.0 man: dark skin tone, blond hair
-1F9D3 ; fully-qualified # 🧓 E5.0 older person
-1F9D3 1F3FB ; fully-qualified # 🧓🏻 E5.0 older person: light skin tone
-1F9D3 1F3FC ; fully-qualified # 🧓🏼 E5.0 older person: medium-light skin tone
-1F9D3 1F3FD ; fully-qualified # 🧓🏽 E5.0 older person: medium skin tone
-1F9D3 1F3FE ; fully-qualified # 🧓🏾 E5.0 older person: medium-dark skin tone
-1F9D3 1F3FF ; fully-qualified # 🧓🏿 E5.0 older person: dark skin tone
-1F474 ; fully-qualified # 👴 E0.6 old man
-1F474 1F3FB ; fully-qualified # 👴🏻 E1.0 old man: light skin tone
-1F474 1F3FC ; fully-qualified # 👴🏼 E1.0 old man: medium-light skin tone
-1F474 1F3FD ; fully-qualified # 👴🏽 E1.0 old man: medium skin tone
-1F474 1F3FE ; fully-qualified # 👴🏾 E1.0 old man: medium-dark skin tone
-1F474 1F3FF ; fully-qualified # 👴🏿 E1.0 old man: dark skin tone
-1F475 ; fully-qualified # 👵 E0.6 old woman
-1F475 1F3FB ; fully-qualified # 👵🏻 E1.0 old woman: light skin tone
-1F475 1F3FC ; fully-qualified # 👵🏼 E1.0 old woman: medium-light skin tone
-1F475 1F3FD ; fully-qualified # 👵🏽 E1.0 old woman: medium skin tone
-1F475 1F3FE ; fully-qualified # 👵🏾 E1.0 old woman: medium-dark skin tone
-1F475 1F3FF ; fully-qualified # 👵🏿 E1.0 old woman: dark skin tone
+1F476 ; fully-qualified # 👶 E0.6 baby
+1F476 1F3FB ; fully-qualified # 👶🏻 E1.0 baby: light skin tone
+1F476 1F3FC ; fully-qualified # 👶🏼 E1.0 baby: medium-light skin tone
+1F476 1F3FD ; fully-qualified # 👶🏽 E1.0 baby: medium skin tone
+1F476 1F3FE ; fully-qualified # 👶🏾 E1.0 baby: medium-dark skin tone
+1F476 1F3FF ; fully-qualified # 👶🏿 E1.0 baby: dark skin tone
+1F9D2 ; fully-qualified # 🧒 E5.0 child
+1F9D2 1F3FB ; fully-qualified # 🧒🏻 E5.0 child: light skin tone
+1F9D2 1F3FC ; fully-qualified # 🧒🏼 E5.0 child: medium-light skin tone
+1F9D2 1F3FD ; fully-qualified # 🧒🏽 E5.0 child: medium skin tone
+1F9D2 1F3FE ; fully-qualified # 🧒🏾 E5.0 child: medium-dark skin tone
+1F9D2 1F3FF ; fully-qualified # 🧒🏿 E5.0 child: dark skin tone
+1F466 ; fully-qualified # 👦 E0.6 boy
+1F466 1F3FB ; fully-qualified # 👦🏻 E1.0 boy: light skin tone
+1F466 1F3FC ; fully-qualified # 👦🏼 E1.0 boy: medium-light skin tone
+1F466 1F3FD ; fully-qualified # 👦🏽 E1.0 boy: medium skin tone
+1F466 1F3FE ; fully-qualified # 👦🏾 E1.0 boy: medium-dark skin tone
+1F466 1F3FF ; fully-qualified # 👦🏿 E1.0 boy: dark skin tone
+1F467 ; fully-qualified # 👧 E0.6 girl
+1F467 1F3FB ; fully-qualified # 👧🏻 E1.0 girl: light skin tone
+1F467 1F3FC ; fully-qualified # 👧🏼 E1.0 girl: medium-light skin tone
+1F467 1F3FD ; fully-qualified # 👧🏽 E1.0 girl: medium skin tone
+1F467 1F3FE ; fully-qualified # 👧🏾 E1.0 girl: medium-dark skin tone
+1F467 1F3FF ; fully-qualified # 👧🏿 E1.0 girl: dark skin tone
+1F9D1 ; fully-qualified # 🧑 E5.0 person
+1F9D1 1F3FB ; fully-qualified # 🧑🏻 E5.0 person: light skin tone
+1F9D1 1F3FC ; fully-qualified # 🧑🏼 E5.0 person: medium-light skin tone
+1F9D1 1F3FD ; fully-qualified # 🧑🏽 E5.0 person: medium skin tone
+1F9D1 1F3FE ; fully-qualified # 🧑🏾 E5.0 person: medium-dark skin tone
+1F9D1 1F3FF ; fully-qualified # 🧑🏿 E5.0 person: dark skin tone
+1F471 ; fully-qualified # 👱 E0.6 person: blond hair
+1F471 1F3FB ; fully-qualified # 👱🏻 E1.0 person: light skin tone, blond hair
+1F471 1F3FC ; fully-qualified # 👱🏼 E1.0 person: medium-light skin tone, blond hair
+1F471 1F3FD ; fully-qualified # 👱🏽 E1.0 person: medium skin tone, blond hair
+1F471 1F3FE ; fully-qualified # 👱🏾 E1.0 person: medium-dark skin tone, blond hair
+1F471 1F3FF ; fully-qualified # 👱🏿 E1.0 person: dark skin tone, blond hair
+1F468 ; fully-qualified # 👨 E0.6 man
+1F468 1F3FB ; fully-qualified # 👨🏻 E1.0 man: light skin tone
+1F468 1F3FC ; fully-qualified # 👨🏼 E1.0 man: medium-light skin tone
+1F468 1F3FD ; fully-qualified # 👨🏽 E1.0 man: medium skin tone
+1F468 1F3FE ; fully-qualified # 👨🏾 E1.0 man: medium-dark skin tone
+1F468 1F3FF ; fully-qualified # 👨🏿 E1.0 man: dark skin tone
+1F9D4 ; fully-qualified # 🧔 E5.0 person: beard
+1F9D4 1F3FB ; fully-qualified # 🧔🏻 E5.0 person: light skin tone, beard
+1F9D4 1F3FC ; fully-qualified # 🧔🏼 E5.0 person: medium-light skin tone, beard
+1F9D4 1F3FD ; fully-qualified # 🧔🏽 E5.0 person: medium skin tone, beard
+1F9D4 1F3FE ; fully-qualified # 🧔🏾 E5.0 person: medium-dark skin tone, beard
+1F9D4 1F3FF ; fully-qualified # 🧔🏿 E5.0 person: dark skin tone, beard
+1F9D4 200D 2642 FE0F ; fully-qualified # 🧔♂️ E13.1 man: beard
+1F9D4 200D 2642 ; minimally-qualified # 🧔♂ E13.1 man: beard
+1F9D4 1F3FB 200D 2642 FE0F ; fully-qualified # 🧔🏻♂️ E13.1 man: light skin tone, beard
+1F9D4 1F3FB 200D 2642 ; minimally-qualified # 🧔🏻♂ E13.1 man: light skin tone, beard
+1F9D4 1F3FC 200D 2642 FE0F ; fully-qualified # 🧔🏼♂️ E13.1 man: medium-light skin tone, beard
+1F9D4 1F3FC 200D 2642 ; minimally-qualified # 🧔🏼♂ E13.1 man: medium-light skin tone, beard
+1F9D4 1F3FD 200D 2642 FE0F ; fully-qualified # 🧔🏽♂️ E13.1 man: medium skin tone, beard
+1F9D4 1F3FD 200D 2642 ; minimally-qualified # 🧔🏽♂ E13.1 man: medium skin tone, beard
+1F9D4 1F3FE 200D 2642 FE0F ; fully-qualified # 🧔🏾♂️ E13.1 man: medium-dark skin tone, beard
+1F9D4 1F3FE 200D 2642 ; minimally-qualified # 🧔🏾♂ E13.1 man: medium-dark skin tone, beard
+1F9D4 1F3FF 200D 2642 FE0F ; fully-qualified # 🧔🏿♂️ E13.1 man: dark skin tone, beard
+1F9D4 1F3FF 200D 2642 ; minimally-qualified # 🧔🏿♂ E13.1 man: dark skin tone, beard
+1F9D4 200D 2640 FE0F ; fully-qualified # 🧔♀️ E13.1 woman: beard
+1F9D4 200D 2640 ; minimally-qualified # 🧔♀ E13.1 woman: beard
+1F9D4 1F3FB 200D 2640 FE0F ; fully-qualified # 🧔🏻♀️ E13.1 woman: light skin tone, beard
+1F9D4 1F3FB 200D 2640 ; minimally-qualified # 🧔🏻♀ E13.1 woman: light skin tone, beard
+1F9D4 1F3FC 200D 2640 FE0F ; fully-qualified # 🧔🏼♀️ E13.1 woman: medium-light skin tone, beard
+1F9D4 1F3FC 200D 2640 ; minimally-qualified # 🧔🏼♀ E13.1 woman: medium-light skin tone, beard
+1F9D4 1F3FD 200D 2640 FE0F ; fully-qualified # 🧔🏽♀️ E13.1 woman: medium skin tone, beard
+1F9D4 1F3FD 200D 2640 ; minimally-qualified # 🧔🏽♀ E13.1 woman: medium skin tone, beard
+1F9D4 1F3FE 200D 2640 FE0F ; fully-qualified # 🧔🏾♀️ E13.1 woman: medium-dark skin tone, beard
+1F9D4 1F3FE 200D 2640 ; minimally-qualified # 🧔🏾♀ E13.1 woman: medium-dark skin tone, beard
+1F9D4 1F3FF 200D 2640 FE0F ; fully-qualified # 🧔🏿♀️ E13.1 woman: dark skin tone, beard
+1F9D4 1F3FF 200D 2640 ; minimally-qualified # 🧔🏿♀ E13.1 woman: dark skin tone, beard
+1F468 200D 1F9B0 ; fully-qualified # 👨🦰 E11.0 man: red hair
+1F468 1F3FB 200D 1F9B0 ; fully-qualified # 👨🏻🦰 E11.0 man: light skin tone, red hair
+1F468 1F3FC 200D 1F9B0 ; fully-qualified # 👨🏼🦰 E11.0 man: medium-light skin tone, red hair
+1F468 1F3FD 200D 1F9B0 ; fully-qualified # 👨🏽🦰 E11.0 man: medium skin tone, red hair
+1F468 1F3FE 200D 1F9B0 ; fully-qualified # 👨🏾🦰 E11.0 man: medium-dark skin tone, red hair
+1F468 1F3FF 200D 1F9B0 ; fully-qualified # 👨🏿🦰 E11.0 man: dark skin tone, red hair
+1F468 200D 1F9B1 ; fully-qualified # 👨🦱 E11.0 man: curly hair
+1F468 1F3FB 200D 1F9B1 ; fully-qualified # 👨🏻🦱 E11.0 man: light skin tone, curly hair
+1F468 1F3FC 200D 1F9B1 ; fully-qualified # 👨🏼🦱 E11.0 man: medium-light skin tone, curly hair
+1F468 1F3FD 200D 1F9B1 ; fully-qualified # 👨🏽🦱 E11.0 man: medium skin tone, curly hair
+1F468 1F3FE 200D 1F9B1 ; fully-qualified # 👨🏾🦱 E11.0 man: medium-dark skin tone, curly hair
+1F468 1F3FF 200D 1F9B1 ; fully-qualified # 👨🏿🦱 E11.0 man: dark skin tone, curly hair
+1F468 200D 1F9B3 ; fully-qualified # 👨🦳 E11.0 man: white hair
+1F468 1F3FB 200D 1F9B3 ; fully-qualified # 👨🏻🦳 E11.0 man: light skin tone, white hair
+1F468 1F3FC 200D 1F9B3 ; fully-qualified # 👨🏼🦳 E11.0 man: medium-light skin tone, white hair
+1F468 1F3FD 200D 1F9B3 ; fully-qualified # 👨🏽🦳 E11.0 man: medium skin tone, white hair
+1F468 1F3FE 200D 1F9B3 ; fully-qualified # 👨🏾🦳 E11.0 man: medium-dark skin tone, white hair
+1F468 1F3FF 200D 1F9B3 ; fully-qualified # 👨🏿🦳 E11.0 man: dark skin tone, white hair
+1F468 200D 1F9B2 ; fully-qualified # 👨🦲 E11.0 man: bald
+1F468 1F3FB 200D 1F9B2 ; fully-qualified # 👨🏻🦲 E11.0 man: light skin tone, bald
+1F468 1F3FC 200D 1F9B2 ; fully-qualified # 👨🏼🦲 E11.0 man: medium-light skin tone, bald
+1F468 1F3FD 200D 1F9B2 ; fully-qualified # 👨🏽🦲 E11.0 man: medium skin tone, bald
+1F468 1F3FE 200D 1F9B2 ; fully-qualified # 👨🏾🦲 E11.0 man: medium-dark skin tone, bald
+1F468 1F3FF 200D 1F9B2 ; fully-qualified # 👨🏿🦲 E11.0 man: dark skin tone, bald
+1F469 ; fully-qualified # 👩 E0.6 woman
+1F469 1F3FB ; fully-qualified # 👩🏻 E1.0 woman: light skin tone
+1F469 1F3FC ; fully-qualified # 👩🏼 E1.0 woman: medium-light skin tone
+1F469 1F3FD ; fully-qualified # 👩🏽 E1.0 woman: medium skin tone
+1F469 1F3FE ; fully-qualified # 👩🏾 E1.0 woman: medium-dark skin tone
+1F469 1F3FF ; fully-qualified # 👩🏿 E1.0 woman: dark skin tone
+1F469 200D 1F9B0 ; fully-qualified # 👩🦰 E11.0 woman: red hair
+1F469 1F3FB 200D 1F9B0 ; fully-qualified # 👩🏻🦰 E11.0 woman: light skin tone, red hair
+1F469 1F3FC 200D 1F9B0 ; fully-qualified # 👩🏼🦰 E11.0 woman: medium-light skin tone, red hair
+1F469 1F3FD 200D 1F9B0 ; fully-qualified # 👩🏽🦰 E11.0 woman: medium skin tone, red hair
+1F469 1F3FE 200D 1F9B0 ; fully-qualified # 👩🏾🦰 E11.0 woman: medium-dark skin tone, red hair
+1F469 1F3FF 200D 1F9B0 ; fully-qualified # 👩🏿🦰 E11.0 woman: dark skin tone, red hair
+1F9D1 200D 1F9B0 ; fully-qualified # 🧑🦰 E12.1 person: red hair
+1F9D1 1F3FB 200D 1F9B0 ; fully-qualified # 🧑🏻🦰 E12.1 person: light skin tone, red hair
+1F9D1 1F3FC 200D 1F9B0 ; fully-qualified # 🧑🏼🦰 E12.1 person: medium-light skin tone, red hair
+1F9D1 1F3FD 200D 1F9B0 ; fully-qualified # 🧑🏽🦰 E12.1 person: medium skin tone, red hair
+1F9D1 1F3FE 200D 1F9B0 ; fully-qualified # 🧑🏾🦰 E12.1 person: medium-dark skin tone, red hair
+1F9D1 1F3FF 200D 1F9B0 ; fully-qualified # 🧑🏿🦰 E12.1 person: dark skin tone, red hair
+1F469 200D 1F9B1 ; fully-qualified # 👩🦱 E11.0 woman: curly hair
+1F469 1F3FB 200D 1F9B1 ; fully-qualified # 👩🏻🦱 E11.0 woman: light skin tone, curly hair
+1F469 1F3FC 200D 1F9B1 ; fully-qualified # 👩🏼🦱 E11.0 woman: medium-light skin tone, curly hair
+1F469 1F3FD 200D 1F9B1 ; fully-qualified # 👩🏽🦱 E11.0 woman: medium skin tone, curly hair
+1F469 1F3FE 200D 1F9B1 ; fully-qualified # 👩🏾🦱 E11.0 woman: medium-dark skin tone, curly hair
+1F469 1F3FF 200D 1F9B1 ; fully-qualified # 👩🏿🦱 E11.0 woman: dark skin tone, curly hair
+1F9D1 200D 1F9B1 ; fully-qualified # 🧑🦱 E12.1 person: curly hair
+1F9D1 1F3FB 200D 1F9B1 ; fully-qualified # 🧑🏻🦱 E12.1 person: light skin tone, curly hair
+1F9D1 1F3FC 200D 1F9B1 ; fully-qualified # 🧑🏼🦱 E12.1 person: medium-light skin tone, curly hair
+1F9D1 1F3FD 200D 1F9B1 ; fully-qualified # 🧑🏽🦱 E12.1 person: medium skin tone, curly hair
+1F9D1 1F3FE 200D 1F9B1 ; fully-qualified # 🧑🏾🦱 E12.1 person: medium-dark skin tone, curly hair
+1F9D1 1F3FF 200D 1F9B1 ; fully-qualified # 🧑🏿🦱 E12.1 person: dark skin tone, curly hair
+1F469 200D 1F9B3 ; fully-qualified # 👩🦳 E11.0 woman: white hair
+1F469 1F3FB 200D 1F9B3 ; fully-qualified # 👩🏻🦳 E11.0 woman: light skin tone, white hair
+1F469 1F3FC 200D 1F9B3 ; fully-qualified # 👩🏼🦳 E11.0 woman: medium-light skin tone, white hair
+1F469 1F3FD 200D 1F9B3 ; fully-qualified # 👩🏽🦳 E11.0 woman: medium skin tone, white hair
+1F469 1F3FE 200D 1F9B3 ; fully-qualified # 👩🏾🦳 E11.0 woman: medium-dark skin tone, white hair
+1F469 1F3FF 200D 1F9B3 ; fully-qualified # 👩🏿🦳 E11.0 woman: dark skin tone, white hair
+1F9D1 200D 1F9B3 ; fully-qualified # 🧑🦳 E12.1 person: white hair
+1F9D1 1F3FB 200D 1F9B3 ; fully-qualified # 🧑🏻🦳 E12.1 person: light skin tone, white hair
+1F9D1 1F3FC 200D 1F9B3 ; fully-qualified # 🧑🏼🦳 E12.1 person: medium-light skin tone, white hair
+1F9D1 1F3FD 200D 1F9B3 ; fully-qualified # 🧑🏽🦳 E12.1 person: medium skin tone, white hair
+1F9D1 1F3FE 200D 1F9B3 ; fully-qualified # 🧑🏾🦳 E12.1 person: medium-dark skin tone, white hair
+1F9D1 1F3FF 200D 1F9B3 ; fully-qualified # 🧑🏿🦳 E12.1 person: dark skin tone, white hair
+1F469 200D 1F9B2 ; fully-qualified # 👩🦲 E11.0 woman: bald
+1F469 1F3FB 200D 1F9B2 ; fully-qualified # 👩🏻🦲 E11.0 woman: light skin tone, bald
+1F469 1F3FC 200D 1F9B2 ; fully-qualified # 👩🏼🦲 E11.0 woman: medium-light skin tone, bald
+1F469 1F3FD 200D 1F9B2 ; fully-qualified # 👩🏽🦲 E11.0 woman: medium skin tone, bald
+1F469 1F3FE 200D 1F9B2 ; fully-qualified # 👩🏾🦲 E11.0 woman: medium-dark skin tone, bald
+1F469 1F3FF 200D 1F9B2 ; fully-qualified # 👩🏿🦲 E11.0 woman: dark skin tone, bald
+1F9D1 200D 1F9B2 ; fully-qualified # 🧑🦲 E12.1 person: bald
+1F9D1 1F3FB 200D 1F9B2 ; fully-qualified # 🧑🏻🦲 E12.1 person: light skin tone, bald
+1F9D1 1F3FC 200D 1F9B2 ; fully-qualified # 🧑🏼🦲 E12.1 person: medium-light skin tone, bald
+1F9D1 1F3FD 200D 1F9B2 ; fully-qualified # 🧑🏽🦲 E12.1 person: medium skin tone, bald
+1F9D1 1F3FE 200D 1F9B2 ; fully-qualified # 🧑🏾🦲 E12.1 person: medium-dark skin tone, bald
+1F9D1 1F3FF 200D 1F9B2 ; fully-qualified # 🧑🏿🦲 E12.1 person: dark skin tone, bald
+1F471 200D 2640 FE0F ; fully-qualified # 👱♀️ E4.0 woman: blond hair
+1F471 200D 2640 ; minimally-qualified # 👱♀ E4.0 woman: blond hair
+1F471 1F3FB 200D 2640 FE0F ; fully-qualified # 👱🏻♀️ E4.0 woman: light skin tone, blond hair
+1F471 1F3FB 200D 2640 ; minimally-qualified # 👱🏻♀ E4.0 woman: light skin tone, blond hair
+1F471 1F3FC 200D 2640 FE0F ; fully-qualified # 👱🏼♀️ E4.0 woman: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2640 ; minimally-qualified # 👱🏼♀ E4.0 woman: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2640 FE0F ; fully-qualified # 👱🏽♀️ E4.0 woman: medium skin tone, blond hair
+1F471 1F3FD 200D 2640 ; minimally-qualified # 👱🏽♀ E4.0 woman: medium skin tone, blond hair
+1F471 1F3FE 200D 2640 FE0F ; fully-qualified # 👱🏾♀️ E4.0 woman: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2640 ; minimally-qualified # 👱🏾♀ E4.0 woman: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2640 FE0F ; fully-qualified # 👱🏿♀️ E4.0 woman: dark skin tone, blond hair
+1F471 1F3FF 200D 2640 ; minimally-qualified # 👱🏿♀ E4.0 woman: dark skin tone, blond hair
+1F471 200D 2642 FE0F ; fully-qualified # 👱♂️ E4.0 man: blond hair
+1F471 200D 2642 ; minimally-qualified # 👱♂ E4.0 man: blond hair
+1F471 1F3FB 200D 2642 FE0F ; fully-qualified # 👱🏻♂️ E4.0 man: light skin tone, blond hair
+1F471 1F3FB 200D 2642 ; minimally-qualified # 👱🏻♂ E4.0 man: light skin tone, blond hair
+1F471 1F3FC 200D 2642 FE0F ; fully-qualified # 👱🏼♂️ E4.0 man: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2642 ; minimally-qualified # 👱🏼♂ E4.0 man: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2642 FE0F ; fully-qualified # 👱🏽♂️ E4.0 man: medium skin tone, blond hair
+1F471 1F3FD 200D 2642 ; minimally-qualified # 👱🏽♂ E4.0 man: medium skin tone, blond hair
+1F471 1F3FE 200D 2642 FE0F ; fully-qualified # 👱🏾♂️ E4.0 man: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2642 ; minimally-qualified # 👱🏾♂ E4.0 man: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2642 FE0F ; fully-qualified # 👱🏿♂️ E4.0 man: dark skin tone, blond hair
+1F471 1F3FF 200D 2642 ; minimally-qualified # 👱🏿♂ E4.0 man: dark skin tone, blond hair
+1F9D3 ; fully-qualified # 🧓 E5.0 older person
+1F9D3 1F3FB ; fully-qualified # 🧓🏻 E5.0 older person: light skin tone
+1F9D3 1F3FC ; fully-qualified # 🧓🏼 E5.0 older person: medium-light skin tone
+1F9D3 1F3FD ; fully-qualified # 🧓🏽 E5.0 older person: medium skin tone
+1F9D3 1F3FE ; fully-qualified # 🧓🏾 E5.0 older person: medium-dark skin tone
+1F9D3 1F3FF ; fully-qualified # 🧓🏿 E5.0 older person: dark skin tone
+1F474 ; fully-qualified # 👴 E0.6 old man
+1F474 1F3FB ; fully-qualified # 👴🏻 E1.0 old man: light skin tone
+1F474 1F3FC ; fully-qualified # 👴🏼 E1.0 old man: medium-light skin tone
+1F474 1F3FD ; fully-qualified # 👴🏽 E1.0 old man: medium skin tone
+1F474 1F3FE ; fully-qualified # 👴🏾 E1.0 old man: medium-dark skin tone
+1F474 1F3FF ; fully-qualified # 👴🏿 E1.0 old man: dark skin tone
+1F475 ; fully-qualified # 👵 E0.6 old woman
+1F475 1F3FB ; fully-qualified # 👵🏻 E1.0 old woman: light skin tone
+1F475 1F3FC ; fully-qualified # 👵🏼 E1.0 old woman: medium-light skin tone
+1F475 1F3FD ; fully-qualified # 👵🏽 E1.0 old woman: medium skin tone
+1F475 1F3FE ; fully-qualified # 👵🏾 E1.0 old woman: medium-dark skin tone
+1F475 1F3FF ; fully-qualified # 👵🏿 E1.0 old woman: dark skin tone
# subgroup: person-gesture
-1F64D ; fully-qualified # 🙍 E0.6 person frowning
-1F64D 1F3FB ; fully-qualified # 🙍🏻 E1.0 person frowning: light skin tone
-1F64D 1F3FC ; fully-qualified # 🙍🏼 E1.0 person frowning: medium-light skin tone
-1F64D 1F3FD ; fully-qualified # 🙍🏽 E1.0 person frowning: medium skin tone
-1F64D 1F3FE ; fully-qualified # 🙍🏾 E1.0 person frowning: medium-dark skin tone
-1F64D 1F3FF ; fully-qualified # 🙍🏿 E1.0 person frowning: dark skin tone
-1F64D 200D 2642 FE0F ; fully-qualified # 🙍♂️ E4.0 man frowning
-1F64D 200D 2642 ; minimally-qualified # 🙍♂ E4.0 man frowning
-1F64D 1F3FB 200D 2642 FE0F ; fully-qualified # 🙍🏻♂️ E4.0 man frowning: light skin tone
-1F64D 1F3FB 200D 2642 ; minimally-qualified # 🙍🏻♂ E4.0 man frowning: light skin tone
-1F64D 1F3FC 200D 2642 FE0F ; fully-qualified # 🙍🏼♂️ E4.0 man frowning: medium-light skin tone
-1F64D 1F3FC 200D 2642 ; minimally-qualified # 🙍🏼♂ E4.0 man frowning: medium-light skin tone
-1F64D 1F3FD 200D 2642 FE0F ; fully-qualified # 🙍🏽♂️ E4.0 man frowning: medium skin tone
-1F64D 1F3FD 200D 2642 ; minimally-qualified # 🙍🏽♂ E4.0 man frowning: medium skin tone
-1F64D 1F3FE 200D 2642 FE0F ; fully-qualified # 🙍🏾♂️ E4.0 man frowning: medium-dark skin tone
-1F64D 1F3FE 200D 2642 ; minimally-qualified # 🙍🏾♂ E4.0 man frowning: medium-dark skin tone
-1F64D 1F3FF 200D 2642 FE0F ; fully-qualified # 🙍🏿♂️ E4.0 man frowning: dark skin tone
-1F64D 1F3FF 200D 2642 ; minimally-qualified # 🙍🏿♂ E4.0 man frowning: dark skin tone
-1F64D 200D 2640 FE0F ; fully-qualified # 🙍♀️ E4.0 woman frowning
-1F64D 200D 2640 ; minimally-qualified # 🙍♀ E4.0 woman frowning
-1F64D 1F3FB 200D 2640 FE0F ; fully-qualified # 🙍🏻♀️ E4.0 woman frowning: light skin tone
-1F64D 1F3FB 200D 2640 ; minimally-qualified # 🙍🏻♀ E4.0 woman frowning: light skin tone
-1F64D 1F3FC 200D 2640 FE0F ; fully-qualified # 🙍🏼♀️ E4.0 woman frowning: medium-light skin tone
-1F64D 1F3FC 200D 2640 ; minimally-qualified # 🙍🏼♀ E4.0 woman frowning: medium-light skin tone
-1F64D 1F3FD 200D 2640 FE0F ; fully-qualified # 🙍🏽♀️ E4.0 woman frowning: medium skin tone
-1F64D 1F3FD 200D 2640 ; minimally-qualified # 🙍🏽♀ E4.0 woman frowning: medium skin tone
-1F64D 1F3FE 200D 2640 FE0F ; fully-qualified # 🙍🏾♀️ E4.0 woman frowning: medium-dark skin tone
-1F64D 1F3FE 200D 2640 ; minimally-qualified # 🙍🏾♀ E4.0 woman frowning: medium-dark skin tone
-1F64D 1F3FF 200D 2640 FE0F ; fully-qualified # 🙍🏿♀️ E4.0 woman frowning: dark skin tone
-1F64D 1F3FF 200D 2640 ; minimally-qualified # 🙍🏿♀ E4.0 woman frowning: dark skin tone
-1F64E ; fully-qualified # 🙎 E0.6 person pouting
-1F64E 1F3FB ; fully-qualified # 🙎🏻 E1.0 person pouting: light skin tone
-1F64E 1F3FC ; fully-qualified # 🙎🏼 E1.0 person pouting: medium-light skin tone
-1F64E 1F3FD ; fully-qualified # 🙎🏽 E1.0 person pouting: medium skin tone
-1F64E 1F3FE ; fully-qualified # 🙎🏾 E1.0 person pouting: medium-dark skin tone
-1F64E 1F3FF ; fully-qualified # 🙎🏿 E1.0 person pouting: dark skin tone
-1F64E 200D 2642 FE0F ; fully-qualified # 🙎♂️ E4.0 man pouting
-1F64E 200D 2642 ; minimally-qualified # 🙎♂ E4.0 man pouting
-1F64E 1F3FB 200D 2642 FE0F ; fully-qualified # 🙎🏻♂️ E4.0 man pouting: light skin tone
-1F64E 1F3FB 200D 2642 ; minimally-qualified # 🙎🏻♂ E4.0 man pouting: light skin tone
-1F64E 1F3FC 200D 2642 FE0F ; fully-qualified # 🙎🏼♂️ E4.0 man pouting: medium-light skin tone
-1F64E 1F3FC 200D 2642 ; minimally-qualified # 🙎🏼♂ E4.0 man pouting: medium-light skin tone
-1F64E 1F3FD 200D 2642 FE0F ; fully-qualified # 🙎🏽♂️ E4.0 man pouting: medium skin tone
-1F64E 1F3FD 200D 2642 ; minimally-qualified # 🙎🏽♂ E4.0 man pouting: medium skin tone
-1F64E 1F3FE 200D 2642 FE0F ; fully-qualified # 🙎🏾♂️ E4.0 man pouting: medium-dark skin tone
-1F64E 1F3FE 200D 2642 ; minimally-qualified # 🙎🏾♂ E4.0 man pouting: medium-dark skin tone
-1F64E 1F3FF 200D 2642 FE0F ; fully-qualified # 🙎🏿♂️ E4.0 man pouting: dark skin tone
-1F64E 1F3FF 200D 2642 ; minimally-qualified # 🙎🏿♂ E4.0 man pouting: dark skin tone
-1F64E 200D 2640 FE0F ; fully-qualified # 🙎♀️ E4.0 woman pouting
-1F64E 200D 2640 ; minimally-qualified # 🙎♀ E4.0 woman pouting
-1F64E 1F3FB 200D 2640 FE0F ; fully-qualified # 🙎🏻♀️ E4.0 woman pouting: light skin tone
-1F64E 1F3FB 200D 2640 ; minimally-qualified # 🙎🏻♀ E4.0 woman pouting: light skin tone
-1F64E 1F3FC 200D 2640 FE0F ; fully-qualified # 🙎🏼♀️ E4.0 woman pouting: medium-light skin tone
-1F64E 1F3FC 200D 2640 ; minimally-qualified # 🙎🏼♀ E4.0 woman pouting: medium-light skin tone
-1F64E 1F3FD 200D 2640 FE0F ; fully-qualified # 🙎🏽♀️ E4.0 woman pouting: medium skin tone
-1F64E 1F3FD 200D 2640 ; minimally-qualified # 🙎🏽♀ E4.0 woman pouting: medium skin tone
-1F64E 1F3FE 200D 2640 FE0F ; fully-qualified # 🙎🏾♀️ E4.0 woman pouting: medium-dark skin tone
-1F64E 1F3FE 200D 2640 ; minimally-qualified # 🙎🏾♀ E4.0 woman pouting: medium-dark skin tone
-1F64E 1F3FF 200D 2640 FE0F ; fully-qualified # 🙎🏿♀️ E4.0 woman pouting: dark skin tone
-1F64E 1F3FF 200D 2640 ; minimally-qualified # 🙎🏿♀ E4.0 woman pouting: dark skin tone
-1F645 ; fully-qualified # 🙅 E0.6 person gesturing NO
-1F645 1F3FB ; fully-qualified # 🙅🏻 E1.0 person gesturing NO: light skin tone
-1F645 1F3FC ; fully-qualified # 🙅🏼 E1.0 person gesturing NO: medium-light skin tone
-1F645 1F3FD ; fully-qualified # 🙅🏽 E1.0 person gesturing NO: medium skin tone
-1F645 1F3FE ; fully-qualified # 🙅🏾 E1.0 person gesturing NO: medium-dark skin tone
-1F645 1F3FF ; fully-qualified # 🙅🏿 E1.0 person gesturing NO: dark skin tone
-1F645 200D 2642 FE0F ; fully-qualified # 🙅♂️ E4.0 man gesturing NO
-1F645 200D 2642 ; minimally-qualified # 🙅♂ E4.0 man gesturing NO
-1F645 1F3FB 200D 2642 FE0F ; fully-qualified # 🙅🏻♂️ E4.0 man gesturing NO: light skin tone
-1F645 1F3FB 200D 2642 ; minimally-qualified # 🙅🏻♂ E4.0 man gesturing NO: light skin tone
-1F645 1F3FC 200D 2642 FE0F ; fully-qualified # 🙅🏼♂️ E4.0 man gesturing NO: medium-light skin tone
-1F645 1F3FC 200D 2642 ; minimally-qualified # 🙅🏼♂ E4.0 man gesturing NO: medium-light skin tone
-1F645 1F3FD 200D 2642 FE0F ; fully-qualified # 🙅🏽♂️ E4.0 man gesturing NO: medium skin tone
-1F645 1F3FD 200D 2642 ; minimally-qualified # 🙅🏽♂ E4.0 man gesturing NO: medium skin tone
-1F645 1F3FE 200D 2642 FE0F ; fully-qualified # 🙅🏾♂️ E4.0 man gesturing NO: medium-dark skin tone
-1F645 1F3FE 200D 2642 ; minimally-qualified # 🙅🏾♂ E4.0 man gesturing NO: medium-dark skin tone
-1F645 1F3FF 200D 2642 FE0F ; fully-qualified # 🙅🏿♂️ E4.0 man gesturing NO: dark skin tone
-1F645 1F3FF 200D 2642 ; minimally-qualified # 🙅🏿♂ E4.0 man gesturing NO: dark skin tone
-1F645 200D 2640 FE0F ; fully-qualified # 🙅♀️ E4.0 woman gesturing NO
-1F645 200D 2640 ; minimally-qualified # 🙅♀ E4.0 woman gesturing NO
-1F645 1F3FB 200D 2640 FE0F ; fully-qualified # 🙅🏻♀️ E4.0 woman gesturing NO: light skin tone
-1F645 1F3FB 200D 2640 ; minimally-qualified # 🙅🏻♀ E4.0 woman gesturing NO: light skin tone
-1F645 1F3FC 200D 2640 FE0F ; fully-qualified # 🙅🏼♀️ E4.0 woman gesturing NO: medium-light skin tone
-1F645 1F3FC 200D 2640 ; minimally-qualified # 🙅🏼♀ E4.0 woman gesturing NO: medium-light skin tone
-1F645 1F3FD 200D 2640 FE0F ; fully-qualified # 🙅🏽♀️ E4.0 woman gesturing NO: medium skin tone
-1F645 1F3FD 200D 2640 ; minimally-qualified # 🙅🏽♀ E4.0 woman gesturing NO: medium skin tone
-1F645 1F3FE 200D 2640 FE0F ; fully-qualified # 🙅🏾♀️ E4.0 woman gesturing NO: medium-dark skin tone
-1F645 1F3FE 200D 2640 ; minimally-qualified # 🙅🏾♀ E4.0 woman gesturing NO: medium-dark skin tone
-1F645 1F3FF 200D 2640 FE0F ; fully-qualified # 🙅🏿♀️ E4.0 woman gesturing NO: dark skin tone
-1F645 1F3FF 200D 2640 ; minimally-qualified # 🙅🏿♀ E4.0 woman gesturing NO: dark skin tone
-1F646 ; fully-qualified # 🙆 E0.6 person gesturing OK
-1F646 1F3FB ; fully-qualified # 🙆🏻 E1.0 person gesturing OK: light skin tone
-1F646 1F3FC ; fully-qualified # 🙆🏼 E1.0 person gesturing OK: medium-light skin tone
-1F646 1F3FD ; fully-qualified # 🙆🏽 E1.0 person gesturing OK: medium skin tone
-1F646 1F3FE ; fully-qualified # 🙆🏾 E1.0 person gesturing OK: medium-dark skin tone
-1F646 1F3FF ; fully-qualified # 🙆🏿 E1.0 person gesturing OK: dark skin tone
-1F646 200D 2642 FE0F ; fully-qualified # 🙆♂️ E4.0 man gesturing OK
-1F646 200D 2642 ; minimally-qualified # 🙆♂ E4.0 man gesturing OK
-1F646 1F3FB 200D 2642 FE0F ; fully-qualified # 🙆🏻♂️ E4.0 man gesturing OK: light skin tone
-1F646 1F3FB 200D 2642 ; minimally-qualified # 🙆🏻♂ E4.0 man gesturing OK: light skin tone
-1F646 1F3FC 200D 2642 FE0F ; fully-qualified # 🙆🏼♂️ E4.0 man gesturing OK: medium-light skin tone
-1F646 1F3FC 200D 2642 ; minimally-qualified # 🙆🏼♂ E4.0 man gesturing OK: medium-light skin tone
-1F646 1F3FD 200D 2642 FE0F ; fully-qualified # 🙆🏽♂️ E4.0 man gesturing OK: medium skin tone
-1F646 1F3FD 200D 2642 ; minimally-qualified # 🙆🏽♂ E4.0 man gesturing OK: medium skin tone
-1F646 1F3FE 200D 2642 FE0F ; fully-qualified # 🙆🏾♂️ E4.0 man gesturing OK: medium-dark skin tone
-1F646 1F3FE 200D 2642 ; minimally-qualified # 🙆🏾♂ E4.0 man gesturing OK: medium-dark skin tone
-1F646 1F3FF 200D 2642 FE0F ; fully-qualified # 🙆🏿♂️ E4.0 man gesturing OK: dark skin tone
-1F646 1F3FF 200D 2642 ; minimally-qualified # 🙆🏿♂ E4.0 man gesturing OK: dark skin tone
-1F646 200D 2640 FE0F ; fully-qualified # 🙆♀️ E4.0 woman gesturing OK
-1F646 200D 2640 ; minimally-qualified # 🙆♀ E4.0 woman gesturing OK
-1F646 1F3FB 200D 2640 FE0F ; fully-qualified # 🙆🏻♀️ E4.0 woman gesturing OK: light skin tone
-1F646 1F3FB 200D 2640 ; minimally-qualified # 🙆🏻♀ E4.0 woman gesturing OK: light skin tone
-1F646 1F3FC 200D 2640 FE0F ; fully-qualified # 🙆🏼♀️ E4.0 woman gesturing OK: medium-light skin tone
-1F646 1F3FC 200D 2640 ; minimally-qualified # 🙆🏼♀ E4.0 woman gesturing OK: medium-light skin tone
-1F646 1F3FD 200D 2640 FE0F ; fully-qualified # 🙆🏽♀️ E4.0 woman gesturing OK: medium skin tone
-1F646 1F3FD 200D 2640 ; minimally-qualified # 🙆🏽♀ E4.0 woman gesturing OK: medium skin tone
-1F646 1F3FE 200D 2640 FE0F ; fully-qualified # 🙆🏾♀️ E4.0 woman gesturing OK: medium-dark skin tone
-1F646 1F3FE 200D 2640 ; minimally-qualified # 🙆🏾♀ E4.0 woman gesturing OK: medium-dark skin tone
-1F646 1F3FF 200D 2640 FE0F ; fully-qualified # 🙆🏿♀️ E4.0 woman gesturing OK: dark skin tone
-1F646 1F3FF 200D 2640 ; minimally-qualified # 🙆🏿♀ E4.0 woman gesturing OK: dark skin tone
-1F481 ; fully-qualified # 💁 E0.6 person tipping hand
-1F481 1F3FB ; fully-qualified # 💁🏻 E1.0 person tipping hand: light skin tone
-1F481 1F3FC ; fully-qualified # 💁🏼 E1.0 person tipping hand: medium-light skin tone
-1F481 1F3FD ; fully-qualified # 💁🏽 E1.0 person tipping hand: medium skin tone
-1F481 1F3FE ; fully-qualified # 💁🏾 E1.0 person tipping hand: medium-dark skin tone
-1F481 1F3FF ; fully-qualified # 💁🏿 E1.0 person tipping hand: dark skin tone
-1F481 200D 2642 FE0F ; fully-qualified # 💁♂️ E4.0 man tipping hand
-1F481 200D 2642 ; minimally-qualified # 💁♂ E4.0 man tipping hand
-1F481 1F3FB 200D 2642 FE0F ; fully-qualified # 💁🏻♂️ E4.0 man tipping hand: light skin tone
-1F481 1F3FB 200D 2642 ; minimally-qualified # 💁🏻♂ E4.0 man tipping hand: light skin tone
-1F481 1F3FC 200D 2642 FE0F ; fully-qualified # 💁🏼♂️ E4.0 man tipping hand: medium-light skin tone
-1F481 1F3FC 200D 2642 ; minimally-qualified # 💁🏼♂ E4.0 man tipping hand: medium-light skin tone
-1F481 1F3FD 200D 2642 FE0F ; fully-qualified # 💁🏽♂️ E4.0 man tipping hand: medium skin tone
-1F481 1F3FD 200D 2642 ; minimally-qualified # 💁🏽♂ E4.0 man tipping hand: medium skin tone
-1F481 1F3FE 200D 2642 FE0F ; fully-qualified # 💁🏾♂️ E4.0 man tipping hand: medium-dark skin tone
-1F481 1F3FE 200D 2642 ; minimally-qualified # 💁🏾♂ E4.0 man tipping hand: medium-dark skin tone
-1F481 1F3FF 200D 2642 FE0F ; fully-qualified # 💁🏿♂️ E4.0 man tipping hand: dark skin tone
-1F481 1F3FF 200D 2642 ; minimally-qualified # 💁🏿♂ E4.0 man tipping hand: dark skin tone
-1F481 200D 2640 FE0F ; fully-qualified # 💁♀️ E4.0 woman tipping hand
-1F481 200D 2640 ; minimally-qualified # 💁♀ E4.0 woman tipping hand
-1F481 1F3FB 200D 2640 FE0F ; fully-qualified # 💁🏻♀️ E4.0 woman tipping hand: light skin tone
-1F481 1F3FB 200D 2640 ; minimally-qualified # 💁🏻♀ E4.0 woman tipping hand: light skin tone
-1F481 1F3FC 200D 2640 FE0F ; fully-qualified # 💁🏼♀️ E4.0 woman tipping hand: medium-light skin tone
-1F481 1F3FC 200D 2640 ; minimally-qualified # 💁🏼♀ E4.0 woman tipping hand: medium-light skin tone
-1F481 1F3FD 200D 2640 FE0F ; fully-qualified # 💁🏽♀️ E4.0 woman tipping hand: medium skin tone
-1F481 1F3FD 200D 2640 ; minimally-qualified # 💁🏽♀ E4.0 woman tipping hand: medium skin tone
-1F481 1F3FE 200D 2640 FE0F ; fully-qualified # 💁🏾♀️ E4.0 woman tipping hand: medium-dark skin tone
-1F481 1F3FE 200D 2640 ; minimally-qualified # 💁🏾♀ E4.0 woman tipping hand: medium-dark skin tone
-1F481 1F3FF 200D 2640 FE0F ; fully-qualified # 💁🏿♀️ E4.0 woman tipping hand: dark skin tone
-1F481 1F3FF 200D 2640 ; minimally-qualified # 💁🏿♀ E4.0 woman tipping hand: dark skin tone
-1F64B ; fully-qualified # 🙋 E0.6 person raising hand
-1F64B 1F3FB ; fully-qualified # 🙋🏻 E1.0 person raising hand: light skin tone
-1F64B 1F3FC ; fully-qualified # 🙋🏼 E1.0 person raising hand: medium-light skin tone
-1F64B 1F3FD ; fully-qualified # 🙋🏽 E1.0 person raising hand: medium skin tone
-1F64B 1F3FE ; fully-qualified # 🙋🏾 E1.0 person raising hand: medium-dark skin tone
-1F64B 1F3FF ; fully-qualified # 🙋🏿 E1.0 person raising hand: dark skin tone
-1F64B 200D 2642 FE0F ; fully-qualified # 🙋♂️ E4.0 man raising hand
-1F64B 200D 2642 ; minimally-qualified # 🙋♂ E4.0 man raising hand
-1F64B 1F3FB 200D 2642 FE0F ; fully-qualified # 🙋🏻♂️ E4.0 man raising hand: light skin tone
-1F64B 1F3FB 200D 2642 ; minimally-qualified # 🙋🏻♂ E4.0 man raising hand: light skin tone
-1F64B 1F3FC 200D 2642 FE0F ; fully-qualified # 🙋🏼♂️ E4.0 man raising hand: medium-light skin tone
-1F64B 1F3FC 200D 2642 ; minimally-qualified # 🙋🏼♂ E4.0 man raising hand: medium-light skin tone
-1F64B 1F3FD 200D 2642 FE0F ; fully-qualified # 🙋🏽♂️ E4.0 man raising hand: medium skin tone
-1F64B 1F3FD 200D 2642 ; minimally-qualified # 🙋🏽♂ E4.0 man raising hand: medium skin tone
-1F64B 1F3FE 200D 2642 FE0F ; fully-qualified # 🙋🏾♂️ E4.0 man raising hand: medium-dark skin tone
-1F64B 1F3FE 200D 2642 ; minimally-qualified # 🙋🏾♂ E4.0 man raising hand: medium-dark skin tone
-1F64B 1F3FF 200D 2642 FE0F ; fully-qualified # 🙋🏿♂️ E4.0 man raising hand: dark skin tone
-1F64B 1F3FF 200D 2642 ; minimally-qualified # 🙋🏿♂ E4.0 man raising hand: dark skin tone
-1F64B 200D 2640 FE0F ; fully-qualified # 🙋♀️ E4.0 woman raising hand
-1F64B 200D 2640 ; minimally-qualified # 🙋♀ E4.0 woman raising hand
-1F64B 1F3FB 200D 2640 FE0F ; fully-qualified # 🙋🏻♀️ E4.0 woman raising hand: light skin tone
-1F64B 1F3FB 200D 2640 ; minimally-qualified # 🙋🏻♀ E4.0 woman raising hand: light skin tone
-1F64B 1F3FC 200D 2640 FE0F ; fully-qualified # 🙋🏼♀️ E4.0 woman raising hand: medium-light skin tone
-1F64B 1F3FC 200D 2640 ; minimally-qualified # 🙋🏼♀ E4.0 woman raising hand: medium-light skin tone
-1F64B 1F3FD 200D 2640 FE0F ; fully-qualified # 🙋🏽♀️ E4.0 woman raising hand: medium skin tone
-1F64B 1F3FD 200D 2640 ; minimally-qualified # 🙋🏽♀ E4.0 woman raising hand: medium skin tone
-1F64B 1F3FE 200D 2640 FE0F ; fully-qualified # 🙋🏾♀️ E4.0 woman raising hand: medium-dark skin tone
-1F64B 1F3FE 200D 2640 ; minimally-qualified # 🙋🏾♀ E4.0 woman raising hand: medium-dark skin tone
-1F64B 1F3FF 200D 2640 FE0F ; fully-qualified # 🙋🏿♀️ E4.0 woman raising hand: dark skin tone
-1F64B 1F3FF 200D 2640 ; minimally-qualified # 🙋🏿♀ E4.0 woman raising hand: dark skin tone
-1F9CF ; fully-qualified # 🧏 E12.0 deaf person
-1F9CF 1F3FB ; fully-qualified # 🧏🏻 E12.0 deaf person: light skin tone
-1F9CF 1F3FC ; fully-qualified # 🧏🏼 E12.0 deaf person: medium-light skin tone
-1F9CF 1F3FD ; fully-qualified # 🧏🏽 E12.0 deaf person: medium skin tone
-1F9CF 1F3FE ; fully-qualified # 🧏🏾 E12.0 deaf person: medium-dark skin tone
-1F9CF 1F3FF ; fully-qualified # 🧏🏿 E12.0 deaf person: dark skin tone
-1F9CF 200D 2642 FE0F ; fully-qualified # 🧏♂️ E12.0 deaf man
-1F9CF 200D 2642 ; minimally-qualified # 🧏♂ E12.0 deaf man
-1F9CF 1F3FB 200D 2642 FE0F ; fully-qualified # 🧏🏻♂️ E12.0 deaf man: light skin tone
-1F9CF 1F3FB 200D 2642 ; minimally-qualified # 🧏🏻♂ E12.0 deaf man: light skin tone
-1F9CF 1F3FC 200D 2642 FE0F ; fully-qualified # 🧏🏼♂️ E12.0 deaf man: medium-light skin tone
-1F9CF 1F3FC 200D 2642 ; minimally-qualified # 🧏🏼♂ E12.0 deaf man: medium-light skin tone
-1F9CF 1F3FD 200D 2642 FE0F ; fully-qualified # 🧏🏽♂️ E12.0 deaf man: medium skin tone
-1F9CF 1F3FD 200D 2642 ; minimally-qualified # 🧏🏽♂ E12.0 deaf man: medium skin tone
-1F9CF 1F3FE 200D 2642 FE0F ; fully-qualified # 🧏🏾♂️ E12.0 deaf man: medium-dark skin tone
-1F9CF 1F3FE 200D 2642 ; minimally-qualified # 🧏🏾♂ E12.0 deaf man: medium-dark skin tone
-1F9CF 1F3FF 200D 2642 FE0F ; fully-qualified # 🧏🏿♂️ E12.0 deaf man: dark skin tone
-1F9CF 1F3FF 200D 2642 ; minimally-qualified # 🧏🏿♂ E12.0 deaf man: dark skin tone
-1F9CF 200D 2640 FE0F ; fully-qualified # 🧏♀️ E12.0 deaf woman
-1F9CF 200D 2640 ; minimally-qualified # 🧏♀ E12.0 deaf woman
-1F9CF 1F3FB 200D 2640 FE0F ; fully-qualified # 🧏🏻♀️ E12.0 deaf woman: light skin tone
-1F9CF 1F3FB 200D 2640 ; minimally-qualified # 🧏🏻♀ E12.0 deaf woman: light skin tone
-1F9CF 1F3FC 200D 2640 FE0F ; fully-qualified # 🧏🏼♀️ E12.0 deaf woman: medium-light skin tone
-1F9CF 1F3FC 200D 2640 ; minimally-qualified # 🧏🏼♀ E12.0 deaf woman: medium-light skin tone
-1F9CF 1F3FD 200D 2640 FE0F ; fully-qualified # 🧏🏽♀️ E12.0 deaf woman: medium skin tone
-1F9CF 1F3FD 200D 2640 ; minimally-qualified # 🧏🏽♀ E12.0 deaf woman: medium skin tone
-1F9CF 1F3FE 200D 2640 FE0F ; fully-qualified # 🧏🏾♀️ E12.0 deaf woman: medium-dark skin tone
-1F9CF 1F3FE 200D 2640 ; minimally-qualified # 🧏🏾♀ E12.0 deaf woman: medium-dark skin tone
-1F9CF 1F3FF 200D 2640 FE0F ; fully-qualified # 🧏🏿♀️ E12.0 deaf woman: dark skin tone
-1F9CF 1F3FF 200D 2640 ; minimally-qualified # 🧏🏿♀ E12.0 deaf woman: dark skin tone
-1F647 ; fully-qualified # 🙇 E0.6 person bowing
-1F647 1F3FB ; fully-qualified # 🙇🏻 E1.0 person bowing: light skin tone
-1F647 1F3FC ; fully-qualified # 🙇🏼 E1.0 person bowing: medium-light skin tone
-1F647 1F3FD ; fully-qualified # 🙇🏽 E1.0 person bowing: medium skin tone
-1F647 1F3FE ; fully-qualified # 🙇🏾 E1.0 person bowing: medium-dark skin tone
-1F647 1F3FF ; fully-qualified # 🙇🏿 E1.0 person bowing: dark skin tone
-1F647 200D 2642 FE0F ; fully-qualified # 🙇♂️ E4.0 man bowing
-1F647 200D 2642 ; minimally-qualified # 🙇♂ E4.0 man bowing
-1F647 1F3FB 200D 2642 FE0F ; fully-qualified # 🙇🏻♂️ E4.0 man bowing: light skin tone
-1F647 1F3FB 200D 2642 ; minimally-qualified # 🙇🏻♂ E4.0 man bowing: light skin tone
-1F647 1F3FC 200D 2642 FE0F ; fully-qualified # 🙇🏼♂️ E4.0 man bowing: medium-light skin tone
-1F647 1F3FC 200D 2642 ; minimally-qualified # 🙇🏼♂ E4.0 man bowing: medium-light skin tone
-1F647 1F3FD 200D 2642 FE0F ; fully-qualified # 🙇🏽♂️ E4.0 man bowing: medium skin tone
-1F647 1F3FD 200D 2642 ; minimally-qualified # 🙇🏽♂ E4.0 man bowing: medium skin tone
-1F647 1F3FE 200D 2642 FE0F ; fully-qualified # 🙇🏾♂️ E4.0 man bowing: medium-dark skin tone
-1F647 1F3FE 200D 2642 ; minimally-qualified # 🙇🏾♂ E4.0 man bowing: medium-dark skin tone
-1F647 1F3FF 200D 2642 FE0F ; fully-qualified # 🙇🏿♂️ E4.0 man bowing: dark skin tone
-1F647 1F3FF 200D 2642 ; minimally-qualified # 🙇🏿♂ E4.0 man bowing: dark skin tone
-1F647 200D 2640 FE0F ; fully-qualified # 🙇♀️ E4.0 woman bowing
-1F647 200D 2640 ; minimally-qualified # 🙇♀ E4.0 woman bowing
-1F647 1F3FB 200D 2640 FE0F ; fully-qualified # 🙇🏻♀️ E4.0 woman bowing: light skin tone
-1F647 1F3FB 200D 2640 ; minimally-qualified # 🙇🏻♀ E4.0 woman bowing: light skin tone
-1F647 1F3FC 200D 2640 FE0F ; fully-qualified # 🙇🏼♀️ E4.0 woman bowing: medium-light skin tone
-1F647 1F3FC 200D 2640 ; minimally-qualified # 🙇🏼♀ E4.0 woman bowing: medium-light skin tone
-1F647 1F3FD 200D 2640 FE0F ; fully-qualified # 🙇🏽♀️ E4.0 woman bowing: medium skin tone
-1F647 1F3FD 200D 2640 ; minimally-qualified # 🙇🏽♀ E4.0 woman bowing: medium skin tone
-1F647 1F3FE 200D 2640 FE0F ; fully-qualified # 🙇🏾♀️ E4.0 woman bowing: medium-dark skin tone
-1F647 1F3FE 200D 2640 ; minimally-qualified # 🙇🏾♀ E4.0 woman bowing: medium-dark skin tone
-1F647 1F3FF 200D 2640 FE0F ; fully-qualified # 🙇🏿♀️ E4.0 woman bowing: dark skin tone
-1F647 1F3FF 200D 2640 ; minimally-qualified # 🙇🏿♀ E4.0 woman bowing: dark skin tone
-1F926 ; fully-qualified # 🤦 E3.0 person facepalming
-1F926 1F3FB ; fully-qualified # 🤦🏻 E3.0 person facepalming: light skin tone
-1F926 1F3FC ; fully-qualified # 🤦🏼 E3.0 person facepalming: medium-light skin tone
-1F926 1F3FD ; fully-qualified # 🤦🏽 E3.0 person facepalming: medium skin tone
-1F926 1F3FE ; fully-qualified # 🤦🏾 E3.0 person facepalming: medium-dark skin tone
-1F926 1F3FF ; fully-qualified # 🤦🏿 E3.0 person facepalming: dark skin tone
-1F926 200D 2642 FE0F ; fully-qualified # 🤦♂️ E4.0 man facepalming
-1F926 200D 2642 ; minimally-qualified # 🤦♂ E4.0 man facepalming
-1F926 1F3FB 200D 2642 FE0F ; fully-qualified # 🤦🏻♂️ E4.0 man facepalming: light skin tone
-1F926 1F3FB 200D 2642 ; minimally-qualified # 🤦🏻♂ E4.0 man facepalming: light skin tone
-1F926 1F3FC 200D 2642 FE0F ; fully-qualified # 🤦🏼♂️ E4.0 man facepalming: medium-light skin tone
-1F926 1F3FC 200D 2642 ; minimally-qualified # 🤦🏼♂ E4.0 man facepalming: medium-light skin tone
-1F926 1F3FD 200D 2642 FE0F ; fully-qualified # 🤦🏽♂️ E4.0 man facepalming: medium skin tone
-1F926 1F3FD 200D 2642 ; minimally-qualified # 🤦🏽♂ E4.0 man facepalming: medium skin tone
-1F926 1F3FE 200D 2642 FE0F ; fully-qualified # 🤦🏾♂️ E4.0 man facepalming: medium-dark skin tone
-1F926 1F3FE 200D 2642 ; minimally-qualified # 🤦🏾♂ E4.0 man facepalming: medium-dark skin tone
-1F926 1F3FF 200D 2642 FE0F ; fully-qualified # 🤦🏿♂️ E4.0 man facepalming: dark skin tone
-1F926 1F3FF 200D 2642 ; minimally-qualified # 🤦🏿♂ E4.0 man facepalming: dark skin tone
-1F926 200D 2640 FE0F ; fully-qualified # 🤦♀️ E4.0 woman facepalming
-1F926 200D 2640 ; minimally-qualified # 🤦♀ E4.0 woman facepalming
-1F926 1F3FB 200D 2640 FE0F ; fully-qualified # 🤦🏻♀️ E4.0 woman facepalming: light skin tone
-1F926 1F3FB 200D 2640 ; minimally-qualified # 🤦🏻♀ E4.0 woman facepalming: light skin tone
-1F926 1F3FC 200D 2640 FE0F ; fully-qualified # 🤦🏼♀️ E4.0 woman facepalming: medium-light skin tone
-1F926 1F3FC 200D 2640 ; minimally-qualified # 🤦🏼♀ E4.0 woman facepalming: medium-light skin tone
-1F926 1F3FD 200D 2640 FE0F ; fully-qualified # 🤦🏽♀️ E4.0 woman facepalming: medium skin tone
-1F926 1F3FD 200D 2640 ; minimally-qualified # 🤦🏽♀ E4.0 woman facepalming: medium skin tone
-1F926 1F3FE 200D 2640 FE0F ; fully-qualified # 🤦🏾♀️ E4.0 woman facepalming: medium-dark skin tone
-1F926 1F3FE 200D 2640 ; minimally-qualified # 🤦🏾♀ E4.0 woman facepalming: medium-dark skin tone
-1F926 1F3FF 200D 2640 FE0F ; fully-qualified # 🤦🏿♀️ E4.0 woman facepalming: dark skin tone
-1F926 1F3FF 200D 2640 ; minimally-qualified # 🤦🏿♀ E4.0 woman facepalming: dark skin tone
-1F937 ; fully-qualified # 🤷 E3.0 person shrugging
-1F937 1F3FB ; fully-qualified # 🤷🏻 E3.0 person shrugging: light skin tone
-1F937 1F3FC ; fully-qualified # 🤷🏼 E3.0 person shrugging: medium-light skin tone
-1F937 1F3FD ; fully-qualified # 🤷🏽 E3.0 person shrugging: medium skin tone
-1F937 1F3FE ; fully-qualified # 🤷🏾 E3.0 person shrugging: medium-dark skin tone
-1F937 1F3FF ; fully-qualified # 🤷🏿 E3.0 person shrugging: dark skin tone
-1F937 200D 2642 FE0F ; fully-qualified # 🤷♂️ E4.0 man shrugging
-1F937 200D 2642 ; minimally-qualified # 🤷♂ E4.0 man shrugging
-1F937 1F3FB 200D 2642 FE0F ; fully-qualified # 🤷🏻♂️ E4.0 man shrugging: light skin tone
-1F937 1F3FB 200D 2642 ; minimally-qualified # 🤷🏻♂ E4.0 man shrugging: light skin tone
-1F937 1F3FC 200D 2642 FE0F ; fully-qualified # 🤷🏼♂️ E4.0 man shrugging: medium-light skin tone
-1F937 1F3FC 200D 2642 ; minimally-qualified # 🤷🏼♂ E4.0 man shrugging: medium-light skin tone
-1F937 1F3FD 200D 2642 FE0F ; fully-qualified # 🤷🏽♂️ E4.0 man shrugging: medium skin tone
-1F937 1F3FD 200D 2642 ; minimally-qualified # 🤷🏽♂ E4.0 man shrugging: medium skin tone
-1F937 1F3FE 200D 2642 FE0F ; fully-qualified # 🤷🏾♂️ E4.0 man shrugging: medium-dark skin tone
-1F937 1F3FE 200D 2642 ; minimally-qualified # 🤷🏾♂ E4.0 man shrugging: medium-dark skin tone
-1F937 1F3FF 200D 2642 FE0F ; fully-qualified # 🤷🏿♂️ E4.0 man shrugging: dark skin tone
-1F937 1F3FF 200D 2642 ; minimally-qualified # 🤷🏿♂ E4.0 man shrugging: dark skin tone
-1F937 200D 2640 FE0F ; fully-qualified # 🤷♀️ E4.0 woman shrugging
-1F937 200D 2640 ; minimally-qualified # 🤷♀ E4.0 woman shrugging
-1F937 1F3FB 200D 2640 FE0F ; fully-qualified # 🤷🏻♀️ E4.0 woman shrugging: light skin tone
-1F937 1F3FB 200D 2640 ; minimally-qualified # 🤷🏻♀ E4.0 woman shrugging: light skin tone
-1F937 1F3FC 200D 2640 FE0F ; fully-qualified # 🤷🏼♀️ E4.0 woman shrugging: medium-light skin tone
-1F937 1F3FC 200D 2640 ; minimally-qualified # 🤷🏼♀ E4.0 woman shrugging: medium-light skin tone
-1F937 1F3FD 200D 2640 FE0F ; fully-qualified # 🤷🏽♀️ E4.0 woman shrugging: medium skin tone
-1F937 1F3FD 200D 2640 ; minimally-qualified # 🤷🏽♀ E4.0 woman shrugging: medium skin tone
-1F937 1F3FE 200D 2640 FE0F ; fully-qualified # 🤷🏾♀️ E4.0 woman shrugging: medium-dark skin tone
-1F937 1F3FE 200D 2640 ; minimally-qualified # 🤷🏾♀ E4.0 woman shrugging: medium-dark skin tone
-1F937 1F3FF 200D 2640 FE0F ; fully-qualified # 🤷🏿♀️ E4.0 woman shrugging: dark skin tone
-1F937 1F3FF 200D 2640 ; minimally-qualified # 🤷🏿♀ E4.0 woman shrugging: dark skin tone
+1F64D ; fully-qualified # 🙍 E0.6 person frowning
+1F64D 1F3FB ; fully-qualified # 🙍🏻 E1.0 person frowning: light skin tone
+1F64D 1F3FC ; fully-qualified # 🙍🏼 E1.0 person frowning: medium-light skin tone
+1F64D 1F3FD ; fully-qualified # 🙍🏽 E1.0 person frowning: medium skin tone
+1F64D 1F3FE ; fully-qualified # 🙍🏾 E1.0 person frowning: medium-dark skin tone
+1F64D 1F3FF ; fully-qualified # 🙍🏿 E1.0 person frowning: dark skin tone
+1F64D 200D 2642 FE0F ; fully-qualified # 🙍♂️ E4.0 man frowning
+1F64D 200D 2642 ; minimally-qualified # 🙍♂ E4.0 man frowning
+1F64D 1F3FB 200D 2642 FE0F ; fully-qualified # 🙍🏻♂️ E4.0 man frowning: light skin tone
+1F64D 1F3FB 200D 2642 ; minimally-qualified # 🙍🏻♂ E4.0 man frowning: light skin tone
+1F64D 1F3FC 200D 2642 FE0F ; fully-qualified # 🙍🏼♂️ E4.0 man frowning: medium-light skin tone
+1F64D 1F3FC 200D 2642 ; minimally-qualified # 🙍🏼♂ E4.0 man frowning: medium-light skin tone
+1F64D 1F3FD 200D 2642 FE0F ; fully-qualified # 🙍🏽♂️ E4.0 man frowning: medium skin tone
+1F64D 1F3FD 200D 2642 ; minimally-qualified # 🙍🏽♂ E4.0 man frowning: medium skin tone
+1F64D 1F3FE 200D 2642 FE0F ; fully-qualified # 🙍🏾♂️ E4.0 man frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2642 ; minimally-qualified # 🙍🏾♂ E4.0 man frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2642 FE0F ; fully-qualified # 🙍🏿♂️ E4.0 man frowning: dark skin tone
+1F64D 1F3FF 200D 2642 ; minimally-qualified # 🙍🏿♂ E4.0 man frowning: dark skin tone
+1F64D 200D 2640 FE0F ; fully-qualified # 🙍♀️ E4.0 woman frowning
+1F64D 200D 2640 ; minimally-qualified # 🙍♀ E4.0 woman frowning
+1F64D 1F3FB 200D 2640 FE0F ; fully-qualified # 🙍🏻♀️ E4.0 woman frowning: light skin tone
+1F64D 1F3FB 200D 2640 ; minimally-qualified # 🙍🏻♀ E4.0 woman frowning: light skin tone
+1F64D 1F3FC 200D 2640 FE0F ; fully-qualified # 🙍🏼♀️ E4.0 woman frowning: medium-light skin tone
+1F64D 1F3FC 200D 2640 ; minimally-qualified # 🙍🏼♀ E4.0 woman frowning: medium-light skin tone
+1F64D 1F3FD 200D 2640 FE0F ; fully-qualified # 🙍🏽♀️ E4.0 woman frowning: medium skin tone
+1F64D 1F3FD 200D 2640 ; minimally-qualified # 🙍🏽♀ E4.0 woman frowning: medium skin tone
+1F64D 1F3FE 200D 2640 FE0F ; fully-qualified # 🙍🏾♀️ E4.0 woman frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2640 ; minimally-qualified # 🙍🏾♀ E4.0 woman frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2640 FE0F ; fully-qualified # 🙍🏿♀️ E4.0 woman frowning: dark skin tone
+1F64D 1F3FF 200D 2640 ; minimally-qualified # 🙍🏿♀ E4.0 woman frowning: dark skin tone
+1F64E ; fully-qualified # 🙎 E0.6 person pouting
+1F64E 1F3FB ; fully-qualified # 🙎🏻 E1.0 person pouting: light skin tone
+1F64E 1F3FC ; fully-qualified # 🙎🏼 E1.0 person pouting: medium-light skin tone
+1F64E 1F3FD ; fully-qualified # 🙎🏽 E1.0 person pouting: medium skin tone
+1F64E 1F3FE ; fully-qualified # 🙎🏾 E1.0 person pouting: medium-dark skin tone
+1F64E 1F3FF ; fully-qualified # 🙎🏿 E1.0 person pouting: dark skin tone
+1F64E 200D 2642 FE0F ; fully-qualified # 🙎♂️ E4.0 man pouting
+1F64E 200D 2642 ; minimally-qualified # 🙎♂ E4.0 man pouting
+1F64E 1F3FB 200D 2642 FE0F ; fully-qualified # 🙎🏻♂️ E4.0 man pouting: light skin tone
+1F64E 1F3FB 200D 2642 ; minimally-qualified # 🙎🏻♂ E4.0 man pouting: light skin tone
+1F64E 1F3FC 200D 2642 FE0F ; fully-qualified # 🙎🏼♂️ E4.0 man pouting: medium-light skin tone
+1F64E 1F3FC 200D 2642 ; minimally-qualified # 🙎🏼♂ E4.0 man pouting: medium-light skin tone
+1F64E 1F3FD 200D 2642 FE0F ; fully-qualified # 🙎🏽♂️ E4.0 man pouting: medium skin tone
+1F64E 1F3FD 200D 2642 ; minimally-qualified # 🙎🏽♂ E4.0 man pouting: medium skin tone
+1F64E 1F3FE 200D 2642 FE0F ; fully-qualified # 🙎🏾♂️ E4.0 man pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2642 ; minimally-qualified # 🙎🏾♂ E4.0 man pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2642 FE0F ; fully-qualified # 🙎🏿♂️ E4.0 man pouting: dark skin tone
+1F64E 1F3FF 200D 2642 ; minimally-qualified # 🙎🏿♂ E4.0 man pouting: dark skin tone
+1F64E 200D 2640 FE0F ; fully-qualified # 🙎♀️ E4.0 woman pouting
+1F64E 200D 2640 ; minimally-qualified # 🙎♀ E4.0 woman pouting
+1F64E 1F3FB 200D 2640 FE0F ; fully-qualified # 🙎🏻♀️ E4.0 woman pouting: light skin tone
+1F64E 1F3FB 200D 2640 ; minimally-qualified # 🙎🏻♀ E4.0 woman pouting: light skin tone
+1F64E 1F3FC 200D 2640 FE0F ; fully-qualified # 🙎🏼♀️ E4.0 woman pouting: medium-light skin tone
+1F64E 1F3FC 200D 2640 ; minimally-qualified # 🙎🏼♀ E4.0 woman pouting: medium-light skin tone
+1F64E 1F3FD 200D 2640 FE0F ; fully-qualified # 🙎🏽♀️ E4.0 woman pouting: medium skin tone
+1F64E 1F3FD 200D 2640 ; minimally-qualified # 🙎🏽♀ E4.0 woman pouting: medium skin tone
+1F64E 1F3FE 200D 2640 FE0F ; fully-qualified # 🙎🏾♀️ E4.0 woman pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2640 ; minimally-qualified # 🙎🏾♀ E4.0 woman pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2640 FE0F ; fully-qualified # 🙎🏿♀️ E4.0 woman pouting: dark skin tone
+1F64E 1F3FF 200D 2640 ; minimally-qualified # 🙎🏿♀ E4.0 woman pouting: dark skin tone
+1F645 ; fully-qualified # 🙅 E0.6 person gesturing NO
+1F645 1F3FB ; fully-qualified # 🙅🏻 E1.0 person gesturing NO: light skin tone
+1F645 1F3FC ; fully-qualified # 🙅🏼 E1.0 person gesturing NO: medium-light skin tone
+1F645 1F3FD ; fully-qualified # 🙅🏽 E1.0 person gesturing NO: medium skin tone
+1F645 1F3FE ; fully-qualified # 🙅🏾 E1.0 person gesturing NO: medium-dark skin tone
+1F645 1F3FF ; fully-qualified # 🙅🏿 E1.0 person gesturing NO: dark skin tone
+1F645 200D 2642 FE0F ; fully-qualified # 🙅♂️ E4.0 man gesturing NO
+1F645 200D 2642 ; minimally-qualified # 🙅♂ E4.0 man gesturing NO
+1F645 1F3FB 200D 2642 FE0F ; fully-qualified # 🙅🏻♂️ E4.0 man gesturing NO: light skin tone
+1F645 1F3FB 200D 2642 ; minimally-qualified # 🙅🏻♂ E4.0 man gesturing NO: light skin tone
+1F645 1F3FC 200D 2642 FE0F ; fully-qualified # 🙅🏼♂️ E4.0 man gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2642 ; minimally-qualified # 🙅🏼♂ E4.0 man gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2642 FE0F ; fully-qualified # 🙅🏽♂️ E4.0 man gesturing NO: medium skin tone
+1F645 1F3FD 200D 2642 ; minimally-qualified # 🙅🏽♂ E4.0 man gesturing NO: medium skin tone
+1F645 1F3FE 200D 2642 FE0F ; fully-qualified # 🙅🏾♂️ E4.0 man gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2642 ; minimally-qualified # 🙅🏾♂ E4.0 man gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2642 FE0F ; fully-qualified # 🙅🏿♂️ E4.0 man gesturing NO: dark skin tone
+1F645 1F3FF 200D 2642 ; minimally-qualified # 🙅🏿♂ E4.0 man gesturing NO: dark skin tone
+1F645 200D 2640 FE0F ; fully-qualified # 🙅♀️ E4.0 woman gesturing NO
+1F645 200D 2640 ; minimally-qualified # 🙅♀ E4.0 woman gesturing NO
+1F645 1F3FB 200D 2640 FE0F ; fully-qualified # 🙅🏻♀️ E4.0 woman gesturing NO: light skin tone
+1F645 1F3FB 200D 2640 ; minimally-qualified # 🙅🏻♀ E4.0 woman gesturing NO: light skin tone
+1F645 1F3FC 200D 2640 FE0F ; fully-qualified # 🙅🏼♀️ E4.0 woman gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2640 ; minimally-qualified # 🙅🏼♀ E4.0 woman gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2640 FE0F ; fully-qualified # 🙅🏽♀️ E4.0 woman gesturing NO: medium skin tone
+1F645 1F3FD 200D 2640 ; minimally-qualified # 🙅🏽♀ E4.0 woman gesturing NO: medium skin tone
+1F645 1F3FE 200D 2640 FE0F ; fully-qualified # 🙅🏾♀️ E4.0 woman gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2640 ; minimally-qualified # 🙅🏾♀ E4.0 woman gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2640 FE0F ; fully-qualified # 🙅🏿♀️ E4.0 woman gesturing NO: dark skin tone
+1F645 1F3FF 200D 2640 ; minimally-qualified # 🙅🏿♀ E4.0 woman gesturing NO: dark skin tone
+1F646 ; fully-qualified # 🙆 E0.6 person gesturing OK
+1F646 1F3FB ; fully-qualified # 🙆🏻 E1.0 person gesturing OK: light skin tone
+1F646 1F3FC ; fully-qualified # 🙆🏼 E1.0 person gesturing OK: medium-light skin tone
+1F646 1F3FD ; fully-qualified # 🙆🏽 E1.0 person gesturing OK: medium skin tone
+1F646 1F3FE ; fully-qualified # 🙆🏾 E1.0 person gesturing OK: medium-dark skin tone
+1F646 1F3FF ; fully-qualified # 🙆🏿 E1.0 person gesturing OK: dark skin tone
+1F646 200D 2642 FE0F ; fully-qualified # 🙆♂️ E4.0 man gesturing OK
+1F646 200D 2642 ; minimally-qualified # 🙆♂ E4.0 man gesturing OK
+1F646 1F3FB 200D 2642 FE0F ; fully-qualified # 🙆🏻♂️ E4.0 man gesturing OK: light skin tone
+1F646 1F3FB 200D 2642 ; minimally-qualified # 🙆🏻♂ E4.0 man gesturing OK: light skin tone
+1F646 1F3FC 200D 2642 FE0F ; fully-qualified # 🙆🏼♂️ E4.0 man gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2642 ; minimally-qualified # 🙆🏼♂ E4.0 man gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2642 FE0F ; fully-qualified # 🙆🏽♂️ E4.0 man gesturing OK: medium skin tone
+1F646 1F3FD 200D 2642 ; minimally-qualified # 🙆🏽♂ E4.0 man gesturing OK: medium skin tone
+1F646 1F3FE 200D 2642 FE0F ; fully-qualified # 🙆🏾♂️ E4.0 man gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2642 ; minimally-qualified # 🙆🏾♂ E4.0 man gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2642 FE0F ; fully-qualified # 🙆🏿♂️ E4.0 man gesturing OK: dark skin tone
+1F646 1F3FF 200D 2642 ; minimally-qualified # 🙆🏿♂ E4.0 man gesturing OK: dark skin tone
+1F646 200D 2640 FE0F ; fully-qualified # 🙆♀️ E4.0 woman gesturing OK
+1F646 200D 2640 ; minimally-qualified # 🙆♀ E4.0 woman gesturing OK
+1F646 1F3FB 200D 2640 FE0F ; fully-qualified # 🙆🏻♀️ E4.0 woman gesturing OK: light skin tone
+1F646 1F3FB 200D 2640 ; minimally-qualified # 🙆🏻♀ E4.0 woman gesturing OK: light skin tone
+1F646 1F3FC 200D 2640 FE0F ; fully-qualified # 🙆🏼♀️ E4.0 woman gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2640 ; minimally-qualified # 🙆🏼♀ E4.0 woman gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2640 FE0F ; fully-qualified # 🙆🏽♀️ E4.0 woman gesturing OK: medium skin tone
+1F646 1F3FD 200D 2640 ; minimally-qualified # 🙆🏽♀ E4.0 woman gesturing OK: medium skin tone
+1F646 1F3FE 200D 2640 FE0F ; fully-qualified # 🙆🏾♀️ E4.0 woman gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2640 ; minimally-qualified # 🙆🏾♀ E4.0 woman gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2640 FE0F ; fully-qualified # 🙆🏿♀️ E4.0 woman gesturing OK: dark skin tone
+1F646 1F3FF 200D 2640 ; minimally-qualified # 🙆🏿♀ E4.0 woman gesturing OK: dark skin tone
+1F481 ; fully-qualified # 💁 E0.6 person tipping hand
+1F481 1F3FB ; fully-qualified # 💁🏻 E1.0 person tipping hand: light skin tone
+1F481 1F3FC ; fully-qualified # 💁🏼 E1.0 person tipping hand: medium-light skin tone
+1F481 1F3FD ; fully-qualified # 💁🏽 E1.0 person tipping hand: medium skin tone
+1F481 1F3FE ; fully-qualified # 💁🏾 E1.0 person tipping hand: medium-dark skin tone
+1F481 1F3FF ; fully-qualified # 💁🏿 E1.0 person tipping hand: dark skin tone
+1F481 200D 2642 FE0F ; fully-qualified # 💁♂️ E4.0 man tipping hand
+1F481 200D 2642 ; minimally-qualified # 💁♂ E4.0 man tipping hand
+1F481 1F3FB 200D 2642 FE0F ; fully-qualified # 💁🏻♂️ E4.0 man tipping hand: light skin tone
+1F481 1F3FB 200D 2642 ; minimally-qualified # 💁🏻♂ E4.0 man tipping hand: light skin tone
+1F481 1F3FC 200D 2642 FE0F ; fully-qualified # 💁🏼♂️ E4.0 man tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2642 ; minimally-qualified # 💁🏼♂ E4.0 man tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2642 FE0F ; fully-qualified # 💁🏽♂️ E4.0 man tipping hand: medium skin tone
+1F481 1F3FD 200D 2642 ; minimally-qualified # 💁🏽♂ E4.0 man tipping hand: medium skin tone
+1F481 1F3FE 200D 2642 FE0F ; fully-qualified # 💁🏾♂️ E4.0 man tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2642 ; minimally-qualified # 💁🏾♂ E4.0 man tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2642 FE0F ; fully-qualified # 💁🏿♂️ E4.0 man tipping hand: dark skin tone
+1F481 1F3FF 200D 2642 ; minimally-qualified # 💁🏿♂ E4.0 man tipping hand: dark skin tone
+1F481 200D 2640 FE0F ; fully-qualified # 💁♀️ E4.0 woman tipping hand
+1F481 200D 2640 ; minimally-qualified # 💁♀ E4.0 woman tipping hand
+1F481 1F3FB 200D 2640 FE0F ; fully-qualified # 💁🏻♀️ E4.0 woman tipping hand: light skin tone
+1F481 1F3FB 200D 2640 ; minimally-qualified # 💁🏻♀ E4.0 woman tipping hand: light skin tone
+1F481 1F3FC 200D 2640 FE0F ; fully-qualified # 💁🏼♀️ E4.0 woman tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2640 ; minimally-qualified # 💁🏼♀ E4.0 woman tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2640 FE0F ; fully-qualified # 💁🏽♀️ E4.0 woman tipping hand: medium skin tone
+1F481 1F3FD 200D 2640 ; minimally-qualified # 💁🏽♀ E4.0 woman tipping hand: medium skin tone
+1F481 1F3FE 200D 2640 FE0F ; fully-qualified # 💁🏾♀️ E4.0 woman tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2640 ; minimally-qualified # 💁🏾♀ E4.0 woman tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2640 FE0F ; fully-qualified # 💁🏿♀️ E4.0 woman tipping hand: dark skin tone
+1F481 1F3FF 200D 2640 ; minimally-qualified # 💁🏿♀ E4.0 woman tipping hand: dark skin tone
+1F64B ; fully-qualified # 🙋 E0.6 person raising hand
+1F64B 1F3FB ; fully-qualified # 🙋🏻 E1.0 person raising hand: light skin tone
+1F64B 1F3FC ; fully-qualified # 🙋🏼 E1.0 person raising hand: medium-light skin tone
+1F64B 1F3FD ; fully-qualified # 🙋🏽 E1.0 person raising hand: medium skin tone
+1F64B 1F3FE ; fully-qualified # 🙋🏾 E1.0 person raising hand: medium-dark skin tone
+1F64B 1F3FF ; fully-qualified # 🙋🏿 E1.0 person raising hand: dark skin tone
+1F64B 200D 2642 FE0F ; fully-qualified # 🙋♂️ E4.0 man raising hand
+1F64B 200D 2642 ; minimally-qualified # 🙋♂ E4.0 man raising hand
+1F64B 1F3FB 200D 2642 FE0F ; fully-qualified # 🙋🏻♂️ E4.0 man raising hand: light skin tone
+1F64B 1F3FB 200D 2642 ; minimally-qualified # 🙋🏻♂ E4.0 man raising hand: light skin tone
+1F64B 1F3FC 200D 2642 FE0F ; fully-qualified # 🙋🏼♂️ E4.0 man raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2642 ; minimally-qualified # 🙋🏼♂ E4.0 man raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2642 FE0F ; fully-qualified # 🙋🏽♂️ E4.0 man raising hand: medium skin tone
+1F64B 1F3FD 200D 2642 ; minimally-qualified # 🙋🏽♂ E4.0 man raising hand: medium skin tone
+1F64B 1F3FE 200D 2642 FE0F ; fully-qualified # 🙋🏾♂️ E4.0 man raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2642 ; minimally-qualified # 🙋🏾♂ E4.0 man raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2642 FE0F ; fully-qualified # 🙋🏿♂️ E4.0 man raising hand: dark skin tone
+1F64B 1F3FF 200D 2642 ; minimally-qualified # 🙋🏿♂ E4.0 man raising hand: dark skin tone
+1F64B 200D 2640 FE0F ; fully-qualified # 🙋♀️ E4.0 woman raising hand
+1F64B 200D 2640 ; minimally-qualified # 🙋♀ E4.0 woman raising hand
+1F64B 1F3FB 200D 2640 FE0F ; fully-qualified # 🙋🏻♀️ E4.0 woman raising hand: light skin tone
+1F64B 1F3FB 200D 2640 ; minimally-qualified # 🙋🏻♀ E4.0 woman raising hand: light skin tone
+1F64B 1F3FC 200D 2640 FE0F ; fully-qualified # 🙋🏼♀️ E4.0 woman raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2640 ; minimally-qualified # 🙋🏼♀ E4.0 woman raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2640 FE0F ; fully-qualified # 🙋🏽♀️ E4.0 woman raising hand: medium skin tone
+1F64B 1F3FD 200D 2640 ; minimally-qualified # 🙋🏽♀ E4.0 woman raising hand: medium skin tone
+1F64B 1F3FE 200D 2640 FE0F ; fully-qualified # 🙋🏾♀️ E4.0 woman raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2640 ; minimally-qualified # 🙋🏾♀ E4.0 woman raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2640 FE0F ; fully-qualified # 🙋🏿♀️ E4.0 woman raising hand: dark skin tone
+1F64B 1F3FF 200D 2640 ; minimally-qualified # 🙋🏿♀ E4.0 woman raising hand: dark skin tone
+1F9CF ; fully-qualified # 🧏 E12.0 deaf person
+1F9CF 1F3FB ; fully-qualified # 🧏🏻 E12.0 deaf person: light skin tone
+1F9CF 1F3FC ; fully-qualified # 🧏🏼 E12.0 deaf person: medium-light skin tone
+1F9CF 1F3FD ; fully-qualified # 🧏🏽 E12.0 deaf person: medium skin tone
+1F9CF 1F3FE ; fully-qualified # 🧏🏾 E12.0 deaf person: medium-dark skin tone
+1F9CF 1F3FF ; fully-qualified # 🧏🏿 E12.0 deaf person: dark skin tone
+1F9CF 200D 2642 FE0F ; fully-qualified # 🧏♂️ E12.0 deaf man
+1F9CF 200D 2642 ; minimally-qualified # 🧏♂ E12.0 deaf man
+1F9CF 1F3FB 200D 2642 FE0F ; fully-qualified # 🧏🏻♂️ E12.0 deaf man: light skin tone
+1F9CF 1F3FB 200D 2642 ; minimally-qualified # 🧏🏻♂ E12.0 deaf man: light skin tone
+1F9CF 1F3FC 200D 2642 FE0F ; fully-qualified # 🧏🏼♂️ E12.0 deaf man: medium-light skin tone
+1F9CF 1F3FC 200D 2642 ; minimally-qualified # 🧏🏼♂ E12.0 deaf man: medium-light skin tone
+1F9CF 1F3FD 200D 2642 FE0F ; fully-qualified # 🧏🏽♂️ E12.0 deaf man: medium skin tone
+1F9CF 1F3FD 200D 2642 ; minimally-qualified # 🧏🏽♂ E12.0 deaf man: medium skin tone
+1F9CF 1F3FE 200D 2642 FE0F ; fully-qualified # 🧏🏾♂️ E12.0 deaf man: medium-dark skin tone
+1F9CF 1F3FE 200D 2642 ; minimally-qualified # 🧏🏾♂ E12.0 deaf man: medium-dark skin tone
+1F9CF 1F3FF 200D 2642 FE0F ; fully-qualified # 🧏🏿♂️ E12.0 deaf man: dark skin tone
+1F9CF 1F3FF 200D 2642 ; minimally-qualified # 🧏🏿♂ E12.0 deaf man: dark skin tone
+1F9CF 200D 2640 FE0F ; fully-qualified # 🧏♀️ E12.0 deaf woman
+1F9CF 200D 2640 ; minimally-qualified # 🧏♀ E12.0 deaf woman
+1F9CF 1F3FB 200D 2640 FE0F ; fully-qualified # 🧏🏻♀️ E12.0 deaf woman: light skin tone
+1F9CF 1F3FB 200D 2640 ; minimally-qualified # 🧏🏻♀ E12.0 deaf woman: light skin tone
+1F9CF 1F3FC 200D 2640 FE0F ; fully-qualified # 🧏🏼♀️ E12.0 deaf woman: medium-light skin tone
+1F9CF 1F3FC 200D 2640 ; minimally-qualified # 🧏🏼♀ E12.0 deaf woman: medium-light skin tone
+1F9CF 1F3FD 200D 2640 FE0F ; fully-qualified # 🧏🏽♀️ E12.0 deaf woman: medium skin tone
+1F9CF 1F3FD 200D 2640 ; minimally-qualified # 🧏🏽♀ E12.0 deaf woman: medium skin tone
+1F9CF 1F3FE 200D 2640 FE0F ; fully-qualified # 🧏🏾♀️ E12.0 deaf woman: medium-dark skin tone
+1F9CF 1F3FE 200D 2640 ; minimally-qualified # 🧏🏾♀ E12.0 deaf woman: medium-dark skin tone
+1F9CF 1F3FF 200D 2640 FE0F ; fully-qualified # 🧏🏿♀️ E12.0 deaf woman: dark skin tone
+1F9CF 1F3FF 200D 2640 ; minimally-qualified # 🧏🏿♀ E12.0 deaf woman: dark skin tone
+1F647 ; fully-qualified # 🙇 E0.6 person bowing
+1F647 1F3FB ; fully-qualified # 🙇🏻 E1.0 person bowing: light skin tone
+1F647 1F3FC ; fully-qualified # 🙇🏼 E1.0 person bowing: medium-light skin tone
+1F647 1F3FD ; fully-qualified # 🙇🏽 E1.0 person bowing: medium skin tone
+1F647 1F3FE ; fully-qualified # 🙇🏾 E1.0 person bowing: medium-dark skin tone
+1F647 1F3FF ; fully-qualified # 🙇🏿 E1.0 person bowing: dark skin tone
+1F647 200D 2642 FE0F ; fully-qualified # 🙇♂️ E4.0 man bowing
+1F647 200D 2642 ; minimally-qualified # 🙇♂ E4.0 man bowing
+1F647 1F3FB 200D 2642 FE0F ; fully-qualified # 🙇🏻♂️ E4.0 man bowing: light skin tone
+1F647 1F3FB 200D 2642 ; minimally-qualified # 🙇🏻♂ E4.0 man bowing: light skin tone
+1F647 1F3FC 200D 2642 FE0F ; fully-qualified # 🙇🏼♂️ E4.0 man bowing: medium-light skin tone
+1F647 1F3FC 200D 2642 ; minimally-qualified # 🙇🏼♂ E4.0 man bowing: medium-light skin tone
+1F647 1F3FD 200D 2642 FE0F ; fully-qualified # 🙇🏽♂️ E4.0 man bowing: medium skin tone
+1F647 1F3FD 200D 2642 ; minimally-qualified # 🙇🏽♂ E4.0 man bowing: medium skin tone
+1F647 1F3FE 200D 2642 FE0F ; fully-qualified # 🙇🏾♂️ E4.0 man bowing: medium-dark skin tone
+1F647 1F3FE 200D 2642 ; minimally-qualified # 🙇🏾♂ E4.0 man bowing: medium-dark skin tone
+1F647 1F3FF 200D 2642 FE0F ; fully-qualified # 🙇🏿♂️ E4.0 man bowing: dark skin tone
+1F647 1F3FF 200D 2642 ; minimally-qualified # 🙇🏿♂ E4.0 man bowing: dark skin tone
+1F647 200D 2640 FE0F ; fully-qualified # 🙇♀️ E4.0 woman bowing
+1F647 200D 2640 ; minimally-qualified # 🙇♀ E4.0 woman bowing
+1F647 1F3FB 200D 2640 FE0F ; fully-qualified # 🙇🏻♀️ E4.0 woman bowing: light skin tone
+1F647 1F3FB 200D 2640 ; minimally-qualified # 🙇🏻♀ E4.0 woman bowing: light skin tone
+1F647 1F3FC 200D 2640 FE0F ; fully-qualified # 🙇🏼♀️ E4.0 woman bowing: medium-light skin tone
+1F647 1F3FC 200D 2640 ; minimally-qualified # 🙇🏼♀ E4.0 woman bowing: medium-light skin tone
+1F647 1F3FD 200D 2640 FE0F ; fully-qualified # 🙇🏽♀️ E4.0 woman bowing: medium skin tone
+1F647 1F3FD 200D 2640 ; minimally-qualified # 🙇🏽♀ E4.0 woman bowing: medium skin tone
+1F647 1F3FE 200D 2640 FE0F ; fully-qualified # 🙇🏾♀️ E4.0 woman bowing: medium-dark skin tone
+1F647 1F3FE 200D 2640 ; minimally-qualified # 🙇🏾♀ E4.0 woman bowing: medium-dark skin tone
+1F647 1F3FF 200D 2640 FE0F ; fully-qualified # 🙇🏿♀️ E4.0 woman bowing: dark skin tone
+1F647 1F3FF 200D 2640 ; minimally-qualified # 🙇🏿♀ E4.0 woman bowing: dark skin tone
+1F926 ; fully-qualified # 🤦 E3.0 person facepalming
+1F926 1F3FB ; fully-qualified # 🤦🏻 E3.0 person facepalming: light skin tone
+1F926 1F3FC ; fully-qualified # 🤦🏼 E3.0 person facepalming: medium-light skin tone
+1F926 1F3FD ; fully-qualified # 🤦🏽 E3.0 person facepalming: medium skin tone
+1F926 1F3FE ; fully-qualified # 🤦🏾 E3.0 person facepalming: medium-dark skin tone
+1F926 1F3FF ; fully-qualified # 🤦🏿 E3.0 person facepalming: dark skin tone
+1F926 200D 2642 FE0F ; fully-qualified # 🤦♂️ E4.0 man facepalming
+1F926 200D 2642 ; minimally-qualified # 🤦♂ E4.0 man facepalming
+1F926 1F3FB 200D 2642 FE0F ; fully-qualified # 🤦🏻♂️ E4.0 man facepalming: light skin tone
+1F926 1F3FB 200D 2642 ; minimally-qualified # 🤦🏻♂ E4.0 man facepalming: light skin tone
+1F926 1F3FC 200D 2642 FE0F ; fully-qualified # 🤦🏼♂️ E4.0 man facepalming: medium-light skin tone
+1F926 1F3FC 200D 2642 ; minimally-qualified # 🤦🏼♂ E4.0 man facepalming: medium-light skin tone
+1F926 1F3FD 200D 2642 FE0F ; fully-qualified # 🤦🏽♂️ E4.0 man facepalming: medium skin tone
+1F926 1F3FD 200D 2642 ; minimally-qualified # 🤦🏽♂ E4.0 man facepalming: medium skin tone
+1F926 1F3FE 200D 2642 FE0F ; fully-qualified # 🤦🏾♂️ E4.0 man facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2642 ; minimally-qualified # 🤦🏾♂ E4.0 man facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2642 FE0F ; fully-qualified # 🤦🏿♂️ E4.0 man facepalming: dark skin tone
+1F926 1F3FF 200D 2642 ; minimally-qualified # 🤦🏿♂ E4.0 man facepalming: dark skin tone
+1F926 200D 2640 FE0F ; fully-qualified # 🤦♀️ E4.0 woman facepalming
+1F926 200D 2640 ; minimally-qualified # 🤦♀ E4.0 woman facepalming
+1F926 1F3FB 200D 2640 FE0F ; fully-qualified # 🤦🏻♀️ E4.0 woman facepalming: light skin tone
+1F926 1F3FB 200D 2640 ; minimally-qualified # 🤦🏻♀ E4.0 woman facepalming: light skin tone
+1F926 1F3FC 200D 2640 FE0F ; fully-qualified # 🤦🏼♀️ E4.0 woman facepalming: medium-light skin tone
+1F926 1F3FC 200D 2640 ; minimally-qualified # 🤦🏼♀ E4.0 woman facepalming: medium-light skin tone
+1F926 1F3FD 200D 2640 FE0F ; fully-qualified # 🤦🏽♀️ E4.0 woman facepalming: medium skin tone
+1F926 1F3FD 200D 2640 ; minimally-qualified # 🤦🏽♀ E4.0 woman facepalming: medium skin tone
+1F926 1F3FE 200D 2640 FE0F ; fully-qualified # 🤦🏾♀️ E4.0 woman facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2640 ; minimally-qualified # 🤦🏾♀ E4.0 woman facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2640 FE0F ; fully-qualified # 🤦🏿♀️ E4.0 woman facepalming: dark skin tone
+1F926 1F3FF 200D 2640 ; minimally-qualified # 🤦🏿♀ E4.0 woman facepalming: dark skin tone
+1F937 ; fully-qualified # 🤷 E3.0 person shrugging
+1F937 1F3FB ; fully-qualified # 🤷🏻 E3.0 person shrugging: light skin tone
+1F937 1F3FC ; fully-qualified # 🤷🏼 E3.0 person shrugging: medium-light skin tone
+1F937 1F3FD ; fully-qualified # 🤷🏽 E3.0 person shrugging: medium skin tone
+1F937 1F3FE ; fully-qualified # 🤷🏾 E3.0 person shrugging: medium-dark skin tone
+1F937 1F3FF ; fully-qualified # 🤷🏿 E3.0 person shrugging: dark skin tone
+1F937 200D 2642 FE0F ; fully-qualified # 🤷♂️ E4.0 man shrugging
+1F937 200D 2642 ; minimally-qualified # 🤷♂ E4.0 man shrugging
+1F937 1F3FB 200D 2642 FE0F ; fully-qualified # 🤷🏻♂️ E4.0 man shrugging: light skin tone
+1F937 1F3FB 200D 2642 ; minimally-qualified # 🤷🏻♂ E4.0 man shrugging: light skin tone
+1F937 1F3FC 200D 2642 FE0F ; fully-qualified # 🤷🏼♂️ E4.0 man shrugging: medium-light skin tone
+1F937 1F3FC 200D 2642 ; minimally-qualified # 🤷🏼♂ E4.0 man shrugging: medium-light skin tone
+1F937 1F3FD 200D 2642 FE0F ; fully-qualified # 🤷🏽♂️ E4.0 man shrugging: medium skin tone
+1F937 1F3FD 200D 2642 ; minimally-qualified # 🤷🏽♂ E4.0 man shrugging: medium skin tone
+1F937 1F3FE 200D 2642 FE0F ; fully-qualified # 🤷🏾♂️ E4.0 man shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2642 ; minimally-qualified # 🤷🏾♂ E4.0 man shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2642 FE0F ; fully-qualified # 🤷🏿♂️ E4.0 man shrugging: dark skin tone
+1F937 1F3FF 200D 2642 ; minimally-qualified # 🤷🏿♂ E4.0 man shrugging: dark skin tone
+1F937 200D 2640 FE0F ; fully-qualified # 🤷♀️ E4.0 woman shrugging
+1F937 200D 2640 ; minimally-qualified # 🤷♀ E4.0 woman shrugging
+1F937 1F3FB 200D 2640 FE0F ; fully-qualified # 🤷🏻♀️ E4.0 woman shrugging: light skin tone
+1F937 1F3FB 200D 2640 ; minimally-qualified # 🤷🏻♀ E4.0 woman shrugging: light skin tone
+1F937 1F3FC 200D 2640 FE0F ; fully-qualified # 🤷🏼♀️ E4.0 woman shrugging: medium-light skin tone
+1F937 1F3FC 200D 2640 ; minimally-qualified # 🤷🏼♀ E4.0 woman shrugging: medium-light skin tone
+1F937 1F3FD 200D 2640 FE0F ; fully-qualified # 🤷🏽♀️ E4.0 woman shrugging: medium skin tone
+1F937 1F3FD 200D 2640 ; minimally-qualified # 🤷🏽♀ E4.0 woman shrugging: medium skin tone
+1F937 1F3FE 200D 2640 FE0F ; fully-qualified # 🤷🏾♀️ E4.0 woman shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2640 ; minimally-qualified # 🤷🏾♀ E4.0 woman shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2640 FE0F ; fully-qualified # 🤷🏿♀️ E4.0 woman shrugging: dark skin tone
+1F937 1F3FF 200D 2640 ; minimally-qualified # 🤷🏿♀ E4.0 woman shrugging: dark skin tone
# subgroup: person-role
-1F9D1 200D 2695 FE0F ; fully-qualified # 🧑⚕️ E12.1 health worker
-1F9D1 200D 2695 ; minimally-qualified # 🧑⚕ E12.1 health worker
-1F9D1 1F3FB 200D 2695 FE0F ; fully-qualified # 🧑🏻⚕️ E12.1 health worker: light skin tone
-1F9D1 1F3FB 200D 2695 ; minimally-qualified # 🧑🏻⚕ E12.1 health worker: light skin tone
-1F9D1 1F3FC 200D 2695 FE0F ; fully-qualified # 🧑🏼⚕️ E12.1 health worker: medium-light skin tone
-1F9D1 1F3FC 200D 2695 ; minimally-qualified # 🧑🏼⚕ E12.1 health worker: medium-light skin tone
-1F9D1 1F3FD 200D 2695 FE0F ; fully-qualified # 🧑🏽⚕️ E12.1 health worker: medium skin tone
-1F9D1 1F3FD 200D 2695 ; minimally-qualified # 🧑🏽⚕ E12.1 health worker: medium skin tone
-1F9D1 1F3FE 200D 2695 FE0F ; fully-qualified # 🧑🏾⚕️ E12.1 health worker: medium-dark skin tone
-1F9D1 1F3FE 200D 2695 ; minimally-qualified # 🧑🏾⚕ E12.1 health worker: medium-dark skin tone
-1F9D1 1F3FF 200D 2695 FE0F ; fully-qualified # 🧑🏿⚕️ E12.1 health worker: dark skin tone
-1F9D1 1F3FF 200D 2695 ; minimally-qualified # 🧑🏿⚕ E12.1 health worker: dark skin tone
-1F468 200D 2695 FE0F ; fully-qualified # 👨⚕️ E4.0 man health worker
-1F468 200D 2695 ; minimally-qualified # 👨⚕ E4.0 man health worker
-1F468 1F3FB 200D 2695 FE0F ; fully-qualified # 👨🏻⚕️ E4.0 man health worker: light skin tone
-1F468 1F3FB 200D 2695 ; minimally-qualified # 👨🏻⚕ E4.0 man health worker: light skin tone
-1F468 1F3FC 200D 2695 FE0F ; fully-qualified # 👨🏼⚕️ E4.0 man health worker: medium-light skin tone
-1F468 1F3FC 200D 2695 ; minimally-qualified # 👨🏼⚕ E4.0 man health worker: medium-light skin tone
-1F468 1F3FD 200D 2695 FE0F ; fully-qualified # 👨🏽⚕️ E4.0 man health worker: medium skin tone
-1F468 1F3FD 200D 2695 ; minimally-qualified # 👨🏽⚕ E4.0 man health worker: medium skin tone
-1F468 1F3FE 200D 2695 FE0F ; fully-qualified # 👨🏾⚕️ E4.0 man health worker: medium-dark skin tone
-1F468 1F3FE 200D 2695 ; minimally-qualified # 👨🏾⚕ E4.0 man health worker: medium-dark skin tone
-1F468 1F3FF 200D 2695 FE0F ; fully-qualified # 👨🏿⚕️ E4.0 man health worker: dark skin tone
-1F468 1F3FF 200D 2695 ; minimally-qualified # 👨🏿⚕ E4.0 man health worker: dark skin tone
-1F469 200D 2695 FE0F ; fully-qualified # 👩⚕️ E4.0 woman health worker
-1F469 200D 2695 ; minimally-qualified # 👩⚕ E4.0 woman health worker
-1F469 1F3FB 200D 2695 FE0F ; fully-qualified # 👩🏻⚕️ E4.0 woman health worker: light skin tone
-1F469 1F3FB 200D 2695 ; minimally-qualified # 👩🏻⚕ E4.0 woman health worker: light skin tone
-1F469 1F3FC 200D 2695 FE0F ; fully-qualified # 👩🏼⚕️ E4.0 woman health worker: medium-light skin tone
-1F469 1F3FC 200D 2695 ; minimally-qualified # 👩🏼⚕ E4.0 woman health worker: medium-light skin tone
-1F469 1F3FD 200D 2695 FE0F ; fully-qualified # 👩🏽⚕️ E4.0 woman health worker: medium skin tone
-1F469 1F3FD 200D 2695 ; minimally-qualified # 👩🏽⚕ E4.0 woman health worker: medium skin tone
-1F469 1F3FE 200D 2695 FE0F ; fully-qualified # 👩🏾⚕️ E4.0 woman health worker: medium-dark skin tone
-1F469 1F3FE 200D 2695 ; minimally-qualified # 👩🏾⚕ E4.0 woman health worker: medium-dark skin tone
-1F469 1F3FF 200D 2695 FE0F ; fully-qualified # 👩🏿⚕️ E4.0 woman health worker: dark skin tone
-1F469 1F3FF 200D 2695 ; minimally-qualified # 👩🏿⚕ E4.0 woman health worker: dark skin tone
-1F9D1 200D 1F393 ; fully-qualified # 🧑🎓 E12.1 student
-1F9D1 1F3FB 200D 1F393 ; fully-qualified # 🧑🏻🎓 E12.1 student: light skin tone
-1F9D1 1F3FC 200D 1F393 ; fully-qualified # 🧑🏼🎓 E12.1 student: medium-light skin tone
-1F9D1 1F3FD 200D 1F393 ; fully-qualified # 🧑🏽🎓 E12.1 student: medium skin tone
-1F9D1 1F3FE 200D 1F393 ; fully-qualified # 🧑🏾🎓 E12.1 student: medium-dark skin tone
-1F9D1 1F3FF 200D 1F393 ; fully-qualified # 🧑🏿🎓 E12.1 student: dark skin tone
-1F468 200D 1F393 ; fully-qualified # 👨🎓 E4.0 man student
-1F468 1F3FB 200D 1F393 ; fully-qualified # 👨🏻🎓 E4.0 man student: light skin tone
-1F468 1F3FC 200D 1F393 ; fully-qualified # 👨🏼🎓 E4.0 man student: medium-light skin tone
-1F468 1F3FD 200D 1F393 ; fully-qualified # 👨🏽🎓 E4.0 man student: medium skin tone
-1F468 1F3FE 200D 1F393 ; fully-qualified # 👨🏾🎓 E4.0 man student: medium-dark skin tone
-1F468 1F3FF 200D 1F393 ; fully-qualified # 👨🏿🎓 E4.0 man student: dark skin tone
-1F469 200D 1F393 ; fully-qualified # 👩🎓 E4.0 woman student
-1F469 1F3FB 200D 1F393 ; fully-qualified # 👩🏻🎓 E4.0 woman student: light skin tone
-1F469 1F3FC 200D 1F393 ; fully-qualified # 👩🏼🎓 E4.0 woman student: medium-light skin tone
-1F469 1F3FD 200D 1F393 ; fully-qualified # 👩🏽🎓 E4.0 woman student: medium skin tone
-1F469 1F3FE 200D 1F393 ; fully-qualified # 👩🏾🎓 E4.0 woman student: medium-dark skin tone
-1F469 1F3FF 200D 1F393 ; fully-qualified # 👩🏿🎓 E4.0 woman student: dark skin tone
-1F9D1 200D 1F3EB ; fully-qualified # 🧑🏫 E12.1 teacher
-1F9D1 1F3FB 200D 1F3EB ; fully-qualified # 🧑🏻🏫 E12.1 teacher: light skin tone
-1F9D1 1F3FC 200D 1F3EB ; fully-qualified # 🧑🏼🏫 E12.1 teacher: medium-light skin tone
-1F9D1 1F3FD 200D 1F3EB ; fully-qualified # 🧑🏽🏫 E12.1 teacher: medium skin tone
-1F9D1 1F3FE 200D 1F3EB ; fully-qualified # 🧑🏾🏫 E12.1 teacher: medium-dark skin tone
-1F9D1 1F3FF 200D 1F3EB ; fully-qualified # 🧑🏿🏫 E12.1 teacher: dark skin tone
-1F468 200D 1F3EB ; fully-qualified # 👨🏫 E4.0 man teacher
-1F468 1F3FB 200D 1F3EB ; fully-qualified # 👨🏻🏫 E4.0 man teacher: light skin tone
-1F468 1F3FC 200D 1F3EB ; fully-qualified # 👨🏼🏫 E4.0 man teacher: medium-light skin tone
-1F468 1F3FD 200D 1F3EB ; fully-qualified # 👨🏽🏫 E4.0 man teacher: medium skin tone
-1F468 1F3FE 200D 1F3EB ; fully-qualified # 👨🏾🏫 E4.0 man teacher: medium-dark skin tone
-1F468 1F3FF 200D 1F3EB ; fully-qualified # 👨🏿🏫 E4.0 man teacher: dark skin tone
-1F469 200D 1F3EB ; fully-qualified # 👩🏫 E4.0 woman teacher
-1F469 1F3FB 200D 1F3EB ; fully-qualified # 👩🏻🏫 E4.0 woman teacher: light skin tone
-1F469 1F3FC 200D 1F3EB ; fully-qualified # 👩🏼🏫 E4.0 woman teacher: medium-light skin tone
-1F469 1F3FD 200D 1F3EB ; fully-qualified # 👩🏽🏫 E4.0 woman teacher: medium skin tone
-1F469 1F3FE 200D 1F3EB ; fully-qualified # 👩🏾🏫 E4.0 woman teacher: medium-dark skin tone
-1F469 1F3FF 200D 1F3EB ; fully-qualified # 👩🏿🏫 E4.0 woman teacher: dark skin tone
-1F9D1 200D 2696 FE0F ; fully-qualified # 🧑⚖️ E12.1 judge
-1F9D1 200D 2696 ; minimally-qualified # 🧑⚖ E12.1 judge
-1F9D1 1F3FB 200D 2696 FE0F ; fully-qualified # 🧑🏻⚖️ E12.1 judge: light skin tone
-1F9D1 1F3FB 200D 2696 ; minimally-qualified # 🧑🏻⚖ E12.1 judge: light skin tone
-1F9D1 1F3FC 200D 2696 FE0F ; fully-qualified # 🧑🏼⚖️ E12.1 judge: medium-light skin tone
-1F9D1 1F3FC 200D 2696 ; minimally-qualified # 🧑🏼⚖ E12.1 judge: medium-light skin tone
-1F9D1 1F3FD 200D 2696 FE0F ; fully-qualified # 🧑🏽⚖️ E12.1 judge: medium skin tone
-1F9D1 1F3FD 200D 2696 ; minimally-qualified # 🧑🏽⚖ E12.1 judge: medium skin tone
-1F9D1 1F3FE 200D 2696 FE0F ; fully-qualified # 🧑🏾⚖️ E12.1 judge: medium-dark skin tone
-1F9D1 1F3FE 200D 2696 ; minimally-qualified # 🧑🏾⚖ E12.1 judge: medium-dark skin tone
-1F9D1 1F3FF 200D 2696 FE0F ; fully-qualified # 🧑🏿⚖️ E12.1 judge: dark skin tone
-1F9D1 1F3FF 200D 2696 ; minimally-qualified # 🧑🏿⚖ E12.1 judge: dark skin tone
-1F468 200D 2696 FE0F ; fully-qualified # 👨⚖️ E4.0 man judge
-1F468 200D 2696 ; minimally-qualified # 👨⚖ E4.0 man judge
-1F468 1F3FB 200D 2696 FE0F ; fully-qualified # 👨🏻⚖️ E4.0 man judge: light skin tone
-1F468 1F3FB 200D 2696 ; minimally-qualified # 👨🏻⚖ E4.0 man judge: light skin tone
-1F468 1F3FC 200D 2696 FE0F ; fully-qualified # 👨🏼⚖️ E4.0 man judge: medium-light skin tone
-1F468 1F3FC 200D 2696 ; minimally-qualified # 👨🏼⚖ E4.0 man judge: medium-light skin tone
-1F468 1F3FD 200D 2696 FE0F ; fully-qualified # 👨🏽⚖️ E4.0 man judge: medium skin tone
-1F468 1F3FD 200D 2696 ; minimally-qualified # 👨🏽⚖ E4.0 man judge: medium skin tone
-1F468 1F3FE 200D 2696 FE0F ; fully-qualified # 👨🏾⚖️ E4.0 man judge: medium-dark skin tone
-1F468 1F3FE 200D 2696 ; minimally-qualified # 👨🏾⚖ E4.0 man judge: medium-dark skin tone
-1F468 1F3FF 200D 2696 FE0F ; fully-qualified # 👨🏿⚖️ E4.0 man judge: dark skin tone
-1F468 1F3FF 200D 2696 ; minimally-qualified # 👨🏿⚖ E4.0 man judge: dark skin tone
-1F469 200D 2696 FE0F ; fully-qualified # 👩⚖️ E4.0 woman judge
-1F469 200D 2696 ; minimally-qualified # 👩⚖ E4.0 woman judge
-1F469 1F3FB 200D 2696 FE0F ; fully-qualified # 👩🏻⚖️ E4.0 woman judge: light skin tone
-1F469 1F3FB 200D 2696 ; minimally-qualified # 👩🏻⚖ E4.0 woman judge: light skin tone
-1F469 1F3FC 200D 2696 FE0F ; fully-qualified # 👩🏼⚖️ E4.0 woman judge: medium-light skin tone
-1F469 1F3FC 200D 2696 ; minimally-qualified # 👩🏼⚖ E4.0 woman judge: medium-light skin tone
-1F469 1F3FD 200D 2696 FE0F ; fully-qualified # 👩🏽⚖️ E4.0 woman judge: medium skin tone
-1F469 1F3FD 200D 2696 ; minimally-qualified # 👩🏽⚖ E4.0 woman judge: medium skin tone
-1F469 1F3FE 200D 2696 FE0F ; fully-qualified # 👩🏾⚖️ E4.0 woman judge: medium-dark skin tone
-1F469 1F3FE 200D 2696 ; minimally-qualified # 👩🏾⚖ E4.0 woman judge: medium-dark skin tone
-1F469 1F3FF 200D 2696 FE0F ; fully-qualified # 👩🏿⚖️ E4.0 woman judge: dark skin tone
-1F469 1F3FF 200D 2696 ; minimally-qualified # 👩🏿⚖ E4.0 woman judge: dark skin tone
-1F9D1 200D 1F33E ; fully-qualified # 🧑🌾 E12.1 farmer
-1F9D1 1F3FB 200D 1F33E ; fully-qualified # 🧑🏻🌾 E12.1 farmer: light skin tone
-1F9D1 1F3FC 200D 1F33E ; fully-qualified # 🧑🏼🌾 E12.1 farmer: medium-light skin tone
-1F9D1 1F3FD 200D 1F33E ; fully-qualified # 🧑🏽🌾 E12.1 farmer: medium skin tone
-1F9D1 1F3FE 200D 1F33E ; fully-qualified # 🧑🏾🌾 E12.1 farmer: medium-dark skin tone
-1F9D1 1F3FF 200D 1F33E ; fully-qualified # 🧑🏿🌾 E12.1 farmer: dark skin tone
-1F468 200D 1F33E ; fully-qualified # 👨🌾 E4.0 man farmer
-1F468 1F3FB 200D 1F33E ; fully-qualified # 👨🏻🌾 E4.0 man farmer: light skin tone
-1F468 1F3FC 200D 1F33E ; fully-qualified # 👨🏼🌾 E4.0 man farmer: medium-light skin tone
-1F468 1F3FD 200D 1F33E ; fully-qualified # 👨🏽🌾 E4.0 man farmer: medium skin tone
-1F468 1F3FE 200D 1F33E ; fully-qualified # 👨🏾🌾 E4.0 man farmer: medium-dark skin tone
-1F468 1F3FF 200D 1F33E ; fully-qualified # 👨🏿🌾 E4.0 man farmer: dark skin tone
-1F469 200D 1F33E ; fully-qualified # 👩🌾 E4.0 woman farmer
-1F469 1F3FB 200D 1F33E ; fully-qualified # 👩🏻🌾 E4.0 woman farmer: light skin tone
-1F469 1F3FC 200D 1F33E ; fully-qualified # 👩🏼🌾 E4.0 woman farmer: medium-light skin tone
-1F469 1F3FD 200D 1F33E ; fully-qualified # 👩🏽🌾 E4.0 woman farmer: medium skin tone
-1F469 1F3FE 200D 1F33E ; fully-qualified # 👩🏾🌾 E4.0 woman farmer: medium-dark skin tone
-1F469 1F3FF 200D 1F33E ; fully-qualified # 👩🏿🌾 E4.0 woman farmer: dark skin tone
-1F9D1 200D 1F373 ; fully-qualified # 🧑🍳 E12.1 cook
-1F9D1 1F3FB 200D 1F373 ; fully-qualified # 🧑🏻🍳 E12.1 cook: light skin tone
-1F9D1 1F3FC 200D 1F373 ; fully-qualified # 🧑🏼🍳 E12.1 cook: medium-light skin tone
-1F9D1 1F3FD 200D 1F373 ; fully-qualified # 🧑🏽🍳 E12.1 cook: medium skin tone
-1F9D1 1F3FE 200D 1F373 ; fully-qualified # 🧑🏾🍳 E12.1 cook: medium-dark skin tone
-1F9D1 1F3FF 200D 1F373 ; fully-qualified # 🧑🏿🍳 E12.1 cook: dark skin tone
-1F468 200D 1F373 ; fully-qualified # 👨🍳 E4.0 man cook
-1F468 1F3FB 200D 1F373 ; fully-qualified # 👨🏻🍳 E4.0 man cook: light skin tone
-1F468 1F3FC 200D 1F373 ; fully-qualified # 👨🏼🍳 E4.0 man cook: medium-light skin tone
-1F468 1F3FD 200D 1F373 ; fully-qualified # 👨🏽🍳 E4.0 man cook: medium skin tone
-1F468 1F3FE 200D 1F373 ; fully-qualified # 👨🏾🍳 E4.0 man cook: medium-dark skin tone
-1F468 1F3FF 200D 1F373 ; fully-qualified # 👨🏿🍳 E4.0 man cook: dark skin tone
-1F469 200D 1F373 ; fully-qualified # 👩🍳 E4.0 woman cook
-1F469 1F3FB 200D 1F373 ; fully-qualified # 👩🏻🍳 E4.0 woman cook: light skin tone
-1F469 1F3FC 200D 1F373 ; fully-qualified # 👩🏼🍳 E4.0 woman cook: medium-light skin tone
-1F469 1F3FD 200D 1F373 ; fully-qualified # 👩🏽🍳 E4.0 woman cook: medium skin tone
-1F469 1F3FE 200D 1F373 ; fully-qualified # 👩🏾🍳 E4.0 woman cook: medium-dark skin tone
-1F469 1F3FF 200D 1F373 ; fully-qualified # 👩🏿🍳 E4.0 woman cook: dark skin tone
-1F9D1 200D 1F527 ; fully-qualified # 🧑🔧 E12.1 mechanic
-1F9D1 1F3FB 200D 1F527 ; fully-qualified # 🧑🏻🔧 E12.1 mechanic: light skin tone
-1F9D1 1F3FC 200D 1F527 ; fully-qualified # 🧑🏼🔧 E12.1 mechanic: medium-light skin tone
-1F9D1 1F3FD 200D 1F527 ; fully-qualified # 🧑🏽🔧 E12.1 mechanic: medium skin tone
-1F9D1 1F3FE 200D 1F527 ; fully-qualified # 🧑🏾🔧 E12.1 mechanic: medium-dark skin tone
-1F9D1 1F3FF 200D 1F527 ; fully-qualified # 🧑🏿🔧 E12.1 mechanic: dark skin tone
-1F468 200D 1F527 ; fully-qualified # 👨🔧 E4.0 man mechanic
-1F468 1F3FB 200D 1F527 ; fully-qualified # 👨🏻🔧 E4.0 man mechanic: light skin tone
-1F468 1F3FC 200D 1F527 ; fully-qualified # 👨🏼🔧 E4.0 man mechanic: medium-light skin tone
-1F468 1F3FD 200D 1F527 ; fully-qualified # 👨🏽🔧 E4.0 man mechanic: medium skin tone
-1F468 1F3FE 200D 1F527 ; fully-qualified # 👨🏾🔧 E4.0 man mechanic: medium-dark skin tone
-1F468 1F3FF 200D 1F527 ; fully-qualified # 👨🏿🔧 E4.0 man mechanic: dark skin tone
-1F469 200D 1F527 ; fully-qualified # 👩🔧 E4.0 woman mechanic
-1F469 1F3FB 200D 1F527 ; fully-qualified # 👩🏻🔧 E4.0 woman mechanic: light skin tone
-1F469 1F3FC 200D 1F527 ; fully-qualified # 👩🏼🔧 E4.0 woman mechanic: medium-light skin tone
-1F469 1F3FD 200D 1F527 ; fully-qualified # 👩🏽🔧 E4.0 woman mechanic: medium skin tone
-1F469 1F3FE 200D 1F527 ; fully-qualified # 👩🏾🔧 E4.0 woman mechanic: medium-dark skin tone
-1F469 1F3FF 200D 1F527 ; fully-qualified # 👩🏿🔧 E4.0 woman mechanic: dark skin tone
-1F9D1 200D 1F3ED ; fully-qualified # 🧑🏭 E12.1 factory worker
-1F9D1 1F3FB 200D 1F3ED ; fully-qualified # 🧑🏻🏭 E12.1 factory worker: light skin tone
-1F9D1 1F3FC 200D 1F3ED ; fully-qualified # 🧑🏼🏭 E12.1 factory worker: medium-light skin tone
-1F9D1 1F3FD 200D 1F3ED ; fully-qualified # 🧑🏽🏭 E12.1 factory worker: medium skin tone
-1F9D1 1F3FE 200D 1F3ED ; fully-qualified # 🧑🏾🏭 E12.1 factory worker: medium-dark skin tone
-1F9D1 1F3FF 200D 1F3ED ; fully-qualified # 🧑🏿🏭 E12.1 factory worker: dark skin tone
-1F468 200D 1F3ED ; fully-qualified # 👨🏭 E4.0 man factory worker
-1F468 1F3FB 200D 1F3ED ; fully-qualified # 👨🏻🏭 E4.0 man factory worker: light skin tone
-1F468 1F3FC 200D 1F3ED ; fully-qualified # 👨🏼🏭 E4.0 man factory worker: medium-light skin tone
-1F468 1F3FD 200D 1F3ED ; fully-qualified # 👨🏽🏭 E4.0 man factory worker: medium skin tone
-1F468 1F3FE 200D 1F3ED ; fully-qualified # 👨🏾🏭 E4.0 man factory worker: medium-dark skin tone
-1F468 1F3FF 200D 1F3ED ; fully-qualified # 👨🏿🏭 E4.0 man factory worker: dark skin tone
-1F469 200D 1F3ED ; fully-qualified # 👩🏭 E4.0 woman factory worker
-1F469 1F3FB 200D 1F3ED ; fully-qualified # 👩🏻🏭 E4.0 woman factory worker: light skin tone
-1F469 1F3FC 200D 1F3ED ; fully-qualified # 👩🏼🏭 E4.0 woman factory worker: medium-light skin tone
-1F469 1F3FD 200D 1F3ED ; fully-qualified # 👩🏽🏭 E4.0 woman factory worker: medium skin tone
-1F469 1F3FE 200D 1F3ED ; fully-qualified # 👩🏾🏭 E4.0 woman factory worker: medium-dark skin tone
-1F469 1F3FF 200D 1F3ED ; fully-qualified # 👩🏿🏭 E4.0 woman factory worker: dark skin tone
-1F9D1 200D 1F4BC ; fully-qualified # 🧑💼 E12.1 office worker
-1F9D1 1F3FB 200D 1F4BC ; fully-qualified # 🧑🏻💼 E12.1 office worker: light skin tone
-1F9D1 1F3FC 200D 1F4BC ; fully-qualified # 🧑🏼💼 E12.1 office worker: medium-light skin tone
-1F9D1 1F3FD 200D 1F4BC ; fully-qualified # 🧑🏽💼 E12.1 office worker: medium skin tone
-1F9D1 1F3FE 200D 1F4BC ; fully-qualified # 🧑🏾💼 E12.1 office worker: medium-dark skin tone
-1F9D1 1F3FF 200D 1F4BC ; fully-qualified # 🧑🏿💼 E12.1 office worker: dark skin tone
-1F468 200D 1F4BC ; fully-qualified # 👨💼 E4.0 man office worker
-1F468 1F3FB 200D 1F4BC ; fully-qualified # 👨🏻💼 E4.0 man office worker: light skin tone
-1F468 1F3FC 200D 1F4BC ; fully-qualified # 👨🏼💼 E4.0 man office worker: medium-light skin tone
-1F468 1F3FD 200D 1F4BC ; fully-qualified # 👨🏽💼 E4.0 man office worker: medium skin tone
-1F468 1F3FE 200D 1F4BC ; fully-qualified # 👨🏾💼 E4.0 man office worker: medium-dark skin tone
-1F468 1F3FF 200D 1F4BC ; fully-qualified # 👨🏿💼 E4.0 man office worker: dark skin tone
-1F469 200D 1F4BC ; fully-qualified # 👩💼 E4.0 woman office worker
-1F469 1F3FB 200D 1F4BC ; fully-qualified # 👩🏻💼 E4.0 woman office worker: light skin tone
-1F469 1F3FC 200D 1F4BC ; fully-qualified # 👩🏼💼 E4.0 woman office worker: medium-light skin tone
-1F469 1F3FD 200D 1F4BC ; fully-qualified # 👩🏽💼 E4.0 woman office worker: medium skin tone
-1F469 1F3FE 200D 1F4BC ; fully-qualified # 👩🏾💼 E4.0 woman office worker: medium-dark skin tone
-1F469 1F3FF 200D 1F4BC ; fully-qualified # 👩🏿💼 E4.0 woman office worker: dark skin tone
-1F9D1 200D 1F52C ; fully-qualified # 🧑🔬 E12.1 scientist
-1F9D1 1F3FB 200D 1F52C ; fully-qualified # 🧑🏻🔬 E12.1 scientist: light skin tone
-1F9D1 1F3FC 200D 1F52C ; fully-qualified # 🧑🏼🔬 E12.1 scientist: medium-light skin tone
-1F9D1 1F3FD 200D 1F52C ; fully-qualified # 🧑🏽🔬 E12.1 scientist: medium skin tone
-1F9D1 1F3FE 200D 1F52C ; fully-qualified # 🧑🏾🔬 E12.1 scientist: medium-dark skin tone
-1F9D1 1F3FF 200D 1F52C ; fully-qualified # 🧑🏿🔬 E12.1 scientist: dark skin tone
-1F468 200D 1F52C ; fully-qualified # 👨🔬 E4.0 man scientist
-1F468 1F3FB 200D 1F52C ; fully-qualified # 👨🏻🔬 E4.0 man scientist: light skin tone
-1F468 1F3FC 200D 1F52C ; fully-qualified # 👨🏼🔬 E4.0 man scientist: medium-light skin tone
-1F468 1F3FD 200D 1F52C ; fully-qualified # 👨🏽🔬 E4.0 man scientist: medium skin tone
-1F468 1F3FE 200D 1F52C ; fully-qualified # 👨🏾🔬 E4.0 man scientist: medium-dark skin tone
-1F468 1F3FF 200D 1F52C ; fully-qualified # 👨🏿🔬 E4.0 man scientist: dark skin tone
-1F469 200D 1F52C ; fully-qualified # 👩🔬 E4.0 woman scientist
-1F469 1F3FB 200D 1F52C ; fully-qualified # 👩🏻🔬 E4.0 woman scientist: light skin tone
-1F469 1F3FC 200D 1F52C ; fully-qualified # 👩🏼🔬 E4.0 woman scientist: medium-light skin tone
-1F469 1F3FD 200D 1F52C ; fully-qualified # 👩🏽🔬 E4.0 woman scientist: medium skin tone
-1F469 1F3FE 200D 1F52C ; fully-qualified # 👩🏾🔬 E4.0 woman scientist: medium-dark skin tone
-1F469 1F3FF 200D 1F52C ; fully-qualified # 👩🏿🔬 E4.0 woman scientist: dark skin tone
-1F9D1 200D 1F4BB ; fully-qualified # 🧑💻 E12.1 technologist
-1F9D1 1F3FB 200D 1F4BB ; fully-qualified # 🧑🏻💻 E12.1 technologist: light skin tone
-1F9D1 1F3FC 200D 1F4BB ; fully-qualified # 🧑🏼💻 E12.1 technologist: medium-light skin tone
-1F9D1 1F3FD 200D 1F4BB ; fully-qualified # 🧑🏽💻 E12.1 technologist: medium skin tone
-1F9D1 1F3FE 200D 1F4BB ; fully-qualified # 🧑🏾💻 E12.1 technologist: medium-dark skin tone
-1F9D1 1F3FF 200D 1F4BB ; fully-qualified # 🧑🏿💻 E12.1 technologist: dark skin tone
-1F468 200D 1F4BB ; fully-qualified # 👨💻 E4.0 man technologist
-1F468 1F3FB 200D 1F4BB ; fully-qualified # 👨🏻💻 E4.0 man technologist: light skin tone
-1F468 1F3FC 200D 1F4BB ; fully-qualified # 👨🏼💻 E4.0 man technologist: medium-light skin tone
-1F468 1F3FD 200D 1F4BB ; fully-qualified # 👨🏽💻 E4.0 man technologist: medium skin tone
-1F468 1F3FE 200D 1F4BB ; fully-qualified # 👨🏾💻 E4.0 man technologist: medium-dark skin tone
-1F468 1F3FF 200D 1F4BB ; fully-qualified # 👨🏿💻 E4.0 man technologist: dark skin tone
-1F469 200D 1F4BB ; fully-qualified # 👩💻 E4.0 woman technologist
-1F469 1F3FB 200D 1F4BB ; fully-qualified # 👩🏻💻 E4.0 woman technologist: light skin tone
-1F469 1F3FC 200D 1F4BB ; fully-qualified # 👩🏼💻 E4.0 woman technologist: medium-light skin tone
-1F469 1F3FD 200D 1F4BB ; fully-qualified # 👩🏽💻 E4.0 woman technologist: medium skin tone
-1F469 1F3FE 200D 1F4BB ; fully-qualified # 👩🏾💻 E4.0 woman technologist: medium-dark skin tone
-1F469 1F3FF 200D 1F4BB ; fully-qualified # 👩🏿💻 E4.0 woman technologist: dark skin tone
-1F9D1 200D 1F3A4 ; fully-qualified # 🧑🎤 E12.1 singer
-1F9D1 1F3FB 200D 1F3A4 ; fully-qualified # 🧑🏻🎤 E12.1 singer: light skin tone
-1F9D1 1F3FC 200D 1F3A4 ; fully-qualified # 🧑🏼🎤 E12.1 singer: medium-light skin tone
-1F9D1 1F3FD 200D 1F3A4 ; fully-qualified # 🧑🏽🎤 E12.1 singer: medium skin tone
-1F9D1 1F3FE 200D 1F3A4 ; fully-qualified # 🧑🏾🎤 E12.1 singer: medium-dark skin tone
-1F9D1 1F3FF 200D 1F3A4 ; fully-qualified # 🧑🏿🎤 E12.1 singer: dark skin tone
-1F468 200D 1F3A4 ; fully-qualified # 👨🎤 E4.0 man singer
-1F468 1F3FB 200D 1F3A4 ; fully-qualified # 👨🏻🎤 E4.0 man singer: light skin tone
-1F468 1F3FC 200D 1F3A4 ; fully-qualified # 👨🏼🎤 E4.0 man singer: medium-light skin tone
-1F468 1F3FD 200D 1F3A4 ; fully-qualified # 👨🏽🎤 E4.0 man singer: medium skin tone
-1F468 1F3FE 200D 1F3A4 ; fully-qualified # 👨🏾🎤 E4.0 man singer: medium-dark skin tone
-1F468 1F3FF 200D 1F3A4 ; fully-qualified # 👨🏿🎤 E4.0 man singer: dark skin tone
-1F469 200D 1F3A4 ; fully-qualified # 👩🎤 E4.0 woman singer
-1F469 1F3FB 200D 1F3A4 ; fully-qualified # 👩🏻🎤 E4.0 woman singer: light skin tone
-1F469 1F3FC 200D 1F3A4 ; fully-qualified # 👩🏼🎤 E4.0 woman singer: medium-light skin tone
-1F469 1F3FD 200D 1F3A4 ; fully-qualified # 👩🏽🎤 E4.0 woman singer: medium skin tone
-1F469 1F3FE 200D 1F3A4 ; fully-qualified # 👩🏾🎤 E4.0 woman singer: medium-dark skin tone
-1F469 1F3FF 200D 1F3A4 ; fully-qualified # 👩🏿🎤 E4.0 woman singer: dark skin tone
-1F9D1 200D 1F3A8 ; fully-qualified # 🧑🎨 E12.1 artist
-1F9D1 1F3FB 200D 1F3A8 ; fully-qualified # 🧑🏻🎨 E12.1 artist: light skin tone
-1F9D1 1F3FC 200D 1F3A8 ; fully-qualified # 🧑🏼🎨 E12.1 artist: medium-light skin tone
-1F9D1 1F3FD 200D 1F3A8 ; fully-qualified # 🧑🏽🎨 E12.1 artist: medium skin tone
-1F9D1 1F3FE 200D 1F3A8 ; fully-qualified # 🧑🏾🎨 E12.1 artist: medium-dark skin tone
-1F9D1 1F3FF 200D 1F3A8 ; fully-qualified # 🧑🏿🎨 E12.1 artist: dark skin tone
-1F468 200D 1F3A8 ; fully-qualified # 👨🎨 E4.0 man artist
-1F468 1F3FB 200D 1F3A8 ; fully-qualified # 👨🏻🎨 E4.0 man artist: light skin tone
-1F468 1F3FC 200D 1F3A8 ; fully-qualified # 👨🏼🎨 E4.0 man artist: medium-light skin tone
-1F468 1F3FD 200D 1F3A8 ; fully-qualified # 👨🏽🎨 E4.0 man artist: medium skin tone
-1F468 1F3FE 200D 1F3A8 ; fully-qualified # 👨🏾🎨 E4.0 man artist: medium-dark skin tone
-1F468 1F3FF 200D 1F3A8 ; fully-qualified # 👨🏿🎨 E4.0 man artist: dark skin tone
-1F469 200D 1F3A8 ; fully-qualified # 👩🎨 E4.0 woman artist
-1F469 1F3FB 200D 1F3A8 ; fully-qualified # 👩🏻🎨 E4.0 woman artist: light skin tone
-1F469 1F3FC 200D 1F3A8 ; fully-qualified # 👩🏼🎨 E4.0 woman artist: medium-light skin tone
-1F469 1F3FD 200D 1F3A8 ; fully-qualified # 👩🏽🎨 E4.0 woman artist: medium skin tone
-1F469 1F3FE 200D 1F3A8 ; fully-qualified # 👩🏾🎨 E4.0 woman artist: medium-dark skin tone
-1F469 1F3FF 200D 1F3A8 ; fully-qualified # 👩🏿🎨 E4.0 woman artist: dark skin tone
-1F9D1 200D 2708 FE0F ; fully-qualified # 🧑✈️ E12.1 pilot
-1F9D1 200D 2708 ; minimally-qualified # 🧑✈ E12.1 pilot
-1F9D1 1F3FB 200D 2708 FE0F ; fully-qualified # 🧑🏻✈️ E12.1 pilot: light skin tone
-1F9D1 1F3FB 200D 2708 ; minimally-qualified # 🧑🏻✈ E12.1 pilot: light skin tone
-1F9D1 1F3FC 200D 2708 FE0F ; fully-qualified # 🧑🏼✈️ E12.1 pilot: medium-light skin tone
-1F9D1 1F3FC 200D 2708 ; minimally-qualified # 🧑🏼✈ E12.1 pilot: medium-light skin tone
-1F9D1 1F3FD 200D 2708 FE0F ; fully-qualified # 🧑🏽✈️ E12.1 pilot: medium skin tone
-1F9D1 1F3FD 200D 2708 ; minimally-qualified # 🧑🏽✈ E12.1 pilot: medium skin tone
-1F9D1 1F3FE 200D 2708 FE0F ; fully-qualified # 🧑🏾✈️ E12.1 pilot: medium-dark skin tone
-1F9D1 1F3FE 200D 2708 ; minimally-qualified # 🧑🏾✈ E12.1 pilot: medium-dark skin tone
-1F9D1 1F3FF 200D 2708 FE0F ; fully-qualified # 🧑🏿✈️ E12.1 pilot: dark skin tone
-1F9D1 1F3FF 200D 2708 ; minimally-qualified # 🧑🏿✈ E12.1 pilot: dark skin tone
-1F468 200D 2708 FE0F ; fully-qualified # 👨✈️ E4.0 man pilot
-1F468 200D 2708 ; minimally-qualified # 👨✈ E4.0 man pilot
-1F468 1F3FB 200D 2708 FE0F ; fully-qualified # 👨🏻✈️ E4.0 man pilot: light skin tone
-1F468 1F3FB 200D 2708 ; minimally-qualified # 👨🏻✈ E4.0 man pilot: light skin tone
-1F468 1F3FC 200D 2708 FE0F ; fully-qualified # 👨🏼✈️ E4.0 man pilot: medium-light skin tone
-1F468 1F3FC 200D 2708 ; minimally-qualified # 👨🏼✈ E4.0 man pilot: medium-light skin tone
-1F468 1F3FD 200D 2708 FE0F ; fully-qualified # 👨🏽✈️ E4.0 man pilot: medium skin tone
-1F468 1F3FD 200D 2708 ; minimally-qualified # 👨🏽✈ E4.0 man pilot: medium skin tone
-1F468 1F3FE 200D 2708 FE0F ; fully-qualified # 👨🏾✈️ E4.0 man pilot: medium-dark skin tone
-1F468 1F3FE 200D 2708 ; minimally-qualified # 👨🏾✈ E4.0 man pilot: medium-dark skin tone
-1F468 1F3FF 200D 2708 FE0F ; fully-qualified # 👨🏿✈️ E4.0 man pilot: dark skin tone
-1F468 1F3FF 200D 2708 ; minimally-qualified # 👨🏿✈ E4.0 man pilot: dark skin tone
-1F469 200D 2708 FE0F ; fully-qualified # 👩✈️ E4.0 woman pilot
-1F469 200D 2708 ; minimally-qualified # 👩✈ E4.0 woman pilot
-1F469 1F3FB 200D 2708 FE0F ; fully-qualified # 👩🏻✈️ E4.0 woman pilot: light skin tone
-1F469 1F3FB 200D 2708 ; minimally-qualified # 👩🏻✈ E4.0 woman pilot: light skin tone
-1F469 1F3FC 200D 2708 FE0F ; fully-qualified # 👩🏼✈️ E4.0 woman pilot: medium-light skin tone
-1F469 1F3FC 200D 2708 ; minimally-qualified # 👩🏼✈ E4.0 woman pilot: medium-light skin tone
-1F469 1F3FD 200D 2708 FE0F ; fully-qualified # 👩🏽✈️ E4.0 woman pilot: medium skin tone
-1F469 1F3FD 200D 2708 ; minimally-qualified # 👩🏽✈ E4.0 woman pilot: medium skin tone
-1F469 1F3FE 200D 2708 FE0F ; fully-qualified # 👩🏾✈️ E4.0 woman pilot: medium-dark skin tone
-1F469 1F3FE 200D 2708 ; minimally-qualified # 👩🏾✈ E4.0 woman pilot: medium-dark skin tone
-1F469 1F3FF 200D 2708 FE0F ; fully-qualified # 👩🏿✈️ E4.0 woman pilot: dark skin tone
-1F469 1F3FF 200D 2708 ; minimally-qualified # 👩🏿✈ E4.0 woman pilot: dark skin tone
-1F9D1 200D 1F680 ; fully-qualified # 🧑🚀 E12.1 astronaut
-1F9D1 1F3FB 200D 1F680 ; fully-qualified # 🧑🏻🚀 E12.1 astronaut: light skin tone
-1F9D1 1F3FC 200D 1F680 ; fully-qualified # 🧑🏼🚀 E12.1 astronaut: medium-light skin tone
-1F9D1 1F3FD 200D 1F680 ; fully-qualified # 🧑🏽🚀 E12.1 astronaut: medium skin tone
-1F9D1 1F3FE 200D 1F680 ; fully-qualified # 🧑🏾🚀 E12.1 astronaut: medium-dark skin tone
-1F9D1 1F3FF 200D 1F680 ; fully-qualified # 🧑🏿🚀 E12.1 astronaut: dark skin tone
-1F468 200D 1F680 ; fully-qualified # 👨🚀 E4.0 man astronaut
-1F468 1F3FB 200D 1F680 ; fully-qualified # 👨🏻🚀 E4.0 man astronaut: light skin tone
-1F468 1F3FC 200D 1F680 ; fully-qualified # 👨🏼🚀 E4.0 man astronaut: medium-light skin tone
-1F468 1F3FD 200D 1F680 ; fully-qualified # 👨🏽🚀 E4.0 man astronaut: medium skin tone
-1F468 1F3FE 200D 1F680 ; fully-qualified # 👨🏾🚀 E4.0 man astronaut: medium-dark skin tone
-1F468 1F3FF 200D 1F680 ; fully-qualified # 👨🏿🚀 E4.0 man astronaut: dark skin tone
-1F469 200D 1F680 ; fully-qualified # 👩🚀 E4.0 woman astronaut
-1F469 1F3FB 200D 1F680 ; fully-qualified # 👩🏻🚀 E4.0 woman astronaut: light skin tone
-1F469 1F3FC 200D 1F680 ; fully-qualified # 👩🏼🚀 E4.0 woman astronaut: medium-light skin tone
-1F469 1F3FD 200D 1F680 ; fully-qualified # 👩🏽🚀 E4.0 woman astronaut: medium skin tone
-1F469 1F3FE 200D 1F680 ; fully-qualified # 👩🏾🚀 E4.0 woman astronaut: medium-dark skin tone
-1F469 1F3FF 200D 1F680 ; fully-qualified # 👩🏿🚀 E4.0 woman astronaut: dark skin tone
-1F9D1 200D 1F692 ; fully-qualified # 🧑🚒 E12.1 firefighter
-1F9D1 1F3FB 200D 1F692 ; fully-qualified # 🧑🏻🚒 E12.1 firefighter: light skin tone
-1F9D1 1F3FC 200D 1F692 ; fully-qualified # 🧑🏼🚒 E12.1 firefighter: medium-light skin tone
-1F9D1 1F3FD 200D 1F692 ; fully-qualified # 🧑🏽🚒 E12.1 firefighter: medium skin tone
-1F9D1 1F3FE 200D 1F692 ; fully-qualified # 🧑🏾🚒 E12.1 firefighter: medium-dark skin tone
-1F9D1 1F3FF 200D 1F692 ; fully-qualified # 🧑🏿🚒 E12.1 firefighter: dark skin tone
-1F468 200D 1F692 ; fully-qualified # 👨🚒 E4.0 man firefighter
-1F468 1F3FB 200D 1F692 ; fully-qualified # 👨🏻🚒 E4.0 man firefighter: light skin tone
-1F468 1F3FC 200D 1F692 ; fully-qualified # 👨🏼🚒 E4.0 man firefighter: medium-light skin tone
-1F468 1F3FD 200D 1F692 ; fully-qualified # 👨🏽🚒 E4.0 man firefighter: medium skin tone
-1F468 1F3FE 200D 1F692 ; fully-qualified # 👨🏾🚒 E4.0 man firefighter: medium-dark skin tone
-1F468 1F3FF 200D 1F692 ; fully-qualified # 👨🏿🚒 E4.0 man firefighter: dark skin tone
-1F469 200D 1F692 ; fully-qualified # 👩🚒 E4.0 woman firefighter
-1F469 1F3FB 200D 1F692 ; fully-qualified # 👩🏻🚒 E4.0 woman firefighter: light skin tone
-1F469 1F3FC 200D 1F692 ; fully-qualified # 👩🏼🚒 E4.0 woman firefighter: medium-light skin tone
-1F469 1F3FD 200D 1F692 ; fully-qualified # 👩🏽🚒 E4.0 woman firefighter: medium skin tone
-1F469 1F3FE 200D 1F692 ; fully-qualified # 👩🏾🚒 E4.0 woman firefighter: medium-dark skin tone
-1F469 1F3FF 200D 1F692 ; fully-qualified # 👩🏿🚒 E4.0 woman firefighter: dark skin tone
-1F46E ; fully-qualified # 👮 E0.6 police officer
-1F46E 1F3FB ; fully-qualified # 👮🏻 E1.0 police officer: light skin tone
-1F46E 1F3FC ; fully-qualified # 👮🏼 E1.0 police officer: medium-light skin tone
-1F46E 1F3FD ; fully-qualified # 👮🏽 E1.0 police officer: medium skin tone
-1F46E 1F3FE ; fully-qualified # 👮🏾 E1.0 police officer: medium-dark skin tone
-1F46E 1F3FF ; fully-qualified # 👮🏿 E1.0 police officer: dark skin tone
-1F46E 200D 2642 FE0F ; fully-qualified # 👮♂️ E4.0 man police officer
-1F46E 200D 2642 ; minimally-qualified # 👮♂ E4.0 man police officer
-1F46E 1F3FB 200D 2642 FE0F ; fully-qualified # 👮🏻♂️ E4.0 man police officer: light skin tone
-1F46E 1F3FB 200D 2642 ; minimally-qualified # 👮🏻♂ E4.0 man police officer: light skin tone
-1F46E 1F3FC 200D 2642 FE0F ; fully-qualified # 👮🏼♂️ E4.0 man police officer: medium-light skin tone
-1F46E 1F3FC 200D 2642 ; minimally-qualified # 👮🏼♂ E4.0 man police officer: medium-light skin tone
-1F46E 1F3FD 200D 2642 FE0F ; fully-qualified # 👮🏽♂️ E4.0 man police officer: medium skin tone
-1F46E 1F3FD 200D 2642 ; minimally-qualified # 👮🏽♂ E4.0 man police officer: medium skin tone
-1F46E 1F3FE 200D 2642 FE0F ; fully-qualified # 👮🏾♂️ E4.0 man police officer: medium-dark skin tone
-1F46E 1F3FE 200D 2642 ; minimally-qualified # 👮🏾♂ E4.0 man police officer: medium-dark skin tone
-1F46E 1F3FF 200D 2642 FE0F ; fully-qualified # 👮🏿♂️ E4.0 man police officer: dark skin tone
-1F46E 1F3FF 200D 2642 ; minimally-qualified # 👮🏿♂ E4.0 man police officer: dark skin tone
-1F46E 200D 2640 FE0F ; fully-qualified # 👮♀️ E4.0 woman police officer
-1F46E 200D 2640 ; minimally-qualified # 👮♀ E4.0 woman police officer
-1F46E 1F3FB 200D 2640 FE0F ; fully-qualified # 👮🏻♀️ E4.0 woman police officer: light skin tone
-1F46E 1F3FB 200D 2640 ; minimally-qualified # 👮🏻♀ E4.0 woman police officer: light skin tone
-1F46E 1F3FC 200D 2640 FE0F ; fully-qualified # 👮🏼♀️ E4.0 woman police officer: medium-light skin tone
-1F46E 1F3FC 200D 2640 ; minimally-qualified # 👮🏼♀ E4.0 woman police officer: medium-light skin tone
-1F46E 1F3FD 200D 2640 FE0F ; fully-qualified # 👮🏽♀️ E4.0 woman police officer: medium skin tone
-1F46E 1F3FD 200D 2640 ; minimally-qualified # 👮🏽♀ E4.0 woman police officer: medium skin tone
-1F46E 1F3FE 200D 2640 FE0F ; fully-qualified # 👮🏾♀️ E4.0 woman police officer: medium-dark skin tone
-1F46E 1F3FE 200D 2640 ; minimally-qualified # 👮🏾♀ E4.0 woman police officer: medium-dark skin tone
-1F46E 1F3FF 200D 2640 FE0F ; fully-qualified # 👮🏿♀️ E4.0 woman police officer: dark skin tone
-1F46E 1F3FF 200D 2640 ; minimally-qualified # 👮🏿♀ E4.0 woman police officer: dark skin tone
-1F575 FE0F ; fully-qualified # 🕵️ E0.7 detective
-1F575 ; unqualified # 🕵 E0.7 detective
-1F575 1F3FB ; fully-qualified # 🕵🏻 E2.0 detective: light skin tone
-1F575 1F3FC ; fully-qualified # 🕵🏼 E2.0 detective: medium-light skin tone
-1F575 1F3FD ; fully-qualified # 🕵🏽 E2.0 detective: medium skin tone
-1F575 1F3FE ; fully-qualified # 🕵🏾 E2.0 detective: medium-dark skin tone
-1F575 1F3FF ; fully-qualified # 🕵🏿 E2.0 detective: dark skin tone
-1F575 FE0F 200D 2642 FE0F ; fully-qualified # 🕵️♂️ E4.0 man detective
-1F575 200D 2642 FE0F ; unqualified # 🕵♂️ E4.0 man detective
-1F575 FE0F 200D 2642 ; unqualified # 🕵️♂ E4.0 man detective
-1F575 200D 2642 ; unqualified # 🕵♂ E4.0 man detective
-1F575 1F3FB 200D 2642 FE0F ; fully-qualified # 🕵🏻♂️ E4.0 man detective: light skin tone
-1F575 1F3FB 200D 2642 ; minimally-qualified # 🕵🏻♂ E4.0 man detective: light skin tone
-1F575 1F3FC 200D 2642 FE0F ; fully-qualified # 🕵🏼♂️ E4.0 man detective: medium-light skin tone
-1F575 1F3FC 200D 2642 ; minimally-qualified # 🕵🏼♂ E4.0 man detective: medium-light skin tone
-1F575 1F3FD 200D 2642 FE0F ; fully-qualified # 🕵🏽♂️ E4.0 man detective: medium skin tone
-1F575 1F3FD 200D 2642 ; minimally-qualified # 🕵🏽♂ E4.0 man detective: medium skin tone
-1F575 1F3FE 200D 2642 FE0F ; fully-qualified # 🕵🏾♂️ E4.0 man detective: medium-dark skin tone
-1F575 1F3FE 200D 2642 ; minimally-qualified # 🕵🏾♂ E4.0 man detective: medium-dark skin tone
-1F575 1F3FF 200D 2642 FE0F ; fully-qualified # 🕵🏿♂️ E4.0 man detective: dark skin tone
-1F575 1F3FF 200D 2642 ; minimally-qualified # 🕵🏿♂ E4.0 man detective: dark skin tone
-1F575 FE0F 200D 2640 FE0F ; fully-qualified # 🕵️♀️ E4.0 woman detective
-1F575 200D 2640 FE0F ; unqualified # 🕵♀️ E4.0 woman detective
-1F575 FE0F 200D 2640 ; unqualified # 🕵️♀ E4.0 woman detective
-1F575 200D 2640 ; unqualified # 🕵♀ E4.0 woman detective
-1F575 1F3FB 200D 2640 FE0F ; fully-qualified # 🕵🏻♀️ E4.0 woman detective: light skin tone
-1F575 1F3FB 200D 2640 ; minimally-qualified # 🕵🏻♀ E4.0 woman detective: light skin tone
-1F575 1F3FC 200D 2640 FE0F ; fully-qualified # 🕵🏼♀️ E4.0 woman detective: medium-light skin tone
-1F575 1F3FC 200D 2640 ; minimally-qualified # 🕵🏼♀ E4.0 woman detective: medium-light skin tone
-1F575 1F3FD 200D 2640 FE0F ; fully-qualified # 🕵🏽♀️ E4.0 woman detective: medium skin tone
-1F575 1F3FD 200D 2640 ; minimally-qualified # 🕵🏽♀ E4.0 woman detective: medium skin tone
-1F575 1F3FE 200D 2640 FE0F ; fully-qualified # 🕵🏾♀️ E4.0 woman detective: medium-dark skin tone
-1F575 1F3FE 200D 2640 ; minimally-qualified # 🕵🏾♀ E4.0 woman detective: medium-dark skin tone
-1F575 1F3FF 200D 2640 FE0F ; fully-qualified # 🕵🏿♀️ E4.0 woman detective: dark skin tone
-1F575 1F3FF 200D 2640 ; minimally-qualified # 🕵🏿♀ E4.0 woman detective: dark skin tone
-1F482 ; fully-qualified # 💂 E0.6 guard
-1F482 1F3FB ; fully-qualified # 💂🏻 E1.0 guard: light skin tone
-1F482 1F3FC ; fully-qualified # 💂🏼 E1.0 guard: medium-light skin tone
-1F482 1F3FD ; fully-qualified # 💂🏽 E1.0 guard: medium skin tone
-1F482 1F3FE ; fully-qualified # 💂🏾 E1.0 guard: medium-dark skin tone
-1F482 1F3FF ; fully-qualified # 💂🏿 E1.0 guard: dark skin tone
-1F482 200D 2642 FE0F ; fully-qualified # 💂♂️ E4.0 man guard
-1F482 200D 2642 ; minimally-qualified # 💂♂ E4.0 man guard
-1F482 1F3FB 200D 2642 FE0F ; fully-qualified # 💂🏻♂️ E4.0 man guard: light skin tone
-1F482 1F3FB 200D 2642 ; minimally-qualified # 💂🏻♂ E4.0 man guard: light skin tone
-1F482 1F3FC 200D 2642 FE0F ; fully-qualified # 💂🏼♂️ E4.0 man guard: medium-light skin tone
-1F482 1F3FC 200D 2642 ; minimally-qualified # 💂🏼♂ E4.0 man guard: medium-light skin tone
-1F482 1F3FD 200D 2642 FE0F ; fully-qualified # 💂🏽♂️ E4.0 man guard: medium skin tone
-1F482 1F3FD 200D 2642 ; minimally-qualified # 💂🏽♂ E4.0 man guard: medium skin tone
-1F482 1F3FE 200D 2642 FE0F ; fully-qualified # 💂🏾♂️ E4.0 man guard: medium-dark skin tone
-1F482 1F3FE 200D 2642 ; minimally-qualified # 💂🏾♂ E4.0 man guard: medium-dark skin tone
-1F482 1F3FF 200D 2642 FE0F ; fully-qualified # 💂🏿♂️ E4.0 man guard: dark skin tone
-1F482 1F3FF 200D 2642 ; minimally-qualified # 💂🏿♂ E4.0 man guard: dark skin tone
-1F482 200D 2640 FE0F ; fully-qualified # 💂♀️ E4.0 woman guard
-1F482 200D 2640 ; minimally-qualified # 💂♀ E4.0 woman guard
-1F482 1F3FB 200D 2640 FE0F ; fully-qualified # 💂🏻♀️ E4.0 woman guard: light skin tone
-1F482 1F3FB 200D 2640 ; minimally-qualified # 💂🏻♀ E4.0 woman guard: light skin tone
-1F482 1F3FC 200D 2640 FE0F ; fully-qualified # 💂🏼♀️ E4.0 woman guard: medium-light skin tone
-1F482 1F3FC 200D 2640 ; minimally-qualified # 💂🏼♀ E4.0 woman guard: medium-light skin tone
-1F482 1F3FD 200D 2640 FE0F ; fully-qualified # 💂🏽♀️ E4.0 woman guard: medium skin tone
-1F482 1F3FD 200D 2640 ; minimally-qualified # 💂🏽♀ E4.0 woman guard: medium skin tone
-1F482 1F3FE 200D 2640 FE0F ; fully-qualified # 💂🏾♀️ E4.0 woman guard: medium-dark skin tone
-1F482 1F3FE 200D 2640 ; minimally-qualified # 💂🏾♀ E4.0 woman guard: medium-dark skin tone
-1F482 1F3FF 200D 2640 FE0F ; fully-qualified # 💂🏿♀️ E4.0 woman guard: dark skin tone
-1F482 1F3FF 200D 2640 ; minimally-qualified # 💂🏿♀ E4.0 woman guard: dark skin tone
-1F977 ; fully-qualified # 🥷 E13.0 ninja
-1F977 1F3FB ; fully-qualified # 🥷🏻 E13.0 ninja: light skin tone
-1F977 1F3FC ; fully-qualified # 🥷🏼 E13.0 ninja: medium-light skin tone
-1F977 1F3FD ; fully-qualified # 🥷🏽 E13.0 ninja: medium skin tone
-1F977 1F3FE ; fully-qualified # 🥷🏾 E13.0 ninja: medium-dark skin tone
-1F977 1F3FF ; fully-qualified # 🥷🏿 E13.0 ninja: dark skin tone
-1F477 ; fully-qualified # 👷 E0.6 construction worker
-1F477 1F3FB ; fully-qualified # 👷🏻 E1.0 construction worker: light skin tone
-1F477 1F3FC ; fully-qualified # 👷🏼 E1.0 construction worker: medium-light skin tone
-1F477 1F3FD ; fully-qualified # 👷🏽 E1.0 construction worker: medium skin tone
-1F477 1F3FE ; fully-qualified # 👷🏾 E1.0 construction worker: medium-dark skin tone
-1F477 1F3FF ; fully-qualified # 👷🏿 E1.0 construction worker: dark skin tone
-1F477 200D 2642 FE0F ; fully-qualified # 👷♂️ E4.0 man construction worker
-1F477 200D 2642 ; minimally-qualified # 👷♂ E4.0 man construction worker
-1F477 1F3FB 200D 2642 FE0F ; fully-qualified # 👷🏻♂️ E4.0 man construction worker: light skin tone
-1F477 1F3FB 200D 2642 ; minimally-qualified # 👷🏻♂ E4.0 man construction worker: light skin tone
-1F477 1F3FC 200D 2642 FE0F ; fully-qualified # 👷🏼♂️ E4.0 man construction worker: medium-light skin tone
-1F477 1F3FC 200D 2642 ; minimally-qualified # 👷🏼♂ E4.0 man construction worker: medium-light skin tone
-1F477 1F3FD 200D 2642 FE0F ; fully-qualified # 👷🏽♂️ E4.0 man construction worker: medium skin tone
-1F477 1F3FD 200D 2642 ; minimally-qualified # 👷🏽♂ E4.0 man construction worker: medium skin tone
-1F477 1F3FE 200D 2642 FE0F ; fully-qualified # 👷🏾♂️ E4.0 man construction worker: medium-dark skin tone
-1F477 1F3FE 200D 2642 ; minimally-qualified # 👷🏾♂ E4.0 man construction worker: medium-dark skin tone
-1F477 1F3FF 200D 2642 FE0F ; fully-qualified # 👷🏿♂️ E4.0 man construction worker: dark skin tone
-1F477 1F3FF 200D 2642 ; minimally-qualified # 👷🏿♂ E4.0 man construction worker: dark skin tone
-1F477 200D 2640 FE0F ; fully-qualified # 👷♀️ E4.0 woman construction worker
-1F477 200D 2640 ; minimally-qualified # 👷♀ E4.0 woman construction worker
-1F477 1F3FB 200D 2640 FE0F ; fully-qualified # 👷🏻♀️ E4.0 woman construction worker: light skin tone
-1F477 1F3FB 200D 2640 ; minimally-qualified # 👷🏻♀ E4.0 woman construction worker: light skin tone
-1F477 1F3FC 200D 2640 FE0F ; fully-qualified # 👷🏼♀️ E4.0 woman construction worker: medium-light skin tone
-1F477 1F3FC 200D 2640 ; minimally-qualified # 👷🏼♀ E4.0 woman construction worker: medium-light skin tone
-1F477 1F3FD 200D 2640 FE0F ; fully-qualified # 👷🏽♀️ E4.0 woman construction worker: medium skin tone
-1F477 1F3FD 200D 2640 ; minimally-qualified # 👷🏽♀ E4.0 woman construction worker: medium skin tone
-1F477 1F3FE 200D 2640 FE0F ; fully-qualified # 👷🏾♀️ E4.0 woman construction worker: medium-dark skin tone
-1F477 1F3FE 200D 2640 ; minimally-qualified # 👷🏾♀ E4.0 woman construction worker: medium-dark skin tone
-1F477 1F3FF 200D 2640 FE0F ; fully-qualified # 👷🏿♀️ E4.0 woman construction worker: dark skin tone
-1F477 1F3FF 200D 2640 ; minimally-qualified # 👷🏿♀ E4.0 woman construction worker: dark skin tone
-1F934 ; fully-qualified # 🤴 E3.0 prince
-1F934 1F3FB ; fully-qualified # 🤴🏻 E3.0 prince: light skin tone
-1F934 1F3FC ; fully-qualified # 🤴🏼 E3.0 prince: medium-light skin tone
-1F934 1F3FD ; fully-qualified # 🤴🏽 E3.0 prince: medium skin tone
-1F934 1F3FE ; fully-qualified # 🤴🏾 E3.0 prince: medium-dark skin tone
-1F934 1F3FF ; fully-qualified # 🤴🏿 E3.0 prince: dark skin tone
-1F478 ; fully-qualified # 👸 E0.6 princess
-1F478 1F3FB ; fully-qualified # 👸🏻 E1.0 princess: light skin tone
-1F478 1F3FC ; fully-qualified # 👸🏼 E1.0 princess: medium-light skin tone
-1F478 1F3FD ; fully-qualified # 👸🏽 E1.0 princess: medium skin tone
-1F478 1F3FE ; fully-qualified # 👸🏾 E1.0 princess: medium-dark skin tone
-1F478 1F3FF ; fully-qualified # 👸🏿 E1.0 princess: dark skin tone
-1F473 ; fully-qualified # 👳 E0.6 person wearing turban
-1F473 1F3FB ; fully-qualified # 👳🏻 E1.0 person wearing turban: light skin tone
-1F473 1F3FC ; fully-qualified # 👳🏼 E1.0 person wearing turban: medium-light skin tone
-1F473 1F3FD ; fully-qualified # 👳🏽 E1.0 person wearing turban: medium skin tone
-1F473 1F3FE ; fully-qualified # 👳🏾 E1.0 person wearing turban: medium-dark skin tone
-1F473 1F3FF ; fully-qualified # 👳🏿 E1.0 person wearing turban: dark skin tone
-1F473 200D 2642 FE0F ; fully-qualified # 👳♂️ E4.0 man wearing turban
-1F473 200D 2642 ; minimally-qualified # 👳♂ E4.0 man wearing turban
-1F473 1F3FB 200D 2642 FE0F ; fully-qualified # 👳🏻♂️ E4.0 man wearing turban: light skin tone
-1F473 1F3FB 200D 2642 ; minimally-qualified # 👳🏻♂ E4.0 man wearing turban: light skin tone
-1F473 1F3FC 200D 2642 FE0F ; fully-qualified # 👳🏼♂️ E4.0 man wearing turban: medium-light skin tone
-1F473 1F3FC 200D 2642 ; minimally-qualified # 👳🏼♂ E4.0 man wearing turban: medium-light skin tone
-1F473 1F3FD 200D 2642 FE0F ; fully-qualified # 👳🏽♂️ E4.0 man wearing turban: medium skin tone
-1F473 1F3FD 200D 2642 ; minimally-qualified # 👳🏽♂ E4.0 man wearing turban: medium skin tone
-1F473 1F3FE 200D 2642 FE0F ; fully-qualified # 👳🏾♂️ E4.0 man wearing turban: medium-dark skin tone
-1F473 1F3FE 200D 2642 ; minimally-qualified # 👳🏾♂ E4.0 man wearing turban: medium-dark skin tone
-1F473 1F3FF 200D 2642 FE0F ; fully-qualified # 👳🏿♂️ E4.0 man wearing turban: dark skin tone
-1F473 1F3FF 200D 2642 ; minimally-qualified # 👳🏿♂ E4.0 man wearing turban: dark skin tone
-1F473 200D 2640 FE0F ; fully-qualified # 👳♀️ E4.0 woman wearing turban
-1F473 200D 2640 ; minimally-qualified # 👳♀ E4.0 woman wearing turban
-1F473 1F3FB 200D 2640 FE0F ; fully-qualified # 👳🏻♀️ E4.0 woman wearing turban: light skin tone
-1F473 1F3FB 200D 2640 ; minimally-qualified # 👳🏻♀ E4.0 woman wearing turban: light skin tone
-1F473 1F3FC 200D 2640 FE0F ; fully-qualified # 👳🏼♀️ E4.0 woman wearing turban: medium-light skin tone
-1F473 1F3FC 200D 2640 ; minimally-qualified # 👳🏼♀ E4.0 woman wearing turban: medium-light skin tone
-1F473 1F3FD 200D 2640 FE0F ; fully-qualified # 👳🏽♀️ E4.0 woman wearing turban: medium skin tone
-1F473 1F3FD 200D 2640 ; minimally-qualified # 👳🏽♀ E4.0 woman wearing turban: medium skin tone
-1F473 1F3FE 200D 2640 FE0F ; fully-qualified # 👳🏾♀️ E4.0 woman wearing turban: medium-dark skin tone
-1F473 1F3FE 200D 2640 ; minimally-qualified # 👳🏾♀ E4.0 woman wearing turban: medium-dark skin tone
-1F473 1F3FF 200D 2640 FE0F ; fully-qualified # 👳🏿♀️ E4.0 woman wearing turban: dark skin tone
-1F473 1F3FF 200D 2640 ; minimally-qualified # 👳🏿♀ E4.0 woman wearing turban: dark skin tone
-1F472 ; fully-qualified # 👲 E0.6 person with skullcap
-1F472 1F3FB ; fully-qualified # 👲🏻 E1.0 person with skullcap: light skin tone
-1F472 1F3FC ; fully-qualified # 👲🏼 E1.0 person with skullcap: medium-light skin tone
-1F472 1F3FD ; fully-qualified # 👲🏽 E1.0 person with skullcap: medium skin tone
-1F472 1F3FE ; fully-qualified # 👲🏾 E1.0 person with skullcap: medium-dark skin tone
-1F472 1F3FF ; fully-qualified # 👲🏿 E1.0 person with skullcap: dark skin tone
-1F9D5 ; fully-qualified # 🧕 E5.0 woman with headscarf
-1F9D5 1F3FB ; fully-qualified # 🧕🏻 E5.0 woman with headscarf: light skin tone
-1F9D5 1F3FC ; fully-qualified # 🧕🏼 E5.0 woman with headscarf: medium-light skin tone
-1F9D5 1F3FD ; fully-qualified # 🧕🏽 E5.0 woman with headscarf: medium skin tone
-1F9D5 1F3FE ; fully-qualified # 🧕🏾 E5.0 woman with headscarf: medium-dark skin tone
-1F9D5 1F3FF ; fully-qualified # 🧕🏿 E5.0 woman with headscarf: dark skin tone
-1F935 ; fully-qualified # 🤵 E3.0 person in tuxedo
-1F935 1F3FB ; fully-qualified # 🤵🏻 E3.0 person in tuxedo: light skin tone
-1F935 1F3FC ; fully-qualified # 🤵🏼 E3.0 person in tuxedo: medium-light skin tone
-1F935 1F3FD ; fully-qualified # 🤵🏽 E3.0 person in tuxedo: medium skin tone
-1F935 1F3FE ; fully-qualified # 🤵🏾 E3.0 person in tuxedo: medium-dark skin tone
-1F935 1F3FF ; fully-qualified # 🤵🏿 E3.0 person in tuxedo: dark skin tone
-1F935 200D 2642 FE0F ; fully-qualified # 🤵♂️ E13.0 man in tuxedo
-1F935 200D 2642 ; minimally-qualified # 🤵♂ E13.0 man in tuxedo
-1F935 1F3FB 200D 2642 FE0F ; fully-qualified # 🤵🏻♂️ E13.0 man in tuxedo: light skin tone
-1F935 1F3FB 200D 2642 ; minimally-qualified # 🤵🏻♂ E13.0 man in tuxedo: light skin tone
-1F935 1F3FC 200D 2642 FE0F ; fully-qualified # 🤵🏼♂️ E13.0 man in tuxedo: medium-light skin tone
-1F935 1F3FC 200D 2642 ; minimally-qualified # 🤵🏼♂ E13.0 man in tuxedo: medium-light skin tone
-1F935 1F3FD 200D 2642 FE0F ; fully-qualified # 🤵🏽♂️ E13.0 man in tuxedo: medium skin tone
-1F935 1F3FD 200D 2642 ; minimally-qualified # 🤵🏽♂ E13.0 man in tuxedo: medium skin tone
-1F935 1F3FE 200D 2642 FE0F ; fully-qualified # 🤵🏾♂️ E13.0 man in tuxedo: medium-dark skin tone
-1F935 1F3FE 200D 2642 ; minimally-qualified # 🤵🏾♂ E13.0 man in tuxedo: medium-dark skin tone
-1F935 1F3FF 200D 2642 FE0F ; fully-qualified # 🤵🏿♂️ E13.0 man in tuxedo: dark skin tone
-1F935 1F3FF 200D 2642 ; minimally-qualified # 🤵🏿♂ E13.0 man in tuxedo: dark skin tone
-1F935 200D 2640 FE0F ; fully-qualified # 🤵♀️ E13.0 woman in tuxedo
-1F935 200D 2640 ; minimally-qualified # 🤵♀ E13.0 woman in tuxedo
-1F935 1F3FB 200D 2640 FE0F ; fully-qualified # 🤵🏻♀️ E13.0 woman in tuxedo: light skin tone
-1F935 1F3FB 200D 2640 ; minimally-qualified # 🤵🏻♀ E13.0 woman in tuxedo: light skin tone
-1F935 1F3FC 200D 2640 FE0F ; fully-qualified # 🤵🏼♀️ E13.0 woman in tuxedo: medium-light skin tone
-1F935 1F3FC 200D 2640 ; minimally-qualified # 🤵🏼♀ E13.0 woman in tuxedo: medium-light skin tone
-1F935 1F3FD 200D 2640 FE0F ; fully-qualified # 🤵🏽♀️ E13.0 woman in tuxedo: medium skin tone
-1F935 1F3FD 200D 2640 ; minimally-qualified # 🤵🏽♀ E13.0 woman in tuxedo: medium skin tone
-1F935 1F3FE 200D 2640 FE0F ; fully-qualified # 🤵🏾♀️ E13.0 woman in tuxedo: medium-dark skin tone
-1F935 1F3FE 200D 2640 ; minimally-qualified # 🤵🏾♀ E13.0 woman in tuxedo: medium-dark skin tone
-1F935 1F3FF 200D 2640 FE0F ; fully-qualified # 🤵🏿♀️ E13.0 woman in tuxedo: dark skin tone
-1F935 1F3FF 200D 2640 ; minimally-qualified # 🤵🏿♀ E13.0 woman in tuxedo: dark skin tone
-1F470 ; fully-qualified # 👰 E0.6 person with veil
-1F470 1F3FB ; fully-qualified # 👰🏻 E1.0 person with veil: light skin tone
-1F470 1F3FC ; fully-qualified # 👰🏼 E1.0 person with veil: medium-light skin tone
-1F470 1F3FD ; fully-qualified # 👰🏽 E1.0 person with veil: medium skin tone
-1F470 1F3FE ; fully-qualified # 👰🏾 E1.0 person with veil: medium-dark skin tone
-1F470 1F3FF ; fully-qualified # 👰🏿 E1.0 person with veil: dark skin tone
-1F470 200D 2642 FE0F ; fully-qualified # 👰♂️ E13.0 man with veil
-1F470 200D 2642 ; minimally-qualified # 👰♂ E13.0 man with veil
-1F470 1F3FB 200D 2642 FE0F ; fully-qualified # 👰🏻♂️ E13.0 man with veil: light skin tone
-1F470 1F3FB 200D 2642 ; minimally-qualified # 👰🏻♂ E13.0 man with veil: light skin tone
-1F470 1F3FC 200D 2642 FE0F ; fully-qualified # 👰🏼♂️ E13.0 man with veil: medium-light skin tone
-1F470 1F3FC 200D 2642 ; minimally-qualified # 👰🏼♂ E13.0 man with veil: medium-light skin tone
-1F470 1F3FD 200D 2642 FE0F ; fully-qualified # 👰🏽♂️ E13.0 man with veil: medium skin tone
-1F470 1F3FD 200D 2642 ; minimally-qualified # 👰🏽♂ E13.0 man with veil: medium skin tone
-1F470 1F3FE 200D 2642 FE0F ; fully-qualified # 👰🏾♂️ E13.0 man with veil: medium-dark skin tone
-1F470 1F3FE 200D 2642 ; minimally-qualified # 👰🏾♂ E13.0 man with veil: medium-dark skin tone
-1F470 1F3FF 200D 2642 FE0F ; fully-qualified # 👰🏿♂️ E13.0 man with veil: dark skin tone
-1F470 1F3FF 200D 2642 ; minimally-qualified # 👰🏿♂ E13.0 man with veil: dark skin tone
-1F470 200D 2640 FE0F ; fully-qualified # 👰♀️ E13.0 woman with veil
-1F470 200D 2640 ; minimally-qualified # 👰♀ E13.0 woman with veil
-1F470 1F3FB 200D 2640 FE0F ; fully-qualified # 👰🏻♀️ E13.0 woman with veil: light skin tone
-1F470 1F3FB 200D 2640 ; minimally-qualified # 👰🏻♀ E13.0 woman with veil: light skin tone
-1F470 1F3FC 200D 2640 FE0F ; fully-qualified # 👰🏼♀️ E13.0 woman with veil: medium-light skin tone
-1F470 1F3FC 200D 2640 ; minimally-qualified # 👰🏼♀ E13.0 woman with veil: medium-light skin tone
-1F470 1F3FD 200D 2640 FE0F ; fully-qualified # 👰🏽♀️ E13.0 woman with veil: medium skin tone
-1F470 1F3FD 200D 2640 ; minimally-qualified # 👰🏽♀ E13.0 woman with veil: medium skin tone
-1F470 1F3FE 200D 2640 FE0F ; fully-qualified # 👰🏾♀️ E13.0 woman with veil: medium-dark skin tone
-1F470 1F3FE 200D 2640 ; minimally-qualified # 👰🏾♀ E13.0 woman with veil: medium-dark skin tone
-1F470 1F3FF 200D 2640 FE0F ; fully-qualified # 👰🏿♀️ E13.0 woman with veil: dark skin tone
-1F470 1F3FF 200D 2640 ; minimally-qualified # 👰🏿♀ E13.0 woman with veil: dark skin tone
-1F930 ; fully-qualified # 🤰 E3.0 pregnant woman
-1F930 1F3FB ; fully-qualified # 🤰🏻 E3.0 pregnant woman: light skin tone
-1F930 1F3FC ; fully-qualified # 🤰🏼 E3.0 pregnant woman: medium-light skin tone
-1F930 1F3FD ; fully-qualified # 🤰🏽 E3.0 pregnant woman: medium skin tone
-1F930 1F3FE ; fully-qualified # 🤰🏾 E3.0 pregnant woman: medium-dark skin tone
-1F930 1F3FF ; fully-qualified # 🤰🏿 E3.0 pregnant woman: dark skin tone
-1F931 ; fully-qualified # 🤱 E5.0 breast-feeding
-1F931 1F3FB ; fully-qualified # 🤱🏻 E5.0 breast-feeding: light skin tone
-1F931 1F3FC ; fully-qualified # 🤱🏼 E5.0 breast-feeding: medium-light skin tone
-1F931 1F3FD ; fully-qualified # 🤱🏽 E5.0 breast-feeding: medium skin tone
-1F931 1F3FE ; fully-qualified # 🤱🏾 E5.0 breast-feeding: medium-dark skin tone
-1F931 1F3FF ; fully-qualified # 🤱🏿 E5.0 breast-feeding: dark skin tone
-1F469 200D 1F37C ; fully-qualified # 👩🍼 E13.0 woman feeding baby
-1F469 1F3FB 200D 1F37C ; fully-qualified # 👩🏻🍼 E13.0 woman feeding baby: light skin tone
-1F469 1F3FC 200D 1F37C ; fully-qualified # 👩🏼🍼 E13.0 woman feeding baby: medium-light skin tone
-1F469 1F3FD 200D 1F37C ; fully-qualified # 👩🏽🍼 E13.0 woman feeding baby: medium skin tone
-1F469 1F3FE 200D 1F37C ; fully-qualified # 👩🏾🍼 E13.0 woman feeding baby: medium-dark skin tone
-1F469 1F3FF 200D 1F37C ; fully-qualified # 👩🏿🍼 E13.0 woman feeding baby: dark skin tone
-1F468 200D 1F37C ; fully-qualified # 👨🍼 E13.0 man feeding baby
-1F468 1F3FB 200D 1F37C ; fully-qualified # 👨🏻🍼 E13.0 man feeding baby: light skin tone
-1F468 1F3FC 200D 1F37C ; fully-qualified # 👨🏼🍼 E13.0 man feeding baby: medium-light skin tone
-1F468 1F3FD 200D 1F37C ; fully-qualified # 👨🏽🍼 E13.0 man feeding baby: medium skin tone
-1F468 1F3FE 200D 1F37C ; fully-qualified # 👨🏾🍼 E13.0 man feeding baby: medium-dark skin tone
-1F468 1F3FF 200D 1F37C ; fully-qualified # 👨🏿🍼 E13.0 man feeding baby: dark skin tone
-1F9D1 200D 1F37C ; fully-qualified # 🧑🍼 E13.0 person feeding baby
-1F9D1 1F3FB 200D 1F37C ; fully-qualified # 🧑🏻🍼 E13.0 person feeding baby: light skin tone
-1F9D1 1F3FC 200D 1F37C ; fully-qualified # 🧑🏼🍼 E13.0 person feeding baby: medium-light skin tone
-1F9D1 1F3FD 200D 1F37C ; fully-qualified # 🧑🏽🍼 E13.0 person feeding baby: medium skin tone
-1F9D1 1F3FE 200D 1F37C ; fully-qualified # 🧑🏾🍼 E13.0 person feeding baby: medium-dark skin tone
-1F9D1 1F3FF 200D 1F37C ; fully-qualified # 🧑🏿🍼 E13.0 person feeding baby: dark skin tone
+1F9D1 200D 2695 FE0F ; fully-qualified # 🧑⚕️ E12.1 health worker
+1F9D1 200D 2695 ; minimally-qualified # 🧑⚕ E12.1 health worker
+1F9D1 1F3FB 200D 2695 FE0F ; fully-qualified # 🧑🏻⚕️ E12.1 health worker: light skin tone
+1F9D1 1F3FB 200D 2695 ; minimally-qualified # 🧑🏻⚕ E12.1 health worker: light skin tone
+1F9D1 1F3FC 200D 2695 FE0F ; fully-qualified # 🧑🏼⚕️ E12.1 health worker: medium-light skin tone
+1F9D1 1F3FC 200D 2695 ; minimally-qualified # 🧑🏼⚕ E12.1 health worker: medium-light skin tone
+1F9D1 1F3FD 200D 2695 FE0F ; fully-qualified # 🧑🏽⚕️ E12.1 health worker: medium skin tone
+1F9D1 1F3FD 200D 2695 ; minimally-qualified # 🧑🏽⚕ E12.1 health worker: medium skin tone
+1F9D1 1F3FE 200D 2695 FE0F ; fully-qualified # 🧑🏾⚕️ E12.1 health worker: medium-dark skin tone
+1F9D1 1F3FE 200D 2695 ; minimally-qualified # 🧑🏾⚕ E12.1 health worker: medium-dark skin tone
+1F9D1 1F3FF 200D 2695 FE0F ; fully-qualified # 🧑🏿⚕️ E12.1 health worker: dark skin tone
+1F9D1 1F3FF 200D 2695 ; minimally-qualified # 🧑🏿⚕ E12.1 health worker: dark skin tone
+1F468 200D 2695 FE0F ; fully-qualified # 👨⚕️ E4.0 man health worker
+1F468 200D 2695 ; minimally-qualified # 👨⚕ E4.0 man health worker
+1F468 1F3FB 200D 2695 FE0F ; fully-qualified # 👨🏻⚕️ E4.0 man health worker: light skin tone
+1F468 1F3FB 200D 2695 ; minimally-qualified # 👨🏻⚕ E4.0 man health worker: light skin tone
+1F468 1F3FC 200D 2695 FE0F ; fully-qualified # 👨🏼⚕️ E4.0 man health worker: medium-light skin tone
+1F468 1F3FC 200D 2695 ; minimally-qualified # 👨🏼⚕ E4.0 man health worker: medium-light skin tone
+1F468 1F3FD 200D 2695 FE0F ; fully-qualified # 👨🏽⚕️ E4.0 man health worker: medium skin tone
+1F468 1F3FD 200D 2695 ; minimally-qualified # 👨🏽⚕ E4.0 man health worker: medium skin tone
+1F468 1F3FE 200D 2695 FE0F ; fully-qualified # 👨🏾⚕️ E4.0 man health worker: medium-dark skin tone
+1F468 1F3FE 200D 2695 ; minimally-qualified # 👨🏾⚕ E4.0 man health worker: medium-dark skin tone
+1F468 1F3FF 200D 2695 FE0F ; fully-qualified # 👨🏿⚕️ E4.0 man health worker: dark skin tone
+1F468 1F3FF 200D 2695 ; minimally-qualified # 👨🏿⚕ E4.0 man health worker: dark skin tone
+1F469 200D 2695 FE0F ; fully-qualified # 👩⚕️ E4.0 woman health worker
+1F469 200D 2695 ; minimally-qualified # 👩⚕ E4.0 woman health worker
+1F469 1F3FB 200D 2695 FE0F ; fully-qualified # 👩🏻⚕️ E4.0 woman health worker: light skin tone
+1F469 1F3FB 200D 2695 ; minimally-qualified # 👩🏻⚕ E4.0 woman health worker: light skin tone
+1F469 1F3FC 200D 2695 FE0F ; fully-qualified # 👩🏼⚕️ E4.0 woman health worker: medium-light skin tone
+1F469 1F3FC 200D 2695 ; minimally-qualified # 👩🏼⚕ E4.0 woman health worker: medium-light skin tone
+1F469 1F3FD 200D 2695 FE0F ; fully-qualified # 👩🏽⚕️ E4.0 woman health worker: medium skin tone
+1F469 1F3FD 200D 2695 ; minimally-qualified # 👩🏽⚕ E4.0 woman health worker: medium skin tone
+1F469 1F3FE 200D 2695 FE0F ; fully-qualified # 👩🏾⚕️ E4.0 woman health worker: medium-dark skin tone
+1F469 1F3FE 200D 2695 ; minimally-qualified # 👩🏾⚕ E4.0 woman health worker: medium-dark skin tone
+1F469 1F3FF 200D 2695 FE0F ; fully-qualified # 👩🏿⚕️ E4.0 woman health worker: dark skin tone
+1F469 1F3FF 200D 2695 ; minimally-qualified # 👩🏿⚕ E4.0 woman health worker: dark skin tone
+1F9D1 200D 1F393 ; fully-qualified # 🧑🎓 E12.1 student
+1F9D1 1F3FB 200D 1F393 ; fully-qualified # 🧑🏻🎓 E12.1 student: light skin tone
+1F9D1 1F3FC 200D 1F393 ; fully-qualified # 🧑🏼🎓 E12.1 student: medium-light skin tone
+1F9D1 1F3FD 200D 1F393 ; fully-qualified # 🧑🏽🎓 E12.1 student: medium skin tone
+1F9D1 1F3FE 200D 1F393 ; fully-qualified # 🧑🏾🎓 E12.1 student: medium-dark skin tone
+1F9D1 1F3FF 200D 1F393 ; fully-qualified # 🧑🏿🎓 E12.1 student: dark skin tone
+1F468 200D 1F393 ; fully-qualified # 👨🎓 E4.0 man student
+1F468 1F3FB 200D 1F393 ; fully-qualified # 👨🏻🎓 E4.0 man student: light skin tone
+1F468 1F3FC 200D 1F393 ; fully-qualified # 👨🏼🎓 E4.0 man student: medium-light skin tone
+1F468 1F3FD 200D 1F393 ; fully-qualified # 👨🏽🎓 E4.0 man student: medium skin tone
+1F468 1F3FE 200D 1F393 ; fully-qualified # 👨🏾🎓 E4.0 man student: medium-dark skin tone
+1F468 1F3FF 200D 1F393 ; fully-qualified # 👨🏿🎓 E4.0 man student: dark skin tone
+1F469 200D 1F393 ; fully-qualified # 👩🎓 E4.0 woman student
+1F469 1F3FB 200D 1F393 ; fully-qualified # 👩🏻🎓 E4.0 woman student: light skin tone
+1F469 1F3FC 200D 1F393 ; fully-qualified # 👩🏼🎓 E4.0 woman student: medium-light skin tone
+1F469 1F3FD 200D 1F393 ; fully-qualified # 👩🏽🎓 E4.0 woman student: medium skin tone
+1F469 1F3FE 200D 1F393 ; fully-qualified # 👩🏾🎓 E4.0 woman student: medium-dark skin tone
+1F469 1F3FF 200D 1F393 ; fully-qualified # 👩🏿🎓 E4.0 woman student: dark skin tone
+1F9D1 200D 1F3EB ; fully-qualified # 🧑🏫 E12.1 teacher
+1F9D1 1F3FB 200D 1F3EB ; fully-qualified # 🧑🏻🏫 E12.1 teacher: light skin tone
+1F9D1 1F3FC 200D 1F3EB ; fully-qualified # 🧑🏼🏫 E12.1 teacher: medium-light skin tone
+1F9D1 1F3FD 200D 1F3EB ; fully-qualified # 🧑🏽🏫 E12.1 teacher: medium skin tone
+1F9D1 1F3FE 200D 1F3EB ; fully-qualified # 🧑🏾🏫 E12.1 teacher: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3EB ; fully-qualified # 🧑🏿🏫 E12.1 teacher: dark skin tone
+1F468 200D 1F3EB ; fully-qualified # 👨🏫 E4.0 man teacher
+1F468 1F3FB 200D 1F3EB ; fully-qualified # 👨🏻🏫 E4.0 man teacher: light skin tone
+1F468 1F3FC 200D 1F3EB ; fully-qualified # 👨🏼🏫 E4.0 man teacher: medium-light skin tone
+1F468 1F3FD 200D 1F3EB ; fully-qualified # 👨🏽🏫 E4.0 man teacher: medium skin tone
+1F468 1F3FE 200D 1F3EB ; fully-qualified # 👨🏾🏫 E4.0 man teacher: medium-dark skin tone
+1F468 1F3FF 200D 1F3EB ; fully-qualified # 👨🏿🏫 E4.0 man teacher: dark skin tone
+1F469 200D 1F3EB ; fully-qualified # 👩🏫 E4.0 woman teacher
+1F469 1F3FB 200D 1F3EB ; fully-qualified # 👩🏻🏫 E4.0 woman teacher: light skin tone
+1F469 1F3FC 200D 1F3EB ; fully-qualified # 👩🏼🏫 E4.0 woman teacher: medium-light skin tone
+1F469 1F3FD 200D 1F3EB ; fully-qualified # 👩🏽🏫 E4.0 woman teacher: medium skin tone
+1F469 1F3FE 200D 1F3EB ; fully-qualified # 👩🏾🏫 E4.0 woman teacher: medium-dark skin tone
+1F469 1F3FF 200D 1F3EB ; fully-qualified # 👩🏿🏫 E4.0 woman teacher: dark skin tone
+1F9D1 200D 2696 FE0F ; fully-qualified # 🧑⚖️ E12.1 judge
+1F9D1 200D 2696 ; minimally-qualified # 🧑⚖ E12.1 judge
+1F9D1 1F3FB 200D 2696 FE0F ; fully-qualified # 🧑🏻⚖️ E12.1 judge: light skin tone
+1F9D1 1F3FB 200D 2696 ; minimally-qualified # 🧑🏻⚖ E12.1 judge: light skin tone
+1F9D1 1F3FC 200D 2696 FE0F ; fully-qualified # 🧑🏼⚖️ E12.1 judge: medium-light skin tone
+1F9D1 1F3FC 200D 2696 ; minimally-qualified # 🧑🏼⚖ E12.1 judge: medium-light skin tone
+1F9D1 1F3FD 200D 2696 FE0F ; fully-qualified # 🧑🏽⚖️ E12.1 judge: medium skin tone
+1F9D1 1F3FD 200D 2696 ; minimally-qualified # 🧑🏽⚖ E12.1 judge: medium skin tone
+1F9D1 1F3FE 200D 2696 FE0F ; fully-qualified # 🧑🏾⚖️ E12.1 judge: medium-dark skin tone
+1F9D1 1F3FE 200D 2696 ; minimally-qualified # 🧑🏾⚖ E12.1 judge: medium-dark skin tone
+1F9D1 1F3FF 200D 2696 FE0F ; fully-qualified # 🧑🏿⚖️ E12.1 judge: dark skin tone
+1F9D1 1F3FF 200D 2696 ; minimally-qualified # 🧑🏿⚖ E12.1 judge: dark skin tone
+1F468 200D 2696 FE0F ; fully-qualified # 👨⚖️ E4.0 man judge
+1F468 200D 2696 ; minimally-qualified # 👨⚖ E4.0 man judge
+1F468 1F3FB 200D 2696 FE0F ; fully-qualified # 👨🏻⚖️ E4.0 man judge: light skin tone
+1F468 1F3FB 200D 2696 ; minimally-qualified # 👨🏻⚖ E4.0 man judge: light skin tone
+1F468 1F3FC 200D 2696 FE0F ; fully-qualified # 👨🏼⚖️ E4.0 man judge: medium-light skin tone
+1F468 1F3FC 200D 2696 ; minimally-qualified # 👨🏼⚖ E4.0 man judge: medium-light skin tone
+1F468 1F3FD 200D 2696 FE0F ; fully-qualified # 👨🏽⚖️ E4.0 man judge: medium skin tone
+1F468 1F3FD 200D 2696 ; minimally-qualified # 👨🏽⚖ E4.0 man judge: medium skin tone
+1F468 1F3FE 200D 2696 FE0F ; fully-qualified # 👨🏾⚖️ E4.0 man judge: medium-dark skin tone
+1F468 1F3FE 200D 2696 ; minimally-qualified # 👨🏾⚖ E4.0 man judge: medium-dark skin tone
+1F468 1F3FF 200D 2696 FE0F ; fully-qualified # 👨🏿⚖️ E4.0 man judge: dark skin tone
+1F468 1F3FF 200D 2696 ; minimally-qualified # 👨🏿⚖ E4.0 man judge: dark skin tone
+1F469 200D 2696 FE0F ; fully-qualified # 👩⚖️ E4.0 woman judge
+1F469 200D 2696 ; minimally-qualified # 👩⚖ E4.0 woman judge
+1F469 1F3FB 200D 2696 FE0F ; fully-qualified # 👩🏻⚖️ E4.0 woman judge: light skin tone
+1F469 1F3FB 200D 2696 ; minimally-qualified # 👩🏻⚖ E4.0 woman judge: light skin tone
+1F469 1F3FC 200D 2696 FE0F ; fully-qualified # 👩🏼⚖️ E4.0 woman judge: medium-light skin tone
+1F469 1F3FC 200D 2696 ; minimally-qualified # 👩🏼⚖ E4.0 woman judge: medium-light skin tone
+1F469 1F3FD 200D 2696 FE0F ; fully-qualified # 👩🏽⚖️ E4.0 woman judge: medium skin tone
+1F469 1F3FD 200D 2696 ; minimally-qualified # 👩🏽⚖ E4.0 woman judge: medium skin tone
+1F469 1F3FE 200D 2696 FE0F ; fully-qualified # 👩🏾⚖️ E4.0 woman judge: medium-dark skin tone
+1F469 1F3FE 200D 2696 ; minimally-qualified # 👩🏾⚖ E4.0 woman judge: medium-dark skin tone
+1F469 1F3FF 200D 2696 FE0F ; fully-qualified # 👩🏿⚖️ E4.0 woman judge: dark skin tone
+1F469 1F3FF 200D 2696 ; minimally-qualified # 👩🏿⚖ E4.0 woman judge: dark skin tone
+1F9D1 200D 1F33E ; fully-qualified # 🧑🌾 E12.1 farmer
+1F9D1 1F3FB 200D 1F33E ; fully-qualified # 🧑🏻🌾 E12.1 farmer: light skin tone
+1F9D1 1F3FC 200D 1F33E ; fully-qualified # 🧑🏼🌾 E12.1 farmer: medium-light skin tone
+1F9D1 1F3FD 200D 1F33E ; fully-qualified # 🧑🏽🌾 E12.1 farmer: medium skin tone
+1F9D1 1F3FE 200D 1F33E ; fully-qualified # 🧑🏾🌾 E12.1 farmer: medium-dark skin tone
+1F9D1 1F3FF 200D 1F33E ; fully-qualified # 🧑🏿🌾 E12.1 farmer: dark skin tone
+1F468 200D 1F33E ; fully-qualified # 👨🌾 E4.0 man farmer
+1F468 1F3FB 200D 1F33E ; fully-qualified # 👨🏻🌾 E4.0 man farmer: light skin tone
+1F468 1F3FC 200D 1F33E ; fully-qualified # 👨🏼🌾 E4.0 man farmer: medium-light skin tone
+1F468 1F3FD 200D 1F33E ; fully-qualified # 👨🏽🌾 E4.0 man farmer: medium skin tone
+1F468 1F3FE 200D 1F33E ; fully-qualified # 👨🏾🌾 E4.0 man farmer: medium-dark skin tone
+1F468 1F3FF 200D 1F33E ; fully-qualified # 👨🏿🌾 E4.0 man farmer: dark skin tone
+1F469 200D 1F33E ; fully-qualified # 👩🌾 E4.0 woman farmer
+1F469 1F3FB 200D 1F33E ; fully-qualified # 👩🏻🌾 E4.0 woman farmer: light skin tone
+1F469 1F3FC 200D 1F33E ; fully-qualified # 👩🏼🌾 E4.0 woman farmer: medium-light skin tone
+1F469 1F3FD 200D 1F33E ; fully-qualified # 👩🏽🌾 E4.0 woman farmer: medium skin tone
+1F469 1F3FE 200D 1F33E ; fully-qualified # 👩🏾🌾 E4.0 woman farmer: medium-dark skin tone
+1F469 1F3FF 200D 1F33E ; fully-qualified # 👩🏿🌾 E4.0 woman farmer: dark skin tone
+1F9D1 200D 1F373 ; fully-qualified # 🧑🍳 E12.1 cook
+1F9D1 1F3FB 200D 1F373 ; fully-qualified # 🧑🏻🍳 E12.1 cook: light skin tone
+1F9D1 1F3FC 200D 1F373 ; fully-qualified # 🧑🏼🍳 E12.1 cook: medium-light skin tone
+1F9D1 1F3FD 200D 1F373 ; fully-qualified # 🧑🏽🍳 E12.1 cook: medium skin tone
+1F9D1 1F3FE 200D 1F373 ; fully-qualified # 🧑🏾🍳 E12.1 cook: medium-dark skin tone
+1F9D1 1F3FF 200D 1F373 ; fully-qualified # 🧑🏿🍳 E12.1 cook: dark skin tone
+1F468 200D 1F373 ; fully-qualified # 👨🍳 E4.0 man cook
+1F468 1F3FB 200D 1F373 ; fully-qualified # 👨🏻🍳 E4.0 man cook: light skin tone
+1F468 1F3FC 200D 1F373 ; fully-qualified # 👨🏼🍳 E4.0 man cook: medium-light skin tone
+1F468 1F3FD 200D 1F373 ; fully-qualified # 👨🏽🍳 E4.0 man cook: medium skin tone
+1F468 1F3FE 200D 1F373 ; fully-qualified # 👨🏾🍳 E4.0 man cook: medium-dark skin tone
+1F468 1F3FF 200D 1F373 ; fully-qualified # 👨🏿🍳 E4.0 man cook: dark skin tone
+1F469 200D 1F373 ; fully-qualified # 👩🍳 E4.0 woman cook
+1F469 1F3FB 200D 1F373 ; fully-qualified # 👩🏻🍳 E4.0 woman cook: light skin tone
+1F469 1F3FC 200D 1F373 ; fully-qualified # 👩🏼🍳 E4.0 woman cook: medium-light skin tone
+1F469 1F3FD 200D 1F373 ; fully-qualified # 👩🏽🍳 E4.0 woman cook: medium skin tone
+1F469 1F3FE 200D 1F373 ; fully-qualified # 👩🏾🍳 E4.0 woman cook: medium-dark skin tone
+1F469 1F3FF 200D 1F373 ; fully-qualified # 👩🏿🍳 E4.0 woman cook: dark skin tone
+1F9D1 200D 1F527 ; fully-qualified # 🧑🔧 E12.1 mechanic
+1F9D1 1F3FB 200D 1F527 ; fully-qualified # 🧑🏻🔧 E12.1 mechanic: light skin tone
+1F9D1 1F3FC 200D 1F527 ; fully-qualified # 🧑🏼🔧 E12.1 mechanic: medium-light skin tone
+1F9D1 1F3FD 200D 1F527 ; fully-qualified # 🧑🏽🔧 E12.1 mechanic: medium skin tone
+1F9D1 1F3FE 200D 1F527 ; fully-qualified # 🧑🏾🔧 E12.1 mechanic: medium-dark skin tone
+1F9D1 1F3FF 200D 1F527 ; fully-qualified # 🧑🏿🔧 E12.1 mechanic: dark skin tone
+1F468 200D 1F527 ; fully-qualified # 👨🔧 E4.0 man mechanic
+1F468 1F3FB 200D 1F527 ; fully-qualified # 👨🏻🔧 E4.0 man mechanic: light skin tone
+1F468 1F3FC 200D 1F527 ; fully-qualified # 👨🏼🔧 E4.0 man mechanic: medium-light skin tone
+1F468 1F3FD 200D 1F527 ; fully-qualified # 👨🏽🔧 E4.0 man mechanic: medium skin tone
+1F468 1F3FE 200D 1F527 ; fully-qualified # 👨🏾🔧 E4.0 man mechanic: medium-dark skin tone
+1F468 1F3FF 200D 1F527 ; fully-qualified # 👨🏿🔧 E4.0 man mechanic: dark skin tone
+1F469 200D 1F527 ; fully-qualified # 👩🔧 E4.0 woman mechanic
+1F469 1F3FB 200D 1F527 ; fully-qualified # 👩🏻🔧 E4.0 woman mechanic: light skin tone
+1F469 1F3FC 200D 1F527 ; fully-qualified # 👩🏼🔧 E4.0 woman mechanic: medium-light skin tone
+1F469 1F3FD 200D 1F527 ; fully-qualified # 👩🏽🔧 E4.0 woman mechanic: medium skin tone
+1F469 1F3FE 200D 1F527 ; fully-qualified # 👩🏾🔧 E4.0 woman mechanic: medium-dark skin tone
+1F469 1F3FF 200D 1F527 ; fully-qualified # 👩🏿🔧 E4.0 woman mechanic: dark skin tone
+1F9D1 200D 1F3ED ; fully-qualified # 🧑🏭 E12.1 factory worker
+1F9D1 1F3FB 200D 1F3ED ; fully-qualified # 🧑🏻🏭 E12.1 factory worker: light skin tone
+1F9D1 1F3FC 200D 1F3ED ; fully-qualified # 🧑🏼🏭 E12.1 factory worker: medium-light skin tone
+1F9D1 1F3FD 200D 1F3ED ; fully-qualified # 🧑🏽🏭 E12.1 factory worker: medium skin tone
+1F9D1 1F3FE 200D 1F3ED ; fully-qualified # 🧑🏾🏭 E12.1 factory worker: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3ED ; fully-qualified # 🧑🏿🏭 E12.1 factory worker: dark skin tone
+1F468 200D 1F3ED ; fully-qualified # 👨🏭 E4.0 man factory worker
+1F468 1F3FB 200D 1F3ED ; fully-qualified # 👨🏻🏭 E4.0 man factory worker: light skin tone
+1F468 1F3FC 200D 1F3ED ; fully-qualified # 👨🏼🏭 E4.0 man factory worker: medium-light skin tone
+1F468 1F3FD 200D 1F3ED ; fully-qualified # 👨🏽🏭 E4.0 man factory worker: medium skin tone
+1F468 1F3FE 200D 1F3ED ; fully-qualified # 👨🏾🏭 E4.0 man factory worker: medium-dark skin tone
+1F468 1F3FF 200D 1F3ED ; fully-qualified # 👨🏿🏭 E4.0 man factory worker: dark skin tone
+1F469 200D 1F3ED ; fully-qualified # 👩🏭 E4.0 woman factory worker
+1F469 1F3FB 200D 1F3ED ; fully-qualified # 👩🏻🏭 E4.0 woman factory worker: light skin tone
+1F469 1F3FC 200D 1F3ED ; fully-qualified # 👩🏼🏭 E4.0 woman factory worker: medium-light skin tone
+1F469 1F3FD 200D 1F3ED ; fully-qualified # 👩🏽🏭 E4.0 woman factory worker: medium skin tone
+1F469 1F3FE 200D 1F3ED ; fully-qualified # 👩🏾🏭 E4.0 woman factory worker: medium-dark skin tone
+1F469 1F3FF 200D 1F3ED ; fully-qualified # 👩🏿🏭 E4.0 woman factory worker: dark skin tone
+1F9D1 200D 1F4BC ; fully-qualified # 🧑💼 E12.1 office worker
+1F9D1 1F3FB 200D 1F4BC ; fully-qualified # 🧑🏻💼 E12.1 office worker: light skin tone
+1F9D1 1F3FC 200D 1F4BC ; fully-qualified # 🧑🏼💼 E12.1 office worker: medium-light skin tone
+1F9D1 1F3FD 200D 1F4BC ; fully-qualified # 🧑🏽💼 E12.1 office worker: medium skin tone
+1F9D1 1F3FE 200D 1F4BC ; fully-qualified # 🧑🏾💼 E12.1 office worker: medium-dark skin tone
+1F9D1 1F3FF 200D 1F4BC ; fully-qualified # 🧑🏿💼 E12.1 office worker: dark skin tone
+1F468 200D 1F4BC ; fully-qualified # 👨💼 E4.0 man office worker
+1F468 1F3FB 200D 1F4BC ; fully-qualified # 👨🏻💼 E4.0 man office worker: light skin tone
+1F468 1F3FC 200D 1F4BC ; fully-qualified # 👨🏼💼 E4.0 man office worker: medium-light skin tone
+1F468 1F3FD 200D 1F4BC ; fully-qualified # 👨🏽💼 E4.0 man office worker: medium skin tone
+1F468 1F3FE 200D 1F4BC ; fully-qualified # 👨🏾💼 E4.0 man office worker: medium-dark skin tone
+1F468 1F3FF 200D 1F4BC ; fully-qualified # 👨🏿💼 E4.0 man office worker: dark skin tone
+1F469 200D 1F4BC ; fully-qualified # 👩💼 E4.0 woman office worker
+1F469 1F3FB 200D 1F4BC ; fully-qualified # 👩🏻💼 E4.0 woman office worker: light skin tone
+1F469 1F3FC 200D 1F4BC ; fully-qualified # 👩🏼💼 E4.0 woman office worker: medium-light skin tone
+1F469 1F3FD 200D 1F4BC ; fully-qualified # 👩🏽💼 E4.0 woman office worker: medium skin tone
+1F469 1F3FE 200D 1F4BC ; fully-qualified # 👩🏾💼 E4.0 woman office worker: medium-dark skin tone
+1F469 1F3FF 200D 1F4BC ; fully-qualified # 👩🏿💼 E4.0 woman office worker: dark skin tone
+1F9D1 200D 1F52C ; fully-qualified # 🧑🔬 E12.1 scientist
+1F9D1 1F3FB 200D 1F52C ; fully-qualified # 🧑🏻🔬 E12.1 scientist: light skin tone
+1F9D1 1F3FC 200D 1F52C ; fully-qualified # 🧑🏼🔬 E12.1 scientist: medium-light skin tone
+1F9D1 1F3FD 200D 1F52C ; fully-qualified # 🧑🏽🔬 E12.1 scientist: medium skin tone
+1F9D1 1F3FE 200D 1F52C ; fully-qualified # 🧑🏾🔬 E12.1 scientist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F52C ; fully-qualified # 🧑🏿🔬 E12.1 scientist: dark skin tone
+1F468 200D 1F52C ; fully-qualified # 👨🔬 E4.0 man scientist
+1F468 1F3FB 200D 1F52C ; fully-qualified # 👨🏻🔬 E4.0 man scientist: light skin tone
+1F468 1F3FC 200D 1F52C ; fully-qualified # 👨🏼🔬 E4.0 man scientist: medium-light skin tone
+1F468 1F3FD 200D 1F52C ; fully-qualified # 👨🏽🔬 E4.0 man scientist: medium skin tone
+1F468 1F3FE 200D 1F52C ; fully-qualified # 👨🏾🔬 E4.0 man scientist: medium-dark skin tone
+1F468 1F3FF 200D 1F52C ; fully-qualified # 👨🏿🔬 E4.0 man scientist: dark skin tone
+1F469 200D 1F52C ; fully-qualified # 👩🔬 E4.0 woman scientist
+1F469 1F3FB 200D 1F52C ; fully-qualified # 👩🏻🔬 E4.0 woman scientist: light skin tone
+1F469 1F3FC 200D 1F52C ; fully-qualified # 👩🏼🔬 E4.0 woman scientist: medium-light skin tone
+1F469 1F3FD 200D 1F52C ; fully-qualified # 👩🏽🔬 E4.0 woman scientist: medium skin tone
+1F469 1F3FE 200D 1F52C ; fully-qualified # 👩🏾🔬 E4.0 woman scientist: medium-dark skin tone
+1F469 1F3FF 200D 1F52C ; fully-qualified # 👩🏿🔬 E4.0 woman scientist: dark skin tone
+1F9D1 200D 1F4BB ; fully-qualified # 🧑💻 E12.1 technologist
+1F9D1 1F3FB 200D 1F4BB ; fully-qualified # 🧑🏻💻 E12.1 technologist: light skin tone
+1F9D1 1F3FC 200D 1F4BB ; fully-qualified # 🧑🏼💻 E12.1 technologist: medium-light skin tone
+1F9D1 1F3FD 200D 1F4BB ; fully-qualified # 🧑🏽💻 E12.1 technologist: medium skin tone
+1F9D1 1F3FE 200D 1F4BB ; fully-qualified # 🧑🏾💻 E12.1 technologist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F4BB ; fully-qualified # 🧑🏿💻 E12.1 technologist: dark skin tone
+1F468 200D 1F4BB ; fully-qualified # 👨💻 E4.0 man technologist
+1F468 1F3FB 200D 1F4BB ; fully-qualified # 👨🏻💻 E4.0 man technologist: light skin tone
+1F468 1F3FC 200D 1F4BB ; fully-qualified # 👨🏼💻 E4.0 man technologist: medium-light skin tone
+1F468 1F3FD 200D 1F4BB ; fully-qualified # 👨🏽💻 E4.0 man technologist: medium skin tone
+1F468 1F3FE 200D 1F4BB ; fully-qualified # 👨🏾💻 E4.0 man technologist: medium-dark skin tone
+1F468 1F3FF 200D 1F4BB ; fully-qualified # 👨🏿💻 E4.0 man technologist: dark skin tone
+1F469 200D 1F4BB ; fully-qualified # 👩💻 E4.0 woman technologist
+1F469 1F3FB 200D 1F4BB ; fully-qualified # 👩🏻💻 E4.0 woman technologist: light skin tone
+1F469 1F3FC 200D 1F4BB ; fully-qualified # 👩🏼💻 E4.0 woman technologist: medium-light skin tone
+1F469 1F3FD 200D 1F4BB ; fully-qualified # 👩🏽💻 E4.0 woman technologist: medium skin tone
+1F469 1F3FE 200D 1F4BB ; fully-qualified # 👩🏾💻 E4.0 woman technologist: medium-dark skin tone
+1F469 1F3FF 200D 1F4BB ; fully-qualified # 👩🏿💻 E4.0 woman technologist: dark skin tone
+1F9D1 200D 1F3A4 ; fully-qualified # 🧑🎤 E12.1 singer
+1F9D1 1F3FB 200D 1F3A4 ; fully-qualified # 🧑🏻🎤 E12.1 singer: light skin tone
+1F9D1 1F3FC 200D 1F3A4 ; fully-qualified # 🧑🏼🎤 E12.1 singer: medium-light skin tone
+1F9D1 1F3FD 200D 1F3A4 ; fully-qualified # 🧑🏽🎤 E12.1 singer: medium skin tone
+1F9D1 1F3FE 200D 1F3A4 ; fully-qualified # 🧑🏾🎤 E12.1 singer: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3A4 ; fully-qualified # 🧑🏿🎤 E12.1 singer: dark skin tone
+1F468 200D 1F3A4 ; fully-qualified # 👨🎤 E4.0 man singer
+1F468 1F3FB 200D 1F3A4 ; fully-qualified # 👨🏻🎤 E4.0 man singer: light skin tone
+1F468 1F3FC 200D 1F3A4 ; fully-qualified # 👨🏼🎤 E4.0 man singer: medium-light skin tone
+1F468 1F3FD 200D 1F3A4 ; fully-qualified # 👨🏽🎤 E4.0 man singer: medium skin tone
+1F468 1F3FE 200D 1F3A4 ; fully-qualified # 👨🏾🎤 E4.0 man singer: medium-dark skin tone
+1F468 1F3FF 200D 1F3A4 ; fully-qualified # 👨🏿🎤 E4.0 man singer: dark skin tone
+1F469 200D 1F3A4 ; fully-qualified # 👩🎤 E4.0 woman singer
+1F469 1F3FB 200D 1F3A4 ; fully-qualified # 👩🏻🎤 E4.0 woman singer: light skin tone
+1F469 1F3FC 200D 1F3A4 ; fully-qualified # 👩🏼🎤 E4.0 woman singer: medium-light skin tone
+1F469 1F3FD 200D 1F3A4 ; fully-qualified # 👩🏽🎤 E4.0 woman singer: medium skin tone
+1F469 1F3FE 200D 1F3A4 ; fully-qualified # 👩🏾🎤 E4.0 woman singer: medium-dark skin tone
+1F469 1F3FF 200D 1F3A4 ; fully-qualified # 👩🏿🎤 E4.0 woman singer: dark skin tone
+1F9D1 200D 1F3A8 ; fully-qualified # 🧑🎨 E12.1 artist
+1F9D1 1F3FB 200D 1F3A8 ; fully-qualified # 🧑🏻🎨 E12.1 artist: light skin tone
+1F9D1 1F3FC 200D 1F3A8 ; fully-qualified # 🧑🏼🎨 E12.1 artist: medium-light skin tone
+1F9D1 1F3FD 200D 1F3A8 ; fully-qualified # 🧑🏽🎨 E12.1 artist: medium skin tone
+1F9D1 1F3FE 200D 1F3A8 ; fully-qualified # 🧑🏾🎨 E12.1 artist: medium-dark skin tone
+1F9D1 1F3FF 200D 1F3A8 ; fully-qualified # 🧑🏿🎨 E12.1 artist: dark skin tone
+1F468 200D 1F3A8 ; fully-qualified # 👨🎨 E4.0 man artist
+1F468 1F3FB 200D 1F3A8 ; fully-qualified # 👨🏻🎨 E4.0 man artist: light skin tone
+1F468 1F3FC 200D 1F3A8 ; fully-qualified # 👨🏼🎨 E4.0 man artist: medium-light skin tone
+1F468 1F3FD 200D 1F3A8 ; fully-qualified # 👨🏽🎨 E4.0 man artist: medium skin tone
+1F468 1F3FE 200D 1F3A8 ; fully-qualified # 👨🏾🎨 E4.0 man artist: medium-dark skin tone
+1F468 1F3FF 200D 1F3A8 ; fully-qualified # 👨🏿🎨 E4.0 man artist: dark skin tone
+1F469 200D 1F3A8 ; fully-qualified # 👩🎨 E4.0 woman artist
+1F469 1F3FB 200D 1F3A8 ; fully-qualified # 👩🏻🎨 E4.0 woman artist: light skin tone
+1F469 1F3FC 200D 1F3A8 ; fully-qualified # 👩🏼🎨 E4.0 woman artist: medium-light skin tone
+1F469 1F3FD 200D 1F3A8 ; fully-qualified # 👩🏽🎨 E4.0 woman artist: medium skin tone
+1F469 1F3FE 200D 1F3A8 ; fully-qualified # 👩🏾🎨 E4.0 woman artist: medium-dark skin tone
+1F469 1F3FF 200D 1F3A8 ; fully-qualified # 👩🏿🎨 E4.0 woman artist: dark skin tone
+1F9D1 200D 2708 FE0F ; fully-qualified # 🧑✈️ E12.1 pilot
+1F9D1 200D 2708 ; minimally-qualified # 🧑✈ E12.1 pilot
+1F9D1 1F3FB 200D 2708 FE0F ; fully-qualified # 🧑🏻✈️ E12.1 pilot: light skin tone
+1F9D1 1F3FB 200D 2708 ; minimally-qualified # 🧑🏻✈ E12.1 pilot: light skin tone
+1F9D1 1F3FC 200D 2708 FE0F ; fully-qualified # 🧑🏼✈️ E12.1 pilot: medium-light skin tone
+1F9D1 1F3FC 200D 2708 ; minimally-qualified # 🧑🏼✈ E12.1 pilot: medium-light skin tone
+1F9D1 1F3FD 200D 2708 FE0F ; fully-qualified # 🧑🏽✈️ E12.1 pilot: medium skin tone
+1F9D1 1F3FD 200D 2708 ; minimally-qualified # 🧑🏽✈ E12.1 pilot: medium skin tone
+1F9D1 1F3FE 200D 2708 FE0F ; fully-qualified # 🧑🏾✈️ E12.1 pilot: medium-dark skin tone
+1F9D1 1F3FE 200D 2708 ; minimally-qualified # 🧑🏾✈ E12.1 pilot: medium-dark skin tone
+1F9D1 1F3FF 200D 2708 FE0F ; fully-qualified # 🧑🏿✈️ E12.1 pilot: dark skin tone
+1F9D1 1F3FF 200D 2708 ; minimally-qualified # 🧑🏿✈ E12.1 pilot: dark skin tone
+1F468 200D 2708 FE0F ; fully-qualified # 👨✈️ E4.0 man pilot
+1F468 200D 2708 ; minimally-qualified # 👨✈ E4.0 man pilot
+1F468 1F3FB 200D 2708 FE0F ; fully-qualified # 👨🏻✈️ E4.0 man pilot: light skin tone
+1F468 1F3FB 200D 2708 ; minimally-qualified # 👨🏻✈ E4.0 man pilot: light skin tone
+1F468 1F3FC 200D 2708 FE0F ; fully-qualified # 👨🏼✈️ E4.0 man pilot: medium-light skin tone
+1F468 1F3FC 200D 2708 ; minimally-qualified # 👨🏼✈ E4.0 man pilot: medium-light skin tone
+1F468 1F3FD 200D 2708 FE0F ; fully-qualified # 👨🏽✈️ E4.0 man pilot: medium skin tone
+1F468 1F3FD 200D 2708 ; minimally-qualified # 👨🏽✈ E4.0 man pilot: medium skin tone
+1F468 1F3FE 200D 2708 FE0F ; fully-qualified # 👨🏾✈️ E4.0 man pilot: medium-dark skin tone
+1F468 1F3FE 200D 2708 ; minimally-qualified # 👨🏾✈ E4.0 man pilot: medium-dark skin tone
+1F468 1F3FF 200D 2708 FE0F ; fully-qualified # 👨🏿✈️ E4.0 man pilot: dark skin tone
+1F468 1F3FF 200D 2708 ; minimally-qualified # 👨🏿✈ E4.0 man pilot: dark skin tone
+1F469 200D 2708 FE0F ; fully-qualified # 👩✈️ E4.0 woman pilot
+1F469 200D 2708 ; minimally-qualified # 👩✈ E4.0 woman pilot
+1F469 1F3FB 200D 2708 FE0F ; fully-qualified # 👩🏻✈️ E4.0 woman pilot: light skin tone
+1F469 1F3FB 200D 2708 ; minimally-qualified # 👩🏻✈ E4.0 woman pilot: light skin tone
+1F469 1F3FC 200D 2708 FE0F ; fully-qualified # 👩🏼✈️ E4.0 woman pilot: medium-light skin tone
+1F469 1F3FC 200D 2708 ; minimally-qualified # 👩🏼✈ E4.0 woman pilot: medium-light skin tone
+1F469 1F3FD 200D 2708 FE0F ; fully-qualified # 👩🏽✈️ E4.0 woman pilot: medium skin tone
+1F469 1F3FD 200D 2708 ; minimally-qualified # 👩🏽✈ E4.0 woman pilot: medium skin tone
+1F469 1F3FE 200D 2708 FE0F ; fully-qualified # 👩🏾✈️ E4.0 woman pilot: medium-dark skin tone
+1F469 1F3FE 200D 2708 ; minimally-qualified # 👩🏾✈ E4.0 woman pilot: medium-dark skin tone
+1F469 1F3FF 200D 2708 FE0F ; fully-qualified # 👩🏿✈️ E4.0 woman pilot: dark skin tone
+1F469 1F3FF 200D 2708 ; minimally-qualified # 👩🏿✈ E4.0 woman pilot: dark skin tone
+1F9D1 200D 1F680 ; fully-qualified # 🧑🚀 E12.1 astronaut
+1F9D1 1F3FB 200D 1F680 ; fully-qualified # 🧑🏻🚀 E12.1 astronaut: light skin tone
+1F9D1 1F3FC 200D 1F680 ; fully-qualified # 🧑🏼🚀 E12.1 astronaut: medium-light skin tone
+1F9D1 1F3FD 200D 1F680 ; fully-qualified # 🧑🏽🚀 E12.1 astronaut: medium skin tone
+1F9D1 1F3FE 200D 1F680 ; fully-qualified # 🧑🏾🚀 E12.1 astronaut: medium-dark skin tone
+1F9D1 1F3FF 200D 1F680 ; fully-qualified # 🧑🏿🚀 E12.1 astronaut: dark skin tone
+1F468 200D 1F680 ; fully-qualified # 👨🚀 E4.0 man astronaut
+1F468 1F3FB 200D 1F680 ; fully-qualified # 👨🏻🚀 E4.0 man astronaut: light skin tone
+1F468 1F3FC 200D 1F680 ; fully-qualified # 👨🏼🚀 E4.0 man astronaut: medium-light skin tone
+1F468 1F3FD 200D 1F680 ; fully-qualified # 👨🏽🚀 E4.0 man astronaut: medium skin tone
+1F468 1F3FE 200D 1F680 ; fully-qualified # 👨🏾🚀 E4.0 man astronaut: medium-dark skin tone
+1F468 1F3FF 200D 1F680 ; fully-qualified # 👨🏿🚀 E4.0 man astronaut: dark skin tone
+1F469 200D 1F680 ; fully-qualified # 👩🚀 E4.0 woman astronaut
+1F469 1F3FB 200D 1F680 ; fully-qualified # 👩🏻🚀 E4.0 woman astronaut: light skin tone
+1F469 1F3FC 200D 1F680 ; fully-qualified # 👩🏼🚀 E4.0 woman astronaut: medium-light skin tone
+1F469 1F3FD 200D 1F680 ; fully-qualified # 👩🏽🚀 E4.0 woman astronaut: medium skin tone
+1F469 1F3FE 200D 1F680 ; fully-qualified # 👩🏾🚀 E4.0 woman astronaut: medium-dark skin tone
+1F469 1F3FF 200D 1F680 ; fully-qualified # 👩🏿🚀 E4.0 woman astronaut: dark skin tone
+1F9D1 200D 1F692 ; fully-qualified # 🧑🚒 E12.1 firefighter
+1F9D1 1F3FB 200D 1F692 ; fully-qualified # 🧑🏻🚒 E12.1 firefighter: light skin tone
+1F9D1 1F3FC 200D 1F692 ; fully-qualified # 🧑🏼🚒 E12.1 firefighter: medium-light skin tone
+1F9D1 1F3FD 200D 1F692 ; fully-qualified # 🧑🏽🚒 E12.1 firefighter: medium skin tone
+1F9D1 1F3FE 200D 1F692 ; fully-qualified # 🧑🏾🚒 E12.1 firefighter: medium-dark skin tone
+1F9D1 1F3FF 200D 1F692 ; fully-qualified # 🧑🏿🚒 E12.1 firefighter: dark skin tone
+1F468 200D 1F692 ; fully-qualified # 👨🚒 E4.0 man firefighter
+1F468 1F3FB 200D 1F692 ; fully-qualified # 👨🏻🚒 E4.0 man firefighter: light skin tone
+1F468 1F3FC 200D 1F692 ; fully-qualified # 👨🏼🚒 E4.0 man firefighter: medium-light skin tone
+1F468 1F3FD 200D 1F692 ; fully-qualified # 👨🏽🚒 E4.0 man firefighter: medium skin tone
+1F468 1F3FE 200D 1F692 ; fully-qualified # 👨🏾🚒 E4.0 man firefighter: medium-dark skin tone
+1F468 1F3FF 200D 1F692 ; fully-qualified # 👨🏿🚒 E4.0 man firefighter: dark skin tone
+1F469 200D 1F692 ; fully-qualified # 👩🚒 E4.0 woman firefighter
+1F469 1F3FB 200D 1F692 ; fully-qualified # 👩🏻🚒 E4.0 woman firefighter: light skin tone
+1F469 1F3FC 200D 1F692 ; fully-qualified # 👩🏼🚒 E4.0 woman firefighter: medium-light skin tone
+1F469 1F3FD 200D 1F692 ; fully-qualified # 👩🏽🚒 E4.0 woman firefighter: medium skin tone
+1F469 1F3FE 200D 1F692 ; fully-qualified # 👩🏾🚒 E4.0 woman firefighter: medium-dark skin tone
+1F469 1F3FF 200D 1F692 ; fully-qualified # 👩🏿🚒 E4.0 woman firefighter: dark skin tone
+1F46E ; fully-qualified # 👮 E0.6 police officer
+1F46E 1F3FB ; fully-qualified # 👮🏻 E1.0 police officer: light skin tone
+1F46E 1F3FC ; fully-qualified # 👮🏼 E1.0 police officer: medium-light skin tone
+1F46E 1F3FD ; fully-qualified # 👮🏽 E1.0 police officer: medium skin tone
+1F46E 1F3FE ; fully-qualified # 👮🏾 E1.0 police officer: medium-dark skin tone
+1F46E 1F3FF ; fully-qualified # 👮🏿 E1.0 police officer: dark skin tone
+1F46E 200D 2642 FE0F ; fully-qualified # 👮♂️ E4.0 man police officer
+1F46E 200D 2642 ; minimally-qualified # 👮♂ E4.0 man police officer
+1F46E 1F3FB 200D 2642 FE0F ; fully-qualified # 👮🏻♂️ E4.0 man police officer: light skin tone
+1F46E 1F3FB 200D 2642 ; minimally-qualified # 👮🏻♂ E4.0 man police officer: light skin tone
+1F46E 1F3FC 200D 2642 FE0F ; fully-qualified # 👮🏼♂️ E4.0 man police officer: medium-light skin tone
+1F46E 1F3FC 200D 2642 ; minimally-qualified # 👮🏼♂ E4.0 man police officer: medium-light skin tone
+1F46E 1F3FD 200D 2642 FE0F ; fully-qualified # 👮🏽♂️ E4.0 man police officer: medium skin tone
+1F46E 1F3FD 200D 2642 ; minimally-qualified # 👮🏽♂ E4.0 man police officer: medium skin tone
+1F46E 1F3FE 200D 2642 FE0F ; fully-qualified # 👮🏾♂️ E4.0 man police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2642 ; minimally-qualified # 👮🏾♂ E4.0 man police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2642 FE0F ; fully-qualified # 👮🏿♂️ E4.0 man police officer: dark skin tone
+1F46E 1F3FF 200D 2642 ; minimally-qualified # 👮🏿♂ E4.0 man police officer: dark skin tone
+1F46E 200D 2640 FE0F ; fully-qualified # 👮♀️ E4.0 woman police officer
+1F46E 200D 2640 ; minimally-qualified # 👮♀ E4.0 woman police officer
+1F46E 1F3FB 200D 2640 FE0F ; fully-qualified # 👮🏻♀️ E4.0 woman police officer: light skin tone
+1F46E 1F3FB 200D 2640 ; minimally-qualified # 👮🏻♀ E4.0 woman police officer: light skin tone
+1F46E 1F3FC 200D 2640 FE0F ; fully-qualified # 👮🏼♀️ E4.0 woman police officer: medium-light skin tone
+1F46E 1F3FC 200D 2640 ; minimally-qualified # 👮🏼♀ E4.0 woman police officer: medium-light skin tone
+1F46E 1F3FD 200D 2640 FE0F ; fully-qualified # 👮🏽♀️ E4.0 woman police officer: medium skin tone
+1F46E 1F3FD 200D 2640 ; minimally-qualified # 👮🏽♀ E4.0 woman police officer: medium skin tone
+1F46E 1F3FE 200D 2640 FE0F ; fully-qualified # 👮🏾♀️ E4.0 woman police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2640 ; minimally-qualified # 👮🏾♀ E4.0 woman police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2640 FE0F ; fully-qualified # 👮🏿♀️ E4.0 woman police officer: dark skin tone
+1F46E 1F3FF 200D 2640 ; minimally-qualified # 👮🏿♀ E4.0 woman police officer: dark skin tone
+1F575 FE0F ; fully-qualified # 🕵️ E0.7 detective
+1F575 ; unqualified # 🕵 E0.7 detective
+1F575 1F3FB ; fully-qualified # 🕵🏻 E2.0 detective: light skin tone
+1F575 1F3FC ; fully-qualified # 🕵🏼 E2.0 detective: medium-light skin tone
+1F575 1F3FD ; fully-qualified # 🕵🏽 E2.0 detective: medium skin tone
+1F575 1F3FE ; fully-qualified # 🕵🏾 E2.0 detective: medium-dark skin tone
+1F575 1F3FF ; fully-qualified # 🕵🏿 E2.0 detective: dark skin tone
+1F575 FE0F 200D 2642 FE0F ; fully-qualified # 🕵️♂️ E4.0 man detective
+1F575 200D 2642 FE0F ; unqualified # 🕵♂️ E4.0 man detective
+1F575 FE0F 200D 2642 ; unqualified # 🕵️♂ E4.0 man detective
+1F575 200D 2642 ; unqualified # 🕵♂ E4.0 man detective
+1F575 1F3FB 200D 2642 FE0F ; fully-qualified # 🕵🏻♂️ E4.0 man detective: light skin tone
+1F575 1F3FB 200D 2642 ; minimally-qualified # 🕵🏻♂ E4.0 man detective: light skin tone
+1F575 1F3FC 200D 2642 FE0F ; fully-qualified # 🕵🏼♂️ E4.0 man detective: medium-light skin tone
+1F575 1F3FC 200D 2642 ; minimally-qualified # 🕵🏼♂ E4.0 man detective: medium-light skin tone
+1F575 1F3FD 200D 2642 FE0F ; fully-qualified # 🕵🏽♂️ E4.0 man detective: medium skin tone
+1F575 1F3FD 200D 2642 ; minimally-qualified # 🕵🏽♂ E4.0 man detective: medium skin tone
+1F575 1F3FE 200D 2642 FE0F ; fully-qualified # 🕵🏾♂️ E4.0 man detective: medium-dark skin tone
+1F575 1F3FE 200D 2642 ; minimally-qualified # 🕵🏾♂ E4.0 man detective: medium-dark skin tone
+1F575 1F3FF 200D 2642 FE0F ; fully-qualified # 🕵🏿♂️ E4.0 man detective: dark skin tone
+1F575 1F3FF 200D 2642 ; minimally-qualified # 🕵🏿♂ E4.0 man detective: dark skin tone
+1F575 FE0F 200D 2640 FE0F ; fully-qualified # 🕵️♀️ E4.0 woman detective
+1F575 200D 2640 FE0F ; unqualified # 🕵♀️ E4.0 woman detective
+1F575 FE0F 200D 2640 ; unqualified # 🕵️♀ E4.0 woman detective
+1F575 200D 2640 ; unqualified # 🕵♀ E4.0 woman detective
+1F575 1F3FB 200D 2640 FE0F ; fully-qualified # 🕵🏻♀️ E4.0 woman detective: light skin tone
+1F575 1F3FB 200D 2640 ; minimally-qualified # 🕵🏻♀ E4.0 woman detective: light skin tone
+1F575 1F3FC 200D 2640 FE0F ; fully-qualified # 🕵🏼♀️ E4.0 woman detective: medium-light skin tone
+1F575 1F3FC 200D 2640 ; minimally-qualified # 🕵🏼♀ E4.0 woman detective: medium-light skin tone
+1F575 1F3FD 200D 2640 FE0F ; fully-qualified # 🕵🏽♀️ E4.0 woman detective: medium skin tone
+1F575 1F3FD 200D 2640 ; minimally-qualified # 🕵🏽♀ E4.0 woman detective: medium skin tone
+1F575 1F3FE 200D 2640 FE0F ; fully-qualified # 🕵🏾♀️ E4.0 woman detective: medium-dark skin tone
+1F575 1F3FE 200D 2640 ; minimally-qualified # 🕵🏾♀ E4.0 woman detective: medium-dark skin tone
+1F575 1F3FF 200D 2640 FE0F ; fully-qualified # 🕵🏿♀️ E4.0 woman detective: dark skin tone
+1F575 1F3FF 200D 2640 ; minimally-qualified # 🕵🏿♀ E4.0 woman detective: dark skin tone
+1F482 ; fully-qualified # 💂 E0.6 guard
+1F482 1F3FB ; fully-qualified # 💂🏻 E1.0 guard: light skin tone
+1F482 1F3FC ; fully-qualified # 💂🏼 E1.0 guard: medium-light skin tone
+1F482 1F3FD ; fully-qualified # 💂🏽 E1.0 guard: medium skin tone
+1F482 1F3FE ; fully-qualified # 💂🏾 E1.0 guard: medium-dark skin tone
+1F482 1F3FF ; fully-qualified # 💂🏿 E1.0 guard: dark skin tone
+1F482 200D 2642 FE0F ; fully-qualified # 💂♂️ E4.0 man guard
+1F482 200D 2642 ; minimally-qualified # 💂♂ E4.0 man guard
+1F482 1F3FB 200D 2642 FE0F ; fully-qualified # 💂🏻♂️ E4.0 man guard: light skin tone
+1F482 1F3FB 200D 2642 ; minimally-qualified # 💂🏻♂ E4.0 man guard: light skin tone
+1F482 1F3FC 200D 2642 FE0F ; fully-qualified # 💂🏼♂️ E4.0 man guard: medium-light skin tone
+1F482 1F3FC 200D 2642 ; minimally-qualified # 💂🏼♂ E4.0 man guard: medium-light skin tone
+1F482 1F3FD 200D 2642 FE0F ; fully-qualified # 💂🏽♂️ E4.0 man guard: medium skin tone
+1F482 1F3FD 200D 2642 ; minimally-qualified # 💂🏽♂ E4.0 man guard: medium skin tone
+1F482 1F3FE 200D 2642 FE0F ; fully-qualified # 💂🏾♂️ E4.0 man guard: medium-dark skin tone
+1F482 1F3FE 200D 2642 ; minimally-qualified # 💂🏾♂ E4.0 man guard: medium-dark skin tone
+1F482 1F3FF 200D 2642 FE0F ; fully-qualified # 💂🏿♂️ E4.0 man guard: dark skin tone
+1F482 1F3FF 200D 2642 ; minimally-qualified # 💂🏿♂ E4.0 man guard: dark skin tone
+1F482 200D 2640 FE0F ; fully-qualified # 💂♀️ E4.0 woman guard
+1F482 200D 2640 ; minimally-qualified # 💂♀ E4.0 woman guard
+1F482 1F3FB 200D 2640 FE0F ; fully-qualified # 💂🏻♀️ E4.0 woman guard: light skin tone
+1F482 1F3FB 200D 2640 ; minimally-qualified # 💂🏻♀ E4.0 woman guard: light skin tone
+1F482 1F3FC 200D 2640 FE0F ; fully-qualified # 💂🏼♀️ E4.0 woman guard: medium-light skin tone
+1F482 1F3FC 200D 2640 ; minimally-qualified # 💂🏼♀ E4.0 woman guard: medium-light skin tone
+1F482 1F3FD 200D 2640 FE0F ; fully-qualified # 💂🏽♀️ E4.0 woman guard: medium skin tone
+1F482 1F3FD 200D 2640 ; minimally-qualified # 💂🏽♀ E4.0 woman guard: medium skin tone
+1F482 1F3FE 200D 2640 FE0F ; fully-qualified # 💂🏾♀️ E4.0 woman guard: medium-dark skin tone
+1F482 1F3FE 200D 2640 ; minimally-qualified # 💂🏾♀ E4.0 woman guard: medium-dark skin tone
+1F482 1F3FF 200D 2640 FE0F ; fully-qualified # 💂🏿♀️ E4.0 woman guard: dark skin tone
+1F482 1F3FF 200D 2640 ; minimally-qualified # 💂🏿♀ E4.0 woman guard: dark skin tone
+1F977 ; fully-qualified # 🥷 E13.0 ninja
+1F977 1F3FB ; fully-qualified # 🥷🏻 E13.0 ninja: light skin tone
+1F977 1F3FC ; fully-qualified # 🥷🏼 E13.0 ninja: medium-light skin tone
+1F977 1F3FD ; fully-qualified # 🥷🏽 E13.0 ninja: medium skin tone
+1F977 1F3FE ; fully-qualified # 🥷🏾 E13.0 ninja: medium-dark skin tone
+1F977 1F3FF ; fully-qualified # 🥷🏿 E13.0 ninja: dark skin tone
+1F477 ; fully-qualified # 👷 E0.6 construction worker
+1F477 1F3FB ; fully-qualified # 👷🏻 E1.0 construction worker: light skin tone
+1F477 1F3FC ; fully-qualified # 👷🏼 E1.0 construction worker: medium-light skin tone
+1F477 1F3FD ; fully-qualified # 👷🏽 E1.0 construction worker: medium skin tone
+1F477 1F3FE ; fully-qualified # 👷🏾 E1.0 construction worker: medium-dark skin tone
+1F477 1F3FF ; fully-qualified # 👷🏿 E1.0 construction worker: dark skin tone
+1F477 200D 2642 FE0F ; fully-qualified # 👷♂️ E4.0 man construction worker
+1F477 200D 2642 ; minimally-qualified # 👷♂ E4.0 man construction worker
+1F477 1F3FB 200D 2642 FE0F ; fully-qualified # 👷🏻♂️ E4.0 man construction worker: light skin tone
+1F477 1F3FB 200D 2642 ; minimally-qualified # 👷🏻♂ E4.0 man construction worker: light skin tone
+1F477 1F3FC 200D 2642 FE0F ; fully-qualified # 👷🏼♂️ E4.0 man construction worker: medium-light skin tone
+1F477 1F3FC 200D 2642 ; minimally-qualified # 👷🏼♂ E4.0 man construction worker: medium-light skin tone
+1F477 1F3FD 200D 2642 FE0F ; fully-qualified # 👷🏽♂️ E4.0 man construction worker: medium skin tone
+1F477 1F3FD 200D 2642 ; minimally-qualified # 👷🏽♂ E4.0 man construction worker: medium skin tone
+1F477 1F3FE 200D 2642 FE0F ; fully-qualified # 👷🏾♂️ E4.0 man construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2642 ; minimally-qualified # 👷🏾♂ E4.0 man construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2642 FE0F ; fully-qualified # 👷🏿♂️ E4.0 man construction worker: dark skin tone
+1F477 1F3FF 200D 2642 ; minimally-qualified # 👷🏿♂ E4.0 man construction worker: dark skin tone
+1F477 200D 2640 FE0F ; fully-qualified # 👷♀️ E4.0 woman construction worker
+1F477 200D 2640 ; minimally-qualified # 👷♀ E4.0 woman construction worker
+1F477 1F3FB 200D 2640 FE0F ; fully-qualified # 👷🏻♀️ E4.0 woman construction worker: light skin tone
+1F477 1F3FB 200D 2640 ; minimally-qualified # 👷🏻♀ E4.0 woman construction worker: light skin tone
+1F477 1F3FC 200D 2640 FE0F ; fully-qualified # 👷🏼♀️ E4.0 woman construction worker: medium-light skin tone
+1F477 1F3FC 200D 2640 ; minimally-qualified # 👷🏼♀ E4.0 woman construction worker: medium-light skin tone
+1F477 1F3FD 200D 2640 FE0F ; fully-qualified # 👷🏽♀️ E4.0 woman construction worker: medium skin tone
+1F477 1F3FD 200D 2640 ; minimally-qualified # 👷🏽♀ E4.0 woman construction worker: medium skin tone
+1F477 1F3FE 200D 2640 FE0F ; fully-qualified # 👷🏾♀️ E4.0 woman construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2640 ; minimally-qualified # 👷🏾♀ E4.0 woman construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2640 FE0F ; fully-qualified # 👷🏿♀️ E4.0 woman construction worker: dark skin tone
+1F477 1F3FF 200D 2640 ; minimally-qualified # 👷🏿♀ E4.0 woman construction worker: dark skin tone
+1F934 ; fully-qualified # 🤴 E3.0 prince
+1F934 1F3FB ; fully-qualified # 🤴🏻 E3.0 prince: light skin tone
+1F934 1F3FC ; fully-qualified # 🤴🏼 E3.0 prince: medium-light skin tone
+1F934 1F3FD ; fully-qualified # 🤴🏽 E3.0 prince: medium skin tone
+1F934 1F3FE ; fully-qualified # 🤴🏾 E3.0 prince: medium-dark skin tone
+1F934 1F3FF ; fully-qualified # 🤴🏿 E3.0 prince: dark skin tone
+1F478 ; fully-qualified # 👸 E0.6 princess
+1F478 1F3FB ; fully-qualified # 👸🏻 E1.0 princess: light skin tone
+1F478 1F3FC ; fully-qualified # 👸🏼 E1.0 princess: medium-light skin tone
+1F478 1F3FD ; fully-qualified # 👸🏽 E1.0 princess: medium skin tone
+1F478 1F3FE ; fully-qualified # 👸🏾 E1.0 princess: medium-dark skin tone
+1F478 1F3FF ; fully-qualified # 👸🏿 E1.0 princess: dark skin tone
+1F473 ; fully-qualified # 👳 E0.6 person wearing turban
+1F473 1F3FB ; fully-qualified # 👳🏻 E1.0 person wearing turban: light skin tone
+1F473 1F3FC ; fully-qualified # 👳🏼 E1.0 person wearing turban: medium-light skin tone
+1F473 1F3FD ; fully-qualified # 👳🏽 E1.0 person wearing turban: medium skin tone
+1F473 1F3FE ; fully-qualified # 👳🏾 E1.0 person wearing turban: medium-dark skin tone
+1F473 1F3FF ; fully-qualified # 👳🏿 E1.0 person wearing turban: dark skin tone
+1F473 200D 2642 FE0F ; fully-qualified # 👳♂️ E4.0 man wearing turban
+1F473 200D 2642 ; minimally-qualified # 👳♂ E4.0 man wearing turban
+1F473 1F3FB 200D 2642 FE0F ; fully-qualified # 👳🏻♂️ E4.0 man wearing turban: light skin tone
+1F473 1F3FB 200D 2642 ; minimally-qualified # 👳🏻♂ E4.0 man wearing turban: light skin tone
+1F473 1F3FC 200D 2642 FE0F ; fully-qualified # 👳🏼♂️ E4.0 man wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2642 ; minimally-qualified # 👳🏼♂ E4.0 man wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2642 FE0F ; fully-qualified # 👳🏽♂️ E4.0 man wearing turban: medium skin tone
+1F473 1F3FD 200D 2642 ; minimally-qualified # 👳🏽♂ E4.0 man wearing turban: medium skin tone
+1F473 1F3FE 200D 2642 FE0F ; fully-qualified # 👳🏾♂️ E4.0 man wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2642 ; minimally-qualified # 👳🏾♂ E4.0 man wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2642 FE0F ; fully-qualified # 👳🏿♂️ E4.0 man wearing turban: dark skin tone
+1F473 1F3FF 200D 2642 ; minimally-qualified # 👳🏿♂ E4.0 man wearing turban: dark skin tone
+1F473 200D 2640 FE0F ; fully-qualified # 👳♀️ E4.0 woman wearing turban
+1F473 200D 2640 ; minimally-qualified # 👳♀ E4.0 woman wearing turban
+1F473 1F3FB 200D 2640 FE0F ; fully-qualified # 👳🏻♀️ E4.0 woman wearing turban: light skin tone
+1F473 1F3FB 200D 2640 ; minimally-qualified # 👳🏻♀ E4.0 woman wearing turban: light skin tone
+1F473 1F3FC 200D 2640 FE0F ; fully-qualified # 👳🏼♀️ E4.0 woman wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2640 ; minimally-qualified # 👳🏼♀ E4.0 woman wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2640 FE0F ; fully-qualified # 👳🏽♀️ E4.0 woman wearing turban: medium skin tone
+1F473 1F3FD 200D 2640 ; minimally-qualified # 👳🏽♀ E4.0 woman wearing turban: medium skin tone
+1F473 1F3FE 200D 2640 FE0F ; fully-qualified # 👳🏾♀️ E4.0 woman wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2640 ; minimally-qualified # 👳🏾♀ E4.0 woman wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2640 FE0F ; fully-qualified # 👳🏿♀️ E4.0 woman wearing turban: dark skin tone
+1F473 1F3FF 200D 2640 ; minimally-qualified # 👳🏿♀ E4.0 woman wearing turban: dark skin tone
+1F472 ; fully-qualified # 👲 E0.6 person with skullcap
+1F472 1F3FB ; fully-qualified # 👲🏻 E1.0 person with skullcap: light skin tone
+1F472 1F3FC ; fully-qualified # 👲🏼 E1.0 person with skullcap: medium-light skin tone
+1F472 1F3FD ; fully-qualified # 👲🏽 E1.0 person with skullcap: medium skin tone
+1F472 1F3FE ; fully-qualified # 👲🏾 E1.0 person with skullcap: medium-dark skin tone
+1F472 1F3FF ; fully-qualified # 👲🏿 E1.0 person with skullcap: dark skin tone
+1F9D5 ; fully-qualified # 🧕 E5.0 woman with headscarf
+1F9D5 1F3FB ; fully-qualified # 🧕🏻 E5.0 woman with headscarf: light skin tone
+1F9D5 1F3FC ; fully-qualified # 🧕🏼 E5.0 woman with headscarf: medium-light skin tone
+1F9D5 1F3FD ; fully-qualified # 🧕🏽 E5.0 woman with headscarf: medium skin tone
+1F9D5 1F3FE ; fully-qualified # 🧕🏾 E5.0 woman with headscarf: medium-dark skin tone
+1F9D5 1F3FF ; fully-qualified # 🧕🏿 E5.0 woman with headscarf: dark skin tone
+1F935 ; fully-qualified # 🤵 E3.0 person in tuxedo
+1F935 1F3FB ; fully-qualified # 🤵🏻 E3.0 person in tuxedo: light skin tone
+1F935 1F3FC ; fully-qualified # 🤵🏼 E3.0 person in tuxedo: medium-light skin tone
+1F935 1F3FD ; fully-qualified # 🤵🏽 E3.0 person in tuxedo: medium skin tone
+1F935 1F3FE ; fully-qualified # 🤵🏾 E3.0 person in tuxedo: medium-dark skin tone
+1F935 1F3FF ; fully-qualified # 🤵🏿 E3.0 person in tuxedo: dark skin tone
+1F935 200D 2642 FE0F ; fully-qualified # 🤵♂️ E13.0 man in tuxedo
+1F935 200D 2642 ; minimally-qualified # 🤵♂ E13.0 man in tuxedo
+1F935 1F3FB 200D 2642 FE0F ; fully-qualified # 🤵🏻♂️ E13.0 man in tuxedo: light skin tone
+1F935 1F3FB 200D 2642 ; minimally-qualified # 🤵🏻♂ E13.0 man in tuxedo: light skin tone
+1F935 1F3FC 200D 2642 FE0F ; fully-qualified # 🤵🏼♂️ E13.0 man in tuxedo: medium-light skin tone
+1F935 1F3FC 200D 2642 ; minimally-qualified # 🤵🏼♂ E13.0 man in tuxedo: medium-light skin tone
+1F935 1F3FD 200D 2642 FE0F ; fully-qualified # 🤵🏽♂️ E13.0 man in tuxedo: medium skin tone
+1F935 1F3FD 200D 2642 ; minimally-qualified # 🤵🏽♂ E13.0 man in tuxedo: medium skin tone
+1F935 1F3FE 200D 2642 FE0F ; fully-qualified # 🤵🏾♂️ E13.0 man in tuxedo: medium-dark skin tone
+1F935 1F3FE 200D 2642 ; minimally-qualified # 🤵🏾♂ E13.0 man in tuxedo: medium-dark skin tone
+1F935 1F3FF 200D 2642 FE0F ; fully-qualified # 🤵🏿♂️ E13.0 man in tuxedo: dark skin tone
+1F935 1F3FF 200D 2642 ; minimally-qualified # 🤵🏿♂ E13.0 man in tuxedo: dark skin tone
+1F935 200D 2640 FE0F ; fully-qualified # 🤵♀️ E13.0 woman in tuxedo
+1F935 200D 2640 ; minimally-qualified # 🤵♀ E13.0 woman in tuxedo
+1F935 1F3FB 200D 2640 FE0F ; fully-qualified # 🤵🏻♀️ E13.0 woman in tuxedo: light skin tone
+1F935 1F3FB 200D 2640 ; minimally-qualified # 🤵🏻♀ E13.0 woman in tuxedo: light skin tone
+1F935 1F3FC 200D 2640 FE0F ; fully-qualified # 🤵🏼♀️ E13.0 woman in tuxedo: medium-light skin tone
+1F935 1F3FC 200D 2640 ; minimally-qualified # 🤵🏼♀ E13.0 woman in tuxedo: medium-light skin tone
+1F935 1F3FD 200D 2640 FE0F ; fully-qualified # 🤵🏽♀️ E13.0 woman in tuxedo: medium skin tone
+1F935 1F3FD 200D 2640 ; minimally-qualified # 🤵🏽♀ E13.0 woman in tuxedo: medium skin tone
+1F935 1F3FE 200D 2640 FE0F ; fully-qualified # 🤵🏾♀️ E13.0 woman in tuxedo: medium-dark skin tone
+1F935 1F3FE 200D 2640 ; minimally-qualified # 🤵🏾♀ E13.0 woman in tuxedo: medium-dark skin tone
+1F935 1F3FF 200D 2640 FE0F ; fully-qualified # 🤵🏿♀️ E13.0 woman in tuxedo: dark skin tone
+1F935 1F3FF 200D 2640 ; minimally-qualified # 🤵🏿♀ E13.0 woman in tuxedo: dark skin tone
+1F470 ; fully-qualified # 👰 E0.6 person with veil
+1F470 1F3FB ; fully-qualified # 👰🏻 E1.0 person with veil: light skin tone
+1F470 1F3FC ; fully-qualified # 👰🏼 E1.0 person with veil: medium-light skin tone
+1F470 1F3FD ; fully-qualified # 👰🏽 E1.0 person with veil: medium skin tone
+1F470 1F3FE ; fully-qualified # 👰🏾 E1.0 person with veil: medium-dark skin tone
+1F470 1F3FF ; fully-qualified # 👰🏿 E1.0 person with veil: dark skin tone
+1F470 200D 2642 FE0F ; fully-qualified # 👰♂️ E13.0 man with veil
+1F470 200D 2642 ; minimally-qualified # 👰♂ E13.0 man with veil
+1F470 1F3FB 200D 2642 FE0F ; fully-qualified # 👰🏻♂️ E13.0 man with veil: light skin tone
+1F470 1F3FB 200D 2642 ; minimally-qualified # 👰🏻♂ E13.0 man with veil: light skin tone
+1F470 1F3FC 200D 2642 FE0F ; fully-qualified # 👰🏼♂️ E13.0 man with veil: medium-light skin tone
+1F470 1F3FC 200D 2642 ; minimally-qualified # 👰🏼♂ E13.0 man with veil: medium-light skin tone
+1F470 1F3FD 200D 2642 FE0F ; fully-qualified # 👰🏽♂️ E13.0 man with veil: medium skin tone
+1F470 1F3FD 200D 2642 ; minimally-qualified # 👰🏽♂ E13.0 man with veil: medium skin tone
+1F470 1F3FE 200D 2642 FE0F ; fully-qualified # 👰🏾♂️ E13.0 man with veil: medium-dark skin tone
+1F470 1F3FE 200D 2642 ; minimally-qualified # 👰🏾♂ E13.0 man with veil: medium-dark skin tone
+1F470 1F3FF 200D 2642 FE0F ; fully-qualified # 👰🏿♂️ E13.0 man with veil: dark skin tone
+1F470 1F3FF 200D 2642 ; minimally-qualified # 👰🏿♂ E13.0 man with veil: dark skin tone
+1F470 200D 2640 FE0F ; fully-qualified # 👰♀️ E13.0 woman with veil
+1F470 200D 2640 ; minimally-qualified # 👰♀ E13.0 woman with veil
+1F470 1F3FB 200D 2640 FE0F ; fully-qualified # 👰🏻♀️ E13.0 woman with veil: light skin tone
+1F470 1F3FB 200D 2640 ; minimally-qualified # 👰🏻♀ E13.0 woman with veil: light skin tone
+1F470 1F3FC 200D 2640 FE0F ; fully-qualified # 👰🏼♀️ E13.0 woman with veil: medium-light skin tone
+1F470 1F3FC 200D 2640 ; minimally-qualified # 👰🏼♀ E13.0 woman with veil: medium-light skin tone
+1F470 1F3FD 200D 2640 FE0F ; fully-qualified # 👰🏽♀️ E13.0 woman with veil: medium skin tone
+1F470 1F3FD 200D 2640 ; minimally-qualified # 👰🏽♀ E13.0 woman with veil: medium skin tone
+1F470 1F3FE 200D 2640 FE0F ; fully-qualified # 👰🏾♀️ E13.0 woman with veil: medium-dark skin tone
+1F470 1F3FE 200D 2640 ; minimally-qualified # 👰🏾♀ E13.0 woman with veil: medium-dark skin tone
+1F470 1F3FF 200D 2640 FE0F ; fully-qualified # 👰🏿♀️ E13.0 woman with veil: dark skin tone
+1F470 1F3FF 200D 2640 ; minimally-qualified # 👰🏿♀ E13.0 woman with veil: dark skin tone
+1F930 ; fully-qualified # 🤰 E3.0 pregnant woman
+1F930 1F3FB ; fully-qualified # 🤰🏻 E3.0 pregnant woman: light skin tone
+1F930 1F3FC ; fully-qualified # 🤰🏼 E3.0 pregnant woman: medium-light skin tone
+1F930 1F3FD ; fully-qualified # 🤰🏽 E3.0 pregnant woman: medium skin tone
+1F930 1F3FE ; fully-qualified # 🤰🏾 E3.0 pregnant woman: medium-dark skin tone
+1F930 1F3FF ; fully-qualified # 🤰🏿 E3.0 pregnant woman: dark skin tone
+1F931 ; fully-qualified # 🤱 E5.0 breast-feeding
+1F931 1F3FB ; fully-qualified # 🤱🏻 E5.0 breast-feeding: light skin tone
+1F931 1F3FC ; fully-qualified # 🤱🏼 E5.0 breast-feeding: medium-light skin tone
+1F931 1F3FD ; fully-qualified # 🤱🏽 E5.0 breast-feeding: medium skin tone
+1F931 1F3FE ; fully-qualified # 🤱🏾 E5.0 breast-feeding: medium-dark skin tone
+1F931 1F3FF ; fully-qualified # 🤱🏿 E5.0 breast-feeding: dark skin tone
+1F469 200D 1F37C ; fully-qualified # 👩🍼 E13.0 woman feeding baby
+1F469 1F3FB 200D 1F37C ; fully-qualified # 👩🏻🍼 E13.0 woman feeding baby: light skin tone
+1F469 1F3FC 200D 1F37C ; fully-qualified # 👩🏼🍼 E13.0 woman feeding baby: medium-light skin tone
+1F469 1F3FD 200D 1F37C ; fully-qualified # 👩🏽🍼 E13.0 woman feeding baby: medium skin tone
+1F469 1F3FE 200D 1F37C ; fully-qualified # 👩🏾🍼 E13.0 woman feeding baby: medium-dark skin tone
+1F469 1F3FF 200D 1F37C ; fully-qualified # 👩🏿🍼 E13.0 woman feeding baby: dark skin tone
+1F468 200D 1F37C ; fully-qualified # 👨🍼 E13.0 man feeding baby
+1F468 1F3FB 200D 1F37C ; fully-qualified # 👨🏻🍼 E13.0 man feeding baby: light skin tone
+1F468 1F3FC 200D 1F37C ; fully-qualified # 👨🏼🍼 E13.0 man feeding baby: medium-light skin tone
+1F468 1F3FD 200D 1F37C ; fully-qualified # 👨🏽🍼 E13.0 man feeding baby: medium skin tone
+1F468 1F3FE 200D 1F37C ; fully-qualified # 👨🏾🍼 E13.0 man feeding baby: medium-dark skin tone
+1F468 1F3FF 200D 1F37C ; fully-qualified # 👨🏿🍼 E13.0 man feeding baby: dark skin tone
+1F9D1 200D 1F37C ; fully-qualified # 🧑🍼 E13.0 person feeding baby
+1F9D1 1F3FB 200D 1F37C ; fully-qualified # 🧑🏻🍼 E13.0 person feeding baby: light skin tone
+1F9D1 1F3FC 200D 1F37C ; fully-qualified # 🧑🏼🍼 E13.0 person feeding baby: medium-light skin tone
+1F9D1 1F3FD 200D 1F37C ; fully-qualified # 🧑🏽🍼 E13.0 person feeding baby: medium skin tone
+1F9D1 1F3FE 200D 1F37C ; fully-qualified # 🧑🏾🍼 E13.0 person feeding baby: medium-dark skin tone
+1F9D1 1F3FF 200D 1F37C ; fully-qualified # 🧑🏿🍼 E13.0 person feeding baby: dark skin tone
# subgroup: person-fantasy
-1F47C ; fully-qualified # 👼 E0.6 baby angel
-1F47C 1F3FB ; fully-qualified # 👼🏻 E1.0 baby angel: light skin tone
-1F47C 1F3FC ; fully-qualified # 👼🏼 E1.0 baby angel: medium-light skin tone
-1F47C 1F3FD ; fully-qualified # 👼🏽 E1.0 baby angel: medium skin tone
-1F47C 1F3FE ; fully-qualified # 👼🏾 E1.0 baby angel: medium-dark skin tone
-1F47C 1F3FF ; fully-qualified # 👼🏿 E1.0 baby angel: dark skin tone
-1F385 ; fully-qualified # 🎅 E0.6 Santa Claus
-1F385 1F3FB ; fully-qualified # 🎅🏻 E1.0 Santa Claus: light skin tone
-1F385 1F3FC ; fully-qualified # 🎅🏼 E1.0 Santa Claus: medium-light skin tone
-1F385 1F3FD ; fully-qualified # 🎅🏽 E1.0 Santa Claus: medium skin tone
-1F385 1F3FE ; fully-qualified # 🎅🏾 E1.0 Santa Claus: medium-dark skin tone
-1F385 1F3FF ; fully-qualified # 🎅🏿 E1.0 Santa Claus: dark skin tone
-1F936 ; fully-qualified # 🤶 E3.0 Mrs. Claus
-1F936 1F3FB ; fully-qualified # 🤶🏻 E3.0 Mrs. Claus: light skin tone
-1F936 1F3FC ; fully-qualified # 🤶🏼 E3.0 Mrs. Claus: medium-light skin tone
-1F936 1F3FD ; fully-qualified # 🤶🏽 E3.0 Mrs. Claus: medium skin tone
-1F936 1F3FE ; fully-qualified # 🤶🏾 E3.0 Mrs. Claus: medium-dark skin tone
-1F936 1F3FF ; fully-qualified # 🤶🏿 E3.0 Mrs. Claus: dark skin tone
-1F9D1 200D 1F384 ; fully-qualified # 🧑🎄 E13.0 mx claus
-1F9D1 1F3FB 200D 1F384 ; fully-qualified # 🧑🏻🎄 E13.0 mx claus: light skin tone
-1F9D1 1F3FC 200D 1F384 ; fully-qualified # 🧑🏼🎄 E13.0 mx claus: medium-light skin tone
-1F9D1 1F3FD 200D 1F384 ; fully-qualified # 🧑🏽🎄 E13.0 mx claus: medium skin tone
-1F9D1 1F3FE 200D 1F384 ; fully-qualified # 🧑🏾🎄 E13.0 mx claus: medium-dark skin tone
-1F9D1 1F3FF 200D 1F384 ; fully-qualified # 🧑🏿🎄 E13.0 mx claus: dark skin tone
-1F9B8 ; fully-qualified # 🦸 E11.0 superhero
-1F9B8 1F3FB ; fully-qualified # 🦸🏻 E11.0 superhero: light skin tone
-1F9B8 1F3FC ; fully-qualified # 🦸🏼 E11.0 superhero: medium-light skin tone
-1F9B8 1F3FD ; fully-qualified # 🦸🏽 E11.0 superhero: medium skin tone
-1F9B8 1F3FE ; fully-qualified # 🦸🏾 E11.0 superhero: medium-dark skin tone
-1F9B8 1F3FF ; fully-qualified # 🦸🏿 E11.0 superhero: dark skin tone
-1F9B8 200D 2642 FE0F ; fully-qualified # 🦸♂️ E11.0 man superhero
-1F9B8 200D 2642 ; minimally-qualified # 🦸♂ E11.0 man superhero
-1F9B8 1F3FB 200D 2642 FE0F ; fully-qualified # 🦸🏻♂️ E11.0 man superhero: light skin tone
-1F9B8 1F3FB 200D 2642 ; minimally-qualified # 🦸🏻♂ E11.0 man superhero: light skin tone
-1F9B8 1F3FC 200D 2642 FE0F ; fully-qualified # 🦸🏼♂️ E11.0 man superhero: medium-light skin tone
-1F9B8 1F3FC 200D 2642 ; minimally-qualified # 🦸🏼♂ E11.0 man superhero: medium-light skin tone
-1F9B8 1F3FD 200D 2642 FE0F ; fully-qualified # 🦸🏽♂️ E11.0 man superhero: medium skin tone
-1F9B8 1F3FD 200D 2642 ; minimally-qualified # 🦸🏽♂ E11.0 man superhero: medium skin tone
-1F9B8 1F3FE 200D 2642 FE0F ; fully-qualified # 🦸🏾♂️ E11.0 man superhero: medium-dark skin tone
-1F9B8 1F3FE 200D 2642 ; minimally-qualified # 🦸🏾♂ E11.0 man superhero: medium-dark skin tone
-1F9B8 1F3FF 200D 2642 FE0F ; fully-qualified # 🦸🏿♂️ E11.0 man superhero: dark skin tone
-1F9B8 1F3FF 200D 2642 ; minimally-qualified # 🦸🏿♂ E11.0 man superhero: dark skin tone
-1F9B8 200D 2640 FE0F ; fully-qualified # 🦸♀️ E11.0 woman superhero
-1F9B8 200D 2640 ; minimally-qualified # 🦸♀ E11.0 woman superhero
-1F9B8 1F3FB 200D 2640 FE0F ; fully-qualified # 🦸🏻♀️ E11.0 woman superhero: light skin tone
-1F9B8 1F3FB 200D 2640 ; minimally-qualified # 🦸🏻♀ E11.0 woman superhero: light skin tone
-1F9B8 1F3FC 200D 2640 FE0F ; fully-qualified # 🦸🏼♀️ E11.0 woman superhero: medium-light skin tone
-1F9B8 1F3FC 200D 2640 ; minimally-qualified # 🦸🏼♀ E11.0 woman superhero: medium-light skin tone
-1F9B8 1F3FD 200D 2640 FE0F ; fully-qualified # 🦸🏽♀️ E11.0 woman superhero: medium skin tone
-1F9B8 1F3FD 200D 2640 ; minimally-qualified # 🦸🏽♀ E11.0 woman superhero: medium skin tone
-1F9B8 1F3FE 200D 2640 FE0F ; fully-qualified # 🦸🏾♀️ E11.0 woman superhero: medium-dark skin tone
-1F9B8 1F3FE 200D 2640 ; minimally-qualified # 🦸🏾♀ E11.0 woman superhero: medium-dark skin tone
-1F9B8 1F3FF 200D 2640 FE0F ; fully-qualified # 🦸🏿♀️ E11.0 woman superhero: dark skin tone
-1F9B8 1F3FF 200D 2640 ; minimally-qualified # 🦸🏿♀ E11.0 woman superhero: dark skin tone
-1F9B9 ; fully-qualified # 🦹 E11.0 supervillain
-1F9B9 1F3FB ; fully-qualified # 🦹🏻 E11.0 supervillain: light skin tone
-1F9B9 1F3FC ; fully-qualified # 🦹🏼 E11.0 supervillain: medium-light skin tone
-1F9B9 1F3FD ; fully-qualified # 🦹🏽 E11.0 supervillain: medium skin tone
-1F9B9 1F3FE ; fully-qualified # 🦹🏾 E11.0 supervillain: medium-dark skin tone
-1F9B9 1F3FF ; fully-qualified # 🦹🏿 E11.0 supervillain: dark skin tone
-1F9B9 200D 2642 FE0F ; fully-qualified # 🦹♂️ E11.0 man supervillain
-1F9B9 200D 2642 ; minimally-qualified # 🦹♂ E11.0 man supervillain
-1F9B9 1F3FB 200D 2642 FE0F ; fully-qualified # 🦹🏻♂️ E11.0 man supervillain: light skin tone
-1F9B9 1F3FB 200D 2642 ; minimally-qualified # 🦹🏻♂ E11.0 man supervillain: light skin tone
-1F9B9 1F3FC 200D 2642 FE0F ; fully-qualified # 🦹🏼♂️ E11.0 man supervillain: medium-light skin tone
-1F9B9 1F3FC 200D 2642 ; minimally-qualified # 🦹🏼♂ E11.0 man supervillain: medium-light skin tone
-1F9B9 1F3FD 200D 2642 FE0F ; fully-qualified # 🦹🏽♂️ E11.0 man supervillain: medium skin tone
-1F9B9 1F3FD 200D 2642 ; minimally-qualified # 🦹🏽♂ E11.0 man supervillain: medium skin tone
-1F9B9 1F3FE 200D 2642 FE0F ; fully-qualified # 🦹🏾♂️ E11.0 man supervillain: medium-dark skin tone
-1F9B9 1F3FE 200D 2642 ; minimally-qualified # 🦹🏾♂ E11.0 man supervillain: medium-dark skin tone
-1F9B9 1F3FF 200D 2642 FE0F ; fully-qualified # 🦹🏿♂️ E11.0 man supervillain: dark skin tone
-1F9B9 1F3FF 200D 2642 ; minimally-qualified # 🦹🏿♂ E11.0 man supervillain: dark skin tone
-1F9B9 200D 2640 FE0F ; fully-qualified # 🦹♀️ E11.0 woman supervillain
-1F9B9 200D 2640 ; minimally-qualified # 🦹♀ E11.0 woman supervillain
-1F9B9 1F3FB 200D 2640 FE0F ; fully-qualified # 🦹🏻♀️ E11.0 woman supervillain: light skin tone
-1F9B9 1F3FB 200D 2640 ; minimally-qualified # 🦹🏻♀ E11.0 woman supervillain: light skin tone
-1F9B9 1F3FC 200D 2640 FE0F ; fully-qualified # 🦹🏼♀️ E11.0 woman supervillain: medium-light skin tone
-1F9B9 1F3FC 200D 2640 ; minimally-qualified # 🦹🏼♀ E11.0 woman supervillain: medium-light skin tone
-1F9B9 1F3FD 200D 2640 FE0F ; fully-qualified # 🦹🏽♀️ E11.0 woman supervillain: medium skin tone
-1F9B9 1F3FD 200D 2640 ; minimally-qualified # 🦹🏽♀ E11.0 woman supervillain: medium skin tone
-1F9B9 1F3FE 200D 2640 FE0F ; fully-qualified # 🦹🏾♀️ E11.0 woman supervillain: medium-dark skin tone
-1F9B9 1F3FE 200D 2640 ; minimally-qualified # 🦹🏾♀ E11.0 woman supervillain: medium-dark skin tone
-1F9B9 1F3FF 200D 2640 FE0F ; fully-qualified # 🦹🏿♀️ E11.0 woman supervillain: dark skin tone
-1F9B9 1F3FF 200D 2640 ; minimally-qualified # 🦹🏿♀ E11.0 woman supervillain: dark skin tone
-1F9D9 ; fully-qualified # 🧙 E5.0 mage
-1F9D9 1F3FB ; fully-qualified # 🧙🏻 E5.0 mage: light skin tone
-1F9D9 1F3FC ; fully-qualified # 🧙🏼 E5.0 mage: medium-light skin tone
-1F9D9 1F3FD ; fully-qualified # 🧙🏽 E5.0 mage: medium skin tone
-1F9D9 1F3FE ; fully-qualified # 🧙🏾 E5.0 mage: medium-dark skin tone
-1F9D9 1F3FF ; fully-qualified # 🧙🏿 E5.0 mage: dark skin tone
-1F9D9 200D 2642 FE0F ; fully-qualified # 🧙♂️ E5.0 man mage
-1F9D9 200D 2642 ; minimally-qualified # 🧙♂ E5.0 man mage
-1F9D9 1F3FB 200D 2642 FE0F ; fully-qualified # 🧙🏻♂️ E5.0 man mage: light skin tone
-1F9D9 1F3FB 200D 2642 ; minimally-qualified # 🧙🏻♂ E5.0 man mage: light skin tone
-1F9D9 1F3FC 200D 2642 FE0F ; fully-qualified # 🧙🏼♂️ E5.0 man mage: medium-light skin tone
-1F9D9 1F3FC 200D 2642 ; minimally-qualified # 🧙🏼♂ E5.0 man mage: medium-light skin tone
-1F9D9 1F3FD 200D 2642 FE0F ; fully-qualified # 🧙🏽♂️ E5.0 man mage: medium skin tone
-1F9D9 1F3FD 200D 2642 ; minimally-qualified # 🧙🏽♂ E5.0 man mage: medium skin tone
-1F9D9 1F3FE 200D 2642 FE0F ; fully-qualified # 🧙🏾♂️ E5.0 man mage: medium-dark skin tone
-1F9D9 1F3FE 200D 2642 ; minimally-qualified # 🧙🏾♂ E5.0 man mage: medium-dark skin tone
-1F9D9 1F3FF 200D 2642 FE0F ; fully-qualified # 🧙🏿♂️ E5.0 man mage: dark skin tone
-1F9D9 1F3FF 200D 2642 ; minimally-qualified # 🧙🏿♂ E5.0 man mage: dark skin tone
-1F9D9 200D 2640 FE0F ; fully-qualified # 🧙♀️ E5.0 woman mage
-1F9D9 200D 2640 ; minimally-qualified # 🧙♀ E5.0 woman mage
-1F9D9 1F3FB 200D 2640 FE0F ; fully-qualified # 🧙🏻♀️ E5.0 woman mage: light skin tone
-1F9D9 1F3FB 200D 2640 ; minimally-qualified # 🧙🏻♀ E5.0 woman mage: light skin tone
-1F9D9 1F3FC 200D 2640 FE0F ; fully-qualified # 🧙🏼♀️ E5.0 woman mage: medium-light skin tone
-1F9D9 1F3FC 200D 2640 ; minimally-qualified # 🧙🏼♀ E5.0 woman mage: medium-light skin tone
-1F9D9 1F3FD 200D 2640 FE0F ; fully-qualified # 🧙🏽♀️ E5.0 woman mage: medium skin tone
-1F9D9 1F3FD 200D 2640 ; minimally-qualified # 🧙🏽♀ E5.0 woman mage: medium skin tone
-1F9D9 1F3FE 200D 2640 FE0F ; fully-qualified # 🧙🏾♀️ E5.0 woman mage: medium-dark skin tone
-1F9D9 1F3FE 200D 2640 ; minimally-qualified # 🧙🏾♀ E5.0 woman mage: medium-dark skin tone
-1F9D9 1F3FF 200D 2640 FE0F ; fully-qualified # 🧙🏿♀️ E5.0 woman mage: dark skin tone
-1F9D9 1F3FF 200D 2640 ; minimally-qualified # 🧙🏿♀ E5.0 woman mage: dark skin tone
-1F9DA ; fully-qualified # 🧚 E5.0 fairy
-1F9DA 1F3FB ; fully-qualified # 🧚🏻 E5.0 fairy: light skin tone
-1F9DA 1F3FC ; fully-qualified # 🧚🏼 E5.0 fairy: medium-light skin tone
-1F9DA 1F3FD ; fully-qualified # 🧚🏽 E5.0 fairy: medium skin tone
-1F9DA 1F3FE ; fully-qualified # 🧚🏾 E5.0 fairy: medium-dark skin tone
-1F9DA 1F3FF ; fully-qualified # 🧚🏿 E5.0 fairy: dark skin tone
-1F9DA 200D 2642 FE0F ; fully-qualified # 🧚♂️ E5.0 man fairy
-1F9DA 200D 2642 ; minimally-qualified # 🧚♂ E5.0 man fairy
-1F9DA 1F3FB 200D 2642 FE0F ; fully-qualified # 🧚🏻♂️ E5.0 man fairy: light skin tone
-1F9DA 1F3FB 200D 2642 ; minimally-qualified # 🧚🏻♂ E5.0 man fairy: light skin tone
-1F9DA 1F3FC 200D 2642 FE0F ; fully-qualified # 🧚🏼♂️ E5.0 man fairy: medium-light skin tone
-1F9DA 1F3FC 200D 2642 ; minimally-qualified # 🧚🏼♂ E5.0 man fairy: medium-light skin tone
-1F9DA 1F3FD 200D 2642 FE0F ; fully-qualified # 🧚🏽♂️ E5.0 man fairy: medium skin tone
-1F9DA 1F3FD 200D 2642 ; minimally-qualified # 🧚🏽♂ E5.0 man fairy: medium skin tone
-1F9DA 1F3FE 200D 2642 FE0F ; fully-qualified # 🧚🏾♂️ E5.0 man fairy: medium-dark skin tone
-1F9DA 1F3FE 200D 2642 ; minimally-qualified # 🧚🏾♂ E5.0 man fairy: medium-dark skin tone
-1F9DA 1F3FF 200D 2642 FE0F ; fully-qualified # 🧚🏿♂️ E5.0 man fairy: dark skin tone
-1F9DA 1F3FF 200D 2642 ; minimally-qualified # 🧚🏿♂ E5.0 man fairy: dark skin tone
-1F9DA 200D 2640 FE0F ; fully-qualified # 🧚♀️ E5.0 woman fairy
-1F9DA 200D 2640 ; minimally-qualified # 🧚♀ E5.0 woman fairy
-1F9DA 1F3FB 200D 2640 FE0F ; fully-qualified # 🧚🏻♀️ E5.0 woman fairy: light skin tone
-1F9DA 1F3FB 200D 2640 ; minimally-qualified # 🧚🏻♀ E5.0 woman fairy: light skin tone
-1F9DA 1F3FC 200D 2640 FE0F ; fully-qualified # 🧚🏼♀️ E5.0 woman fairy: medium-light skin tone
-1F9DA 1F3FC 200D 2640 ; minimally-qualified # 🧚🏼♀ E5.0 woman fairy: medium-light skin tone
-1F9DA 1F3FD 200D 2640 FE0F ; fully-qualified # 🧚🏽♀️ E5.0 woman fairy: medium skin tone
-1F9DA 1F3FD 200D 2640 ; minimally-qualified # 🧚🏽♀ E5.0 woman fairy: medium skin tone
-1F9DA 1F3FE 200D 2640 FE0F ; fully-qualified # 🧚🏾♀️ E5.0 woman fairy: medium-dark skin tone
-1F9DA 1F3FE 200D 2640 ; minimally-qualified # 🧚🏾♀ E5.0 woman fairy: medium-dark skin tone
-1F9DA 1F3FF 200D 2640 FE0F ; fully-qualified # 🧚🏿♀️ E5.0 woman fairy: dark skin tone
-1F9DA 1F3FF 200D 2640 ; minimally-qualified # 🧚🏿♀ E5.0 woman fairy: dark skin tone
-1F9DB ; fully-qualified # 🧛 E5.0 vampire
-1F9DB 1F3FB ; fully-qualified # 🧛🏻 E5.0 vampire: light skin tone
-1F9DB 1F3FC ; fully-qualified # 🧛🏼 E5.0 vampire: medium-light skin tone
-1F9DB 1F3FD ; fully-qualified # 🧛🏽 E5.0 vampire: medium skin tone
-1F9DB 1F3FE ; fully-qualified # 🧛🏾 E5.0 vampire: medium-dark skin tone
-1F9DB 1F3FF ; fully-qualified # 🧛🏿 E5.0 vampire: dark skin tone
-1F9DB 200D 2642 FE0F ; fully-qualified # 🧛♂️ E5.0 man vampire
-1F9DB 200D 2642 ; minimally-qualified # 🧛♂ E5.0 man vampire
-1F9DB 1F3FB 200D 2642 FE0F ; fully-qualified # 🧛🏻♂️ E5.0 man vampire: light skin tone
-1F9DB 1F3FB 200D 2642 ; minimally-qualified # 🧛🏻♂ E5.0 man vampire: light skin tone
-1F9DB 1F3FC 200D 2642 FE0F ; fully-qualified # 🧛🏼♂️ E5.0 man vampire: medium-light skin tone
-1F9DB 1F3FC 200D 2642 ; minimally-qualified # 🧛🏼♂ E5.0 man vampire: medium-light skin tone
-1F9DB 1F3FD 200D 2642 FE0F ; fully-qualified # 🧛🏽♂️ E5.0 man vampire: medium skin tone
-1F9DB 1F3FD 200D 2642 ; minimally-qualified # 🧛🏽♂ E5.0 man vampire: medium skin tone
-1F9DB 1F3FE 200D 2642 FE0F ; fully-qualified # 🧛🏾♂️ E5.0 man vampire: medium-dark skin tone
-1F9DB 1F3FE 200D 2642 ; minimally-qualified # 🧛🏾♂ E5.0 man vampire: medium-dark skin tone
-1F9DB 1F3FF 200D 2642 FE0F ; fully-qualified # 🧛🏿♂️ E5.0 man vampire: dark skin tone
-1F9DB 1F3FF 200D 2642 ; minimally-qualified # 🧛🏿♂ E5.0 man vampire: dark skin tone
-1F9DB 200D 2640 FE0F ; fully-qualified # 🧛♀️ E5.0 woman vampire
-1F9DB 200D 2640 ; minimally-qualified # 🧛♀ E5.0 woman vampire
-1F9DB 1F3FB 200D 2640 FE0F ; fully-qualified # 🧛🏻♀️ E5.0 woman vampire: light skin tone
-1F9DB 1F3FB 200D 2640 ; minimally-qualified # 🧛🏻♀ E5.0 woman vampire: light skin tone
-1F9DB 1F3FC 200D 2640 FE0F ; fully-qualified # 🧛🏼♀️ E5.0 woman vampire: medium-light skin tone
-1F9DB 1F3FC 200D 2640 ; minimally-qualified # 🧛🏼♀ E5.0 woman vampire: medium-light skin tone
-1F9DB 1F3FD 200D 2640 FE0F ; fully-qualified # 🧛🏽♀️ E5.0 woman vampire: medium skin tone
-1F9DB 1F3FD 200D 2640 ; minimally-qualified # 🧛🏽♀ E5.0 woman vampire: medium skin tone
-1F9DB 1F3FE 200D 2640 FE0F ; fully-qualified # 🧛🏾♀️ E5.0 woman vampire: medium-dark skin tone
-1F9DB 1F3FE 200D 2640 ; minimally-qualified # 🧛🏾♀ E5.0 woman vampire: medium-dark skin tone
-1F9DB 1F3FF 200D 2640 FE0F ; fully-qualified # 🧛🏿♀️ E5.0 woman vampire: dark skin tone
-1F9DB 1F3FF 200D 2640 ; minimally-qualified # 🧛🏿♀ E5.0 woman vampire: dark skin tone
-1F9DC ; fully-qualified # 🧜 E5.0 merperson
-1F9DC 1F3FB ; fully-qualified # 🧜🏻 E5.0 merperson: light skin tone
-1F9DC 1F3FC ; fully-qualified # 🧜🏼 E5.0 merperson: medium-light skin tone
-1F9DC 1F3FD ; fully-qualified # 🧜🏽 E5.0 merperson: medium skin tone
-1F9DC 1F3FE ; fully-qualified # 🧜🏾 E5.0 merperson: medium-dark skin tone
-1F9DC 1F3FF ; fully-qualified # 🧜🏿 E5.0 merperson: dark skin tone
-1F9DC 200D 2642 FE0F ; fully-qualified # 🧜♂️ E5.0 merman
-1F9DC 200D 2642 ; minimally-qualified # 🧜♂ E5.0 merman
-1F9DC 1F3FB 200D 2642 FE0F ; fully-qualified # 🧜🏻♂️ E5.0 merman: light skin tone
-1F9DC 1F3FB 200D 2642 ; minimally-qualified # 🧜🏻♂ E5.0 merman: light skin tone
-1F9DC 1F3FC 200D 2642 FE0F ; fully-qualified # 🧜🏼♂️ E5.0 merman: medium-light skin tone
-1F9DC 1F3FC 200D 2642 ; minimally-qualified # 🧜🏼♂ E5.0 merman: medium-light skin tone
-1F9DC 1F3FD 200D 2642 FE0F ; fully-qualified # 🧜🏽♂️ E5.0 merman: medium skin tone
-1F9DC 1F3FD 200D 2642 ; minimally-qualified # 🧜🏽♂ E5.0 merman: medium skin tone
-1F9DC 1F3FE 200D 2642 FE0F ; fully-qualified # 🧜🏾♂️ E5.0 merman: medium-dark skin tone
-1F9DC 1F3FE 200D 2642 ; minimally-qualified # 🧜🏾♂ E5.0 merman: medium-dark skin tone
-1F9DC 1F3FF 200D 2642 FE0F ; fully-qualified # 🧜🏿♂️ E5.0 merman: dark skin tone
-1F9DC 1F3FF 200D 2642 ; minimally-qualified # 🧜🏿♂ E5.0 merman: dark skin tone
-1F9DC 200D 2640 FE0F ; fully-qualified # 🧜♀️ E5.0 mermaid
-1F9DC 200D 2640 ; minimally-qualified # 🧜♀ E5.0 mermaid
-1F9DC 1F3FB 200D 2640 FE0F ; fully-qualified # 🧜🏻♀️ E5.0 mermaid: light skin tone
-1F9DC 1F3FB 200D 2640 ; minimally-qualified # 🧜🏻♀ E5.0 mermaid: light skin tone
-1F9DC 1F3FC 200D 2640 FE0F ; fully-qualified # 🧜🏼♀️ E5.0 mermaid: medium-light skin tone
-1F9DC 1F3FC 200D 2640 ; minimally-qualified # 🧜🏼♀ E5.0 mermaid: medium-light skin tone
-1F9DC 1F3FD 200D 2640 FE0F ; fully-qualified # 🧜🏽♀️ E5.0 mermaid: medium skin tone
-1F9DC 1F3FD 200D 2640 ; minimally-qualified # 🧜🏽♀ E5.0 mermaid: medium skin tone
-1F9DC 1F3FE 200D 2640 FE0F ; fully-qualified # 🧜🏾♀️ E5.0 mermaid: medium-dark skin tone
-1F9DC 1F3FE 200D 2640 ; minimally-qualified # 🧜🏾♀ E5.0 mermaid: medium-dark skin tone
-1F9DC 1F3FF 200D 2640 FE0F ; fully-qualified # 🧜🏿♀️ E5.0 mermaid: dark skin tone
-1F9DC 1F3FF 200D 2640 ; minimally-qualified # 🧜🏿♀ E5.0 mermaid: dark skin tone
-1F9DD ; fully-qualified # 🧝 E5.0 elf
-1F9DD 1F3FB ; fully-qualified # 🧝🏻 E5.0 elf: light skin tone
-1F9DD 1F3FC ; fully-qualified # 🧝🏼 E5.0 elf: medium-light skin tone
-1F9DD 1F3FD ; fully-qualified # 🧝🏽 E5.0 elf: medium skin tone
-1F9DD 1F3FE ; fully-qualified # 🧝🏾 E5.0 elf: medium-dark skin tone
-1F9DD 1F3FF ; fully-qualified # 🧝🏿 E5.0 elf: dark skin tone
-1F9DD 200D 2642 FE0F ; fully-qualified # 🧝♂️ E5.0 man elf
-1F9DD 200D 2642 ; minimally-qualified # 🧝♂ E5.0 man elf
-1F9DD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧝🏻♂️ E5.0 man elf: light skin tone
-1F9DD 1F3FB 200D 2642 ; minimally-qualified # 🧝🏻♂ E5.0 man elf: light skin tone
-1F9DD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧝🏼♂️ E5.0 man elf: medium-light skin tone
-1F9DD 1F3FC 200D 2642 ; minimally-qualified # 🧝🏼♂ E5.0 man elf: medium-light skin tone
-1F9DD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧝🏽♂️ E5.0 man elf: medium skin tone
-1F9DD 1F3FD 200D 2642 ; minimally-qualified # 🧝🏽♂ E5.0 man elf: medium skin tone
-1F9DD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧝🏾♂️ E5.0 man elf: medium-dark skin tone
-1F9DD 1F3FE 200D 2642 ; minimally-qualified # 🧝🏾♂ E5.0 man elf: medium-dark skin tone
-1F9DD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧝🏿♂️ E5.0 man elf: dark skin tone
-1F9DD 1F3FF 200D 2642 ; minimally-qualified # 🧝🏿♂ E5.0 man elf: dark skin tone
-1F9DD 200D 2640 FE0F ; fully-qualified # 🧝♀️ E5.0 woman elf
-1F9DD 200D 2640 ; minimally-qualified # 🧝♀ E5.0 woman elf
-1F9DD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧝🏻♀️ E5.0 woman elf: light skin tone
-1F9DD 1F3FB 200D 2640 ; minimally-qualified # 🧝🏻♀ E5.0 woman elf: light skin tone
-1F9DD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧝🏼♀️ E5.0 woman elf: medium-light skin tone
-1F9DD 1F3FC 200D 2640 ; minimally-qualified # 🧝🏼♀ E5.0 woman elf: medium-light skin tone
-1F9DD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧝🏽♀️ E5.0 woman elf: medium skin tone
-1F9DD 1F3FD 200D 2640 ; minimally-qualified # 🧝🏽♀ E5.0 woman elf: medium skin tone
-1F9DD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧝🏾♀️ E5.0 woman elf: medium-dark skin tone
-1F9DD 1F3FE 200D 2640 ; minimally-qualified # 🧝🏾♀ E5.0 woman elf: medium-dark skin tone
-1F9DD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧝🏿♀️ E5.0 woman elf: dark skin tone
-1F9DD 1F3FF 200D 2640 ; minimally-qualified # 🧝🏿♀ E5.0 woman elf: dark skin tone
-1F9DE ; fully-qualified # 🧞 E5.0 genie
-1F9DE 200D 2642 FE0F ; fully-qualified # 🧞♂️ E5.0 man genie
-1F9DE 200D 2642 ; minimally-qualified # 🧞♂ E5.0 man genie
-1F9DE 200D 2640 FE0F ; fully-qualified # 🧞♀️ E5.0 woman genie
-1F9DE 200D 2640 ; minimally-qualified # 🧞♀ E5.0 woman genie
-1F9DF ; fully-qualified # 🧟 E5.0 zombie
-1F9DF 200D 2642 FE0F ; fully-qualified # 🧟♂️ E5.0 man zombie
-1F9DF 200D 2642 ; minimally-qualified # 🧟♂ E5.0 man zombie
-1F9DF 200D 2640 FE0F ; fully-qualified # 🧟♀️ E5.0 woman zombie
-1F9DF 200D 2640 ; minimally-qualified # 🧟♀ E5.0 woman zombie
+1F47C ; fully-qualified # 👼 E0.6 baby angel
+1F47C 1F3FB ; fully-qualified # 👼🏻 E1.0 baby angel: light skin tone
+1F47C 1F3FC ; fully-qualified # 👼🏼 E1.0 baby angel: medium-light skin tone
+1F47C 1F3FD ; fully-qualified # 👼🏽 E1.0 baby angel: medium skin tone
+1F47C 1F3FE ; fully-qualified # 👼🏾 E1.0 baby angel: medium-dark skin tone
+1F47C 1F3FF ; fully-qualified # 👼🏿 E1.0 baby angel: dark skin tone
+1F385 ; fully-qualified # 🎅 E0.6 Santa Claus
+1F385 1F3FB ; fully-qualified # 🎅🏻 E1.0 Santa Claus: light skin tone
+1F385 1F3FC ; fully-qualified # 🎅🏼 E1.0 Santa Claus: medium-light skin tone
+1F385 1F3FD ; fully-qualified # 🎅🏽 E1.0 Santa Claus: medium skin tone
+1F385 1F3FE ; fully-qualified # 🎅🏾 E1.0 Santa Claus: medium-dark skin tone
+1F385 1F3FF ; fully-qualified # 🎅🏿 E1.0 Santa Claus: dark skin tone
+1F936 ; fully-qualified # 🤶 E3.0 Mrs. Claus
+1F936 1F3FB ; fully-qualified # 🤶🏻 E3.0 Mrs. Claus: light skin tone
+1F936 1F3FC ; fully-qualified # 🤶🏼 E3.0 Mrs. Claus: medium-light skin tone
+1F936 1F3FD ; fully-qualified # 🤶🏽 E3.0 Mrs. Claus: medium skin tone
+1F936 1F3FE ; fully-qualified # 🤶🏾 E3.0 Mrs. Claus: medium-dark skin tone
+1F936 1F3FF ; fully-qualified # 🤶🏿 E3.0 Mrs. Claus: dark skin tone
+1F9D1 200D 1F384 ; fully-qualified # 🧑🎄 E13.0 mx claus
+1F9D1 1F3FB 200D 1F384 ; fully-qualified # 🧑🏻🎄 E13.0 mx claus: light skin tone
+1F9D1 1F3FC 200D 1F384 ; fully-qualified # 🧑🏼🎄 E13.0 mx claus: medium-light skin tone
+1F9D1 1F3FD 200D 1F384 ; fully-qualified # 🧑🏽🎄 E13.0 mx claus: medium skin tone
+1F9D1 1F3FE 200D 1F384 ; fully-qualified # 🧑🏾🎄 E13.0 mx claus: medium-dark skin tone
+1F9D1 1F3FF 200D 1F384 ; fully-qualified # 🧑🏿🎄 E13.0 mx claus: dark skin tone
+1F9B8 ; fully-qualified # 🦸 E11.0 superhero
+1F9B8 1F3FB ; fully-qualified # 🦸🏻 E11.0 superhero: light skin tone
+1F9B8 1F3FC ; fully-qualified # 🦸🏼 E11.0 superhero: medium-light skin tone
+1F9B8 1F3FD ; fully-qualified # 🦸🏽 E11.0 superhero: medium skin tone
+1F9B8 1F3FE ; fully-qualified # 🦸🏾 E11.0 superhero: medium-dark skin tone
+1F9B8 1F3FF ; fully-qualified # 🦸🏿 E11.0 superhero: dark skin tone
+1F9B8 200D 2642 FE0F ; fully-qualified # 🦸♂️ E11.0 man superhero
+1F9B8 200D 2642 ; minimally-qualified # 🦸♂ E11.0 man superhero
+1F9B8 1F3FB 200D 2642 FE0F ; fully-qualified # 🦸🏻♂️ E11.0 man superhero: light skin tone
+1F9B8 1F3FB 200D 2642 ; minimally-qualified # 🦸🏻♂ E11.0 man superhero: light skin tone
+1F9B8 1F3FC 200D 2642 FE0F ; fully-qualified # 🦸🏼♂️ E11.0 man superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2642 ; minimally-qualified # 🦸🏼♂ E11.0 man superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2642 FE0F ; fully-qualified # 🦸🏽♂️ E11.0 man superhero: medium skin tone
+1F9B8 1F3FD 200D 2642 ; minimally-qualified # 🦸🏽♂ E11.0 man superhero: medium skin tone
+1F9B8 1F3FE 200D 2642 FE0F ; fully-qualified # 🦸🏾♂️ E11.0 man superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2642 ; minimally-qualified # 🦸🏾♂ E11.0 man superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2642 FE0F ; fully-qualified # 🦸🏿♂️ E11.0 man superhero: dark skin tone
+1F9B8 1F3FF 200D 2642 ; minimally-qualified # 🦸🏿♂ E11.0 man superhero: dark skin tone
+1F9B8 200D 2640 FE0F ; fully-qualified # 🦸♀️ E11.0 woman superhero
+1F9B8 200D 2640 ; minimally-qualified # 🦸♀ E11.0 woman superhero
+1F9B8 1F3FB 200D 2640 FE0F ; fully-qualified # 🦸🏻♀️ E11.0 woman superhero: light skin tone
+1F9B8 1F3FB 200D 2640 ; minimally-qualified # 🦸🏻♀ E11.0 woman superhero: light skin tone
+1F9B8 1F3FC 200D 2640 FE0F ; fully-qualified # 🦸🏼♀️ E11.0 woman superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2640 ; minimally-qualified # 🦸🏼♀ E11.0 woman superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2640 FE0F ; fully-qualified # 🦸🏽♀️ E11.0 woman superhero: medium skin tone
+1F9B8 1F3FD 200D 2640 ; minimally-qualified # 🦸🏽♀ E11.0 woman superhero: medium skin tone
+1F9B8 1F3FE 200D 2640 FE0F ; fully-qualified # 🦸🏾♀️ E11.0 woman superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2640 ; minimally-qualified # 🦸🏾♀ E11.0 woman superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2640 FE0F ; fully-qualified # 🦸🏿♀️ E11.0 woman superhero: dark skin tone
+1F9B8 1F3FF 200D 2640 ; minimally-qualified # 🦸🏿♀ E11.0 woman superhero: dark skin tone
+1F9B9 ; fully-qualified # 🦹 E11.0 supervillain
+1F9B9 1F3FB ; fully-qualified # 🦹🏻 E11.0 supervillain: light skin tone
+1F9B9 1F3FC ; fully-qualified # 🦹🏼 E11.0 supervillain: medium-light skin tone
+1F9B9 1F3FD ; fully-qualified # 🦹🏽 E11.0 supervillain: medium skin tone
+1F9B9 1F3FE ; fully-qualified # 🦹🏾 E11.0 supervillain: medium-dark skin tone
+1F9B9 1F3FF ; fully-qualified # 🦹🏿 E11.0 supervillain: dark skin tone
+1F9B9 200D 2642 FE0F ; fully-qualified # 🦹♂️ E11.0 man supervillain
+1F9B9 200D 2642 ; minimally-qualified # 🦹♂ E11.0 man supervillain
+1F9B9 1F3FB 200D 2642 FE0F ; fully-qualified # 🦹🏻♂️ E11.0 man supervillain: light skin tone
+1F9B9 1F3FB 200D 2642 ; minimally-qualified # 🦹🏻♂ E11.0 man supervillain: light skin tone
+1F9B9 1F3FC 200D 2642 FE0F ; fully-qualified # 🦹🏼♂️ E11.0 man supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2642 ; minimally-qualified # 🦹🏼♂ E11.0 man supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2642 FE0F ; fully-qualified # 🦹🏽♂️ E11.0 man supervillain: medium skin tone
+1F9B9 1F3FD 200D 2642 ; minimally-qualified # 🦹🏽♂ E11.0 man supervillain: medium skin tone
+1F9B9 1F3FE 200D 2642 FE0F ; fully-qualified # 🦹🏾♂️ E11.0 man supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2642 ; minimally-qualified # 🦹🏾♂ E11.0 man supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2642 FE0F ; fully-qualified # 🦹🏿♂️ E11.0 man supervillain: dark skin tone
+1F9B9 1F3FF 200D 2642 ; minimally-qualified # 🦹🏿♂ E11.0 man supervillain: dark skin tone
+1F9B9 200D 2640 FE0F ; fully-qualified # 🦹♀️ E11.0 woman supervillain
+1F9B9 200D 2640 ; minimally-qualified # 🦹♀ E11.0 woman supervillain
+1F9B9 1F3FB 200D 2640 FE0F ; fully-qualified # 🦹🏻♀️ E11.0 woman supervillain: light skin tone
+1F9B9 1F3FB 200D 2640 ; minimally-qualified # 🦹🏻♀ E11.0 woman supervillain: light skin tone
+1F9B9 1F3FC 200D 2640 FE0F ; fully-qualified # 🦹🏼♀️ E11.0 woman supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2640 ; minimally-qualified # 🦹🏼♀ E11.0 woman supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2640 FE0F ; fully-qualified # 🦹🏽♀️ E11.0 woman supervillain: medium skin tone
+1F9B9 1F3FD 200D 2640 ; minimally-qualified # 🦹🏽♀ E11.0 woman supervillain: medium skin tone
+1F9B9 1F3FE 200D 2640 FE0F ; fully-qualified # 🦹🏾♀️ E11.0 woman supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2640 ; minimally-qualified # 🦹🏾♀ E11.0 woman supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2640 FE0F ; fully-qualified # 🦹🏿♀️ E11.0 woman supervillain: dark skin tone
+1F9B9 1F3FF 200D 2640 ; minimally-qualified # 🦹🏿♀ E11.0 woman supervillain: dark skin tone
+1F9D9 ; fully-qualified # 🧙 E5.0 mage
+1F9D9 1F3FB ; fully-qualified # 🧙🏻 E5.0 mage: light skin tone
+1F9D9 1F3FC ; fully-qualified # 🧙🏼 E5.0 mage: medium-light skin tone
+1F9D9 1F3FD ; fully-qualified # 🧙🏽 E5.0 mage: medium skin tone
+1F9D9 1F3FE ; fully-qualified # 🧙🏾 E5.0 mage: medium-dark skin tone
+1F9D9 1F3FF ; fully-qualified # 🧙🏿 E5.0 mage: dark skin tone
+1F9D9 200D 2642 FE0F ; fully-qualified # 🧙♂️ E5.0 man mage
+1F9D9 200D 2642 ; minimally-qualified # 🧙♂ E5.0 man mage
+1F9D9 1F3FB 200D 2642 FE0F ; fully-qualified # 🧙🏻♂️ E5.0 man mage: light skin tone
+1F9D9 1F3FB 200D 2642 ; minimally-qualified # 🧙🏻♂ E5.0 man mage: light skin tone
+1F9D9 1F3FC 200D 2642 FE0F ; fully-qualified # 🧙🏼♂️ E5.0 man mage: medium-light skin tone
+1F9D9 1F3FC 200D 2642 ; minimally-qualified # 🧙🏼♂ E5.0 man mage: medium-light skin tone
+1F9D9 1F3FD 200D 2642 FE0F ; fully-qualified # 🧙🏽♂️ E5.0 man mage: medium skin tone
+1F9D9 1F3FD 200D 2642 ; minimally-qualified # 🧙🏽♂ E5.0 man mage: medium skin tone
+1F9D9 1F3FE 200D 2642 FE0F ; fully-qualified # 🧙🏾♂️ E5.0 man mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2642 ; minimally-qualified # 🧙🏾♂ E5.0 man mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2642 FE0F ; fully-qualified # 🧙🏿♂️ E5.0 man mage: dark skin tone
+1F9D9 1F3FF 200D 2642 ; minimally-qualified # 🧙🏿♂ E5.0 man mage: dark skin tone
+1F9D9 200D 2640 FE0F ; fully-qualified # 🧙♀️ E5.0 woman mage
+1F9D9 200D 2640 ; minimally-qualified # 🧙♀ E5.0 woman mage
+1F9D9 1F3FB 200D 2640 FE0F ; fully-qualified # 🧙🏻♀️ E5.0 woman mage: light skin tone
+1F9D9 1F3FB 200D 2640 ; minimally-qualified # 🧙🏻♀ E5.0 woman mage: light skin tone
+1F9D9 1F3FC 200D 2640 FE0F ; fully-qualified # 🧙🏼♀️ E5.0 woman mage: medium-light skin tone
+1F9D9 1F3FC 200D 2640 ; minimally-qualified # 🧙🏼♀ E5.0 woman mage: medium-light skin tone
+1F9D9 1F3FD 200D 2640 FE0F ; fully-qualified # 🧙🏽♀️ E5.0 woman mage: medium skin tone
+1F9D9 1F3FD 200D 2640 ; minimally-qualified # 🧙🏽♀ E5.0 woman mage: medium skin tone
+1F9D9 1F3FE 200D 2640 FE0F ; fully-qualified # 🧙🏾♀️ E5.0 woman mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2640 ; minimally-qualified # 🧙🏾♀ E5.0 woman mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2640 FE0F ; fully-qualified # 🧙🏿♀️ E5.0 woman mage: dark skin tone
+1F9D9 1F3FF 200D 2640 ; minimally-qualified # 🧙🏿♀ E5.0 woman mage: dark skin tone
+1F9DA ; fully-qualified # 🧚 E5.0 fairy
+1F9DA 1F3FB ; fully-qualified # 🧚🏻 E5.0 fairy: light skin tone
+1F9DA 1F3FC ; fully-qualified # 🧚🏼 E5.0 fairy: medium-light skin tone
+1F9DA 1F3FD ; fully-qualified # 🧚🏽 E5.0 fairy: medium skin tone
+1F9DA 1F3FE ; fully-qualified # 🧚🏾 E5.0 fairy: medium-dark skin tone
+1F9DA 1F3FF ; fully-qualified # 🧚🏿 E5.0 fairy: dark skin tone
+1F9DA 200D 2642 FE0F ; fully-qualified # 🧚♂️ E5.0 man fairy
+1F9DA 200D 2642 ; minimally-qualified # 🧚♂ E5.0 man fairy
+1F9DA 1F3FB 200D 2642 FE0F ; fully-qualified # 🧚🏻♂️ E5.0 man fairy: light skin tone
+1F9DA 1F3FB 200D 2642 ; minimally-qualified # 🧚🏻♂ E5.0 man fairy: light skin tone
+1F9DA 1F3FC 200D 2642 FE0F ; fully-qualified # 🧚🏼♂️ E5.0 man fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2642 ; minimally-qualified # 🧚🏼♂ E5.0 man fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2642 FE0F ; fully-qualified # 🧚🏽♂️ E5.0 man fairy: medium skin tone
+1F9DA 1F3FD 200D 2642 ; minimally-qualified # 🧚🏽♂ E5.0 man fairy: medium skin tone
+1F9DA 1F3FE 200D 2642 FE0F ; fully-qualified # 🧚🏾♂️ E5.0 man fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2642 ; minimally-qualified # 🧚🏾♂ E5.0 man fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2642 FE0F ; fully-qualified # 🧚🏿♂️ E5.0 man fairy: dark skin tone
+1F9DA 1F3FF 200D 2642 ; minimally-qualified # 🧚🏿♂ E5.0 man fairy: dark skin tone
+1F9DA 200D 2640 FE0F ; fully-qualified # 🧚♀️ E5.0 woman fairy
+1F9DA 200D 2640 ; minimally-qualified # 🧚♀ E5.0 woman fairy
+1F9DA 1F3FB 200D 2640 FE0F ; fully-qualified # 🧚🏻♀️ E5.0 woman fairy: light skin tone
+1F9DA 1F3FB 200D 2640 ; minimally-qualified # 🧚🏻♀ E5.0 woman fairy: light skin tone
+1F9DA 1F3FC 200D 2640 FE0F ; fully-qualified # 🧚🏼♀️ E5.0 woman fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2640 ; minimally-qualified # 🧚🏼♀ E5.0 woman fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2640 FE0F ; fully-qualified # 🧚🏽♀️ E5.0 woman fairy: medium skin tone
+1F9DA 1F3FD 200D 2640 ; minimally-qualified # 🧚🏽♀ E5.0 woman fairy: medium skin tone
+1F9DA 1F3FE 200D 2640 FE0F ; fully-qualified # 🧚🏾♀️ E5.0 woman fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2640 ; minimally-qualified # 🧚🏾♀ E5.0 woman fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2640 FE0F ; fully-qualified # 🧚🏿♀️ E5.0 woman fairy: dark skin tone
+1F9DA 1F3FF 200D 2640 ; minimally-qualified # 🧚🏿♀ E5.0 woman fairy: dark skin tone
+1F9DB ; fully-qualified # 🧛 E5.0 vampire
+1F9DB 1F3FB ; fully-qualified # 🧛🏻 E5.0 vampire: light skin tone
+1F9DB 1F3FC ; fully-qualified # 🧛🏼 E5.0 vampire: medium-light skin tone
+1F9DB 1F3FD ; fully-qualified # 🧛🏽 E5.0 vampire: medium skin tone
+1F9DB 1F3FE ; fully-qualified # 🧛🏾 E5.0 vampire: medium-dark skin tone
+1F9DB 1F3FF ; fully-qualified # 🧛🏿 E5.0 vampire: dark skin tone
+1F9DB 200D 2642 FE0F ; fully-qualified # 🧛♂️ E5.0 man vampire
+1F9DB 200D 2642 ; minimally-qualified # 🧛♂ E5.0 man vampire
+1F9DB 1F3FB 200D 2642 FE0F ; fully-qualified # 🧛🏻♂️ E5.0 man vampire: light skin tone
+1F9DB 1F3FB 200D 2642 ; minimally-qualified # 🧛🏻♂ E5.0 man vampire: light skin tone
+1F9DB 1F3FC 200D 2642 FE0F ; fully-qualified # 🧛🏼♂️ E5.0 man vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2642 ; minimally-qualified # 🧛🏼♂ E5.0 man vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2642 FE0F ; fully-qualified # 🧛🏽♂️ E5.0 man vampire: medium skin tone
+1F9DB 1F3FD 200D 2642 ; minimally-qualified # 🧛🏽♂ E5.0 man vampire: medium skin tone
+1F9DB 1F3FE 200D 2642 FE0F ; fully-qualified # 🧛🏾♂️ E5.0 man vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2642 ; minimally-qualified # 🧛🏾♂ E5.0 man vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2642 FE0F ; fully-qualified # 🧛🏿♂️ E5.0 man vampire: dark skin tone
+1F9DB 1F3FF 200D 2642 ; minimally-qualified # 🧛🏿♂ E5.0 man vampire: dark skin tone
+1F9DB 200D 2640 FE0F ; fully-qualified # 🧛♀️ E5.0 woman vampire
+1F9DB 200D 2640 ; minimally-qualified # 🧛♀ E5.0 woman vampire
+1F9DB 1F3FB 200D 2640 FE0F ; fully-qualified # 🧛🏻♀️ E5.0 woman vampire: light skin tone
+1F9DB 1F3FB 200D 2640 ; minimally-qualified # 🧛🏻♀ E5.0 woman vampire: light skin tone
+1F9DB 1F3FC 200D 2640 FE0F ; fully-qualified # 🧛🏼♀️ E5.0 woman vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2640 ; minimally-qualified # 🧛🏼♀ E5.0 woman vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2640 FE0F ; fully-qualified # 🧛🏽♀️ E5.0 woman vampire: medium skin tone
+1F9DB 1F3FD 200D 2640 ; minimally-qualified # 🧛🏽♀ E5.0 woman vampire: medium skin tone
+1F9DB 1F3FE 200D 2640 FE0F ; fully-qualified # 🧛🏾♀️ E5.0 woman vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2640 ; minimally-qualified # 🧛🏾♀ E5.0 woman vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2640 FE0F ; fully-qualified # 🧛🏿♀️ E5.0 woman vampire: dark skin tone
+1F9DB 1F3FF 200D 2640 ; minimally-qualified # 🧛🏿♀ E5.0 woman vampire: dark skin tone
+1F9DC ; fully-qualified # 🧜 E5.0 merperson
+1F9DC 1F3FB ; fully-qualified # 🧜🏻 E5.0 merperson: light skin tone
+1F9DC 1F3FC ; fully-qualified # 🧜🏼 E5.0 merperson: medium-light skin tone
+1F9DC 1F3FD ; fully-qualified # 🧜🏽 E5.0 merperson: medium skin tone
+1F9DC 1F3FE ; fully-qualified # 🧜🏾 E5.0 merperson: medium-dark skin tone
+1F9DC 1F3FF ; fully-qualified # 🧜🏿 E5.0 merperson: dark skin tone
+1F9DC 200D 2642 FE0F ; fully-qualified # 🧜♂️ E5.0 merman
+1F9DC 200D 2642 ; minimally-qualified # 🧜♂ E5.0 merman
+1F9DC 1F3FB 200D 2642 FE0F ; fully-qualified # 🧜🏻♂️ E5.0 merman: light skin tone
+1F9DC 1F3FB 200D 2642 ; minimally-qualified # 🧜🏻♂ E5.0 merman: light skin tone
+1F9DC 1F3FC 200D 2642 FE0F ; fully-qualified # 🧜🏼♂️ E5.0 merman: medium-light skin tone
+1F9DC 1F3FC 200D 2642 ; minimally-qualified # 🧜🏼♂ E5.0 merman: medium-light skin tone
+1F9DC 1F3FD 200D 2642 FE0F ; fully-qualified # 🧜🏽♂️ E5.0 merman: medium skin tone
+1F9DC 1F3FD 200D 2642 ; minimally-qualified # 🧜🏽♂ E5.0 merman: medium skin tone
+1F9DC 1F3FE 200D 2642 FE0F ; fully-qualified # 🧜🏾♂️ E5.0 merman: medium-dark skin tone
+1F9DC 1F3FE 200D 2642 ; minimally-qualified # 🧜🏾♂ E5.0 merman: medium-dark skin tone
+1F9DC 1F3FF 200D 2642 FE0F ; fully-qualified # 🧜🏿♂️ E5.0 merman: dark skin tone
+1F9DC 1F3FF 200D 2642 ; minimally-qualified # 🧜🏿♂ E5.0 merman: dark skin tone
+1F9DC 200D 2640 FE0F ; fully-qualified # 🧜♀️ E5.0 mermaid
+1F9DC 200D 2640 ; minimally-qualified # 🧜♀ E5.0 mermaid
+1F9DC 1F3FB 200D 2640 FE0F ; fully-qualified # 🧜🏻♀️ E5.0 mermaid: light skin tone
+1F9DC 1F3FB 200D 2640 ; minimally-qualified # 🧜🏻♀ E5.0 mermaid: light skin tone
+1F9DC 1F3FC 200D 2640 FE0F ; fully-qualified # 🧜🏼♀️ E5.0 mermaid: medium-light skin tone
+1F9DC 1F3FC 200D 2640 ; minimally-qualified # 🧜🏼♀ E5.0 mermaid: medium-light skin tone
+1F9DC 1F3FD 200D 2640 FE0F ; fully-qualified # 🧜🏽♀️ E5.0 mermaid: medium skin tone
+1F9DC 1F3FD 200D 2640 ; minimally-qualified # 🧜🏽♀ E5.0 mermaid: medium skin tone
+1F9DC 1F3FE 200D 2640 FE0F ; fully-qualified # 🧜🏾♀️ E5.0 mermaid: medium-dark skin tone
+1F9DC 1F3FE 200D 2640 ; minimally-qualified # 🧜🏾♀ E5.0 mermaid: medium-dark skin tone
+1F9DC 1F3FF 200D 2640 FE0F ; fully-qualified # 🧜🏿♀️ E5.0 mermaid: dark skin tone
+1F9DC 1F3FF 200D 2640 ; minimally-qualified # 🧜🏿♀ E5.0 mermaid: dark skin tone
+1F9DD ; fully-qualified # 🧝 E5.0 elf
+1F9DD 1F3FB ; fully-qualified # 🧝🏻 E5.0 elf: light skin tone
+1F9DD 1F3FC ; fully-qualified # 🧝🏼 E5.0 elf: medium-light skin tone
+1F9DD 1F3FD ; fully-qualified # 🧝🏽 E5.0 elf: medium skin tone
+1F9DD 1F3FE ; fully-qualified # 🧝🏾 E5.0 elf: medium-dark skin tone
+1F9DD 1F3FF ; fully-qualified # 🧝🏿 E5.0 elf: dark skin tone
+1F9DD 200D 2642 FE0F ; fully-qualified # 🧝♂️ E5.0 man elf
+1F9DD 200D 2642 ; minimally-qualified # 🧝♂ E5.0 man elf
+1F9DD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧝🏻♂️ E5.0 man elf: light skin tone
+1F9DD 1F3FB 200D 2642 ; minimally-qualified # 🧝🏻♂ E5.0 man elf: light skin tone
+1F9DD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧝🏼♂️ E5.0 man elf: medium-light skin tone
+1F9DD 1F3FC 200D 2642 ; minimally-qualified # 🧝🏼♂ E5.0 man elf: medium-light skin tone
+1F9DD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧝🏽♂️ E5.0 man elf: medium skin tone
+1F9DD 1F3FD 200D 2642 ; minimally-qualified # 🧝🏽♂ E5.0 man elf: medium skin tone
+1F9DD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧝🏾♂️ E5.0 man elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2642 ; minimally-qualified # 🧝🏾♂ E5.0 man elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧝🏿♂️ E5.0 man elf: dark skin tone
+1F9DD 1F3FF 200D 2642 ; minimally-qualified # 🧝🏿♂ E5.0 man elf: dark skin tone
+1F9DD 200D 2640 FE0F ; fully-qualified # 🧝♀️ E5.0 woman elf
+1F9DD 200D 2640 ; minimally-qualified # 🧝♀ E5.0 woman elf
+1F9DD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧝🏻♀️ E5.0 woman elf: light skin tone
+1F9DD 1F3FB 200D 2640 ; minimally-qualified # 🧝🏻♀ E5.0 woman elf: light skin tone
+1F9DD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧝🏼♀️ E5.0 woman elf: medium-light skin tone
+1F9DD 1F3FC 200D 2640 ; minimally-qualified # 🧝🏼♀ E5.0 woman elf: medium-light skin tone
+1F9DD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧝🏽♀️ E5.0 woman elf: medium skin tone
+1F9DD 1F3FD 200D 2640 ; minimally-qualified # 🧝🏽♀ E5.0 woman elf: medium skin tone
+1F9DD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧝🏾♀️ E5.0 woman elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2640 ; minimally-qualified # 🧝🏾♀ E5.0 woman elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧝🏿♀️ E5.0 woman elf: dark skin tone
+1F9DD 1F3FF 200D 2640 ; minimally-qualified # 🧝🏿♀ E5.0 woman elf: dark skin tone
+1F9DE ; fully-qualified # 🧞 E5.0 genie
+1F9DE 200D 2642 FE0F ; fully-qualified # 🧞♂️ E5.0 man genie
+1F9DE 200D 2642 ; minimally-qualified # 🧞♂ E5.0 man genie
+1F9DE 200D 2640 FE0F ; fully-qualified # 🧞♀️ E5.0 woman genie
+1F9DE 200D 2640 ; minimally-qualified # 🧞♀ E5.0 woman genie
+1F9DF ; fully-qualified # 🧟 E5.0 zombie
+1F9DF 200D 2642 FE0F ; fully-qualified # 🧟♂️ E5.0 man zombie
+1F9DF 200D 2642 ; minimally-qualified # 🧟♂ E5.0 man zombie
+1F9DF 200D 2640 FE0F ; fully-qualified # 🧟♀️ E5.0 woman zombie
+1F9DF 200D 2640 ; minimally-qualified # 🧟♀ E5.0 woman zombie
# subgroup: person-activity
-1F486 ; fully-qualified # 💆 E0.6 person getting massage
-1F486 1F3FB ; fully-qualified # 💆🏻 E1.0 person getting massage: light skin tone
-1F486 1F3FC ; fully-qualified # 💆🏼 E1.0 person getting massage: medium-light skin tone
-1F486 1F3FD ; fully-qualified # 💆🏽 E1.0 person getting massage: medium skin tone
-1F486 1F3FE ; fully-qualified # 💆🏾 E1.0 person getting massage: medium-dark skin tone
-1F486 1F3FF ; fully-qualified # 💆🏿 E1.0 person getting massage: dark skin tone
-1F486 200D 2642 FE0F ; fully-qualified # 💆♂️ E4.0 man getting massage
-1F486 200D 2642 ; minimally-qualified # 💆♂ E4.0 man getting massage
-1F486 1F3FB 200D 2642 FE0F ; fully-qualified # 💆🏻♂️ E4.0 man getting massage: light skin tone
-1F486 1F3FB 200D 2642 ; minimally-qualified # 💆🏻♂ E4.0 man getting massage: light skin tone
-1F486 1F3FC 200D 2642 FE0F ; fully-qualified # 💆🏼♂️ E4.0 man getting massage: medium-light skin tone
-1F486 1F3FC 200D 2642 ; minimally-qualified # 💆🏼♂ E4.0 man getting massage: medium-light skin tone
-1F486 1F3FD 200D 2642 FE0F ; fully-qualified # 💆🏽♂️ E4.0 man getting massage: medium skin tone
-1F486 1F3FD 200D 2642 ; minimally-qualified # 💆🏽♂ E4.0 man getting massage: medium skin tone
-1F486 1F3FE 200D 2642 FE0F ; fully-qualified # 💆🏾♂️ E4.0 man getting massage: medium-dark skin tone
-1F486 1F3FE 200D 2642 ; minimally-qualified # 💆🏾♂ E4.0 man getting massage: medium-dark skin tone
-1F486 1F3FF 200D 2642 FE0F ; fully-qualified # 💆🏿♂️ E4.0 man getting massage: dark skin tone
-1F486 1F3FF 200D 2642 ; minimally-qualified # 💆🏿♂ E4.0 man getting massage: dark skin tone
-1F486 200D 2640 FE0F ; fully-qualified # 💆♀️ E4.0 woman getting massage
-1F486 200D 2640 ; minimally-qualified # 💆♀ E4.0 woman getting massage
-1F486 1F3FB 200D 2640 FE0F ; fully-qualified # 💆🏻♀️ E4.0 woman getting massage: light skin tone
-1F486 1F3FB 200D 2640 ; minimally-qualified # 💆🏻♀ E4.0 woman getting massage: light skin tone
-1F486 1F3FC 200D 2640 FE0F ; fully-qualified # 💆🏼♀️ E4.0 woman getting massage: medium-light skin tone
-1F486 1F3FC 200D 2640 ; minimally-qualified # 💆🏼♀ E4.0 woman getting massage: medium-light skin tone
-1F486 1F3FD 200D 2640 FE0F ; fully-qualified # 💆🏽♀️ E4.0 woman getting massage: medium skin tone
-1F486 1F3FD 200D 2640 ; minimally-qualified # 💆🏽♀ E4.0 woman getting massage: medium skin tone
-1F486 1F3FE 200D 2640 FE0F ; fully-qualified # 💆🏾♀️ E4.0 woman getting massage: medium-dark skin tone
-1F486 1F3FE 200D 2640 ; minimally-qualified # 💆🏾♀ E4.0 woman getting massage: medium-dark skin tone
-1F486 1F3FF 200D 2640 FE0F ; fully-qualified # 💆🏿♀️ E4.0 woman getting massage: dark skin tone
-1F486 1F3FF 200D 2640 ; minimally-qualified # 💆🏿♀ E4.0 woman getting massage: dark skin tone
-1F487 ; fully-qualified # 💇 E0.6 person getting haircut
-1F487 1F3FB ; fully-qualified # 💇🏻 E1.0 person getting haircut: light skin tone
-1F487 1F3FC ; fully-qualified # 💇🏼 E1.0 person getting haircut: medium-light skin tone
-1F487 1F3FD ; fully-qualified # 💇🏽 E1.0 person getting haircut: medium skin tone
-1F487 1F3FE ; fully-qualified # 💇🏾 E1.0 person getting haircut: medium-dark skin tone
-1F487 1F3FF ; fully-qualified # 💇🏿 E1.0 person getting haircut: dark skin tone
-1F487 200D 2642 FE0F ; fully-qualified # 💇♂️ E4.0 man getting haircut
-1F487 200D 2642 ; minimally-qualified # 💇♂ E4.0 man getting haircut
-1F487 1F3FB 200D 2642 FE0F ; fully-qualified # 💇🏻♂️ E4.0 man getting haircut: light skin tone
-1F487 1F3FB 200D 2642 ; minimally-qualified # 💇🏻♂ E4.0 man getting haircut: light skin tone
-1F487 1F3FC 200D 2642 FE0F ; fully-qualified # 💇🏼♂️ E4.0 man getting haircut: medium-light skin tone
-1F487 1F3FC 200D 2642 ; minimally-qualified # 💇🏼♂ E4.0 man getting haircut: medium-light skin tone
-1F487 1F3FD 200D 2642 FE0F ; fully-qualified # 💇🏽♂️ E4.0 man getting haircut: medium skin tone
-1F487 1F3FD 200D 2642 ; minimally-qualified # 💇🏽♂ E4.0 man getting haircut: medium skin tone
-1F487 1F3FE 200D 2642 FE0F ; fully-qualified # 💇🏾♂️ E4.0 man getting haircut: medium-dark skin tone
-1F487 1F3FE 200D 2642 ; minimally-qualified # 💇🏾♂ E4.0 man getting haircut: medium-dark skin tone
-1F487 1F3FF 200D 2642 FE0F ; fully-qualified # 💇🏿♂️ E4.0 man getting haircut: dark skin tone
-1F487 1F3FF 200D 2642 ; minimally-qualified # 💇🏿♂ E4.0 man getting haircut: dark skin tone
-1F487 200D 2640 FE0F ; fully-qualified # 💇♀️ E4.0 woman getting haircut
-1F487 200D 2640 ; minimally-qualified # 💇♀ E4.0 woman getting haircut
-1F487 1F3FB 200D 2640 FE0F ; fully-qualified # 💇🏻♀️ E4.0 woman getting haircut: light skin tone
-1F487 1F3FB 200D 2640 ; minimally-qualified # 💇🏻♀ E4.0 woman getting haircut: light skin tone
-1F487 1F3FC 200D 2640 FE0F ; fully-qualified # 💇🏼♀️ E4.0 woman getting haircut: medium-light skin tone
-1F487 1F3FC 200D 2640 ; minimally-qualified # 💇🏼♀ E4.0 woman getting haircut: medium-light skin tone
-1F487 1F3FD 200D 2640 FE0F ; fully-qualified # 💇🏽♀️ E4.0 woman getting haircut: medium skin tone
-1F487 1F3FD 200D 2640 ; minimally-qualified # 💇🏽♀ E4.0 woman getting haircut: medium skin tone
-1F487 1F3FE 200D 2640 FE0F ; fully-qualified # 💇🏾♀️ E4.0 woman getting haircut: medium-dark skin tone
-1F487 1F3FE 200D 2640 ; minimally-qualified # 💇🏾♀ E4.0 woman getting haircut: medium-dark skin tone
-1F487 1F3FF 200D 2640 FE0F ; fully-qualified # 💇🏿♀️ E4.0 woman getting haircut: dark skin tone
-1F487 1F3FF 200D 2640 ; minimally-qualified # 💇🏿♀ E4.0 woman getting haircut: dark skin tone
-1F6B6 ; fully-qualified # 🚶 E0.6 person walking
-1F6B6 1F3FB ; fully-qualified # 🚶🏻 E1.0 person walking: light skin tone
-1F6B6 1F3FC ; fully-qualified # 🚶🏼 E1.0 person walking: medium-light skin tone
-1F6B6 1F3FD ; fully-qualified # 🚶🏽 E1.0 person walking: medium skin tone
-1F6B6 1F3FE ; fully-qualified # 🚶🏾 E1.0 person walking: medium-dark skin tone
-1F6B6 1F3FF ; fully-qualified # 🚶🏿 E1.0 person walking: dark skin tone
-1F6B6 200D 2642 FE0F ; fully-qualified # 🚶♂️ E4.0 man walking
-1F6B6 200D 2642 ; minimally-qualified # 🚶♂ E4.0 man walking
-1F6B6 1F3FB 200D 2642 FE0F ; fully-qualified # 🚶🏻♂️ E4.0 man walking: light skin tone
-1F6B6 1F3FB 200D 2642 ; minimally-qualified # 🚶🏻♂ E4.0 man walking: light skin tone
-1F6B6 1F3FC 200D 2642 FE0F ; fully-qualified # 🚶🏼♂️ E4.0 man walking: medium-light skin tone
-1F6B6 1F3FC 200D 2642 ; minimally-qualified # 🚶🏼♂ E4.0 man walking: medium-light skin tone
-1F6B6 1F3FD 200D 2642 FE0F ; fully-qualified # 🚶🏽♂️ E4.0 man walking: medium skin tone
-1F6B6 1F3FD 200D 2642 ; minimally-qualified # 🚶🏽♂ E4.0 man walking: medium skin tone
-1F6B6 1F3FE 200D 2642 FE0F ; fully-qualified # 🚶🏾♂️ E4.0 man walking: medium-dark skin tone
-1F6B6 1F3FE 200D 2642 ; minimally-qualified # 🚶🏾♂ E4.0 man walking: medium-dark skin tone
-1F6B6 1F3FF 200D 2642 FE0F ; fully-qualified # 🚶🏿♂️ E4.0 man walking: dark skin tone
-1F6B6 1F3FF 200D 2642 ; minimally-qualified # 🚶🏿♂ E4.0 man walking: dark skin tone
-1F6B6 200D 2640 FE0F ; fully-qualified # 🚶♀️ E4.0 woman walking
-1F6B6 200D 2640 ; minimally-qualified # 🚶♀ E4.0 woman walking
-1F6B6 1F3FB 200D 2640 FE0F ; fully-qualified # 🚶🏻♀️ E4.0 woman walking: light skin tone
-1F6B6 1F3FB 200D 2640 ; minimally-qualified # 🚶🏻♀ E4.0 woman walking: light skin tone
-1F6B6 1F3FC 200D 2640 FE0F ; fully-qualified # 🚶🏼♀️ E4.0 woman walking: medium-light skin tone
-1F6B6 1F3FC 200D 2640 ; minimally-qualified # 🚶🏼♀ E4.0 woman walking: medium-light skin tone
-1F6B6 1F3FD 200D 2640 FE0F ; fully-qualified # 🚶🏽♀️ E4.0 woman walking: medium skin tone
-1F6B6 1F3FD 200D 2640 ; minimally-qualified # 🚶🏽♀ E4.0 woman walking: medium skin tone
-1F6B6 1F3FE 200D 2640 FE0F ; fully-qualified # 🚶🏾♀️ E4.0 woman walking: medium-dark skin tone
-1F6B6 1F3FE 200D 2640 ; minimally-qualified # 🚶🏾♀ E4.0 woman walking: medium-dark skin tone
-1F6B6 1F3FF 200D 2640 FE0F ; fully-qualified # 🚶🏿♀️ E4.0 woman walking: dark skin tone
-1F6B6 1F3FF 200D 2640 ; minimally-qualified # 🚶🏿♀ E4.0 woman walking: dark skin tone
-1F9CD ; fully-qualified # 🧍 E12.0 person standing
-1F9CD 1F3FB ; fully-qualified # 🧍🏻 E12.0 person standing: light skin tone
-1F9CD 1F3FC ; fully-qualified # 🧍🏼 E12.0 person standing: medium-light skin tone
-1F9CD 1F3FD ; fully-qualified # 🧍🏽 E12.0 person standing: medium skin tone
-1F9CD 1F3FE ; fully-qualified # 🧍🏾 E12.0 person standing: medium-dark skin tone
-1F9CD 1F3FF ; fully-qualified # 🧍🏿 E12.0 person standing: dark skin tone
-1F9CD 200D 2642 FE0F ; fully-qualified # 🧍♂️ E12.0 man standing
-1F9CD 200D 2642 ; minimally-qualified # 🧍♂ E12.0 man standing
-1F9CD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧍🏻♂️ E12.0 man standing: light skin tone
-1F9CD 1F3FB 200D 2642 ; minimally-qualified # 🧍🏻♂ E12.0 man standing: light skin tone
-1F9CD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧍🏼♂️ E12.0 man standing: medium-light skin tone
-1F9CD 1F3FC 200D 2642 ; minimally-qualified # 🧍🏼♂ E12.0 man standing: medium-light skin tone
-1F9CD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧍🏽♂️ E12.0 man standing: medium skin tone
-1F9CD 1F3FD 200D 2642 ; minimally-qualified # 🧍🏽♂ E12.0 man standing: medium skin tone
-1F9CD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧍🏾♂️ E12.0 man standing: medium-dark skin tone
-1F9CD 1F3FE 200D 2642 ; minimally-qualified # 🧍🏾♂ E12.0 man standing: medium-dark skin tone
-1F9CD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧍🏿♂️ E12.0 man standing: dark skin tone
-1F9CD 1F3FF 200D 2642 ; minimally-qualified # 🧍🏿♂ E12.0 man standing: dark skin tone
-1F9CD 200D 2640 FE0F ; fully-qualified # 🧍♀️ E12.0 woman standing
-1F9CD 200D 2640 ; minimally-qualified # 🧍♀ E12.0 woman standing
-1F9CD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧍🏻♀️ E12.0 woman standing: light skin tone
-1F9CD 1F3FB 200D 2640 ; minimally-qualified # 🧍🏻♀ E12.0 woman standing: light skin tone
-1F9CD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧍🏼♀️ E12.0 woman standing: medium-light skin tone
-1F9CD 1F3FC 200D 2640 ; minimally-qualified # 🧍🏼♀ E12.0 woman standing: medium-light skin tone
-1F9CD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧍🏽♀️ E12.0 woman standing: medium skin tone
-1F9CD 1F3FD 200D 2640 ; minimally-qualified # 🧍🏽♀ E12.0 woman standing: medium skin tone
-1F9CD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧍🏾♀️ E12.0 woman standing: medium-dark skin tone
-1F9CD 1F3FE 200D 2640 ; minimally-qualified # 🧍🏾♀ E12.0 woman standing: medium-dark skin tone
-1F9CD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧍🏿♀️ E12.0 woman standing: dark skin tone
-1F9CD 1F3FF 200D 2640 ; minimally-qualified # 🧍🏿♀ E12.0 woman standing: dark skin tone
-1F9CE ; fully-qualified # 🧎 E12.0 person kneeling
-1F9CE 1F3FB ; fully-qualified # 🧎🏻 E12.0 person kneeling: light skin tone
-1F9CE 1F3FC ; fully-qualified # 🧎🏼 E12.0 person kneeling: medium-light skin tone
-1F9CE 1F3FD ; fully-qualified # 🧎🏽 E12.0 person kneeling: medium skin tone
-1F9CE 1F3FE ; fully-qualified # 🧎🏾 E12.0 person kneeling: medium-dark skin tone
-1F9CE 1F3FF ; fully-qualified # 🧎🏿 E12.0 person kneeling: dark skin tone
-1F9CE 200D 2642 FE0F ; fully-qualified # 🧎♂️ E12.0 man kneeling
-1F9CE 200D 2642 ; minimally-qualified # 🧎♂ E12.0 man kneeling
-1F9CE 1F3FB 200D 2642 FE0F ; fully-qualified # 🧎🏻♂️ E12.0 man kneeling: light skin tone
-1F9CE 1F3FB 200D 2642 ; minimally-qualified # 🧎🏻♂ E12.0 man kneeling: light skin tone
-1F9CE 1F3FC 200D 2642 FE0F ; fully-qualified # 🧎🏼♂️ E12.0 man kneeling: medium-light skin tone
-1F9CE 1F3FC 200D 2642 ; minimally-qualified # 🧎🏼♂ E12.0 man kneeling: medium-light skin tone
-1F9CE 1F3FD 200D 2642 FE0F ; fully-qualified # 🧎🏽♂️ E12.0 man kneeling: medium skin tone
-1F9CE 1F3FD 200D 2642 ; minimally-qualified # 🧎🏽♂ E12.0 man kneeling: medium skin tone
-1F9CE 1F3FE 200D 2642 FE0F ; fully-qualified # 🧎🏾♂️ E12.0 man kneeling: medium-dark skin tone
-1F9CE 1F3FE 200D 2642 ; minimally-qualified # 🧎🏾♂ E12.0 man kneeling: medium-dark skin tone
-1F9CE 1F3FF 200D 2642 FE0F ; fully-qualified # 🧎🏿♂️ E12.0 man kneeling: dark skin tone
-1F9CE 1F3FF 200D 2642 ; minimally-qualified # 🧎🏿♂ E12.0 man kneeling: dark skin tone
-1F9CE 200D 2640 FE0F ; fully-qualified # 🧎♀️ E12.0 woman kneeling
-1F9CE 200D 2640 ; minimally-qualified # 🧎♀ E12.0 woman kneeling
-1F9CE 1F3FB 200D 2640 FE0F ; fully-qualified # 🧎🏻♀️ E12.0 woman kneeling: light skin tone
-1F9CE 1F3FB 200D 2640 ; minimally-qualified # 🧎🏻♀ E12.0 woman kneeling: light skin tone
-1F9CE 1F3FC 200D 2640 FE0F ; fully-qualified # 🧎🏼♀️ E12.0 woman kneeling: medium-light skin tone
-1F9CE 1F3FC 200D 2640 ; minimally-qualified # 🧎🏼♀ E12.0 woman kneeling: medium-light skin tone
-1F9CE 1F3FD 200D 2640 FE0F ; fully-qualified # 🧎🏽♀️ E12.0 woman kneeling: medium skin tone
-1F9CE 1F3FD 200D 2640 ; minimally-qualified # 🧎🏽♀ E12.0 woman kneeling: medium skin tone
-1F9CE 1F3FE 200D 2640 FE0F ; fully-qualified # 🧎🏾♀️ E12.0 woman kneeling: medium-dark skin tone
-1F9CE 1F3FE 200D 2640 ; minimally-qualified # 🧎🏾♀ E12.0 woman kneeling: medium-dark skin tone
-1F9CE 1F3FF 200D 2640 FE0F ; fully-qualified # 🧎🏿♀️ E12.0 woman kneeling: dark skin tone
-1F9CE 1F3FF 200D 2640 ; minimally-qualified # 🧎🏿♀ E12.0 woman kneeling: dark skin tone
-1F9D1 200D 1F9AF ; fully-qualified # 🧑🦯 E12.1 person with white cane
-1F9D1 1F3FB 200D 1F9AF ; fully-qualified # 🧑🏻🦯 E12.1 person with white cane: light skin tone
-1F9D1 1F3FC 200D 1F9AF ; fully-qualified # 🧑🏼🦯 E12.1 person with white cane: medium-light skin tone
-1F9D1 1F3FD 200D 1F9AF ; fully-qualified # 🧑🏽🦯 E12.1 person with white cane: medium skin tone
-1F9D1 1F3FE 200D 1F9AF ; fully-qualified # 🧑🏾🦯 E12.1 person with white cane: medium-dark skin tone
-1F9D1 1F3FF 200D 1F9AF ; fully-qualified # 🧑🏿🦯 E12.1 person with white cane: dark skin tone
-1F468 200D 1F9AF ; fully-qualified # 👨🦯 E12.0 man with white cane
-1F468 1F3FB 200D 1F9AF ; fully-qualified # 👨🏻🦯 E12.0 man with white cane: light skin tone
-1F468 1F3FC 200D 1F9AF ; fully-qualified # 👨🏼🦯 E12.0 man with white cane: medium-light skin tone
-1F468 1F3FD 200D 1F9AF ; fully-qualified # 👨🏽🦯 E12.0 man with white cane: medium skin tone
-1F468 1F3FE 200D 1F9AF ; fully-qualified # 👨🏾🦯 E12.0 man with white cane: medium-dark skin tone
-1F468 1F3FF 200D 1F9AF ; fully-qualified # 👨🏿🦯 E12.0 man with white cane: dark skin tone
-1F469 200D 1F9AF ; fully-qualified # 👩🦯 E12.0 woman with white cane
-1F469 1F3FB 200D 1F9AF ; fully-qualified # 👩🏻🦯 E12.0 woman with white cane: light skin tone
-1F469 1F3FC 200D 1F9AF ; fully-qualified # 👩🏼🦯 E12.0 woman with white cane: medium-light skin tone
-1F469 1F3FD 200D 1F9AF ; fully-qualified # 👩🏽🦯 E12.0 woman with white cane: medium skin tone
-1F469 1F3FE 200D 1F9AF ; fully-qualified # 👩🏾🦯 E12.0 woman with white cane: medium-dark skin tone
-1F469 1F3FF 200D 1F9AF ; fully-qualified # 👩🏿🦯 E12.0 woman with white cane: dark skin tone
-1F9D1 200D 1F9BC ; fully-qualified # 🧑🦼 E12.1 person in motorized wheelchair
-1F9D1 1F3FB 200D 1F9BC ; fully-qualified # 🧑🏻🦼 E12.1 person in motorized wheelchair: light skin tone
-1F9D1 1F3FC 200D 1F9BC ; fully-qualified # 🧑🏼🦼 E12.1 person in motorized wheelchair: medium-light skin tone
-1F9D1 1F3FD 200D 1F9BC ; fully-qualified # 🧑🏽🦼 E12.1 person in motorized wheelchair: medium skin tone
-1F9D1 1F3FE 200D 1F9BC ; fully-qualified # 🧑🏾🦼 E12.1 person in motorized wheelchair: medium-dark skin tone
-1F9D1 1F3FF 200D 1F9BC ; fully-qualified # 🧑🏿🦼 E12.1 person in motorized wheelchair: dark skin tone
-1F468 200D 1F9BC ; fully-qualified # 👨🦼 E12.0 man in motorized wheelchair
-1F468 1F3FB 200D 1F9BC ; fully-qualified # 👨🏻🦼 E12.0 man in motorized wheelchair: light skin tone
-1F468 1F3FC 200D 1F9BC ; fully-qualified # 👨🏼🦼 E12.0 man in motorized wheelchair: medium-light skin tone
-1F468 1F3FD 200D 1F9BC ; fully-qualified # 👨🏽🦼 E12.0 man in motorized wheelchair: medium skin tone
-1F468 1F3FE 200D 1F9BC ; fully-qualified # 👨🏾🦼 E12.0 man in motorized wheelchair: medium-dark skin tone
-1F468 1F3FF 200D 1F9BC ; fully-qualified # 👨🏿🦼 E12.0 man in motorized wheelchair: dark skin tone
-1F469 200D 1F9BC ; fully-qualified # 👩🦼 E12.0 woman in motorized wheelchair
-1F469 1F3FB 200D 1F9BC ; fully-qualified # 👩🏻🦼 E12.0 woman in motorized wheelchair: light skin tone
-1F469 1F3FC 200D 1F9BC ; fully-qualified # 👩🏼🦼 E12.0 woman in motorized wheelchair: medium-light skin tone
-1F469 1F3FD 200D 1F9BC ; fully-qualified # 👩🏽🦼 E12.0 woman in motorized wheelchair: medium skin tone
-1F469 1F3FE 200D 1F9BC ; fully-qualified # 👩🏾🦼 E12.0 woman in motorized wheelchair: medium-dark skin tone
-1F469 1F3FF 200D 1F9BC ; fully-qualified # 👩🏿🦼 E12.0 woman in motorized wheelchair: dark skin tone
-1F9D1 200D 1F9BD ; fully-qualified # 🧑🦽 E12.1 person in manual wheelchair
-1F9D1 1F3FB 200D 1F9BD ; fully-qualified # 🧑🏻🦽 E12.1 person in manual wheelchair: light skin tone
-1F9D1 1F3FC 200D 1F9BD ; fully-qualified # 🧑🏼🦽 E12.1 person in manual wheelchair: medium-light skin tone
-1F9D1 1F3FD 200D 1F9BD ; fully-qualified # 🧑🏽🦽 E12.1 person in manual wheelchair: medium skin tone
-1F9D1 1F3FE 200D 1F9BD ; fully-qualified # 🧑🏾🦽 E12.1 person in manual wheelchair: medium-dark skin tone
-1F9D1 1F3FF 200D 1F9BD ; fully-qualified # 🧑🏿🦽 E12.1 person in manual wheelchair: dark skin tone
-1F468 200D 1F9BD ; fully-qualified # 👨🦽 E12.0 man in manual wheelchair
-1F468 1F3FB 200D 1F9BD ; fully-qualified # 👨🏻🦽 E12.0 man in manual wheelchair: light skin tone
-1F468 1F3FC 200D 1F9BD ; fully-qualified # 👨🏼🦽 E12.0 man in manual wheelchair: medium-light skin tone
-1F468 1F3FD 200D 1F9BD ; fully-qualified # 👨🏽🦽 E12.0 man in manual wheelchair: medium skin tone
-1F468 1F3FE 200D 1F9BD ; fully-qualified # 👨🏾🦽 E12.0 man in manual wheelchair: medium-dark skin tone
-1F468 1F3FF 200D 1F9BD ; fully-qualified # 👨🏿🦽 E12.0 man in manual wheelchair: dark skin tone
-1F469 200D 1F9BD ; fully-qualified # 👩🦽 E12.0 woman in manual wheelchair
-1F469 1F3FB 200D 1F9BD ; fully-qualified # 👩🏻🦽 E12.0 woman in manual wheelchair: light skin tone
-1F469 1F3FC 200D 1F9BD ; fully-qualified # 👩🏼🦽 E12.0 woman in manual wheelchair: medium-light skin tone
-1F469 1F3FD 200D 1F9BD ; fully-qualified # 👩🏽🦽 E12.0 woman in manual wheelchair: medium skin tone
-1F469 1F3FE 200D 1F9BD ; fully-qualified # 👩🏾🦽 E12.0 woman in manual wheelchair: medium-dark skin tone
-1F469 1F3FF 200D 1F9BD ; fully-qualified # 👩🏿🦽 E12.0 woman in manual wheelchair: dark skin tone
-1F3C3 ; fully-qualified # 🏃 E0.6 person running
-1F3C3 1F3FB ; fully-qualified # 🏃🏻 E1.0 person running: light skin tone
-1F3C3 1F3FC ; fully-qualified # 🏃🏼 E1.0 person running: medium-light skin tone
-1F3C3 1F3FD ; fully-qualified # 🏃🏽 E1.0 person running: medium skin tone
-1F3C3 1F3FE ; fully-qualified # 🏃🏾 E1.0 person running: medium-dark skin tone
-1F3C3 1F3FF ; fully-qualified # 🏃🏿 E1.0 person running: dark skin tone
-1F3C3 200D 2642 FE0F ; fully-qualified # 🏃♂️ E4.0 man running
-1F3C3 200D 2642 ; minimally-qualified # 🏃♂ E4.0 man running
-1F3C3 1F3FB 200D 2642 FE0F ; fully-qualified # 🏃🏻♂️ E4.0 man running: light skin tone
-1F3C3 1F3FB 200D 2642 ; minimally-qualified # 🏃🏻♂ E4.0 man running: light skin tone
-1F3C3 1F3FC 200D 2642 FE0F ; fully-qualified # 🏃🏼♂️ E4.0 man running: medium-light skin tone
-1F3C3 1F3FC 200D 2642 ; minimally-qualified # 🏃🏼♂ E4.0 man running: medium-light skin tone
-1F3C3 1F3FD 200D 2642 FE0F ; fully-qualified # 🏃🏽♂️ E4.0 man running: medium skin tone
-1F3C3 1F3FD 200D 2642 ; minimally-qualified # 🏃🏽♂ E4.0 man running: medium skin tone
-1F3C3 1F3FE 200D 2642 FE0F ; fully-qualified # 🏃🏾♂️ E4.0 man running: medium-dark skin tone
-1F3C3 1F3FE 200D 2642 ; minimally-qualified # 🏃🏾♂ E4.0 man running: medium-dark skin tone
-1F3C3 1F3FF 200D 2642 FE0F ; fully-qualified # 🏃🏿♂️ E4.0 man running: dark skin tone
-1F3C3 1F3FF 200D 2642 ; minimally-qualified # 🏃🏿♂ E4.0 man running: dark skin tone
-1F3C3 200D 2640 FE0F ; fully-qualified # 🏃♀️ E4.0 woman running
-1F3C3 200D 2640 ; minimally-qualified # 🏃♀ E4.0 woman running
-1F3C3 1F3FB 200D 2640 FE0F ; fully-qualified # 🏃🏻♀️ E4.0 woman running: light skin tone
-1F3C3 1F3FB 200D 2640 ; minimally-qualified # 🏃🏻♀ E4.0 woman running: light skin tone
-1F3C3 1F3FC 200D 2640 FE0F ; fully-qualified # 🏃🏼♀️ E4.0 woman running: medium-light skin tone
-1F3C3 1F3FC 200D 2640 ; minimally-qualified # 🏃🏼♀ E4.0 woman running: medium-light skin tone
-1F3C3 1F3FD 200D 2640 FE0F ; fully-qualified # 🏃🏽♀️ E4.0 woman running: medium skin tone
-1F3C3 1F3FD 200D 2640 ; minimally-qualified # 🏃🏽♀ E4.0 woman running: medium skin tone
-1F3C3 1F3FE 200D 2640 FE0F ; fully-qualified # 🏃🏾♀️ E4.0 woman running: medium-dark skin tone
-1F3C3 1F3FE 200D 2640 ; minimally-qualified # 🏃🏾♀ E4.0 woman running: medium-dark skin tone
-1F3C3 1F3FF 200D 2640 FE0F ; fully-qualified # 🏃🏿♀️ E4.0 woman running: dark skin tone
-1F3C3 1F3FF 200D 2640 ; minimally-qualified # 🏃🏿♀ E4.0 woman running: dark skin tone
-1F483 ; fully-qualified # 💃 E0.6 woman dancing
-1F483 1F3FB ; fully-qualified # 💃🏻 E1.0 woman dancing: light skin tone
-1F483 1F3FC ; fully-qualified # 💃🏼 E1.0 woman dancing: medium-light skin tone
-1F483 1F3FD ; fully-qualified # 💃🏽 E1.0 woman dancing: medium skin tone
-1F483 1F3FE ; fully-qualified # 💃🏾 E1.0 woman dancing: medium-dark skin tone
-1F483 1F3FF ; fully-qualified # 💃🏿 E1.0 woman dancing: dark skin tone
-1F57A ; fully-qualified # 🕺 E3.0 man dancing
-1F57A 1F3FB ; fully-qualified # 🕺🏻 E3.0 man dancing: light skin tone
-1F57A 1F3FC ; fully-qualified # 🕺🏼 E3.0 man dancing: medium-light skin tone
-1F57A 1F3FD ; fully-qualified # 🕺🏽 E3.0 man dancing: medium skin tone
-1F57A 1F3FE ; fully-qualified # 🕺🏾 E3.0 man dancing: medium-dark skin tone
-1F57A 1F3FF ; fully-qualified # 🕺🏿 E3.0 man dancing: dark skin tone
-1F574 FE0F ; fully-qualified # 🕴️ E0.7 person in suit levitating
-1F574 ; unqualified # 🕴 E0.7 person in suit levitating
-1F574 1F3FB ; fully-qualified # 🕴🏻 E4.0 person in suit levitating: light skin tone
-1F574 1F3FC ; fully-qualified # 🕴🏼 E4.0 person in suit levitating: medium-light skin tone
-1F574 1F3FD ; fully-qualified # 🕴🏽 E4.0 person in suit levitating: medium skin tone
-1F574 1F3FE ; fully-qualified # 🕴🏾 E4.0 person in suit levitating: medium-dark skin tone
-1F574 1F3FF ; fully-qualified # 🕴🏿 E4.0 person in suit levitating: dark skin tone
-1F46F ; fully-qualified # 👯 E0.6 people with bunny ears
-1F46F 200D 2642 FE0F ; fully-qualified # 👯♂️ E4.0 men with bunny ears
-1F46F 200D 2642 ; minimally-qualified # 👯♂ E4.0 men with bunny ears
-1F46F 200D 2640 FE0F ; fully-qualified # 👯♀️ E4.0 women with bunny ears
-1F46F 200D 2640 ; minimally-qualified # 👯♀ E4.0 women with bunny ears
-1F9D6 ; fully-qualified # 🧖 E5.0 person in steamy room
-1F9D6 1F3FB ; fully-qualified # 🧖🏻 E5.0 person in steamy room: light skin tone
-1F9D6 1F3FC ; fully-qualified # 🧖🏼 E5.0 person in steamy room: medium-light skin tone
-1F9D6 1F3FD ; fully-qualified # 🧖🏽 E5.0 person in steamy room: medium skin tone
-1F9D6 1F3FE ; fully-qualified # 🧖🏾 E5.0 person in steamy room: medium-dark skin tone
-1F9D6 1F3FF ; fully-qualified # 🧖🏿 E5.0 person in steamy room: dark skin tone
-1F9D6 200D 2642 FE0F ; fully-qualified # 🧖♂️ E5.0 man in steamy room
-1F9D6 200D 2642 ; minimally-qualified # 🧖♂ E5.0 man in steamy room
-1F9D6 1F3FB 200D 2642 FE0F ; fully-qualified # 🧖🏻♂️ E5.0 man in steamy room: light skin tone
-1F9D6 1F3FB 200D 2642 ; minimally-qualified # 🧖🏻♂ E5.0 man in steamy room: light skin tone
-1F9D6 1F3FC 200D 2642 FE0F ; fully-qualified # 🧖🏼♂️ E5.0 man in steamy room: medium-light skin tone
-1F9D6 1F3FC 200D 2642 ; minimally-qualified # 🧖🏼♂ E5.0 man in steamy room: medium-light skin tone
-1F9D6 1F3FD 200D 2642 FE0F ; fully-qualified # 🧖🏽♂️ E5.0 man in steamy room: medium skin tone
-1F9D6 1F3FD 200D 2642 ; minimally-qualified # 🧖🏽♂ E5.0 man in steamy room: medium skin tone
-1F9D6 1F3FE 200D 2642 FE0F ; fully-qualified # 🧖🏾♂️ E5.0 man in steamy room: medium-dark skin tone
-1F9D6 1F3FE 200D 2642 ; minimally-qualified # 🧖🏾♂ E5.0 man in steamy room: medium-dark skin tone
-1F9D6 1F3FF 200D 2642 FE0F ; fully-qualified # 🧖🏿♂️ E5.0 man in steamy room: dark skin tone
-1F9D6 1F3FF 200D 2642 ; minimally-qualified # 🧖🏿♂ E5.0 man in steamy room: dark skin tone
-1F9D6 200D 2640 FE0F ; fully-qualified # 🧖♀️ E5.0 woman in steamy room
-1F9D6 200D 2640 ; minimally-qualified # 🧖♀ E5.0 woman in steamy room
-1F9D6 1F3FB 200D 2640 FE0F ; fully-qualified # 🧖🏻♀️ E5.0 woman in steamy room: light skin tone
-1F9D6 1F3FB 200D 2640 ; minimally-qualified # 🧖🏻♀ E5.0 woman in steamy room: light skin tone
-1F9D6 1F3FC 200D 2640 FE0F ; fully-qualified # 🧖🏼♀️ E5.0 woman in steamy room: medium-light skin tone
-1F9D6 1F3FC 200D 2640 ; minimally-qualified # 🧖🏼♀ E5.0 woman in steamy room: medium-light skin tone
-1F9D6 1F3FD 200D 2640 FE0F ; fully-qualified # 🧖🏽♀️ E5.0 woman in steamy room: medium skin tone
-1F9D6 1F3FD 200D 2640 ; minimally-qualified # 🧖🏽♀ E5.0 woman in steamy room: medium skin tone
-1F9D6 1F3FE 200D 2640 FE0F ; fully-qualified # 🧖🏾♀️ E5.0 woman in steamy room: medium-dark skin tone
-1F9D6 1F3FE 200D 2640 ; minimally-qualified # 🧖🏾♀ E5.0 woman in steamy room: medium-dark skin tone
-1F9D6 1F3FF 200D 2640 FE0F ; fully-qualified # 🧖🏿♀️ E5.0 woman in steamy room: dark skin tone
-1F9D6 1F3FF 200D 2640 ; minimally-qualified # 🧖🏿♀ E5.0 woman in steamy room: dark skin tone
-1F9D7 ; fully-qualified # 🧗 E5.0 person climbing
-1F9D7 1F3FB ; fully-qualified # 🧗🏻 E5.0 person climbing: light skin tone
-1F9D7 1F3FC ; fully-qualified # 🧗🏼 E5.0 person climbing: medium-light skin tone
-1F9D7 1F3FD ; fully-qualified # 🧗🏽 E5.0 person climbing: medium skin tone
-1F9D7 1F3FE ; fully-qualified # 🧗🏾 E5.0 person climbing: medium-dark skin tone
-1F9D7 1F3FF ; fully-qualified # 🧗🏿 E5.0 person climbing: dark skin tone
-1F9D7 200D 2642 FE0F ; fully-qualified # 🧗♂️ E5.0 man climbing
-1F9D7 200D 2642 ; minimally-qualified # 🧗♂ E5.0 man climbing
-1F9D7 1F3FB 200D 2642 FE0F ; fully-qualified # 🧗🏻♂️ E5.0 man climbing: light skin tone
-1F9D7 1F3FB 200D 2642 ; minimally-qualified # 🧗🏻♂ E5.0 man climbing: light skin tone
-1F9D7 1F3FC 200D 2642 FE0F ; fully-qualified # 🧗🏼♂️ E5.0 man climbing: medium-light skin tone
-1F9D7 1F3FC 200D 2642 ; minimally-qualified # 🧗🏼♂ E5.0 man climbing: medium-light skin tone
-1F9D7 1F3FD 200D 2642 FE0F ; fully-qualified # 🧗🏽♂️ E5.0 man climbing: medium skin tone
-1F9D7 1F3FD 200D 2642 ; minimally-qualified # 🧗🏽♂ E5.0 man climbing: medium skin tone
-1F9D7 1F3FE 200D 2642 FE0F ; fully-qualified # 🧗🏾♂️ E5.0 man climbing: medium-dark skin tone
-1F9D7 1F3FE 200D 2642 ; minimally-qualified # 🧗🏾♂ E5.0 man climbing: medium-dark skin tone
-1F9D7 1F3FF 200D 2642 FE0F ; fully-qualified # 🧗🏿♂️ E5.0 man climbing: dark skin tone
-1F9D7 1F3FF 200D 2642 ; minimally-qualified # 🧗🏿♂ E5.0 man climbing: dark skin tone
-1F9D7 200D 2640 FE0F ; fully-qualified # 🧗♀️ E5.0 woman climbing
-1F9D7 200D 2640 ; minimally-qualified # 🧗♀ E5.0 woman climbing
-1F9D7 1F3FB 200D 2640 FE0F ; fully-qualified # 🧗🏻♀️ E5.0 woman climbing: light skin tone
-1F9D7 1F3FB 200D 2640 ; minimally-qualified # 🧗🏻♀ E5.0 woman climbing: light skin tone
-1F9D7 1F3FC 200D 2640 FE0F ; fully-qualified # 🧗🏼♀️ E5.0 woman climbing: medium-light skin tone
-1F9D7 1F3FC 200D 2640 ; minimally-qualified # 🧗🏼♀ E5.0 woman climbing: medium-light skin tone
-1F9D7 1F3FD 200D 2640 FE0F ; fully-qualified # 🧗🏽♀️ E5.0 woman climbing: medium skin tone
-1F9D7 1F3FD 200D 2640 ; minimally-qualified # 🧗🏽♀ E5.0 woman climbing: medium skin tone
-1F9D7 1F3FE 200D 2640 FE0F ; fully-qualified # 🧗🏾♀️ E5.0 woman climbing: medium-dark skin tone
-1F9D7 1F3FE 200D 2640 ; minimally-qualified # 🧗🏾♀ E5.0 woman climbing: medium-dark skin tone
-1F9D7 1F3FF 200D 2640 FE0F ; fully-qualified # 🧗🏿♀️ E5.0 woman climbing: dark skin tone
-1F9D7 1F3FF 200D 2640 ; minimally-qualified # 🧗🏿♀ E5.0 woman climbing: dark skin tone
+1F486 ; fully-qualified # 💆 E0.6 person getting massage
+1F486 1F3FB ; fully-qualified # 💆🏻 E1.0 person getting massage: light skin tone
+1F486 1F3FC ; fully-qualified # 💆🏼 E1.0 person getting massage: medium-light skin tone
+1F486 1F3FD ; fully-qualified # 💆🏽 E1.0 person getting massage: medium skin tone
+1F486 1F3FE ; fully-qualified # 💆🏾 E1.0 person getting massage: medium-dark skin tone
+1F486 1F3FF ; fully-qualified # 💆🏿 E1.0 person getting massage: dark skin tone
+1F486 200D 2642 FE0F ; fully-qualified # 💆♂️ E4.0 man getting massage
+1F486 200D 2642 ; minimally-qualified # 💆♂ E4.0 man getting massage
+1F486 1F3FB 200D 2642 FE0F ; fully-qualified # 💆🏻♂️ E4.0 man getting massage: light skin tone
+1F486 1F3FB 200D 2642 ; minimally-qualified # 💆🏻♂ E4.0 man getting massage: light skin tone
+1F486 1F3FC 200D 2642 FE0F ; fully-qualified # 💆🏼♂️ E4.0 man getting massage: medium-light skin tone
+1F486 1F3FC 200D 2642 ; minimally-qualified # 💆🏼♂ E4.0 man getting massage: medium-light skin tone
+1F486 1F3FD 200D 2642 FE0F ; fully-qualified # 💆🏽♂️ E4.0 man getting massage: medium skin tone
+1F486 1F3FD 200D 2642 ; minimally-qualified # 💆🏽♂ E4.0 man getting massage: medium skin tone
+1F486 1F3FE 200D 2642 FE0F ; fully-qualified # 💆🏾♂️ E4.0 man getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2642 ; minimally-qualified # 💆🏾♂ E4.0 man getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2642 FE0F ; fully-qualified # 💆🏿♂️ E4.0 man getting massage: dark skin tone
+1F486 1F3FF 200D 2642 ; minimally-qualified # 💆🏿♂ E4.0 man getting massage: dark skin tone
+1F486 200D 2640 FE0F ; fully-qualified # 💆♀️ E4.0 woman getting massage
+1F486 200D 2640 ; minimally-qualified # 💆♀ E4.0 woman getting massage
+1F486 1F3FB 200D 2640 FE0F ; fully-qualified # 💆🏻♀️ E4.0 woman getting massage: light skin tone
+1F486 1F3FB 200D 2640 ; minimally-qualified # 💆🏻♀ E4.0 woman getting massage: light skin tone
+1F486 1F3FC 200D 2640 FE0F ; fully-qualified # 💆🏼♀️ E4.0 woman getting massage: medium-light skin tone
+1F486 1F3FC 200D 2640 ; minimally-qualified # 💆🏼♀ E4.0 woman getting massage: medium-light skin tone
+1F486 1F3FD 200D 2640 FE0F ; fully-qualified # 💆🏽♀️ E4.0 woman getting massage: medium skin tone
+1F486 1F3FD 200D 2640 ; minimally-qualified # 💆🏽♀ E4.0 woman getting massage: medium skin tone
+1F486 1F3FE 200D 2640 FE0F ; fully-qualified # 💆🏾♀️ E4.0 woman getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2640 ; minimally-qualified # 💆🏾♀ E4.0 woman getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2640 FE0F ; fully-qualified # 💆🏿♀️ E4.0 woman getting massage: dark skin tone
+1F486 1F3FF 200D 2640 ; minimally-qualified # 💆🏿♀ E4.0 woman getting massage: dark skin tone
+1F487 ; fully-qualified # 💇 E0.6 person getting haircut
+1F487 1F3FB ; fully-qualified # 💇🏻 E1.0 person getting haircut: light skin tone
+1F487 1F3FC ; fully-qualified # 💇🏼 E1.0 person getting haircut: medium-light skin tone
+1F487 1F3FD ; fully-qualified # 💇🏽 E1.0 person getting haircut: medium skin tone
+1F487 1F3FE ; fully-qualified # 💇🏾 E1.0 person getting haircut: medium-dark skin tone
+1F487 1F3FF ; fully-qualified # 💇🏿 E1.0 person getting haircut: dark skin tone
+1F487 200D 2642 FE0F ; fully-qualified # 💇♂️ E4.0 man getting haircut
+1F487 200D 2642 ; minimally-qualified # 💇♂ E4.0 man getting haircut
+1F487 1F3FB 200D 2642 FE0F ; fully-qualified # 💇🏻♂️ E4.0 man getting haircut: light skin tone
+1F487 1F3FB 200D 2642 ; minimally-qualified # 💇🏻♂ E4.0 man getting haircut: light skin tone
+1F487 1F3FC 200D 2642 FE0F ; fully-qualified # 💇🏼♂️ E4.0 man getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2642 ; minimally-qualified # 💇🏼♂ E4.0 man getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2642 FE0F ; fully-qualified # 💇🏽♂️ E4.0 man getting haircut: medium skin tone
+1F487 1F3FD 200D 2642 ; minimally-qualified # 💇🏽♂ E4.0 man getting haircut: medium skin tone
+1F487 1F3FE 200D 2642 FE0F ; fully-qualified # 💇🏾♂️ E4.0 man getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2642 ; minimally-qualified # 💇🏾♂ E4.0 man getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2642 FE0F ; fully-qualified # 💇🏿♂️ E4.0 man getting haircut: dark skin tone
+1F487 1F3FF 200D 2642 ; minimally-qualified # 💇🏿♂ E4.0 man getting haircut: dark skin tone
+1F487 200D 2640 FE0F ; fully-qualified # 💇♀️ E4.0 woman getting haircut
+1F487 200D 2640 ; minimally-qualified # 💇♀ E4.0 woman getting haircut
+1F487 1F3FB 200D 2640 FE0F ; fully-qualified # 💇🏻♀️ E4.0 woman getting haircut: light skin tone
+1F487 1F3FB 200D 2640 ; minimally-qualified # 💇🏻♀ E4.0 woman getting haircut: light skin tone
+1F487 1F3FC 200D 2640 FE0F ; fully-qualified # 💇🏼♀️ E4.0 woman getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2640 ; minimally-qualified # 💇🏼♀ E4.0 woman getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2640 FE0F ; fully-qualified # 💇🏽♀️ E4.0 woman getting haircut: medium skin tone
+1F487 1F3FD 200D 2640 ; minimally-qualified # 💇🏽♀ E4.0 woman getting haircut: medium skin tone
+1F487 1F3FE 200D 2640 FE0F ; fully-qualified # 💇🏾♀️ E4.0 woman getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2640 ; minimally-qualified # 💇🏾♀ E4.0 woman getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2640 FE0F ; fully-qualified # 💇🏿♀️ E4.0 woman getting haircut: dark skin tone
+1F487 1F3FF 200D 2640 ; minimally-qualified # 💇🏿♀ E4.0 woman getting haircut: dark skin tone
+1F6B6 ; fully-qualified # 🚶 E0.6 person walking
+1F6B6 1F3FB ; fully-qualified # 🚶🏻 E1.0 person walking: light skin tone
+1F6B6 1F3FC ; fully-qualified # 🚶🏼 E1.0 person walking: medium-light skin tone
+1F6B6 1F3FD ; fully-qualified # 🚶🏽 E1.0 person walking: medium skin tone
+1F6B6 1F3FE ; fully-qualified # 🚶🏾 E1.0 person walking: medium-dark skin tone
+1F6B6 1F3FF ; fully-qualified # 🚶🏿 E1.0 person walking: dark skin tone
+1F6B6 200D 2642 FE0F ; fully-qualified # 🚶♂️ E4.0 man walking
+1F6B6 200D 2642 ; minimally-qualified # 🚶♂ E4.0 man walking
+1F6B6 1F3FB 200D 2642 FE0F ; fully-qualified # 🚶🏻♂️ E4.0 man walking: light skin tone
+1F6B6 1F3FB 200D 2642 ; minimally-qualified # 🚶🏻♂ E4.0 man walking: light skin tone
+1F6B6 1F3FC 200D 2642 FE0F ; fully-qualified # 🚶🏼♂️ E4.0 man walking: medium-light skin tone
+1F6B6 1F3FC 200D 2642 ; minimally-qualified # 🚶🏼♂ E4.0 man walking: medium-light skin tone
+1F6B6 1F3FD 200D 2642 FE0F ; fully-qualified # 🚶🏽♂️ E4.0 man walking: medium skin tone
+1F6B6 1F3FD 200D 2642 ; minimally-qualified # 🚶🏽♂ E4.0 man walking: medium skin tone
+1F6B6 1F3FE 200D 2642 FE0F ; fully-qualified # 🚶🏾♂️ E4.0 man walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2642 ; minimally-qualified # 🚶🏾♂ E4.0 man walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2642 FE0F ; fully-qualified # 🚶🏿♂️ E4.0 man walking: dark skin tone
+1F6B6 1F3FF 200D 2642 ; minimally-qualified # 🚶🏿♂ E4.0 man walking: dark skin tone
+1F6B6 200D 2640 FE0F ; fully-qualified # 🚶♀️ E4.0 woman walking
+1F6B6 200D 2640 ; minimally-qualified # 🚶♀ E4.0 woman walking
+1F6B6 1F3FB 200D 2640 FE0F ; fully-qualified # 🚶🏻♀️ E4.0 woman walking: light skin tone
+1F6B6 1F3FB 200D 2640 ; minimally-qualified # 🚶🏻♀ E4.0 woman walking: light skin tone
+1F6B6 1F3FC 200D 2640 FE0F ; fully-qualified # 🚶🏼♀️ E4.0 woman walking: medium-light skin tone
+1F6B6 1F3FC 200D 2640 ; minimally-qualified # 🚶🏼♀ E4.0 woman walking: medium-light skin tone
+1F6B6 1F3FD 200D 2640 FE0F ; fully-qualified # 🚶🏽♀️ E4.0 woman walking: medium skin tone
+1F6B6 1F3FD 200D 2640 ; minimally-qualified # 🚶🏽♀ E4.0 woman walking: medium skin tone
+1F6B6 1F3FE 200D 2640 FE0F ; fully-qualified # 🚶🏾♀️ E4.0 woman walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2640 ; minimally-qualified # 🚶🏾♀ E4.0 woman walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2640 FE0F ; fully-qualified # 🚶🏿♀️ E4.0 woman walking: dark skin tone
+1F6B6 1F3FF 200D 2640 ; minimally-qualified # 🚶🏿♀ E4.0 woman walking: dark skin tone
+1F9CD ; fully-qualified # 🧍 E12.0 person standing
+1F9CD 1F3FB ; fully-qualified # 🧍🏻 E12.0 person standing: light skin tone
+1F9CD 1F3FC ; fully-qualified # 🧍🏼 E12.0 person standing: medium-light skin tone
+1F9CD 1F3FD ; fully-qualified # 🧍🏽 E12.0 person standing: medium skin tone
+1F9CD 1F3FE ; fully-qualified # 🧍🏾 E12.0 person standing: medium-dark skin tone
+1F9CD 1F3FF ; fully-qualified # 🧍🏿 E12.0 person standing: dark skin tone
+1F9CD 200D 2642 FE0F ; fully-qualified # 🧍♂️ E12.0 man standing
+1F9CD 200D 2642 ; minimally-qualified # 🧍♂ E12.0 man standing
+1F9CD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧍🏻♂️ E12.0 man standing: light skin tone
+1F9CD 1F3FB 200D 2642 ; minimally-qualified # 🧍🏻♂ E12.0 man standing: light skin tone
+1F9CD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧍🏼♂️ E12.0 man standing: medium-light skin tone
+1F9CD 1F3FC 200D 2642 ; minimally-qualified # 🧍🏼♂ E12.0 man standing: medium-light skin tone
+1F9CD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧍🏽♂️ E12.0 man standing: medium skin tone
+1F9CD 1F3FD 200D 2642 ; minimally-qualified # 🧍🏽♂ E12.0 man standing: medium skin tone
+1F9CD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧍🏾♂️ E12.0 man standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2642 ; minimally-qualified # 🧍🏾♂ E12.0 man standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧍🏿♂️ E12.0 man standing: dark skin tone
+1F9CD 1F3FF 200D 2642 ; minimally-qualified # 🧍🏿♂ E12.0 man standing: dark skin tone
+1F9CD 200D 2640 FE0F ; fully-qualified # 🧍♀️ E12.0 woman standing
+1F9CD 200D 2640 ; minimally-qualified # 🧍♀ E12.0 woman standing
+1F9CD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧍🏻♀️ E12.0 woman standing: light skin tone
+1F9CD 1F3FB 200D 2640 ; minimally-qualified # 🧍🏻♀ E12.0 woman standing: light skin tone
+1F9CD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧍🏼♀️ E12.0 woman standing: medium-light skin tone
+1F9CD 1F3FC 200D 2640 ; minimally-qualified # 🧍🏼♀ E12.0 woman standing: medium-light skin tone
+1F9CD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧍🏽♀️ E12.0 woman standing: medium skin tone
+1F9CD 1F3FD 200D 2640 ; minimally-qualified # 🧍🏽♀ E12.0 woman standing: medium skin tone
+1F9CD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧍🏾♀️ E12.0 woman standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2640 ; minimally-qualified # 🧍🏾♀ E12.0 woman standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧍🏿♀️ E12.0 woman standing: dark skin tone
+1F9CD 1F3FF 200D 2640 ; minimally-qualified # 🧍🏿♀ E12.0 woman standing: dark skin tone
+1F9CE ; fully-qualified # 🧎 E12.0 person kneeling
+1F9CE 1F3FB ; fully-qualified # 🧎🏻 E12.0 person kneeling: light skin tone
+1F9CE 1F3FC ; fully-qualified # 🧎🏼 E12.0 person kneeling: medium-light skin tone
+1F9CE 1F3FD ; fully-qualified # 🧎🏽 E12.0 person kneeling: medium skin tone
+1F9CE 1F3FE ; fully-qualified # 🧎🏾 E12.0 person kneeling: medium-dark skin tone
+1F9CE 1F3FF ; fully-qualified # 🧎🏿 E12.0 person kneeling: dark skin tone
+1F9CE 200D 2642 FE0F ; fully-qualified # 🧎♂️ E12.0 man kneeling
+1F9CE 200D 2642 ; minimally-qualified # 🧎♂ E12.0 man kneeling
+1F9CE 1F3FB 200D 2642 FE0F ; fully-qualified # 🧎🏻♂️ E12.0 man kneeling: light skin tone
+1F9CE 1F3FB 200D 2642 ; minimally-qualified # 🧎🏻♂ E12.0 man kneeling: light skin tone
+1F9CE 1F3FC 200D 2642 FE0F ; fully-qualified # 🧎🏼♂️ E12.0 man kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2642 ; minimally-qualified # 🧎🏼♂ E12.0 man kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2642 FE0F ; fully-qualified # 🧎🏽♂️ E12.0 man kneeling: medium skin tone
+1F9CE 1F3FD 200D 2642 ; minimally-qualified # 🧎🏽♂ E12.0 man kneeling: medium skin tone
+1F9CE 1F3FE 200D 2642 FE0F ; fully-qualified # 🧎🏾♂️ E12.0 man kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2642 ; minimally-qualified # 🧎🏾♂ E12.0 man kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2642 FE0F ; fully-qualified # 🧎🏿♂️ E12.0 man kneeling: dark skin tone
+1F9CE 1F3FF 200D 2642 ; minimally-qualified # 🧎🏿♂ E12.0 man kneeling: dark skin tone
+1F9CE 200D 2640 FE0F ; fully-qualified # 🧎♀️ E12.0 woman kneeling
+1F9CE 200D 2640 ; minimally-qualified # 🧎♀ E12.0 woman kneeling
+1F9CE 1F3FB 200D 2640 FE0F ; fully-qualified # 🧎🏻♀️ E12.0 woman kneeling: light skin tone
+1F9CE 1F3FB 200D 2640 ; minimally-qualified # 🧎🏻♀ E12.0 woman kneeling: light skin tone
+1F9CE 1F3FC 200D 2640 FE0F ; fully-qualified # 🧎🏼♀️ E12.0 woman kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2640 ; minimally-qualified # 🧎🏼♀ E12.0 woman kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2640 FE0F ; fully-qualified # 🧎🏽♀️ E12.0 woman kneeling: medium skin tone
+1F9CE 1F3FD 200D 2640 ; minimally-qualified # 🧎🏽♀ E12.0 woman kneeling: medium skin tone
+1F9CE 1F3FE 200D 2640 FE0F ; fully-qualified # 🧎🏾♀️ E12.0 woman kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2640 ; minimally-qualified # 🧎🏾♀ E12.0 woman kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2640 FE0F ; fully-qualified # 🧎🏿♀️ E12.0 woman kneeling: dark skin tone
+1F9CE 1F3FF 200D 2640 ; minimally-qualified # 🧎🏿♀ E12.0 woman kneeling: dark skin tone
+1F9D1 200D 1F9AF ; fully-qualified # 🧑🦯 E12.1 person with white cane
+1F9D1 1F3FB 200D 1F9AF ; fully-qualified # 🧑🏻🦯 E12.1 person with white cane: light skin tone
+1F9D1 1F3FC 200D 1F9AF ; fully-qualified # 🧑🏼🦯 E12.1 person with white cane: medium-light skin tone
+1F9D1 1F3FD 200D 1F9AF ; fully-qualified # 🧑🏽🦯 E12.1 person with white cane: medium skin tone
+1F9D1 1F3FE 200D 1F9AF ; fully-qualified # 🧑🏾🦯 E12.1 person with white cane: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9AF ; fully-qualified # 🧑🏿🦯 E12.1 person with white cane: dark skin tone
+1F468 200D 1F9AF ; fully-qualified # 👨🦯 E12.0 man with white cane
+1F468 1F3FB 200D 1F9AF ; fully-qualified # 👨🏻🦯 E12.0 man with white cane: light skin tone
+1F468 1F3FC 200D 1F9AF ; fully-qualified # 👨🏼🦯 E12.0 man with white cane: medium-light skin tone
+1F468 1F3FD 200D 1F9AF ; fully-qualified # 👨🏽🦯 E12.0 man with white cane: medium skin tone
+1F468 1F3FE 200D 1F9AF ; fully-qualified # 👨🏾🦯 E12.0 man with white cane: medium-dark skin tone
+1F468 1F3FF 200D 1F9AF ; fully-qualified # 👨🏿🦯 E12.0 man with white cane: dark skin tone
+1F469 200D 1F9AF ; fully-qualified # 👩🦯 E12.0 woman with white cane
+1F469 1F3FB 200D 1F9AF ; fully-qualified # 👩🏻🦯 E12.0 woman with white cane: light skin tone
+1F469 1F3FC 200D 1F9AF ; fully-qualified # 👩🏼🦯 E12.0 woman with white cane: medium-light skin tone
+1F469 1F3FD 200D 1F9AF ; fully-qualified # 👩🏽🦯 E12.0 woman with white cane: medium skin tone
+1F469 1F3FE 200D 1F9AF ; fully-qualified # 👩🏾🦯 E12.0 woman with white cane: medium-dark skin tone
+1F469 1F3FF 200D 1F9AF ; fully-qualified # 👩🏿🦯 E12.0 woman with white cane: dark skin tone
+1F9D1 200D 1F9BC ; fully-qualified # 🧑🦼 E12.1 person in motorized wheelchair
+1F9D1 1F3FB 200D 1F9BC ; fully-qualified # 🧑🏻🦼 E12.1 person in motorized wheelchair: light skin tone
+1F9D1 1F3FC 200D 1F9BC ; fully-qualified # 🧑🏼🦼 E12.1 person in motorized wheelchair: medium-light skin tone
+1F9D1 1F3FD 200D 1F9BC ; fully-qualified # 🧑🏽🦼 E12.1 person in motorized wheelchair: medium skin tone
+1F9D1 1F3FE 200D 1F9BC ; fully-qualified # 🧑🏾🦼 E12.1 person in motorized wheelchair: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9BC ; fully-qualified # 🧑🏿🦼 E12.1 person in motorized wheelchair: dark skin tone
+1F468 200D 1F9BC ; fully-qualified # 👨🦼 E12.0 man in motorized wheelchair
+1F468 1F3FB 200D 1F9BC ; fully-qualified # 👨🏻🦼 E12.0 man in motorized wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BC ; fully-qualified # 👨🏼🦼 E12.0 man in motorized wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BC ; fully-qualified # 👨🏽🦼 E12.0 man in motorized wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BC ; fully-qualified # 👨🏾🦼 E12.0 man in motorized wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BC ; fully-qualified # 👨🏿🦼 E12.0 man in motorized wheelchair: dark skin tone
+1F469 200D 1F9BC ; fully-qualified # 👩🦼 E12.0 woman in motorized wheelchair
+1F469 1F3FB 200D 1F9BC ; fully-qualified # 👩🏻🦼 E12.0 woman in motorized wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BC ; fully-qualified # 👩🏼🦼 E12.0 woman in motorized wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BC ; fully-qualified # 👩🏽🦼 E12.0 woman in motorized wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BC ; fully-qualified # 👩🏾🦼 E12.0 woman in motorized wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BC ; fully-qualified # 👩🏿🦼 E12.0 woman in motorized wheelchair: dark skin tone
+1F9D1 200D 1F9BD ; fully-qualified # 🧑🦽 E12.1 person in manual wheelchair
+1F9D1 1F3FB 200D 1F9BD ; fully-qualified # 🧑🏻🦽 E12.1 person in manual wheelchair: light skin tone
+1F9D1 1F3FC 200D 1F9BD ; fully-qualified # 🧑🏼🦽 E12.1 person in manual wheelchair: medium-light skin tone
+1F9D1 1F3FD 200D 1F9BD ; fully-qualified # 🧑🏽🦽 E12.1 person in manual wheelchair: medium skin tone
+1F9D1 1F3FE 200D 1F9BD ; fully-qualified # 🧑🏾🦽 E12.1 person in manual wheelchair: medium-dark skin tone
+1F9D1 1F3FF 200D 1F9BD ; fully-qualified # 🧑🏿🦽 E12.1 person in manual wheelchair: dark skin tone
+1F468 200D 1F9BD ; fully-qualified # 👨🦽 E12.0 man in manual wheelchair
+1F468 1F3FB 200D 1F9BD ; fully-qualified # 👨🏻🦽 E12.0 man in manual wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BD ; fully-qualified # 👨🏼🦽 E12.0 man in manual wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BD ; fully-qualified # 👨🏽🦽 E12.0 man in manual wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BD ; fully-qualified # 👨🏾🦽 E12.0 man in manual wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BD ; fully-qualified # 👨🏿🦽 E12.0 man in manual wheelchair: dark skin tone
+1F469 200D 1F9BD ; fully-qualified # 👩🦽 E12.0 woman in manual wheelchair
+1F469 1F3FB 200D 1F9BD ; fully-qualified # 👩🏻🦽 E12.0 woman in manual wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BD ; fully-qualified # 👩🏼🦽 E12.0 woman in manual wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BD ; fully-qualified # 👩🏽🦽 E12.0 woman in manual wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BD ; fully-qualified # 👩🏾🦽 E12.0 woman in manual wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BD ; fully-qualified # 👩🏿🦽 E12.0 woman in manual wheelchair: dark skin tone
+1F3C3 ; fully-qualified # 🏃 E0.6 person running
+1F3C3 1F3FB ; fully-qualified # 🏃🏻 E1.0 person running: light skin tone
+1F3C3 1F3FC ; fully-qualified # 🏃🏼 E1.0 person running: medium-light skin tone
+1F3C3 1F3FD ; fully-qualified # 🏃🏽 E1.0 person running: medium skin tone
+1F3C3 1F3FE ; fully-qualified # 🏃🏾 E1.0 person running: medium-dark skin tone
+1F3C3 1F3FF ; fully-qualified # 🏃🏿 E1.0 person running: dark skin tone
+1F3C3 200D 2642 FE0F ; fully-qualified # 🏃♂️ E4.0 man running
+1F3C3 200D 2642 ; minimally-qualified # 🏃♂ E4.0 man running
+1F3C3 1F3FB 200D 2642 FE0F ; fully-qualified # 🏃🏻♂️ E4.0 man running: light skin tone
+1F3C3 1F3FB 200D 2642 ; minimally-qualified # 🏃🏻♂ E4.0 man running: light skin tone
+1F3C3 1F3FC 200D 2642 FE0F ; fully-qualified # 🏃🏼♂️ E4.0 man running: medium-light skin tone
+1F3C3 1F3FC 200D 2642 ; minimally-qualified # 🏃🏼♂ E4.0 man running: medium-light skin tone
+1F3C3 1F3FD 200D 2642 FE0F ; fully-qualified # 🏃🏽♂️ E4.0 man running: medium skin tone
+1F3C3 1F3FD 200D 2642 ; minimally-qualified # 🏃🏽♂ E4.0 man running: medium skin tone
+1F3C3 1F3FE 200D 2642 FE0F ; fully-qualified # 🏃🏾♂️ E4.0 man running: medium-dark skin tone
+1F3C3 1F3FE 200D 2642 ; minimally-qualified # 🏃🏾♂ E4.0 man running: medium-dark skin tone
+1F3C3 1F3FF 200D 2642 FE0F ; fully-qualified # 🏃🏿♂️ E4.0 man running: dark skin tone
+1F3C3 1F3FF 200D 2642 ; minimally-qualified # 🏃🏿♂ E4.0 man running: dark skin tone
+1F3C3 200D 2640 FE0F ; fully-qualified # 🏃♀️ E4.0 woman running
+1F3C3 200D 2640 ; minimally-qualified # 🏃♀ E4.0 woman running
+1F3C3 1F3FB 200D 2640 FE0F ; fully-qualified # 🏃🏻♀️ E4.0 woman running: light skin tone
+1F3C3 1F3FB 200D 2640 ; minimally-qualified # 🏃🏻♀ E4.0 woman running: light skin tone
+1F3C3 1F3FC 200D 2640 FE0F ; fully-qualified # 🏃🏼♀️ E4.0 woman running: medium-light skin tone
+1F3C3 1F3FC 200D 2640 ; minimally-qualified # 🏃🏼♀ E4.0 woman running: medium-light skin tone
+1F3C3 1F3FD 200D 2640 FE0F ; fully-qualified # 🏃🏽♀️ E4.0 woman running: medium skin tone
+1F3C3 1F3FD 200D 2640 ; minimally-qualified # 🏃🏽♀ E4.0 woman running: medium skin tone
+1F3C3 1F3FE 200D 2640 FE0F ; fully-qualified # 🏃🏾♀️ E4.0 woman running: medium-dark skin tone
+1F3C3 1F3FE 200D 2640 ; minimally-qualified # 🏃🏾♀ E4.0 woman running: medium-dark skin tone
+1F3C3 1F3FF 200D 2640 FE0F ; fully-qualified # 🏃🏿♀️ E4.0 woman running: dark skin tone
+1F3C3 1F3FF 200D 2640 ; minimally-qualified # 🏃🏿♀ E4.0 woman running: dark skin tone
+1F483 ; fully-qualified # 💃 E0.6 woman dancing
+1F483 1F3FB ; fully-qualified # 💃🏻 E1.0 woman dancing: light skin tone
+1F483 1F3FC ; fully-qualified # 💃🏼 E1.0 woman dancing: medium-light skin tone
+1F483 1F3FD ; fully-qualified # 💃🏽 E1.0 woman dancing: medium skin tone
+1F483 1F3FE ; fully-qualified # 💃🏾 E1.0 woman dancing: medium-dark skin tone
+1F483 1F3FF ; fully-qualified # 💃🏿 E1.0 woman dancing: dark skin tone
+1F57A ; fully-qualified # 🕺 E3.0 man dancing
+1F57A 1F3FB ; fully-qualified # 🕺🏻 E3.0 man dancing: light skin tone
+1F57A 1F3FC ; fully-qualified # 🕺🏼 E3.0 man dancing: medium-light skin tone
+1F57A 1F3FD ; fully-qualified # 🕺🏽 E3.0 man dancing: medium skin tone
+1F57A 1F3FE ; fully-qualified # 🕺🏾 E3.0 man dancing: medium-dark skin tone
+1F57A 1F3FF ; fully-qualified # 🕺🏿 E3.0 man dancing: dark skin tone
+1F574 FE0F ; fully-qualified # 🕴️ E0.7 person in suit levitating
+1F574 ; unqualified # 🕴 E0.7 person in suit levitating
+1F574 1F3FB ; fully-qualified # 🕴🏻 E4.0 person in suit levitating: light skin tone
+1F574 1F3FC ; fully-qualified # 🕴🏼 E4.0 person in suit levitating: medium-light skin tone
+1F574 1F3FD ; fully-qualified # 🕴🏽 E4.0 person in suit levitating: medium skin tone
+1F574 1F3FE ; fully-qualified # 🕴🏾 E4.0 person in suit levitating: medium-dark skin tone
+1F574 1F3FF ; fully-qualified # 🕴🏿 E4.0 person in suit levitating: dark skin tone
+1F46F ; fully-qualified # 👯 E0.6 people with bunny ears
+1F46F 200D 2642 FE0F ; fully-qualified # 👯♂️ E4.0 men with bunny ears
+1F46F 200D 2642 ; minimally-qualified # 👯♂ E4.0 men with bunny ears
+1F46F 200D 2640 FE0F ; fully-qualified # 👯♀️ E4.0 women with bunny ears
+1F46F 200D 2640 ; minimally-qualified # 👯♀ E4.0 women with bunny ears
+1F9D6 ; fully-qualified # 🧖 E5.0 person in steamy room
+1F9D6 1F3FB ; fully-qualified # 🧖🏻 E5.0 person in steamy room: light skin tone
+1F9D6 1F3FC ; fully-qualified # 🧖🏼 E5.0 person in steamy room: medium-light skin tone
+1F9D6 1F3FD ; fully-qualified # 🧖🏽 E5.0 person in steamy room: medium skin tone
+1F9D6 1F3FE ; fully-qualified # 🧖🏾 E5.0 person in steamy room: medium-dark skin tone
+1F9D6 1F3FF ; fully-qualified # 🧖🏿 E5.0 person in steamy room: dark skin tone
+1F9D6 200D 2642 FE0F ; fully-qualified # 🧖♂️ E5.0 man in steamy room
+1F9D6 200D 2642 ; minimally-qualified # 🧖♂ E5.0 man in steamy room
+1F9D6 1F3FB 200D 2642 FE0F ; fully-qualified # 🧖🏻♂️ E5.0 man in steamy room: light skin tone
+1F9D6 1F3FB 200D 2642 ; minimally-qualified # 🧖🏻♂ E5.0 man in steamy room: light skin tone
+1F9D6 1F3FC 200D 2642 FE0F ; fully-qualified # 🧖🏼♂️ E5.0 man in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2642 ; minimally-qualified # 🧖🏼♂ E5.0 man in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2642 FE0F ; fully-qualified # 🧖🏽♂️ E5.0 man in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2642 ; minimally-qualified # 🧖🏽♂ E5.0 man in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2642 FE0F ; fully-qualified # 🧖🏾♂️ E5.0 man in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2642 ; minimally-qualified # 🧖🏾♂ E5.0 man in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2642 FE0F ; fully-qualified # 🧖🏿♂️ E5.0 man in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2642 ; minimally-qualified # 🧖🏿♂ E5.0 man in steamy room: dark skin tone
+1F9D6 200D 2640 FE0F ; fully-qualified # 🧖♀️ E5.0 woman in steamy room
+1F9D6 200D 2640 ; minimally-qualified # 🧖♀ E5.0 woman in steamy room
+1F9D6 1F3FB 200D 2640 FE0F ; fully-qualified # 🧖🏻♀️ E5.0 woman in steamy room: light skin tone
+1F9D6 1F3FB 200D 2640 ; minimally-qualified # 🧖🏻♀ E5.0 woman in steamy room: light skin tone
+1F9D6 1F3FC 200D 2640 FE0F ; fully-qualified # 🧖🏼♀️ E5.0 woman in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2640 ; minimally-qualified # 🧖🏼♀ E5.0 woman in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2640 FE0F ; fully-qualified # 🧖🏽♀️ E5.0 woman in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2640 ; minimally-qualified # 🧖🏽♀ E5.0 woman in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2640 FE0F ; fully-qualified # 🧖🏾♀️ E5.0 woman in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2640 ; minimally-qualified # 🧖🏾♀ E5.0 woman in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2640 FE0F ; fully-qualified # 🧖🏿♀️ E5.0 woman in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2640 ; minimally-qualified # 🧖🏿♀ E5.0 woman in steamy room: dark skin tone
+1F9D7 ; fully-qualified # 🧗 E5.0 person climbing
+1F9D7 1F3FB ; fully-qualified # 🧗🏻 E5.0 person climbing: light skin tone
+1F9D7 1F3FC ; fully-qualified # 🧗🏼 E5.0 person climbing: medium-light skin tone
+1F9D7 1F3FD ; fully-qualified # 🧗🏽 E5.0 person climbing: medium skin tone
+1F9D7 1F3FE ; fully-qualified # 🧗🏾 E5.0 person climbing: medium-dark skin tone
+1F9D7 1F3FF ; fully-qualified # 🧗🏿 E5.0 person climbing: dark skin tone
+1F9D7 200D 2642 FE0F ; fully-qualified # 🧗♂️ E5.0 man climbing
+1F9D7 200D 2642 ; minimally-qualified # 🧗♂ E5.0 man climbing
+1F9D7 1F3FB 200D 2642 FE0F ; fully-qualified # 🧗🏻♂️ E5.0 man climbing: light skin tone
+1F9D7 1F3FB 200D 2642 ; minimally-qualified # 🧗🏻♂ E5.0 man climbing: light skin tone
+1F9D7 1F3FC 200D 2642 FE0F ; fully-qualified # 🧗🏼♂️ E5.0 man climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2642 ; minimally-qualified # 🧗🏼♂ E5.0 man climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2642 FE0F ; fully-qualified # 🧗🏽♂️ E5.0 man climbing: medium skin tone
+1F9D7 1F3FD 200D 2642 ; minimally-qualified # 🧗🏽♂ E5.0 man climbing: medium skin tone
+1F9D7 1F3FE 200D 2642 FE0F ; fully-qualified # 🧗🏾♂️ E5.0 man climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2642 ; minimally-qualified # 🧗🏾♂ E5.0 man climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2642 FE0F ; fully-qualified # 🧗🏿♂️ E5.0 man climbing: dark skin tone
+1F9D7 1F3FF 200D 2642 ; minimally-qualified # 🧗🏿♂ E5.0 man climbing: dark skin tone
+1F9D7 200D 2640 FE0F ; fully-qualified # 🧗♀️ E5.0 woman climbing
+1F9D7 200D 2640 ; minimally-qualified # 🧗♀ E5.0 woman climbing
+1F9D7 1F3FB 200D 2640 FE0F ; fully-qualified # 🧗🏻♀️ E5.0 woman climbing: light skin tone
+1F9D7 1F3FB 200D 2640 ; minimally-qualified # 🧗🏻♀ E5.0 woman climbing: light skin tone
+1F9D7 1F3FC 200D 2640 FE0F ; fully-qualified # 🧗🏼♀️ E5.0 woman climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2640 ; minimally-qualified # 🧗🏼♀ E5.0 woman climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2640 FE0F ; fully-qualified # 🧗🏽♀️ E5.0 woman climbing: medium skin tone
+1F9D7 1F3FD 200D 2640 ; minimally-qualified # 🧗🏽♀ E5.0 woman climbing: medium skin tone
+1F9D7 1F3FE 200D 2640 FE0F ; fully-qualified # 🧗🏾♀️ E5.0 woman climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2640 ; minimally-qualified # 🧗🏾♀ E5.0 woman climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2640 FE0F ; fully-qualified # 🧗🏿♀️ E5.0 woman climbing: dark skin tone
+1F9D7 1F3FF 200D 2640 ; minimally-qualified # 🧗🏿♀ E5.0 woman climbing: dark skin tone
# subgroup: person-sport
-1F93A ; fully-qualified # 🤺 E3.0 person fencing
-1F3C7 ; fully-qualified # 🏇 E1.0 horse racing
-1F3C7 1F3FB ; fully-qualified # 🏇🏻 E1.0 horse racing: light skin tone
-1F3C7 1F3FC ; fully-qualified # 🏇🏼 E1.0 horse racing: medium-light skin tone
-1F3C7 1F3FD ; fully-qualified # 🏇🏽 E1.0 horse racing: medium skin tone
-1F3C7 1F3FE ; fully-qualified # 🏇🏾 E1.0 horse racing: medium-dark skin tone
-1F3C7 1F3FF ; fully-qualified # 🏇🏿 E1.0 horse racing: dark skin tone
-26F7 FE0F ; fully-qualified # ⛷️ E0.7 skier
-26F7 ; unqualified # ⛷ E0.7 skier
-1F3C2 ; fully-qualified # 🏂 E0.6 snowboarder
-1F3C2 1F3FB ; fully-qualified # 🏂🏻 E1.0 snowboarder: light skin tone
-1F3C2 1F3FC ; fully-qualified # 🏂🏼 E1.0 snowboarder: medium-light skin tone
-1F3C2 1F3FD ; fully-qualified # 🏂🏽 E1.0 snowboarder: medium skin tone
-1F3C2 1F3FE ; fully-qualified # 🏂🏾 E1.0 snowboarder: medium-dark skin tone
-1F3C2 1F3FF ; fully-qualified # 🏂🏿 E1.0 snowboarder: dark skin tone
-1F3CC FE0F ; fully-qualified # 🏌️ E0.7 person golfing
-1F3CC ; unqualified # 🏌 E0.7 person golfing
-1F3CC 1F3FB ; fully-qualified # 🏌🏻 E4.0 person golfing: light skin tone
-1F3CC 1F3FC ; fully-qualified # 🏌🏼 E4.0 person golfing: medium-light skin tone
-1F3CC 1F3FD ; fully-qualified # 🏌🏽 E4.0 person golfing: medium skin tone
-1F3CC 1F3FE ; fully-qualified # 🏌🏾 E4.0 person golfing: medium-dark skin tone
-1F3CC 1F3FF ; fully-qualified # 🏌🏿 E4.0 person golfing: dark skin tone
-1F3CC FE0F 200D 2642 FE0F ; fully-qualified # 🏌️♂️ E4.0 man golfing
-1F3CC 200D 2642 FE0F ; unqualified # 🏌♂️ E4.0 man golfing
-1F3CC FE0F 200D 2642 ; unqualified # 🏌️♂ E4.0 man golfing
-1F3CC 200D 2642 ; unqualified # 🏌♂ E4.0 man golfing
-1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # 🏌🏻♂️ E4.0 man golfing: light skin tone
-1F3CC 1F3FB 200D 2642 ; minimally-qualified # 🏌🏻♂ E4.0 man golfing: light skin tone
-1F3CC 1F3FC 200D 2642 FE0F ; fully-qualified # 🏌🏼♂️ E4.0 man golfing: medium-light skin tone
-1F3CC 1F3FC 200D 2642 ; minimally-qualified # 🏌🏼♂ E4.0 man golfing: medium-light skin tone
-1F3CC 1F3FD 200D 2642 FE0F ; fully-qualified # 🏌🏽♂️ E4.0 man golfing: medium skin tone
-1F3CC 1F3FD 200D 2642 ; minimally-qualified # 🏌🏽♂ E4.0 man golfing: medium skin tone
-1F3CC 1F3FE 200D 2642 FE0F ; fully-qualified # 🏌🏾♂️ E4.0 man golfing: medium-dark skin tone
-1F3CC 1F3FE 200D 2642 ; minimally-qualified # 🏌🏾♂ E4.0 man golfing: medium-dark skin tone
-1F3CC 1F3FF 200D 2642 FE0F ; fully-qualified # 🏌🏿♂️ E4.0 man golfing: dark skin tone
-1F3CC 1F3FF 200D 2642 ; minimally-qualified # 🏌🏿♂ E4.0 man golfing: dark skin tone
-1F3CC FE0F 200D 2640 FE0F ; fully-qualified # 🏌️♀️ E4.0 woman golfing
-1F3CC 200D 2640 FE0F ; unqualified # 🏌♀️ E4.0 woman golfing
-1F3CC FE0F 200D 2640 ; unqualified # 🏌️♀ E4.0 woman golfing
-1F3CC 200D 2640 ; unqualified # 🏌♀ E4.0 woman golfing
-1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # 🏌🏻♀️ E4.0 woman golfing: light skin tone
-1F3CC 1F3FB 200D 2640 ; minimally-qualified # 🏌🏻♀ E4.0 woman golfing: light skin tone
-1F3CC 1F3FC 200D 2640 FE0F ; fully-qualified # 🏌🏼♀️ E4.0 woman golfing: medium-light skin tone
-1F3CC 1F3FC 200D 2640 ; minimally-qualified # 🏌🏼♀ E4.0 woman golfing: medium-light skin tone
-1F3CC 1F3FD 200D 2640 FE0F ; fully-qualified # 🏌🏽♀️ E4.0 woman golfing: medium skin tone
-1F3CC 1F3FD 200D 2640 ; minimally-qualified # 🏌🏽♀ E4.0 woman golfing: medium skin tone
-1F3CC 1F3FE 200D 2640 FE0F ; fully-qualified # 🏌🏾♀️ E4.0 woman golfing: medium-dark skin tone
-1F3CC 1F3FE 200D 2640 ; minimally-qualified # 🏌🏾♀ E4.0 woman golfing: medium-dark skin tone
-1F3CC 1F3FF 200D 2640 FE0F ; fully-qualified # 🏌🏿♀️ E4.0 woman golfing: dark skin tone
-1F3CC 1F3FF 200D 2640 ; minimally-qualified # 🏌🏿♀ E4.0 woman golfing: dark skin tone
-1F3C4 ; fully-qualified # 🏄 E0.6 person surfing
-1F3C4 1F3FB ; fully-qualified # 🏄🏻 E1.0 person surfing: light skin tone
-1F3C4 1F3FC ; fully-qualified # 🏄🏼 E1.0 person surfing: medium-light skin tone
-1F3C4 1F3FD ; fully-qualified # 🏄🏽 E1.0 person surfing: medium skin tone
-1F3C4 1F3FE ; fully-qualified # 🏄🏾 E1.0 person surfing: medium-dark skin tone
-1F3C4 1F3FF ; fully-qualified # 🏄🏿 E1.0 person surfing: dark skin tone
-1F3C4 200D 2642 FE0F ; fully-qualified # 🏄♂️ E4.0 man surfing
-1F3C4 200D 2642 ; minimally-qualified # 🏄♂ E4.0 man surfing
-1F3C4 1F3FB 200D 2642 FE0F ; fully-qualified # 🏄🏻♂️ E4.0 man surfing: light skin tone
-1F3C4 1F3FB 200D 2642 ; minimally-qualified # 🏄🏻♂ E4.0 man surfing: light skin tone
-1F3C4 1F3FC 200D 2642 FE0F ; fully-qualified # 🏄🏼♂️ E4.0 man surfing: medium-light skin tone
-1F3C4 1F3FC 200D 2642 ; minimally-qualified # 🏄🏼♂ E4.0 man surfing: medium-light skin tone
-1F3C4 1F3FD 200D 2642 FE0F ; fully-qualified # 🏄🏽♂️ E4.0 man surfing: medium skin tone
-1F3C4 1F3FD 200D 2642 ; minimally-qualified # 🏄🏽♂ E4.0 man surfing: medium skin tone
-1F3C4 1F3FE 200D 2642 FE0F ; fully-qualified # 🏄🏾♂️ E4.0 man surfing: medium-dark skin tone
-1F3C4 1F3FE 200D 2642 ; minimally-qualified # 🏄🏾♂ E4.0 man surfing: medium-dark skin tone
-1F3C4 1F3FF 200D 2642 FE0F ; fully-qualified # 🏄🏿♂️ E4.0 man surfing: dark skin tone
-1F3C4 1F3FF 200D 2642 ; minimally-qualified # 🏄🏿♂ E4.0 man surfing: dark skin tone
-1F3C4 200D 2640 FE0F ; fully-qualified # 🏄♀️ E4.0 woman surfing
-1F3C4 200D 2640 ; minimally-qualified # 🏄♀ E4.0 woman surfing
-1F3C4 1F3FB 200D 2640 FE0F ; fully-qualified # 🏄🏻♀️ E4.0 woman surfing: light skin tone
-1F3C4 1F3FB 200D 2640 ; minimally-qualified # 🏄🏻♀ E4.0 woman surfing: light skin tone
-1F3C4 1F3FC 200D 2640 FE0F ; fully-qualified # 🏄🏼♀️ E4.0 woman surfing: medium-light skin tone
-1F3C4 1F3FC 200D 2640 ; minimally-qualified # 🏄🏼♀ E4.0 woman surfing: medium-light skin tone
-1F3C4 1F3FD 200D 2640 FE0F ; fully-qualified # 🏄🏽♀️ E4.0 woman surfing: medium skin tone
-1F3C4 1F3FD 200D 2640 ; minimally-qualified # 🏄🏽♀ E4.0 woman surfing: medium skin tone
-1F3C4 1F3FE 200D 2640 FE0F ; fully-qualified # 🏄🏾♀️ E4.0 woman surfing: medium-dark skin tone
-1F3C4 1F3FE 200D 2640 ; minimally-qualified # 🏄🏾♀ E4.0 woman surfing: medium-dark skin tone
-1F3C4 1F3FF 200D 2640 FE0F ; fully-qualified # 🏄🏿♀️ E4.0 woman surfing: dark skin tone
-1F3C4 1F3FF 200D 2640 ; minimally-qualified # 🏄🏿♀ E4.0 woman surfing: dark skin tone
-1F6A3 ; fully-qualified # 🚣 E1.0 person rowing boat
-1F6A3 1F3FB ; fully-qualified # 🚣🏻 E1.0 person rowing boat: light skin tone
-1F6A3 1F3FC ; fully-qualified # 🚣🏼 E1.0 person rowing boat: medium-light skin tone
-1F6A3 1F3FD ; fully-qualified # 🚣🏽 E1.0 person rowing boat: medium skin tone
-1F6A3 1F3FE ; fully-qualified # 🚣🏾 E1.0 person rowing boat: medium-dark skin tone
-1F6A3 1F3FF ; fully-qualified # 🚣🏿 E1.0 person rowing boat: dark skin tone
-1F6A3 200D 2642 FE0F ; fully-qualified # 🚣♂️ E4.0 man rowing boat
-1F6A3 200D 2642 ; minimally-qualified # 🚣♂ E4.0 man rowing boat
-1F6A3 1F3FB 200D 2642 FE0F ; fully-qualified # 🚣🏻♂️ E4.0 man rowing boat: light skin tone
-1F6A3 1F3FB 200D 2642 ; minimally-qualified # 🚣🏻♂ E4.0 man rowing boat: light skin tone
-1F6A3 1F3FC 200D 2642 FE0F ; fully-qualified # 🚣🏼♂️ E4.0 man rowing boat: medium-light skin tone
-1F6A3 1F3FC 200D 2642 ; minimally-qualified # 🚣🏼♂ E4.0 man rowing boat: medium-light skin tone
-1F6A3 1F3FD 200D 2642 FE0F ; fully-qualified # 🚣🏽♂️ E4.0 man rowing boat: medium skin tone
-1F6A3 1F3FD 200D 2642 ; minimally-qualified # 🚣🏽♂ E4.0 man rowing boat: medium skin tone
-1F6A3 1F3FE 200D 2642 FE0F ; fully-qualified # 🚣🏾♂️ E4.0 man rowing boat: medium-dark skin tone
-1F6A3 1F3FE 200D 2642 ; minimally-qualified # 🚣🏾♂ E4.0 man rowing boat: medium-dark skin tone
-1F6A3 1F3FF 200D 2642 FE0F ; fully-qualified # 🚣🏿♂️ E4.0 man rowing boat: dark skin tone
-1F6A3 1F3FF 200D 2642 ; minimally-qualified # 🚣🏿♂ E4.0 man rowing boat: dark skin tone
-1F6A3 200D 2640 FE0F ; fully-qualified # 🚣♀️ E4.0 woman rowing boat
-1F6A3 200D 2640 ; minimally-qualified # 🚣♀ E4.0 woman rowing boat
-1F6A3 1F3FB 200D 2640 FE0F ; fully-qualified # 🚣🏻♀️ E4.0 woman rowing boat: light skin tone
-1F6A3 1F3FB 200D 2640 ; minimally-qualified # 🚣🏻♀ E4.0 woman rowing boat: light skin tone
-1F6A3 1F3FC 200D 2640 FE0F ; fully-qualified # 🚣🏼♀️ E4.0 woman rowing boat: medium-light skin tone
-1F6A3 1F3FC 200D 2640 ; minimally-qualified # 🚣🏼♀ E4.0 woman rowing boat: medium-light skin tone
-1F6A3 1F3FD 200D 2640 FE0F ; fully-qualified # 🚣🏽♀️ E4.0 woman rowing boat: medium skin tone
-1F6A3 1F3FD 200D 2640 ; minimally-qualified # 🚣🏽♀ E4.0 woman rowing boat: medium skin tone
-1F6A3 1F3FE 200D 2640 FE0F ; fully-qualified # 🚣🏾♀️ E4.0 woman rowing boat: medium-dark skin tone
-1F6A3 1F3FE 200D 2640 ; minimally-qualified # 🚣🏾♀ E4.0 woman rowing boat: medium-dark skin tone
-1F6A3 1F3FF 200D 2640 FE0F ; fully-qualified # 🚣🏿♀️ E4.0 woman rowing boat: dark skin tone
-1F6A3 1F3FF 200D 2640 ; minimally-qualified # 🚣🏿♀ E4.0 woman rowing boat: dark skin tone
-1F3CA ; fully-qualified # 🏊 E0.6 person swimming
-1F3CA 1F3FB ; fully-qualified # 🏊🏻 E1.0 person swimming: light skin tone
-1F3CA 1F3FC ; fully-qualified # 🏊🏼 E1.0 person swimming: medium-light skin tone
-1F3CA 1F3FD ; fully-qualified # 🏊🏽 E1.0 person swimming: medium skin tone
-1F3CA 1F3FE ; fully-qualified # 🏊🏾 E1.0 person swimming: medium-dark skin tone
-1F3CA 1F3FF ; fully-qualified # 🏊🏿 E1.0 person swimming: dark skin tone
-1F3CA 200D 2642 FE0F ; fully-qualified # 🏊♂️ E4.0 man swimming
-1F3CA 200D 2642 ; minimally-qualified # 🏊♂ E4.0 man swimming
-1F3CA 1F3FB 200D 2642 FE0F ; fully-qualified # 🏊🏻♂️ E4.0 man swimming: light skin tone
-1F3CA 1F3FB 200D 2642 ; minimally-qualified # 🏊🏻♂ E4.0 man swimming: light skin tone
-1F3CA 1F3FC 200D 2642 FE0F ; fully-qualified # 🏊🏼♂️ E4.0 man swimming: medium-light skin tone
-1F3CA 1F3FC 200D 2642 ; minimally-qualified # 🏊🏼♂ E4.0 man swimming: medium-light skin tone
-1F3CA 1F3FD 200D 2642 FE0F ; fully-qualified # 🏊🏽♂️ E4.0 man swimming: medium skin tone
-1F3CA 1F3FD 200D 2642 ; minimally-qualified # 🏊🏽♂ E4.0 man swimming: medium skin tone
-1F3CA 1F3FE 200D 2642 FE0F ; fully-qualified # 🏊🏾♂️ E4.0 man swimming: medium-dark skin tone
-1F3CA 1F3FE 200D 2642 ; minimally-qualified # 🏊🏾♂ E4.0 man swimming: medium-dark skin tone
-1F3CA 1F3FF 200D 2642 FE0F ; fully-qualified # 🏊🏿♂️ E4.0 man swimming: dark skin tone
-1F3CA 1F3FF 200D 2642 ; minimally-qualified # 🏊🏿♂ E4.0 man swimming: dark skin tone
-1F3CA 200D 2640 FE0F ; fully-qualified # 🏊♀️ E4.0 woman swimming
-1F3CA 200D 2640 ; minimally-qualified # 🏊♀ E4.0 woman swimming
-1F3CA 1F3FB 200D 2640 FE0F ; fully-qualified # 🏊🏻♀️ E4.0 woman swimming: light skin tone
-1F3CA 1F3FB 200D 2640 ; minimally-qualified # 🏊🏻♀ E4.0 woman swimming: light skin tone
-1F3CA 1F3FC 200D 2640 FE0F ; fully-qualified # 🏊🏼♀️ E4.0 woman swimming: medium-light skin tone
-1F3CA 1F3FC 200D 2640 ; minimally-qualified # 🏊🏼♀ E4.0 woman swimming: medium-light skin tone
-1F3CA 1F3FD 200D 2640 FE0F ; fully-qualified # 🏊🏽♀️ E4.0 woman swimming: medium skin tone
-1F3CA 1F3FD 200D 2640 ; minimally-qualified # 🏊🏽♀ E4.0 woman swimming: medium skin tone
-1F3CA 1F3FE 200D 2640 FE0F ; fully-qualified # 🏊🏾♀️ E4.0 woman swimming: medium-dark skin tone
-1F3CA 1F3FE 200D 2640 ; minimally-qualified # 🏊🏾♀ E4.0 woman swimming: medium-dark skin tone
-1F3CA 1F3FF 200D 2640 FE0F ; fully-qualified # 🏊🏿♀️ E4.0 woman swimming: dark skin tone
-1F3CA 1F3FF 200D 2640 ; minimally-qualified # 🏊🏿♀ E4.0 woman swimming: dark skin tone
-26F9 FE0F ; fully-qualified # ⛹️ E0.7 person bouncing ball
-26F9 ; unqualified # ⛹ E0.7 person bouncing ball
-26F9 1F3FB ; fully-qualified # ⛹🏻 E2.0 person bouncing ball: light skin tone
-26F9 1F3FC ; fully-qualified # ⛹🏼 E2.0 person bouncing ball: medium-light skin tone
-26F9 1F3FD ; fully-qualified # ⛹🏽 E2.0 person bouncing ball: medium skin tone
-26F9 1F3FE ; fully-qualified # ⛹🏾 E2.0 person bouncing ball: medium-dark skin tone
-26F9 1F3FF ; fully-qualified # ⛹🏿 E2.0 person bouncing ball: dark skin tone
-26F9 FE0F 200D 2642 FE0F ; fully-qualified # ⛹️♂️ E4.0 man bouncing ball
-26F9 200D 2642 FE0F ; unqualified # ⛹♂️ E4.0 man bouncing ball
-26F9 FE0F 200D 2642 ; unqualified # ⛹️♂ E4.0 man bouncing ball
-26F9 200D 2642 ; unqualified # ⛹♂ E4.0 man bouncing ball
-26F9 1F3FB 200D 2642 FE0F ; fully-qualified # ⛹🏻♂️ E4.0 man bouncing ball: light skin tone
-26F9 1F3FB 200D 2642 ; minimally-qualified # ⛹🏻♂ E4.0 man bouncing ball: light skin tone
-26F9 1F3FC 200D 2642 FE0F ; fully-qualified # ⛹🏼♂️ E4.0 man bouncing ball: medium-light skin tone
-26F9 1F3FC 200D 2642 ; minimally-qualified # ⛹🏼♂ E4.0 man bouncing ball: medium-light skin tone
-26F9 1F3FD 200D 2642 FE0F ; fully-qualified # ⛹🏽♂️ E4.0 man bouncing ball: medium skin tone
-26F9 1F3FD 200D 2642 ; minimally-qualified # ⛹🏽♂ E4.0 man bouncing ball: medium skin tone
-26F9 1F3FE 200D 2642 FE0F ; fully-qualified # ⛹🏾♂️ E4.0 man bouncing ball: medium-dark skin tone
-26F9 1F3FE 200D 2642 ; minimally-qualified # ⛹🏾♂ E4.0 man bouncing ball: medium-dark skin tone
-26F9 1F3FF 200D 2642 FE0F ; fully-qualified # ⛹🏿♂️ E4.0 man bouncing ball: dark skin tone
-26F9 1F3FF 200D 2642 ; minimally-qualified # ⛹🏿♂ E4.0 man bouncing ball: dark skin tone
-26F9 FE0F 200D 2640 FE0F ; fully-qualified # ⛹️♀️ E4.0 woman bouncing ball
-26F9 200D 2640 FE0F ; unqualified # ⛹♀️ E4.0 woman bouncing ball
-26F9 FE0F 200D 2640 ; unqualified # ⛹️♀ E4.0 woman bouncing ball
-26F9 200D 2640 ; unqualified # ⛹♀ E4.0 woman bouncing ball
-26F9 1F3FB 200D 2640 FE0F ; fully-qualified # ⛹🏻♀️ E4.0 woman bouncing ball: light skin tone
-26F9 1F3FB 200D 2640 ; minimally-qualified # ⛹🏻♀ E4.0 woman bouncing ball: light skin tone
-26F9 1F3FC 200D 2640 FE0F ; fully-qualified # ⛹🏼♀️ E4.0 woman bouncing ball: medium-light skin tone
-26F9 1F3FC 200D 2640 ; minimally-qualified # ⛹🏼♀ E4.0 woman bouncing ball: medium-light skin tone
-26F9 1F3FD 200D 2640 FE0F ; fully-qualified # ⛹🏽♀️ E4.0 woman bouncing ball: medium skin tone
-26F9 1F3FD 200D 2640 ; minimally-qualified # ⛹🏽♀ E4.0 woman bouncing ball: medium skin tone
-26F9 1F3FE 200D 2640 FE0F ; fully-qualified # ⛹🏾♀️ E4.0 woman bouncing ball: medium-dark skin tone
-26F9 1F3FE 200D 2640 ; minimally-qualified # ⛹🏾♀ E4.0 woman bouncing ball: medium-dark skin tone
-26F9 1F3FF 200D 2640 FE0F ; fully-qualified # ⛹🏿♀️ E4.0 woman bouncing ball: dark skin tone
-26F9 1F3FF 200D 2640 ; minimally-qualified # ⛹🏿♀ E4.0 woman bouncing ball: dark skin tone
-1F3CB FE0F ; fully-qualified # 🏋️ E0.7 person lifting weights
-1F3CB ; unqualified # 🏋 E0.7 person lifting weights
-1F3CB 1F3FB ; fully-qualified # 🏋🏻 E2.0 person lifting weights: light skin tone
-1F3CB 1F3FC ; fully-qualified # 🏋🏼 E2.0 person lifting weights: medium-light skin tone
-1F3CB 1F3FD ; fully-qualified # 🏋🏽 E2.0 person lifting weights: medium skin tone
-1F3CB 1F3FE ; fully-qualified # 🏋🏾 E2.0 person lifting weights: medium-dark skin tone
-1F3CB 1F3FF ; fully-qualified # 🏋🏿 E2.0 person lifting weights: dark skin tone
-1F3CB FE0F 200D 2642 FE0F ; fully-qualified # 🏋️♂️ E4.0 man lifting weights
-1F3CB 200D 2642 FE0F ; unqualified # 🏋♂️ E4.0 man lifting weights
-1F3CB FE0F 200D 2642 ; unqualified # 🏋️♂ E4.0 man lifting weights
-1F3CB 200D 2642 ; unqualified # 🏋♂ E4.0 man lifting weights
-1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # 🏋🏻♂️ E4.0 man lifting weights: light skin tone
-1F3CB 1F3FB 200D 2642 ; minimally-qualified # 🏋🏻♂ E4.0 man lifting weights: light skin tone
-1F3CB 1F3FC 200D 2642 FE0F ; fully-qualified # 🏋🏼♂️ E4.0 man lifting weights: medium-light skin tone
-1F3CB 1F3FC 200D 2642 ; minimally-qualified # 🏋🏼♂ E4.0 man lifting weights: medium-light skin tone
-1F3CB 1F3FD 200D 2642 FE0F ; fully-qualified # 🏋🏽♂️ E4.0 man lifting weights: medium skin tone
-1F3CB 1F3FD 200D 2642 ; minimally-qualified # 🏋🏽♂ E4.0 man lifting weights: medium skin tone
-1F3CB 1F3FE 200D 2642 FE0F ; fully-qualified # 🏋🏾♂️ E4.0 man lifting weights: medium-dark skin tone
-1F3CB 1F3FE 200D 2642 ; minimally-qualified # 🏋🏾♂ E4.0 man lifting weights: medium-dark skin tone
-1F3CB 1F3FF 200D 2642 FE0F ; fully-qualified # 🏋🏿♂️ E4.0 man lifting weights: dark skin tone
-1F3CB 1F3FF 200D 2642 ; minimally-qualified # 🏋🏿♂ E4.0 man lifting weights: dark skin tone
-1F3CB FE0F 200D 2640 FE0F ; fully-qualified # 🏋️♀️ E4.0 woman lifting weights
-1F3CB 200D 2640 FE0F ; unqualified # 🏋♀️ E4.0 woman lifting weights
-1F3CB FE0F 200D 2640 ; unqualified # 🏋️♀ E4.0 woman lifting weights
-1F3CB 200D 2640 ; unqualified # 🏋♀ E4.0 woman lifting weights
-1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # 🏋🏻♀️ E4.0 woman lifting weights: light skin tone
-1F3CB 1F3FB 200D 2640 ; minimally-qualified # 🏋🏻♀ E4.0 woman lifting weights: light skin tone
-1F3CB 1F3FC 200D 2640 FE0F ; fully-qualified # 🏋🏼♀️ E4.0 woman lifting weights: medium-light skin tone
-1F3CB 1F3FC 200D 2640 ; minimally-qualified # 🏋🏼♀ E4.0 woman lifting weights: medium-light skin tone
-1F3CB 1F3FD 200D 2640 FE0F ; fully-qualified # 🏋🏽♀️ E4.0 woman lifting weights: medium skin tone
-1F3CB 1F3FD 200D 2640 ; minimally-qualified # 🏋🏽♀ E4.0 woman lifting weights: medium skin tone
-1F3CB 1F3FE 200D 2640 FE0F ; fully-qualified # 🏋🏾♀️ E4.0 woman lifting weights: medium-dark skin tone
-1F3CB 1F3FE 200D 2640 ; minimally-qualified # 🏋🏾♀ E4.0 woman lifting weights: medium-dark skin tone
-1F3CB 1F3FF 200D 2640 FE0F ; fully-qualified # 🏋🏿♀️ E4.0 woman lifting weights: dark skin tone
-1F3CB 1F3FF 200D 2640 ; minimally-qualified # 🏋🏿♀ E4.0 woman lifting weights: dark skin tone
-1F6B4 ; fully-qualified # 🚴 E1.0 person biking
-1F6B4 1F3FB ; fully-qualified # 🚴🏻 E1.0 person biking: light skin tone
-1F6B4 1F3FC ; fully-qualified # 🚴🏼 E1.0 person biking: medium-light skin tone
-1F6B4 1F3FD ; fully-qualified # 🚴🏽 E1.0 person biking: medium skin tone
-1F6B4 1F3FE ; fully-qualified # 🚴🏾 E1.0 person biking: medium-dark skin tone
-1F6B4 1F3FF ; fully-qualified # 🚴🏿 E1.0 person biking: dark skin tone
-1F6B4 200D 2642 FE0F ; fully-qualified # 🚴♂️ E4.0 man biking
-1F6B4 200D 2642 ; minimally-qualified # 🚴♂ E4.0 man biking
-1F6B4 1F3FB 200D 2642 FE0F ; fully-qualified # 🚴🏻♂️ E4.0 man biking: light skin tone
-1F6B4 1F3FB 200D 2642 ; minimally-qualified # 🚴🏻♂ E4.0 man biking: light skin tone
-1F6B4 1F3FC 200D 2642 FE0F ; fully-qualified # 🚴🏼♂️ E4.0 man biking: medium-light skin tone
-1F6B4 1F3FC 200D 2642 ; minimally-qualified # 🚴🏼♂ E4.0 man biking: medium-light skin tone
-1F6B4 1F3FD 200D 2642 FE0F ; fully-qualified # 🚴🏽♂️ E4.0 man biking: medium skin tone
-1F6B4 1F3FD 200D 2642 ; minimally-qualified # 🚴🏽♂ E4.0 man biking: medium skin tone
-1F6B4 1F3FE 200D 2642 FE0F ; fully-qualified # 🚴🏾♂️ E4.0 man biking: medium-dark skin tone
-1F6B4 1F3FE 200D 2642 ; minimally-qualified # 🚴🏾♂ E4.0 man biking: medium-dark skin tone
-1F6B4 1F3FF 200D 2642 FE0F ; fully-qualified # 🚴🏿♂️ E4.0 man biking: dark skin tone
-1F6B4 1F3FF 200D 2642 ; minimally-qualified # 🚴🏿♂ E4.0 man biking: dark skin tone
-1F6B4 200D 2640 FE0F ; fully-qualified # 🚴♀️ E4.0 woman biking
-1F6B4 200D 2640 ; minimally-qualified # 🚴♀ E4.0 woman biking
-1F6B4 1F3FB 200D 2640 FE0F ; fully-qualified # 🚴🏻♀️ E4.0 woman biking: light skin tone
-1F6B4 1F3FB 200D 2640 ; minimally-qualified # 🚴🏻♀ E4.0 woman biking: light skin tone
-1F6B4 1F3FC 200D 2640 FE0F ; fully-qualified # 🚴🏼♀️ E4.0 woman biking: medium-light skin tone
-1F6B4 1F3FC 200D 2640 ; minimally-qualified # 🚴🏼♀ E4.0 woman biking: medium-light skin tone
-1F6B4 1F3FD 200D 2640 FE0F ; fully-qualified # 🚴🏽♀️ E4.0 woman biking: medium skin tone
-1F6B4 1F3FD 200D 2640 ; minimally-qualified # 🚴🏽♀ E4.0 woman biking: medium skin tone
-1F6B4 1F3FE 200D 2640 FE0F ; fully-qualified # 🚴🏾♀️ E4.0 woman biking: medium-dark skin tone
-1F6B4 1F3FE 200D 2640 ; minimally-qualified # 🚴🏾♀ E4.0 woman biking: medium-dark skin tone
-1F6B4 1F3FF 200D 2640 FE0F ; fully-qualified # 🚴🏿♀️ E4.0 woman biking: dark skin tone
-1F6B4 1F3FF 200D 2640 ; minimally-qualified # 🚴🏿♀ E4.0 woman biking: dark skin tone
-1F6B5 ; fully-qualified # 🚵 E1.0 person mountain biking
-1F6B5 1F3FB ; fully-qualified # 🚵🏻 E1.0 person mountain biking: light skin tone
-1F6B5 1F3FC ; fully-qualified # 🚵🏼 E1.0 person mountain biking: medium-light skin tone
-1F6B5 1F3FD ; fully-qualified # 🚵🏽 E1.0 person mountain biking: medium skin tone
-1F6B5 1F3FE ; fully-qualified # 🚵🏾 E1.0 person mountain biking: medium-dark skin tone
-1F6B5 1F3FF ; fully-qualified # 🚵🏿 E1.0 person mountain biking: dark skin tone
-1F6B5 200D 2642 FE0F ; fully-qualified # 🚵♂️ E4.0 man mountain biking
-1F6B5 200D 2642 ; minimally-qualified # 🚵♂ E4.0 man mountain biking
-1F6B5 1F3FB 200D 2642 FE0F ; fully-qualified # 🚵🏻♂️ E4.0 man mountain biking: light skin tone
-1F6B5 1F3FB 200D 2642 ; minimally-qualified # 🚵🏻♂ E4.0 man mountain biking: light skin tone
-1F6B5 1F3FC 200D 2642 FE0F ; fully-qualified # 🚵🏼♂️ E4.0 man mountain biking: medium-light skin tone
-1F6B5 1F3FC 200D 2642 ; minimally-qualified # 🚵🏼♂ E4.0 man mountain biking: medium-light skin tone
-1F6B5 1F3FD 200D 2642 FE0F ; fully-qualified # 🚵🏽♂️ E4.0 man mountain biking: medium skin tone
-1F6B5 1F3FD 200D 2642 ; minimally-qualified # 🚵🏽♂ E4.0 man mountain biking: medium skin tone
-1F6B5 1F3FE 200D 2642 FE0F ; fully-qualified # 🚵🏾♂️ E4.0 man mountain biking: medium-dark skin tone
-1F6B5 1F3FE 200D 2642 ; minimally-qualified # 🚵🏾♂ E4.0 man mountain biking: medium-dark skin tone
-1F6B5 1F3FF 200D 2642 FE0F ; fully-qualified # 🚵🏿♂️ E4.0 man mountain biking: dark skin tone
-1F6B5 1F3FF 200D 2642 ; minimally-qualified # 🚵🏿♂ E4.0 man mountain biking: dark skin tone
-1F6B5 200D 2640 FE0F ; fully-qualified # 🚵♀️ E4.0 woman mountain biking
-1F6B5 200D 2640 ; minimally-qualified # 🚵♀ E4.0 woman mountain biking
-1F6B5 1F3FB 200D 2640 FE0F ; fully-qualified # 🚵🏻♀️ E4.0 woman mountain biking: light skin tone
-1F6B5 1F3FB 200D 2640 ; minimally-qualified # 🚵🏻♀ E4.0 woman mountain biking: light skin tone
-1F6B5 1F3FC 200D 2640 FE0F ; fully-qualified # 🚵🏼♀️ E4.0 woman mountain biking: medium-light skin tone
-1F6B5 1F3FC 200D 2640 ; minimally-qualified # 🚵🏼♀ E4.0 woman mountain biking: medium-light skin tone
-1F6B5 1F3FD 200D 2640 FE0F ; fully-qualified # 🚵🏽♀️ E4.0 woman mountain biking: medium skin tone
-1F6B5 1F3FD 200D 2640 ; minimally-qualified # 🚵🏽♀ E4.0 woman mountain biking: medium skin tone
-1F6B5 1F3FE 200D 2640 FE0F ; fully-qualified # 🚵🏾♀️ E4.0 woman mountain biking: medium-dark skin tone
-1F6B5 1F3FE 200D 2640 ; minimally-qualified # 🚵🏾♀ E4.0 woman mountain biking: medium-dark skin tone
-1F6B5 1F3FF 200D 2640 FE0F ; fully-qualified # 🚵🏿♀️ E4.0 woman mountain biking: dark skin tone
-1F6B5 1F3FF 200D 2640 ; minimally-qualified # 🚵🏿♀ E4.0 woman mountain biking: dark skin tone
-1F938 ; fully-qualified # 🤸 E3.0 person cartwheeling
-1F938 1F3FB ; fully-qualified # 🤸🏻 E3.0 person cartwheeling: light skin tone
-1F938 1F3FC ; fully-qualified # 🤸🏼 E3.0 person cartwheeling: medium-light skin tone
-1F938 1F3FD ; fully-qualified # 🤸🏽 E3.0 person cartwheeling: medium skin tone
-1F938 1F3FE ; fully-qualified # 🤸🏾 E3.0 person cartwheeling: medium-dark skin tone
-1F938 1F3FF ; fully-qualified # 🤸🏿 E3.0 person cartwheeling: dark skin tone
-1F938 200D 2642 FE0F ; fully-qualified # 🤸♂️ E4.0 man cartwheeling
-1F938 200D 2642 ; minimally-qualified # 🤸♂ E4.0 man cartwheeling
-1F938 1F3FB 200D 2642 FE0F ; fully-qualified # 🤸🏻♂️ E4.0 man cartwheeling: light skin tone
-1F938 1F3FB 200D 2642 ; minimally-qualified # 🤸🏻♂ E4.0 man cartwheeling: light skin tone
-1F938 1F3FC 200D 2642 FE0F ; fully-qualified # 🤸🏼♂️ E4.0 man cartwheeling: medium-light skin tone
-1F938 1F3FC 200D 2642 ; minimally-qualified # 🤸🏼♂ E4.0 man cartwheeling: medium-light skin tone
-1F938 1F3FD 200D 2642 FE0F ; fully-qualified # 🤸🏽♂️ E4.0 man cartwheeling: medium skin tone
-1F938 1F3FD 200D 2642 ; minimally-qualified # 🤸🏽♂ E4.0 man cartwheeling: medium skin tone
-1F938 1F3FE 200D 2642 FE0F ; fully-qualified # 🤸🏾♂️ E4.0 man cartwheeling: medium-dark skin tone
-1F938 1F3FE 200D 2642 ; minimally-qualified # 🤸🏾♂ E4.0 man cartwheeling: medium-dark skin tone
-1F938 1F3FF 200D 2642 FE0F ; fully-qualified # 🤸🏿♂️ E4.0 man cartwheeling: dark skin tone
-1F938 1F3FF 200D 2642 ; minimally-qualified # 🤸🏿♂ E4.0 man cartwheeling: dark skin tone
-1F938 200D 2640 FE0F ; fully-qualified # 🤸♀️ E4.0 woman cartwheeling
-1F938 200D 2640 ; minimally-qualified # 🤸♀ E4.0 woman cartwheeling
-1F938 1F3FB 200D 2640 FE0F ; fully-qualified # 🤸🏻♀️ E4.0 woman cartwheeling: light skin tone
-1F938 1F3FB 200D 2640 ; minimally-qualified # 🤸🏻♀ E4.0 woman cartwheeling: light skin tone
-1F938 1F3FC 200D 2640 FE0F ; fully-qualified # 🤸🏼♀️ E4.0 woman cartwheeling: medium-light skin tone
-1F938 1F3FC 200D 2640 ; minimally-qualified # 🤸🏼♀ E4.0 woman cartwheeling: medium-light skin tone
-1F938 1F3FD 200D 2640 FE0F ; fully-qualified # 🤸🏽♀️ E4.0 woman cartwheeling: medium skin tone
-1F938 1F3FD 200D 2640 ; minimally-qualified # 🤸🏽♀ E4.0 woman cartwheeling: medium skin tone
-1F938 1F3FE 200D 2640 FE0F ; fully-qualified # 🤸🏾♀️ E4.0 woman cartwheeling: medium-dark skin tone
-1F938 1F3FE 200D 2640 ; minimally-qualified # 🤸🏾♀ E4.0 woman cartwheeling: medium-dark skin tone
-1F938 1F3FF 200D 2640 FE0F ; fully-qualified # 🤸🏿♀️ E4.0 woman cartwheeling: dark skin tone
-1F938 1F3FF 200D 2640 ; minimally-qualified # 🤸🏿♀ E4.0 woman cartwheeling: dark skin tone
-1F93C ; fully-qualified # 🤼 E3.0 people wrestling
-1F93C 200D 2642 FE0F ; fully-qualified # 🤼♂️ E4.0 men wrestling
-1F93C 200D 2642 ; minimally-qualified # 🤼♂ E4.0 men wrestling
-1F93C 200D 2640 FE0F ; fully-qualified # 🤼♀️ E4.0 women wrestling
-1F93C 200D 2640 ; minimally-qualified # 🤼♀ E4.0 women wrestling
-1F93D ; fully-qualified # 🤽 E3.0 person playing water polo
-1F93D 1F3FB ; fully-qualified # 🤽🏻 E3.0 person playing water polo: light skin tone
-1F93D 1F3FC ; fully-qualified # 🤽🏼 E3.0 person playing water polo: medium-light skin tone
-1F93D 1F3FD ; fully-qualified # 🤽🏽 E3.0 person playing water polo: medium skin tone
-1F93D 1F3FE ; fully-qualified # 🤽🏾 E3.0 person playing water polo: medium-dark skin tone
-1F93D 1F3FF ; fully-qualified # 🤽🏿 E3.0 person playing water polo: dark skin tone
-1F93D 200D 2642 FE0F ; fully-qualified # 🤽♂️ E4.0 man playing water polo
-1F93D 200D 2642 ; minimally-qualified # 🤽♂ E4.0 man playing water polo
-1F93D 1F3FB 200D 2642 FE0F ; fully-qualified # 🤽🏻♂️ E4.0 man playing water polo: light skin tone
-1F93D 1F3FB 200D 2642 ; minimally-qualified # 🤽🏻♂ E4.0 man playing water polo: light skin tone
-1F93D 1F3FC 200D 2642 FE0F ; fully-qualified # 🤽🏼♂️ E4.0 man playing water polo: medium-light skin tone
-1F93D 1F3FC 200D 2642 ; minimally-qualified # 🤽🏼♂ E4.0 man playing water polo: medium-light skin tone
-1F93D 1F3FD 200D 2642 FE0F ; fully-qualified # 🤽🏽♂️ E4.0 man playing water polo: medium skin tone
-1F93D 1F3FD 200D 2642 ; minimally-qualified # 🤽🏽♂ E4.0 man playing water polo: medium skin tone
-1F93D 1F3FE 200D 2642 FE0F ; fully-qualified # 🤽🏾♂️ E4.0 man playing water polo: medium-dark skin tone
-1F93D 1F3FE 200D 2642 ; minimally-qualified # 🤽🏾♂ E4.0 man playing water polo: medium-dark skin tone
-1F93D 1F3FF 200D 2642 FE0F ; fully-qualified # 🤽🏿♂️ E4.0 man playing water polo: dark skin tone
-1F93D 1F3FF 200D 2642 ; minimally-qualified # 🤽🏿♂ E4.0 man playing water polo: dark skin tone
-1F93D 200D 2640 FE0F ; fully-qualified # 🤽♀️ E4.0 woman playing water polo
-1F93D 200D 2640 ; minimally-qualified # 🤽♀ E4.0 woman playing water polo
-1F93D 1F3FB 200D 2640 FE0F ; fully-qualified # 🤽🏻♀️ E4.0 woman playing water polo: light skin tone
-1F93D 1F3FB 200D 2640 ; minimally-qualified # 🤽🏻♀ E4.0 woman playing water polo: light skin tone
-1F93D 1F3FC 200D 2640 FE0F ; fully-qualified # 🤽🏼♀️ E4.0 woman playing water polo: medium-light skin tone
-1F93D 1F3FC 200D 2640 ; minimally-qualified # 🤽🏼♀ E4.0 woman playing water polo: medium-light skin tone
-1F93D 1F3FD 200D 2640 FE0F ; fully-qualified # 🤽🏽♀️ E4.0 woman playing water polo: medium skin tone
-1F93D 1F3FD 200D 2640 ; minimally-qualified # 🤽🏽♀ E4.0 woman playing water polo: medium skin tone
-1F93D 1F3FE 200D 2640 FE0F ; fully-qualified # 🤽🏾♀️ E4.0 woman playing water polo: medium-dark skin tone
-1F93D 1F3FE 200D 2640 ; minimally-qualified # 🤽🏾♀ E4.0 woman playing water polo: medium-dark skin tone
-1F93D 1F3FF 200D 2640 FE0F ; fully-qualified # 🤽🏿♀️ E4.0 woman playing water polo: dark skin tone
-1F93D 1F3FF 200D 2640 ; minimally-qualified # 🤽🏿♀ E4.0 woman playing water polo: dark skin tone
-1F93E ; fully-qualified # 🤾 E3.0 person playing handball
-1F93E 1F3FB ; fully-qualified # 🤾🏻 E3.0 person playing handball: light skin tone
-1F93E 1F3FC ; fully-qualified # 🤾🏼 E3.0 person playing handball: medium-light skin tone
-1F93E 1F3FD ; fully-qualified # 🤾🏽 E3.0 person playing handball: medium skin tone
-1F93E 1F3FE ; fully-qualified # 🤾🏾 E3.0 person playing handball: medium-dark skin tone
-1F93E 1F3FF ; fully-qualified # 🤾🏿 E3.0 person playing handball: dark skin tone
-1F93E 200D 2642 FE0F ; fully-qualified # 🤾♂️ E4.0 man playing handball
-1F93E 200D 2642 ; minimally-qualified # 🤾♂ E4.0 man playing handball
-1F93E 1F3FB 200D 2642 FE0F ; fully-qualified # 🤾🏻♂️ E4.0 man playing handball: light skin tone
-1F93E 1F3FB 200D 2642 ; minimally-qualified # 🤾🏻♂ E4.0 man playing handball: light skin tone
-1F93E 1F3FC 200D 2642 FE0F ; fully-qualified # 🤾🏼♂️ E4.0 man playing handball: medium-light skin tone
-1F93E 1F3FC 200D 2642 ; minimally-qualified # 🤾🏼♂ E4.0 man playing handball: medium-light skin tone
-1F93E 1F3FD 200D 2642 FE0F ; fully-qualified # 🤾🏽♂️ E4.0 man playing handball: medium skin tone
-1F93E 1F3FD 200D 2642 ; minimally-qualified # 🤾🏽♂ E4.0 man playing handball: medium skin tone
-1F93E 1F3FE 200D 2642 FE0F ; fully-qualified # 🤾🏾♂️ E4.0 man playing handball: medium-dark skin tone
-1F93E 1F3FE 200D 2642 ; minimally-qualified # 🤾🏾♂ E4.0 man playing handball: medium-dark skin tone
-1F93E 1F3FF 200D 2642 FE0F ; fully-qualified # 🤾🏿♂️ E4.0 man playing handball: dark skin tone
-1F93E 1F3FF 200D 2642 ; minimally-qualified # 🤾🏿♂ E4.0 man playing handball: dark skin tone
-1F93E 200D 2640 FE0F ; fully-qualified # 🤾♀️ E4.0 woman playing handball
-1F93E 200D 2640 ; minimally-qualified # 🤾♀ E4.0 woman playing handball
-1F93E 1F3FB 200D 2640 FE0F ; fully-qualified # 🤾🏻♀️ E4.0 woman playing handball: light skin tone
-1F93E 1F3FB 200D 2640 ; minimally-qualified # 🤾🏻♀ E4.0 woman playing handball: light skin tone
-1F93E 1F3FC 200D 2640 FE0F ; fully-qualified # 🤾🏼♀️ E4.0 woman playing handball: medium-light skin tone
-1F93E 1F3FC 200D 2640 ; minimally-qualified # 🤾🏼♀ E4.0 woman playing handball: medium-light skin tone
-1F93E 1F3FD 200D 2640 FE0F ; fully-qualified # 🤾🏽♀️ E4.0 woman playing handball: medium skin tone
-1F93E 1F3FD 200D 2640 ; minimally-qualified # 🤾🏽♀ E4.0 woman playing handball: medium skin tone
-1F93E 1F3FE 200D 2640 FE0F ; fully-qualified # 🤾🏾♀️ E4.0 woman playing handball: medium-dark skin tone
-1F93E 1F3FE 200D 2640 ; minimally-qualified # 🤾🏾♀ E4.0 woman playing handball: medium-dark skin tone
-1F93E 1F3FF 200D 2640 FE0F ; fully-qualified # 🤾🏿♀️ E4.0 woman playing handball: dark skin tone
-1F93E 1F3FF 200D 2640 ; minimally-qualified # 🤾🏿♀ E4.0 woman playing handball: dark skin tone
-1F939 ; fully-qualified # 🤹 E3.0 person juggling
-1F939 1F3FB ; fully-qualified # 🤹🏻 E3.0 person juggling: light skin tone
-1F939 1F3FC ; fully-qualified # 🤹🏼 E3.0 person juggling: medium-light skin tone
-1F939 1F3FD ; fully-qualified # 🤹🏽 E3.0 person juggling: medium skin tone
-1F939 1F3FE ; fully-qualified # 🤹🏾 E3.0 person juggling: medium-dark skin tone
-1F939 1F3FF ; fully-qualified # 🤹🏿 E3.0 person juggling: dark skin tone
-1F939 200D 2642 FE0F ; fully-qualified # 🤹♂️ E4.0 man juggling
-1F939 200D 2642 ; minimally-qualified # 🤹♂ E4.0 man juggling
-1F939 1F3FB 200D 2642 FE0F ; fully-qualified # 🤹🏻♂️ E4.0 man juggling: light skin tone
-1F939 1F3FB 200D 2642 ; minimally-qualified # 🤹🏻♂ E4.0 man juggling: light skin tone
-1F939 1F3FC 200D 2642 FE0F ; fully-qualified # 🤹🏼♂️ E4.0 man juggling: medium-light skin tone
-1F939 1F3FC 200D 2642 ; minimally-qualified # 🤹🏼♂ E4.0 man juggling: medium-light skin tone
-1F939 1F3FD 200D 2642 FE0F ; fully-qualified # 🤹🏽♂️ E4.0 man juggling: medium skin tone
-1F939 1F3FD 200D 2642 ; minimally-qualified # 🤹🏽♂ E4.0 man juggling: medium skin tone
-1F939 1F3FE 200D 2642 FE0F ; fully-qualified # 🤹🏾♂️ E4.0 man juggling: medium-dark skin tone
-1F939 1F3FE 200D 2642 ; minimally-qualified # 🤹🏾♂ E4.0 man juggling: medium-dark skin tone
-1F939 1F3FF 200D 2642 FE0F ; fully-qualified # 🤹🏿♂️ E4.0 man juggling: dark skin tone
-1F939 1F3FF 200D 2642 ; minimally-qualified # 🤹🏿♂ E4.0 man juggling: dark skin tone
-1F939 200D 2640 FE0F ; fully-qualified # 🤹♀️ E4.0 woman juggling
-1F939 200D 2640 ; minimally-qualified # 🤹♀ E4.0 woman juggling
-1F939 1F3FB 200D 2640 FE0F ; fully-qualified # 🤹🏻♀️ E4.0 woman juggling: light skin tone
-1F939 1F3FB 200D 2640 ; minimally-qualified # 🤹🏻♀ E4.0 woman juggling: light skin tone
-1F939 1F3FC 200D 2640 FE0F ; fully-qualified # 🤹🏼♀️ E4.0 woman juggling: medium-light skin tone
-1F939 1F3FC 200D 2640 ; minimally-qualified # 🤹🏼♀ E4.0 woman juggling: medium-light skin tone
-1F939 1F3FD 200D 2640 FE0F ; fully-qualified # 🤹🏽♀️ E4.0 woman juggling: medium skin tone
-1F939 1F3FD 200D 2640 ; minimally-qualified # 🤹🏽♀ E4.0 woman juggling: medium skin tone
-1F939 1F3FE 200D 2640 FE0F ; fully-qualified # 🤹🏾♀️ E4.0 woman juggling: medium-dark skin tone
-1F939 1F3FE 200D 2640 ; minimally-qualified # 🤹🏾♀ E4.0 woman juggling: medium-dark skin tone
-1F939 1F3FF 200D 2640 FE0F ; fully-qualified # 🤹🏿♀️ E4.0 woman juggling: dark skin tone
-1F939 1F3FF 200D 2640 ; minimally-qualified # 🤹🏿♀ E4.0 woman juggling: dark skin tone
+1F93A ; fully-qualified # 🤺 E3.0 person fencing
+1F3C7 ; fully-qualified # 🏇 E1.0 horse racing
+1F3C7 1F3FB ; fully-qualified # 🏇🏻 E1.0 horse racing: light skin tone
+1F3C7 1F3FC ; fully-qualified # 🏇🏼 E1.0 horse racing: medium-light skin tone
+1F3C7 1F3FD ; fully-qualified # 🏇🏽 E1.0 horse racing: medium skin tone
+1F3C7 1F3FE ; fully-qualified # 🏇🏾 E1.0 horse racing: medium-dark skin tone
+1F3C7 1F3FF ; fully-qualified # 🏇🏿 E1.0 horse racing: dark skin tone
+26F7 FE0F ; fully-qualified # ⛷️ E0.7 skier
+26F7 ; unqualified # ⛷ E0.7 skier
+1F3C2 ; fully-qualified # 🏂 E0.6 snowboarder
+1F3C2 1F3FB ; fully-qualified # 🏂🏻 E1.0 snowboarder: light skin tone
+1F3C2 1F3FC ; fully-qualified # 🏂🏼 E1.0 snowboarder: medium-light skin tone
+1F3C2 1F3FD ; fully-qualified # 🏂🏽 E1.0 snowboarder: medium skin tone
+1F3C2 1F3FE ; fully-qualified # 🏂🏾 E1.0 snowboarder: medium-dark skin tone
+1F3C2 1F3FF ; fully-qualified # 🏂🏿 E1.0 snowboarder: dark skin tone
+1F3CC FE0F ; fully-qualified # 🏌️ E0.7 person golfing
+1F3CC ; unqualified # 🏌 E0.7 person golfing
+1F3CC 1F3FB ; fully-qualified # 🏌🏻 E4.0 person golfing: light skin tone
+1F3CC 1F3FC ; fully-qualified # 🏌🏼 E4.0 person golfing: medium-light skin tone
+1F3CC 1F3FD ; fully-qualified # 🏌🏽 E4.0 person golfing: medium skin tone
+1F3CC 1F3FE ; fully-qualified # 🏌🏾 E4.0 person golfing: medium-dark skin tone
+1F3CC 1F3FF ; fully-qualified # 🏌🏿 E4.0 person golfing: dark skin tone
+1F3CC FE0F 200D 2642 FE0F ; fully-qualified # 🏌️♂️ E4.0 man golfing
+1F3CC 200D 2642 FE0F ; unqualified # 🏌♂️ E4.0 man golfing
+1F3CC FE0F 200D 2642 ; unqualified # 🏌️♂ E4.0 man golfing
+1F3CC 200D 2642 ; unqualified # 🏌♂ E4.0 man golfing
+1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # 🏌🏻♂️ E4.0 man golfing: light skin tone
+1F3CC 1F3FB 200D 2642 ; minimally-qualified # 🏌🏻♂ E4.0 man golfing: light skin tone
+1F3CC 1F3FC 200D 2642 FE0F ; fully-qualified # 🏌🏼♂️ E4.0 man golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2642 ; minimally-qualified # 🏌🏼♂ E4.0 man golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2642 FE0F ; fully-qualified # 🏌🏽♂️ E4.0 man golfing: medium skin tone
+1F3CC 1F3FD 200D 2642 ; minimally-qualified # 🏌🏽♂ E4.0 man golfing: medium skin tone
+1F3CC 1F3FE 200D 2642 FE0F ; fully-qualified # 🏌🏾♂️ E4.0 man golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2642 ; minimally-qualified # 🏌🏾♂ E4.0 man golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2642 FE0F ; fully-qualified # 🏌🏿♂️ E4.0 man golfing: dark skin tone
+1F3CC 1F3FF 200D 2642 ; minimally-qualified # 🏌🏿♂ E4.0 man golfing: dark skin tone
+1F3CC FE0F 200D 2640 FE0F ; fully-qualified # 🏌️♀️ E4.0 woman golfing
+1F3CC 200D 2640 FE0F ; unqualified # 🏌♀️ E4.0 woman golfing
+1F3CC FE0F 200D 2640 ; unqualified # 🏌️♀ E4.0 woman golfing
+1F3CC 200D 2640 ; unqualified # 🏌♀ E4.0 woman golfing
+1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # 🏌🏻♀️ E4.0 woman golfing: light skin tone
+1F3CC 1F3FB 200D 2640 ; minimally-qualified # 🏌🏻♀ E4.0 woman golfing: light skin tone
+1F3CC 1F3FC 200D 2640 FE0F ; fully-qualified # 🏌🏼♀️ E4.0 woman golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2640 ; minimally-qualified # 🏌🏼♀ E4.0 woman golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2640 FE0F ; fully-qualified # 🏌🏽♀️ E4.0 woman golfing: medium skin tone
+1F3CC 1F3FD 200D 2640 ; minimally-qualified # 🏌🏽♀ E4.0 woman golfing: medium skin tone
+1F3CC 1F3FE 200D 2640 FE0F ; fully-qualified # 🏌🏾♀️ E4.0 woman golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2640 ; minimally-qualified # 🏌🏾♀ E4.0 woman golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2640 FE0F ; fully-qualified # 🏌🏿♀️ E4.0 woman golfing: dark skin tone
+1F3CC 1F3FF 200D 2640 ; minimally-qualified # 🏌🏿♀ E4.0 woman golfing: dark skin tone
+1F3C4 ; fully-qualified # 🏄 E0.6 person surfing
+1F3C4 1F3FB ; fully-qualified # 🏄🏻 E1.0 person surfing: light skin tone
+1F3C4 1F3FC ; fully-qualified # 🏄🏼 E1.0 person surfing: medium-light skin tone
+1F3C4 1F3FD ; fully-qualified # 🏄🏽 E1.0 person surfing: medium skin tone
+1F3C4 1F3FE ; fully-qualified # 🏄🏾 E1.0 person surfing: medium-dark skin tone
+1F3C4 1F3FF ; fully-qualified # 🏄🏿 E1.0 person surfing: dark skin tone
+1F3C4 200D 2642 FE0F ; fully-qualified # 🏄♂️ E4.0 man surfing
+1F3C4 200D 2642 ; minimally-qualified # 🏄♂ E4.0 man surfing
+1F3C4 1F3FB 200D 2642 FE0F ; fully-qualified # 🏄🏻♂️ E4.0 man surfing: light skin tone
+1F3C4 1F3FB 200D 2642 ; minimally-qualified # 🏄🏻♂ E4.0 man surfing: light skin tone
+1F3C4 1F3FC 200D 2642 FE0F ; fully-qualified # 🏄🏼♂️ E4.0 man surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2642 ; minimally-qualified # 🏄🏼♂ E4.0 man surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2642 FE0F ; fully-qualified # 🏄🏽♂️ E4.0 man surfing: medium skin tone
+1F3C4 1F3FD 200D 2642 ; minimally-qualified # 🏄🏽♂ E4.0 man surfing: medium skin tone
+1F3C4 1F3FE 200D 2642 FE0F ; fully-qualified # 🏄🏾♂️ E4.0 man surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2642 ; minimally-qualified # 🏄🏾♂ E4.0 man surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2642 FE0F ; fully-qualified # 🏄🏿♂️ E4.0 man surfing: dark skin tone
+1F3C4 1F3FF 200D 2642 ; minimally-qualified # 🏄🏿♂ E4.0 man surfing: dark skin tone
+1F3C4 200D 2640 FE0F ; fully-qualified # 🏄♀️ E4.0 woman surfing
+1F3C4 200D 2640 ; minimally-qualified # 🏄♀ E4.0 woman surfing
+1F3C4 1F3FB 200D 2640 FE0F ; fully-qualified # 🏄🏻♀️ E4.0 woman surfing: light skin tone
+1F3C4 1F3FB 200D 2640 ; minimally-qualified # 🏄🏻♀ E4.0 woman surfing: light skin tone
+1F3C4 1F3FC 200D 2640 FE0F ; fully-qualified # 🏄🏼♀️ E4.0 woman surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2640 ; minimally-qualified # 🏄🏼♀ E4.0 woman surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2640 FE0F ; fully-qualified # 🏄🏽♀️ E4.0 woman surfing: medium skin tone
+1F3C4 1F3FD 200D 2640 ; minimally-qualified # 🏄🏽♀ E4.0 woman surfing: medium skin tone
+1F3C4 1F3FE 200D 2640 FE0F ; fully-qualified # 🏄🏾♀️ E4.0 woman surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2640 ; minimally-qualified # 🏄🏾♀ E4.0 woman surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2640 FE0F ; fully-qualified # 🏄🏿♀️ E4.0 woman surfing: dark skin tone
+1F3C4 1F3FF 200D 2640 ; minimally-qualified # 🏄🏿♀ E4.0 woman surfing: dark skin tone
+1F6A3 ; fully-qualified # 🚣 E1.0 person rowing boat
+1F6A3 1F3FB ; fully-qualified # 🚣🏻 E1.0 person rowing boat: light skin tone
+1F6A3 1F3FC ; fully-qualified # 🚣🏼 E1.0 person rowing boat: medium-light skin tone
+1F6A3 1F3FD ; fully-qualified # 🚣🏽 E1.0 person rowing boat: medium skin tone
+1F6A3 1F3FE ; fully-qualified # 🚣🏾 E1.0 person rowing boat: medium-dark skin tone
+1F6A3 1F3FF ; fully-qualified # 🚣🏿 E1.0 person rowing boat: dark skin tone
+1F6A3 200D 2642 FE0F ; fully-qualified # 🚣♂️ E4.0 man rowing boat
+1F6A3 200D 2642 ; minimally-qualified # 🚣♂ E4.0 man rowing boat
+1F6A3 1F3FB 200D 2642 FE0F ; fully-qualified # 🚣🏻♂️ E4.0 man rowing boat: light skin tone
+1F6A3 1F3FB 200D 2642 ; minimally-qualified # 🚣🏻♂ E4.0 man rowing boat: light skin tone
+1F6A3 1F3FC 200D 2642 FE0F ; fully-qualified # 🚣🏼♂️ E4.0 man rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2642 ; minimally-qualified # 🚣🏼♂ E4.0 man rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2642 FE0F ; fully-qualified # 🚣🏽♂️ E4.0 man rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2642 ; minimally-qualified # 🚣🏽♂ E4.0 man rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2642 FE0F ; fully-qualified # 🚣🏾♂️ E4.0 man rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2642 ; minimally-qualified # 🚣🏾♂ E4.0 man rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2642 FE0F ; fully-qualified # 🚣🏿♂️ E4.0 man rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2642 ; minimally-qualified # 🚣🏿♂ E4.0 man rowing boat: dark skin tone
+1F6A3 200D 2640 FE0F ; fully-qualified # 🚣♀️ E4.0 woman rowing boat
+1F6A3 200D 2640 ; minimally-qualified # 🚣♀ E4.0 woman rowing boat
+1F6A3 1F3FB 200D 2640 FE0F ; fully-qualified # 🚣🏻♀️ E4.0 woman rowing boat: light skin tone
+1F6A3 1F3FB 200D 2640 ; minimally-qualified # 🚣🏻♀ E4.0 woman rowing boat: light skin tone
+1F6A3 1F3FC 200D 2640 FE0F ; fully-qualified # 🚣🏼♀️ E4.0 woman rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2640 ; minimally-qualified # 🚣🏼♀ E4.0 woman rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2640 FE0F ; fully-qualified # 🚣🏽♀️ E4.0 woman rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2640 ; minimally-qualified # 🚣🏽♀ E4.0 woman rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2640 FE0F ; fully-qualified # 🚣🏾♀️ E4.0 woman rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2640 ; minimally-qualified # 🚣🏾♀ E4.0 woman rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2640 FE0F ; fully-qualified # 🚣🏿♀️ E4.0 woman rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2640 ; minimally-qualified # 🚣🏿♀ E4.0 woman rowing boat: dark skin tone
+1F3CA ; fully-qualified # 🏊 E0.6 person swimming
+1F3CA 1F3FB ; fully-qualified # 🏊🏻 E1.0 person swimming: light skin tone
+1F3CA 1F3FC ; fully-qualified # 🏊🏼 E1.0 person swimming: medium-light skin tone
+1F3CA 1F3FD ; fully-qualified # 🏊🏽 E1.0 person swimming: medium skin tone
+1F3CA 1F3FE ; fully-qualified # 🏊🏾 E1.0 person swimming: medium-dark skin tone
+1F3CA 1F3FF ; fully-qualified # 🏊🏿 E1.0 person swimming: dark skin tone
+1F3CA 200D 2642 FE0F ; fully-qualified # 🏊♂️ E4.0 man swimming
+1F3CA 200D 2642 ; minimally-qualified # 🏊♂ E4.0 man swimming
+1F3CA 1F3FB 200D 2642 FE0F ; fully-qualified # 🏊🏻♂️ E4.0 man swimming: light skin tone
+1F3CA 1F3FB 200D 2642 ; minimally-qualified # 🏊🏻♂ E4.0 man swimming: light skin tone
+1F3CA 1F3FC 200D 2642 FE0F ; fully-qualified # 🏊🏼♂️ E4.0 man swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2642 ; minimally-qualified # 🏊🏼♂ E4.0 man swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2642 FE0F ; fully-qualified # 🏊🏽♂️ E4.0 man swimming: medium skin tone
+1F3CA 1F3FD 200D 2642 ; minimally-qualified # 🏊🏽♂ E4.0 man swimming: medium skin tone
+1F3CA 1F3FE 200D 2642 FE0F ; fully-qualified # 🏊🏾♂️ E4.0 man swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2642 ; minimally-qualified # 🏊🏾♂ E4.0 man swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2642 FE0F ; fully-qualified # 🏊🏿♂️ E4.0 man swimming: dark skin tone
+1F3CA 1F3FF 200D 2642 ; minimally-qualified # 🏊🏿♂ E4.0 man swimming: dark skin tone
+1F3CA 200D 2640 FE0F ; fully-qualified # 🏊♀️ E4.0 woman swimming
+1F3CA 200D 2640 ; minimally-qualified # 🏊♀ E4.0 woman swimming
+1F3CA 1F3FB 200D 2640 FE0F ; fully-qualified # 🏊🏻♀️ E4.0 woman swimming: light skin tone
+1F3CA 1F3FB 200D 2640 ; minimally-qualified # 🏊🏻♀ E4.0 woman swimming: light skin tone
+1F3CA 1F3FC 200D 2640 FE0F ; fully-qualified # 🏊🏼♀️ E4.0 woman swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2640 ; minimally-qualified # 🏊🏼♀ E4.0 woman swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2640 FE0F ; fully-qualified # 🏊🏽♀️ E4.0 woman swimming: medium skin tone
+1F3CA 1F3FD 200D 2640 ; minimally-qualified # 🏊🏽♀ E4.0 woman swimming: medium skin tone
+1F3CA 1F3FE 200D 2640 FE0F ; fully-qualified # 🏊🏾♀️ E4.0 woman swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2640 ; minimally-qualified # 🏊🏾♀ E4.0 woman swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2640 FE0F ; fully-qualified # 🏊🏿♀️ E4.0 woman swimming: dark skin tone
+1F3CA 1F3FF 200D 2640 ; minimally-qualified # 🏊🏿♀ E4.0 woman swimming: dark skin tone
+26F9 FE0F ; fully-qualified # ⛹️ E0.7 person bouncing ball
+26F9 ; unqualified # ⛹ E0.7 person bouncing ball
+26F9 1F3FB ; fully-qualified # ⛹🏻 E2.0 person bouncing ball: light skin tone
+26F9 1F3FC ; fully-qualified # ⛹🏼 E2.0 person bouncing ball: medium-light skin tone
+26F9 1F3FD ; fully-qualified # ⛹🏽 E2.0 person bouncing ball: medium skin tone
+26F9 1F3FE ; fully-qualified # ⛹🏾 E2.0 person bouncing ball: medium-dark skin tone
+26F9 1F3FF ; fully-qualified # ⛹🏿 E2.0 person bouncing ball: dark skin tone
+26F9 FE0F 200D 2642 FE0F ; fully-qualified # ⛹️♂️ E4.0 man bouncing ball
+26F9 200D 2642 FE0F ; unqualified # ⛹♂️ E4.0 man bouncing ball
+26F9 FE0F 200D 2642 ; unqualified # ⛹️♂ E4.0 man bouncing ball
+26F9 200D 2642 ; unqualified # ⛹♂ E4.0 man bouncing ball
+26F9 1F3FB 200D 2642 FE0F ; fully-qualified # ⛹🏻♂️ E4.0 man bouncing ball: light skin tone
+26F9 1F3FB 200D 2642 ; minimally-qualified # ⛹🏻♂ E4.0 man bouncing ball: light skin tone
+26F9 1F3FC 200D 2642 FE0F ; fully-qualified # ⛹🏼♂️ E4.0 man bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2642 ; minimally-qualified # ⛹🏼♂ E4.0 man bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2642 FE0F ; fully-qualified # ⛹🏽♂️ E4.0 man bouncing ball: medium skin tone
+26F9 1F3FD 200D 2642 ; minimally-qualified # ⛹🏽♂ E4.0 man bouncing ball: medium skin tone
+26F9 1F3FE 200D 2642 FE0F ; fully-qualified # ⛹🏾♂️ E4.0 man bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2642 ; minimally-qualified # ⛹🏾♂ E4.0 man bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2642 FE0F ; fully-qualified # ⛹🏿♂️ E4.0 man bouncing ball: dark skin tone
+26F9 1F3FF 200D 2642 ; minimally-qualified # ⛹🏿♂ E4.0 man bouncing ball: dark skin tone
+26F9 FE0F 200D 2640 FE0F ; fully-qualified # ⛹️♀️ E4.0 woman bouncing ball
+26F9 200D 2640 FE0F ; unqualified # ⛹♀️ E4.0 woman bouncing ball
+26F9 FE0F 200D 2640 ; unqualified # ⛹️♀ E4.0 woman bouncing ball
+26F9 200D 2640 ; unqualified # ⛹♀ E4.0 woman bouncing ball
+26F9 1F3FB 200D 2640 FE0F ; fully-qualified # ⛹🏻♀️ E4.0 woman bouncing ball: light skin tone
+26F9 1F3FB 200D 2640 ; minimally-qualified # ⛹🏻♀ E4.0 woman bouncing ball: light skin tone
+26F9 1F3FC 200D 2640 FE0F ; fully-qualified # ⛹🏼♀️ E4.0 woman bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2640 ; minimally-qualified # ⛹🏼♀ E4.0 woman bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2640 FE0F ; fully-qualified # ⛹🏽♀️ E4.0 woman bouncing ball: medium skin tone
+26F9 1F3FD 200D 2640 ; minimally-qualified # ⛹🏽♀ E4.0 woman bouncing ball: medium skin tone
+26F9 1F3FE 200D 2640 FE0F ; fully-qualified # ⛹🏾♀️ E4.0 woman bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2640 ; minimally-qualified # ⛹🏾♀ E4.0 woman bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2640 FE0F ; fully-qualified # ⛹🏿♀️ E4.0 woman bouncing ball: dark skin tone
+26F9 1F3FF 200D 2640 ; minimally-qualified # ⛹🏿♀ E4.0 woman bouncing ball: dark skin tone
+1F3CB FE0F ; fully-qualified # 🏋️ E0.7 person lifting weights
+1F3CB ; unqualified # 🏋 E0.7 person lifting weights
+1F3CB 1F3FB ; fully-qualified # 🏋🏻 E2.0 person lifting weights: light skin tone
+1F3CB 1F3FC ; fully-qualified # 🏋🏼 E2.0 person lifting weights: medium-light skin tone
+1F3CB 1F3FD ; fully-qualified # 🏋🏽 E2.0 person lifting weights: medium skin tone
+1F3CB 1F3FE ; fully-qualified # 🏋🏾 E2.0 person lifting weights: medium-dark skin tone
+1F3CB 1F3FF ; fully-qualified # 🏋🏿 E2.0 person lifting weights: dark skin tone
+1F3CB FE0F 200D 2642 FE0F ; fully-qualified # 🏋️♂️ E4.0 man lifting weights
+1F3CB 200D 2642 FE0F ; unqualified # 🏋♂️ E4.0 man lifting weights
+1F3CB FE0F 200D 2642 ; unqualified # 🏋️♂ E4.0 man lifting weights
+1F3CB 200D 2642 ; unqualified # 🏋♂ E4.0 man lifting weights
+1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # 🏋🏻♂️ E4.0 man lifting weights: light skin tone
+1F3CB 1F3FB 200D 2642 ; minimally-qualified # 🏋🏻♂ E4.0 man lifting weights: light skin tone
+1F3CB 1F3FC 200D 2642 FE0F ; fully-qualified # 🏋🏼♂️ E4.0 man lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2642 ; minimally-qualified # 🏋🏼♂ E4.0 man lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2642 FE0F ; fully-qualified # 🏋🏽♂️ E4.0 man lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2642 ; minimally-qualified # 🏋🏽♂ E4.0 man lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2642 FE0F ; fully-qualified # 🏋🏾♂️ E4.0 man lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2642 ; minimally-qualified # 🏋🏾♂ E4.0 man lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2642 FE0F ; fully-qualified # 🏋🏿♂️ E4.0 man lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2642 ; minimally-qualified # 🏋🏿♂ E4.0 man lifting weights: dark skin tone
+1F3CB FE0F 200D 2640 FE0F ; fully-qualified # 🏋️♀️ E4.0 woman lifting weights
+1F3CB 200D 2640 FE0F ; unqualified # 🏋♀️ E4.0 woman lifting weights
+1F3CB FE0F 200D 2640 ; unqualified # 🏋️♀ E4.0 woman lifting weights
+1F3CB 200D 2640 ; unqualified # 🏋♀ E4.0 woman lifting weights
+1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # 🏋🏻♀️ E4.0 woman lifting weights: light skin tone
+1F3CB 1F3FB 200D 2640 ; minimally-qualified # 🏋🏻♀ E4.0 woman lifting weights: light skin tone
+1F3CB 1F3FC 200D 2640 FE0F ; fully-qualified # 🏋🏼♀️ E4.0 woman lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2640 ; minimally-qualified # 🏋🏼♀ E4.0 woman lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2640 FE0F ; fully-qualified # 🏋🏽♀️ E4.0 woman lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2640 ; minimally-qualified # 🏋🏽♀ E4.0 woman lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2640 FE0F ; fully-qualified # 🏋🏾♀️ E4.0 woman lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2640 ; minimally-qualified # 🏋🏾♀ E4.0 woman lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2640 FE0F ; fully-qualified # 🏋🏿♀️ E4.0 woman lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2640 ; minimally-qualified # 🏋🏿♀ E4.0 woman lifting weights: dark skin tone
+1F6B4 ; fully-qualified # 🚴 E1.0 person biking
+1F6B4 1F3FB ; fully-qualified # 🚴🏻 E1.0 person biking: light skin tone
+1F6B4 1F3FC ; fully-qualified # 🚴🏼 E1.0 person biking: medium-light skin tone
+1F6B4 1F3FD ; fully-qualified # 🚴🏽 E1.0 person biking: medium skin tone
+1F6B4 1F3FE ; fully-qualified # 🚴🏾 E1.0 person biking: medium-dark skin tone
+1F6B4 1F3FF ; fully-qualified # 🚴🏿 E1.0 person biking: dark skin tone
+1F6B4 200D 2642 FE0F ; fully-qualified # 🚴♂️ E4.0 man biking
+1F6B4 200D 2642 ; minimally-qualified # 🚴♂ E4.0 man biking
+1F6B4 1F3FB 200D 2642 FE0F ; fully-qualified # 🚴🏻♂️ E4.0 man biking: light skin tone
+1F6B4 1F3FB 200D 2642 ; minimally-qualified # 🚴🏻♂ E4.0 man biking: light skin tone
+1F6B4 1F3FC 200D 2642 FE0F ; fully-qualified # 🚴🏼♂️ E4.0 man biking: medium-light skin tone
+1F6B4 1F3FC 200D 2642 ; minimally-qualified # 🚴🏼♂ E4.0 man biking: medium-light skin tone
+1F6B4 1F3FD 200D 2642 FE0F ; fully-qualified # 🚴🏽♂️ E4.0 man biking: medium skin tone
+1F6B4 1F3FD 200D 2642 ; minimally-qualified # 🚴🏽♂ E4.0 man biking: medium skin tone
+1F6B4 1F3FE 200D 2642 FE0F ; fully-qualified # 🚴🏾♂️ E4.0 man biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2642 ; minimally-qualified # 🚴🏾♂ E4.0 man biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2642 FE0F ; fully-qualified # 🚴🏿♂️ E4.0 man biking: dark skin tone
+1F6B4 1F3FF 200D 2642 ; minimally-qualified # 🚴🏿♂ E4.0 man biking: dark skin tone
+1F6B4 200D 2640 FE0F ; fully-qualified # 🚴♀️ E4.0 woman biking
+1F6B4 200D 2640 ; minimally-qualified # 🚴♀ E4.0 woman biking
+1F6B4 1F3FB 200D 2640 FE0F ; fully-qualified # 🚴🏻♀️ E4.0 woman biking: light skin tone
+1F6B4 1F3FB 200D 2640 ; minimally-qualified # 🚴🏻♀ E4.0 woman biking: light skin tone
+1F6B4 1F3FC 200D 2640 FE0F ; fully-qualified # 🚴🏼♀️ E4.0 woman biking: medium-light skin tone
+1F6B4 1F3FC 200D 2640 ; minimally-qualified # 🚴🏼♀ E4.0 woman biking: medium-light skin tone
+1F6B4 1F3FD 200D 2640 FE0F ; fully-qualified # 🚴🏽♀️ E4.0 woman biking: medium skin tone
+1F6B4 1F3FD 200D 2640 ; minimally-qualified # 🚴🏽♀ E4.0 woman biking: medium skin tone
+1F6B4 1F3FE 200D 2640 FE0F ; fully-qualified # 🚴🏾♀️ E4.0 woman biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2640 ; minimally-qualified # 🚴🏾♀ E4.0 woman biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2640 FE0F ; fully-qualified # 🚴🏿♀️ E4.0 woman biking: dark skin tone
+1F6B4 1F3FF 200D 2640 ; minimally-qualified # 🚴🏿♀ E4.0 woman biking: dark skin tone
+1F6B5 ; fully-qualified # 🚵 E1.0 person mountain biking
+1F6B5 1F3FB ; fully-qualified # 🚵🏻 E1.0 person mountain biking: light skin tone
+1F6B5 1F3FC ; fully-qualified # 🚵🏼 E1.0 person mountain biking: medium-light skin tone
+1F6B5 1F3FD ; fully-qualified # 🚵🏽 E1.0 person mountain biking: medium skin tone
+1F6B5 1F3FE ; fully-qualified # 🚵🏾 E1.0 person mountain biking: medium-dark skin tone
+1F6B5 1F3FF ; fully-qualified # 🚵🏿 E1.0 person mountain biking: dark skin tone
+1F6B5 200D 2642 FE0F ; fully-qualified # 🚵♂️ E4.0 man mountain biking
+1F6B5 200D 2642 ; minimally-qualified # 🚵♂ E4.0 man mountain biking
+1F6B5 1F3FB 200D 2642 FE0F ; fully-qualified # 🚵🏻♂️ E4.0 man mountain biking: light skin tone
+1F6B5 1F3FB 200D 2642 ; minimally-qualified # 🚵🏻♂ E4.0 man mountain biking: light skin tone
+1F6B5 1F3FC 200D 2642 FE0F ; fully-qualified # 🚵🏼♂️ E4.0 man mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2642 ; minimally-qualified # 🚵🏼♂ E4.0 man mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2642 FE0F ; fully-qualified # 🚵🏽♂️ E4.0 man mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2642 ; minimally-qualified # 🚵🏽♂ E4.0 man mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2642 FE0F ; fully-qualified # 🚵🏾♂️ E4.0 man mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2642 ; minimally-qualified # 🚵🏾♂ E4.0 man mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2642 FE0F ; fully-qualified # 🚵🏿♂️ E4.0 man mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2642 ; minimally-qualified # 🚵🏿♂ E4.0 man mountain biking: dark skin tone
+1F6B5 200D 2640 FE0F ; fully-qualified # 🚵♀️ E4.0 woman mountain biking
+1F6B5 200D 2640 ; minimally-qualified # 🚵♀ E4.0 woman mountain biking
+1F6B5 1F3FB 200D 2640 FE0F ; fully-qualified # 🚵🏻♀️ E4.0 woman mountain biking: light skin tone
+1F6B5 1F3FB 200D 2640 ; minimally-qualified # 🚵🏻♀ E4.0 woman mountain biking: light skin tone
+1F6B5 1F3FC 200D 2640 FE0F ; fully-qualified # 🚵🏼♀️ E4.0 woman mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2640 ; minimally-qualified # 🚵🏼♀ E4.0 woman mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2640 FE0F ; fully-qualified # 🚵🏽♀️ E4.0 woman mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2640 ; minimally-qualified # 🚵🏽♀ E4.0 woman mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2640 FE0F ; fully-qualified # 🚵🏾♀️ E4.0 woman mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2640 ; minimally-qualified # 🚵🏾♀ E4.0 woman mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2640 FE0F ; fully-qualified # 🚵🏿♀️ E4.0 woman mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2640 ; minimally-qualified # 🚵🏿♀ E4.0 woman mountain biking: dark skin tone
+1F938 ; fully-qualified # 🤸 E3.0 person cartwheeling
+1F938 1F3FB ; fully-qualified # 🤸🏻 E3.0 person cartwheeling: light skin tone
+1F938 1F3FC ; fully-qualified # 🤸🏼 E3.0 person cartwheeling: medium-light skin tone
+1F938 1F3FD ; fully-qualified # 🤸🏽 E3.0 person cartwheeling: medium skin tone
+1F938 1F3FE ; fully-qualified # 🤸🏾 E3.0 person cartwheeling: medium-dark skin tone
+1F938 1F3FF ; fully-qualified # 🤸🏿 E3.0 person cartwheeling: dark skin tone
+1F938 200D 2642 FE0F ; fully-qualified # 🤸♂️ E4.0 man cartwheeling
+1F938 200D 2642 ; minimally-qualified # 🤸♂ E4.0 man cartwheeling
+1F938 1F3FB 200D 2642 FE0F ; fully-qualified # 🤸🏻♂️ E4.0 man cartwheeling: light skin tone
+1F938 1F3FB 200D 2642 ; minimally-qualified # 🤸🏻♂ E4.0 man cartwheeling: light skin tone
+1F938 1F3FC 200D 2642 FE0F ; fully-qualified # 🤸🏼♂️ E4.0 man cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2642 ; minimally-qualified # 🤸🏼♂ E4.0 man cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2642 FE0F ; fully-qualified # 🤸🏽♂️ E4.0 man cartwheeling: medium skin tone
+1F938 1F3FD 200D 2642 ; minimally-qualified # 🤸🏽♂ E4.0 man cartwheeling: medium skin tone
+1F938 1F3FE 200D 2642 FE0F ; fully-qualified # 🤸🏾♂️ E4.0 man cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2642 ; minimally-qualified # 🤸🏾♂ E4.0 man cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2642 FE0F ; fully-qualified # 🤸🏿♂️ E4.0 man cartwheeling: dark skin tone
+1F938 1F3FF 200D 2642 ; minimally-qualified # 🤸🏿♂ E4.0 man cartwheeling: dark skin tone
+1F938 200D 2640 FE0F ; fully-qualified # 🤸♀️ E4.0 woman cartwheeling
+1F938 200D 2640 ; minimally-qualified # 🤸♀ E4.0 woman cartwheeling
+1F938 1F3FB 200D 2640 FE0F ; fully-qualified # 🤸🏻♀️ E4.0 woman cartwheeling: light skin tone
+1F938 1F3FB 200D 2640 ; minimally-qualified # 🤸🏻♀ E4.0 woman cartwheeling: light skin tone
+1F938 1F3FC 200D 2640 FE0F ; fully-qualified # 🤸🏼♀️ E4.0 woman cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2640 ; minimally-qualified # 🤸🏼♀ E4.0 woman cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2640 FE0F ; fully-qualified # 🤸🏽♀️ E4.0 woman cartwheeling: medium skin tone
+1F938 1F3FD 200D 2640 ; minimally-qualified # 🤸🏽♀ E4.0 woman cartwheeling: medium skin tone
+1F938 1F3FE 200D 2640 FE0F ; fully-qualified # 🤸🏾♀️ E4.0 woman cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2640 ; minimally-qualified # 🤸🏾♀ E4.0 woman cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2640 FE0F ; fully-qualified # 🤸🏿♀️ E4.0 woman cartwheeling: dark skin tone
+1F938 1F3FF 200D 2640 ; minimally-qualified # 🤸🏿♀ E4.0 woman cartwheeling: dark skin tone
+1F93C ; fully-qualified # 🤼 E3.0 people wrestling
+1F93C 200D 2642 FE0F ; fully-qualified # 🤼♂️ E4.0 men wrestling
+1F93C 200D 2642 ; minimally-qualified # 🤼♂ E4.0 men wrestling
+1F93C 200D 2640 FE0F ; fully-qualified # 🤼♀️ E4.0 women wrestling
+1F93C 200D 2640 ; minimally-qualified # 🤼♀ E4.0 women wrestling
+1F93D ; fully-qualified # 🤽 E3.0 person playing water polo
+1F93D 1F3FB ; fully-qualified # 🤽🏻 E3.0 person playing water polo: light skin tone
+1F93D 1F3FC ; fully-qualified # 🤽🏼 E3.0 person playing water polo: medium-light skin tone
+1F93D 1F3FD ; fully-qualified # 🤽🏽 E3.0 person playing water polo: medium skin tone
+1F93D 1F3FE ; fully-qualified # 🤽🏾 E3.0 person playing water polo: medium-dark skin tone
+1F93D 1F3FF ; fully-qualified # 🤽🏿 E3.0 person playing water polo: dark skin tone
+1F93D 200D 2642 FE0F ; fully-qualified # 🤽♂️ E4.0 man playing water polo
+1F93D 200D 2642 ; minimally-qualified # 🤽♂ E4.0 man playing water polo
+1F93D 1F3FB 200D 2642 FE0F ; fully-qualified # 🤽🏻♂️ E4.0 man playing water polo: light skin tone
+1F93D 1F3FB 200D 2642 ; minimally-qualified # 🤽🏻♂ E4.0 man playing water polo: light skin tone
+1F93D 1F3FC 200D 2642 FE0F ; fully-qualified # 🤽🏼♂️ E4.0 man playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2642 ; minimally-qualified # 🤽🏼♂ E4.0 man playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2642 FE0F ; fully-qualified # 🤽🏽♂️ E4.0 man playing water polo: medium skin tone
+1F93D 1F3FD 200D 2642 ; minimally-qualified # 🤽🏽♂ E4.0 man playing water polo: medium skin tone
+1F93D 1F3FE 200D 2642 FE0F ; fully-qualified # 🤽🏾♂️ E4.0 man playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2642 ; minimally-qualified # 🤽🏾♂ E4.0 man playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2642 FE0F ; fully-qualified # 🤽🏿♂️ E4.0 man playing water polo: dark skin tone
+1F93D 1F3FF 200D 2642 ; minimally-qualified # 🤽🏿♂ E4.0 man playing water polo: dark skin tone
+1F93D 200D 2640 FE0F ; fully-qualified # 🤽♀️ E4.0 woman playing water polo
+1F93D 200D 2640 ; minimally-qualified # 🤽♀ E4.0 woman playing water polo
+1F93D 1F3FB 200D 2640 FE0F ; fully-qualified # 🤽🏻♀️ E4.0 woman playing water polo: light skin tone
+1F93D 1F3FB 200D 2640 ; minimally-qualified # 🤽🏻♀ E4.0 woman playing water polo: light skin tone
+1F93D 1F3FC 200D 2640 FE0F ; fully-qualified # 🤽🏼♀️ E4.0 woman playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2640 ; minimally-qualified # 🤽🏼♀ E4.0 woman playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2640 FE0F ; fully-qualified # 🤽🏽♀️ E4.0 woman playing water polo: medium skin tone
+1F93D 1F3FD 200D 2640 ; minimally-qualified # 🤽🏽♀ E4.0 woman playing water polo: medium skin tone
+1F93D 1F3FE 200D 2640 FE0F ; fully-qualified # 🤽🏾♀️ E4.0 woman playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2640 ; minimally-qualified # 🤽🏾♀ E4.0 woman playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2640 FE0F ; fully-qualified # 🤽🏿♀️ E4.0 woman playing water polo: dark skin tone
+1F93D 1F3FF 200D 2640 ; minimally-qualified # 🤽🏿♀ E4.0 woman playing water polo: dark skin tone
+1F93E ; fully-qualified # 🤾 E3.0 person playing handball
+1F93E 1F3FB ; fully-qualified # 🤾🏻 E3.0 person playing handball: light skin tone
+1F93E 1F3FC ; fully-qualified # 🤾🏼 E3.0 person playing handball: medium-light skin tone
+1F93E 1F3FD ; fully-qualified # 🤾🏽 E3.0 person playing handball: medium skin tone
+1F93E 1F3FE ; fully-qualified # 🤾🏾 E3.0 person playing handball: medium-dark skin tone
+1F93E 1F3FF ; fully-qualified # 🤾🏿 E3.0 person playing handball: dark skin tone
+1F93E 200D 2642 FE0F ; fully-qualified # 🤾♂️ E4.0 man playing handball
+1F93E 200D 2642 ; minimally-qualified # 🤾♂ E4.0 man playing handball
+1F93E 1F3FB 200D 2642 FE0F ; fully-qualified # 🤾🏻♂️ E4.0 man playing handball: light skin tone
+1F93E 1F3FB 200D 2642 ; minimally-qualified # 🤾🏻♂ E4.0 man playing handball: light skin tone
+1F93E 1F3FC 200D 2642 FE0F ; fully-qualified # 🤾🏼♂️ E4.0 man playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2642 ; minimally-qualified # 🤾🏼♂ E4.0 man playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2642 FE0F ; fully-qualified # 🤾🏽♂️ E4.0 man playing handball: medium skin tone
+1F93E 1F3FD 200D 2642 ; minimally-qualified # 🤾🏽♂ E4.0 man playing handball: medium skin tone
+1F93E 1F3FE 200D 2642 FE0F ; fully-qualified # 🤾🏾♂️ E4.0 man playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2642 ; minimally-qualified # 🤾🏾♂ E4.0 man playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2642 FE0F ; fully-qualified # 🤾🏿♂️ E4.0 man playing handball: dark skin tone
+1F93E 1F3FF 200D 2642 ; minimally-qualified # 🤾🏿♂ E4.0 man playing handball: dark skin tone
+1F93E 200D 2640 FE0F ; fully-qualified # 🤾♀️ E4.0 woman playing handball
+1F93E 200D 2640 ; minimally-qualified # 🤾♀ E4.0 woman playing handball
+1F93E 1F3FB 200D 2640 FE0F ; fully-qualified # 🤾🏻♀️ E4.0 woman playing handball: light skin tone
+1F93E 1F3FB 200D 2640 ; minimally-qualified # 🤾🏻♀ E4.0 woman playing handball: light skin tone
+1F93E 1F3FC 200D 2640 FE0F ; fully-qualified # 🤾🏼♀️ E4.0 woman playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2640 ; minimally-qualified # 🤾🏼♀ E4.0 woman playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2640 FE0F ; fully-qualified # 🤾🏽♀️ E4.0 woman playing handball: medium skin tone
+1F93E 1F3FD 200D 2640 ; minimally-qualified # 🤾🏽♀ E4.0 woman playing handball: medium skin tone
+1F93E 1F3FE 200D 2640 FE0F ; fully-qualified # 🤾🏾♀️ E4.0 woman playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2640 ; minimally-qualified # 🤾🏾♀ E4.0 woman playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2640 FE0F ; fully-qualified # 🤾🏿♀️ E4.0 woman playing handball: dark skin tone
+1F93E 1F3FF 200D 2640 ; minimally-qualified # 🤾🏿♀ E4.0 woman playing handball: dark skin tone
+1F939 ; fully-qualified # 🤹 E3.0 person juggling
+1F939 1F3FB ; fully-qualified # 🤹🏻 E3.0 person juggling: light skin tone
+1F939 1F3FC ; fully-qualified # 🤹🏼 E3.0 person juggling: medium-light skin tone
+1F939 1F3FD ; fully-qualified # 🤹🏽 E3.0 person juggling: medium skin tone
+1F939 1F3FE ; fully-qualified # 🤹🏾 E3.0 person juggling: medium-dark skin tone
+1F939 1F3FF ; fully-qualified # 🤹🏿 E3.0 person juggling: dark skin tone
+1F939 200D 2642 FE0F ; fully-qualified # 🤹♂️ E4.0 man juggling
+1F939 200D 2642 ; minimally-qualified # 🤹♂ E4.0 man juggling
+1F939 1F3FB 200D 2642 FE0F ; fully-qualified # 🤹🏻♂️ E4.0 man juggling: light skin tone
+1F939 1F3FB 200D 2642 ; minimally-qualified # 🤹🏻♂ E4.0 man juggling: light skin tone
+1F939 1F3FC 200D 2642 FE0F ; fully-qualified # 🤹🏼♂️ E4.0 man juggling: medium-light skin tone
+1F939 1F3FC 200D 2642 ; minimally-qualified # 🤹🏼♂ E4.0 man juggling: medium-light skin tone
+1F939 1F3FD 200D 2642 FE0F ; fully-qualified # 🤹🏽♂️ E4.0 man juggling: medium skin tone
+1F939 1F3FD 200D 2642 ; minimally-qualified # 🤹🏽♂ E4.0 man juggling: medium skin tone
+1F939 1F3FE 200D 2642 FE0F ; fully-qualified # 🤹🏾♂️ E4.0 man juggling: medium-dark skin tone
+1F939 1F3FE 200D 2642 ; minimally-qualified # 🤹🏾♂ E4.0 man juggling: medium-dark skin tone
+1F939 1F3FF 200D 2642 FE0F ; fully-qualified # 🤹🏿♂️ E4.0 man juggling: dark skin tone
+1F939 1F3FF 200D 2642 ; minimally-qualified # 🤹🏿♂ E4.0 man juggling: dark skin tone
+1F939 200D 2640 FE0F ; fully-qualified # 🤹♀️ E4.0 woman juggling
+1F939 200D 2640 ; minimally-qualified # 🤹♀ E4.0 woman juggling
+1F939 1F3FB 200D 2640 FE0F ; fully-qualified # 🤹🏻♀️ E4.0 woman juggling: light skin tone
+1F939 1F3FB 200D 2640 ; minimally-qualified # 🤹🏻♀ E4.0 woman juggling: light skin tone
+1F939 1F3FC 200D 2640 FE0F ; fully-qualified # 🤹🏼♀️ E4.0 woman juggling: medium-light skin tone
+1F939 1F3FC 200D 2640 ; minimally-qualified # 🤹🏼♀ E4.0 woman juggling: medium-light skin tone
+1F939 1F3FD 200D 2640 FE0F ; fully-qualified # 🤹🏽♀️ E4.0 woman juggling: medium skin tone
+1F939 1F3FD 200D 2640 ; minimally-qualified # 🤹🏽♀ E4.0 woman juggling: medium skin tone
+1F939 1F3FE 200D 2640 FE0F ; fully-qualified # 🤹🏾♀️ E4.0 woman juggling: medium-dark skin tone
+1F939 1F3FE 200D 2640 ; minimally-qualified # 🤹🏾♀ E4.0 woman juggling: medium-dark skin tone
+1F939 1F3FF 200D 2640 FE0F ; fully-qualified # 🤹🏿♀️ E4.0 woman juggling: dark skin tone
+1F939 1F3FF 200D 2640 ; minimally-qualified # 🤹🏿♀ E4.0 woman juggling: dark skin tone
# subgroup: person-resting
-1F9D8 ; fully-qualified # 🧘 E5.0 person in lotus position
-1F9D8 1F3FB ; fully-qualified # 🧘🏻 E5.0 person in lotus position: light skin tone
-1F9D8 1F3FC ; fully-qualified # 🧘🏼 E5.0 person in lotus position: medium-light skin tone
-1F9D8 1F3FD ; fully-qualified # 🧘🏽 E5.0 person in lotus position: medium skin tone
-1F9D8 1F3FE ; fully-qualified # 🧘🏾 E5.0 person in lotus position: medium-dark skin tone
-1F9D8 1F3FF ; fully-qualified # 🧘🏿 E5.0 person in lotus position: dark skin tone
-1F9D8 200D 2642 FE0F ; fully-qualified # 🧘♂️ E5.0 man in lotus position
-1F9D8 200D 2642 ; minimally-qualified # 🧘♂ E5.0 man in lotus position
-1F9D8 1F3FB 200D 2642 FE0F ; fully-qualified # 🧘🏻♂️ E5.0 man in lotus position: light skin tone
-1F9D8 1F3FB 200D 2642 ; minimally-qualified # 🧘🏻♂ E5.0 man in lotus position: light skin tone
-1F9D8 1F3FC 200D 2642 FE0F ; fully-qualified # 🧘🏼♂️ E5.0 man in lotus position: medium-light skin tone
-1F9D8 1F3FC 200D 2642 ; minimally-qualified # 🧘🏼♂ E5.0 man in lotus position: medium-light skin tone
-1F9D8 1F3FD 200D 2642 FE0F ; fully-qualified # 🧘🏽♂️ E5.0 man in lotus position: medium skin tone
-1F9D8 1F3FD 200D 2642 ; minimally-qualified # 🧘🏽♂ E5.0 man in lotus position: medium skin tone
-1F9D8 1F3FE 200D 2642 FE0F ; fully-qualified # 🧘🏾♂️ E5.0 man in lotus position: medium-dark skin tone
-1F9D8 1F3FE 200D 2642 ; minimally-qualified # 🧘🏾♂ E5.0 man in lotus position: medium-dark skin tone
-1F9D8 1F3FF 200D 2642 FE0F ; fully-qualified # 🧘🏿♂️ E5.0 man in lotus position: dark skin tone
-1F9D8 1F3FF 200D 2642 ; minimally-qualified # 🧘🏿♂ E5.0 man in lotus position: dark skin tone
-1F9D8 200D 2640 FE0F ; fully-qualified # 🧘♀️ E5.0 woman in lotus position
-1F9D8 200D 2640 ; minimally-qualified # 🧘♀ E5.0 woman in lotus position
-1F9D8 1F3FB 200D 2640 FE0F ; fully-qualified # 🧘🏻♀️ E5.0 woman in lotus position: light skin tone
-1F9D8 1F3FB 200D 2640 ; minimally-qualified # 🧘🏻♀ E5.0 woman in lotus position: light skin tone
-1F9D8 1F3FC 200D 2640 FE0F ; fully-qualified # 🧘🏼♀️ E5.0 woman in lotus position: medium-light skin tone
-1F9D8 1F3FC 200D 2640 ; minimally-qualified # 🧘🏼♀ E5.0 woman in lotus position: medium-light skin tone
-1F9D8 1F3FD 200D 2640 FE0F ; fully-qualified # 🧘🏽♀️ E5.0 woman in lotus position: medium skin tone
-1F9D8 1F3FD 200D 2640 ; minimally-qualified # 🧘🏽♀ E5.0 woman in lotus position: medium skin tone
-1F9D8 1F3FE 200D 2640 FE0F ; fully-qualified # 🧘🏾♀️ E5.0 woman in lotus position: medium-dark skin tone
-1F9D8 1F3FE 200D 2640 ; minimally-qualified # 🧘🏾♀ E5.0 woman in lotus position: medium-dark skin tone
-1F9D8 1F3FF 200D 2640 FE0F ; fully-qualified # 🧘🏿♀️ E5.0 woman in lotus position: dark skin tone
-1F9D8 1F3FF 200D 2640 ; minimally-qualified # 🧘🏿♀ E5.0 woman in lotus position: dark skin tone
-1F6C0 ; fully-qualified # 🛀 E0.6 person taking bath
-1F6C0 1F3FB ; fully-qualified # 🛀🏻 E1.0 person taking bath: light skin tone
-1F6C0 1F3FC ; fully-qualified # 🛀🏼 E1.0 person taking bath: medium-light skin tone
-1F6C0 1F3FD ; fully-qualified # 🛀🏽 E1.0 person taking bath: medium skin tone
-1F6C0 1F3FE ; fully-qualified # 🛀🏾 E1.0 person taking bath: medium-dark skin tone
-1F6C0 1F3FF ; fully-qualified # 🛀🏿 E1.0 person taking bath: dark skin tone
-1F6CC ; fully-qualified # 🛌 E1.0 person in bed
-1F6CC 1F3FB ; fully-qualified # 🛌🏻 E4.0 person in bed: light skin tone
-1F6CC 1F3FC ; fully-qualified # 🛌🏼 E4.0 person in bed: medium-light skin tone
-1F6CC 1F3FD ; fully-qualified # 🛌🏽 E4.0 person in bed: medium skin tone
-1F6CC 1F3FE ; fully-qualified # 🛌🏾 E4.0 person in bed: medium-dark skin tone
-1F6CC 1F3FF ; fully-qualified # 🛌🏿 E4.0 person in bed: dark skin tone
+1F9D8 ; fully-qualified # 🧘 E5.0 person in lotus position
+1F9D8 1F3FB ; fully-qualified # 🧘🏻 E5.0 person in lotus position: light skin tone
+1F9D8 1F3FC ; fully-qualified # 🧘🏼 E5.0 person in lotus position: medium-light skin tone
+1F9D8 1F3FD ; fully-qualified # 🧘🏽 E5.0 person in lotus position: medium skin tone
+1F9D8 1F3FE ; fully-qualified # 🧘🏾 E5.0 person in lotus position: medium-dark skin tone
+1F9D8 1F3FF ; fully-qualified # 🧘🏿 E5.0 person in lotus position: dark skin tone
+1F9D8 200D 2642 FE0F ; fully-qualified # 🧘♂️ E5.0 man in lotus position
+1F9D8 200D 2642 ; minimally-qualified # 🧘♂ E5.0 man in lotus position
+1F9D8 1F3FB 200D 2642 FE0F ; fully-qualified # 🧘🏻♂️ E5.0 man in lotus position: light skin tone
+1F9D8 1F3FB 200D 2642 ; minimally-qualified # 🧘🏻♂ E5.0 man in lotus position: light skin tone
+1F9D8 1F3FC 200D 2642 FE0F ; fully-qualified # 🧘🏼♂️ E5.0 man in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2642 ; minimally-qualified # 🧘🏼♂ E5.0 man in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2642 FE0F ; fully-qualified # 🧘🏽♂️ E5.0 man in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2642 ; minimally-qualified # 🧘🏽♂ E5.0 man in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2642 FE0F ; fully-qualified # 🧘🏾♂️ E5.0 man in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2642 ; minimally-qualified # 🧘🏾♂ E5.0 man in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2642 FE0F ; fully-qualified # 🧘🏿♂️ E5.0 man in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2642 ; minimally-qualified # 🧘🏿♂ E5.0 man in lotus position: dark skin tone
+1F9D8 200D 2640 FE0F ; fully-qualified # 🧘♀️ E5.0 woman in lotus position
+1F9D8 200D 2640 ; minimally-qualified # 🧘♀ E5.0 woman in lotus position
+1F9D8 1F3FB 200D 2640 FE0F ; fully-qualified # 🧘🏻♀️ E5.0 woman in lotus position: light skin tone
+1F9D8 1F3FB 200D 2640 ; minimally-qualified # 🧘🏻♀ E5.0 woman in lotus position: light skin tone
+1F9D8 1F3FC 200D 2640 FE0F ; fully-qualified # 🧘🏼♀️ E5.0 woman in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2640 ; minimally-qualified # 🧘🏼♀ E5.0 woman in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2640 FE0F ; fully-qualified # 🧘🏽♀️ E5.0 woman in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2640 ; minimally-qualified # 🧘🏽♀ E5.0 woman in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2640 FE0F ; fully-qualified # 🧘🏾♀️ E5.0 woman in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2640 ; minimally-qualified # 🧘🏾♀ E5.0 woman in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2640 FE0F ; fully-qualified # 🧘🏿♀️ E5.0 woman in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2640 ; minimally-qualified # 🧘🏿♀ E5.0 woman in lotus position: dark skin tone
+1F6C0 ; fully-qualified # 🛀 E0.6 person taking bath
+1F6C0 1F3FB ; fully-qualified # 🛀🏻 E1.0 person taking bath: light skin tone
+1F6C0 1F3FC ; fully-qualified # 🛀🏼 E1.0 person taking bath: medium-light skin tone
+1F6C0 1F3FD ; fully-qualified # 🛀🏽 E1.0 person taking bath: medium skin tone
+1F6C0 1F3FE ; fully-qualified # 🛀🏾 E1.0 person taking bath: medium-dark skin tone
+1F6C0 1F3FF ; fully-qualified # 🛀🏿 E1.0 person taking bath: dark skin tone
+1F6CC ; fully-qualified # 🛌 E1.0 person in bed
+1F6CC 1F3FB ; fully-qualified # 🛌🏻 E4.0 person in bed: light skin tone
+1F6CC 1F3FC ; fully-qualified # 🛌🏼 E4.0 person in bed: medium-light skin tone
+1F6CC 1F3FD ; fully-qualified # 🛌🏽 E4.0 person in bed: medium skin tone
+1F6CC 1F3FE ; fully-qualified # 🛌🏾 E4.0 person in bed: medium-dark skin tone
+1F6CC 1F3FF ; fully-qualified # 🛌🏿 E4.0 person in bed: dark skin tone
# subgroup: family
-1F9D1 200D 1F91D 200D 1F9D1 ; fully-qualified # 🧑🤝🧑 E12.0 people holding hands
-1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏻🤝🧑🏻 E12.0 people holding hands: light skin tone
-1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻🤝🧑🏼 E12.1 people holding hands: light skin tone, medium-light skin tone
-1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻🤝🧑🏽 E12.1 people holding hands: light skin tone, medium skin tone
-1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻🤝🧑🏾 E12.1 people holding hands: light skin tone, medium-dark skin tone
-1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻🤝🧑🏿 E12.1 people holding hands: light skin tone, dark skin tone
-1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼🤝🧑🏻 E12.0 people holding hands: medium-light skin tone, light skin tone
-1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏼🤝🧑🏼 E12.0 people holding hands: medium-light skin tone
-1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼🤝🧑🏽 E12.1 people holding hands: medium-light skin tone, medium skin tone
-1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼🤝🧑🏾 E12.1 people holding hands: medium-light skin tone, medium-dark skin tone
-1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼🤝🧑🏿 E12.1 people holding hands: medium-light skin tone, dark skin tone
-1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽🤝🧑🏻 E12.0 people holding hands: medium skin tone, light skin tone
-1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽🤝🧑🏼 E12.0 people holding hands: medium skin tone, medium-light skin tone
-1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏽🤝🧑🏽 E12.0 people holding hands: medium skin tone
-1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽🤝🧑🏾 E12.1 people holding hands: medium skin tone, medium-dark skin tone
-1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽🤝🧑🏿 E12.1 people holding hands: medium skin tone, dark skin tone
-1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾🤝🧑🏻 E12.0 people holding hands: medium-dark skin tone, light skin tone
-1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾🤝🧑🏼 E12.0 people holding hands: medium-dark skin tone, medium-light skin tone
-1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾🤝🧑🏽 E12.0 people holding hands: medium-dark skin tone, medium skin tone
-1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏾🤝🧑🏾 E12.0 people holding hands: medium-dark skin tone
-1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾🤝🧑🏿 E12.1 people holding hands: medium-dark skin tone, dark skin tone
-1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿🤝🧑🏻 E12.0 people holding hands: dark skin tone, light skin tone
-1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿🤝🧑🏼 E12.0 people holding hands: dark skin tone, medium-light skin tone
-1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿🤝🧑🏽 E12.0 people holding hands: dark skin tone, medium skin tone
-1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿🤝🧑🏾 E12.0 people holding hands: dark skin tone, medium-dark skin tone
-1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏿🤝🧑🏿 E12.0 people holding hands: dark skin tone
-1F46D ; fully-qualified # 👭 E1.0 women holding hands
-1F46D 1F3FB ; fully-qualified # 👭🏻 E12.0 women holding hands: light skin tone
-1F469 1F3FB 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏻🤝👩🏼 E12.1 women holding hands: light skin tone, medium-light skin tone
-1F469 1F3FB 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏻🤝👩🏽 E12.1 women holding hands: light skin tone, medium skin tone
-1F469 1F3FB 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏻🤝👩🏾 E12.1 women holding hands: light skin tone, medium-dark skin tone
-1F469 1F3FB 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏻🤝👩🏿 E12.1 women holding hands: light skin tone, dark skin tone
-1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏼🤝👩🏻 E12.0 women holding hands: medium-light skin tone, light skin tone
-1F46D 1F3FC ; fully-qualified # 👭🏼 E12.0 women holding hands: medium-light skin tone
-1F469 1F3FC 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏼🤝👩🏽 E12.1 women holding hands: medium-light skin tone, medium skin tone
-1F469 1F3FC 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏼🤝👩🏾 E12.1 women holding hands: medium-light skin tone, medium-dark skin tone
-1F469 1F3FC 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏼🤝👩🏿 E12.1 women holding hands: medium-light skin tone, dark skin tone
-1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏽🤝👩🏻 E12.0 women holding hands: medium skin tone, light skin tone
-1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏽🤝👩🏼 E12.0 women holding hands: medium skin tone, medium-light skin tone
-1F46D 1F3FD ; fully-qualified # 👭🏽 E12.0 women holding hands: medium skin tone
-1F469 1F3FD 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏽🤝👩🏾 E12.1 women holding hands: medium skin tone, medium-dark skin tone
-1F469 1F3FD 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏽🤝👩🏿 E12.1 women holding hands: medium skin tone, dark skin tone
-1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏾🤝👩🏻 E12.0 women holding hands: medium-dark skin tone, light skin tone
-1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏾🤝👩🏼 E12.0 women holding hands: medium-dark skin tone, medium-light skin tone
-1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏾🤝👩🏽 E12.0 women holding hands: medium-dark skin tone, medium skin tone
-1F46D 1F3FE ; fully-qualified # 👭🏾 E12.0 women holding hands: medium-dark skin tone
-1F469 1F3FE 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏾🤝👩🏿 E12.1 women holding hands: medium-dark skin tone, dark skin tone
-1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏿🤝👩🏻 E12.0 women holding hands: dark skin tone, light skin tone
-1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏿🤝👩🏼 E12.0 women holding hands: dark skin tone, medium-light skin tone
-1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏿🤝👩🏽 E12.0 women holding hands: dark skin tone, medium skin tone
-1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏿🤝👩🏾 E12.0 women holding hands: dark skin tone, medium-dark skin tone
-1F46D 1F3FF ; fully-qualified # 👭🏿 E12.0 women holding hands: dark skin tone
-1F46B ; fully-qualified # 👫 E0.6 woman and man holding hands
-1F46B 1F3FB ; fully-qualified # 👫🏻 E12.0 woman and man holding hands: light skin tone
-1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏻🤝👨🏼 E12.0 woman and man holding hands: light skin tone, medium-light skin tone
-1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏻🤝👨🏽 E12.0 woman and man holding hands: light skin tone, medium skin tone
-1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏻🤝👨🏾 E12.0 woman and man holding hands: light skin tone, medium-dark skin tone
-1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏻🤝👨🏿 E12.0 woman and man holding hands: light skin tone, dark skin tone
-1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏼🤝👨🏻 E12.0 woman and man holding hands: medium-light skin tone, light skin tone
-1F46B 1F3FC ; fully-qualified # 👫🏼 E12.0 woman and man holding hands: medium-light skin tone
-1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏼🤝👨🏽 E12.0 woman and man holding hands: medium-light skin tone, medium skin tone
-1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏼🤝👨🏾 E12.0 woman and man holding hands: medium-light skin tone, medium-dark skin tone
-1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏼🤝👨🏿 E12.0 woman and man holding hands: medium-light skin tone, dark skin tone
-1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏽🤝👨🏻 E12.0 woman and man holding hands: medium skin tone, light skin tone
-1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏽🤝👨🏼 E12.0 woman and man holding hands: medium skin tone, medium-light skin tone
-1F46B 1F3FD ; fully-qualified # 👫🏽 E12.0 woman and man holding hands: medium skin tone
-1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏽🤝👨🏾 E12.0 woman and man holding hands: medium skin tone, medium-dark skin tone
-1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏽🤝👨🏿 E12.0 woman and man holding hands: medium skin tone, dark skin tone
-1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏾🤝👨🏻 E12.0 woman and man holding hands: medium-dark skin tone, light skin tone
-1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏾🤝👨🏼 E12.0 woman and man holding hands: medium-dark skin tone, medium-light skin tone
-1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏾🤝👨🏽 E12.0 woman and man holding hands: medium-dark skin tone, medium skin tone
-1F46B 1F3FE ; fully-qualified # 👫🏾 E12.0 woman and man holding hands: medium-dark skin tone
-1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏾🤝👨🏿 E12.0 woman and man holding hands: medium-dark skin tone, dark skin tone
-1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏿🤝👨🏻 E12.0 woman and man holding hands: dark skin tone, light skin tone
-1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏿🤝👨🏼 E12.0 woman and man holding hands: dark skin tone, medium-light skin tone
-1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏿🤝👨🏽 E12.0 woman and man holding hands: dark skin tone, medium skin tone
-1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏿🤝👨🏾 E12.0 woman and man holding hands: dark skin tone, medium-dark skin tone
-1F46B 1F3FF ; fully-qualified # 👫🏿 E12.0 woman and man holding hands: dark skin tone
-1F46C ; fully-qualified # 👬 E1.0 men holding hands
-1F46C 1F3FB ; fully-qualified # 👬🏻 E12.0 men holding hands: light skin tone
-1F468 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏻🤝👨🏼 E12.1 men holding hands: light skin tone, medium-light skin tone
-1F468 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏻🤝👨🏽 E12.1 men holding hands: light skin tone, medium skin tone
-1F468 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏻🤝👨🏾 E12.1 men holding hands: light skin tone, medium-dark skin tone
-1F468 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏻🤝👨🏿 E12.1 men holding hands: light skin tone, dark skin tone
-1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏼🤝👨🏻 E12.0 men holding hands: medium-light skin tone, light skin tone
-1F46C 1F3FC ; fully-qualified # 👬🏼 E12.0 men holding hands: medium-light skin tone
-1F468 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏼🤝👨🏽 E12.1 men holding hands: medium-light skin tone, medium skin tone
-1F468 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏼🤝👨🏾 E12.1 men holding hands: medium-light skin tone, medium-dark skin tone
-1F468 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏼🤝👨🏿 E12.1 men holding hands: medium-light skin tone, dark skin tone
-1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏽🤝👨🏻 E12.0 men holding hands: medium skin tone, light skin tone
-1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏽🤝👨🏼 E12.0 men holding hands: medium skin tone, medium-light skin tone
-1F46C 1F3FD ; fully-qualified # 👬🏽 E12.0 men holding hands: medium skin tone
-1F468 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏽🤝👨🏾 E12.1 men holding hands: medium skin tone, medium-dark skin tone
-1F468 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏽🤝👨🏿 E12.1 men holding hands: medium skin tone, dark skin tone
-1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏾🤝👨🏻 E12.0 men holding hands: medium-dark skin tone, light skin tone
-1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏾🤝👨🏼 E12.0 men holding hands: medium-dark skin tone, medium-light skin tone
-1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏾🤝👨🏽 E12.0 men holding hands: medium-dark skin tone, medium skin tone
-1F46C 1F3FE ; fully-qualified # 👬🏾 E12.0 men holding hands: medium-dark skin tone
-1F468 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏾🤝👨🏿 E12.1 men holding hands: medium-dark skin tone, dark skin tone
-1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏿🤝👨🏻 E12.0 men holding hands: dark skin tone, light skin tone
-1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏿🤝👨🏼 E12.0 men holding hands: dark skin tone, medium-light skin tone
-1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏿🤝👨🏽 E12.0 men holding hands: dark skin tone, medium skin tone
-1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏿🤝👨🏾 E12.0 men holding hands: dark skin tone, medium-dark skin tone
-1F46C 1F3FF ; fully-qualified # 👬🏿 E12.0 men holding hands: dark skin tone
-1F48F ; fully-qualified # 💏 E0.6 kiss
-1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👩❤️💋👨 E2.0 kiss: woman, man
-1F469 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👩❤💋👨 E2.0 kiss: woman, man
-1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👨❤️💋👨 E2.0 kiss: man, man
-1F468 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👨❤💋👨 E2.0 kiss: man, man
-1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; fully-qualified # 👩❤️💋👩 E2.0 kiss: woman, woman
-1F469 200D 2764 200D 1F48B 200D 1F469 ; minimally-qualified # 👩❤💋👩 E2.0 kiss: woman, woman
-1F491 ; fully-qualified # 💑 E0.6 couple with heart
-1F469 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👩❤️👨 E2.0 couple with heart: woman, man
-1F469 200D 2764 200D 1F468 ; minimally-qualified # 👩❤👨 E2.0 couple with heart: woman, man
-1F468 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👨❤️👨 E2.0 couple with heart: man, man
-1F468 200D 2764 200D 1F468 ; minimally-qualified # 👨❤👨 E2.0 couple with heart: man, man
-1F469 200D 2764 FE0F 200D 1F469 ; fully-qualified # 👩❤️👩 E2.0 couple with heart: woman, woman
-1F469 200D 2764 200D 1F469 ; minimally-qualified # 👩❤👩 E2.0 couple with heart: woman, woman
-1F46A ; fully-qualified # 👪 E0.6 family
-1F468 200D 1F469 200D 1F466 ; fully-qualified # 👨👩👦 E2.0 family: man, woman, boy
-1F468 200D 1F469 200D 1F467 ; fully-qualified # 👨👩👧 E2.0 family: man, woman, girl
-1F468 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👨👩👧👦 E2.0 family: man, woman, girl, boy
-1F468 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👨👩👦👦 E2.0 family: man, woman, boy, boy
-1F468 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👨👩👧👧 E2.0 family: man, woman, girl, girl
-1F468 200D 1F468 200D 1F466 ; fully-qualified # 👨👨👦 E2.0 family: man, man, boy
-1F468 200D 1F468 200D 1F467 ; fully-qualified # 👨👨👧 E2.0 family: man, man, girl
-1F468 200D 1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨👨👧👦 E2.0 family: man, man, girl, boy
-1F468 200D 1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨👨👦👦 E2.0 family: man, man, boy, boy
-1F468 200D 1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨👨👧👧 E2.0 family: man, man, girl, girl
-1F469 200D 1F469 200D 1F466 ; fully-qualified # 👩👩👦 E2.0 family: woman, woman, boy
-1F469 200D 1F469 200D 1F467 ; fully-qualified # 👩👩👧 E2.0 family: woman, woman, girl
-1F469 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩👩👧👦 E2.0 family: woman, woman, girl, boy
-1F469 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩👩👦👦 E2.0 family: woman, woman, boy, boy
-1F469 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩👩👧👧 E2.0 family: woman, woman, girl, girl
-1F468 200D 1F466 ; fully-qualified # 👨👦 E4.0 family: man, boy
-1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨👦👦 E4.0 family: man, boy, boy
-1F468 200D 1F467 ; fully-qualified # 👨👧 E4.0 family: man, girl
-1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨👧👦 E4.0 family: man, girl, boy
-1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨👧👧 E4.0 family: man, girl, girl
-1F469 200D 1F466 ; fully-qualified # 👩👦 E4.0 family: woman, boy
-1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩👦👦 E4.0 family: woman, boy, boy
-1F469 200D 1F467 ; fully-qualified # 👩👧 E4.0 family: woman, girl
-1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩👧👦 E4.0 family: woman, girl, boy
-1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩👧👧 E4.0 family: woman, girl, girl
+1F9D1 200D 1F91D 200D 1F9D1 ; fully-qualified # 🧑🤝🧑 E12.0 people holding hands
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏻🤝🧑🏻 E12.0 people holding hands: light skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻🤝🧑🏼 E12.1 people holding hands: light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻🤝🧑🏽 E12.1 people holding hands: light skin tone, medium skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻🤝🧑🏾 E12.1 people holding hands: light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻🤝🧑🏿 E12.1 people holding hands: light skin tone, dark skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼🤝🧑🏻 E12.0 people holding hands: medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏼🤝🧑🏼 E12.0 people holding hands: medium-light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼🤝🧑🏽 E12.1 people holding hands: medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼🤝🧑🏾 E12.1 people holding hands: medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼🤝🧑🏿 E12.1 people holding hands: medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽🤝🧑🏻 E12.0 people holding hands: medium skin tone, light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽🤝🧑🏼 E12.0 people holding hands: medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏽🤝🧑🏽 E12.0 people holding hands: medium skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽🤝🧑🏾 E12.1 people holding hands: medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽🤝🧑🏿 E12.1 people holding hands: medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾🤝🧑🏻 E12.0 people holding hands: medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾🤝🧑🏼 E12.0 people holding hands: medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾🤝🧑🏽 E12.0 people holding hands: medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏾🤝🧑🏾 E12.0 people holding hands: medium-dark skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾🤝🧑🏿 E12.1 people holding hands: medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿🤝🧑🏻 E12.0 people holding hands: dark skin tone, light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿🤝🧑🏼 E12.0 people holding hands: dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿🤝🧑🏽 E12.0 people holding hands: dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿🤝🧑🏾 E12.0 people holding hands: dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏿🤝🧑🏿 E12.0 people holding hands: dark skin tone
+1F46D ; fully-qualified # 👭 E1.0 women holding hands
+1F46D 1F3FB ; fully-qualified # 👭🏻 E12.0 women holding hands: light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏻🤝👩🏼 E12.1 women holding hands: light skin tone, medium-light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏻🤝👩🏽 E12.1 women holding hands: light skin tone, medium skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏻🤝👩🏾 E12.1 women holding hands: light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏻🤝👩🏿 E12.1 women holding hands: light skin tone, dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏼🤝👩🏻 E12.0 women holding hands: medium-light skin tone, light skin tone
+1F46D 1F3FC ; fully-qualified # 👭🏼 E12.0 women holding hands: medium-light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏼🤝👩🏽 E12.1 women holding hands: medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏼🤝👩🏾 E12.1 women holding hands: medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏼🤝👩🏿 E12.1 women holding hands: medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏽🤝👩🏻 E12.0 women holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏽🤝👩🏼 E12.0 women holding hands: medium skin tone, medium-light skin tone
+1F46D 1F3FD ; fully-qualified # 👭🏽 E12.0 women holding hands: medium skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏽🤝👩🏾 E12.1 women holding hands: medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏽🤝👩🏿 E12.1 women holding hands: medium skin tone, dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏾🤝👩🏻 E12.0 women holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏾🤝👩🏼 E12.0 women holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏾🤝👩🏽 E12.0 women holding hands: medium-dark skin tone, medium skin tone
+1F46D 1F3FE ; fully-qualified # 👭🏾 E12.0 women holding hands: medium-dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FF ; fully-qualified # 👩🏾🤝👩🏿 E12.1 women holding hands: medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB ; fully-qualified # 👩🏿🤝👩🏻 E12.0 women holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC ; fully-qualified # 👩🏿🤝👩🏼 E12.0 women holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD ; fully-qualified # 👩🏿🤝👩🏽 E12.0 women holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE ; fully-qualified # 👩🏿🤝👩🏾 E12.0 women holding hands: dark skin tone, medium-dark skin tone
+1F46D 1F3FF ; fully-qualified # 👭🏿 E12.0 women holding hands: dark skin tone
+1F46B ; fully-qualified # 👫 E0.6 woman and man holding hands
+1F46B 1F3FB ; fully-qualified # 👫🏻 E12.0 woman and man holding hands: light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏻🤝👨🏼 E12.0 woman and man holding hands: light skin tone, medium-light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏻🤝👨🏽 E12.0 woman and man holding hands: light skin tone, medium skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏻🤝👨🏾 E12.0 woman and man holding hands: light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏻🤝👨🏿 E12.0 woman and man holding hands: light skin tone, dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏼🤝👨🏻 E12.0 woman and man holding hands: medium-light skin tone, light skin tone
+1F46B 1F3FC ; fully-qualified # 👫🏼 E12.0 woman and man holding hands: medium-light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏼🤝👨🏽 E12.0 woman and man holding hands: medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏼🤝👨🏾 E12.0 woman and man holding hands: medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏼🤝👨🏿 E12.0 woman and man holding hands: medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏽🤝👨🏻 E12.0 woman and man holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏽🤝👨🏼 E12.0 woman and man holding hands: medium skin tone, medium-light skin tone
+1F46B 1F3FD ; fully-qualified # 👫🏽 E12.0 woman and man holding hands: medium skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏽🤝👨🏾 E12.0 woman and man holding hands: medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏽🤝👨🏿 E12.0 woman and man holding hands: medium skin tone, dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏾🤝👨🏻 E12.0 woman and man holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏾🤝👨🏼 E12.0 woman and man holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏾🤝👨🏽 E12.0 woman and man holding hands: medium-dark skin tone, medium skin tone
+1F46B 1F3FE ; fully-qualified # 👫🏾 E12.0 woman and man holding hands: medium-dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👩🏾🤝👨🏿 E12.0 woman and man holding hands: medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👩🏿🤝👨🏻 E12.0 woman and man holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👩🏿🤝👨🏼 E12.0 woman and man holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👩🏿🤝👨🏽 E12.0 woman and man holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👩🏿🤝👨🏾 E12.0 woman and man holding hands: dark skin tone, medium-dark skin tone
+1F46B 1F3FF ; fully-qualified # 👫🏿 E12.0 woman and man holding hands: dark skin tone
+1F46C ; fully-qualified # 👬 E1.0 men holding hands
+1F46C 1F3FB ; fully-qualified # 👬🏻 E12.0 men holding hands: light skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏻🤝👨🏼 E12.1 men holding hands: light skin tone, medium-light skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏻🤝👨🏽 E12.1 men holding hands: light skin tone, medium skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏻🤝👨🏾 E12.1 men holding hands: light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏻🤝👨🏿 E12.1 men holding hands: light skin tone, dark skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏼🤝👨🏻 E12.0 men holding hands: medium-light skin tone, light skin tone
+1F46C 1F3FC ; fully-qualified # 👬🏼 E12.0 men holding hands: medium-light skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏼🤝👨🏽 E12.1 men holding hands: medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏼🤝👨🏾 E12.1 men holding hands: medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏼🤝👨🏿 E12.1 men holding hands: medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏽🤝👨🏻 E12.0 men holding hands: medium skin tone, light skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏽🤝👨🏼 E12.0 men holding hands: medium skin tone, medium-light skin tone
+1F46C 1F3FD ; fully-qualified # 👬🏽 E12.0 men holding hands: medium skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏽🤝👨🏾 E12.1 men holding hands: medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏽🤝👨🏿 E12.1 men holding hands: medium skin tone, dark skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏾🤝👨🏻 E12.0 men holding hands: medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏾🤝👨🏼 E12.0 men holding hands: medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏾🤝👨🏽 E12.0 men holding hands: medium-dark skin tone, medium skin tone
+1F46C 1F3FE ; fully-qualified # 👬🏾 E12.0 men holding hands: medium-dark skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FF ; fully-qualified # 👨🏾🤝👨🏿 E12.1 men holding hands: medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB ; fully-qualified # 👨🏿🤝👨🏻 E12.0 men holding hands: dark skin tone, light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC ; fully-qualified # 👨🏿🤝👨🏼 E12.0 men holding hands: dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD ; fully-qualified # 👨🏿🤝👨🏽 E12.0 men holding hands: dark skin tone, medium skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE ; fully-qualified # 👨🏿🤝👨🏾 E12.0 men holding hands: dark skin tone, medium-dark skin tone
+1F46C 1F3FF ; fully-qualified # 👬🏿 E12.0 men holding hands: dark skin tone
+1F48F ; fully-qualified # 💏 E0.6 kiss
+1F48F 1F3FB ; fully-qualified # 💏🏻 E13.1 kiss: light skin tone
+1F48F 1F3FC ; fully-qualified # 💏🏼 E13.1 kiss: medium-light skin tone
+1F48F 1F3FD ; fully-qualified # 💏🏽 E13.1 kiss: medium skin tone
+1F48F 1F3FE ; fully-qualified # 💏🏾 E13.1 kiss: medium-dark skin tone
+1F48F 1F3FF ; fully-qualified # 💏🏿 E13.1 kiss: dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻❤️💋🧑🏼 E13.1 kiss: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏻❤💋🧑🏼 E13.1 kiss: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻❤️💋🧑🏽 E13.1 kiss: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏻❤💋🧑🏽 E13.1 kiss: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻❤️💋🧑🏾 E13.1 kiss: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏻❤💋🧑🏾 E13.1 kiss: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻❤️💋🧑🏿 E13.1 kiss: person, person, light skin tone, dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏻❤💋🧑🏿 E13.1 kiss: person, person, light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼❤️💋🧑🏻 E13.1 kiss: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏼❤💋🧑🏻 E13.1 kiss: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼❤️💋🧑🏽 E13.1 kiss: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏼❤💋🧑🏽 E13.1 kiss: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼❤️💋🧑🏾 E13.1 kiss: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏼❤💋🧑🏾 E13.1 kiss: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼❤️💋🧑🏿 E13.1 kiss: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏼❤💋🧑🏿 E13.1 kiss: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽❤️💋🧑🏻 E13.1 kiss: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏽❤💋🧑🏻 E13.1 kiss: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽❤️💋🧑🏼 E13.1 kiss: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏽❤💋🧑🏼 E13.1 kiss: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽❤️💋🧑🏾 E13.1 kiss: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏽❤💋🧑🏾 E13.1 kiss: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽❤️💋🧑🏿 E13.1 kiss: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏽❤💋🧑🏿 E13.1 kiss: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾❤️💋🧑🏻 E13.1 kiss: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏾❤💋🧑🏻 E13.1 kiss: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾❤️💋🧑🏼 E13.1 kiss: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏾❤💋🧑🏼 E13.1 kiss: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾❤️💋🧑🏽 E13.1 kiss: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏾❤💋🧑🏽 E13.1 kiss: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾❤️💋🧑🏿 E13.1 kiss: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 200D 1F48B 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏾❤💋🧑🏿 E13.1 kiss: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿❤️💋🧑🏻 E13.1 kiss: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏿❤💋🧑🏻 E13.1 kiss: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿❤️💋🧑🏼 E13.1 kiss: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏿❤💋🧑🏼 E13.1 kiss: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿❤️💋🧑🏽 E13.1 kiss: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏿❤💋🧑🏽 E13.1 kiss: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿❤️💋🧑🏾 E13.1 kiss: person, person, dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 2764 200D 1F48B 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏿❤💋🧑🏾 E13.1 kiss: person, person, dark skin tone, medium-dark skin tone
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👩❤️💋👨 E2.0 kiss: woman, man
+1F469 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👩❤💋👨 E2.0 kiss: woman, man
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏻❤️💋👨🏻 E13.1 kiss: woman, man, light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏻❤💋👨🏻 E13.1 kiss: woman, man, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏻❤️💋👨🏼 E13.1 kiss: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏻❤💋👨🏼 E13.1 kiss: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏻❤️💋👨🏽 E13.1 kiss: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏻❤💋👨🏽 E13.1 kiss: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏻❤️💋👨🏾 E13.1 kiss: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏻❤💋👨🏾 E13.1 kiss: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏻❤️💋👨🏿 E13.1 kiss: woman, man, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏻❤💋👨🏿 E13.1 kiss: woman, man, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏼❤️💋👨🏻 E13.1 kiss: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏼❤💋👨🏻 E13.1 kiss: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏼❤️💋👨🏼 E13.1 kiss: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏼❤💋👨🏼 E13.1 kiss: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏼❤️💋👨🏽 E13.1 kiss: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏼❤💋👨🏽 E13.1 kiss: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏼❤️💋👨🏾 E13.1 kiss: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏼❤💋👨🏾 E13.1 kiss: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏼❤️💋👨🏿 E13.1 kiss: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏼❤💋👨🏿 E13.1 kiss: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏽❤️💋👨🏻 E13.1 kiss: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏽❤💋👨🏻 E13.1 kiss: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏽❤️💋👨🏼 E13.1 kiss: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏽❤💋👨🏼 E13.1 kiss: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏽❤️💋👨🏽 E13.1 kiss: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏽❤💋👨🏽 E13.1 kiss: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏽❤️💋👨🏾 E13.1 kiss: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏽❤💋👨🏾 E13.1 kiss: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏽❤️💋👨🏿 E13.1 kiss: woman, man, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏽❤💋👨🏿 E13.1 kiss: woman, man, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏾❤️💋👨🏻 E13.1 kiss: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏾❤💋👨🏻 E13.1 kiss: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏾❤️💋👨🏼 E13.1 kiss: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏾❤💋👨🏼 E13.1 kiss: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏾❤️💋👨🏽 E13.1 kiss: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏾❤💋👨🏽 E13.1 kiss: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏾❤️💋👨🏾 E13.1 kiss: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏾❤💋👨🏾 E13.1 kiss: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏾❤️💋👨🏿 E13.1 kiss: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏾❤💋👨🏿 E13.1 kiss: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👩🏿❤️💋👨🏻 E13.1 kiss: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👩🏿❤💋👨🏻 E13.1 kiss: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👩🏿❤️💋👨🏼 E13.1 kiss: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👩🏿❤💋👨🏼 E13.1 kiss: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👩🏿❤️💋👨🏽 E13.1 kiss: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👩🏿❤💋👨🏽 E13.1 kiss: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👩🏿❤️💋👨🏾 E13.1 kiss: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👩🏿❤💋👨🏾 E13.1 kiss: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👩🏿❤️💋👨🏿 E13.1 kiss: woman, man, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👩🏿❤💋👨🏿 E13.1 kiss: woman, man, dark skin tone
+1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👨❤️💋👨 E2.0 kiss: man, man
+1F468 200D 2764 200D 1F48B 200D 1F468 ; minimally-qualified # 👨❤💋👨 E2.0 kiss: man, man
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏻❤️💋👨🏻 E13.1 kiss: man, man, light skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏻❤💋👨🏻 E13.1 kiss: man, man, light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏻❤️💋👨🏼 E13.1 kiss: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏻❤💋👨🏼 E13.1 kiss: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏻❤️💋👨🏽 E13.1 kiss: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏻❤💋👨🏽 E13.1 kiss: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏻❤️💋👨🏾 E13.1 kiss: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏻❤💋👨🏾 E13.1 kiss: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏻❤️💋👨🏿 E13.1 kiss: man, man, light skin tone, dark skin tone
+1F468 1F3FB 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏻❤💋👨🏿 E13.1 kiss: man, man, light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏼❤️💋👨🏻 E13.1 kiss: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏼❤💋👨🏻 E13.1 kiss: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏼❤️💋👨🏼 E13.1 kiss: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏼❤💋👨🏼 E13.1 kiss: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏼❤️💋👨🏽 E13.1 kiss: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏼❤💋👨🏽 E13.1 kiss: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏼❤️💋👨🏾 E13.1 kiss: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏼❤💋👨🏾 E13.1 kiss: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏼❤️💋👨🏿 E13.1 kiss: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏼❤💋👨🏿 E13.1 kiss: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏽❤️💋👨🏻 E13.1 kiss: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏽❤💋👨🏻 E13.1 kiss: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏽❤️💋👨🏼 E13.1 kiss: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏽❤💋👨🏼 E13.1 kiss: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏽❤️💋👨🏽 E13.1 kiss: man, man, medium skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏽❤💋👨🏽 E13.1 kiss: man, man, medium skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏽❤️💋👨🏾 E13.1 kiss: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏽❤💋👨🏾 E13.1 kiss: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏽❤️💋👨🏿 E13.1 kiss: man, man, medium skin tone, dark skin tone
+1F468 1F3FD 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏽❤💋👨🏿 E13.1 kiss: man, man, medium skin tone, dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏾❤️💋👨🏻 E13.1 kiss: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏾❤💋👨🏻 E13.1 kiss: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏾❤️💋👨🏼 E13.1 kiss: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏾❤💋👨🏼 E13.1 kiss: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏾❤️💋👨🏽 E13.1 kiss: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏾❤💋👨🏽 E13.1 kiss: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏾❤️💋👨🏾 E13.1 kiss: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏾❤💋👨🏾 E13.1 kiss: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏾❤️💋👨🏿 E13.1 kiss: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FE 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏾❤💋👨🏿 E13.1 kiss: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FB ; fully-qualified # 👨🏿❤️💋👨🏻 E13.1 kiss: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FB ; minimally-qualified # 👨🏿❤💋👨🏻 E13.1 kiss: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FC ; fully-qualified # 👨🏿❤️💋👨🏼 E13.1 kiss: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FC ; minimally-qualified # 👨🏿❤💋👨🏼 E13.1 kiss: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FD ; fully-qualified # 👨🏿❤️💋👨🏽 E13.1 kiss: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FD ; minimally-qualified # 👨🏿❤💋👨🏽 E13.1 kiss: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FE ; fully-qualified # 👨🏿❤️💋👨🏾 E13.1 kiss: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FE ; minimally-qualified # 👨🏿❤💋👨🏾 E13.1 kiss: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F468 1F3FF ; fully-qualified # 👨🏿❤️💋👨🏿 E13.1 kiss: man, man, dark skin tone
+1F468 1F3FF 200D 2764 200D 1F48B 200D 1F468 1F3FF ; minimally-qualified # 👨🏿❤💋👨🏿 E13.1 kiss: man, man, dark skin tone
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; fully-qualified # 👩❤️💋👩 E2.0 kiss: woman, woman
+1F469 200D 2764 200D 1F48B 200D 1F469 ; minimally-qualified # 👩❤💋👩 E2.0 kiss: woman, woman
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏻❤️💋👩🏻 E13.1 kiss: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏻❤💋👩🏻 E13.1 kiss: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏻❤️💋👩🏼 E13.1 kiss: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏻❤💋👩🏼 E13.1 kiss: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏻❤️💋👩🏽 E13.1 kiss: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏻❤💋👩🏽 E13.1 kiss: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏻❤️💋👩🏾 E13.1 kiss: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏻❤💋👩🏾 E13.1 kiss: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏻❤️💋👩🏿 E13.1 kiss: woman, woman, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏻❤💋👩🏿 E13.1 kiss: woman, woman, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏼❤️💋👩🏻 E13.1 kiss: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏼❤💋👩🏻 E13.1 kiss: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏼❤️💋👩🏼 E13.1 kiss: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏼❤💋👩🏼 E13.1 kiss: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏼❤️💋👩🏽 E13.1 kiss: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏼❤💋👩🏽 E13.1 kiss: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏼❤️💋👩🏾 E13.1 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏼❤💋👩🏾 E13.1 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏼❤️💋👩🏿 E13.1 kiss: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏼❤💋👩🏿 E13.1 kiss: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏽❤️💋👩🏻 E13.1 kiss: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏽❤💋👩🏻 E13.1 kiss: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏽❤️💋👩🏼 E13.1 kiss: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏽❤💋👩🏼 E13.1 kiss: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏽❤️💋👩🏽 E13.1 kiss: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏽❤💋👩🏽 E13.1 kiss: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏽❤️💋👩🏾 E13.1 kiss: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏽❤💋👩🏾 E13.1 kiss: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏽❤️💋👩🏿 E13.1 kiss: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏽❤💋👩🏿 E13.1 kiss: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏾❤️💋👩🏻 E13.1 kiss: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏾❤💋👩🏻 E13.1 kiss: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏾❤️💋👩🏼 E13.1 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏾❤💋👩🏼 E13.1 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏾❤️💋👩🏽 E13.1 kiss: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏾❤💋👩🏽 E13.1 kiss: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏾❤️💋👩🏾 E13.1 kiss: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏾❤💋👩🏾 E13.1 kiss: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏾❤️💋👩🏿 E13.1 kiss: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏾❤💋👩🏿 E13.1 kiss: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FB ; fully-qualified # 👩🏿❤️💋👩🏻 E13.1 kiss: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FB ; minimally-qualified # 👩🏿❤💋👩🏻 E13.1 kiss: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FC ; fully-qualified # 👩🏿❤️💋👩🏼 E13.1 kiss: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FC ; minimally-qualified # 👩🏿❤💋👩🏼 E13.1 kiss: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FD ; fully-qualified # 👩🏿❤️💋👩🏽 E13.1 kiss: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FD ; minimally-qualified # 👩🏿❤💋👩🏽 E13.1 kiss: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FE ; fully-qualified # 👩🏿❤️💋👩🏾 E13.1 kiss: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FE ; minimally-qualified # 👩🏿❤💋👩🏾 E13.1 kiss: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F48B 200D 1F469 1F3FF ; fully-qualified # 👩🏿❤️💋👩🏿 E13.1 kiss: woman, woman, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F48B 200D 1F469 1F3FF ; minimally-qualified # 👩🏿❤💋👩🏿 E13.1 kiss: woman, woman, dark skin tone
+1F491 ; fully-qualified # 💑 E0.6 couple with heart
+1F491 1F3FB ; fully-qualified # 💑🏻 E13.1 couple with heart: light skin tone
+1F491 1F3FC ; fully-qualified # 💑🏼 E13.1 couple with heart: medium-light skin tone
+1F491 1F3FD ; fully-qualified # 💑🏽 E13.1 couple with heart: medium skin tone
+1F491 1F3FE ; fully-qualified # 💑🏾 E13.1 couple with heart: medium-dark skin tone
+1F491 1F3FF ; fully-qualified # 💑🏿 E13.1 couple with heart: dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏻❤️🧑🏼 E13.1 couple with heart: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏻❤🧑🏼 E13.1 couple with heart: person, person, light skin tone, medium-light skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏻❤️🧑🏽 E13.1 couple with heart: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏻❤🧑🏽 E13.1 couple with heart: person, person, light skin tone, medium skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏻❤️🧑🏾 E13.1 couple with heart: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏻❤🧑🏾 E13.1 couple with heart: person, person, light skin tone, medium-dark skin tone
+1F9D1 1F3FB 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏻❤️🧑🏿 E13.1 couple with heart: person, person, light skin tone, dark skin tone
+1F9D1 1F3FB 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏻❤🧑🏿 E13.1 couple with heart: person, person, light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏼❤️🧑🏻 E13.1 couple with heart: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏼❤🧑🏻 E13.1 couple with heart: person, person, medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏼❤️🧑🏽 E13.1 couple with heart: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏼❤🧑🏽 E13.1 couple with heart: person, person, medium-light skin tone, medium skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏼❤️🧑🏾 E13.1 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏼❤🧑🏾 E13.1 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
+1F9D1 1F3FC 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏼❤️🧑🏿 E13.1 couple with heart: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FC 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏼❤🧑🏿 E13.1 couple with heart: person, person, medium-light skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏽❤️🧑🏻 E13.1 couple with heart: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏽❤🧑🏻 E13.1 couple with heart: person, person, medium skin tone, light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏽❤️🧑🏼 E13.1 couple with heart: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏽❤🧑🏼 E13.1 couple with heart: person, person, medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏽❤️🧑🏾 E13.1 couple with heart: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏽❤🧑🏾 E13.1 couple with heart: person, person, medium skin tone, medium-dark skin tone
+1F9D1 1F3FD 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏽❤️🧑🏿 E13.1 couple with heart: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FD 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏽❤🧑🏿 E13.1 couple with heart: person, person, medium skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏾❤️🧑🏻 E13.1 couple with heart: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏾❤🧑🏻 E13.1 couple with heart: person, person, medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏾❤️🧑🏼 E13.1 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏾❤🧑🏼 E13.1 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏾❤️🧑🏽 E13.1 couple with heart: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏾❤🧑🏽 E13.1 couple with heart: person, person, medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 2764 FE0F 200D 1F9D1 1F3FF ; fully-qualified # 🧑🏾❤️🧑🏿 E13.1 couple with heart: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FE 200D 2764 200D 1F9D1 1F3FF ; minimally-qualified # 🧑🏾❤🧑🏿 E13.1 couple with heart: person, person, medium-dark skin tone, dark skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FB ; fully-qualified # 🧑🏿❤️🧑🏻 E13.1 couple with heart: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FB ; minimally-qualified # 🧑🏿❤🧑🏻 E13.1 couple with heart: person, person, dark skin tone, light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FC ; fully-qualified # 🧑🏿❤️🧑🏼 E13.1 couple with heart: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FC ; minimally-qualified # 🧑🏿❤🧑🏼 E13.1 couple with heart: person, person, dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FD ; fully-qualified # 🧑🏿❤️🧑🏽 E13.1 couple with heart: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FD ; minimally-qualified # 🧑🏿❤🧑🏽 E13.1 couple with heart: person, person, dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 2764 FE0F 200D 1F9D1 1F3FE ; fully-qualified # 🧑🏿❤️🧑🏾 E13.1 couple with heart: person, person, dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 2764 200D 1F9D1 1F3FE ; minimally-qualified # 🧑🏿❤🧑🏾 E13.1 couple with heart: person, person, dark skin tone, medium-dark skin tone
+1F469 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👩❤️👨 E2.0 couple with heart: woman, man
+1F469 200D 2764 200D 1F468 ; minimally-qualified # 👩❤👨 E2.0 couple with heart: woman, man
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏻❤️👨🏻 E13.1 couple with heart: woman, man, light skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏻❤👨🏻 E13.1 couple with heart: woman, man, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏻❤️👨🏼 E13.1 couple with heart: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏻❤👨🏼 E13.1 couple with heart: woman, man, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏻❤️👨🏽 E13.1 couple with heart: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏻❤👨🏽 E13.1 couple with heart: woman, man, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏻❤️👨🏾 E13.1 couple with heart: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏻❤👨🏾 E13.1 couple with heart: woman, man, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏻❤️👨🏿 E13.1 couple with heart: woman, man, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏻❤👨🏿 E13.1 couple with heart: woman, man, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏼❤️👨🏻 E13.1 couple with heart: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏼❤👨🏻 E13.1 couple with heart: woman, man, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏼❤️👨🏼 E13.1 couple with heart: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏼❤👨🏼 E13.1 couple with heart: woman, man, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏼❤️👨🏽 E13.1 couple with heart: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏼❤👨🏽 E13.1 couple with heart: woman, man, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏼❤️👨🏾 E13.1 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏼❤👨🏾 E13.1 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏼❤️👨🏿 E13.1 couple with heart: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏼❤👨🏿 E13.1 couple with heart: woman, man, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏽❤️👨🏻 E13.1 couple with heart: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏽❤👨🏻 E13.1 couple with heart: woman, man, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏽❤️👨🏼 E13.1 couple with heart: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏽❤👨🏼 E13.1 couple with heart: woman, man, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏽❤️👨🏽 E13.1 couple with heart: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏽❤👨🏽 E13.1 couple with heart: woman, man, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏽❤️👨🏾 E13.1 couple with heart: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏽❤👨🏾 E13.1 couple with heart: woman, man, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏽❤️👨🏿 E13.1 couple with heart: woman, man, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏽❤👨🏿 E13.1 couple with heart: woman, man, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏾❤️👨🏻 E13.1 couple with heart: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏾❤👨🏻 E13.1 couple with heart: woman, man, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏾❤️👨🏼 E13.1 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏾❤👨🏼 E13.1 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏾❤️👨🏽 E13.1 couple with heart: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏾❤👨🏽 E13.1 couple with heart: woman, man, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏾❤️👨🏾 E13.1 couple with heart: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏾❤👨🏾 E13.1 couple with heart: woman, man, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏾❤️👨🏿 E13.1 couple with heart: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏾❤👨🏿 E13.1 couple with heart: woman, man, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👩🏿❤️👨🏻 E13.1 couple with heart: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👩🏿❤👨🏻 E13.1 couple with heart: woman, man, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👩🏿❤️👨🏼 E13.1 couple with heart: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👩🏿❤👨🏼 E13.1 couple with heart: woman, man, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👩🏿❤️👨🏽 E13.1 couple with heart: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👩🏿❤👨🏽 E13.1 couple with heart: woman, man, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👩🏿❤️👨🏾 E13.1 couple with heart: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👩🏿❤👨🏾 E13.1 couple with heart: woman, man, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👩🏿❤️👨🏿 E13.1 couple with heart: woman, man, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👩🏿❤👨🏿 E13.1 couple with heart: woman, man, dark skin tone
+1F468 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👨❤️👨 E2.0 couple with heart: man, man
+1F468 200D 2764 200D 1F468 ; minimally-qualified # 👨❤👨 E2.0 couple with heart: man, man
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏻❤️👨🏻 E13.1 couple with heart: man, man, light skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏻❤👨🏻 E13.1 couple with heart: man, man, light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏻❤️👨🏼 E13.1 couple with heart: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏻❤👨🏼 E13.1 couple with heart: man, man, light skin tone, medium-light skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏻❤️👨🏽 E13.1 couple with heart: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏻❤👨🏽 E13.1 couple with heart: man, man, light skin tone, medium skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏻❤️👨🏾 E13.1 couple with heart: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏻❤👨🏾 E13.1 couple with heart: man, man, light skin tone, medium-dark skin tone
+1F468 1F3FB 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏻❤️👨🏿 E13.1 couple with heart: man, man, light skin tone, dark skin tone
+1F468 1F3FB 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏻❤👨🏿 E13.1 couple with heart: man, man, light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏼❤️👨🏻 E13.1 couple with heart: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏼❤👨🏻 E13.1 couple with heart: man, man, medium-light skin tone, light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏼❤️👨🏼 E13.1 couple with heart: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏼❤👨🏼 E13.1 couple with heart: man, man, medium-light skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏼❤️👨🏽 E13.1 couple with heart: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏼❤👨🏽 E13.1 couple with heart: man, man, medium-light skin tone, medium skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏼❤️👨🏾 E13.1 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏼❤👨🏾 E13.1 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
+1F468 1F3FC 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏼❤️👨🏿 E13.1 couple with heart: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FC 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏼❤👨🏿 E13.1 couple with heart: man, man, medium-light skin tone, dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏽❤️👨🏻 E13.1 couple with heart: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏽❤👨🏻 E13.1 couple with heart: man, man, medium skin tone, light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏽❤️👨🏼 E13.1 couple with heart: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏽❤👨🏼 E13.1 couple with heart: man, man, medium skin tone, medium-light skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏽❤️👨🏽 E13.1 couple with heart: man, man, medium skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏽❤👨🏽 E13.1 couple with heart: man, man, medium skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏽❤️👨🏾 E13.1 couple with heart: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏽❤👨🏾 E13.1 couple with heart: man, man, medium skin tone, medium-dark skin tone
+1F468 1F3FD 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏽❤️👨🏿 E13.1 couple with heart: man, man, medium skin tone, dark skin tone
+1F468 1F3FD 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏽❤👨🏿 E13.1 couple with heart: man, man, medium skin tone, dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏾❤️👨🏻 E13.1 couple with heart: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏾❤👨🏻 E13.1 couple with heart: man, man, medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏾❤️👨🏼 E13.1 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏾❤👨🏼 E13.1 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏾❤️👨🏽 E13.1 couple with heart: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏾❤👨🏽 E13.1 couple with heart: man, man, medium-dark skin tone, medium skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏾❤️👨🏾 E13.1 couple with heart: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏾❤👨🏾 E13.1 couple with heart: man, man, medium-dark skin tone
+1F468 1F3FE 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏾❤️👨🏿 E13.1 couple with heart: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FE 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏾❤👨🏿 E13.1 couple with heart: man, man, medium-dark skin tone, dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FB ; fully-qualified # 👨🏿❤️👨🏻 E13.1 couple with heart: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FB ; minimally-qualified # 👨🏿❤👨🏻 E13.1 couple with heart: man, man, dark skin tone, light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FC ; fully-qualified # 👨🏿❤️👨🏼 E13.1 couple with heart: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FC ; minimally-qualified # 👨🏿❤👨🏼 E13.1 couple with heart: man, man, dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FD ; fully-qualified # 👨🏿❤️👨🏽 E13.1 couple with heart: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FD ; minimally-qualified # 👨🏿❤👨🏽 E13.1 couple with heart: man, man, dark skin tone, medium skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FE ; fully-qualified # 👨🏿❤️👨🏾 E13.1 couple with heart: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FE ; minimally-qualified # 👨🏿❤👨🏾 E13.1 couple with heart: man, man, dark skin tone, medium-dark skin tone
+1F468 1F3FF 200D 2764 FE0F 200D 1F468 1F3FF ; fully-qualified # 👨🏿❤️👨🏿 E13.1 couple with heart: man, man, dark skin tone
+1F468 1F3FF 200D 2764 200D 1F468 1F3FF ; minimally-qualified # 👨🏿❤👨🏿 E13.1 couple with heart: man, man, dark skin tone
+1F469 200D 2764 FE0F 200D 1F469 ; fully-qualified # 👩❤️👩 E2.0 couple with heart: woman, woman
+1F469 200D 2764 200D 1F469 ; minimally-qualified # 👩❤👩 E2.0 couple with heart: woman, woman
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏻❤️👩🏻 E13.1 couple with heart: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏻❤👩🏻 E13.1 couple with heart: woman, woman, light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏻❤️👩🏼 E13.1 couple with heart: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏻❤👩🏼 E13.1 couple with heart: woman, woman, light skin tone, medium-light skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏻❤️👩🏽 E13.1 couple with heart: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏻❤👩🏽 E13.1 couple with heart: woman, woman, light skin tone, medium skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏻❤️👩🏾 E13.1 couple with heart: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏻❤👩🏾 E13.1 couple with heart: woman, woman, light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏻❤️👩🏿 E13.1 couple with heart: woman, woman, light skin tone, dark skin tone
+1F469 1F3FB 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏻❤👩🏿 E13.1 couple with heart: woman, woman, light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏼❤️👩🏻 E13.1 couple with heart: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏼❤👩🏻 E13.1 couple with heart: woman, woman, medium-light skin tone, light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏼❤️👩🏼 E13.1 couple with heart: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏼❤👩🏼 E13.1 couple with heart: woman, woman, medium-light skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏼❤️👩🏽 E13.1 couple with heart: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏼❤👩🏽 E13.1 couple with heart: woman, woman, medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏼❤️👩🏾 E13.1 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏼❤👩🏾 E13.1 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏼❤️👩🏿 E13.1 couple with heart: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FC 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏼❤👩🏿 E13.1 couple with heart: woman, woman, medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏽❤️👩🏻 E13.1 couple with heart: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏽❤👩🏻 E13.1 couple with heart: woman, woman, medium skin tone, light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏽❤️👩🏼 E13.1 couple with heart: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏽❤👩🏼 E13.1 couple with heart: woman, woman, medium skin tone, medium-light skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏽❤️👩🏽 E13.1 couple with heart: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏽❤👩🏽 E13.1 couple with heart: woman, woman, medium skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏽❤️👩🏾 E13.1 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏽❤👩🏾 E13.1 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏽❤️👩🏿 E13.1 couple with heart: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FD 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏽❤👩🏿 E13.1 couple with heart: woman, woman, medium skin tone, dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏾❤️👩🏻 E13.1 couple with heart: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏾❤👩🏻 E13.1 couple with heart: woman, woman, medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏾❤️👩🏼 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏾❤👩🏼 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏾❤️👩🏽 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏾❤👩🏽 E13.1 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏾❤️👩🏾 E13.1 couple with heart: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏾❤👩🏾 E13.1 couple with heart: woman, woman, medium-dark skin tone
+1F469 1F3FE 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏾❤️👩🏿 E13.1 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FE 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏾❤👩🏿 E13.1 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FB ; fully-qualified # 👩🏿❤️👩🏻 E13.1 couple with heart: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FB ; minimally-qualified # 👩🏿❤👩🏻 E13.1 couple with heart: woman, woman, dark skin tone, light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FC ; fully-qualified # 👩🏿❤️👩🏼 E13.1 couple with heart: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FC ; minimally-qualified # 👩🏿❤👩🏼 E13.1 couple with heart: woman, woman, dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FD ; fully-qualified # 👩🏿❤️👩🏽 E13.1 couple with heart: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FD ; minimally-qualified # 👩🏿❤👩🏽 E13.1 couple with heart: woman, woman, dark skin tone, medium skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FE ; fully-qualified # 👩🏿❤️👩🏾 E13.1 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FE ; minimally-qualified # 👩🏿❤👩🏾 E13.1 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
+1F469 1F3FF 200D 2764 FE0F 200D 1F469 1F3FF ; fully-qualified # 👩🏿❤️👩🏿 E13.1 couple with heart: woman, woman, dark skin tone
+1F469 1F3FF 200D 2764 200D 1F469 1F3FF ; minimally-qualified # 👩🏿❤👩🏿 E13.1 couple with heart: woman, woman, dark skin tone
+1F46A ; fully-qualified # 👪 E0.6 family
+1F468 200D 1F469 200D 1F466 ; fully-qualified # 👨👩👦 E2.0 family: man, woman, boy
+1F468 200D 1F469 200D 1F467 ; fully-qualified # 👨👩👧 E2.0 family: man, woman, girl
+1F468 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👨👩👧👦 E2.0 family: man, woman, girl, boy
+1F468 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👨👩👦👦 E2.0 family: man, woman, boy, boy
+1F468 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👨👩👧👧 E2.0 family: man, woman, girl, girl
+1F468 200D 1F468 200D 1F466 ; fully-qualified # 👨👨👦 E2.0 family: man, man, boy
+1F468 200D 1F468 200D 1F467 ; fully-qualified # 👨👨👧 E2.0 family: man, man, girl
+1F468 200D 1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨👨👧👦 E2.0 family: man, man, girl, boy
+1F468 200D 1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨👨👦👦 E2.0 family: man, man, boy, boy
+1F468 200D 1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨👨👧👧 E2.0 family: man, man, girl, girl
+1F469 200D 1F469 200D 1F466 ; fully-qualified # 👩👩👦 E2.0 family: woman, woman, boy
+1F469 200D 1F469 200D 1F467 ; fully-qualified # 👩👩👧 E2.0 family: woman, woman, girl
+1F469 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩👩👧👦 E2.0 family: woman, woman, girl, boy
+1F469 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩👩👦👦 E2.0 family: woman, woman, boy, boy
+1F469 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩👩👧👧 E2.0 family: woman, woman, girl, girl
+1F468 200D 1F466 ; fully-qualified # 👨👦 E4.0 family: man, boy
+1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨👦👦 E4.0 family: man, boy, boy
+1F468 200D 1F467 ; fully-qualified # 👨👧 E4.0 family: man, girl
+1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨👧👦 E4.0 family: man, girl, boy
+1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨👧👧 E4.0 family: man, girl, girl
+1F469 200D 1F466 ; fully-qualified # 👩👦 E4.0 family: woman, boy
+1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩👦👦 E4.0 family: woman, boy, boy
+1F469 200D 1F467 ; fully-qualified # 👩👧 E4.0 family: woman, girl
+1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩👧👦 E4.0 family: woman, girl, boy
+1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩👧👧 E4.0 family: woman, girl, girl
# subgroup: person-symbol
-1F5E3 FE0F ; fully-qualified # 🗣️ E0.7 speaking head
-1F5E3 ; unqualified # 🗣 E0.7 speaking head
-1F464 ; fully-qualified # 👤 E0.6 bust in silhouette
-1F465 ; fully-qualified # 👥 E1.0 busts in silhouette
-1FAC2 ; fully-qualified # 🫂 E13.0 people hugging
-1F463 ; fully-qualified # 👣 E0.6 footprints
+1F5E3 FE0F ; fully-qualified # 🗣️ E0.7 speaking head
+1F5E3 ; unqualified # 🗣 E0.7 speaking head
+1F464 ; fully-qualified # 👤 E0.6 bust in silhouette
+1F465 ; fully-qualified # 👥 E1.0 busts in silhouette
+1FAC2 ; fully-qualified # 🫂 E13.0 people hugging
+1F463 ; fully-qualified # 👣 E0.6 footprints
-# People & Body subtotal: 2485
-# People & Body subtotal: 490 w/o modifiers
+# People & Body subtotal: 2899
+# People & Body subtotal: 494 w/o modifiers
# group: Component
# subgroup: skin-tone
-1F3FB ; component # 🏻 E1.0 light skin tone
-1F3FC ; component # 🏼 E1.0 medium-light skin tone
-1F3FD ; component # 🏽 E1.0 medium skin tone
-1F3FE ; component # 🏾 E1.0 medium-dark skin tone
-1F3FF ; component # 🏿 E1.0 dark skin tone
+1F3FB ; component # 🏻 E1.0 light skin tone
+1F3FC ; component # 🏼 E1.0 medium-light skin tone
+1F3FD ; component # 🏽 E1.0 medium skin tone
+1F3FE ; component # 🏾 E1.0 medium-dark skin tone
+1F3FF ; component # 🏿 E1.0 dark skin tone
# subgroup: hair-style
-1F9B0 ; component # 🦰 E11.0 red hair
-1F9B1 ; component # 🦱 E11.0 curly hair
-1F9B3 ; component # 🦳 E11.0 white hair
-1F9B2 ; component # 🦲 E11.0 bald
+1F9B0 ; component # 🦰 E11.0 red hair
+1F9B1 ; component # 🦱 E11.0 curly hair
+1F9B3 ; component # 🦳 E11.0 white hair
+1F9B2 ; component # 🦲 E11.0 bald
# Component subtotal: 9
# Component subtotal: 4 w/o modifiers
@@ -2770,167 +3192,167 @@
# group: Animals & Nature
# subgroup: animal-mammal
-1F435 ; fully-qualified # 🐵 E0.6 monkey face
-1F412 ; fully-qualified # 🐒 E0.6 monkey
-1F98D ; fully-qualified # 🦍 E3.0 gorilla
-1F9A7 ; fully-qualified # 🦧 E12.0 orangutan
-1F436 ; fully-qualified # 🐶 E0.6 dog face
-1F415 ; fully-qualified # 🐕 E0.7 dog
-1F9AE ; fully-qualified # 🦮 E12.0 guide dog
-1F415 200D 1F9BA ; fully-qualified # 🐕🦺 E12.0 service dog
-1F429 ; fully-qualified # 🐩 E0.6 poodle
-1F43A ; fully-qualified # 🐺 E0.6 wolf
-1F98A ; fully-qualified # 🦊 E3.0 fox
-1F99D ; fully-qualified # 🦝 E11.0 raccoon
-1F431 ; fully-qualified # 🐱 E0.6 cat face
-1F408 ; fully-qualified # 🐈 E0.7 cat
-1F408 200D 2B1B ; fully-qualified # 🐈⬛ E13.0 black cat
-1F981 ; fully-qualified # 🦁 E1.0 lion
-1F42F ; fully-qualified # 🐯 E0.6 tiger face
-1F405 ; fully-qualified # 🐅 E1.0 tiger
-1F406 ; fully-qualified # 🐆 E1.0 leopard
-1F434 ; fully-qualified # 🐴 E0.6 horse face
-1F40E ; fully-qualified # 🐎 E0.6 horse
-1F984 ; fully-qualified # 🦄 E1.0 unicorn
-1F993 ; fully-qualified # 🦓 E5.0 zebra
-1F98C ; fully-qualified # 🦌 E3.0 deer
-1F9AC ; fully-qualified # 🦬 E13.0 bison
-1F42E ; fully-qualified # 🐮 E0.6 cow face
-1F402 ; fully-qualified # 🐂 E1.0 ox
-1F403 ; fully-qualified # 🐃 E1.0 water buffalo
-1F404 ; fully-qualified # 🐄 E1.0 cow
-1F437 ; fully-qualified # 🐷 E0.6 pig face
-1F416 ; fully-qualified # 🐖 E1.0 pig
-1F417 ; fully-qualified # 🐗 E0.6 boar
-1F43D ; fully-qualified # 🐽 E0.6 pig nose
-1F40F ; fully-qualified # 🐏 E1.0 ram
-1F411 ; fully-qualified # 🐑 E0.6 ewe
-1F410 ; fully-qualified # 🐐 E1.0 goat
-1F42A ; fully-qualified # 🐪 E1.0 camel
-1F42B ; fully-qualified # 🐫 E0.6 two-hump camel
-1F999 ; fully-qualified # 🦙 E11.0 llama
-1F992 ; fully-qualified # 🦒 E5.0 giraffe
-1F418 ; fully-qualified # 🐘 E0.6 elephant
-1F9A3 ; fully-qualified # 🦣 E13.0 mammoth
-1F98F ; fully-qualified # 🦏 E3.0 rhinoceros
-1F99B ; fully-qualified # 🦛 E11.0 hippopotamus
-1F42D ; fully-qualified # 🐭 E0.6 mouse face
-1F401 ; fully-qualified # 🐁 E1.0 mouse
-1F400 ; fully-qualified # 🐀 E1.0 rat
-1F439 ; fully-qualified # 🐹 E0.6 hamster
-1F430 ; fully-qualified # 🐰 E0.6 rabbit face
-1F407 ; fully-qualified # 🐇 E1.0 rabbit
-1F43F FE0F ; fully-qualified # 🐿️ E0.7 chipmunk
-1F43F ; unqualified # 🐿 E0.7 chipmunk
-1F9AB ; fully-qualified # 🦫 E13.0 beaver
-1F994 ; fully-qualified # 🦔 E5.0 hedgehog
-1F987 ; fully-qualified # 🦇 E3.0 bat
-1F43B ; fully-qualified # 🐻 E0.6 bear
-1F43B 200D 2744 FE0F ; fully-qualified # 🐻❄️ E13.0 polar bear
-1F43B 200D 2744 ; minimally-qualified # 🐻❄ E13.0 polar bear
-1F428 ; fully-qualified # 🐨 E0.6 koala
-1F43C ; fully-qualified # 🐼 E0.6 panda
-1F9A5 ; fully-qualified # 🦥 E12.0 sloth
-1F9A6 ; fully-qualified # 🦦 E12.0 otter
-1F9A8 ; fully-qualified # 🦨 E12.0 skunk
-1F998 ; fully-qualified # 🦘 E11.0 kangaroo
-1F9A1 ; fully-qualified # 🦡 E11.0 badger
-1F43E ; fully-qualified # 🐾 E0.6 paw prints
+1F435 ; fully-qualified # 🐵 E0.6 monkey face
+1F412 ; fully-qualified # 🐒 E0.6 monkey
+1F98D ; fully-qualified # 🦍 E3.0 gorilla
+1F9A7 ; fully-qualified # 🦧 E12.0 orangutan
+1F436 ; fully-qualified # 🐶 E0.6 dog face
+1F415 ; fully-qualified # 🐕 E0.7 dog
+1F9AE ; fully-qualified # 🦮 E12.0 guide dog
+1F415 200D 1F9BA ; fully-qualified # 🐕🦺 E12.0 service dog
+1F429 ; fully-qualified # 🐩 E0.6 poodle
+1F43A ; fully-qualified # 🐺 E0.6 wolf
+1F98A ; fully-qualified # 🦊 E3.0 fox
+1F99D ; fully-qualified # 🦝 E11.0 raccoon
+1F431 ; fully-qualified # 🐱 E0.6 cat face
+1F408 ; fully-qualified # 🐈 E0.7 cat
+1F408 200D 2B1B ; fully-qualified # 🐈⬛ E13.0 black cat
+1F981 ; fully-qualified # 🦁 E1.0 lion
+1F42F ; fully-qualified # 🐯 E0.6 tiger face
+1F405 ; fully-qualified # 🐅 E1.0 tiger
+1F406 ; fully-qualified # 🐆 E1.0 leopard
+1F434 ; fully-qualified # 🐴 E0.6 horse face
+1F40E ; fully-qualified # 🐎 E0.6 horse
+1F984 ; fully-qualified # 🦄 E1.0 unicorn
+1F993 ; fully-qualified # 🦓 E5.0 zebra
+1F98C ; fully-qualified # 🦌 E3.0 deer
+1F9AC ; fully-qualified # 🦬 E13.0 bison
+1F42E ; fully-qualified # 🐮 E0.6 cow face
+1F402 ; fully-qualified # 🐂 E1.0 ox
+1F403 ; fully-qualified # 🐃 E1.0 water buffalo
+1F404 ; fully-qualified # 🐄 E1.0 cow
+1F437 ; fully-qualified # 🐷 E0.6 pig face
+1F416 ; fully-qualified # 🐖 E1.0 pig
+1F417 ; fully-qualified # 🐗 E0.6 boar
+1F43D ; fully-qualified # 🐽 E0.6 pig nose
+1F40F ; fully-qualified # 🐏 E1.0 ram
+1F411 ; fully-qualified # 🐑 E0.6 ewe
+1F410 ; fully-qualified # 🐐 E1.0 goat
+1F42A ; fully-qualified # 🐪 E1.0 camel
+1F42B ; fully-qualified # 🐫 E0.6 two-hump camel
+1F999 ; fully-qualified # 🦙 E11.0 llama
+1F992 ; fully-qualified # 🦒 E5.0 giraffe
+1F418 ; fully-qualified # 🐘 E0.6 elephant
+1F9A3 ; fully-qualified # 🦣 E13.0 mammoth
+1F98F ; fully-qualified # 🦏 E3.0 rhinoceros
+1F99B ; fully-qualified # 🦛 E11.0 hippopotamus
+1F42D ; fully-qualified # 🐭 E0.6 mouse face
+1F401 ; fully-qualified # 🐁 E1.0 mouse
+1F400 ; fully-qualified # 🐀 E1.0 rat
+1F439 ; fully-qualified # 🐹 E0.6 hamster
+1F430 ; fully-qualified # 🐰 E0.6 rabbit face
+1F407 ; fully-qualified # 🐇 E1.0 rabbit
+1F43F FE0F ; fully-qualified # 🐿️ E0.7 chipmunk
+1F43F ; unqualified # 🐿 E0.7 chipmunk
+1F9AB ; fully-qualified # 🦫 E13.0 beaver
+1F994 ; fully-qualified # 🦔 E5.0 hedgehog
+1F987 ; fully-qualified # 🦇 E3.0 bat
+1F43B ; fully-qualified # 🐻 E0.6 bear
+1F43B 200D 2744 FE0F ; fully-qualified # 🐻❄️ E13.0 polar bear
+1F43B 200D 2744 ; minimally-qualified # 🐻❄ E13.0 polar bear
+1F428 ; fully-qualified # 🐨 E0.6 koala
+1F43C ; fully-qualified # 🐼 E0.6 panda
+1F9A5 ; fully-qualified # 🦥 E12.0 sloth
+1F9A6 ; fully-qualified # 🦦 E12.0 otter
+1F9A8 ; fully-qualified # 🦨 E12.0 skunk
+1F998 ; fully-qualified # 🦘 E11.0 kangaroo
+1F9A1 ; fully-qualified # 🦡 E11.0 badger
+1F43E ; fully-qualified # 🐾 E0.6 paw prints
# subgroup: animal-bird
-1F983 ; fully-qualified # 🦃 E1.0 turkey
-1F414 ; fully-qualified # 🐔 E0.6 chicken
-1F413 ; fully-qualified # 🐓 E1.0 rooster
-1F423 ; fully-qualified # 🐣 E0.6 hatching chick
-1F424 ; fully-qualified # 🐤 E0.6 baby chick
-1F425 ; fully-qualified # 🐥 E0.6 front-facing baby chick
-1F426 ; fully-qualified # 🐦 E0.6 bird
-1F427 ; fully-qualified # 🐧 E0.6 penguin
-1F54A FE0F ; fully-qualified # 🕊️ E0.7 dove
-1F54A ; unqualified # 🕊 E0.7 dove
-1F985 ; fully-qualified # 🦅 E3.0 eagle
-1F986 ; fully-qualified # 🦆 E3.0 duck
-1F9A2 ; fully-qualified # 🦢 E11.0 swan
-1F989 ; fully-qualified # 🦉 E3.0 owl
-1F9A4 ; fully-qualified # 🦤 E13.0 dodo
-1FAB6 ; fully-qualified # 🪶 E13.0 feather
-1F9A9 ; fully-qualified # 🦩 E12.0 flamingo
-1F99A ; fully-qualified # 🦚 E11.0 peacock
-1F99C ; fully-qualified # 🦜 E11.0 parrot
+1F983 ; fully-qualified # 🦃 E1.0 turkey
+1F414 ; fully-qualified # 🐔 E0.6 chicken
+1F413 ; fully-qualified # 🐓 E1.0 rooster
+1F423 ; fully-qualified # 🐣 E0.6 hatching chick
+1F424 ; fully-qualified # 🐤 E0.6 baby chick
+1F425 ; fully-qualified # 🐥 E0.6 front-facing baby chick
+1F426 ; fully-qualified # 🐦 E0.6 bird
+1F427 ; fully-qualified # 🐧 E0.6 penguin
+1F54A FE0F ; fully-qualified # 🕊️ E0.7 dove
+1F54A ; unqualified # 🕊 E0.7 dove
+1F985 ; fully-qualified # 🦅 E3.0 eagle
+1F986 ; fully-qualified # 🦆 E3.0 duck
+1F9A2 ; fully-qualified # 🦢 E11.0 swan
+1F989 ; fully-qualified # 🦉 E3.0 owl
+1F9A4 ; fully-qualified # 🦤 E13.0 dodo
+1FAB6 ; fully-qualified # 🪶 E13.0 feather
+1F9A9 ; fully-qualified # 🦩 E12.0 flamingo
+1F99A ; fully-qualified # 🦚 E11.0 peacock
+1F99C ; fully-qualified # 🦜 E11.0 parrot
# subgroup: animal-amphibian
-1F438 ; fully-qualified # 🐸 E0.6 frog
+1F438 ; fully-qualified # 🐸 E0.6 frog
# subgroup: animal-reptile
-1F40A ; fully-qualified # 🐊 E1.0 crocodile
-1F422 ; fully-qualified # 🐢 E0.6 turtle
-1F98E ; fully-qualified # 🦎 E3.0 lizard
-1F40D ; fully-qualified # 🐍 E0.6 snake
-1F432 ; fully-qualified # 🐲 E0.6 dragon face
-1F409 ; fully-qualified # 🐉 E1.0 dragon
-1F995 ; fully-qualified # 🦕 E5.0 sauropod
-1F996 ; fully-qualified # 🦖 E5.0 T-Rex
+1F40A ; fully-qualified # 🐊 E1.0 crocodile
+1F422 ; fully-qualified # 🐢 E0.6 turtle
+1F98E ; fully-qualified # 🦎 E3.0 lizard
+1F40D ; fully-qualified # 🐍 E0.6 snake
+1F432 ; fully-qualified # 🐲 E0.6 dragon face
+1F409 ; fully-qualified # 🐉 E1.0 dragon
+1F995 ; fully-qualified # 🦕 E5.0 sauropod
+1F996 ; fully-qualified # 🦖 E5.0 T-Rex
# subgroup: animal-marine
-1F433 ; fully-qualified # 🐳 E0.6 spouting whale
-1F40B ; fully-qualified # 🐋 E1.0 whale
-1F42C ; fully-qualified # 🐬 E0.6 dolphin
-1F9AD ; fully-qualified # 🦭 E13.0 seal
-1F41F ; fully-qualified # 🐟 E0.6 fish
-1F420 ; fully-qualified # 🐠 E0.6 tropical fish
-1F421 ; fully-qualified # 🐡 E0.6 blowfish
-1F988 ; fully-qualified # 🦈 E3.0 shark
-1F419 ; fully-qualified # 🐙 E0.6 octopus
-1F41A ; fully-qualified # 🐚 E0.6 spiral shell
+1F433 ; fully-qualified # 🐳 E0.6 spouting whale
+1F40B ; fully-qualified # 🐋 E1.0 whale
+1F42C ; fully-qualified # 🐬 E0.6 dolphin
+1F9AD ; fully-qualified # 🦭 E13.0 seal
+1F41F ; fully-qualified # 🐟 E0.6 fish
+1F420 ; fully-qualified # 🐠 E0.6 tropical fish
+1F421 ; fully-qualified # 🐡 E0.6 blowfish
+1F988 ; fully-qualified # 🦈 E3.0 shark
+1F419 ; fully-qualified # 🐙 E0.6 octopus
+1F41A ; fully-qualified # 🐚 E0.6 spiral shell
# subgroup: animal-bug
-1F40C ; fully-qualified # 🐌 E0.6 snail
-1F98B ; fully-qualified # 🦋 E3.0 butterfly
-1F41B ; fully-qualified # 🐛 E0.6 bug
-1F41C ; fully-qualified # 🐜 E0.6 ant
-1F41D ; fully-qualified # 🐝 E0.6 honeybee
-1FAB2 ; fully-qualified # 🪲 E13.0 beetle
-1F41E ; fully-qualified # 🐞 E0.6 lady beetle
-1F997 ; fully-qualified # 🦗 E5.0 cricket
-1FAB3 ; fully-qualified # 🪳 E13.0 cockroach
-1F577 FE0F ; fully-qualified # 🕷️ E0.7 spider
-1F577 ; unqualified # 🕷 E0.7 spider
-1F578 FE0F ; fully-qualified # 🕸️ E0.7 spider web
-1F578 ; unqualified # 🕸 E0.7 spider web
-1F982 ; fully-qualified # 🦂 E1.0 scorpion
-1F99F ; fully-qualified # 🦟 E11.0 mosquito
-1FAB0 ; fully-qualified # 🪰 E13.0 fly
-1FAB1 ; fully-qualified # 🪱 E13.0 worm
-1F9A0 ; fully-qualified # 🦠 E11.0 microbe
+1F40C ; fully-qualified # 🐌 E0.6 snail
+1F98B ; fully-qualified # 🦋 E3.0 butterfly
+1F41B ; fully-qualified # 🐛 E0.6 bug
+1F41C ; fully-qualified # 🐜 E0.6 ant
+1F41D ; fully-qualified # 🐝 E0.6 honeybee
+1FAB2 ; fully-qualified # 🪲 E13.0 beetle
+1F41E ; fully-qualified # 🐞 E0.6 lady beetle
+1F997 ; fully-qualified # 🦗 E5.0 cricket
+1FAB3 ; fully-qualified # 🪳 E13.0 cockroach
+1F577 FE0F ; fully-qualified # 🕷️ E0.7 spider
+1F577 ; unqualified # 🕷 E0.7 spider
+1F578 FE0F ; fully-qualified # 🕸️ E0.7 spider web
+1F578 ; unqualified # 🕸 E0.7 spider web
+1F982 ; fully-qualified # 🦂 E1.0 scorpion
+1F99F ; fully-qualified # 🦟 E11.0 mosquito
+1FAB0 ; fully-qualified # 🪰 E13.0 fly
+1FAB1 ; fully-qualified # 🪱 E13.0 worm
+1F9A0 ; fully-qualified # 🦠 E11.0 microbe
# subgroup: plant-flower
-1F490 ; fully-qualified # 💐 E0.6 bouquet
-1F338 ; fully-qualified # 🌸 E0.6 cherry blossom
-1F4AE ; fully-qualified # 💮 E0.6 white flower
-1F3F5 FE0F ; fully-qualified # 🏵️ E0.7 rosette
-1F3F5 ; unqualified # 🏵 E0.7 rosette
-1F339 ; fully-qualified # 🌹 E0.6 rose
-1F940 ; fully-qualified # 🥀 E3.0 wilted flower
-1F33A ; fully-qualified # 🌺 E0.6 hibiscus
-1F33B ; fully-qualified # 🌻 E0.6 sunflower
-1F33C ; fully-qualified # 🌼 E0.6 blossom
-1F337 ; fully-qualified # 🌷 E0.6 tulip
+1F490 ; fully-qualified # 💐 E0.6 bouquet
+1F338 ; fully-qualified # 🌸 E0.6 cherry blossom
+1F4AE ; fully-qualified # 💮 E0.6 white flower
+1F3F5 FE0F ; fully-qualified # 🏵️ E0.7 rosette
+1F3F5 ; unqualified # 🏵 E0.7 rosette
+1F339 ; fully-qualified # 🌹 E0.6 rose
+1F940 ; fully-qualified # 🥀 E3.0 wilted flower
+1F33A ; fully-qualified # 🌺 E0.6 hibiscus
+1F33B ; fully-qualified # 🌻 E0.6 sunflower
+1F33C ; fully-qualified # 🌼 E0.6 blossom
+1F337 ; fully-qualified # 🌷 E0.6 tulip
# subgroup: plant-other
-1F331 ; fully-qualified # 🌱 E0.6 seedling
-1FAB4 ; fully-qualified # 🪴 E13.0 potted plant
-1F332 ; fully-qualified # 🌲 E1.0 evergreen tree
-1F333 ; fully-qualified # 🌳 E1.0 deciduous tree
-1F334 ; fully-qualified # 🌴 E0.6 palm tree
-1F335 ; fully-qualified # 🌵 E0.6 cactus
-1F33E ; fully-qualified # 🌾 E0.6 sheaf of rice
-1F33F ; fully-qualified # 🌿 E0.6 herb
-2618 FE0F ; fully-qualified # ☘️ E1.0 shamrock
-2618 ; unqualified # ☘ E1.0 shamrock
-1F340 ; fully-qualified # 🍀 E0.6 four leaf clover
-1F341 ; fully-qualified # 🍁 E0.6 maple leaf
-1F342 ; fully-qualified # 🍂 E0.6 fallen leaf
-1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind
+1F331 ; fully-qualified # 🌱 E0.6 seedling
+1FAB4 ; fully-qualified # 🪴 E13.0 potted plant
+1F332 ; fully-qualified # 🌲 E1.0 evergreen tree
+1F333 ; fully-qualified # 🌳 E1.0 deciduous tree
+1F334 ; fully-qualified # 🌴 E0.6 palm tree
+1F335 ; fully-qualified # 🌵 E0.6 cactus
+1F33E ; fully-qualified # 🌾 E0.6 sheaf of rice
+1F33F ; fully-qualified # 🌿 E0.6 herb
+2618 FE0F ; fully-qualified # ☘️ E1.0 shamrock
+2618 ; unqualified # ☘ E1.0 shamrock
+1F340 ; fully-qualified # 🍀 E0.6 four leaf clover
+1F341 ; fully-qualified # 🍁 E0.6 maple leaf
+1F342 ; fully-qualified # 🍂 E0.6 fallen leaf
+1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind
# Animals & Nature subtotal: 147
# Animals & Nature subtotal: 147 w/o modifiers
@@ -2938,151 +3360,151 @@
# group: Food & Drink
# subgroup: food-fruit
-1F347 ; fully-qualified # 🍇 E0.6 grapes
-1F348 ; fully-qualified # 🍈 E0.6 melon
-1F349 ; fully-qualified # 🍉 E0.6 watermelon
-1F34A ; fully-qualified # 🍊 E0.6 tangerine
-1F34B ; fully-qualified # 🍋 E1.0 lemon
-1F34C ; fully-qualified # 🍌 E0.6 banana
-1F34D ; fully-qualified # 🍍 E0.6 pineapple
-1F96D ; fully-qualified # 🥭 E11.0 mango
-1F34E ; fully-qualified # 🍎 E0.6 red apple
-1F34F ; fully-qualified # 🍏 E0.6 green apple
-1F350 ; fully-qualified # 🍐 E1.0 pear
-1F351 ; fully-qualified # 🍑 E0.6 peach
-1F352 ; fully-qualified # 🍒 E0.6 cherries
-1F353 ; fully-qualified # 🍓 E0.6 strawberry
-1FAD0 ; fully-qualified # 🫐 E13.0 blueberries
-1F95D ; fully-qualified # 🥝 E3.0 kiwi fruit
-1F345 ; fully-qualified # 🍅 E0.6 tomato
-1FAD2 ; fully-qualified # 🫒 E13.0 olive
-1F965 ; fully-qualified # 🥥 E5.0 coconut
+1F347 ; fully-qualified # 🍇 E0.6 grapes
+1F348 ; fully-qualified # 🍈 E0.6 melon
+1F349 ; fully-qualified # 🍉 E0.6 watermelon
+1F34A ; fully-qualified # 🍊 E0.6 tangerine
+1F34B ; fully-qualified # 🍋 E1.0 lemon
+1F34C ; fully-qualified # 🍌 E0.6 banana
+1F34D ; fully-qualified # 🍍 E0.6 pineapple
+1F96D ; fully-qualified # 🥭 E11.0 mango
+1F34E ; fully-qualified # 🍎 E0.6 red apple
+1F34F ; fully-qualified # 🍏 E0.6 green apple
+1F350 ; fully-qualified # 🍐 E1.0 pear
+1F351 ; fully-qualified # 🍑 E0.6 peach
+1F352 ; fully-qualified # 🍒 E0.6 cherries
+1F353 ; fully-qualified # 🍓 E0.6 strawberry
+1FAD0 ; fully-qualified # 🫐 E13.0 blueberries
+1F95D ; fully-qualified # 🥝 E3.0 kiwi fruit
+1F345 ; fully-qualified # 🍅 E0.6 tomato
+1FAD2 ; fully-qualified # 🫒 E13.0 olive
+1F965 ; fully-qualified # 🥥 E5.0 coconut
# subgroup: food-vegetable
-1F951 ; fully-qualified # 🥑 E3.0 avocado
-1F346 ; fully-qualified # 🍆 E0.6 eggplant
-1F954 ; fully-qualified # 🥔 E3.0 potato
-1F955 ; fully-qualified # 🥕 E3.0 carrot
-1F33D ; fully-qualified # 🌽 E0.6 ear of corn
-1F336 FE0F ; fully-qualified # 🌶️ E0.7 hot pepper
-1F336 ; unqualified # 🌶 E0.7 hot pepper
-1FAD1 ; fully-qualified # 🫑 E13.0 bell pepper
-1F952 ; fully-qualified # 🥒 E3.0 cucumber
-1F96C ; fully-qualified # 🥬 E11.0 leafy green
-1F966 ; fully-qualified # 🥦 E5.0 broccoli
-1F9C4 ; fully-qualified # 🧄 E12.0 garlic
-1F9C5 ; fully-qualified # 🧅 E12.0 onion
-1F344 ; fully-qualified # 🍄 E0.6 mushroom
-1F95C ; fully-qualified # 🥜 E3.0 peanuts
-1F330 ; fully-qualified # 🌰 E0.6 chestnut
+1F951 ; fully-qualified # 🥑 E3.0 avocado
+1F346 ; fully-qualified # 🍆 E0.6 eggplant
+1F954 ; fully-qualified # 🥔 E3.0 potato
+1F955 ; fully-qualified # 🥕 E3.0 carrot
+1F33D ; fully-qualified # 🌽 E0.6 ear of corn
+1F336 FE0F ; fully-qualified # 🌶️ E0.7 hot pepper
+1F336 ; unqualified # 🌶 E0.7 hot pepper
+1FAD1 ; fully-qualified # 🫑 E13.0 bell pepper
+1F952 ; fully-qualified # 🥒 E3.0 cucumber
+1F96C ; fully-qualified # 🥬 E11.0 leafy green
+1F966 ; fully-qualified # 🥦 E5.0 broccoli
+1F9C4 ; fully-qualified # 🧄 E12.0 garlic
+1F9C5 ; fully-qualified # 🧅 E12.0 onion
+1F344 ; fully-qualified # 🍄 E0.6 mushroom
+1F95C ; fully-qualified # 🥜 E3.0 peanuts
+1F330 ; fully-qualified # 🌰 E0.6 chestnut
# subgroup: food-prepared
-1F35E ; fully-qualified # 🍞 E0.6 bread
-1F950 ; fully-qualified # 🥐 E3.0 croissant
-1F956 ; fully-qualified # 🥖 E3.0 baguette bread
-1FAD3 ; fully-qualified # 🫓 E13.0 flatbread
-1F968 ; fully-qualified # 🥨 E5.0 pretzel
-1F96F ; fully-qualified # 🥯 E11.0 bagel
-1F95E ; fully-qualified # 🥞 E3.0 pancakes
-1F9C7 ; fully-qualified # 🧇 E12.0 waffle
-1F9C0 ; fully-qualified # 🧀 E1.0 cheese wedge
-1F356 ; fully-qualified # 🍖 E0.6 meat on bone
-1F357 ; fully-qualified # 🍗 E0.6 poultry leg
-1F969 ; fully-qualified # 🥩 E5.0 cut of meat
-1F953 ; fully-qualified # 🥓 E3.0 bacon
-1F354 ; fully-qualified # 🍔 E0.6 hamburger
-1F35F ; fully-qualified # 🍟 E0.6 french fries
-1F355 ; fully-qualified # 🍕 E0.6 pizza
-1F32D ; fully-qualified # 🌭 E1.0 hot dog
-1F96A ; fully-qualified # 🥪 E5.0 sandwich
-1F32E ; fully-qualified # 🌮 E1.0 taco
-1F32F ; fully-qualified # 🌯 E1.0 burrito
-1FAD4 ; fully-qualified # 🫔 E13.0 tamale
-1F959 ; fully-qualified # 🥙 E3.0 stuffed flatbread
-1F9C6 ; fully-qualified # 🧆 E12.0 falafel
-1F95A ; fully-qualified # 🥚 E3.0 egg
-1F373 ; fully-qualified # 🍳 E0.6 cooking
-1F958 ; fully-qualified # 🥘 E3.0 shallow pan of food
-1F372 ; fully-qualified # 🍲 E0.6 pot of food
-1FAD5 ; fully-qualified # 🫕 E13.0 fondue
-1F963 ; fully-qualified # 🥣 E5.0 bowl with spoon
-1F957 ; fully-qualified # 🥗 E3.0 green salad
-1F37F ; fully-qualified # 🍿 E1.0 popcorn
-1F9C8 ; fully-qualified # 🧈 E12.0 butter
-1F9C2 ; fully-qualified # 🧂 E11.0 salt
-1F96B ; fully-qualified # 🥫 E5.0 canned food
+1F35E ; fully-qualified # 🍞 E0.6 bread
+1F950 ; fully-qualified # 🥐 E3.0 croissant
+1F956 ; fully-qualified # 🥖 E3.0 baguette bread
+1FAD3 ; fully-qualified # 🫓 E13.0 flatbread
+1F968 ; fully-qualified # 🥨 E5.0 pretzel
+1F96F ; fully-qualified # 🥯 E11.0 bagel
+1F95E ; fully-qualified # 🥞 E3.0 pancakes
+1F9C7 ; fully-qualified # 🧇 E12.0 waffle
+1F9C0 ; fully-qualified # 🧀 E1.0 cheese wedge
+1F356 ; fully-qualified # 🍖 E0.6 meat on bone
+1F357 ; fully-qualified # 🍗 E0.6 poultry leg
+1F969 ; fully-qualified # 🥩 E5.0 cut of meat
+1F953 ; fully-qualified # 🥓 E3.0 bacon
+1F354 ; fully-qualified # 🍔 E0.6 hamburger
+1F35F ; fully-qualified # 🍟 E0.6 french fries
+1F355 ; fully-qualified # 🍕 E0.6 pizza
+1F32D ; fully-qualified # 🌭 E1.0 hot dog
+1F96A ; fully-qualified # 🥪 E5.0 sandwich
+1F32E ; fully-qualified # 🌮 E1.0 taco
+1F32F ; fully-qualified # 🌯 E1.0 burrito
+1FAD4 ; fully-qualified # 🫔 E13.0 tamale
+1F959 ; fully-qualified # 🥙 E3.0 stuffed flatbread
+1F9C6 ; fully-qualified # 🧆 E12.0 falafel
+1F95A ; fully-qualified # 🥚 E3.0 egg
+1F373 ; fully-qualified # 🍳 E0.6 cooking
+1F958 ; fully-qualified # 🥘 E3.0 shallow pan of food
+1F372 ; fully-qualified # 🍲 E0.6 pot of food
+1FAD5 ; fully-qualified # 🫕 E13.0 fondue
+1F963 ; fully-qualified # 🥣 E5.0 bowl with spoon
+1F957 ; fully-qualified # 🥗 E3.0 green salad
+1F37F ; fully-qualified # 🍿 E1.0 popcorn
+1F9C8 ; fully-qualified # 🧈 E12.0 butter
+1F9C2 ; fully-qualified # 🧂 E11.0 salt
+1F96B ; fully-qualified # 🥫 E5.0 canned food
# subgroup: food-asian
-1F371 ; fully-qualified # 🍱 E0.6 bento box
-1F358 ; fully-qualified # 🍘 E0.6 rice cracker
-1F359 ; fully-qualified # 🍙 E0.6 rice ball
-1F35A ; fully-qualified # 🍚 E0.6 cooked rice
-1F35B ; fully-qualified # 🍛 E0.6 curry rice
-1F35C ; fully-qualified # 🍜 E0.6 steaming bowl
-1F35D ; fully-qualified # 🍝 E0.6 spaghetti
-1F360 ; fully-qualified # 🍠 E0.6 roasted sweet potato
-1F362 ; fully-qualified # 🍢 E0.6 oden
-1F363 ; fully-qualified # 🍣 E0.6 sushi
-1F364 ; fully-qualified # 🍤 E0.6 fried shrimp
-1F365 ; fully-qualified # 🍥 E0.6 fish cake with swirl
-1F96E ; fully-qualified # 🥮 E11.0 moon cake
-1F361 ; fully-qualified # 🍡 E0.6 dango
-1F95F ; fully-qualified # 🥟 E5.0 dumpling
-1F960 ; fully-qualified # 🥠 E5.0 fortune cookie
-1F961 ; fully-qualified # 🥡 E5.0 takeout box
+1F371 ; fully-qualified # 🍱 E0.6 bento box
+1F358 ; fully-qualified # 🍘 E0.6 rice cracker
+1F359 ; fully-qualified # 🍙 E0.6 rice ball
+1F35A ; fully-qualified # 🍚 E0.6 cooked rice
+1F35B ; fully-qualified # 🍛 E0.6 curry rice
+1F35C ; fully-qualified # 🍜 E0.6 steaming bowl
+1F35D ; fully-qualified # 🍝 E0.6 spaghetti
+1F360 ; fully-qualified # 🍠 E0.6 roasted sweet potato
+1F362 ; fully-qualified # 🍢 E0.6 oden
+1F363 ; fully-qualified # 🍣 E0.6 sushi
+1F364 ; fully-qualified # 🍤 E0.6 fried shrimp
+1F365 ; fully-qualified # 🍥 E0.6 fish cake with swirl
+1F96E ; fully-qualified # 🥮 E11.0 moon cake
+1F361 ; fully-qualified # 🍡 E0.6 dango
+1F95F ; fully-qualified # 🥟 E5.0 dumpling
+1F960 ; fully-qualified # 🥠 E5.0 fortune cookie
+1F961 ; fully-qualified # 🥡 E5.0 takeout box
# subgroup: food-marine
-1F980 ; fully-qualified # 🦀 E1.0 crab
-1F99E ; fully-qualified # 🦞 E11.0 lobster
-1F990 ; fully-qualified # 🦐 E3.0 shrimp
-1F991 ; fully-qualified # 🦑 E3.0 squid
-1F9AA ; fully-qualified # 🦪 E12.0 oyster
+1F980 ; fully-qualified # 🦀 E1.0 crab
+1F99E ; fully-qualified # 🦞 E11.0 lobster
+1F990 ; fully-qualified # 🦐 E3.0 shrimp
+1F991 ; fully-qualified # 🦑 E3.0 squid
+1F9AA ; fully-qualified # 🦪 E12.0 oyster
# subgroup: food-sweet
-1F366 ; fully-qualified # 🍦 E0.6 soft ice cream
-1F367 ; fully-qualified # 🍧 E0.6 shaved ice
-1F368 ; fully-qualified # 🍨 E0.6 ice cream
-1F369 ; fully-qualified # 🍩 E0.6 doughnut
-1F36A ; fully-qualified # 🍪 E0.6 cookie
-1F382 ; fully-qualified # 🎂 E0.6 birthday cake
-1F370 ; fully-qualified # 🍰 E0.6 shortcake
-1F9C1 ; fully-qualified # 🧁 E11.0 cupcake
-1F967 ; fully-qualified # 🥧 E5.0 pie
-1F36B ; fully-qualified # 🍫 E0.6 chocolate bar
-1F36C ; fully-qualified # 🍬 E0.6 candy
-1F36D ; fully-qualified # 🍭 E0.6 lollipop
-1F36E ; fully-qualified # 🍮 E0.6 custard
-1F36F ; fully-qualified # 🍯 E0.6 honey pot
+1F366 ; fully-qualified # 🍦 E0.6 soft ice cream
+1F367 ; fully-qualified # 🍧 E0.6 shaved ice
+1F368 ; fully-qualified # 🍨 E0.6 ice cream
+1F369 ; fully-qualified # 🍩 E0.6 doughnut
+1F36A ; fully-qualified # 🍪 E0.6 cookie
+1F382 ; fully-qualified # 🎂 E0.6 birthday cake
+1F370 ; fully-qualified # 🍰 E0.6 shortcake
+1F9C1 ; fully-qualified # 🧁 E11.0 cupcake
+1F967 ; fully-qualified # 🥧 E5.0 pie
+1F36B ; fully-qualified # 🍫 E0.6 chocolate bar
+1F36C ; fully-qualified # 🍬 E0.6 candy
+1F36D ; fully-qualified # 🍭 E0.6 lollipop
+1F36E ; fully-qualified # 🍮 E0.6 custard
+1F36F ; fully-qualified # 🍯 E0.6 honey pot
# subgroup: drink
-1F37C ; fully-qualified # 🍼 E1.0 baby bottle
-1F95B ; fully-qualified # 🥛 E3.0 glass of milk
-2615 ; fully-qualified # ☕ E0.6 hot beverage
-1FAD6 ; fully-qualified # 🫖 E13.0 teapot
-1F375 ; fully-qualified # 🍵 E0.6 teacup without handle
-1F376 ; fully-qualified # 🍶 E0.6 sake
-1F37E ; fully-qualified # 🍾 E1.0 bottle with popping cork
-1F377 ; fully-qualified # 🍷 E0.6 wine glass
-1F378 ; fully-qualified # 🍸 E0.6 cocktail glass
-1F379 ; fully-qualified # 🍹 E0.6 tropical drink
-1F37A ; fully-qualified # 🍺 E0.6 beer mug
-1F37B ; fully-qualified # 🍻 E0.6 clinking beer mugs
-1F942 ; fully-qualified # 🥂 E3.0 clinking glasses
-1F943 ; fully-qualified # 🥃 E3.0 tumbler glass
-1F964 ; fully-qualified # 🥤 E5.0 cup with straw
-1F9CB ; fully-qualified # 🧋 E13.0 bubble tea
-1F9C3 ; fully-qualified # 🧃 E12.0 beverage box
-1F9C9 ; fully-qualified # 🧉 E12.0 mate
-1F9CA ; fully-qualified # 🧊 E12.0 ice
+1F37C ; fully-qualified # 🍼 E1.0 baby bottle
+1F95B ; fully-qualified # 🥛 E3.0 glass of milk
+2615 ; fully-qualified # ☕ E0.6 hot beverage
+1FAD6 ; fully-qualified # 🫖 E13.0 teapot
+1F375 ; fully-qualified # 🍵 E0.6 teacup without handle
+1F376 ; fully-qualified # 🍶 E0.6 sake
+1F37E ; fully-qualified # 🍾 E1.0 bottle with popping cork
+1F377 ; fully-qualified # 🍷 E0.6 wine glass
+1F378 ; fully-qualified # 🍸 E0.6 cocktail glass
+1F379 ; fully-qualified # 🍹 E0.6 tropical drink
+1F37A ; fully-qualified # 🍺 E0.6 beer mug
+1F37B ; fully-qualified # 🍻 E0.6 clinking beer mugs
+1F942 ; fully-qualified # 🥂 E3.0 clinking glasses
+1F943 ; fully-qualified # 🥃 E3.0 tumbler glass
+1F964 ; fully-qualified # 🥤 E5.0 cup with straw
+1F9CB ; fully-qualified # 🧋 E13.0 bubble tea
+1F9C3 ; fully-qualified # 🧃 E12.0 beverage box
+1F9C9 ; fully-qualified # 🧉 E12.0 mate
+1F9CA ; fully-qualified # 🧊 E12.0 ice
# subgroup: dishware
-1F962 ; fully-qualified # 🥢 E5.0 chopsticks
-1F37D FE0F ; fully-qualified # 🍽️ E0.7 fork and knife with plate
-1F37D ; unqualified # 🍽 E0.7 fork and knife with plate
-1F374 ; fully-qualified # 🍴 E0.6 fork and knife
-1F944 ; fully-qualified # 🥄 E3.0 spoon
-1F52A ; fully-qualified # 🔪 E0.6 kitchen knife
-1F3FA ; fully-qualified # 🏺 E1.0 amphora
+1F962 ; fully-qualified # 🥢 E5.0 chopsticks
+1F37D FE0F ; fully-qualified # 🍽️ E0.7 fork and knife with plate
+1F37D ; unqualified # 🍽 E0.7 fork and knife with plate
+1F374 ; fully-qualified # 🍴 E0.6 fork and knife
+1F944 ; fully-qualified # 🥄 E3.0 spoon
+1F52A ; fully-qualified # 🔪 E0.6 kitchen knife
+1F3FA ; fully-qualified # 🏺 E1.0 amphora
# Food & Drink subtotal: 131
# Food & Drink subtotal: 131 w/o modifiers
@@ -3090,290 +3512,290 @@
# group: Travel & Places
# subgroup: place-map
-1F30D ; fully-qualified # 🌍 E0.7 globe showing Europe-Africa
-1F30E ; fully-qualified # 🌎 E0.7 globe showing Americas
-1F30F ; fully-qualified # 🌏 E0.6 globe showing Asia-Australia
-1F310 ; fully-qualified # 🌐 E1.0 globe with meridians
-1F5FA FE0F ; fully-qualified # 🗺️ E0.7 world map
-1F5FA ; unqualified # 🗺 E0.7 world map
-1F5FE ; fully-qualified # 🗾 E0.6 map of Japan
-1F9ED ; fully-qualified # 🧭 E11.0 compass
+1F30D ; fully-qualified # 🌍 E0.7 globe showing Europe-Africa
+1F30E ; fully-qualified # 🌎 E0.7 globe showing Americas
+1F30F ; fully-qualified # 🌏 E0.6 globe showing Asia-Australia
+1F310 ; fully-qualified # 🌐 E1.0 globe with meridians
+1F5FA FE0F ; fully-qualified # 🗺️ E0.7 world map
+1F5FA ; unqualified # 🗺 E0.7 world map
+1F5FE ; fully-qualified # 🗾 E0.6 map of Japan
+1F9ED ; fully-qualified # 🧭 E11.0 compass
# subgroup: place-geographic
-1F3D4 FE0F ; fully-qualified # 🏔️ E0.7 snow-capped mountain
-1F3D4 ; unqualified # 🏔 E0.7 snow-capped mountain
-26F0 FE0F ; fully-qualified # ⛰️ E0.7 mountain
-26F0 ; unqualified # ⛰ E0.7 mountain
-1F30B ; fully-qualified # 🌋 E0.6 volcano
-1F5FB ; fully-qualified # 🗻 E0.6 mount fuji
-1F3D5 FE0F ; fully-qualified # 🏕️ E0.7 camping
-1F3D5 ; unqualified # 🏕 E0.7 camping
-1F3D6 FE0F ; fully-qualified # 🏖️ E0.7 beach with umbrella
-1F3D6 ; unqualified # 🏖 E0.7 beach with umbrella
-1F3DC FE0F ; fully-qualified # 🏜️ E0.7 desert
-1F3DC ; unqualified # 🏜 E0.7 desert
-1F3DD FE0F ; fully-qualified # 🏝️ E0.7 desert island
-1F3DD ; unqualified # 🏝 E0.7 desert island
-1F3DE FE0F ; fully-qualified # 🏞️ E0.7 national park
-1F3DE ; unqualified # 🏞 E0.7 national park
+1F3D4 FE0F ; fully-qualified # 🏔️ E0.7 snow-capped mountain
+1F3D4 ; unqualified # 🏔 E0.7 snow-capped mountain
+26F0 FE0F ; fully-qualified # ⛰️ E0.7 mountain
+26F0 ; unqualified # ⛰ E0.7 mountain
+1F30B ; fully-qualified # 🌋 E0.6 volcano
+1F5FB ; fully-qualified # 🗻 E0.6 mount fuji
+1F3D5 FE0F ; fully-qualified # 🏕️ E0.7 camping
+1F3D5 ; unqualified # 🏕 E0.7 camping
+1F3D6 FE0F ; fully-qualified # 🏖️ E0.7 beach with umbrella
+1F3D6 ; unqualified # 🏖 E0.7 beach with umbrella
+1F3DC FE0F ; fully-qualified # 🏜️ E0.7 desert
+1F3DC ; unqualified # 🏜 E0.7 desert
+1F3DD FE0F ; fully-qualified # 🏝️ E0.7 desert island
+1F3DD ; unqualified # 🏝 E0.7 desert island
+1F3DE FE0F ; fully-qualified # 🏞️ E0.7 national park
+1F3DE ; unqualified # 🏞 E0.7 national park
# subgroup: place-building
-1F3DF FE0F ; fully-qualified # 🏟️ E0.7 stadium
-1F3DF ; unqualified # 🏟 E0.7 stadium
-1F3DB FE0F ; fully-qualified # 🏛️ E0.7 classical building
-1F3DB ; unqualified # 🏛 E0.7 classical building
-1F3D7 FE0F ; fully-qualified # 🏗️ E0.7 building construction
-1F3D7 ; unqualified # 🏗 E0.7 building construction
-1F9F1 ; fully-qualified # 🧱 E11.0 brick
-1FAA8 ; fully-qualified # 🪨 E13.0 rock
-1FAB5 ; fully-qualified # 🪵 E13.0 wood
-1F6D6 ; fully-qualified # 🛖 E13.0 hut
-1F3D8 FE0F ; fully-qualified # 🏘️ E0.7 houses
-1F3D8 ; unqualified # 🏘 E0.7 houses
-1F3DA FE0F ; fully-qualified # 🏚️ E0.7 derelict house
-1F3DA ; unqualified # 🏚 E0.7 derelict house
-1F3E0 ; fully-qualified # 🏠 E0.6 house
-1F3E1 ; fully-qualified # 🏡 E0.6 house with garden
-1F3E2 ; fully-qualified # 🏢 E0.6 office building
-1F3E3 ; fully-qualified # 🏣 E0.6 Japanese post office
-1F3E4 ; fully-qualified # 🏤 E1.0 post office
-1F3E5 ; fully-qualified # 🏥 E0.6 hospital
-1F3E6 ; fully-qualified # 🏦 E0.6 bank
-1F3E8 ; fully-qualified # 🏨 E0.6 hotel
-1F3E9 ; fully-qualified # 🏩 E0.6 love hotel
-1F3EA ; fully-qualified # 🏪 E0.6 convenience store
-1F3EB ; fully-qualified # 🏫 E0.6 school
-1F3EC ; fully-qualified # 🏬 E0.6 department store
-1F3ED ; fully-qualified # 🏭 E0.6 factory
-1F3EF ; fully-qualified # 🏯 E0.6 Japanese castle
-1F3F0 ; fully-qualified # 🏰 E0.6 castle
-1F492 ; fully-qualified # 💒 E0.6 wedding
-1F5FC ; fully-qualified # 🗼 E0.6 Tokyo tower
-1F5FD ; fully-qualified # 🗽 E0.6 Statue of Liberty
+1F3DF FE0F ; fully-qualified # 🏟️ E0.7 stadium
+1F3DF ; unqualified # 🏟 E0.7 stadium
+1F3DB FE0F ; fully-qualified # 🏛️ E0.7 classical building
+1F3DB ; unqualified # 🏛 E0.7 classical building
+1F3D7 FE0F ; fully-qualified # 🏗️ E0.7 building construction
+1F3D7 ; unqualified # 🏗 E0.7 building construction
+1F9F1 ; fully-qualified # 🧱 E11.0 brick
+1FAA8 ; fully-qualified # 🪨 E13.0 rock
+1FAB5 ; fully-qualified # 🪵 E13.0 wood
+1F6D6 ; fully-qualified # 🛖 E13.0 hut
+1F3D8 FE0F ; fully-qualified # 🏘️ E0.7 houses
+1F3D8 ; unqualified # 🏘 E0.7 houses
+1F3DA FE0F ; fully-qualified # 🏚️ E0.7 derelict house
+1F3DA ; unqualified # 🏚 E0.7 derelict house
+1F3E0 ; fully-qualified # 🏠 E0.6 house
+1F3E1 ; fully-qualified # 🏡 E0.6 house with garden
+1F3E2 ; fully-qualified # 🏢 E0.6 office building
+1F3E3 ; fully-qualified # 🏣 E0.6 Japanese post office
+1F3E4 ; fully-qualified # 🏤 E1.0 post office
+1F3E5 ; fully-qualified # 🏥 E0.6 hospital
+1F3E6 ; fully-qualified # 🏦 E0.6 bank
+1F3E8 ; fully-qualified # 🏨 E0.6 hotel
+1F3E9 ; fully-qualified # 🏩 E0.6 love hotel
+1F3EA ; fully-qualified # 🏪 E0.6 convenience store
+1F3EB ; fully-qualified # 🏫 E0.6 school
+1F3EC ; fully-qualified # 🏬 E0.6 department store
+1F3ED ; fully-qualified # 🏭 E0.6 factory
+1F3EF ; fully-qualified # 🏯 E0.6 Japanese castle
+1F3F0 ; fully-qualified # 🏰 E0.6 castle
+1F492 ; fully-qualified # 💒 E0.6 wedding
+1F5FC ; fully-qualified # 🗼 E0.6 Tokyo tower
+1F5FD ; fully-qualified # 🗽 E0.6 Statue of Liberty
# subgroup: place-religious
-26EA ; fully-qualified # ⛪ E0.6 church
-1F54C ; fully-qualified # 🕌 E1.0 mosque
-1F6D5 ; fully-qualified # 🛕 E12.0 hindu temple
-1F54D ; fully-qualified # 🕍 E1.0 synagogue
-26E9 FE0F ; fully-qualified # ⛩️ E0.7 shinto shrine
-26E9 ; unqualified # ⛩ E0.7 shinto shrine
-1F54B ; fully-qualified # 🕋 E1.0 kaaba
+26EA ; fully-qualified # ⛪ E0.6 church
+1F54C ; fully-qualified # 🕌 E1.0 mosque
+1F6D5 ; fully-qualified # 🛕 E12.0 hindu temple
+1F54D ; fully-qualified # 🕍 E1.0 synagogue
+26E9 FE0F ; fully-qualified # ⛩️ E0.7 shinto shrine
+26E9 ; unqualified # ⛩ E0.7 shinto shrine
+1F54B ; fully-qualified # 🕋 E1.0 kaaba
# subgroup: place-other
-26F2 ; fully-qualified # ⛲ E0.6 fountain
-26FA ; fully-qualified # ⛺ E0.6 tent
-1F301 ; fully-qualified # 🌁 E0.6 foggy
-1F303 ; fully-qualified # 🌃 E0.6 night with stars
-1F3D9 FE0F ; fully-qualified # 🏙️ E0.7 cityscape
-1F3D9 ; unqualified # 🏙 E0.7 cityscape
-1F304 ; fully-qualified # 🌄 E0.6 sunrise over mountains
-1F305 ; fully-qualified # 🌅 E0.6 sunrise
-1F306 ; fully-qualified # 🌆 E0.6 cityscape at dusk
-1F307 ; fully-qualified # 🌇 E0.6 sunset
-1F309 ; fully-qualified # 🌉 E0.6 bridge at night
-2668 FE0F ; fully-qualified # ♨️ E0.6 hot springs
-2668 ; unqualified # ♨ E0.6 hot springs
-1F3A0 ; fully-qualified # 🎠 E0.6 carousel horse
-1F3A1 ; fully-qualified # 🎡 E0.6 ferris wheel
-1F3A2 ; fully-qualified # 🎢 E0.6 roller coaster
-1F488 ; fully-qualified # 💈 E0.6 barber pole
-1F3AA ; fully-qualified # 🎪 E0.6 circus tent
+26F2 ; fully-qualified # ⛲ E0.6 fountain
+26FA ; fully-qualified # ⛺ E0.6 tent
+1F301 ; fully-qualified # 🌁 E0.6 foggy
+1F303 ; fully-qualified # 🌃 E0.6 night with stars
+1F3D9 FE0F ; fully-qualified # 🏙️ E0.7 cityscape
+1F3D9 ; unqualified # 🏙 E0.7 cityscape
+1F304 ; fully-qualified # 🌄 E0.6 sunrise over mountains
+1F305 ; fully-qualified # 🌅 E0.6 sunrise
+1F306 ; fully-qualified # 🌆 E0.6 cityscape at dusk
+1F307 ; fully-qualified # 🌇 E0.6 sunset
+1F309 ; fully-qualified # 🌉 E0.6 bridge at night
+2668 FE0F ; fully-qualified # ♨️ E0.6 hot springs
+2668 ; unqualified # ♨ E0.6 hot springs
+1F3A0 ; fully-qualified # 🎠 E0.6 carousel horse
+1F3A1 ; fully-qualified # 🎡 E0.6 ferris wheel
+1F3A2 ; fully-qualified # 🎢 E0.6 roller coaster
+1F488 ; fully-qualified # 💈 E0.6 barber pole
+1F3AA ; fully-qualified # 🎪 E0.6 circus tent
# subgroup: transport-ground
-1F682 ; fully-qualified # 🚂 E1.0 locomotive
-1F683 ; fully-qualified # 🚃 E0.6 railway car
-1F684 ; fully-qualified # 🚄 E0.6 high-speed train
-1F685 ; fully-qualified # 🚅 E0.6 bullet train
-1F686 ; fully-qualified # 🚆 E1.0 train
-1F687 ; fully-qualified # 🚇 E0.6 metro
-1F688 ; fully-qualified # 🚈 E1.0 light rail
-1F689 ; fully-qualified # 🚉 E0.6 station
-1F68A ; fully-qualified # 🚊 E1.0 tram
-1F69D ; fully-qualified # 🚝 E1.0 monorail
-1F69E ; fully-qualified # 🚞 E1.0 mountain railway
-1F68B ; fully-qualified # 🚋 E1.0 tram car
-1F68C ; fully-qualified # 🚌 E0.6 bus
-1F68D ; fully-qualified # 🚍 E0.7 oncoming bus
-1F68E ; fully-qualified # 🚎 E1.0 trolleybus
-1F690 ; fully-qualified # 🚐 E1.0 minibus
-1F691 ; fully-qualified # 🚑 E0.6 ambulance
-1F692 ; fully-qualified # 🚒 E0.6 fire engine
-1F693 ; fully-qualified # 🚓 E0.6 police car
-1F694 ; fully-qualified # 🚔 E0.7 oncoming police car
-1F695 ; fully-qualified # 🚕 E0.6 taxi
-1F696 ; fully-qualified # 🚖 E1.0 oncoming taxi
-1F697 ; fully-qualified # 🚗 E0.6 automobile
-1F698 ; fully-qualified # 🚘 E0.7 oncoming automobile
-1F699 ; fully-qualified # 🚙 E0.6 sport utility vehicle
-1F6FB ; fully-qualified # 🛻 E13.0 pickup truck
-1F69A ; fully-qualified # 🚚 E0.6 delivery truck
-1F69B ; fully-qualified # 🚛 E1.0 articulated lorry
-1F69C ; fully-qualified # 🚜 E1.0 tractor
-1F3CE FE0F ; fully-qualified # 🏎️ E0.7 racing car
-1F3CE ; unqualified # 🏎 E0.7 racing car
-1F3CD FE0F ; fully-qualified # 🏍️ E0.7 motorcycle
-1F3CD ; unqualified # 🏍 E0.7 motorcycle
-1F6F5 ; fully-qualified # 🛵 E3.0 motor scooter
-1F9BD ; fully-qualified # 🦽 E12.0 manual wheelchair
-1F9BC ; fully-qualified # 🦼 E12.0 motorized wheelchair
-1F6FA ; fully-qualified # 🛺 E12.0 auto rickshaw
-1F6B2 ; fully-qualified # 🚲 E0.6 bicycle
-1F6F4 ; fully-qualified # 🛴 E3.0 kick scooter
-1F6F9 ; fully-qualified # 🛹 E11.0 skateboard
-1F6FC ; fully-qualified # 🛼 E13.0 roller skate
-1F68F ; fully-qualified # 🚏 E0.6 bus stop
-1F6E3 FE0F ; fully-qualified # 🛣️ E0.7 motorway
-1F6E3 ; unqualified # 🛣 E0.7 motorway
-1F6E4 FE0F ; fully-qualified # 🛤️ E0.7 railway track
-1F6E4 ; unqualified # 🛤 E0.7 railway track
-1F6E2 FE0F ; fully-qualified # 🛢️ E0.7 oil drum
-1F6E2 ; unqualified # 🛢 E0.7 oil drum
-26FD ; fully-qualified # ⛽ E0.6 fuel pump
-1F6A8 ; fully-qualified # 🚨 E0.6 police car light
-1F6A5 ; fully-qualified # 🚥 E0.6 horizontal traffic light
-1F6A6 ; fully-qualified # 🚦 E1.0 vertical traffic light
-1F6D1 ; fully-qualified # 🛑 E3.0 stop sign
-1F6A7 ; fully-qualified # 🚧 E0.6 construction
+1F682 ; fully-qualified # 🚂 E1.0 locomotive
+1F683 ; fully-qualified # 🚃 E0.6 railway car
+1F684 ; fully-qualified # 🚄 E0.6 high-speed train
+1F685 ; fully-qualified # 🚅 E0.6 bullet train
+1F686 ; fully-qualified # 🚆 E1.0 train
+1F687 ; fully-qualified # 🚇 E0.6 metro
+1F688 ; fully-qualified # 🚈 E1.0 light rail
+1F689 ; fully-qualified # 🚉 E0.6 station
+1F68A ; fully-qualified # 🚊 E1.0 tram
+1F69D ; fully-qualified # 🚝 E1.0 monorail
+1F69E ; fully-qualified # 🚞 E1.0 mountain railway
+1F68B ; fully-qualified # 🚋 E1.0 tram car
+1F68C ; fully-qualified # 🚌 E0.6 bus
+1F68D ; fully-qualified # 🚍 E0.7 oncoming bus
+1F68E ; fully-qualified # 🚎 E1.0 trolleybus
+1F690 ; fully-qualified # 🚐 E1.0 minibus
+1F691 ; fully-qualified # 🚑 E0.6 ambulance
+1F692 ; fully-qualified # 🚒 E0.6 fire engine
+1F693 ; fully-qualified # 🚓 E0.6 police car
+1F694 ; fully-qualified # 🚔 E0.7 oncoming police car
+1F695 ; fully-qualified # 🚕 E0.6 taxi
+1F696 ; fully-qualified # 🚖 E1.0 oncoming taxi
+1F697 ; fully-qualified # 🚗 E0.6 automobile
+1F698 ; fully-qualified # 🚘 E0.7 oncoming automobile
+1F699 ; fully-qualified # 🚙 E0.6 sport utility vehicle
+1F6FB ; fully-qualified # 🛻 E13.0 pickup truck
+1F69A ; fully-qualified # 🚚 E0.6 delivery truck
+1F69B ; fully-qualified # 🚛 E1.0 articulated lorry
+1F69C ; fully-qualified # 🚜 E1.0 tractor
+1F3CE FE0F ; fully-qualified # 🏎️ E0.7 racing car
+1F3CE ; unqualified # 🏎 E0.7 racing car
+1F3CD FE0F ; fully-qualified # 🏍️ E0.7 motorcycle
+1F3CD ; unqualified # 🏍 E0.7 motorcycle
+1F6F5 ; fully-qualified # 🛵 E3.0 motor scooter
+1F9BD ; fully-qualified # 🦽 E12.0 manual wheelchair
+1F9BC ; fully-qualified # 🦼 E12.0 motorized wheelchair
+1F6FA ; fully-qualified # 🛺 E12.0 auto rickshaw
+1F6B2 ; fully-qualified # 🚲 E0.6 bicycle
+1F6F4 ; fully-qualified # 🛴 E3.0 kick scooter
+1F6F9 ; fully-qualified # 🛹 E11.0 skateboard
+1F6FC ; fully-qualified # 🛼 E13.0 roller skate
+1F68F ; fully-qualified # 🚏 E0.6 bus stop
+1F6E3 FE0F ; fully-qualified # 🛣️ E0.7 motorway
+1F6E3 ; unqualified # 🛣 E0.7 motorway
+1F6E4 FE0F ; fully-qualified # 🛤️ E0.7 railway track
+1F6E4 ; unqualified # 🛤 E0.7 railway track
+1F6E2 FE0F ; fully-qualified # 🛢️ E0.7 oil drum
+1F6E2 ; unqualified # 🛢 E0.7 oil drum
+26FD ; fully-qualified # ⛽ E0.6 fuel pump
+1F6A8 ; fully-qualified # 🚨 E0.6 police car light
+1F6A5 ; fully-qualified # 🚥 E0.6 horizontal traffic light
+1F6A6 ; fully-qualified # 🚦 E1.0 vertical traffic light
+1F6D1 ; fully-qualified # 🛑 E3.0 stop sign
+1F6A7 ; fully-qualified # 🚧 E0.6 construction
# subgroup: transport-water
-2693 ; fully-qualified # ⚓ E0.6 anchor
-26F5 ; fully-qualified # ⛵ E0.6 sailboat
-1F6F6 ; fully-qualified # 🛶 E3.0 canoe
-1F6A4 ; fully-qualified # 🚤 E0.6 speedboat
-1F6F3 FE0F ; fully-qualified # 🛳️ E0.7 passenger ship
-1F6F3 ; unqualified # 🛳 E0.7 passenger ship
-26F4 FE0F ; fully-qualified # ⛴️ E0.7 ferry
-26F4 ; unqualified # ⛴ E0.7 ferry
-1F6E5 FE0F ; fully-qualified # 🛥️ E0.7 motor boat
-1F6E5 ; unqualified # 🛥 E0.7 motor boat
-1F6A2 ; fully-qualified # 🚢 E0.6 ship
+2693 ; fully-qualified # ⚓ E0.6 anchor
+26F5 ; fully-qualified # ⛵ E0.6 sailboat
+1F6F6 ; fully-qualified # 🛶 E3.0 canoe
+1F6A4 ; fully-qualified # 🚤 E0.6 speedboat
+1F6F3 FE0F ; fully-qualified # 🛳️ E0.7 passenger ship
+1F6F3 ; unqualified # 🛳 E0.7 passenger ship
+26F4 FE0F ; fully-qualified # ⛴️ E0.7 ferry
+26F4 ; unqualified # ⛴ E0.7 ferry
+1F6E5 FE0F ; fully-qualified # 🛥️ E0.7 motor boat
+1F6E5 ; unqualified # 🛥 E0.7 motor boat
+1F6A2 ; fully-qualified # 🚢 E0.6 ship
# subgroup: transport-air
-2708 FE0F ; fully-qualified # ✈️ E0.6 airplane
-2708 ; unqualified # ✈ E0.6 airplane
-1F6E9 FE0F ; fully-qualified # 🛩️ E0.7 small airplane
-1F6E9 ; unqualified # 🛩 E0.7 small airplane
-1F6EB ; fully-qualified # 🛫 E1.0 airplane departure
-1F6EC ; fully-qualified # 🛬 E1.0 airplane arrival
-1FA82 ; fully-qualified # 🪂 E12.0 parachute
-1F4BA ; fully-qualified # 💺 E0.6 seat
-1F681 ; fully-qualified # 🚁 E1.0 helicopter
-1F69F ; fully-qualified # 🚟 E1.0 suspension railway
-1F6A0 ; fully-qualified # 🚠 E1.0 mountain cableway
-1F6A1 ; fully-qualified # 🚡 E1.0 aerial tramway
-1F6F0 FE0F ; fully-qualified # 🛰️ E0.7 satellite
-1F6F0 ; unqualified # 🛰 E0.7 satellite
-1F680 ; fully-qualified # 🚀 E0.6 rocket
-1F6F8 ; fully-qualified # 🛸 E5.0 flying saucer
+2708 FE0F ; fully-qualified # ✈️ E0.6 airplane
+2708 ; unqualified # ✈ E0.6 airplane
+1F6E9 FE0F ; fully-qualified # 🛩️ E0.7 small airplane
+1F6E9 ; unqualified # 🛩 E0.7 small airplane
+1F6EB ; fully-qualified # 🛫 E1.0 airplane departure
+1F6EC ; fully-qualified # 🛬 E1.0 airplane arrival
+1FA82 ; fully-qualified # 🪂 E12.0 parachute
+1F4BA ; fully-qualified # 💺 E0.6 seat
+1F681 ; fully-qualified # 🚁 E1.0 helicopter
+1F69F ; fully-qualified # 🚟 E1.0 suspension railway
+1F6A0 ; fully-qualified # 🚠 E1.0 mountain cableway
+1F6A1 ; fully-qualified # 🚡 E1.0 aerial tramway
+1F6F0 FE0F ; fully-qualified # 🛰️ E0.7 satellite
+1F6F0 ; unqualified # 🛰 E0.7 satellite
+1F680 ; fully-qualified # 🚀 E0.6 rocket
+1F6F8 ; fully-qualified # 🛸 E5.0 flying saucer
# subgroup: hotel
-1F6CE FE0F ; fully-qualified # 🛎️ E0.7 bellhop bell
-1F6CE ; unqualified # 🛎 E0.7 bellhop bell
-1F9F3 ; fully-qualified # 🧳 E11.0 luggage
+1F6CE FE0F ; fully-qualified # 🛎️ E0.7 bellhop bell
+1F6CE ; unqualified # 🛎 E0.7 bellhop bell
+1F9F3 ; fully-qualified # 🧳 E11.0 luggage
# subgroup: time
-231B ; fully-qualified # ⌛ E0.6 hourglass done
-23F3 ; fully-qualified # ⏳ E0.6 hourglass not done
-231A ; fully-qualified # ⌚ E0.6 watch
-23F0 ; fully-qualified # ⏰ E0.6 alarm clock
-23F1 FE0F ; fully-qualified # ⏱️ E1.0 stopwatch
-23F1 ; unqualified # ⏱ E1.0 stopwatch
-23F2 FE0F ; fully-qualified # ⏲️ E1.0 timer clock
-23F2 ; unqualified # ⏲ E1.0 timer clock
-1F570 FE0F ; fully-qualified # 🕰️ E0.7 mantelpiece clock
-1F570 ; unqualified # 🕰 E0.7 mantelpiece clock
-1F55B ; fully-qualified # 🕛 E0.6 twelve o’clock
-1F567 ; fully-qualified # 🕧 E0.7 twelve-thirty
-1F550 ; fully-qualified # 🕐 E0.6 one o’clock
-1F55C ; fully-qualified # 🕜 E0.7 one-thirty
-1F551 ; fully-qualified # 🕑 E0.6 two o’clock
-1F55D ; fully-qualified # 🕝 E0.7 two-thirty
-1F552 ; fully-qualified # 🕒 E0.6 three o’clock
-1F55E ; fully-qualified # 🕞 E0.7 three-thirty
-1F553 ; fully-qualified # 🕓 E0.6 four o’clock
-1F55F ; fully-qualified # 🕟 E0.7 four-thirty
-1F554 ; fully-qualified # 🕔 E0.6 five o’clock
-1F560 ; fully-qualified # 🕠 E0.7 five-thirty
-1F555 ; fully-qualified # 🕕 E0.6 six o’clock
-1F561 ; fully-qualified # 🕡 E0.7 six-thirty
-1F556 ; fully-qualified # 🕖 E0.6 seven o’clock
-1F562 ; fully-qualified # 🕢 E0.7 seven-thirty
-1F557 ; fully-qualified # 🕗 E0.6 eight o’clock
-1F563 ; fully-qualified # 🕣 E0.7 eight-thirty
-1F558 ; fully-qualified # 🕘 E0.6 nine o’clock
-1F564 ; fully-qualified # 🕤 E0.7 nine-thirty
-1F559 ; fully-qualified # 🕙 E0.6 ten o’clock
-1F565 ; fully-qualified # 🕥 E0.7 ten-thirty
-1F55A ; fully-qualified # 🕚 E0.6 eleven o’clock
-1F566 ; fully-qualified # 🕦 E0.7 eleven-thirty
+231B ; fully-qualified # ⌛ E0.6 hourglass done
+23F3 ; fully-qualified # ⏳ E0.6 hourglass not done
+231A ; fully-qualified # ⌚ E0.6 watch
+23F0 ; fully-qualified # ⏰ E0.6 alarm clock
+23F1 FE0F ; fully-qualified # ⏱️ E1.0 stopwatch
+23F1 ; unqualified # ⏱ E1.0 stopwatch
+23F2 FE0F ; fully-qualified # ⏲️ E1.0 timer clock
+23F2 ; unqualified # ⏲ E1.0 timer clock
+1F570 FE0F ; fully-qualified # 🕰️ E0.7 mantelpiece clock
+1F570 ; unqualified # 🕰 E0.7 mantelpiece clock
+1F55B ; fully-qualified # 🕛 E0.6 twelve o’clock
+1F567 ; fully-qualified # 🕧 E0.7 twelve-thirty
+1F550 ; fully-qualified # 🕐 E0.6 one o’clock
+1F55C ; fully-qualified # 🕜 E0.7 one-thirty
+1F551 ; fully-qualified # 🕑 E0.6 two o’clock
+1F55D ; fully-qualified # 🕝 E0.7 two-thirty
+1F552 ; fully-qualified # 🕒 E0.6 three o’clock
+1F55E ; fully-qualified # 🕞 E0.7 three-thirty
+1F553 ; fully-qualified # 🕓 E0.6 four o’clock
+1F55F ; fully-qualified # 🕟 E0.7 four-thirty
+1F554 ; fully-qualified # 🕔 E0.6 five o’clock
+1F560 ; fully-qualified # 🕠 E0.7 five-thirty
+1F555 ; fully-qualified # 🕕 E0.6 six o’clock
+1F561 ; fully-qualified # 🕡 E0.7 six-thirty
+1F556 ; fully-qualified # 🕖 E0.6 seven o’clock
+1F562 ; fully-qualified # 🕢 E0.7 seven-thirty
+1F557 ; fully-qualified # 🕗 E0.6 eight o’clock
+1F563 ; fully-qualified # 🕣 E0.7 eight-thirty
+1F558 ; fully-qualified # 🕘 E0.6 nine o’clock
+1F564 ; fully-qualified # 🕤 E0.7 nine-thirty
+1F559 ; fully-qualified # 🕙 E0.6 ten o’clock
+1F565 ; fully-qualified # 🕥 E0.7 ten-thirty
+1F55A ; fully-qualified # 🕚 E0.6 eleven o’clock
+1F566 ; fully-qualified # 🕦 E0.7 eleven-thirty
# subgroup: sky & weather
-1F311 ; fully-qualified # 🌑 E0.6 new moon
-1F312 ; fully-qualified # 🌒 E1.0 waxing crescent moon
-1F313 ; fully-qualified # 🌓 E0.6 first quarter moon
-1F314 ; fully-qualified # 🌔 E0.6 waxing gibbous moon
-1F315 ; fully-qualified # 🌕 E0.6 full moon
-1F316 ; fully-qualified # 🌖 E1.0 waning gibbous moon
-1F317 ; fully-qualified # 🌗 E1.0 last quarter moon
-1F318 ; fully-qualified # 🌘 E1.0 waning crescent moon
-1F319 ; fully-qualified # 🌙 E0.6 crescent moon
-1F31A ; fully-qualified # 🌚 E1.0 new moon face
-1F31B ; fully-qualified # 🌛 E0.6 first quarter moon face
-1F31C ; fully-qualified # 🌜 E0.7 last quarter moon face
-1F321 FE0F ; fully-qualified # 🌡️ E0.7 thermometer
-1F321 ; unqualified # 🌡 E0.7 thermometer
-2600 FE0F ; fully-qualified # ☀️ E0.6 sun
-2600 ; unqualified # ☀ E0.6 sun
-1F31D ; fully-qualified # 🌝 E1.0 full moon face
-1F31E ; fully-qualified # 🌞 E1.0 sun with face
-1FA90 ; fully-qualified # 🪐 E12.0 ringed planet
-2B50 ; fully-qualified # ⭐ E0.6 star
-1F31F ; fully-qualified # 🌟 E0.6 glowing star
-1F320 ; fully-qualified # 🌠 E0.6 shooting star
-1F30C ; fully-qualified # 🌌 E0.6 milky way
-2601 FE0F ; fully-qualified # ☁️ E0.6 cloud
-2601 ; unqualified # ☁ E0.6 cloud
-26C5 ; fully-qualified # ⛅ E0.6 sun behind cloud
-26C8 FE0F ; fully-qualified # ⛈️ E0.7 cloud with lightning and rain
-26C8 ; unqualified # ⛈ E0.7 cloud with lightning and rain
-1F324 FE0F ; fully-qualified # 🌤️ E0.7 sun behind small cloud
-1F324 ; unqualified # 🌤 E0.7 sun behind small cloud
-1F325 FE0F ; fully-qualified # 🌥️ E0.7 sun behind large cloud
-1F325 ; unqualified # 🌥 E0.7 sun behind large cloud
-1F326 FE0F ; fully-qualified # 🌦️ E0.7 sun behind rain cloud
-1F326 ; unqualified # 🌦 E0.7 sun behind rain cloud
-1F327 FE0F ; fully-qualified # 🌧️ E0.7 cloud with rain
-1F327 ; unqualified # 🌧 E0.7 cloud with rain
-1F328 FE0F ; fully-qualified # 🌨️ E0.7 cloud with snow
-1F328 ; unqualified # 🌨 E0.7 cloud with snow
-1F329 FE0F ; fully-qualified # 🌩️ E0.7 cloud with lightning
-1F329 ; unqualified # 🌩 E0.7 cloud with lightning
-1F32A FE0F ; fully-qualified # 🌪️ E0.7 tornado
-1F32A ; unqualified # 🌪 E0.7 tornado
-1F32B FE0F ; fully-qualified # 🌫️ E0.7 fog
-1F32B ; unqualified # 🌫 E0.7 fog
-1F32C FE0F ; fully-qualified # 🌬️ E0.7 wind face
-1F32C ; unqualified # 🌬 E0.7 wind face
-1F300 ; fully-qualified # 🌀 E0.6 cyclone
-1F308 ; fully-qualified # 🌈 E0.6 rainbow
-1F302 ; fully-qualified # 🌂 E0.6 closed umbrella
-2602 FE0F ; fully-qualified # ☂️ E0.7 umbrella
-2602 ; unqualified # ☂ E0.7 umbrella
-2614 ; fully-qualified # ☔ E0.6 umbrella with rain drops
-26F1 FE0F ; fully-qualified # ⛱️ E0.7 umbrella on ground
-26F1 ; unqualified # ⛱ E0.7 umbrella on ground
-26A1 ; fully-qualified # ⚡ E0.6 high voltage
-2744 FE0F ; fully-qualified # ❄️ E0.6 snowflake
-2744 ; unqualified # ❄ E0.6 snowflake
-2603 FE0F ; fully-qualified # ☃️ E0.7 snowman
-2603 ; unqualified # ☃ E0.7 snowman
-26C4 ; fully-qualified # ⛄ E0.6 snowman without snow
-2604 FE0F ; fully-qualified # ☄️ E1.0 comet
-2604 ; unqualified # ☄ E1.0 comet
-1F525 ; fully-qualified # 🔥 E0.6 fire
-1F4A7 ; fully-qualified # 💧 E0.6 droplet
-1F30A ; fully-qualified # 🌊 E0.6 water wave
+1F311 ; fully-qualified # 🌑 E0.6 new moon
+1F312 ; fully-qualified # 🌒 E1.0 waxing crescent moon
+1F313 ; fully-qualified # 🌓 E0.6 first quarter moon
+1F314 ; fully-qualified # 🌔 E0.6 waxing gibbous moon
+1F315 ; fully-qualified # 🌕 E0.6 full moon
+1F316 ; fully-qualified # 🌖 E1.0 waning gibbous moon
+1F317 ; fully-qualified # 🌗 E1.0 last quarter moon
+1F318 ; fully-qualified # 🌘 E1.0 waning crescent moon
+1F319 ; fully-qualified # 🌙 E0.6 crescent moon
+1F31A ; fully-qualified # 🌚 E1.0 new moon face
+1F31B ; fully-qualified # 🌛 E0.6 first quarter moon face
+1F31C ; fully-qualified # 🌜 E0.7 last quarter moon face
+1F321 FE0F ; fully-qualified # 🌡️ E0.7 thermometer
+1F321 ; unqualified # 🌡 E0.7 thermometer
+2600 FE0F ; fully-qualified # ☀️ E0.6 sun
+2600 ; unqualified # ☀ E0.6 sun
+1F31D ; fully-qualified # 🌝 E1.0 full moon face
+1F31E ; fully-qualified # 🌞 E1.0 sun with face
+1FA90 ; fully-qualified # 🪐 E12.0 ringed planet
+2B50 ; fully-qualified # ⭐ E0.6 star
+1F31F ; fully-qualified # 🌟 E0.6 glowing star
+1F320 ; fully-qualified # 🌠 E0.6 shooting star
+1F30C ; fully-qualified # 🌌 E0.6 milky way
+2601 FE0F ; fully-qualified # ☁️ E0.6 cloud
+2601 ; unqualified # ☁ E0.6 cloud
+26C5 ; fully-qualified # ⛅ E0.6 sun behind cloud
+26C8 FE0F ; fully-qualified # ⛈️ E0.7 cloud with lightning and rain
+26C8 ; unqualified # ⛈ E0.7 cloud with lightning and rain
+1F324 FE0F ; fully-qualified # 🌤️ E0.7 sun behind small cloud
+1F324 ; unqualified # 🌤 E0.7 sun behind small cloud
+1F325 FE0F ; fully-qualified # 🌥️ E0.7 sun behind large cloud
+1F325 ; unqualified # 🌥 E0.7 sun behind large cloud
+1F326 FE0F ; fully-qualified # 🌦️ E0.7 sun behind rain cloud
+1F326 ; unqualified # 🌦 E0.7 sun behind rain cloud
+1F327 FE0F ; fully-qualified # 🌧️ E0.7 cloud with rain
+1F327 ; unqualified # 🌧 E0.7 cloud with rain
+1F328 FE0F ; fully-qualified # 🌨️ E0.7 cloud with snow
+1F328 ; unqualified # 🌨 E0.7 cloud with snow
+1F329 FE0F ; fully-qualified # 🌩️ E0.7 cloud with lightning
+1F329 ; unqualified # 🌩 E0.7 cloud with lightning
+1F32A FE0F ; fully-qualified # 🌪️ E0.7 tornado
+1F32A ; unqualified # 🌪 E0.7 tornado
+1F32B FE0F ; fully-qualified # 🌫️ E0.7 fog
+1F32B ; unqualified # 🌫 E0.7 fog
+1F32C FE0F ; fully-qualified # 🌬️ E0.7 wind face
+1F32C ; unqualified # 🌬 E0.7 wind face
+1F300 ; fully-qualified # 🌀 E0.6 cyclone
+1F308 ; fully-qualified # 🌈 E0.6 rainbow
+1F302 ; fully-qualified # 🌂 E0.6 closed umbrella
+2602 FE0F ; fully-qualified # ☂️ E0.7 umbrella
+2602 ; unqualified # ☂ E0.7 umbrella
+2614 ; fully-qualified # ☔ E0.6 umbrella with rain drops
+26F1 FE0F ; fully-qualified # ⛱️ E0.7 umbrella on ground
+26F1 ; unqualified # ⛱ E0.7 umbrella on ground
+26A1 ; fully-qualified # ⚡ E0.6 high voltage
+2744 FE0F ; fully-qualified # ❄️ E0.6 snowflake
+2744 ; unqualified # ❄ E0.6 snowflake
+2603 FE0F ; fully-qualified # ☃️ E0.7 snowman
+2603 ; unqualified # ☃ E0.7 snowman
+26C4 ; fully-qualified # ⛄ E0.6 snowman without snow
+2604 FE0F ; fully-qualified # ☄️ E1.0 comet
+2604 ; unqualified # ☄ E1.0 comet
+1F525 ; fully-qualified # 🔥 E0.6 fire
+1F4A7 ; fully-qualified # 💧 E0.6 droplet
+1F30A ; fully-qualified # 🌊 E0.6 water wave
# Travel & Places subtotal: 264
# Travel & Places subtotal: 264 w/o modifiers
@@ -3381,109 +3803,109 @@
# group: Activities
# subgroup: event
-1F383 ; fully-qualified # 🎃 E0.6 jack-o-lantern
-1F384 ; fully-qualified # 🎄 E0.6 Christmas tree
-1F386 ; fully-qualified # 🎆 E0.6 fireworks
-1F387 ; fully-qualified # 🎇 E0.6 sparkler
-1F9E8 ; fully-qualified # 🧨 E11.0 firecracker
-2728 ; fully-qualified # ✨ E0.6 sparkles
-1F388 ; fully-qualified # 🎈 E0.6 balloon
-1F389 ; fully-qualified # 🎉 E0.6 party popper
-1F38A ; fully-qualified # 🎊 E0.6 confetti ball
-1F38B ; fully-qualified # 🎋 E0.6 tanabata tree
-1F38D ; fully-qualified # 🎍 E0.6 pine decoration
-1F38E ; fully-qualified # 🎎 E0.6 Japanese dolls
-1F38F ; fully-qualified # 🎏 E0.6 carp streamer
-1F390 ; fully-qualified # 🎐 E0.6 wind chime
-1F391 ; fully-qualified # 🎑 E0.6 moon viewing ceremony
-1F9E7 ; fully-qualified # 🧧 E11.0 red envelope
-1F380 ; fully-qualified # 🎀 E0.6 ribbon
-1F381 ; fully-qualified # 🎁 E0.6 wrapped gift
-1F397 FE0F ; fully-qualified # 🎗️ E0.7 reminder ribbon
-1F397 ; unqualified # 🎗 E0.7 reminder ribbon
-1F39F FE0F ; fully-qualified # 🎟️ E0.7 admission tickets
-1F39F ; unqualified # 🎟 E0.7 admission tickets
-1F3AB ; fully-qualified # 🎫 E0.6 ticket
+1F383 ; fully-qualified # 🎃 E0.6 jack-o-lantern
+1F384 ; fully-qualified # 🎄 E0.6 Christmas tree
+1F386 ; fully-qualified # 🎆 E0.6 fireworks
+1F387 ; fully-qualified # 🎇 E0.6 sparkler
+1F9E8 ; fully-qualified # 🧨 E11.0 firecracker
+2728 ; fully-qualified # ✨ E0.6 sparkles
+1F388 ; fully-qualified # 🎈 E0.6 balloon
+1F389 ; fully-qualified # 🎉 E0.6 party popper
+1F38A ; fully-qualified # 🎊 E0.6 confetti ball
+1F38B ; fully-qualified # 🎋 E0.6 tanabata tree
+1F38D ; fully-qualified # 🎍 E0.6 pine decoration
+1F38E ; fully-qualified # 🎎 E0.6 Japanese dolls
+1F38F ; fully-qualified # 🎏 E0.6 carp streamer
+1F390 ; fully-qualified # 🎐 E0.6 wind chime
+1F391 ; fully-qualified # 🎑 E0.6 moon viewing ceremony
+1F9E7 ; fully-qualified # 🧧 E11.0 red envelope
+1F380 ; fully-qualified # 🎀 E0.6 ribbon
+1F381 ; fully-qualified # 🎁 E0.6 wrapped gift
+1F397 FE0F ; fully-qualified # 🎗️ E0.7 reminder ribbon
+1F397 ; unqualified # 🎗 E0.7 reminder ribbon
+1F39F FE0F ; fully-qualified # 🎟️ E0.7 admission tickets
+1F39F ; unqualified # 🎟 E0.7 admission tickets
+1F3AB ; fully-qualified # 🎫 E0.6 ticket
# subgroup: award-medal
-1F396 FE0F ; fully-qualified # 🎖️ E0.7 military medal
-1F396 ; unqualified # 🎖 E0.7 military medal
-1F3C6 ; fully-qualified # 🏆 E0.6 trophy
-1F3C5 ; fully-qualified # 🏅 E1.0 sports medal
-1F947 ; fully-qualified # 🥇 E3.0 1st place medal
-1F948 ; fully-qualified # 🥈 E3.0 2nd place medal
-1F949 ; fully-qualified # 🥉 E3.0 3rd place medal
+1F396 FE0F ; fully-qualified # 🎖️ E0.7 military medal
+1F396 ; unqualified # 🎖 E0.7 military medal
+1F3C6 ; fully-qualified # 🏆 E0.6 trophy
+1F3C5 ; fully-qualified # 🏅 E1.0 sports medal
+1F947 ; fully-qualified # 🥇 E3.0 1st place medal
+1F948 ; fully-qualified # 🥈 E3.0 2nd place medal
+1F949 ; fully-qualified # 🥉 E3.0 3rd place medal
# subgroup: sport
-26BD ; fully-qualified # ⚽ E0.6 soccer ball
-26BE ; fully-qualified # ⚾ E0.6 baseball
-1F94E ; fully-qualified # 🥎 E11.0 softball
-1F3C0 ; fully-qualified # 🏀 E0.6 basketball
-1F3D0 ; fully-qualified # 🏐 E1.0 volleyball
-1F3C8 ; fully-qualified # 🏈 E0.6 american football
-1F3C9 ; fully-qualified # 🏉 E1.0 rugby football
-1F3BE ; fully-qualified # 🎾 E0.6 tennis
-1F94F ; fully-qualified # 🥏 E11.0 flying disc
-1F3B3 ; fully-qualified # 🎳 E0.6 bowling
-1F3CF ; fully-qualified # 🏏 E1.0 cricket game
-1F3D1 ; fully-qualified # 🏑 E1.0 field hockey
-1F3D2 ; fully-qualified # 🏒 E1.0 ice hockey
-1F94D ; fully-qualified # 🥍 E11.0 lacrosse
-1F3D3 ; fully-qualified # 🏓 E1.0 ping pong
-1F3F8 ; fully-qualified # 🏸 E1.0 badminton
-1F94A ; fully-qualified # 🥊 E3.0 boxing glove
-1F94B ; fully-qualified # 🥋 E3.0 martial arts uniform
-1F945 ; fully-qualified # 🥅 E3.0 goal net
-26F3 ; fully-qualified # ⛳ E0.6 flag in hole
-26F8 FE0F ; fully-qualified # ⛸️ E0.7 ice skate
-26F8 ; unqualified # ⛸ E0.7 ice skate
-1F3A3 ; fully-qualified # 🎣 E0.6 fishing pole
-1F93F ; fully-qualified # 🤿 E12.0 diving mask
-1F3BD ; fully-qualified # 🎽 E0.6 running shirt
-1F3BF ; fully-qualified # 🎿 E0.6 skis
-1F6F7 ; fully-qualified # 🛷 E5.0 sled
-1F94C ; fully-qualified # 🥌 E5.0 curling stone
+26BD ; fully-qualified # ⚽ E0.6 soccer ball
+26BE ; fully-qualified # ⚾ E0.6 baseball
+1F94E ; fully-qualified # 🥎 E11.0 softball
+1F3C0 ; fully-qualified # 🏀 E0.6 basketball
+1F3D0 ; fully-qualified # 🏐 E1.0 volleyball
+1F3C8 ; fully-qualified # 🏈 E0.6 american football
+1F3C9 ; fully-qualified # 🏉 E1.0 rugby football
+1F3BE ; fully-qualified # 🎾 E0.6 tennis
+1F94F ; fully-qualified # 🥏 E11.0 flying disc
+1F3B3 ; fully-qualified # 🎳 E0.6 bowling
+1F3CF ; fully-qualified # 🏏 E1.0 cricket game
+1F3D1 ; fully-qualified # 🏑 E1.0 field hockey
+1F3D2 ; fully-qualified # 🏒 E1.0 ice hockey
+1F94D ; fully-qualified # 🥍 E11.0 lacrosse
+1F3D3 ; fully-qualified # 🏓 E1.0 ping pong
+1F3F8 ; fully-qualified # 🏸 E1.0 badminton
+1F94A ; fully-qualified # 🥊 E3.0 boxing glove
+1F94B ; fully-qualified # 🥋 E3.0 martial arts uniform
+1F945 ; fully-qualified # 🥅 E3.0 goal net
+26F3 ; fully-qualified # ⛳ E0.6 flag in hole
+26F8 FE0F ; fully-qualified # ⛸️ E0.7 ice skate
+26F8 ; unqualified # ⛸ E0.7 ice skate
+1F3A3 ; fully-qualified # 🎣 E0.6 fishing pole
+1F93F ; fully-qualified # 🤿 E12.0 diving mask
+1F3BD ; fully-qualified # 🎽 E0.6 running shirt
+1F3BF ; fully-qualified # 🎿 E0.6 skis
+1F6F7 ; fully-qualified # 🛷 E5.0 sled
+1F94C ; fully-qualified # 🥌 E5.0 curling stone
# subgroup: game
-1F3AF ; fully-qualified # 🎯 E0.6 direct hit
-1FA80 ; fully-qualified # 🪀 E12.0 yo-yo
-1FA81 ; fully-qualified # 🪁 E12.0 kite
-1F3B1 ; fully-qualified # 🎱 E0.6 pool 8 ball
-1F52E ; fully-qualified # 🔮 E0.6 crystal ball
-1FA84 ; fully-qualified # 🪄 E13.0 magic wand
-1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet
-1F3AE ; fully-qualified # 🎮 E0.6 video game
-1F579 FE0F ; fully-qualified # 🕹️ E0.7 joystick
-1F579 ; unqualified # 🕹 E0.7 joystick
-1F3B0 ; fully-qualified # 🎰 E0.6 slot machine
-1F3B2 ; fully-qualified # 🎲 E0.6 game die
-1F9E9 ; fully-qualified # 🧩 E11.0 puzzle piece
-1F9F8 ; fully-qualified # 🧸 E11.0 teddy bear
-1FA85 ; fully-qualified # 🪅 E13.0 piñata
-1FA86 ; fully-qualified # 🪆 E13.0 nesting dolls
-2660 FE0F ; fully-qualified # ♠️ E0.6 spade suit
-2660 ; unqualified # ♠ E0.6 spade suit
-2665 FE0F ; fully-qualified # ♥️ E0.6 heart suit
-2665 ; unqualified # ♥ E0.6 heart suit
-2666 FE0F ; fully-qualified # ♦️ E0.6 diamond suit
-2666 ; unqualified # ♦ E0.6 diamond suit
-2663 FE0F ; fully-qualified # ♣️ E0.6 club suit
-2663 ; unqualified # ♣ E0.6 club suit
-265F FE0F ; fully-qualified # ♟️ E11.0 chess pawn
-265F ; unqualified # ♟ E11.0 chess pawn
-1F0CF ; fully-qualified # 🃏 E0.6 joker
-1F004 ; fully-qualified # 🀄 E0.6 mahjong red dragon
-1F3B4 ; fully-qualified # 🎴 E0.6 flower playing cards
+1F3AF ; fully-qualified # 🎯 E0.6 bullseye
+1FA80 ; fully-qualified # 🪀 E12.0 yo-yo
+1FA81 ; fully-qualified # 🪁 E12.0 kite
+1F3B1 ; fully-qualified # 🎱 E0.6 pool 8 ball
+1F52E ; fully-qualified # 🔮 E0.6 crystal ball
+1FA84 ; fully-qualified # 🪄 E13.0 magic wand
+1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet
+1F3AE ; fully-qualified # 🎮 E0.6 video game
+1F579 FE0F ; fully-qualified # 🕹️ E0.7 joystick
+1F579 ; unqualified # 🕹 E0.7 joystick
+1F3B0 ; fully-qualified # 🎰 E0.6 slot machine
+1F3B2 ; fully-qualified # 🎲 E0.6 game die
+1F9E9 ; fully-qualified # 🧩 E11.0 puzzle piece
+1F9F8 ; fully-qualified # 🧸 E11.0 teddy bear
+1FA85 ; fully-qualified # 🪅 E13.0 piñata
+1FA86 ; fully-qualified # 🪆 E13.0 nesting dolls
+2660 FE0F ; fully-qualified # ♠️ E0.6 spade suit
+2660 ; unqualified # ♠ E0.6 spade suit
+2665 FE0F ; fully-qualified # ♥️ E0.6 heart suit
+2665 ; unqualified # ♥ E0.6 heart suit
+2666 FE0F ; fully-qualified # ♦️ E0.6 diamond suit
+2666 ; unqualified # ♦ E0.6 diamond suit
+2663 FE0F ; fully-qualified # ♣️ E0.6 club suit
+2663 ; unqualified # ♣ E0.6 club suit
+265F FE0F ; fully-qualified # ♟️ E11.0 chess pawn
+265F ; unqualified # ♟ E11.0 chess pawn
+1F0CF ; fully-qualified # 🃏 E0.6 joker
+1F004 ; fully-qualified # 🀄 E0.6 mahjong red dragon
+1F3B4 ; fully-qualified # 🎴 E0.6 flower playing cards
# subgroup: arts & crafts
-1F3AD ; fully-qualified # 🎭 E0.6 performing arts
-1F5BC FE0F ; fully-qualified # 🖼️ E0.7 framed picture
-1F5BC ; unqualified # 🖼 E0.7 framed picture
-1F3A8 ; fully-qualified # 🎨 E0.6 artist palette
-1F9F5 ; fully-qualified # 🧵 E11.0 thread
-1FAA1 ; fully-qualified # 🪡 E13.0 sewing needle
-1F9F6 ; fully-qualified # 🧶 E11.0 yarn
-1FAA2 ; fully-qualified # 🪢 E13.0 knot
+1F3AD ; fully-qualified # 🎭 E0.6 performing arts
+1F5BC FE0F ; fully-qualified # 🖼️ E0.7 framed picture
+1F5BC ; unqualified # 🖼 E0.7 framed picture
+1F3A8 ; fully-qualified # 🎨 E0.6 artist palette
+1F9F5 ; fully-qualified # 🧵 E11.0 thread
+1FAA1 ; fully-qualified # 🪡 E13.0 sewing needle
+1F9F6 ; fully-qualified # 🧶 E11.0 yarn
+1FAA2 ; fully-qualified # 🪢 E13.0 knot
# Activities subtotal: 95
# Activities subtotal: 95 w/o modifiers
@@ -3491,339 +3913,339 @@
# group: Objects
# subgroup: clothing
-1F453 ; fully-qualified # 👓 E0.6 glasses
-1F576 FE0F ; fully-qualified # 🕶️ E0.7 sunglasses
-1F576 ; unqualified # 🕶 E0.7 sunglasses
-1F97D ; fully-qualified # 🥽 E11.0 goggles
-1F97C ; fully-qualified # 🥼 E11.0 lab coat
-1F9BA ; fully-qualified # 🦺 E12.0 safety vest
-1F454 ; fully-qualified # 👔 E0.6 necktie
-1F455 ; fully-qualified # 👕 E0.6 t-shirt
-1F456 ; fully-qualified # 👖 E0.6 jeans
-1F9E3 ; fully-qualified # 🧣 E5.0 scarf
-1F9E4 ; fully-qualified # 🧤 E5.0 gloves
-1F9E5 ; fully-qualified # 🧥 E5.0 coat
-1F9E6 ; fully-qualified # 🧦 E5.0 socks
-1F457 ; fully-qualified # 👗 E0.6 dress
-1F458 ; fully-qualified # 👘 E0.6 kimono
-1F97B ; fully-qualified # 🥻 E12.0 sari
-1FA71 ; fully-qualified # 🩱 E12.0 one-piece swimsuit
-1FA72 ; fully-qualified # 🩲 E12.0 briefs
-1FA73 ; fully-qualified # 🩳 E12.0 shorts
-1F459 ; fully-qualified # 👙 E0.6 bikini
-1F45A ; fully-qualified # 👚 E0.6 woman’s clothes
-1F45B ; fully-qualified # 👛 E0.6 purse
-1F45C ; fully-qualified # 👜 E0.6 handbag
-1F45D ; fully-qualified # 👝 E0.6 clutch bag
-1F6CD FE0F ; fully-qualified # 🛍️ E0.7 shopping bags
-1F6CD ; unqualified # 🛍 E0.7 shopping bags
-1F392 ; fully-qualified # 🎒 E0.6 backpack
-1FA74 ; fully-qualified # 🩴 E13.0 thong sandal
-1F45E ; fully-qualified # 👞 E0.6 man’s shoe
-1F45F ; fully-qualified # 👟 E0.6 running shoe
-1F97E ; fully-qualified # 🥾 E11.0 hiking boot
-1F97F ; fully-qualified # 🥿 E11.0 flat shoe
-1F460 ; fully-qualified # 👠 E0.6 high-heeled shoe
-1F461 ; fully-qualified # 👡 E0.6 woman’s sandal
-1FA70 ; fully-qualified # 🩰 E12.0 ballet shoes
-1F462 ; fully-qualified # 👢 E0.6 woman’s boot
-1F451 ; fully-qualified # 👑 E0.6 crown
-1F452 ; fully-qualified # 👒 E0.6 woman’s hat
-1F3A9 ; fully-qualified # 🎩 E0.6 top hat
-1F393 ; fully-qualified # 🎓 E0.6 graduation cap
-1F9E2 ; fully-qualified # 🧢 E5.0 billed cap
-1FA96 ; fully-qualified # 🪖 E13.0 military helmet
-26D1 FE0F ; fully-qualified # ⛑️ E0.7 rescue worker’s helmet
-26D1 ; unqualified # ⛑ E0.7 rescue worker’s helmet
-1F4FF ; fully-qualified # 📿 E1.0 prayer beads
-1F484 ; fully-qualified # 💄 E0.6 lipstick
-1F48D ; fully-qualified # 💍 E0.6 ring
-1F48E ; fully-qualified # 💎 E0.6 gem stone
+1F453 ; fully-qualified # 👓 E0.6 glasses
+1F576 FE0F ; fully-qualified # 🕶️ E0.7 sunglasses
+1F576 ; unqualified # 🕶 E0.7 sunglasses
+1F97D ; fully-qualified # 🥽 E11.0 goggles
+1F97C ; fully-qualified # 🥼 E11.0 lab coat
+1F9BA ; fully-qualified # 🦺 E12.0 safety vest
+1F454 ; fully-qualified # 👔 E0.6 necktie
+1F455 ; fully-qualified # 👕 E0.6 t-shirt
+1F456 ; fully-qualified # 👖 E0.6 jeans
+1F9E3 ; fully-qualified # 🧣 E5.0 scarf
+1F9E4 ; fully-qualified # 🧤 E5.0 gloves
+1F9E5 ; fully-qualified # 🧥 E5.0 coat
+1F9E6 ; fully-qualified # 🧦 E5.0 socks
+1F457 ; fully-qualified # 👗 E0.6 dress
+1F458 ; fully-qualified # 👘 E0.6 kimono
+1F97B ; fully-qualified # 🥻 E12.0 sari
+1FA71 ; fully-qualified # 🩱 E12.0 one-piece swimsuit
+1FA72 ; fully-qualified # 🩲 E12.0 briefs
+1FA73 ; fully-qualified # 🩳 E12.0 shorts
+1F459 ; fully-qualified # 👙 E0.6 bikini
+1F45A ; fully-qualified # 👚 E0.6 woman’s clothes
+1F45B ; fully-qualified # 👛 E0.6 purse
+1F45C ; fully-qualified # 👜 E0.6 handbag
+1F45D ; fully-qualified # 👝 E0.6 clutch bag
+1F6CD FE0F ; fully-qualified # 🛍️ E0.7 shopping bags
+1F6CD ; unqualified # 🛍 E0.7 shopping bags
+1F392 ; fully-qualified # 🎒 E0.6 backpack
+1FA74 ; fully-qualified # 🩴 E13.0 thong sandal
+1F45E ; fully-qualified # 👞 E0.6 man’s shoe
+1F45F ; fully-qualified # 👟 E0.6 running shoe
+1F97E ; fully-qualified # 🥾 E11.0 hiking boot
+1F97F ; fully-qualified # 🥿 E11.0 flat shoe
+1F460 ; fully-qualified # 👠 E0.6 high-heeled shoe
+1F461 ; fully-qualified # 👡 E0.6 woman’s sandal
+1FA70 ; fully-qualified # 🩰 E12.0 ballet shoes
+1F462 ; fully-qualified # 👢 E0.6 woman’s boot
+1F451 ; fully-qualified # 👑 E0.6 crown
+1F452 ; fully-qualified # 👒 E0.6 woman’s hat
+1F3A9 ; fully-qualified # 🎩 E0.6 top hat
+1F393 ; fully-qualified # 🎓 E0.6 graduation cap
+1F9E2 ; fully-qualified # 🧢 E5.0 billed cap
+1FA96 ; fully-qualified # 🪖 E13.0 military helmet
+26D1 FE0F ; fully-qualified # ⛑️ E0.7 rescue worker’s helmet
+26D1 ; unqualified # ⛑ E0.7 rescue worker’s helmet
+1F4FF ; fully-qualified # 📿 E1.0 prayer beads
+1F484 ; fully-qualified # 💄 E0.6 lipstick
+1F48D ; fully-qualified # 💍 E0.6 ring
+1F48E ; fully-qualified # 💎 E0.6 gem stone
# subgroup: sound
-1F507 ; fully-qualified # 🔇 E1.0 muted speaker
-1F508 ; fully-qualified # 🔈 E0.7 speaker low volume
-1F509 ; fully-qualified # 🔉 E1.0 speaker medium volume
-1F50A ; fully-qualified # 🔊 E0.6 speaker high volume
-1F4E2 ; fully-qualified # 📢 E0.6 loudspeaker
-1F4E3 ; fully-qualified # 📣 E0.6 megaphone
-1F4EF ; fully-qualified # 📯 E1.0 postal horn
-1F514 ; fully-qualified # 🔔 E0.6 bell
-1F515 ; fully-qualified # 🔕 E1.0 bell with slash
+1F507 ; fully-qualified # 🔇 E1.0 muted speaker
+1F508 ; fully-qualified # 🔈 E0.7 speaker low volume
+1F509 ; fully-qualified # 🔉 E1.0 speaker medium volume
+1F50A ; fully-qualified # 🔊 E0.6 speaker high volume
+1F4E2 ; fully-qualified # 📢 E0.6 loudspeaker
+1F4E3 ; fully-qualified # 📣 E0.6 megaphone
+1F4EF ; fully-qualified # 📯 E1.0 postal horn
+1F514 ; fully-qualified # 🔔 E0.6 bell
+1F515 ; fully-qualified # 🔕 E1.0 bell with slash
# subgroup: music
-1F3BC ; fully-qualified # 🎼 E0.6 musical score
-1F3B5 ; fully-qualified # 🎵 E0.6 musical note
-1F3B6 ; fully-qualified # 🎶 E0.6 musical notes
-1F399 FE0F ; fully-qualified # 🎙️ E0.7 studio microphone
-1F399 ; unqualified # 🎙 E0.7 studio microphone
-1F39A FE0F ; fully-qualified # 🎚️ E0.7 level slider
-1F39A ; unqualified # 🎚 E0.7 level slider
-1F39B FE0F ; fully-qualified # 🎛️ E0.7 control knobs
-1F39B ; unqualified # 🎛 E0.7 control knobs
-1F3A4 ; fully-qualified # 🎤 E0.6 microphone
-1F3A7 ; fully-qualified # 🎧 E0.6 headphone
-1F4FB ; fully-qualified # 📻 E0.6 radio
+1F3BC ; fully-qualified # 🎼 E0.6 musical score
+1F3B5 ; fully-qualified # 🎵 E0.6 musical note
+1F3B6 ; fully-qualified # 🎶 E0.6 musical notes
+1F399 FE0F ; fully-qualified # 🎙️ E0.7 studio microphone
+1F399 ; unqualified # 🎙 E0.7 studio microphone
+1F39A FE0F ; fully-qualified # 🎚️ E0.7 level slider
+1F39A ; unqualified # 🎚 E0.7 level slider
+1F39B FE0F ; fully-qualified # 🎛️ E0.7 control knobs
+1F39B ; unqualified # 🎛 E0.7 control knobs
+1F3A4 ; fully-qualified # 🎤 E0.6 microphone
+1F3A7 ; fully-qualified # 🎧 E0.6 headphone
+1F4FB ; fully-qualified # 📻 E0.6 radio
# subgroup: musical-instrument
-1F3B7 ; fully-qualified # 🎷 E0.6 saxophone
-1FA97 ; fully-qualified # 🪗 E13.0 accordion
-1F3B8 ; fully-qualified # 🎸 E0.6 guitar
-1F3B9 ; fully-qualified # 🎹 E0.6 musical keyboard
-1F3BA ; fully-qualified # 🎺 E0.6 trumpet
-1F3BB ; fully-qualified # 🎻 E0.6 violin
-1FA95 ; fully-qualified # 🪕 E12.0 banjo
-1F941 ; fully-qualified # 🥁 E3.0 drum
-1FA98 ; fully-qualified # 🪘 E13.0 long drum
+1F3B7 ; fully-qualified # 🎷 E0.6 saxophone
+1FA97 ; fully-qualified # 🪗 E13.0 accordion
+1F3B8 ; fully-qualified # 🎸 E0.6 guitar
+1F3B9 ; fully-qualified # 🎹 E0.6 musical keyboard
+1F3BA ; fully-qualified # 🎺 E0.6 trumpet
+1F3BB ; fully-qualified # 🎻 E0.6 violin
+1FA95 ; fully-qualified # 🪕 E12.0 banjo
+1F941 ; fully-qualified # 🥁 E3.0 drum
+1FA98 ; fully-qualified # 🪘 E13.0 long drum
# subgroup: phone
-1F4F1 ; fully-qualified # 📱 E0.6 mobile phone
-1F4F2 ; fully-qualified # 📲 E0.6 mobile phone with arrow
-260E FE0F ; fully-qualified # ☎️ E0.6 telephone
-260E ; unqualified # ☎ E0.6 telephone
-1F4DE ; fully-qualified # 📞 E0.6 telephone receiver
-1F4DF ; fully-qualified # 📟 E0.6 pager
-1F4E0 ; fully-qualified # 📠 E0.6 fax machine
+1F4F1 ; fully-qualified # 📱 E0.6 mobile phone
+1F4F2 ; fully-qualified # 📲 E0.6 mobile phone with arrow
+260E FE0F ; fully-qualified # ☎️ E0.6 telephone
+260E ; unqualified # ☎ E0.6 telephone
+1F4DE ; fully-qualified # 📞 E0.6 telephone receiver
+1F4DF ; fully-qualified # 📟 E0.6 pager
+1F4E0 ; fully-qualified # 📠 E0.6 fax machine
# subgroup: computer
-1F50B ; fully-qualified # 🔋 E0.6 battery
-1F50C ; fully-qualified # 🔌 E0.6 electric plug
-1F4BB ; fully-qualified # 💻 E0.6 laptop
-1F5A5 FE0F ; fully-qualified # 🖥️ E0.7 desktop computer
-1F5A5 ; unqualified # 🖥 E0.7 desktop computer
-1F5A8 FE0F ; fully-qualified # 🖨️ E0.7 printer
-1F5A8 ; unqualified # 🖨 E0.7 printer
-2328 FE0F ; fully-qualified # ⌨️ E1.0 keyboard
-2328 ; unqualified # ⌨ E1.0 keyboard
-1F5B1 FE0F ; fully-qualified # 🖱️ E0.7 computer mouse
-1F5B1 ; unqualified # 🖱 E0.7 computer mouse
-1F5B2 FE0F ; fully-qualified # 🖲️ E0.7 trackball
-1F5B2 ; unqualified # 🖲 E0.7 trackball
-1F4BD ; fully-qualified # 💽 E0.6 computer disk
-1F4BE ; fully-qualified # 💾 E0.6 floppy disk
-1F4BF ; fully-qualified # 💿 E0.6 optical disk
-1F4C0 ; fully-qualified # 📀 E0.6 dvd
-1F9EE ; fully-qualified # 🧮 E11.0 abacus
+1F50B ; fully-qualified # 🔋 E0.6 battery
+1F50C ; fully-qualified # 🔌 E0.6 electric plug
+1F4BB ; fully-qualified # 💻 E0.6 laptop
+1F5A5 FE0F ; fully-qualified # 🖥️ E0.7 desktop computer
+1F5A5 ; unqualified # 🖥 E0.7 desktop computer
+1F5A8 FE0F ; fully-qualified # 🖨️ E0.7 printer
+1F5A8 ; unqualified # 🖨 E0.7 printer
+2328 FE0F ; fully-qualified # ⌨️ E1.0 keyboard
+2328 ; unqualified # ⌨ E1.0 keyboard
+1F5B1 FE0F ; fully-qualified # 🖱️ E0.7 computer mouse
+1F5B1 ; unqualified # 🖱 E0.7 computer mouse
+1F5B2 FE0F ; fully-qualified # 🖲️ E0.7 trackball
+1F5B2 ; unqualified # 🖲 E0.7 trackball
+1F4BD ; fully-qualified # 💽 E0.6 computer disk
+1F4BE ; fully-qualified # 💾 E0.6 floppy disk
+1F4BF ; fully-qualified # 💿 E0.6 optical disk
+1F4C0 ; fully-qualified # 📀 E0.6 dvd
+1F9EE ; fully-qualified # 🧮 E11.0 abacus
# subgroup: light & video
-1F3A5 ; fully-qualified # 🎥 E0.6 movie camera
-1F39E FE0F ; fully-qualified # 🎞️ E0.7 film frames
-1F39E ; unqualified # 🎞 E0.7 film frames
-1F4FD FE0F ; fully-qualified # 📽️ E0.7 film projector
-1F4FD ; unqualified # 📽 E0.7 film projector
-1F3AC ; fully-qualified # 🎬 E0.6 clapper board
-1F4FA ; fully-qualified # 📺 E0.6 television
-1F4F7 ; fully-qualified # 📷 E0.6 camera
-1F4F8 ; fully-qualified # 📸 E1.0 camera with flash
-1F4F9 ; fully-qualified # 📹 E0.6 video camera
-1F4FC ; fully-qualified # 📼 E0.6 videocassette
-1F50D ; fully-qualified # 🔍 E0.6 magnifying glass tilted left
-1F50E ; fully-qualified # 🔎 E0.6 magnifying glass tilted right
-1F56F FE0F ; fully-qualified # 🕯️ E0.7 candle
-1F56F ; unqualified # 🕯 E0.7 candle
-1F4A1 ; fully-qualified # 💡 E0.6 light bulb
-1F526 ; fully-qualified # 🔦 E0.6 flashlight
-1F3EE ; fully-qualified # 🏮 E0.6 red paper lantern
-1FA94 ; fully-qualified # 🪔 E12.0 diya lamp
+1F3A5 ; fully-qualified # 🎥 E0.6 movie camera
+1F39E FE0F ; fully-qualified # 🎞️ E0.7 film frames
+1F39E ; unqualified # 🎞 E0.7 film frames
+1F4FD FE0F ; fully-qualified # 📽️ E0.7 film projector
+1F4FD ; unqualified # 📽 E0.7 film projector
+1F3AC ; fully-qualified # 🎬 E0.6 clapper board
+1F4FA ; fully-qualified # 📺 E0.6 television
+1F4F7 ; fully-qualified # 📷 E0.6 camera
+1F4F8 ; fully-qualified # 📸 E1.0 camera with flash
+1F4F9 ; fully-qualified # 📹 E0.6 video camera
+1F4FC ; fully-qualified # 📼 E0.6 videocassette
+1F50D ; fully-qualified # 🔍 E0.6 magnifying glass tilted left
+1F50E ; fully-qualified # 🔎 E0.6 magnifying glass tilted right
+1F56F FE0F ; fully-qualified # 🕯️ E0.7 candle
+1F56F ; unqualified # 🕯 E0.7 candle
+1F4A1 ; fully-qualified # 💡 E0.6 light bulb
+1F526 ; fully-qualified # 🔦 E0.6 flashlight
+1F3EE ; fully-qualified # 🏮 E0.6 red paper lantern
+1FA94 ; fully-qualified # 🪔 E12.0 diya lamp
# subgroup: book-paper
-1F4D4 ; fully-qualified # 📔 E0.6 notebook with decorative cover
-1F4D5 ; fully-qualified # 📕 E0.6 closed book
-1F4D6 ; fully-qualified # 📖 E0.6 open book
-1F4D7 ; fully-qualified # 📗 E0.6 green book
-1F4D8 ; fully-qualified # 📘 E0.6 blue book
-1F4D9 ; fully-qualified # 📙 E0.6 orange book
-1F4DA ; fully-qualified # 📚 E0.6 books
-1F4D3 ; fully-qualified # 📓 E0.6 notebook
-1F4D2 ; fully-qualified # 📒 E0.6 ledger
-1F4C3 ; fully-qualified # 📃 E0.6 page with curl
-1F4DC ; fully-qualified # 📜 E0.6 scroll
-1F4C4 ; fully-qualified # 📄 E0.6 page facing up
-1F4F0 ; fully-qualified # 📰 E0.6 newspaper
-1F5DE FE0F ; fully-qualified # 🗞️ E0.7 rolled-up newspaper
-1F5DE ; unqualified # 🗞 E0.7 rolled-up newspaper
-1F4D1 ; fully-qualified # 📑 E0.6 bookmark tabs
-1F516 ; fully-qualified # 🔖 E0.6 bookmark
-1F3F7 FE0F ; fully-qualified # 🏷️ E0.7 label
-1F3F7 ; unqualified # 🏷 E0.7 label
+1F4D4 ; fully-qualified # 📔 E0.6 notebook with decorative cover
+1F4D5 ; fully-qualified # 📕 E0.6 closed book
+1F4D6 ; fully-qualified # 📖 E0.6 open book
+1F4D7 ; fully-qualified # 📗 E0.6 green book
+1F4D8 ; fully-qualified # 📘 E0.6 blue book
+1F4D9 ; fully-qualified # 📙 E0.6 orange book
+1F4DA ; fully-qualified # 📚 E0.6 books
+1F4D3 ; fully-qualified # 📓 E0.6 notebook
+1F4D2 ; fully-qualified # 📒 E0.6 ledger
+1F4C3 ; fully-qualified # 📃 E0.6 page with curl
+1F4DC ; fully-qualified # 📜 E0.6 scroll
+1F4C4 ; fully-qualified # 📄 E0.6 page facing up
+1F4F0 ; fully-qualified # 📰 E0.6 newspaper
+1F5DE FE0F ; fully-qualified # 🗞️ E0.7 rolled-up newspaper
+1F5DE ; unqualified # 🗞 E0.7 rolled-up newspaper
+1F4D1 ; fully-qualified # 📑 E0.6 bookmark tabs
+1F516 ; fully-qualified # 🔖 E0.6 bookmark
+1F3F7 FE0F ; fully-qualified # 🏷️ E0.7 label
+1F3F7 ; unqualified # 🏷 E0.7 label
# subgroup: money
-1F4B0 ; fully-qualified # 💰 E0.6 money bag
-1FA99 ; fully-qualified # 🪙 E13.0 coin
-1F4B4 ; fully-qualified # 💴 E0.6 yen banknote
-1F4B5 ; fully-qualified # 💵 E0.6 dollar banknote
-1F4B6 ; fully-qualified # 💶 E1.0 euro banknote
-1F4B7 ; fully-qualified # 💷 E1.0 pound banknote
-1F4B8 ; fully-qualified # 💸 E0.6 money with wings
-1F4B3 ; fully-qualified # 💳 E0.6 credit card
-1F9FE ; fully-qualified # 🧾 E11.0 receipt
-1F4B9 ; fully-qualified # 💹 E0.6 chart increasing with yen
+1F4B0 ; fully-qualified # 💰 E0.6 money bag
+1FA99 ; fully-qualified # 🪙 E13.0 coin
+1F4B4 ; fully-qualified # 💴 E0.6 yen banknote
+1F4B5 ; fully-qualified # 💵 E0.6 dollar banknote
+1F4B6 ; fully-qualified # 💶 E1.0 euro banknote
+1F4B7 ; fully-qualified # 💷 E1.0 pound banknote
+1F4B8 ; fully-qualified # 💸 E0.6 money with wings
+1F4B3 ; fully-qualified # 💳 E0.6 credit card
+1F9FE ; fully-qualified # 🧾 E11.0 receipt
+1F4B9 ; fully-qualified # 💹 E0.6 chart increasing with yen
# subgroup: mail
-2709 FE0F ; fully-qualified # ✉️ E0.6 envelope
-2709 ; unqualified # ✉ E0.6 envelope
-1F4E7 ; fully-qualified # 📧 E0.6 e-mail
-1F4E8 ; fully-qualified # 📨 E0.6 incoming envelope
-1F4E9 ; fully-qualified # 📩 E0.6 envelope with arrow
-1F4E4 ; fully-qualified # 📤 E0.6 outbox tray
-1F4E5 ; fully-qualified # 📥 E0.6 inbox tray
-1F4E6 ; fully-qualified # 📦 E0.6 package
-1F4EB ; fully-qualified # 📫 E0.6 closed mailbox with raised flag
-1F4EA ; fully-qualified # 📪 E0.6 closed mailbox with lowered flag
-1F4EC ; fully-qualified # 📬 E0.7 open mailbox with raised flag
-1F4ED ; fully-qualified # 📭 E0.7 open mailbox with lowered flag
-1F4EE ; fully-qualified # 📮 E0.6 postbox
-1F5F3 FE0F ; fully-qualified # 🗳️ E0.7 ballot box with ballot
-1F5F3 ; unqualified # 🗳 E0.7 ballot box with ballot
+2709 FE0F ; fully-qualified # ✉️ E0.6 envelope
+2709 ; unqualified # ✉ E0.6 envelope
+1F4E7 ; fully-qualified # 📧 E0.6 e-mail
+1F4E8 ; fully-qualified # 📨 E0.6 incoming envelope
+1F4E9 ; fully-qualified # 📩 E0.6 envelope with arrow
+1F4E4 ; fully-qualified # 📤 E0.6 outbox tray
+1F4E5 ; fully-qualified # 📥 E0.6 inbox tray
+1F4E6 ; fully-qualified # 📦 E0.6 package
+1F4EB ; fully-qualified # 📫 E0.6 closed mailbox with raised flag
+1F4EA ; fully-qualified # 📪 E0.6 closed mailbox with lowered flag
+1F4EC ; fully-qualified # 📬 E0.7 open mailbox with raised flag
+1F4ED ; fully-qualified # 📭 E0.7 open mailbox with lowered flag
+1F4EE ; fully-qualified # 📮 E0.6 postbox
+1F5F3 FE0F ; fully-qualified # 🗳️ E0.7 ballot box with ballot
+1F5F3 ; unqualified # 🗳 E0.7 ballot box with ballot
# subgroup: writing
-270F FE0F ; fully-qualified # ✏️ E0.6 pencil
-270F ; unqualified # ✏ E0.6 pencil
-2712 FE0F ; fully-qualified # ✒️ E0.6 black nib
-2712 ; unqualified # ✒ E0.6 black nib
-1F58B FE0F ; fully-qualified # 🖋️ E0.7 fountain pen
-1F58B ; unqualified # 🖋 E0.7 fountain pen
-1F58A FE0F ; fully-qualified # 🖊️ E0.7 pen
-1F58A ; unqualified # 🖊 E0.7 pen
-1F58C FE0F ; fully-qualified # 🖌️ E0.7 paintbrush
-1F58C ; unqualified # 🖌 E0.7 paintbrush
-1F58D FE0F ; fully-qualified # 🖍️ E0.7 crayon
-1F58D ; unqualified # 🖍 E0.7 crayon
-1F4DD ; fully-qualified # 📝 E0.6 memo
+270F FE0F ; fully-qualified # ✏️ E0.6 pencil
+270F ; unqualified # ✏ E0.6 pencil
+2712 FE0F ; fully-qualified # ✒️ E0.6 black nib
+2712 ; unqualified # ✒ E0.6 black nib
+1F58B FE0F ; fully-qualified # 🖋️ E0.7 fountain pen
+1F58B ; unqualified # 🖋 E0.7 fountain pen
+1F58A FE0F ; fully-qualified # 🖊️ E0.7 pen
+1F58A ; unqualified # 🖊 E0.7 pen
+1F58C FE0F ; fully-qualified # 🖌️ E0.7 paintbrush
+1F58C ; unqualified # 🖌 E0.7 paintbrush
+1F58D FE0F ; fully-qualified # 🖍️ E0.7 crayon
+1F58D ; unqualified # 🖍 E0.7 crayon
+1F4DD ; fully-qualified # 📝 E0.6 memo
# subgroup: office
-1F4BC ; fully-qualified # 💼 E0.6 briefcase
-1F4C1 ; fully-qualified # 📁 E0.6 file folder
-1F4C2 ; fully-qualified # 📂 E0.6 open file folder
-1F5C2 FE0F ; fully-qualified # 🗂️ E0.7 card index dividers
-1F5C2 ; unqualified # 🗂 E0.7 card index dividers
-1F4C5 ; fully-qualified # 📅 E0.6 calendar
-1F4C6 ; fully-qualified # 📆 E0.6 tear-off calendar
-1F5D2 FE0F ; fully-qualified # 🗒️ E0.7 spiral notepad
-1F5D2 ; unqualified # 🗒 E0.7 spiral notepad
-1F5D3 FE0F ; fully-qualified # 🗓️ E0.7 spiral calendar
-1F5D3 ; unqualified # 🗓 E0.7 spiral calendar
-1F4C7 ; fully-qualified # 📇 E0.6 card index
-1F4C8 ; fully-qualified # 📈 E0.6 chart increasing
-1F4C9 ; fully-qualified # 📉 E0.6 chart decreasing
-1F4CA ; fully-qualified # 📊 E0.6 bar chart
-1F4CB ; fully-qualified # 📋 E0.6 clipboard
-1F4CC ; fully-qualified # 📌 E0.6 pushpin
-1F4CD ; fully-qualified # 📍 E0.6 round pushpin
-1F4CE ; fully-qualified # 📎 E0.6 paperclip
-1F587 FE0F ; fully-qualified # 🖇️ E0.7 linked paperclips
-1F587 ; unqualified # 🖇 E0.7 linked paperclips
-1F4CF ; fully-qualified # 📏 E0.6 straight ruler
-1F4D0 ; fully-qualified # 📐 E0.6 triangular ruler
-2702 FE0F ; fully-qualified # ✂️ E0.6 scissors
-2702 ; unqualified # ✂ E0.6 scissors
-1F5C3 FE0F ; fully-qualified # 🗃️ E0.7 card file box
-1F5C3 ; unqualified # 🗃 E0.7 card file box
-1F5C4 FE0F ; fully-qualified # 🗄️ E0.7 file cabinet
-1F5C4 ; unqualified # 🗄 E0.7 file cabinet
-1F5D1 FE0F ; fully-qualified # 🗑️ E0.7 wastebasket
-1F5D1 ; unqualified # 🗑 E0.7 wastebasket
+1F4BC ; fully-qualified # 💼 E0.6 briefcase
+1F4C1 ; fully-qualified # 📁 E0.6 file folder
+1F4C2 ; fully-qualified # 📂 E0.6 open file folder
+1F5C2 FE0F ; fully-qualified # 🗂️ E0.7 card index dividers
+1F5C2 ; unqualified # 🗂 E0.7 card index dividers
+1F4C5 ; fully-qualified # 📅 E0.6 calendar
+1F4C6 ; fully-qualified # 📆 E0.6 tear-off calendar
+1F5D2 FE0F ; fully-qualified # 🗒️ E0.7 spiral notepad
+1F5D2 ; unqualified # 🗒 E0.7 spiral notepad
+1F5D3 FE0F ; fully-qualified # 🗓️ E0.7 spiral calendar
+1F5D3 ; unqualified # 🗓 E0.7 spiral calendar
+1F4C7 ; fully-qualified # 📇 E0.6 card index
+1F4C8 ; fully-qualified # 📈 E0.6 chart increasing
+1F4C9 ; fully-qualified # 📉 E0.6 chart decreasing
+1F4CA ; fully-qualified # 📊 E0.6 bar chart
+1F4CB ; fully-qualified # 📋 E0.6 clipboard
+1F4CC ; fully-qualified # 📌 E0.6 pushpin
+1F4CD ; fully-qualified # 📍 E0.6 round pushpin
+1F4CE ; fully-qualified # 📎 E0.6 paperclip
+1F587 FE0F ; fully-qualified # 🖇️ E0.7 linked paperclips
+1F587 ; unqualified # 🖇 E0.7 linked paperclips
+1F4CF ; fully-qualified # 📏 E0.6 straight ruler
+1F4D0 ; fully-qualified # 📐 E0.6 triangular ruler
+2702 FE0F ; fully-qualified # ✂️ E0.6 scissors
+2702 ; unqualified # ✂ E0.6 scissors
+1F5C3 FE0F ; fully-qualified # 🗃️ E0.7 card file box
+1F5C3 ; unqualified # 🗃 E0.7 card file box
+1F5C4 FE0F ; fully-qualified # 🗄️ E0.7 file cabinet
+1F5C4 ; unqualified # 🗄 E0.7 file cabinet
+1F5D1 FE0F ; fully-qualified # 🗑️ E0.7 wastebasket
+1F5D1 ; unqualified # 🗑 E0.7 wastebasket
# subgroup: lock
-1F512 ; fully-qualified # 🔒 E0.6 locked
-1F513 ; fully-qualified # 🔓 E0.6 unlocked
-1F50F ; fully-qualified # 🔏 E0.6 locked with pen
-1F510 ; fully-qualified # 🔐 E0.6 locked with key
-1F511 ; fully-qualified # 🔑 E0.6 key
-1F5DD FE0F ; fully-qualified # 🗝️ E0.7 old key
-1F5DD ; unqualified # 🗝 E0.7 old key
+1F512 ; fully-qualified # 🔒 E0.6 locked
+1F513 ; fully-qualified # 🔓 E0.6 unlocked
+1F50F ; fully-qualified # 🔏 E0.6 locked with pen
+1F510 ; fully-qualified # 🔐 E0.6 locked with key
+1F511 ; fully-qualified # 🔑 E0.6 key
+1F5DD FE0F ; fully-qualified # 🗝️ E0.7 old key
+1F5DD ; unqualified # 🗝 E0.7 old key
# subgroup: tool
-1F528 ; fully-qualified # 🔨 E0.6 hammer
-1FA93 ; fully-qualified # 🪓 E12.0 axe
-26CF FE0F ; fully-qualified # ⛏️ E0.7 pick
-26CF ; unqualified # ⛏ E0.7 pick
-2692 FE0F ; fully-qualified # ⚒️ E1.0 hammer and pick
-2692 ; unqualified # ⚒ E1.0 hammer and pick
-1F6E0 FE0F ; fully-qualified # 🛠️ E0.7 hammer and wrench
-1F6E0 ; unqualified # 🛠 E0.7 hammer and wrench
-1F5E1 FE0F ; fully-qualified # 🗡️ E0.7 dagger
-1F5E1 ; unqualified # 🗡 E0.7 dagger
-2694 FE0F ; fully-qualified # ⚔️ E1.0 crossed swords
-2694 ; unqualified # ⚔ E1.0 crossed swords
-1F52B ; fully-qualified # 🔫 E0.6 pistol
-1FA83 ; fully-qualified # 🪃 E13.0 boomerang
-1F3F9 ; fully-qualified # 🏹 E1.0 bow and arrow
-1F6E1 FE0F ; fully-qualified # 🛡️ E0.7 shield
-1F6E1 ; unqualified # 🛡 E0.7 shield
-1FA9A ; fully-qualified # 🪚 E13.0 carpentry saw
-1F527 ; fully-qualified # 🔧 E0.6 wrench
-1FA9B ; fully-qualified # 🪛 E13.0 screwdriver
-1F529 ; fully-qualified # 🔩 E0.6 nut and bolt
-2699 FE0F ; fully-qualified # ⚙️ E1.0 gear
-2699 ; unqualified # ⚙ E1.0 gear
-1F5DC FE0F ; fully-qualified # 🗜️ E0.7 clamp
-1F5DC ; unqualified # 🗜 E0.7 clamp
-2696 FE0F ; fully-qualified # ⚖️ E1.0 balance scale
-2696 ; unqualified # ⚖ E1.0 balance scale
-1F9AF ; fully-qualified # 🦯 E12.0 white cane
-1F517 ; fully-qualified # 🔗 E0.6 link
-26D3 FE0F ; fully-qualified # ⛓️ E0.7 chains
-26D3 ; unqualified # ⛓ E0.7 chains
-1FA9D ; fully-qualified # 🪝 E13.0 hook
-1F9F0 ; fully-qualified # 🧰 E11.0 toolbox
-1F9F2 ; fully-qualified # 🧲 E11.0 magnet
-1FA9C ; fully-qualified # 🪜 E13.0 ladder
+1F528 ; fully-qualified # 🔨 E0.6 hammer
+1FA93 ; fully-qualified # 🪓 E12.0 axe
+26CF FE0F ; fully-qualified # ⛏️ E0.7 pick
+26CF ; unqualified # ⛏ E0.7 pick
+2692 FE0F ; fully-qualified # ⚒️ E1.0 hammer and pick
+2692 ; unqualified # ⚒ E1.0 hammer and pick
+1F6E0 FE0F ; fully-qualified # 🛠️ E0.7 hammer and wrench
+1F6E0 ; unqualified # 🛠 E0.7 hammer and wrench
+1F5E1 FE0F ; fully-qualified # 🗡️ E0.7 dagger
+1F5E1 ; unqualified # 🗡 E0.7 dagger
+2694 FE0F ; fully-qualified # ⚔️ E1.0 crossed swords
+2694 ; unqualified # ⚔ E1.0 crossed swords
+1F52B ; fully-qualified # 🔫 E0.6 water pistol
+1FA83 ; fully-qualified # 🪃 E13.0 boomerang
+1F3F9 ; fully-qualified # 🏹 E1.0 bow and arrow
+1F6E1 FE0F ; fully-qualified # 🛡️ E0.7 shield
+1F6E1 ; unqualified # 🛡 E0.7 shield
+1FA9A ; fully-qualified # 🪚 E13.0 carpentry saw
+1F527 ; fully-qualified # 🔧 E0.6 wrench
+1FA9B ; fully-qualified # 🪛 E13.0 screwdriver
+1F529 ; fully-qualified # 🔩 E0.6 nut and bolt
+2699 FE0F ; fully-qualified # ⚙️ E1.0 gear
+2699 ; unqualified # ⚙ E1.0 gear
+1F5DC FE0F ; fully-qualified # 🗜️ E0.7 clamp
+1F5DC ; unqualified # 🗜 E0.7 clamp
+2696 FE0F ; fully-qualified # ⚖️ E1.0 balance scale
+2696 ; unqualified # ⚖ E1.0 balance scale
+1F9AF ; fully-qualified # 🦯 E12.0 white cane
+1F517 ; fully-qualified # 🔗 E0.6 link
+26D3 FE0F ; fully-qualified # ⛓️ E0.7 chains
+26D3 ; unqualified # ⛓ E0.7 chains
+1FA9D ; fully-qualified # 🪝 E13.0 hook
+1F9F0 ; fully-qualified # 🧰 E11.0 toolbox
+1F9F2 ; fully-qualified # 🧲 E11.0 magnet
+1FA9C ; fully-qualified # 🪜 E13.0 ladder
# subgroup: science
-2697 FE0F ; fully-qualified # ⚗️ E1.0 alembic
-2697 ; unqualified # ⚗ E1.0 alembic
-1F9EA ; fully-qualified # 🧪 E11.0 test tube
-1F9EB ; fully-qualified # 🧫 E11.0 petri dish
-1F9EC ; fully-qualified # 🧬 E11.0 dna
-1F52C ; fully-qualified # 🔬 E1.0 microscope
-1F52D ; fully-qualified # 🔭 E1.0 telescope
-1F4E1 ; fully-qualified # 📡 E0.6 satellite antenna
+2697 FE0F ; fully-qualified # ⚗️ E1.0 alembic
+2697 ; unqualified # ⚗ E1.0 alembic
+1F9EA ; fully-qualified # 🧪 E11.0 test tube
+1F9EB ; fully-qualified # 🧫 E11.0 petri dish
+1F9EC ; fully-qualified # 🧬 E11.0 dna
+1F52C ; fully-qualified # 🔬 E1.0 microscope
+1F52D ; fully-qualified # 🔭 E1.0 telescope
+1F4E1 ; fully-qualified # 📡 E0.6 satellite antenna
# subgroup: medical
-1F489 ; fully-qualified # 💉 E0.6 syringe
-1FA78 ; fully-qualified # 🩸 E12.0 drop of blood
-1F48A ; fully-qualified # 💊 E0.6 pill
-1FA79 ; fully-qualified # 🩹 E12.0 adhesive bandage
-1FA7A ; fully-qualified # 🩺 E12.0 stethoscope
+1F489 ; fully-qualified # 💉 E0.6 syringe
+1FA78 ; fully-qualified # 🩸 E12.0 drop of blood
+1F48A ; fully-qualified # 💊 E0.6 pill
+1FA79 ; fully-qualified # 🩹 E12.0 adhesive bandage
+1FA7A ; fully-qualified # 🩺 E12.0 stethoscope
# subgroup: household
-1F6AA ; fully-qualified # 🚪 E0.6 door
-1F6D7 ; fully-qualified # 🛗 E13.0 elevator
-1FA9E ; fully-qualified # 🪞 E13.0 mirror
-1FA9F ; fully-qualified # 🪟 E13.0 window
-1F6CF FE0F ; fully-qualified # 🛏️ E0.7 bed
-1F6CF ; unqualified # 🛏 E0.7 bed
-1F6CB FE0F ; fully-qualified # 🛋️ E0.7 couch and lamp
-1F6CB ; unqualified # 🛋 E0.7 couch and lamp
-1FA91 ; fully-qualified # 🪑 E12.0 chair
-1F6BD ; fully-qualified # 🚽 E0.6 toilet
-1FAA0 ; fully-qualified # 🪠 E13.0 plunger
-1F6BF ; fully-qualified # 🚿 E1.0 shower
-1F6C1 ; fully-qualified # 🛁 E1.0 bathtub
-1FAA4 ; fully-qualified # 🪤 E13.0 mouse trap
-1FA92 ; fully-qualified # 🪒 E12.0 razor
-1F9F4 ; fully-qualified # 🧴 E11.0 lotion bottle
-1F9F7 ; fully-qualified # 🧷 E11.0 safety pin
-1F9F9 ; fully-qualified # 🧹 E11.0 broom
-1F9FA ; fully-qualified # 🧺 E11.0 basket
-1F9FB ; fully-qualified # 🧻 E11.0 roll of paper
-1FAA3 ; fully-qualified # 🪣 E13.0 bucket
-1F9FC ; fully-qualified # 🧼 E11.0 soap
-1FAA5 ; fully-qualified # 🪥 E13.0 toothbrush
-1F9FD ; fully-qualified # 🧽 E11.0 sponge
-1F9EF ; fully-qualified # 🧯 E11.0 fire extinguisher
-1F6D2 ; fully-qualified # 🛒 E3.0 shopping cart
+1F6AA ; fully-qualified # 🚪 E0.6 door
+1F6D7 ; fully-qualified # 🛗 E13.0 elevator
+1FA9E ; fully-qualified # 🪞 E13.0 mirror
+1FA9F ; fully-qualified # 🪟 E13.0 window
+1F6CF FE0F ; fully-qualified # 🛏️ E0.7 bed
+1F6CF ; unqualified # 🛏 E0.7 bed
+1F6CB FE0F ; fully-qualified # 🛋️ E0.7 couch and lamp
+1F6CB ; unqualified # 🛋 E0.7 couch and lamp
+1FA91 ; fully-qualified # 🪑 E12.0 chair
+1F6BD ; fully-qualified # 🚽 E0.6 toilet
+1FAA0 ; fully-qualified # 🪠 E13.0 plunger
+1F6BF ; fully-qualified # 🚿 E1.0 shower
+1F6C1 ; fully-qualified # 🛁 E1.0 bathtub
+1FAA4 ; fully-qualified # 🪤 E13.0 mouse trap
+1FA92 ; fully-qualified # 🪒 E12.0 razor
+1F9F4 ; fully-qualified # 🧴 E11.0 lotion bottle
+1F9F7 ; fully-qualified # 🧷 E11.0 safety pin
+1F9F9 ; fully-qualified # 🧹 E11.0 broom
+1F9FA ; fully-qualified # 🧺 E11.0 basket
+1F9FB ; fully-qualified # 🧻 E11.0 roll of paper
+1FAA3 ; fully-qualified # 🪣 E13.0 bucket
+1F9FC ; fully-qualified # 🧼 E11.0 soap
+1FAA5 ; fully-qualified # 🪥 E13.0 toothbrush
+1F9FD ; fully-qualified # 🧽 E11.0 sponge
+1F9EF ; fully-qualified # 🧯 E11.0 fire extinguisher
+1F6D2 ; fully-qualified # 🛒 E3.0 shopping cart
# subgroup: other-object
-1F6AC ; fully-qualified # 🚬 E0.6 cigarette
-26B0 FE0F ; fully-qualified # ⚰️ E1.0 coffin
-26B0 ; unqualified # ⚰ E1.0 coffin
-1FAA6 ; fully-qualified # 🪦 E13.0 headstone
-26B1 FE0F ; fully-qualified # ⚱️ E1.0 funeral urn
-26B1 ; unqualified # ⚱ E1.0 funeral urn
-1F5FF ; fully-qualified # 🗿 E0.6 moai
-1FAA7 ; fully-qualified # 🪧 E13.0 placard
+1F6AC ; fully-qualified # 🚬 E0.6 cigarette
+26B0 FE0F ; fully-qualified # ⚰️ E1.0 coffin
+26B0 ; unqualified # ⚰ E1.0 coffin
+1FAA6 ; fully-qualified # 🪦 E13.0 headstone
+26B1 FE0F ; fully-qualified # ⚱️ E1.0 funeral urn
+26B1 ; unqualified # ⚱ E1.0 funeral urn
+1F5FF ; fully-qualified # 🗿 E0.6 moai
+1FAA7 ; fully-qualified # 🪧 E13.0 placard
# Objects subtotal: 299
# Objects subtotal: 299 w/o modifiers
@@ -3831,333 +4253,333 @@
# group: Symbols
# subgroup: transport-sign
-1F3E7 ; fully-qualified # 🏧 E0.6 ATM sign
-1F6AE ; fully-qualified # 🚮 E1.0 litter in bin sign
-1F6B0 ; fully-qualified # 🚰 E1.0 potable water
-267F ; fully-qualified # ♿ E0.6 wheelchair symbol
-1F6B9 ; fully-qualified # 🚹 E0.6 men’s room
-1F6BA ; fully-qualified # 🚺 E0.6 women’s room
-1F6BB ; fully-qualified # 🚻 E0.6 restroom
-1F6BC ; fully-qualified # 🚼 E0.6 baby symbol
-1F6BE ; fully-qualified # 🚾 E0.6 water closet
-1F6C2 ; fully-qualified # 🛂 E1.0 passport control
-1F6C3 ; fully-qualified # 🛃 E1.0 customs
-1F6C4 ; fully-qualified # 🛄 E1.0 baggage claim
-1F6C5 ; fully-qualified # 🛅 E1.0 left luggage
+1F3E7 ; fully-qualified # 🏧 E0.6 ATM sign
+1F6AE ; fully-qualified # 🚮 E1.0 litter in bin sign
+1F6B0 ; fully-qualified # 🚰 E1.0 potable water
+267F ; fully-qualified # ♿ E0.6 wheelchair symbol
+1F6B9 ; fully-qualified # 🚹 E0.6 men’s room
+1F6BA ; fully-qualified # 🚺 E0.6 women’s room
+1F6BB ; fully-qualified # 🚻 E0.6 restroom
+1F6BC ; fully-qualified # 🚼 E0.6 baby symbol
+1F6BE ; fully-qualified # 🚾 E0.6 water closet
+1F6C2 ; fully-qualified # 🛂 E1.0 passport control
+1F6C3 ; fully-qualified # 🛃 E1.0 customs
+1F6C4 ; fully-qualified # 🛄 E1.0 baggage claim
+1F6C5 ; fully-qualified # 🛅 E1.0 left luggage
# subgroup: warning
-26A0 FE0F ; fully-qualified # ⚠️ E0.6 warning
-26A0 ; unqualified # ⚠ E0.6 warning
-1F6B8 ; fully-qualified # 🚸 E1.0 children crossing
-26D4 ; fully-qualified # ⛔ E0.6 no entry
-1F6AB ; fully-qualified # 🚫 E0.6 prohibited
-1F6B3 ; fully-qualified # 🚳 E1.0 no bicycles
-1F6AD ; fully-qualified # 🚭 E0.6 no smoking
-1F6AF ; fully-qualified # 🚯 E1.0 no littering
-1F6B1 ; fully-qualified # 🚱 E1.0 non-potable water
-1F6B7 ; fully-qualified # 🚷 E1.0 no pedestrians
-1F4F5 ; fully-qualified # 📵 E1.0 no mobile phones
-1F51E ; fully-qualified # 🔞 E0.6 no one under eighteen
-2622 FE0F ; fully-qualified # ☢️ E1.0 radioactive
-2622 ; unqualified # ☢ E1.0 radioactive
-2623 FE0F ; fully-qualified # ☣️ E1.0 biohazard
-2623 ; unqualified # ☣ E1.0 biohazard
+26A0 FE0F ; fully-qualified # ⚠️ E0.6 warning
+26A0 ; unqualified # ⚠ E0.6 warning
+1F6B8 ; fully-qualified # 🚸 E1.0 children crossing
+26D4 ; fully-qualified # ⛔ E0.6 no entry
+1F6AB ; fully-qualified # 🚫 E0.6 prohibited
+1F6B3 ; fully-qualified # 🚳 E1.0 no bicycles
+1F6AD ; fully-qualified # 🚭 E0.6 no smoking
+1F6AF ; fully-qualified # 🚯 E1.0 no littering
+1F6B1 ; fully-qualified # 🚱 E1.0 non-potable water
+1F6B7 ; fully-qualified # 🚷 E1.0 no pedestrians
+1F4F5 ; fully-qualified # 📵 E1.0 no mobile phones
+1F51E ; fully-qualified # 🔞 E0.6 no one under eighteen
+2622 FE0F ; fully-qualified # ☢️ E1.0 radioactive
+2622 ; unqualified # ☢ E1.0 radioactive
+2623 FE0F ; fully-qualified # ☣️ E1.0 biohazard
+2623 ; unqualified # ☣ E1.0 biohazard
# subgroup: arrow
-2B06 FE0F ; fully-qualified # ⬆️ E0.6 up arrow
-2B06 ; unqualified # ⬆ E0.6 up arrow
-2197 FE0F ; fully-qualified # ↗️ E0.6 up-right arrow
-2197 ; unqualified # ↗ E0.6 up-right arrow
-27A1 FE0F ; fully-qualified # ➡️ E0.6 right arrow
-27A1 ; unqualified # ➡ E0.6 right arrow
-2198 FE0F ; fully-qualified # ↘️ E0.6 down-right arrow
-2198 ; unqualified # ↘ E0.6 down-right arrow
-2B07 FE0F ; fully-qualified # ⬇️ E0.6 down arrow
-2B07 ; unqualified # ⬇ E0.6 down arrow
-2199 FE0F ; fully-qualified # ↙️ E0.6 down-left arrow
-2199 ; unqualified # ↙ E0.6 down-left arrow
-2B05 FE0F ; fully-qualified # ⬅️ E0.6 left arrow
-2B05 ; unqualified # ⬅ E0.6 left arrow
-2196 FE0F ; fully-qualified # ↖️ E0.6 up-left arrow
-2196 ; unqualified # ↖ E0.6 up-left arrow
-2195 FE0F ; fully-qualified # ↕️ E0.6 up-down arrow
-2195 ; unqualified # ↕ E0.6 up-down arrow
-2194 FE0F ; fully-qualified # ↔️ E0.6 left-right arrow
-2194 ; unqualified # ↔ E0.6 left-right arrow
-21A9 FE0F ; fully-qualified # ↩️ E0.6 right arrow curving left
-21A9 ; unqualified # ↩ E0.6 right arrow curving left
-21AA FE0F ; fully-qualified # ↪️ E0.6 left arrow curving right
-21AA ; unqualified # ↪ E0.6 left arrow curving right
-2934 FE0F ; fully-qualified # ⤴️ E0.6 right arrow curving up
-2934 ; unqualified # ⤴ E0.6 right arrow curving up
-2935 FE0F ; fully-qualified # ⤵️ E0.6 right arrow curving down
-2935 ; unqualified # ⤵ E0.6 right arrow curving down
-1F503 ; fully-qualified # 🔃 E0.6 clockwise vertical arrows
-1F504 ; fully-qualified # 🔄 E1.0 counterclockwise arrows button
-1F519 ; fully-qualified # 🔙 E0.6 BACK arrow
-1F51A ; fully-qualified # 🔚 E0.6 END arrow
-1F51B ; fully-qualified # 🔛 E0.6 ON! arrow
-1F51C ; fully-qualified # 🔜 E0.6 SOON arrow
-1F51D ; fully-qualified # 🔝 E0.6 TOP arrow
+2B06 FE0F ; fully-qualified # ⬆️ E0.6 up arrow
+2B06 ; unqualified # ⬆ E0.6 up arrow
+2197 FE0F ; fully-qualified # ↗️ E0.6 up-right arrow
+2197 ; unqualified # ↗ E0.6 up-right arrow
+27A1 FE0F ; fully-qualified # ➡️ E0.6 right arrow
+27A1 ; unqualified # ➡ E0.6 right arrow
+2198 FE0F ; fully-qualified # ↘️ E0.6 down-right arrow
+2198 ; unqualified # ↘ E0.6 down-right arrow
+2B07 FE0F ; fully-qualified # ⬇️ E0.6 down arrow
+2B07 ; unqualified # ⬇ E0.6 down arrow
+2199 FE0F ; fully-qualified # ↙️ E0.6 down-left arrow
+2199 ; unqualified # ↙ E0.6 down-left arrow
+2B05 FE0F ; fully-qualified # ⬅️ E0.6 left arrow
+2B05 ; unqualified # ⬅ E0.6 left arrow
+2196 FE0F ; fully-qualified # ↖️ E0.6 up-left arrow
+2196 ; unqualified # ↖ E0.6 up-left arrow
+2195 FE0F ; fully-qualified # ↕️ E0.6 up-down arrow
+2195 ; unqualified # ↕ E0.6 up-down arrow
+2194 FE0F ; fully-qualified # ↔️ E0.6 left-right arrow
+2194 ; unqualified # ↔ E0.6 left-right arrow
+21A9 FE0F ; fully-qualified # ↩️ E0.6 right arrow curving left
+21A9 ; unqualified # ↩ E0.6 right arrow curving left
+21AA FE0F ; fully-qualified # ↪️ E0.6 left arrow curving right
+21AA ; unqualified # ↪ E0.6 left arrow curving right
+2934 FE0F ; fully-qualified # ⤴️ E0.6 right arrow curving up
+2934 ; unqualified # ⤴ E0.6 right arrow curving up
+2935 FE0F ; fully-qualified # ⤵️ E0.6 right arrow curving down
+2935 ; unqualified # ⤵ E0.6 right arrow curving down
+1F503 ; fully-qualified # 🔃 E0.6 clockwise vertical arrows
+1F504 ; fully-qualified # 🔄 E1.0 counterclockwise arrows button
+1F519 ; fully-qualified # 🔙 E0.6 BACK arrow
+1F51A ; fully-qualified # 🔚 E0.6 END arrow
+1F51B ; fully-qualified # 🔛 E0.6 ON! arrow
+1F51C ; fully-qualified # 🔜 E0.6 SOON arrow
+1F51D ; fully-qualified # 🔝 E0.6 TOP arrow
# subgroup: religion
-1F6D0 ; fully-qualified # 🛐 E1.0 place of worship
-269B FE0F ; fully-qualified # ⚛️ E1.0 atom symbol
-269B ; unqualified # ⚛ E1.0 atom symbol
-1F549 FE0F ; fully-qualified # 🕉️ E0.7 om
-1F549 ; unqualified # 🕉 E0.7 om
-2721 FE0F ; fully-qualified # ✡️ E0.7 star of David
-2721 ; unqualified # ✡ E0.7 star of David
-2638 FE0F ; fully-qualified # ☸️ E0.7 wheel of dharma
-2638 ; unqualified # ☸ E0.7 wheel of dharma
-262F FE0F ; fully-qualified # ☯️ E0.7 yin yang
-262F ; unqualified # ☯ E0.7 yin yang
-271D FE0F ; fully-qualified # ✝️ E0.7 latin cross
-271D ; unqualified # ✝ E0.7 latin cross
-2626 FE0F ; fully-qualified # ☦️ E1.0 orthodox cross
-2626 ; unqualified # ☦ E1.0 orthodox cross
-262A FE0F ; fully-qualified # ☪️ E0.7 star and crescent
-262A ; unqualified # ☪ E0.7 star and crescent
-262E FE0F ; fully-qualified # ☮️ E1.0 peace symbol
-262E ; unqualified # ☮ E1.0 peace symbol
-1F54E ; fully-qualified # 🕎 E1.0 menorah
-1F52F ; fully-qualified # 🔯 E0.6 dotted six-pointed star
+1F6D0 ; fully-qualified # 🛐 E1.0 place of worship
+269B FE0F ; fully-qualified # ⚛️ E1.0 atom symbol
+269B ; unqualified # ⚛ E1.0 atom symbol
+1F549 FE0F ; fully-qualified # 🕉️ E0.7 om
+1F549 ; unqualified # 🕉 E0.7 om
+2721 FE0F ; fully-qualified # ✡️ E0.7 star of David
+2721 ; unqualified # ✡ E0.7 star of David
+2638 FE0F ; fully-qualified # ☸️ E0.7 wheel of dharma
+2638 ; unqualified # ☸ E0.7 wheel of dharma
+262F FE0F ; fully-qualified # ☯️ E0.7 yin yang
+262F ; unqualified # ☯ E0.7 yin yang
+271D FE0F ; fully-qualified # ✝️ E0.7 latin cross
+271D ; unqualified # ✝ E0.7 latin cross
+2626 FE0F ; fully-qualified # ☦️ E1.0 orthodox cross
+2626 ; unqualified # ☦ E1.0 orthodox cross
+262A FE0F ; fully-qualified # ☪️ E0.7 star and crescent
+262A ; unqualified # ☪ E0.7 star and crescent
+262E FE0F ; fully-qualified # ☮️ E1.0 peace symbol
+262E ; unqualified # ☮ E1.0 peace symbol
+1F54E ; fully-qualified # 🕎 E1.0 menorah
+1F52F ; fully-qualified # 🔯 E0.6 dotted six-pointed star
# subgroup: zodiac
-2648 ; fully-qualified # ♈ E0.6 Aries
-2649 ; fully-qualified # ♉ E0.6 Taurus
-264A ; fully-qualified # ♊ E0.6 Gemini
-264B ; fully-qualified # ♋ E0.6 Cancer
-264C ; fully-qualified # ♌ E0.6 Leo
-264D ; fully-qualified # ♍ E0.6 Virgo
-264E ; fully-qualified # ♎ E0.6 Libra
-264F ; fully-qualified # ♏ E0.6 Scorpio
-2650 ; fully-qualified # ♐ E0.6 Sagittarius
-2651 ; fully-qualified # ♑ E0.6 Capricorn
-2652 ; fully-qualified # ♒ E0.6 Aquarius
-2653 ; fully-qualified # ♓ E0.6 Pisces
-26CE ; fully-qualified # ⛎ E0.6 Ophiuchus
+2648 ; fully-qualified # ♈ E0.6 Aries
+2649 ; fully-qualified # ♉ E0.6 Taurus
+264A ; fully-qualified # ♊ E0.6 Gemini
+264B ; fully-qualified # ♋ E0.6 Cancer
+264C ; fully-qualified # ♌ E0.6 Leo
+264D ; fully-qualified # ♍ E0.6 Virgo
+264E ; fully-qualified # ♎ E0.6 Libra
+264F ; fully-qualified # ♏ E0.6 Scorpio
+2650 ; fully-qualified # ♐ E0.6 Sagittarius
+2651 ; fully-qualified # ♑ E0.6 Capricorn
+2652 ; fully-qualified # ♒ E0.6 Aquarius
+2653 ; fully-qualified # ♓ E0.6 Pisces
+26CE ; fully-qualified # ⛎ E0.6 Ophiuchus
# subgroup: av-symbol
-1F500 ; fully-qualified # 🔀 E1.0 shuffle tracks button
-1F501 ; fully-qualified # 🔁 E1.0 repeat button
-1F502 ; fully-qualified # 🔂 E1.0 repeat single button
-25B6 FE0F ; fully-qualified # ▶️ E0.6 play button
-25B6 ; unqualified # ▶ E0.6 play button
-23E9 ; fully-qualified # ⏩ E0.6 fast-forward button
-23ED FE0F ; fully-qualified # ⏭️ E0.7 next track button
-23ED ; unqualified # ⏭ E0.7 next track button
-23EF FE0F ; fully-qualified # ⏯️ E1.0 play or pause button
-23EF ; unqualified # ⏯ E1.0 play or pause button
-25C0 FE0F ; fully-qualified # ◀️ E0.6 reverse button
-25C0 ; unqualified # ◀ E0.6 reverse button
-23EA ; fully-qualified # ⏪ E0.6 fast reverse button
-23EE FE0F ; fully-qualified # ⏮️ E0.7 last track button
-23EE ; unqualified # ⏮ E0.7 last track button
-1F53C ; fully-qualified # 🔼 E0.6 upwards button
-23EB ; fully-qualified # ⏫ E0.6 fast up button
-1F53D ; fully-qualified # 🔽 E0.6 downwards button
-23EC ; fully-qualified # ⏬ E0.6 fast down button
-23F8 FE0F ; fully-qualified # ⏸️ E0.7 pause button
-23F8 ; unqualified # ⏸ E0.7 pause button
-23F9 FE0F ; fully-qualified # ⏹️ E0.7 stop button
-23F9 ; unqualified # ⏹ E0.7 stop button
-23FA FE0F ; fully-qualified # ⏺️ E0.7 record button
-23FA ; unqualified # ⏺ E0.7 record button
-23CF FE0F ; fully-qualified # ⏏️ E1.0 eject button
-23CF ; unqualified # ⏏ E1.0 eject button
-1F3A6 ; fully-qualified # 🎦 E0.6 cinema
-1F505 ; fully-qualified # 🔅 E1.0 dim button
-1F506 ; fully-qualified # 🔆 E1.0 bright button
-1F4F6 ; fully-qualified # 📶 E0.6 antenna bars
-1F4F3 ; fully-qualified # 📳 E0.6 vibration mode
-1F4F4 ; fully-qualified # 📴 E0.6 mobile phone off
+1F500 ; fully-qualified # 🔀 E1.0 shuffle tracks button
+1F501 ; fully-qualified # 🔁 E1.0 repeat button
+1F502 ; fully-qualified # 🔂 E1.0 repeat single button
+25B6 FE0F ; fully-qualified # ▶️ E0.6 play button
+25B6 ; unqualified # ▶ E0.6 play button
+23E9 ; fully-qualified # ⏩ E0.6 fast-forward button
+23ED FE0F ; fully-qualified # ⏭️ E0.7 next track button
+23ED ; unqualified # ⏭ E0.7 next track button
+23EF FE0F ; fully-qualified # ⏯️ E1.0 play or pause button
+23EF ; unqualified # ⏯ E1.0 play or pause button
+25C0 FE0F ; fully-qualified # ◀️ E0.6 reverse button
+25C0 ; unqualified # ◀ E0.6 reverse button
+23EA ; fully-qualified # ⏪ E0.6 fast reverse button
+23EE FE0F ; fully-qualified # ⏮️ E0.7 last track button
+23EE ; unqualified # ⏮ E0.7 last track button
+1F53C ; fully-qualified # 🔼 E0.6 upwards button
+23EB ; fully-qualified # ⏫ E0.6 fast up button
+1F53D ; fully-qualified # 🔽 E0.6 downwards button
+23EC ; fully-qualified # ⏬ E0.6 fast down button
+23F8 FE0F ; fully-qualified # ⏸️ E0.7 pause button
+23F8 ; unqualified # ⏸ E0.7 pause button
+23F9 FE0F ; fully-qualified # ⏹️ E0.7 stop button
+23F9 ; unqualified # ⏹ E0.7 stop button
+23FA FE0F ; fully-qualified # ⏺️ E0.7 record button
+23FA ; unqualified # ⏺ E0.7 record button
+23CF FE0F ; fully-qualified # ⏏️ E1.0 eject button
+23CF ; unqualified # ⏏ E1.0 eject button
+1F3A6 ; fully-qualified # 🎦 E0.6 cinema
+1F505 ; fully-qualified # 🔅 E1.0 dim button
+1F506 ; fully-qualified # 🔆 E1.0 bright button
+1F4F6 ; fully-qualified # 📶 E0.6 antenna bars
+1F4F3 ; fully-qualified # 📳 E0.6 vibration mode
+1F4F4 ; fully-qualified # 📴 E0.6 mobile phone off
# subgroup: gender
-2640 FE0F ; fully-qualified # ♀️ E4.0 female sign
-2640 ; unqualified # ♀ E4.0 female sign
-2642 FE0F ; fully-qualified # ♂️ E4.0 male sign
-2642 ; unqualified # ♂ E4.0 male sign
-26A7 FE0F ; fully-qualified # ⚧️ E13.0 transgender symbol
-26A7 ; unqualified # ⚧ E13.0 transgender symbol
+2640 FE0F ; fully-qualified # ♀️ E4.0 female sign
+2640 ; unqualified # ♀ E4.0 female sign
+2642 FE0F ; fully-qualified # ♂️ E4.0 male sign
+2642 ; unqualified # ♂ E4.0 male sign
+26A7 FE0F ; fully-qualified # ⚧️ E13.0 transgender symbol
+26A7 ; unqualified # ⚧ E13.0 transgender symbol
# subgroup: math
-2716 FE0F ; fully-qualified # ✖️ E0.6 multiply
-2716 ; unqualified # ✖ E0.6 multiply
-2795 ; fully-qualified # ➕ E0.6 plus
-2796 ; fully-qualified # ➖ E0.6 minus
-2797 ; fully-qualified # ➗ E0.6 divide
-267E FE0F ; fully-qualified # ♾️ E11.0 infinity
-267E ; unqualified # ♾ E11.0 infinity
+2716 FE0F ; fully-qualified # ✖️ E0.6 multiply
+2716 ; unqualified # ✖ E0.6 multiply
+2795 ; fully-qualified # ➕ E0.6 plus
+2796 ; fully-qualified # ➖ E0.6 minus
+2797 ; fully-qualified # ➗ E0.6 divide
+267E FE0F ; fully-qualified # ♾️ E11.0 infinity
+267E ; unqualified # ♾ E11.0 infinity
# subgroup: punctuation
-203C FE0F ; fully-qualified # ‼️ E0.6 double exclamation mark
-203C ; unqualified # ‼ E0.6 double exclamation mark
-2049 FE0F ; fully-qualified # ⁉️ E0.6 exclamation question mark
-2049 ; unqualified # ⁉ E0.6 exclamation question mark
-2753 ; fully-qualified # ❓ E0.6 question mark
-2754 ; fully-qualified # ❔ E0.6 white question mark
-2755 ; fully-qualified # ❕ E0.6 white exclamation mark
-2757 ; fully-qualified # ❗ E0.6 exclamation mark
-3030 FE0F ; fully-qualified # 〰️ E0.6 wavy dash
-3030 ; unqualified # 〰 E0.6 wavy dash
+203C FE0F ; fully-qualified # ‼️ E0.6 double exclamation mark
+203C ; unqualified # ‼ E0.6 double exclamation mark
+2049 FE0F ; fully-qualified # ⁉️ E0.6 exclamation question mark
+2049 ; unqualified # ⁉ E0.6 exclamation question mark
+2753 ; fully-qualified # ❓ E0.6 red question mark
+2754 ; fully-qualified # ❔ E0.6 white question mark
+2755 ; fully-qualified # ❕ E0.6 white exclamation mark
+2757 ; fully-qualified # ❗ E0.6 red exclamation mark
+3030 FE0F ; fully-qualified # 〰️ E0.6 wavy dash
+3030 ; unqualified # 〰 E0.6 wavy dash
# subgroup: currency
-1F4B1 ; fully-qualified # 💱 E0.6 currency exchange
-1F4B2 ; fully-qualified # 💲 E0.6 heavy dollar sign
+1F4B1 ; fully-qualified # 💱 E0.6 currency exchange
+1F4B2 ; fully-qualified # 💲 E0.6 heavy dollar sign
# subgroup: other-symbol
-2695 FE0F ; fully-qualified # ⚕️ E4.0 medical symbol
-2695 ; unqualified # ⚕ E4.0 medical symbol
-267B FE0F ; fully-qualified # ♻️ E0.6 recycling symbol
-267B ; unqualified # ♻ E0.6 recycling symbol
-269C FE0F ; fully-qualified # ⚜️ E1.0 fleur-de-lis
-269C ; unqualified # ⚜ E1.0 fleur-de-lis
-1F531 ; fully-qualified # 🔱 E0.6 trident emblem
-1F4DB ; fully-qualified # 📛 E0.6 name badge
-1F530 ; fully-qualified # 🔰 E0.6 Japanese symbol for beginner
-2B55 ; fully-qualified # ⭕ E0.6 hollow red circle
-2705 ; fully-qualified # ✅ E0.6 check mark button
-2611 FE0F ; fully-qualified # ☑️ E0.6 check box with check
-2611 ; unqualified # ☑ E0.6 check box with check
-2714 FE0F ; fully-qualified # ✔️ E0.6 check mark
-2714 ; unqualified # ✔ E0.6 check mark
-274C ; fully-qualified # ❌ E0.6 cross mark
-274E ; fully-qualified # ❎ E0.6 cross mark button
-27B0 ; fully-qualified # ➰ E0.6 curly loop
-27BF ; fully-qualified # ➿ E1.0 double curly loop
-303D FE0F ; fully-qualified # 〽️ E0.6 part alternation mark
-303D ; unqualified # 〽 E0.6 part alternation mark
-2733 FE0F ; fully-qualified # ✳️ E0.6 eight-spoked asterisk
-2733 ; unqualified # ✳ E0.6 eight-spoked asterisk
-2734 FE0F ; fully-qualified # ✴️ E0.6 eight-pointed star
-2734 ; unqualified # ✴ E0.6 eight-pointed star
-2747 FE0F ; fully-qualified # ❇️ E0.6 sparkle
-2747 ; unqualified # ❇ E0.6 sparkle
-00A9 FE0F ; fully-qualified # ©️ E0.6 copyright
-00A9 ; unqualified # © E0.6 copyright
-00AE FE0F ; fully-qualified # ®️ E0.6 registered
-00AE ; unqualified # ® E0.6 registered
-2122 FE0F ; fully-qualified # ™️ E0.6 trade mark
-2122 ; unqualified # ™ E0.6 trade mark
+2695 FE0F ; fully-qualified # ⚕️ E4.0 medical symbol
+2695 ; unqualified # ⚕ E4.0 medical symbol
+267B FE0F ; fully-qualified # ♻️ E0.6 recycling symbol
+267B ; unqualified # ♻ E0.6 recycling symbol
+269C FE0F ; fully-qualified # ⚜️ E1.0 fleur-de-lis
+269C ; unqualified # ⚜ E1.0 fleur-de-lis
+1F531 ; fully-qualified # 🔱 E0.6 trident emblem
+1F4DB ; fully-qualified # 📛 E0.6 name badge
+1F530 ; fully-qualified # 🔰 E0.6 Japanese symbol for beginner
+2B55 ; fully-qualified # ⭕ E0.6 hollow red circle
+2705 ; fully-qualified # ✅ E0.6 check mark button
+2611 FE0F ; fully-qualified # ☑️ E0.6 check box with check
+2611 ; unqualified # ☑ E0.6 check box with check
+2714 FE0F ; fully-qualified # ✔️ E0.6 check mark
+2714 ; unqualified # ✔ E0.6 check mark
+274C ; fully-qualified # ❌ E0.6 cross mark
+274E ; fully-qualified # ❎ E0.6 cross mark button
+27B0 ; fully-qualified # ➰ E0.6 curly loop
+27BF ; fully-qualified # ➿ E1.0 double curly loop
+303D FE0F ; fully-qualified # 〽️ E0.6 part alternation mark
+303D ; unqualified # 〽 E0.6 part alternation mark
+2733 FE0F ; fully-qualified # ✳️ E0.6 eight-spoked asterisk
+2733 ; unqualified # ✳ E0.6 eight-spoked asterisk
+2734 FE0F ; fully-qualified # ✴️ E0.6 eight-pointed star
+2734 ; unqualified # ✴ E0.6 eight-pointed star
+2747 FE0F ; fully-qualified # ❇️ E0.6 sparkle
+2747 ; unqualified # ❇ E0.6 sparkle
+00A9 FE0F ; fully-qualified # ©️ E0.6 copyright
+00A9 ; unqualified # © E0.6 copyright
+00AE FE0F ; fully-qualified # ®️ E0.6 registered
+00AE ; unqualified # ® E0.6 registered
+2122 FE0F ; fully-qualified # ™️ E0.6 trade mark
+2122 ; unqualified # ™ E0.6 trade mark
# subgroup: keycap
-0023 FE0F 20E3 ; fully-qualified # #️⃣ E0.6 keycap: #
-0023 20E3 ; unqualified # #⃣ E0.6 keycap: #
-002A FE0F 20E3 ; fully-qualified # *️⃣ E2.0 keycap: *
-002A 20E3 ; unqualified # *⃣ E2.0 keycap: *
-0030 FE0F 20E3 ; fully-qualified # 0️⃣ E0.6 keycap: 0
-0030 20E3 ; unqualified # 0⃣ E0.6 keycap: 0
-0031 FE0F 20E3 ; fully-qualified # 1️⃣ E0.6 keycap: 1
-0031 20E3 ; unqualified # 1⃣ E0.6 keycap: 1
-0032 FE0F 20E3 ; fully-qualified # 2️⃣ E0.6 keycap: 2
-0032 20E3 ; unqualified # 2⃣ E0.6 keycap: 2
-0033 FE0F 20E3 ; fully-qualified # 3️⃣ E0.6 keycap: 3
-0033 20E3 ; unqualified # 3⃣ E0.6 keycap: 3
-0034 FE0F 20E3 ; fully-qualified # 4️⃣ E0.6 keycap: 4
-0034 20E3 ; unqualified # 4⃣ E0.6 keycap: 4
-0035 FE0F 20E3 ; fully-qualified # 5️⃣ E0.6 keycap: 5
-0035 20E3 ; unqualified # 5⃣ E0.6 keycap: 5
-0036 FE0F 20E3 ; fully-qualified # 6️⃣ E0.6 keycap: 6
-0036 20E3 ; unqualified # 6⃣ E0.6 keycap: 6
-0037 FE0F 20E3 ; fully-qualified # 7️⃣ E0.6 keycap: 7
-0037 20E3 ; unqualified # 7⃣ E0.6 keycap: 7
-0038 FE0F 20E3 ; fully-qualified # 8️⃣ E0.6 keycap: 8
-0038 20E3 ; unqualified # 8⃣ E0.6 keycap: 8
-0039 FE0F 20E3 ; fully-qualified # 9️⃣ E0.6 keycap: 9
-0039 20E3 ; unqualified # 9⃣ E0.6 keycap: 9
-1F51F ; fully-qualified # 🔟 E0.6 keycap: 10
+0023 FE0F 20E3 ; fully-qualified # #️⃣ E0.6 keycap: #
+0023 20E3 ; unqualified # #⃣ E0.6 keycap: #
+002A FE0F 20E3 ; fully-qualified # *️⃣ E2.0 keycap: *
+002A 20E3 ; unqualified # *⃣ E2.0 keycap: *
+0030 FE0F 20E3 ; fully-qualified # 0️⃣ E0.6 keycap: 0
+0030 20E3 ; unqualified # 0⃣ E0.6 keycap: 0
+0031 FE0F 20E3 ; fully-qualified # 1️⃣ E0.6 keycap: 1
+0031 20E3 ; unqualified # 1⃣ E0.6 keycap: 1
+0032 FE0F 20E3 ; fully-qualified # 2️⃣ E0.6 keycap: 2
+0032 20E3 ; unqualified # 2⃣ E0.6 keycap: 2
+0033 FE0F 20E3 ; fully-qualified # 3️⃣ E0.6 keycap: 3
+0033 20E3 ; unqualified # 3⃣ E0.6 keycap: 3
+0034 FE0F 20E3 ; fully-qualified # 4️⃣ E0.6 keycap: 4
+0034 20E3 ; unqualified # 4⃣ E0.6 keycap: 4
+0035 FE0F 20E3 ; fully-qualified # 5️⃣ E0.6 keycap: 5
+0035 20E3 ; unqualified # 5⃣ E0.6 keycap: 5
+0036 FE0F 20E3 ; fully-qualified # 6️⃣ E0.6 keycap: 6
+0036 20E3 ; unqualified # 6⃣ E0.6 keycap: 6
+0037 FE0F 20E3 ; fully-qualified # 7️⃣ E0.6 keycap: 7
+0037 20E3 ; unqualified # 7⃣ E0.6 keycap: 7
+0038 FE0F 20E3 ; fully-qualified # 8️⃣ E0.6 keycap: 8
+0038 20E3 ; unqualified # 8⃣ E0.6 keycap: 8
+0039 FE0F 20E3 ; fully-qualified # 9️⃣ E0.6 keycap: 9
+0039 20E3 ; unqualified # 9⃣ E0.6 keycap: 9
+1F51F ; fully-qualified # 🔟 E0.6 keycap: 10
# subgroup: alphanum
-1F520 ; fully-qualified # 🔠 E0.6 input latin uppercase
-1F521 ; fully-qualified # 🔡 E0.6 input latin lowercase
-1F522 ; fully-qualified # 🔢 E0.6 input numbers
-1F523 ; fully-qualified # 🔣 E0.6 input symbols
-1F524 ; fully-qualified # 🔤 E0.6 input latin letters
-1F170 FE0F ; fully-qualified # 🅰️ E0.6 A button (blood type)
-1F170 ; unqualified # 🅰 E0.6 A button (blood type)
-1F18E ; fully-qualified # 🆎 E0.6 AB button (blood type)
-1F171 FE0F ; fully-qualified # 🅱️ E0.6 B button (blood type)
-1F171 ; unqualified # 🅱 E0.6 B button (blood type)
-1F191 ; fully-qualified # 🆑 E0.6 CL button
-1F192 ; fully-qualified # 🆒 E0.6 COOL button
-1F193 ; fully-qualified # 🆓 E0.6 FREE button
-2139 FE0F ; fully-qualified # ℹ️ E0.6 information
-2139 ; unqualified # ℹ E0.6 information
-1F194 ; fully-qualified # 🆔 E0.6 ID button
-24C2 FE0F ; fully-qualified # Ⓜ️ E0.6 circled M
-24C2 ; unqualified # Ⓜ E0.6 circled M
-1F195 ; fully-qualified # 🆕 E0.6 NEW button
-1F196 ; fully-qualified # 🆖 E0.6 NG button
-1F17E FE0F ; fully-qualified # 🅾️ E0.6 O button (blood type)
-1F17E ; unqualified # 🅾 E0.6 O button (blood type)
-1F197 ; fully-qualified # 🆗 E0.6 OK button
-1F17F FE0F ; fully-qualified # 🅿️ E0.6 P button
-1F17F ; unqualified # 🅿 E0.6 P button
-1F198 ; fully-qualified # 🆘 E0.6 SOS button
-1F199 ; fully-qualified # 🆙 E0.6 UP! button
-1F19A ; fully-qualified # 🆚 E0.6 VS button
-1F201 ; fully-qualified # 🈁 E0.6 Japanese “here” button
-1F202 FE0F ; fully-qualified # 🈂️ E0.6 Japanese “service charge” button
-1F202 ; unqualified # 🈂 E0.6 Japanese “service charge” button
-1F237 FE0F ; fully-qualified # 🈷️ E0.6 Japanese “monthly amount” button
-1F237 ; unqualified # 🈷 E0.6 Japanese “monthly amount” button
-1F236 ; fully-qualified # 🈶 E0.6 Japanese “not free of charge” button
-1F22F ; fully-qualified # 🈯 E0.6 Japanese “reserved” button
-1F250 ; fully-qualified # 🉐 E0.6 Japanese “bargain” button
-1F239 ; fully-qualified # 🈹 E0.6 Japanese “discount” button
-1F21A ; fully-qualified # 🈚 E0.6 Japanese “free of charge” button
-1F232 ; fully-qualified # 🈲 E0.6 Japanese “prohibited” button
-1F251 ; fully-qualified # 🉑 E0.6 Japanese “acceptable” button
-1F238 ; fully-qualified # 🈸 E0.6 Japanese “application” button
-1F234 ; fully-qualified # 🈴 E0.6 Japanese “passing grade” button
-1F233 ; fully-qualified # 🈳 E0.6 Japanese “vacancy” button
-3297 FE0F ; fully-qualified # ㊗️ E0.6 Japanese “congratulations” button
-3297 ; unqualified # ㊗ E0.6 Japanese “congratulations” button
-3299 FE0F ; fully-qualified # ㊙️ E0.6 Japanese “secret” button
-3299 ; unqualified # ㊙ E0.6 Japanese “secret” button
-1F23A ; fully-qualified # 🈺 E0.6 Japanese “open for business” button
-1F235 ; fully-qualified # 🈵 E0.6 Japanese “no vacancy” button
+1F520 ; fully-qualified # 🔠 E0.6 input latin uppercase
+1F521 ; fully-qualified # 🔡 E0.6 input latin lowercase
+1F522 ; fully-qualified # 🔢 E0.6 input numbers
+1F523 ; fully-qualified # 🔣 E0.6 input symbols
+1F524 ; fully-qualified # 🔤 E0.6 input latin letters
+1F170 FE0F ; fully-qualified # 🅰️ E0.6 A button (blood type)
+1F170 ; unqualified # 🅰 E0.6 A button (blood type)
+1F18E ; fully-qualified # 🆎 E0.6 AB button (blood type)
+1F171 FE0F ; fully-qualified # 🅱️ E0.6 B button (blood type)
+1F171 ; unqualified # 🅱 E0.6 B button (blood type)
+1F191 ; fully-qualified # 🆑 E0.6 CL button
+1F192 ; fully-qualified # 🆒 E0.6 COOL button
+1F193 ; fully-qualified # 🆓 E0.6 FREE button
+2139 FE0F ; fully-qualified # ℹ️ E0.6 information
+2139 ; unqualified # ℹ E0.6 information
+1F194 ; fully-qualified # 🆔 E0.6 ID button
+24C2 FE0F ; fully-qualified # Ⓜ️ E0.6 circled M
+24C2 ; unqualified # Ⓜ E0.6 circled M
+1F195 ; fully-qualified # 🆕 E0.6 NEW button
+1F196 ; fully-qualified # 🆖 E0.6 NG button
+1F17E FE0F ; fully-qualified # 🅾️ E0.6 O button (blood type)
+1F17E ; unqualified # 🅾 E0.6 O button (blood type)
+1F197 ; fully-qualified # 🆗 E0.6 OK button
+1F17F FE0F ; fully-qualified # 🅿️ E0.6 P button
+1F17F ; unqualified # 🅿 E0.6 P button
+1F198 ; fully-qualified # 🆘 E0.6 SOS button
+1F199 ; fully-qualified # 🆙 E0.6 UP! button
+1F19A ; fully-qualified # 🆚 E0.6 VS button
+1F201 ; fully-qualified # 🈁 E0.6 Japanese “here” button
+1F202 FE0F ; fully-qualified # 🈂️ E0.6 Japanese “service charge” button
+1F202 ; unqualified # 🈂 E0.6 Japanese “service charge” button
+1F237 FE0F ; fully-qualified # 🈷️ E0.6 Japanese “monthly amount” button
+1F237 ; unqualified # 🈷 E0.6 Japanese “monthly amount” button
+1F236 ; fully-qualified # 🈶 E0.6 Japanese “not free of charge” button
+1F22F ; fully-qualified # 🈯 E0.6 Japanese “reserved” button
+1F250 ; fully-qualified # 🉐 E0.6 Japanese “bargain” button
+1F239 ; fully-qualified # 🈹 E0.6 Japanese “discount” button
+1F21A ; fully-qualified # 🈚 E0.6 Japanese “free of charge” button
+1F232 ; fully-qualified # 🈲 E0.6 Japanese “prohibited” button
+1F251 ; fully-qualified # 🉑 E0.6 Japanese “acceptable” button
+1F238 ; fully-qualified # 🈸 E0.6 Japanese “application” button
+1F234 ; fully-qualified # 🈴 E0.6 Japanese “passing grade” button
+1F233 ; fully-qualified # 🈳 E0.6 Japanese “vacancy” button
+3297 FE0F ; fully-qualified # ㊗️ E0.6 Japanese “congratulations” button
+3297 ; unqualified # ㊗ E0.6 Japanese “congratulations” button
+3299 FE0F ; fully-qualified # ㊙️ E0.6 Japanese “secret” button
+3299 ; unqualified # ㊙ E0.6 Japanese “secret” button
+1F23A ; fully-qualified # 🈺 E0.6 Japanese “open for business” button
+1F235 ; fully-qualified # 🈵 E0.6 Japanese “no vacancy” button
# subgroup: geometric
-1F534 ; fully-qualified # 🔴 E0.6 red circle
-1F7E0 ; fully-qualified # 🟠 E12.0 orange circle
-1F7E1 ; fully-qualified # 🟡 E12.0 yellow circle
-1F7E2 ; fully-qualified # 🟢 E12.0 green circle
-1F535 ; fully-qualified # 🔵 E0.6 blue circle
-1F7E3 ; fully-qualified # 🟣 E12.0 purple circle
-1F7E4 ; fully-qualified # 🟤 E12.0 brown circle
-26AB ; fully-qualified # ⚫ E0.6 black circle
-26AA ; fully-qualified # ⚪ E0.6 white circle
-1F7E5 ; fully-qualified # 🟥 E12.0 red square
-1F7E7 ; fully-qualified # 🟧 E12.0 orange square
-1F7E8 ; fully-qualified # 🟨 E12.0 yellow square
-1F7E9 ; fully-qualified # 🟩 E12.0 green square
-1F7E6 ; fully-qualified # 🟦 E12.0 blue square
-1F7EA ; fully-qualified # 🟪 E12.0 purple square
-1F7EB ; fully-qualified # 🟫 E12.0 brown square
-2B1B ; fully-qualified # ⬛ E0.6 black large square
-2B1C ; fully-qualified # ⬜ E0.6 white large square
-25FC FE0F ; fully-qualified # ◼️ E0.6 black medium square
-25FC ; unqualified # ◼ E0.6 black medium square
-25FB FE0F ; fully-qualified # ◻️ E0.6 white medium square
-25FB ; unqualified # ◻ E0.6 white medium square
-25FE ; fully-qualified # ◾ E0.6 black medium-small square
-25FD ; fully-qualified # ◽ E0.6 white medium-small square
-25AA FE0F ; fully-qualified # ▪️ E0.6 black small square
-25AA ; unqualified # ▪ E0.6 black small square
-25AB FE0F ; fully-qualified # ▫️ E0.6 white small square
-25AB ; unqualified # ▫ E0.6 white small square
-1F536 ; fully-qualified # 🔶 E0.6 large orange diamond
-1F537 ; fully-qualified # 🔷 E0.6 large blue diamond
-1F538 ; fully-qualified # 🔸 E0.6 small orange diamond
-1F539 ; fully-qualified # 🔹 E0.6 small blue diamond
-1F53A ; fully-qualified # 🔺 E0.6 red triangle pointed up
-1F53B ; fully-qualified # 🔻 E0.6 red triangle pointed down
-1F4A0 ; fully-qualified # 💠 E0.6 diamond with a dot
-1F518 ; fully-qualified # 🔘 E0.6 radio button
-1F533 ; fully-qualified # 🔳 E0.6 white square button
-1F532 ; fully-qualified # 🔲 E0.6 black square button
+1F534 ; fully-qualified # 🔴 E0.6 red circle
+1F7E0 ; fully-qualified # 🟠 E12.0 orange circle
+1F7E1 ; fully-qualified # 🟡 E12.0 yellow circle
+1F7E2 ; fully-qualified # 🟢 E12.0 green circle
+1F535 ; fully-qualified # 🔵 E0.6 blue circle
+1F7E3 ; fully-qualified # 🟣 E12.0 purple circle
+1F7E4 ; fully-qualified # 🟤 E12.0 brown circle
+26AB ; fully-qualified # ⚫ E0.6 black circle
+26AA ; fully-qualified # ⚪ E0.6 white circle
+1F7E5 ; fully-qualified # 🟥 E12.0 red square
+1F7E7 ; fully-qualified # 🟧 E12.0 orange square
+1F7E8 ; fully-qualified # 🟨 E12.0 yellow square
+1F7E9 ; fully-qualified # 🟩 E12.0 green square
+1F7E6 ; fully-qualified # 🟦 E12.0 blue square
+1F7EA ; fully-qualified # 🟪 E12.0 purple square
+1F7EB ; fully-qualified # 🟫 E12.0 brown square
+2B1B ; fully-qualified # ⬛ E0.6 black large square
+2B1C ; fully-qualified # ⬜ E0.6 white large square
+25FC FE0F ; fully-qualified # ◼️ E0.6 black medium square
+25FC ; unqualified # ◼ E0.6 black medium square
+25FB FE0F ; fully-qualified # ◻️ E0.6 white medium square
+25FB ; unqualified # ◻ E0.6 white medium square
+25FE ; fully-qualified # ◾ E0.6 black medium-small square
+25FD ; fully-qualified # ◽ E0.6 white medium-small square
+25AA FE0F ; fully-qualified # ▪️ E0.6 black small square
+25AA ; unqualified # ▪ E0.6 black small square
+25AB FE0F ; fully-qualified # ▫️ E0.6 white small square
+25AB ; unqualified # ▫ E0.6 white small square
+1F536 ; fully-qualified # 🔶 E0.6 large orange diamond
+1F537 ; fully-qualified # 🔷 E0.6 large blue diamond
+1F538 ; fully-qualified # 🔸 E0.6 small orange diamond
+1F539 ; fully-qualified # 🔹 E0.6 small blue diamond
+1F53A ; fully-qualified # 🔺 E0.6 red triangle pointed up
+1F53B ; fully-qualified # 🔻 E0.6 red triangle pointed down
+1F4A0 ; fully-qualified # 💠 E0.6 diamond with a dot
+1F518 ; fully-qualified # 🔘 E0.6 radio button
+1F533 ; fully-qualified # 🔳 E0.6 white square button
+1F532 ; fully-qualified # 🔲 E0.6 black square button
# Symbols subtotal: 301
# Symbols subtotal: 301 w/o modifiers
@@ -4165,293 +4587,293 @@
# group: Flags
# subgroup: flag
-1F3C1 ; fully-qualified # 🏁 E0.6 chequered flag
-1F6A9 ; fully-qualified # 🚩 E0.6 triangular flag
-1F38C ; fully-qualified # 🎌 E0.6 crossed flags
-1F3F4 ; fully-qualified # 🏴 E1.0 black flag
-1F3F3 FE0F ; fully-qualified # 🏳️ E0.7 white flag
-1F3F3 ; unqualified # 🏳 E0.7 white flag
-1F3F3 FE0F 200D 1F308 ; fully-qualified # 🏳️🌈 E4.0 rainbow flag
-1F3F3 200D 1F308 ; unqualified # 🏳🌈 E4.0 rainbow flag
-1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # 🏳️⚧️ E13.0 transgender flag
-1F3F3 200D 26A7 FE0F ; unqualified # 🏳⚧️ E13.0 transgender flag
-1F3F3 FE0F 200D 26A7 ; unqualified # 🏳️⚧ E13.0 transgender flag
-1F3F3 200D 26A7 ; unqualified # 🏳⚧ E13.0 transgender flag
-1F3F4 200D 2620 FE0F ; fully-qualified # 🏴☠️ E11.0 pirate flag
-1F3F4 200D 2620 ; minimally-qualified # 🏴☠ E11.0 pirate flag
+1F3C1 ; fully-qualified # 🏁 E0.6 chequered flag
+1F6A9 ; fully-qualified # 🚩 E0.6 triangular flag
+1F38C ; fully-qualified # 🎌 E0.6 crossed flags
+1F3F4 ; fully-qualified # 🏴 E1.0 black flag
+1F3F3 FE0F ; fully-qualified # 🏳️ E0.7 white flag
+1F3F3 ; unqualified # 🏳 E0.7 white flag
+1F3F3 FE0F 200D 1F308 ; fully-qualified # 🏳️🌈 E4.0 rainbow flag
+1F3F3 200D 1F308 ; unqualified # 🏳🌈 E4.0 rainbow flag
+1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # 🏳️⚧️ E13.0 transgender flag
+1F3F3 200D 26A7 FE0F ; unqualified # 🏳⚧️ E13.0 transgender flag
+1F3F3 FE0F 200D 26A7 ; unqualified # 🏳️⚧ E13.0 transgender flag
+1F3F3 200D 26A7 ; unqualified # 🏳⚧ E13.0 transgender flag
+1F3F4 200D 2620 FE0F ; fully-qualified # 🏴☠️ E11.0 pirate flag
+1F3F4 200D 2620 ; minimally-qualified # 🏴☠ E11.0 pirate flag
# subgroup: country-flag
-1F1E6 1F1E8 ; fully-qualified # 🇦🇨 E2.0 flag: Ascension Island
-1F1E6 1F1E9 ; fully-qualified # 🇦🇩 E2.0 flag: Andorra
-1F1E6 1F1EA ; fully-qualified # 🇦🇪 E2.0 flag: United Arab Emirates
-1F1E6 1F1EB ; fully-qualified # 🇦🇫 E2.0 flag: Afghanistan
-1F1E6 1F1EC ; fully-qualified # 🇦🇬 E2.0 flag: Antigua & Barbuda
-1F1E6 1F1EE ; fully-qualified # 🇦🇮 E2.0 flag: Anguilla
-1F1E6 1F1F1 ; fully-qualified # 🇦🇱 E2.0 flag: Albania
-1F1E6 1F1F2 ; fully-qualified # 🇦🇲 E2.0 flag: Armenia
-1F1E6 1F1F4 ; fully-qualified # 🇦🇴 E2.0 flag: Angola
-1F1E6 1F1F6 ; fully-qualified # 🇦🇶 E2.0 flag: Antarctica
-1F1E6 1F1F7 ; fully-qualified # 🇦🇷 E2.0 flag: Argentina
-1F1E6 1F1F8 ; fully-qualified # 🇦🇸 E2.0 flag: American Samoa
-1F1E6 1F1F9 ; fully-qualified # 🇦🇹 E2.0 flag: Austria
-1F1E6 1F1FA ; fully-qualified # 🇦🇺 E2.0 flag: Australia
-1F1E6 1F1FC ; fully-qualified # 🇦🇼 E2.0 flag: Aruba
-1F1E6 1F1FD ; fully-qualified # 🇦🇽 E2.0 flag: Åland Islands
-1F1E6 1F1FF ; fully-qualified # 🇦🇿 E2.0 flag: Azerbaijan
-1F1E7 1F1E6 ; fully-qualified # 🇧🇦 E2.0 flag: Bosnia & Herzegovina
-1F1E7 1F1E7 ; fully-qualified # 🇧🇧 E2.0 flag: Barbados
-1F1E7 1F1E9 ; fully-qualified # 🇧🇩 E2.0 flag: Bangladesh
-1F1E7 1F1EA ; fully-qualified # 🇧🇪 E2.0 flag: Belgium
-1F1E7 1F1EB ; fully-qualified # 🇧🇫 E2.0 flag: Burkina Faso
-1F1E7 1F1EC ; fully-qualified # 🇧🇬 E2.0 flag: Bulgaria
-1F1E7 1F1ED ; fully-qualified # 🇧🇭 E2.0 flag: Bahrain
-1F1E7 1F1EE ; fully-qualified # 🇧🇮 E2.0 flag: Burundi
-1F1E7 1F1EF ; fully-qualified # 🇧🇯 E2.0 flag: Benin
-1F1E7 1F1F1 ; fully-qualified # 🇧🇱 E2.0 flag: St. Barthélemy
-1F1E7 1F1F2 ; fully-qualified # 🇧🇲 E2.0 flag: Bermuda
-1F1E7 1F1F3 ; fully-qualified # 🇧🇳 E2.0 flag: Brunei
-1F1E7 1F1F4 ; fully-qualified # 🇧🇴 E2.0 flag: Bolivia
-1F1E7 1F1F6 ; fully-qualified # 🇧🇶 E2.0 flag: Caribbean Netherlands
-1F1E7 1F1F7 ; fully-qualified # 🇧🇷 E2.0 flag: Brazil
-1F1E7 1F1F8 ; fully-qualified # 🇧🇸 E2.0 flag: Bahamas
-1F1E7 1F1F9 ; fully-qualified # 🇧🇹 E2.0 flag: Bhutan
-1F1E7 1F1FB ; fully-qualified # 🇧🇻 E2.0 flag: Bouvet Island
-1F1E7 1F1FC ; fully-qualified # 🇧🇼 E2.0 flag: Botswana
-1F1E7 1F1FE ; fully-qualified # 🇧🇾 E2.0 flag: Belarus
-1F1E7 1F1FF ; fully-qualified # 🇧🇿 E2.0 flag: Belize
-1F1E8 1F1E6 ; fully-qualified # 🇨🇦 E2.0 flag: Canada
-1F1E8 1F1E8 ; fully-qualified # 🇨🇨 E2.0 flag: Cocos (Keeling) Islands
-1F1E8 1F1E9 ; fully-qualified # 🇨🇩 E2.0 flag: Congo - Kinshasa
-1F1E8 1F1EB ; fully-qualified # 🇨🇫 E2.0 flag: Central African Republic
-1F1E8 1F1EC ; fully-qualified # 🇨🇬 E2.0 flag: Congo - Brazzaville
-1F1E8 1F1ED ; fully-qualified # 🇨🇭 E2.0 flag: Switzerland
-1F1E8 1F1EE ; fully-qualified # 🇨🇮 E2.0 flag: Côte d’Ivoire
-1F1E8 1F1F0 ; fully-qualified # 🇨🇰 E2.0 flag: Cook Islands
-1F1E8 1F1F1 ; fully-qualified # 🇨🇱 E2.0 flag: Chile
-1F1E8 1F1F2 ; fully-qualified # 🇨🇲 E2.0 flag: Cameroon
-1F1E8 1F1F3 ; fully-qualified # 🇨🇳 E0.6 flag: China
-1F1E8 1F1F4 ; fully-qualified # 🇨🇴 E2.0 flag: Colombia
-1F1E8 1F1F5 ; fully-qualified # 🇨🇵 E2.0 flag: Clipperton Island
-1F1E8 1F1F7 ; fully-qualified # 🇨🇷 E2.0 flag: Costa Rica
-1F1E8 1F1FA ; fully-qualified # 🇨🇺 E2.0 flag: Cuba
-1F1E8 1F1FB ; fully-qualified # 🇨🇻 E2.0 flag: Cape Verde
-1F1E8 1F1FC ; fully-qualified # 🇨🇼 E2.0 flag: Curaçao
-1F1E8 1F1FD ; fully-qualified # 🇨🇽 E2.0 flag: Christmas Island
-1F1E8 1F1FE ; fully-qualified # 🇨🇾 E2.0 flag: Cyprus
-1F1E8 1F1FF ; fully-qualified # 🇨🇿 E2.0 flag: Czechia
-1F1E9 1F1EA ; fully-qualified # 🇩🇪 E0.6 flag: Germany
-1F1E9 1F1EC ; fully-qualified # 🇩🇬 E2.0 flag: Diego Garcia
-1F1E9 1F1EF ; fully-qualified # 🇩🇯 E2.0 flag: Djibouti
-1F1E9 1F1F0 ; fully-qualified # 🇩🇰 E2.0 flag: Denmark
-1F1E9 1F1F2 ; fully-qualified # 🇩🇲 E2.0 flag: Dominica
-1F1E9 1F1F4 ; fully-qualified # 🇩🇴 E2.0 flag: Dominican Republic
-1F1E9 1F1FF ; fully-qualified # 🇩🇿 E2.0 flag: Algeria
-1F1EA 1F1E6 ; fully-qualified # 🇪🇦 E2.0 flag: Ceuta & Melilla
-1F1EA 1F1E8 ; fully-qualified # 🇪🇨 E2.0 flag: Ecuador
-1F1EA 1F1EA ; fully-qualified # 🇪🇪 E2.0 flag: Estonia
-1F1EA 1F1EC ; fully-qualified # 🇪🇬 E2.0 flag: Egypt
-1F1EA 1F1ED ; fully-qualified # 🇪🇭 E2.0 flag: Western Sahara
-1F1EA 1F1F7 ; fully-qualified # 🇪🇷 E2.0 flag: Eritrea
-1F1EA 1F1F8 ; fully-qualified # 🇪🇸 E0.6 flag: Spain
-1F1EA 1F1F9 ; fully-qualified # 🇪🇹 E2.0 flag: Ethiopia
-1F1EA 1F1FA ; fully-qualified # 🇪🇺 E2.0 flag: European Union
-1F1EB 1F1EE ; fully-qualified # 🇫🇮 E2.0 flag: Finland
-1F1EB 1F1EF ; fully-qualified # 🇫🇯 E2.0 flag: Fiji
-1F1EB 1F1F0 ; fully-qualified # 🇫🇰 E2.0 flag: Falkland Islands
-1F1EB 1F1F2 ; fully-qualified # 🇫🇲 E2.0 flag: Micronesia
-1F1EB 1F1F4 ; fully-qualified # 🇫🇴 E2.0 flag: Faroe Islands
-1F1EB 1F1F7 ; fully-qualified # 🇫🇷 E0.6 flag: France
-1F1EC 1F1E6 ; fully-qualified # 🇬🇦 E2.0 flag: Gabon
-1F1EC 1F1E7 ; fully-qualified # 🇬🇧 E0.6 flag: United Kingdom
-1F1EC 1F1E9 ; fully-qualified # 🇬🇩 E2.0 flag: Grenada
-1F1EC 1F1EA ; fully-qualified # 🇬🇪 E2.0 flag: Georgia
-1F1EC 1F1EB ; fully-qualified # 🇬🇫 E2.0 flag: French Guiana
-1F1EC 1F1EC ; fully-qualified # 🇬🇬 E2.0 flag: Guernsey
-1F1EC 1F1ED ; fully-qualified # 🇬🇭 E2.0 flag: Ghana
-1F1EC 1F1EE ; fully-qualified # 🇬🇮 E2.0 flag: Gibraltar
-1F1EC 1F1F1 ; fully-qualified # 🇬🇱 E2.0 flag: Greenland
-1F1EC 1F1F2 ; fully-qualified # 🇬🇲 E2.0 flag: Gambia
-1F1EC 1F1F3 ; fully-qualified # 🇬🇳 E2.0 flag: Guinea
-1F1EC 1F1F5 ; fully-qualified # 🇬🇵 E2.0 flag: Guadeloupe
-1F1EC 1F1F6 ; fully-qualified # 🇬🇶 E2.0 flag: Equatorial Guinea
-1F1EC 1F1F7 ; fully-qualified # 🇬🇷 E2.0 flag: Greece
-1F1EC 1F1F8 ; fully-qualified # 🇬🇸 E2.0 flag: South Georgia & South Sandwich Islands
-1F1EC 1F1F9 ; fully-qualified # 🇬🇹 E2.0 flag: Guatemala
-1F1EC 1F1FA ; fully-qualified # 🇬🇺 E2.0 flag: Guam
-1F1EC 1F1FC ; fully-qualified # 🇬🇼 E2.0 flag: Guinea-Bissau
-1F1EC 1F1FE ; fully-qualified # 🇬🇾 E2.0 flag: Guyana
-1F1ED 1F1F0 ; fully-qualified # 🇭🇰 E2.0 flag: Hong Kong SAR China
-1F1ED 1F1F2 ; fully-qualified # 🇭🇲 E2.0 flag: Heard & McDonald Islands
-1F1ED 1F1F3 ; fully-qualified # 🇭🇳 E2.0 flag: Honduras
-1F1ED 1F1F7 ; fully-qualified # 🇭🇷 E2.0 flag: Croatia
-1F1ED 1F1F9 ; fully-qualified # 🇭🇹 E2.0 flag: Haiti
-1F1ED 1F1FA ; fully-qualified # 🇭🇺 E2.0 flag: Hungary
-1F1EE 1F1E8 ; fully-qualified # 🇮🇨 E2.0 flag: Canary Islands
-1F1EE 1F1E9 ; fully-qualified # 🇮🇩 E2.0 flag: Indonesia
-1F1EE 1F1EA ; fully-qualified # 🇮🇪 E2.0 flag: Ireland
-1F1EE 1F1F1 ; fully-qualified # 🇮🇱 E2.0 flag: Israel
-1F1EE 1F1F2 ; fully-qualified # 🇮🇲 E2.0 flag: Isle of Man
-1F1EE 1F1F3 ; fully-qualified # 🇮🇳 E2.0 flag: India
-1F1EE 1F1F4 ; fully-qualified # 🇮🇴 E2.0 flag: British Indian Ocean Territory
-1F1EE 1F1F6 ; fully-qualified # 🇮🇶 E2.0 flag: Iraq
-1F1EE 1F1F7 ; fully-qualified # 🇮🇷 E2.0 flag: Iran
-1F1EE 1F1F8 ; fully-qualified # 🇮🇸 E2.0 flag: Iceland
-1F1EE 1F1F9 ; fully-qualified # 🇮🇹 E0.6 flag: Italy
-1F1EF 1F1EA ; fully-qualified # 🇯🇪 E2.0 flag: Jersey
-1F1EF 1F1F2 ; fully-qualified # 🇯🇲 E2.0 flag: Jamaica
-1F1EF 1F1F4 ; fully-qualified # 🇯🇴 E2.0 flag: Jordan
-1F1EF 1F1F5 ; fully-qualified # 🇯🇵 E0.6 flag: Japan
-1F1F0 1F1EA ; fully-qualified # 🇰🇪 E2.0 flag: Kenya
-1F1F0 1F1EC ; fully-qualified # 🇰🇬 E2.0 flag: Kyrgyzstan
-1F1F0 1F1ED ; fully-qualified # 🇰🇭 E2.0 flag: Cambodia
-1F1F0 1F1EE ; fully-qualified # 🇰🇮 E2.0 flag: Kiribati
-1F1F0 1F1F2 ; fully-qualified # 🇰🇲 E2.0 flag: Comoros
-1F1F0 1F1F3 ; fully-qualified # 🇰🇳 E2.0 flag: St. Kitts & Nevis
-1F1F0 1F1F5 ; fully-qualified # 🇰🇵 E2.0 flag: North Korea
-1F1F0 1F1F7 ; fully-qualified # 🇰🇷 E0.6 flag: South Korea
-1F1F0 1F1FC ; fully-qualified # 🇰🇼 E2.0 flag: Kuwait
-1F1F0 1F1FE ; fully-qualified # 🇰🇾 E2.0 flag: Cayman Islands
-1F1F0 1F1FF ; fully-qualified # 🇰🇿 E2.0 flag: Kazakhstan
-1F1F1 1F1E6 ; fully-qualified # 🇱🇦 E2.0 flag: Laos
-1F1F1 1F1E7 ; fully-qualified # 🇱🇧 E2.0 flag: Lebanon
-1F1F1 1F1E8 ; fully-qualified # 🇱🇨 E2.0 flag: St. Lucia
-1F1F1 1F1EE ; fully-qualified # 🇱🇮 E2.0 flag: Liechtenstein
-1F1F1 1F1F0 ; fully-qualified # 🇱🇰 E2.0 flag: Sri Lanka
-1F1F1 1F1F7 ; fully-qualified # 🇱🇷 E2.0 flag: Liberia
-1F1F1 1F1F8 ; fully-qualified # 🇱🇸 E2.0 flag: Lesotho
-1F1F1 1F1F9 ; fully-qualified # 🇱🇹 E2.0 flag: Lithuania
-1F1F1 1F1FA ; fully-qualified # 🇱🇺 E2.0 flag: Luxembourg
-1F1F1 1F1FB ; fully-qualified # 🇱🇻 E2.0 flag: Latvia
-1F1F1 1F1FE ; fully-qualified # 🇱🇾 E2.0 flag: Libya
-1F1F2 1F1E6 ; fully-qualified # 🇲🇦 E2.0 flag: Morocco
-1F1F2 1F1E8 ; fully-qualified # 🇲🇨 E2.0 flag: Monaco
-1F1F2 1F1E9 ; fully-qualified # 🇲🇩 E2.0 flag: Moldova
-1F1F2 1F1EA ; fully-qualified # 🇲🇪 E2.0 flag: Montenegro
-1F1F2 1F1EB ; fully-qualified # 🇲🇫 E2.0 flag: St. Martin
-1F1F2 1F1EC ; fully-qualified # 🇲🇬 E2.0 flag: Madagascar
-1F1F2 1F1ED ; fully-qualified # 🇲🇭 E2.0 flag: Marshall Islands
-1F1F2 1F1F0 ; fully-qualified # 🇲🇰 E2.0 flag: North Macedonia
-1F1F2 1F1F1 ; fully-qualified # 🇲🇱 E2.0 flag: Mali
-1F1F2 1F1F2 ; fully-qualified # 🇲🇲 E2.0 flag: Myanmar (Burma)
-1F1F2 1F1F3 ; fully-qualified # 🇲🇳 E2.0 flag: Mongolia
-1F1F2 1F1F4 ; fully-qualified # 🇲🇴 E2.0 flag: Macao SAR China
-1F1F2 1F1F5 ; fully-qualified # 🇲🇵 E2.0 flag: Northern Mariana Islands
-1F1F2 1F1F6 ; fully-qualified # 🇲🇶 E2.0 flag: Martinique
-1F1F2 1F1F7 ; fully-qualified # 🇲🇷 E2.0 flag: Mauritania
-1F1F2 1F1F8 ; fully-qualified # 🇲🇸 E2.0 flag: Montserrat
-1F1F2 1F1F9 ; fully-qualified # 🇲🇹 E2.0 flag: Malta
-1F1F2 1F1FA ; fully-qualified # 🇲🇺 E2.0 flag: Mauritius
-1F1F2 1F1FB ; fully-qualified # 🇲🇻 E2.0 flag: Maldives
-1F1F2 1F1FC ; fully-qualified # 🇲🇼 E2.0 flag: Malawi
-1F1F2 1F1FD ; fully-qualified # 🇲🇽 E2.0 flag: Mexico
-1F1F2 1F1FE ; fully-qualified # 🇲🇾 E2.0 flag: Malaysia
-1F1F2 1F1FF ; fully-qualified # 🇲🇿 E2.0 flag: Mozambique
-1F1F3 1F1E6 ; fully-qualified # 🇳🇦 E2.0 flag: Namibia
-1F1F3 1F1E8 ; fully-qualified # 🇳🇨 E2.0 flag: New Caledonia
-1F1F3 1F1EA ; fully-qualified # 🇳🇪 E2.0 flag: Niger
-1F1F3 1F1EB ; fully-qualified # 🇳🇫 E2.0 flag: Norfolk Island
-1F1F3 1F1EC ; fully-qualified # 🇳🇬 E2.0 flag: Nigeria
-1F1F3 1F1EE ; fully-qualified # 🇳🇮 E2.0 flag: Nicaragua
-1F1F3 1F1F1 ; fully-qualified # 🇳🇱 E2.0 flag: Netherlands
-1F1F3 1F1F4 ; fully-qualified # 🇳🇴 E2.0 flag: Norway
-1F1F3 1F1F5 ; fully-qualified # 🇳🇵 E2.0 flag: Nepal
-1F1F3 1F1F7 ; fully-qualified # 🇳🇷 E2.0 flag: Nauru
-1F1F3 1F1FA ; fully-qualified # 🇳🇺 E2.0 flag: Niue
-1F1F3 1F1FF ; fully-qualified # 🇳🇿 E2.0 flag: New Zealand
-1F1F4 1F1F2 ; fully-qualified # 🇴🇲 E2.0 flag: Oman
-1F1F5 1F1E6 ; fully-qualified # 🇵🇦 E2.0 flag: Panama
-1F1F5 1F1EA ; fully-qualified # 🇵🇪 E2.0 flag: Peru
-1F1F5 1F1EB ; fully-qualified # 🇵🇫 E2.0 flag: French Polynesia
-1F1F5 1F1EC ; fully-qualified # 🇵🇬 E2.0 flag: Papua New Guinea
-1F1F5 1F1ED ; fully-qualified # 🇵🇭 E2.0 flag: Philippines
-1F1F5 1F1F0 ; fully-qualified # 🇵🇰 E2.0 flag: Pakistan
-1F1F5 1F1F1 ; fully-qualified # 🇵🇱 E2.0 flag: Poland
-1F1F5 1F1F2 ; fully-qualified # 🇵🇲 E2.0 flag: St. Pierre & Miquelon
-1F1F5 1F1F3 ; fully-qualified # 🇵🇳 E2.0 flag: Pitcairn Islands
-1F1F5 1F1F7 ; fully-qualified # 🇵🇷 E2.0 flag: Puerto Rico
-1F1F5 1F1F8 ; fully-qualified # 🇵🇸 E2.0 flag: Palestinian Territories
-1F1F5 1F1F9 ; fully-qualified # 🇵🇹 E2.0 flag: Portugal
-1F1F5 1F1FC ; fully-qualified # 🇵🇼 E2.0 flag: Palau
-1F1F5 1F1FE ; fully-qualified # 🇵🇾 E2.0 flag: Paraguay
-1F1F6 1F1E6 ; fully-qualified # 🇶🇦 E2.0 flag: Qatar
-1F1F7 1F1EA ; fully-qualified # 🇷🇪 E2.0 flag: Réunion
-1F1F7 1F1F4 ; fully-qualified # 🇷🇴 E2.0 flag: Romania
-1F1F7 1F1F8 ; fully-qualified # 🇷🇸 E2.0 flag: Serbia
-1F1F7 1F1FA ; fully-qualified # 🇷🇺 E0.6 flag: Russia
-1F1F7 1F1FC ; fully-qualified # 🇷🇼 E2.0 flag: Rwanda
-1F1F8 1F1E6 ; fully-qualified # 🇸🇦 E2.0 flag: Saudi Arabia
-1F1F8 1F1E7 ; fully-qualified # 🇸🇧 E2.0 flag: Solomon Islands
-1F1F8 1F1E8 ; fully-qualified # 🇸🇨 E2.0 flag: Seychelles
-1F1F8 1F1E9 ; fully-qualified # 🇸🇩 E2.0 flag: Sudan
-1F1F8 1F1EA ; fully-qualified # 🇸🇪 E2.0 flag: Sweden
-1F1F8 1F1EC ; fully-qualified # 🇸🇬 E2.0 flag: Singapore
-1F1F8 1F1ED ; fully-qualified # 🇸🇭 E2.0 flag: St. Helena
-1F1F8 1F1EE ; fully-qualified # 🇸🇮 E2.0 flag: Slovenia
-1F1F8 1F1EF ; fully-qualified # 🇸🇯 E2.0 flag: Svalbard & Jan Mayen
-1F1F8 1F1F0 ; fully-qualified # 🇸🇰 E2.0 flag: Slovakia
-1F1F8 1F1F1 ; fully-qualified # 🇸🇱 E2.0 flag: Sierra Leone
-1F1F8 1F1F2 ; fully-qualified # 🇸🇲 E2.0 flag: San Marino
-1F1F8 1F1F3 ; fully-qualified # 🇸🇳 E2.0 flag: Senegal
-1F1F8 1F1F4 ; fully-qualified # 🇸🇴 E2.0 flag: Somalia
-1F1F8 1F1F7 ; fully-qualified # 🇸🇷 E2.0 flag: Suriname
-1F1F8 1F1F8 ; fully-qualified # 🇸🇸 E2.0 flag: South Sudan
-1F1F8 1F1F9 ; fully-qualified # 🇸🇹 E2.0 flag: São Tomé & Príncipe
-1F1F8 1F1FB ; fully-qualified # 🇸🇻 E2.0 flag: El Salvador
-1F1F8 1F1FD ; fully-qualified # 🇸🇽 E2.0 flag: Sint Maarten
-1F1F8 1F1FE ; fully-qualified # 🇸🇾 E2.0 flag: Syria
-1F1F8 1F1FF ; fully-qualified # 🇸🇿 E2.0 flag: Eswatini
-1F1F9 1F1E6 ; fully-qualified # 🇹🇦 E2.0 flag: Tristan da Cunha
-1F1F9 1F1E8 ; fully-qualified # 🇹🇨 E2.0 flag: Turks & Caicos Islands
-1F1F9 1F1E9 ; fully-qualified # 🇹🇩 E2.0 flag: Chad
-1F1F9 1F1EB ; fully-qualified # 🇹🇫 E2.0 flag: French Southern Territories
-1F1F9 1F1EC ; fully-qualified # 🇹🇬 E2.0 flag: Togo
-1F1F9 1F1ED ; fully-qualified # 🇹🇭 E2.0 flag: Thailand
-1F1F9 1F1EF ; fully-qualified # 🇹🇯 E2.0 flag: Tajikistan
-1F1F9 1F1F0 ; fully-qualified # 🇹🇰 E2.0 flag: Tokelau
-1F1F9 1F1F1 ; fully-qualified # 🇹🇱 E2.0 flag: Timor-Leste
-1F1F9 1F1F2 ; fully-qualified # 🇹🇲 E2.0 flag: Turkmenistan
-1F1F9 1F1F3 ; fully-qualified # 🇹🇳 E2.0 flag: Tunisia
-1F1F9 1F1F4 ; fully-qualified # 🇹🇴 E2.0 flag: Tonga
-1F1F9 1F1F7 ; fully-qualified # 🇹🇷 E2.0 flag: Turkey
-1F1F9 1F1F9 ; fully-qualified # 🇹🇹 E2.0 flag: Trinidad & Tobago
-1F1F9 1F1FB ; fully-qualified # 🇹🇻 E2.0 flag: Tuvalu
-1F1F9 1F1FC ; fully-qualified # 🇹🇼 E2.0 flag: Taiwan
-1F1F9 1F1FF ; fully-qualified # 🇹🇿 E2.0 flag: Tanzania
-1F1FA 1F1E6 ; fully-qualified # 🇺🇦 E2.0 flag: Ukraine
-1F1FA 1F1EC ; fully-qualified # 🇺🇬 E2.0 flag: Uganda
-1F1FA 1F1F2 ; fully-qualified # 🇺🇲 E2.0 flag: U.S. Outlying Islands
-1F1FA 1F1F3 ; fully-qualified # 🇺🇳 E4.0 flag: United Nations
-1F1FA 1F1F8 ; fully-qualified # 🇺🇸 E0.6 flag: United States
-1F1FA 1F1FE ; fully-qualified # 🇺🇾 E2.0 flag: Uruguay
-1F1FA 1F1FF ; fully-qualified # 🇺🇿 E2.0 flag: Uzbekistan
-1F1FB 1F1E6 ; fully-qualified # 🇻🇦 E2.0 flag: Vatican City
-1F1FB 1F1E8 ; fully-qualified # 🇻🇨 E2.0 flag: St. Vincent & Grenadines
-1F1FB 1F1EA ; fully-qualified # 🇻🇪 E2.0 flag: Venezuela
-1F1FB 1F1EC ; fully-qualified # 🇻🇬 E2.0 flag: British Virgin Islands
-1F1FB 1F1EE ; fully-qualified # 🇻🇮 E2.0 flag: U.S. Virgin Islands
-1F1FB 1F1F3 ; fully-qualified # 🇻🇳 E2.0 flag: Vietnam
-1F1FB 1F1FA ; fully-qualified # 🇻🇺 E2.0 flag: Vanuatu
-1F1FC 1F1EB ; fully-qualified # 🇼🇫 E2.0 flag: Wallis & Futuna
-1F1FC 1F1F8 ; fully-qualified # 🇼🇸 E2.0 flag: Samoa
-1F1FD 1F1F0 ; fully-qualified # 🇽🇰 E2.0 flag: Kosovo
-1F1FE 1F1EA ; fully-qualified # 🇾🇪 E2.0 flag: Yemen
-1F1FE 1F1F9 ; fully-qualified # 🇾🇹 E2.0 flag: Mayotte
-1F1FF 1F1E6 ; fully-qualified # 🇿🇦 E2.0 flag: South Africa
-1F1FF 1F1F2 ; fully-qualified # 🇿🇲 E2.0 flag: Zambia
-1F1FF 1F1FC ; fully-qualified # 🇿🇼 E2.0 flag: Zimbabwe
+1F1E6 1F1E8 ; fully-qualified # 🇦🇨 E2.0 flag: Ascension Island
+1F1E6 1F1E9 ; fully-qualified # 🇦🇩 E2.0 flag: Andorra
+1F1E6 1F1EA ; fully-qualified # 🇦🇪 E2.0 flag: United Arab Emirates
+1F1E6 1F1EB ; fully-qualified # 🇦🇫 E2.0 flag: Afghanistan
+1F1E6 1F1EC ; fully-qualified # 🇦🇬 E2.0 flag: Antigua & Barbuda
+1F1E6 1F1EE ; fully-qualified # 🇦🇮 E2.0 flag: Anguilla
+1F1E6 1F1F1 ; fully-qualified # 🇦🇱 E2.0 flag: Albania
+1F1E6 1F1F2 ; fully-qualified # 🇦🇲 E2.0 flag: Armenia
+1F1E6 1F1F4 ; fully-qualified # 🇦🇴 E2.0 flag: Angola
+1F1E6 1F1F6 ; fully-qualified # 🇦🇶 E2.0 flag: Antarctica
+1F1E6 1F1F7 ; fully-qualified # 🇦🇷 E2.0 flag: Argentina
+1F1E6 1F1F8 ; fully-qualified # 🇦🇸 E2.0 flag: American Samoa
+1F1E6 1F1F9 ; fully-qualified # 🇦🇹 E2.0 flag: Austria
+1F1E6 1F1FA ; fully-qualified # 🇦🇺 E2.0 flag: Australia
+1F1E6 1F1FC ; fully-qualified # 🇦🇼 E2.0 flag: Aruba
+1F1E6 1F1FD ; fully-qualified # 🇦🇽 E2.0 flag: Åland Islands
+1F1E6 1F1FF ; fully-qualified # 🇦🇿 E2.0 flag: Azerbaijan
+1F1E7 1F1E6 ; fully-qualified # 🇧🇦 E2.0 flag: Bosnia & Herzegovina
+1F1E7 1F1E7 ; fully-qualified # 🇧🇧 E2.0 flag: Barbados
+1F1E7 1F1E9 ; fully-qualified # 🇧🇩 E2.0 flag: Bangladesh
+1F1E7 1F1EA ; fully-qualified # 🇧🇪 E2.0 flag: Belgium
+1F1E7 1F1EB ; fully-qualified # 🇧🇫 E2.0 flag: Burkina Faso
+1F1E7 1F1EC ; fully-qualified # 🇧🇬 E2.0 flag: Bulgaria
+1F1E7 1F1ED ; fully-qualified # 🇧🇭 E2.0 flag: Bahrain
+1F1E7 1F1EE ; fully-qualified # 🇧🇮 E2.0 flag: Burundi
+1F1E7 1F1EF ; fully-qualified # 🇧🇯 E2.0 flag: Benin
+1F1E7 1F1F1 ; fully-qualified # 🇧🇱 E2.0 flag: St. Barthélemy
+1F1E7 1F1F2 ; fully-qualified # 🇧🇲 E2.0 flag: Bermuda
+1F1E7 1F1F3 ; fully-qualified # 🇧🇳 E2.0 flag: Brunei
+1F1E7 1F1F4 ; fully-qualified # 🇧🇴 E2.0 flag: Bolivia
+1F1E7 1F1F6 ; fully-qualified # 🇧🇶 E2.0 flag: Caribbean Netherlands
+1F1E7 1F1F7 ; fully-qualified # 🇧🇷 E2.0 flag: Brazil
+1F1E7 1F1F8 ; fully-qualified # 🇧🇸 E2.0 flag: Bahamas
+1F1E7 1F1F9 ; fully-qualified # 🇧🇹 E2.0 flag: Bhutan
+1F1E7 1F1FB ; fully-qualified # 🇧🇻 E2.0 flag: Bouvet Island
+1F1E7 1F1FC ; fully-qualified # 🇧🇼 E2.0 flag: Botswana
+1F1E7 1F1FE ; fully-qualified # 🇧🇾 E2.0 flag: Belarus
+1F1E7 1F1FF ; fully-qualified # 🇧🇿 E2.0 flag: Belize
+1F1E8 1F1E6 ; fully-qualified # 🇨🇦 E2.0 flag: Canada
+1F1E8 1F1E8 ; fully-qualified # 🇨🇨 E2.0 flag: Cocos (Keeling) Islands
+1F1E8 1F1E9 ; fully-qualified # 🇨🇩 E2.0 flag: Congo - Kinshasa
+1F1E8 1F1EB ; fully-qualified # 🇨🇫 E2.0 flag: Central African Republic
+1F1E8 1F1EC ; fully-qualified # 🇨🇬 E2.0 flag: Congo - Brazzaville
+1F1E8 1F1ED ; fully-qualified # 🇨🇭 E2.0 flag: Switzerland
+1F1E8 1F1EE ; fully-qualified # 🇨🇮 E2.0 flag: Côte d’Ivoire
+1F1E8 1F1F0 ; fully-qualified # 🇨🇰 E2.0 flag: Cook Islands
+1F1E8 1F1F1 ; fully-qualified # 🇨🇱 E2.0 flag: Chile
+1F1E8 1F1F2 ; fully-qualified # 🇨🇲 E2.0 flag: Cameroon
+1F1E8 1F1F3 ; fully-qualified # 🇨🇳 E0.6 flag: China
+1F1E8 1F1F4 ; fully-qualified # 🇨🇴 E2.0 flag: Colombia
+1F1E8 1F1F5 ; fully-qualified # 🇨🇵 E2.0 flag: Clipperton Island
+1F1E8 1F1F7 ; fully-qualified # 🇨🇷 E2.0 flag: Costa Rica
+1F1E8 1F1FA ; fully-qualified # 🇨🇺 E2.0 flag: Cuba
+1F1E8 1F1FB ; fully-qualified # 🇨🇻 E2.0 flag: Cape Verde
+1F1E8 1F1FC ; fully-qualified # 🇨🇼 E2.0 flag: Curaçao
+1F1E8 1F1FD ; fully-qualified # 🇨🇽 E2.0 flag: Christmas Island
+1F1E8 1F1FE ; fully-qualified # 🇨🇾 E2.0 flag: Cyprus
+1F1E8 1F1FF ; fully-qualified # 🇨🇿 E2.0 flag: Czechia
+1F1E9 1F1EA ; fully-qualified # 🇩🇪 E0.6 flag: Germany
+1F1E9 1F1EC ; fully-qualified # 🇩🇬 E2.0 flag: Diego Garcia
+1F1E9 1F1EF ; fully-qualified # 🇩🇯 E2.0 flag: Djibouti
+1F1E9 1F1F0 ; fully-qualified # 🇩🇰 E2.0 flag: Denmark
+1F1E9 1F1F2 ; fully-qualified # 🇩🇲 E2.0 flag: Dominica
+1F1E9 1F1F4 ; fully-qualified # 🇩🇴 E2.0 flag: Dominican Republic
+1F1E9 1F1FF ; fully-qualified # 🇩🇿 E2.0 flag: Algeria
+1F1EA 1F1E6 ; fully-qualified # 🇪🇦 E2.0 flag: Ceuta & Melilla
+1F1EA 1F1E8 ; fully-qualified # 🇪🇨 E2.0 flag: Ecuador
+1F1EA 1F1EA ; fully-qualified # 🇪🇪 E2.0 flag: Estonia
+1F1EA 1F1EC ; fully-qualified # 🇪🇬 E2.0 flag: Egypt
+1F1EA 1F1ED ; fully-qualified # 🇪🇭 E2.0 flag: Western Sahara
+1F1EA 1F1F7 ; fully-qualified # 🇪🇷 E2.0 flag: Eritrea
+1F1EA 1F1F8 ; fully-qualified # 🇪🇸 E0.6 flag: Spain
+1F1EA 1F1F9 ; fully-qualified # 🇪🇹 E2.0 flag: Ethiopia
+1F1EA 1F1FA ; fully-qualified # 🇪🇺 E2.0 flag: European Union
+1F1EB 1F1EE ; fully-qualified # 🇫🇮 E2.0 flag: Finland
+1F1EB 1F1EF ; fully-qualified # 🇫🇯 E2.0 flag: Fiji
+1F1EB 1F1F0 ; fully-qualified # 🇫🇰 E2.0 flag: Falkland Islands
+1F1EB 1F1F2 ; fully-qualified # 🇫🇲 E2.0 flag: Micronesia
+1F1EB 1F1F4 ; fully-qualified # 🇫🇴 E2.0 flag: Faroe Islands
+1F1EB 1F1F7 ; fully-qualified # 🇫🇷 E0.6 flag: France
+1F1EC 1F1E6 ; fully-qualified # 🇬🇦 E2.0 flag: Gabon
+1F1EC 1F1E7 ; fully-qualified # 🇬🇧 E0.6 flag: United Kingdom
+1F1EC 1F1E9 ; fully-qualified # 🇬🇩 E2.0 flag: Grenada
+1F1EC 1F1EA ; fully-qualified # 🇬🇪 E2.0 flag: Georgia
+1F1EC 1F1EB ; fully-qualified # 🇬🇫 E2.0 flag: French Guiana
+1F1EC 1F1EC ; fully-qualified # 🇬🇬 E2.0 flag: Guernsey
+1F1EC 1F1ED ; fully-qualified # 🇬🇭 E2.0 flag: Ghana
+1F1EC 1F1EE ; fully-qualified # 🇬🇮 E2.0 flag: Gibraltar
+1F1EC 1F1F1 ; fully-qualified # 🇬🇱 E2.0 flag: Greenland
+1F1EC 1F1F2 ; fully-qualified # 🇬🇲 E2.0 flag: Gambia
+1F1EC 1F1F3 ; fully-qualified # 🇬🇳 E2.0 flag: Guinea
+1F1EC 1F1F5 ; fully-qualified # 🇬🇵 E2.0 flag: Guadeloupe
+1F1EC 1F1F6 ; fully-qualified # 🇬🇶 E2.0 flag: Equatorial Guinea
+1F1EC 1F1F7 ; fully-qualified # 🇬🇷 E2.0 flag: Greece
+1F1EC 1F1F8 ; fully-qualified # 🇬🇸 E2.0 flag: South Georgia & South Sandwich Islands
+1F1EC 1F1F9 ; fully-qualified # 🇬🇹 E2.0 flag: Guatemala
+1F1EC 1F1FA ; fully-qualified # 🇬🇺 E2.0 flag: Guam
+1F1EC 1F1FC ; fully-qualified # 🇬🇼 E2.0 flag: Guinea-Bissau
+1F1EC 1F1FE ; fully-qualified # 🇬🇾 E2.0 flag: Guyana
+1F1ED 1F1F0 ; fully-qualified # 🇭🇰 E2.0 flag: Hong Kong SAR China
+1F1ED 1F1F2 ; fully-qualified # 🇭🇲 E2.0 flag: Heard & McDonald Islands
+1F1ED 1F1F3 ; fully-qualified # 🇭🇳 E2.0 flag: Honduras
+1F1ED 1F1F7 ; fully-qualified # 🇭🇷 E2.0 flag: Croatia
+1F1ED 1F1F9 ; fully-qualified # 🇭🇹 E2.0 flag: Haiti
+1F1ED 1F1FA ; fully-qualified # 🇭🇺 E2.0 flag: Hungary
+1F1EE 1F1E8 ; fully-qualified # 🇮🇨 E2.0 flag: Canary Islands
+1F1EE 1F1E9 ; fully-qualified # 🇮🇩 E2.0 flag: Indonesia
+1F1EE 1F1EA ; fully-qualified # 🇮🇪 E2.0 flag: Ireland
+1F1EE 1F1F1 ; fully-qualified # 🇮🇱 E2.0 flag: Israel
+1F1EE 1F1F2 ; fully-qualified # 🇮🇲 E2.0 flag: Isle of Man
+1F1EE 1F1F3 ; fully-qualified # 🇮🇳 E2.0 flag: India
+1F1EE 1F1F4 ; fully-qualified # 🇮🇴 E2.0 flag: British Indian Ocean Territory
+1F1EE 1F1F6 ; fully-qualified # 🇮🇶 E2.0 flag: Iraq
+1F1EE 1F1F7 ; fully-qualified # 🇮🇷 E2.0 flag: Iran
+1F1EE 1F1F8 ; fully-qualified # 🇮🇸 E2.0 flag: Iceland
+1F1EE 1F1F9 ; fully-qualified # 🇮🇹 E0.6 flag: Italy
+1F1EF 1F1EA ; fully-qualified # 🇯🇪 E2.0 flag: Jersey
+1F1EF 1F1F2 ; fully-qualified # 🇯🇲 E2.0 flag: Jamaica
+1F1EF 1F1F4 ; fully-qualified # 🇯🇴 E2.0 flag: Jordan
+1F1EF 1F1F5 ; fully-qualified # 🇯🇵 E0.6 flag: Japan
+1F1F0 1F1EA ; fully-qualified # 🇰🇪 E2.0 flag: Kenya
+1F1F0 1F1EC ; fully-qualified # 🇰🇬 E2.0 flag: Kyrgyzstan
+1F1F0 1F1ED ; fully-qualified # 🇰🇭 E2.0 flag: Cambodia
+1F1F0 1F1EE ; fully-qualified # 🇰🇮 E2.0 flag: Kiribati
+1F1F0 1F1F2 ; fully-qualified # 🇰🇲 E2.0 flag: Comoros
+1F1F0 1F1F3 ; fully-qualified # 🇰🇳 E2.0 flag: St. Kitts & Nevis
+1F1F0 1F1F5 ; fully-qualified # 🇰🇵 E2.0 flag: North Korea
+1F1F0 1F1F7 ; fully-qualified # 🇰🇷 E0.6 flag: South Korea
+1F1F0 1F1FC ; fully-qualified # 🇰🇼 E2.0 flag: Kuwait
+1F1F0 1F1FE ; fully-qualified # 🇰🇾 E2.0 flag: Cayman Islands
+1F1F0 1F1FF ; fully-qualified # 🇰🇿 E2.0 flag: Kazakhstan
+1F1F1 1F1E6 ; fully-qualified # 🇱🇦 E2.0 flag: Laos
+1F1F1 1F1E7 ; fully-qualified # 🇱🇧 E2.0 flag: Lebanon
+1F1F1 1F1E8 ; fully-qualified # 🇱🇨 E2.0 flag: St. Lucia
+1F1F1 1F1EE ; fully-qualified # 🇱🇮 E2.0 flag: Liechtenstein
+1F1F1 1F1F0 ; fully-qualified # 🇱🇰 E2.0 flag: Sri Lanka
+1F1F1 1F1F7 ; fully-qualified # 🇱🇷 E2.0 flag: Liberia
+1F1F1 1F1F8 ; fully-qualified # 🇱🇸 E2.0 flag: Lesotho
+1F1F1 1F1F9 ; fully-qualified # 🇱🇹 E2.0 flag: Lithuania
+1F1F1 1F1FA ; fully-qualified # 🇱🇺 E2.0 flag: Luxembourg
+1F1F1 1F1FB ; fully-qualified # 🇱🇻 E2.0 flag: Latvia
+1F1F1 1F1FE ; fully-qualified # 🇱🇾 E2.0 flag: Libya
+1F1F2 1F1E6 ; fully-qualified # 🇲🇦 E2.0 flag: Morocco
+1F1F2 1F1E8 ; fully-qualified # 🇲🇨 E2.0 flag: Monaco
+1F1F2 1F1E9 ; fully-qualified # 🇲🇩 E2.0 flag: Moldova
+1F1F2 1F1EA ; fully-qualified # 🇲🇪 E2.0 flag: Montenegro
+1F1F2 1F1EB ; fully-qualified # 🇲🇫 E2.0 flag: St. Martin
+1F1F2 1F1EC ; fully-qualified # 🇲🇬 E2.0 flag: Madagascar
+1F1F2 1F1ED ; fully-qualified # 🇲🇭 E2.0 flag: Marshall Islands
+1F1F2 1F1F0 ; fully-qualified # 🇲🇰 E2.0 flag: North Macedonia
+1F1F2 1F1F1 ; fully-qualified # 🇲🇱 E2.0 flag: Mali
+1F1F2 1F1F2 ; fully-qualified # 🇲🇲 E2.0 flag: Myanmar (Burma)
+1F1F2 1F1F3 ; fully-qualified # 🇲🇳 E2.0 flag: Mongolia
+1F1F2 1F1F4 ; fully-qualified # 🇲🇴 E2.0 flag: Macao SAR China
+1F1F2 1F1F5 ; fully-qualified # 🇲🇵 E2.0 flag: Northern Mariana Islands
+1F1F2 1F1F6 ; fully-qualified # 🇲🇶 E2.0 flag: Martinique
+1F1F2 1F1F7 ; fully-qualified # 🇲🇷 E2.0 flag: Mauritania
+1F1F2 1F1F8 ; fully-qualified # 🇲🇸 E2.0 flag: Montserrat
+1F1F2 1F1F9 ; fully-qualified # 🇲🇹 E2.0 flag: Malta
+1F1F2 1F1FA ; fully-qualified # 🇲🇺 E2.0 flag: Mauritius
+1F1F2 1F1FB ; fully-qualified # 🇲🇻 E2.0 flag: Maldives
+1F1F2 1F1FC ; fully-qualified # 🇲🇼 E2.0 flag: Malawi
+1F1F2 1F1FD ; fully-qualified # 🇲🇽 E2.0 flag: Mexico
+1F1F2 1F1FE ; fully-qualified # 🇲🇾 E2.0 flag: Malaysia
+1F1F2 1F1FF ; fully-qualified # 🇲🇿 E2.0 flag: Mozambique
+1F1F3 1F1E6 ; fully-qualified # 🇳🇦 E2.0 flag: Namibia
+1F1F3 1F1E8 ; fully-qualified # 🇳🇨 E2.0 flag: New Caledonia
+1F1F3 1F1EA ; fully-qualified # 🇳🇪 E2.0 flag: Niger
+1F1F3 1F1EB ; fully-qualified # 🇳🇫 E2.0 flag: Norfolk Island
+1F1F3 1F1EC ; fully-qualified # 🇳🇬 E2.0 flag: Nigeria
+1F1F3 1F1EE ; fully-qualified # 🇳🇮 E2.0 flag: Nicaragua
+1F1F3 1F1F1 ; fully-qualified # 🇳🇱 E2.0 flag: Netherlands
+1F1F3 1F1F4 ; fully-qualified # 🇳🇴 E2.0 flag: Norway
+1F1F3 1F1F5 ; fully-qualified # 🇳🇵 E2.0 flag: Nepal
+1F1F3 1F1F7 ; fully-qualified # 🇳🇷 E2.0 flag: Nauru
+1F1F3 1F1FA ; fully-qualified # 🇳🇺 E2.0 flag: Niue
+1F1F3 1F1FF ; fully-qualified # 🇳🇿 E2.0 flag: New Zealand
+1F1F4 1F1F2 ; fully-qualified # 🇴🇲 E2.0 flag: Oman
+1F1F5 1F1E6 ; fully-qualified # 🇵🇦 E2.0 flag: Panama
+1F1F5 1F1EA ; fully-qualified # 🇵🇪 E2.0 flag: Peru
+1F1F5 1F1EB ; fully-qualified # 🇵🇫 E2.0 flag: French Polynesia
+1F1F5 1F1EC ; fully-qualified # 🇵🇬 E2.0 flag: Papua New Guinea
+1F1F5 1F1ED ; fully-qualified # 🇵🇭 E2.0 flag: Philippines
+1F1F5 1F1F0 ; fully-qualified # 🇵🇰 E2.0 flag: Pakistan
+1F1F5 1F1F1 ; fully-qualified # 🇵🇱 E2.0 flag: Poland
+1F1F5 1F1F2 ; fully-qualified # 🇵🇲 E2.0 flag: St. Pierre & Miquelon
+1F1F5 1F1F3 ; fully-qualified # 🇵🇳 E2.0 flag: Pitcairn Islands
+1F1F5 1F1F7 ; fully-qualified # 🇵🇷 E2.0 flag: Puerto Rico
+1F1F5 1F1F8 ; fully-qualified # 🇵🇸 E2.0 flag: Palestinian Territories
+1F1F5 1F1F9 ; fully-qualified # 🇵🇹 E2.0 flag: Portugal
+1F1F5 1F1FC ; fully-qualified # 🇵🇼 E2.0 flag: Palau
+1F1F5 1F1FE ; fully-qualified # 🇵🇾 E2.0 flag: Paraguay
+1F1F6 1F1E6 ; fully-qualified # 🇶🇦 E2.0 flag: Qatar
+1F1F7 1F1EA ; fully-qualified # 🇷🇪 E2.0 flag: Réunion
+1F1F7 1F1F4 ; fully-qualified # 🇷🇴 E2.0 flag: Romania
+1F1F7 1F1F8 ; fully-qualified # 🇷🇸 E2.0 flag: Serbia
+1F1F7 1F1FA ; fully-qualified # 🇷🇺 E0.6 flag: Russia
+1F1F7 1F1FC ; fully-qualified # 🇷🇼 E2.0 flag: Rwanda
+1F1F8 1F1E6 ; fully-qualified # 🇸🇦 E2.0 flag: Saudi Arabia
+1F1F8 1F1E7 ; fully-qualified # 🇸🇧 E2.0 flag: Solomon Islands
+1F1F8 1F1E8 ; fully-qualified # 🇸🇨 E2.0 flag: Seychelles
+1F1F8 1F1E9 ; fully-qualified # 🇸🇩 E2.0 flag: Sudan
+1F1F8 1F1EA ; fully-qualified # 🇸🇪 E2.0 flag: Sweden
+1F1F8 1F1EC ; fully-qualified # 🇸🇬 E2.0 flag: Singapore
+1F1F8 1F1ED ; fully-qualified # 🇸🇭 E2.0 flag: St. Helena
+1F1F8 1F1EE ; fully-qualified # 🇸🇮 E2.0 flag: Slovenia
+1F1F8 1F1EF ; fully-qualified # 🇸🇯 E2.0 flag: Svalbard & Jan Mayen
+1F1F8 1F1F0 ; fully-qualified # 🇸🇰 E2.0 flag: Slovakia
+1F1F8 1F1F1 ; fully-qualified # 🇸🇱 E2.0 flag: Sierra Leone
+1F1F8 1F1F2 ; fully-qualified # 🇸🇲 E2.0 flag: San Marino
+1F1F8 1F1F3 ; fully-qualified # 🇸🇳 E2.0 flag: Senegal
+1F1F8 1F1F4 ; fully-qualified # 🇸🇴 E2.0 flag: Somalia
+1F1F8 1F1F7 ; fully-qualified # 🇸🇷 E2.0 flag: Suriname
+1F1F8 1F1F8 ; fully-qualified # 🇸🇸 E2.0 flag: South Sudan
+1F1F8 1F1F9 ; fully-qualified # 🇸🇹 E2.0 flag: São Tomé & Príncipe
+1F1F8 1F1FB ; fully-qualified # 🇸🇻 E2.0 flag: El Salvador
+1F1F8 1F1FD ; fully-qualified # 🇸🇽 E2.0 flag: Sint Maarten
+1F1F8 1F1FE ; fully-qualified # 🇸🇾 E2.0 flag: Syria
+1F1F8 1F1FF ; fully-qualified # 🇸🇿 E2.0 flag: Eswatini
+1F1F9 1F1E6 ; fully-qualified # 🇹🇦 E2.0 flag: Tristan da Cunha
+1F1F9 1F1E8 ; fully-qualified # 🇹🇨 E2.0 flag: Turks & Caicos Islands
+1F1F9 1F1E9 ; fully-qualified # 🇹🇩 E2.0 flag: Chad
+1F1F9 1F1EB ; fully-qualified # 🇹🇫 E2.0 flag: French Southern Territories
+1F1F9 1F1EC ; fully-qualified # 🇹🇬 E2.0 flag: Togo
+1F1F9 1F1ED ; fully-qualified # 🇹🇭 E2.0 flag: Thailand
+1F1F9 1F1EF ; fully-qualified # 🇹🇯 E2.0 flag: Tajikistan
+1F1F9 1F1F0 ; fully-qualified # 🇹🇰 E2.0 flag: Tokelau
+1F1F9 1F1F1 ; fully-qualified # 🇹🇱 E2.0 flag: Timor-Leste
+1F1F9 1F1F2 ; fully-qualified # 🇹🇲 E2.0 flag: Turkmenistan
+1F1F9 1F1F3 ; fully-qualified # 🇹🇳 E2.0 flag: Tunisia
+1F1F9 1F1F4 ; fully-qualified # 🇹🇴 E2.0 flag: Tonga
+1F1F9 1F1F7 ; fully-qualified # 🇹🇷 E2.0 flag: Turkey
+1F1F9 1F1F9 ; fully-qualified # 🇹🇹 E2.0 flag: Trinidad & Tobago
+1F1F9 1F1FB ; fully-qualified # 🇹🇻 E2.0 flag: Tuvalu
+1F1F9 1F1FC ; fully-qualified # 🇹🇼 E2.0 flag: Taiwan
+1F1F9 1F1FF ; fully-qualified # 🇹🇿 E2.0 flag: Tanzania
+1F1FA 1F1E6 ; fully-qualified # 🇺🇦 E2.0 flag: Ukraine
+1F1FA 1F1EC ; fully-qualified # 🇺🇬 E2.0 flag: Uganda
+1F1FA 1F1F2 ; fully-qualified # 🇺🇲 E2.0 flag: U.S. Outlying Islands
+1F1FA 1F1F3 ; fully-qualified # 🇺🇳 E4.0 flag: United Nations
+1F1FA 1F1F8 ; fully-qualified # 🇺🇸 E0.6 flag: United States
+1F1FA 1F1FE ; fully-qualified # 🇺🇾 E2.0 flag: Uruguay
+1F1FA 1F1FF ; fully-qualified # 🇺🇿 E2.0 flag: Uzbekistan
+1F1FB 1F1E6 ; fully-qualified # 🇻🇦 E2.0 flag: Vatican City
+1F1FB 1F1E8 ; fully-qualified # 🇻🇨 E2.0 flag: St. Vincent & Grenadines
+1F1FB 1F1EA ; fully-qualified # 🇻🇪 E2.0 flag: Venezuela
+1F1FB 1F1EC ; fully-qualified # 🇻🇬 E2.0 flag: British Virgin Islands
+1F1FB 1F1EE ; fully-qualified # 🇻🇮 E2.0 flag: U.S. Virgin Islands
+1F1FB 1F1F3 ; fully-qualified # 🇻🇳 E2.0 flag: Vietnam
+1F1FB 1F1FA ; fully-qualified # 🇻🇺 E2.0 flag: Vanuatu
+1F1FC 1F1EB ; fully-qualified # 🇼🇫 E2.0 flag: Wallis & Futuna
+1F1FC 1F1F8 ; fully-qualified # 🇼🇸 E2.0 flag: Samoa
+1F1FD 1F1F0 ; fully-qualified # 🇽🇰 E2.0 flag: Kosovo
+1F1FE 1F1EA ; fully-qualified # 🇾🇪 E2.0 flag: Yemen
+1F1FE 1F1F9 ; fully-qualified # 🇾🇹 E2.0 flag: Mayotte
+1F1FF 1F1E6 ; fully-qualified # 🇿🇦 E2.0 flag: South Africa
+1F1FF 1F1F2 ; fully-qualified # 🇿🇲 E2.0 flag: Zambia
+1F1FF 1F1FC ; fully-qualified # 🇿🇼 E2.0 flag: Zimbabwe
# subgroup: subdivision-flag
-1F3F4 E0067 E0062 E0065 E006E E0067 E007F ; fully-qualified # 🏴 E5.0 flag: England
-1F3F4 E0067 E0062 E0073 E0063 E0074 E007F ; fully-qualified # 🏴 E5.0 flag: Scotland
-1F3F4 E0067 E0062 E0077 E006C E0073 E007F ; fully-qualified # 🏴 E5.0 flag: Wales
+1F3F4 E0067 E0062 E0065 E006E E0067 E007F ; fully-qualified # 🏴 E5.0 flag: England
+1F3F4 E0067 E0062 E0073 E0063 E0074 E007F ; fully-qualified # 🏴 E5.0 flag: Scotland
+1F3F4 E0067 E0062 E0077 E006C E0073 E007F ; fully-qualified # 🏴 E5.0 flag: Wales
# Flags subtotal: 275
# Flags subtotal: 275 w/o modifiers
# Status Counts
-# fully-qualified : 3295
-# minimally-qualified : 614
-# unqualified : 250
+# fully-qualified : 3512
+# minimally-qualified : 817
+# unqualified : 252
# component : 9
#EOF
diff --git a/tools/java/org/unicode/cldr/util/data/europe b/tools/java/org/unicode/cldr/util/data/europe
index 2728fac..9ba686d 100644
--- a/tools/java/org/unicode/cldr/util/data/europe
+++ b/tools/java/org/unicode/cldr/util/data/europe
@@ -122,7 +122,7 @@
# position is 51° 28' 30" N, 0° 18' 45" W. The longitude should
# be within about ±2". The Ordnance Survey grid reference is TQ172761.
#
-# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
+# [This yields STDOFF = -0:01:15 for London LMT in the 18th century.]
# From Paul Eggert (1993-11-18):
#
@@ -388,7 +388,7 @@
# http://www.irishstatutebook.ie/eli/1926/sro/919/made/en/print
# http://www.irishstatutebook.ie/eli/1947/sro/71/made/en/print
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Summer Time Act, 1916
Rule GB-Eire 1916 only - May 21 2:00s 1:00 BST
Rule GB-Eire 1916 only - Oct 1 2:00s 0 GMT
@@ -500,7 +500,7 @@
#
# Use Europe/London for Jersey, Guernsey, and the Isle of Man.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/London -0:01:15 - LMT 1847 Dec 1 0:00s
0:00 GB-Eire %s 1968 Oct 27
1:00 - BST 1971 Oct 31 2:00u
@@ -529,7 +529,7 @@
# The following is like GB-Eire and EU, except with standard time in
# summer and negative daylight saving time in winter. It is for when
# negative SAVE values are used.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
#Rule Eire 1971 only - Oct 31 2:00u -1:00 -
#Rule Eire 1972 1980 - Mar Sun>=16 2:00u 0 -
#Rule Eire 1972 1980 - Oct Sun>=23 2:00u -1:00 -
@@ -538,7 +538,7 @@
#Rule Eire 1990 1995 - Oct Sun>=22 1:00u -1:00 -
#Rule Eire 1996 max - Oct lastSun 1:00u -1:00 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Dublin -0:25:00 - LMT 1880 Aug 2
-0:25:21 - DMT 1916 May 21 2:00s
-0:25:21 1:00 IST 1916 Oct 1 2:00s
@@ -549,12 +549,13 @@
0:00 1:00 IST 1947 Nov 2 2:00s
0:00 - GMT 1948 Apr 18 2:00s
0:00 GB-Eire GMT/IST 1968 Oct 27
-# The next line is for when negative SAVE values are used.
+# Vanguard section, for zic and other parsers that support negative DST.
# 1:00 Eire IST/GMT
-# These three lines are for when SAVE values are always nonnegative.
+# Rearguard section, for parsers lacking negative DST; see ziguard.awk.
1:00 - IST 1971 Oct 31 2:00u
0:00 GB-Eire GMT/IST 1996
0:00 EU GMT/IST
+# End of rearguard section.
###############################################################################
@@ -565,7 +566,7 @@
# predecessor organization, the European Communities.
# For brevity they are called "EU rules" elsewhere in this file.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
@@ -605,13 +606,13 @@
# corrected in version 2008d). The circumstantial evidence is simply the
# tz database itself, as seen below:
#
-# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01
+# Zone Europe/Paris ...
# 0:00 France WE%sT 1945 Sep 16 3:00
#
-# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
+# Zone Europe/Monaco ...
# 0:00 France WE%sT 1945 Sep 16 3:00
#
-# Zone Europe/Belgrade 1:22:00 - LMT 1884
+# Zone Europe/Belgrade ...
# 1:00 1:00 CEST 1945 Sep 16 2:00s
#
# Rule France 1945 only - Sep 16 3:00 0 -
@@ -657,7 +658,7 @@
#
# The 1917-1921 decree URLs are from Alexander Belopolsky (2016-08-23).
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Russia 1917 only - Jul 1 23:00 1:00 MST # Moscow Summer Time
#
# Decree No. 142 (1917-12-22) http://istmat.info/node/28137
@@ -737,7 +738,7 @@
# These are for backward compatibility with older versions.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone WET 0:00 EU WE%sT
Zone CET 1:00 C-Eur CE%sT
Zone MET 1:00 C-Eur ME%sT
@@ -771,7 +772,7 @@
# Albania
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Albania 1940 only - Jun 16 0:00 1:00 S
Rule Albania 1942 only - Nov 2 3:00 0 -
Rule Albania 1943 only - Mar 29 2:00 1:00 S
@@ -797,14 +798,14 @@
Rule Albania 1983 only - Apr 18 0:00 1:00 S
Rule Albania 1983 only - Oct 1 0:00 0 -
Rule Albania 1984 only - Apr 1 0:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Tirane 1:19:20 - LMT 1914
1:00 - CET 1940 Jun 16
1:00 Albania CE%sT 1984 Jul
1:00 EU CE%sT
# Andorra
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Andorra 0:06:04 - LMT 1901
0:00 - WET 1946 Sep 30
1:00 - CET 1985 Mar 31 2:00
@@ -821,16 +822,21 @@
# Shanks & Pottenger give 02:00, the BEV 00:00. Go with the BEV,
# and guess 02:00 for 1945-04-12.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Alois Triendl (2019-07-22):
+# In 1946 the end of DST was on Monday, 7 October 1946, at 3:00 am.
+# Shanks had this right. Source: Die Weltpresse, 5. Oktober 1946, page 5.
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Austria 1920 only - Apr 5 2:00s 1:00 S
Rule Austria 1920 only - Sep 13 2:00s 0 -
Rule Austria 1946 only - Apr 14 2:00s 1:00 S
-Rule Austria 1946 1948 - Oct Sun>=1 2:00s 0 -
+Rule Austria 1946 only - Oct 7 2:00s 0 -
+Rule Austria 1947 1948 - Oct Sun>=1 2:00s 0 -
Rule Austria 1947 only - Apr 6 2:00s 1:00 S
Rule Austria 1948 only - Apr 18 2:00s 1:00 S
Rule Austria 1980 only - Apr 6 0:00 1:00 S
Rule Austria 1980 only - Sep 28 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
1:00 C-Eur CE%sT 1920
1:00 Austria CE%sT 1940 Apr 1 2:00s
@@ -862,7 +868,7 @@
# Belarussian government decided against changing to winter time....
# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Minsk 1:50:16 - LMT 1880
1:50 - MMT 1924 May 2 # Minsk Mean Time
2:00 - EET 1930 Jun 21
@@ -875,19 +881,39 @@
# Belgium
#
-# From Paul Eggert (1997-07-02):
+# From Michael Deckers (2019-08-25):
+# The exposition in the web page
+# https://www.bestor.be/wiki/index.php/Voyager_dans_le_temps._L%E2%80%99introduction_de_la_norme_de_Greenwich_en_Belgique
+# gives several contemporary sources from which one can conclude that
+# the switch in Europe/Brussels on 1892-05-01 was from 00:17:30 to 00:00:00.
+#
+# From Paul Eggert (2019-08-28):
+# This quote helps explain the late-1914 situation:
+# In early November 1914, the Germans imposed the time zone used in central
+# Europe and forced the inhabitants to set their watches and public clocks
+# sixty minutes ahead. Many were reluctant to accept "German time" and
+# continued to use "Belgian time" among themselves. Reflecting the spirit of
+# resistance that arose in the population, a song made fun of this change....
+# The song ended:
+# Putting your clock forward
+# Will but hasten the happy hour
+# When we kick out the Boches!
+# See: Pluvinage G. Brussels on German time. Cahiers Bruxellois -
+# Brusselse Cahiers. 2014;XLVI(1E):15-38.
+# https://www.cairn.info/revue-cahiers-bruxellois-2014-1E-page-15.htm
+#
+# Entries from 1914 through 1917 are taken from "De tijd in België"
+# <https://www.astro.oma.be/GENERAL/INFO/nli001a.html>.
# Entries from 1918 through 1991 are taken from:
# Annuaire de L'Observatoire Royal de Belgique,
# Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe année, 1991
# (Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
# pp 8-9.
-# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
-# Moniteur Belge, Samedi 30 Avril 1892, N.121.
-# Thanks to Pascal Delmoitie for these references.
+# Thanks to Pascal Delmoitie for the 1918/1991 references.
# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
# Assume Brussels switched to WET in 1918 when the armistice took effect.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Belgium 1918 only - Mar 9 0:00s 1:00 S
Rule Belgium 1918 1919 - Oct Sat>=1 23:00s 0 -
Rule Belgium 1919 only - Mar 1 23:00s 1:00 S
@@ -926,9 +952,9 @@
Rule Belgium 1945 only - Sep 16 2:00s 0 -
Rule Belgium 1946 only - May 19 2:00s 1:00 S
Rule Belgium 1946 only - Oct 7 2:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Brussels 0:17:30 - LMT 1880
- 0:17:30 - BMT 1892 May 1 12:00 # Brussels MT
+ 0:17:30 - BMT 1892 May 1 00:17:30
0:00 - WET 1914 Nov 8
1:00 - CET 1916 May 1 0:00
1:00 C-Eur CE%sT 1918 Nov 11 11:00u
@@ -947,13 +973,13 @@
# EET -> EETDST is in 03:00 Local time in last Sunday of March ...
# EETDST -> EET is in 04:00 Local time in last Sunday of October
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Bulg 1979 only - Mar 31 23:00 1:00 S
Rule Bulg 1979 only - Oct 1 1:00 0 -
Rule Bulg 1980 1982 - Apr Sat>=1 23:00 1:00 S
Rule Bulg 1980 only - Sep 29 1:00 0 -
Rule Bulg 1981 only - Sep 27 2:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Sofia 1:33:16 - LMT 1880
1:56:56 - IMT 1894 Nov 30 # Istanbul MT?
2:00 - EET 1942 Nov 2 3:00
@@ -979,21 +1005,21 @@
# We know of no English-language name for historical Czech winter time;
# abbreviate it as "GMT", as it happened to be GMT.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Czech 1945 only - Apr Mon>=1 2:00s 1:00 S
Rule Czech 1945 only - Oct 1 2:00s 0 -
Rule Czech 1946 only - May 6 2:00s 1:00 S
Rule Czech 1946 1949 - Oct Sun>=1 2:00s 0 -
Rule Czech 1947 1948 - Apr Sun>=15 2:00s 1:00 S
Rule Czech 1949 only - Apr 9 2:00s 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Prague 0:57:44 - LMT 1850
0:57:44 - PMT 1891 Oct # Prague Mean Time
1:00 C-Eur CE%sT 1945 May 9
1:00 Czech CE%sT 1946 Dec 1 3:00
# Vanguard section, for zic and other parsers that support negative DST.
# 1:00 -1:00 GMT 1947 Feb 23 2:00
-# Rearguard section, for parsers that do not support negative DST.
+# Rearguard section, for parsers lacking negative DST; see ziguard.awk.
0:00 - GMT 1947 Feb 23 2:00
# End of rearguard section.
1:00 Czech CE%sT 1979
@@ -1035,7 +1061,7 @@
# Hence the "02:00" of the 1980 law refers to standard time, not
# wall-clock time, and so the EU rules were in effect in 1980.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Denmark 1916 only - May 14 23:00 1:00 S
Rule Denmark 1916 only - Sep 30 23:00 0 -
Rule Denmark 1940 only - May 15 0:00 1:00 S
@@ -1048,7 +1074,7 @@
Rule Denmark 1948 only - May 9 2:00s 1:00 S
Rule Denmark 1948 only - Aug 8 2:00s 0 -
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Copenhagen 0:50:20 - LMT 1890
0:50:20 - CMT 1894 Jan 1 # Copenhagen MT
1:00 Denmark CE%sT 1942 Nov 2 2:00s
@@ -1137,7 +1163,7 @@
# http://naalakkersuisut.gl/~/media/Nanoq/Files/Attached%20Files/Engelske-tekster/Legislation/Executive%20Order%20National%20Park.rtf
# It is their only National Park.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D
Rule Thule 1991 1992 - Sep lastSun 2:00 0 S
Rule Thule 1993 2006 - Apr Sun>=1 2:00 1:00 D
@@ -1145,19 +1171,22 @@
Rule Thule 2007 max - Mar Sun>=8 2:00 1:00 D
Rule Thule 2007 max - Nov Sun>=1 2:00 0 S
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28
-3:00 - -03 1980 Apr 6 2:00
-3:00 EU -03/-02 1996
0:00 - GMT
+#
+# Use the old name Scoresbysund, as the current name Ittoqqortoormiit
+# exceeds tzdb's 14-letter limit and has no common English abbreviation.
Zone America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 # Ittoqqortoormiit
-2:00 - -02 1980 Apr 6 2:00
-2:00 C-Eur -02/-01 1981 Mar 29
-1:00 EU -01/+00
-Zone America/Godthab -3:26:56 - LMT 1916 Jul 28 # Nuuk
+Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb
-3:00 - -03 1980 Apr 6 2:00
-3:00 EU -03/-02
-Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base
+Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik
-4:00 Thule A%sT
# Estonia
@@ -1211,7 +1240,7 @@
# From Urmet Jänes (2002-03-28):
# The legislative reference is Government decree No. 84 on 2002-02-21.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Tallinn 1:39:00 - LMT 1880
1:39:00 - TMT 1918 Feb # Tallinn Mean Time
1:00 C-Eur CE%sT 1919 Jul
@@ -1265,7 +1294,7 @@
# From Paul Eggert (2014-06-14):
# Go with Oja over Shanks.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Finland 1942 only - Apr 2 24:00 1:00 S
Rule Finland 1942 only - Oct 4 1:00 0 -
Rule Finland 1981 1982 - Mar lastSun 2:00 1:00 S
@@ -1274,7 +1303,7 @@
# Milne says Helsinki (Helsingfors) time was 1:39:49.2 (official document);
# round to nearest.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Helsinki 1:39:49 - LMT 1878 May 31
1:39:49 - HMT 1921 May # Helsinki Mean Time
2:00 Finland EE%sT 1983
@@ -1297,10 +1326,58 @@
# Françoise Gauquelin, Problèmes de l'heure résolus en astrologie,
# Guy Trédaniel, Paris 1987
+# From Michael Deckers (2020-06-11):
+# the law of 1891 <https://gallica.bnf.fr/ark:/12148/bpt6k64415343.texteImage>
+# was published on 1891-03-15, so it could only take force on 1891-03-16.
+
+# From Michael Deckers (2020-06-10):
+# Le Gaulois, 1911-03-11, page 1/6, online at
+# https://www.retronews.fr/societe/echo-de-presse/2018/01/29/1911-change-lheure-de-paris
+# ... [ Instantly, all pressure driven clock dials halted... Nine minutes and
+# twenty-one seconds later the hands resumed their circular motion. ]
+# There are also precise reports about how the change was prepared in train
+# stations: all the publicly visible clocks stopped at midnight railway time
+# (or were covered), only the chief of service had a watch, labeled
+# "Heure ancienne", that he kept running until it reached 00:04:21, when
+# he announced "Heure nouvelle". See the "Le Petit Journal 1911-03-11".
+# https://gallica.bnf.fr/ark:/12148/bpt6k6192911/f1.item.zoom
+#
+# From Michael Deckers (2020-06-12):
+# That "all French clocks stopped" for 00:09:21 is a misreading of French
+# newspapers; this sort of adjustment applies only to certain
+# remote-controlled clocks ("pendules pneumatiques", of which there existed
+# perhaps a dozen in Paris, and which simply could not be set back remotely),
+# but not to all the clocks in all French towns and villages. For instance,
+# the following story in the "Courrier de Saône-et-Loire" 1911-03-11, page 2:
+# only works if legal time was stepped back (was not monotone): ...
+# [One can observe that children who had been born at midnight less 5
+# minutes and who had died at midnight of the old time, would turn out to
+# be dead before being born, time having been set back and having
+# suppressed 9 minutes and 25 seconds of their existence, that is, more
+# than they could spend.]
+#
+# From Paul Eggert (2020-06-12):
+# French time in railway stations was legally five minutes behind civil time,
+# which explains why railway "old time" ran to 00:04:21 instead of to 00:09:21.
+# The law's text (which Michael Deckers noted is at
+# <https://gallica.bnf.fr/ark:/12148/bpt6k2022333z/f2>) says only that
+# at 1911-03-11 00:00 legal time was that of Paris mean time delayed by
+# nine minutes and twenty-one seconds, and does not say how the
+# transition from Paris mean time was to occur.
+#
+# tzdb has no way to represent stopped clocks. As the railway practice
+# was to keep a watch running on "old time" to decide when to restart
+# the other clocks, this could be modeled as a transition for "old time" at
+# 00:09:21. However, since the law was ambiguous and clocks outside railway
+# stations were probably done haphazardly with the popular impression being
+# that the transition was done at 00:00 "old time", simply leave the time
+# blank; this causes zic to default to 00:00 "old time" which is good enough.
+# Do something similar for the 1891-03-16 transition. There are similar
+# problems in Algiers, Monaco and Tunis.
#
# Shank & Pottenger seem to use '24:00' ambiguously; resolve it with Whitman.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule France 1916 only - Jun 14 23:00s 1:00 S
Rule France 1916 1919 - Oct Sun>=1 23:00s 0 -
Rule France 1917 only - Mar 24 23:00s 1:00 S
@@ -1360,13 +1437,11 @@
# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
Rule France 1976 only - Mar 28 1:00 1:00 S
Rule France 1976 only - Sep 26 1:00 0 -
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time, and Whitman 0:09:05,
-# but Howse quotes the actual French legislation as saying 0:09:21.
-# Go with Howse. Howse writes that the time in France was officially based
+# Howse writes that the time in France was officially based
# on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01
- 0:09:21 - PMT 1911 Mar 11 0:01 # Paris MT
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Europe/Paris 0:09:21 - LMT 1891 Mar 16
+ 0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
0:00 France WE%sT 1940 Jun 14 23:00
# Le Corre says Paris stuck with occupied-France time after the liberation;
@@ -1395,7 +1470,7 @@
# this was equivalent to UT +03, not +04.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Germany 1946 only - Apr 14 2:00s 1:00 S
Rule Germany 1946 only - Oct 7 2:00s 0 -
Rule Germany 1947 1949 - Oct Sun>=1 2:00s 0 -
@@ -1412,7 +1487,7 @@
Rule SovietZone 1945 only - Sep 24 3:00 1:00 S
Rule SovietZone 1945 only - Nov 18 2:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Berlin 0:53:28 - LMT 1893 Apr
1:00 C-Eur CE%sT 1945 May 24 2:00
1:00 SovietZone CE%sT 1946
@@ -1440,14 +1515,14 @@
# is in Europe. Our reference location Tbilisi is in the Asian part.
# Gibraltar
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2 0:00s
0:00 GB-Eire %s 1957 Apr 14 2:00
1:00 - CET 1982
1:00 EU CE%sT
# Greece
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks & Pottenger.
Rule Greece 1932 only - Jul 7 0:00 1:00 S
Rule Greece 1932 only - Sep 1 0:00 0 -
@@ -1471,7 +1546,7 @@
Rule Greece 1979 only - Sep 29 2:00 0 -
Rule Greece 1980 only - Apr 1 0:00 1:00 S
Rule Greece 1980 only - Sep 28 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Athens 1:34:52 - LMT 1895 Sep 14
1:34:52 - AMT 1916 Jul 28 0:01 # Athens MT
2:00 Greece EE%sT 1941 Apr 30
@@ -1482,38 +1557,69 @@
2:00 EU EE%sT
# Hungary
-# From Paul Eggert (2014-07-15):
-# Dates for 1916-1945 are taken from:
-# Oross A. Jelen a múlt jövője: a nyári időszámítás Magyarországon 1916-1945.
-# National Archives of Hungary (2012-10-29).
-# http://mnl.gov.hu/a_het_dokumentuma/a_nyari_idoszamitas_magyarorszagon_19161945.html
-# This source does not always give times, which are taken from Shanks
-# & Pottenger (which disagree about the dates).
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule Hungary 1918 only - Apr 1 3:00 1:00 S
-Rule Hungary 1918 only - Sep 16 3:00 0 -
-Rule Hungary 1919 only - Apr 15 3:00 1:00 S
-Rule Hungary 1919 only - Nov 24 3:00 0 -
+
+# From Michael Deckers (2020-06-09):
+# an Austrian encyclopedia of railroads of 1913, online at
+# http://www.zeno.org/Roell-1912/A/Eisenbahnzeit
+# says that the switch [to CET] happened on 1890-11-01.
+
+# From Géza Nyáry (2020-06-07):
+# Data for 1918-1983 are based on the archive database of Library Hungaricana.
+# The dates are collected from original, scanned governmental orders,
+# bulletins, instructions and public press.
+# [See URLs below.]
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
+# https://library.hungaricana.hu/hu/view/OGYK_RT_1918/?pg=238
+# https://library.hungaricana.hu/hu/view/OGYK_RT_1919/?pg=808
+# https://library.hungaricana.hu/hu/view/OGYK_RT_1920/?pg=201
+Rule Hungary 1918 1919 - Apr 15 2:00 1:00 S
+Rule Hungary 1918 1920 - Sep Mon>=15 3:00 0 -
+Rule Hungary 1920 only - Apr 5 2:00 1:00 S
+# https://library.hungaricana.hu/hu/view/OGYK_RT_1945/?pg=882
Rule Hungary 1945 only - May 1 23:00 1:00 S
-Rule Hungary 1945 only - Nov 1 0:00 0 -
+Rule Hungary 1945 only - Nov 1 1:00 0 -
+# https://library.hungaricana.hu/hu/view/Delmagyarorszag_1946_03/?pg=49
Rule Hungary 1946 only - Mar 31 2:00s 1:00 S
-Rule Hungary 1946 1949 - Oct Sun>=1 2:00s 0 -
+# https://library.hungaricana.hu/hu/view/Delmagyarorszag_1946_09/?pg=54
+Rule Hungary 1946 only - Oct 7 2:00 0 -
+# https://library.hungaricana.hu/hu/view/KulfBelfHirek_1947_04_1__001-123/?pg=90
+# https://library.hungaricana.hu/hu/view/DunantuliNaplo_1947_09/?pg=128
+# https://library.hungaricana.hu/hu/view/KulfBelfHirek_1948_03_3__001-123/?pg=304
+# https://library.hungaricana.hu/hu/view/Zala_1948_09/?pg=64
+# https://library.hungaricana.hu/hu/view/SatoraljaujhelyiLeveltar_ZempleniNepujsag_1948/?pg=53
+# https://library.hungaricana.hu/hu/view/SatoraljaujhelyiLeveltar_ZempleniNepujsag_1948/?pg=160
+# https://library.hungaricana.hu/hu/view/Delmagyarorszag_1949_09/?pg=94
Rule Hungary 1947 1949 - Apr Sun>=4 2:00s 1:00 S
-Rule Hungary 1950 only - Apr 17 2:00s 1:00 S
-Rule Hungary 1950 only - Oct 23 2:00s 0 -
-Rule Hungary 1954 1955 - May 23 0:00 1:00 S
-Rule Hungary 1954 1955 - Oct 3 0:00 0 -
-Rule Hungary 1956 only - Jun Sun>=1 0:00 1:00 S
-Rule Hungary 1956 only - Sep lastSun 0:00 0 -
-Rule Hungary 1957 only - Jun Sun>=1 1:00 1:00 S
-Rule Hungary 1957 only - Sep lastSun 3:00 0 -
-Rule Hungary 1980 only - Apr 6 1:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Europe/Budapest 1:16:20 - LMT 1890 Oct
+Rule Hungary 1947 1949 - Oct Sun>=1 2:00s 0 -
+# https://library.hungaricana.hu/hu/view/DTT_KOZL_TanacsokKozlonye_1954/?pg=513
+Rule Hungary 1954 only - May 23 0:00 1:00 S
+Rule Hungary 1954 only - Oct 3 0:00 0 -
+# https://library.hungaricana.hu/hu/view/DTT_KOZL_TanacsokKozlonye_1955/?pg=398
+Rule Hungary 1955 only - May 22 2:00 1:00 S
+Rule Hungary 1955 only - Oct 2 3:00 0 -
+# https://library.hungaricana.hu/hu/view/HevesMegyeiNepujsag_1956_06/?pg=0
+# https://library.hungaricana.hu/hu/view/EszakMagyarorszag_1956_06/?pg=6
+# https://library.hungaricana.hu/hu/view/SzolnokMegyeiNeplap_1957_04/?pg=120
+# https://library.hungaricana.hu/hu/view/PestMegyeiHirlap_1957_09/?pg=143
+Rule Hungary 1956 1957 - Jun Sun>=1 2:00 1:00 S
+Rule Hungary 1956 1957 - Sep lastSun 3:00 0 -
+# https://library.hungaricana.hu/hu/view/DTT_KOZL_TanacsokKozlonye_1980/?pg=1227
+Rule Hungary 1980 only - Apr 6 0:00 1:00 S
+Rule Hungary 1980 only - Sep 28 1:00 0 -
+# https://library.hungaricana.hu/hu/view/Delmagyarorszag_1981_01/?pg=79
+# https://library.hungaricana.hu/hu/view/DTT_KOZL_TanacsokKozlonye_1982/?pg=115
+# https://library.hungaricana.hu/hu/view/DTT_KOZL_TanacsokKozlonye_1983/?pg=85
+Rule Hungary 1981 1983 - Mar lastSun 0:00 1:00 S
+Rule Hungary 1981 1983 - Sep lastSun 1:00 0 -
+#
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Europe/Budapest 1:16:20 - LMT 1890 Nov 1
1:00 C-Eur CE%sT 1918
- 1:00 Hungary CE%sT 1941 Apr 8
+# https://library.hungaricana.hu/hu/view/OGYK_RT_1941/?pg=1204
+ 1:00 Hungary CE%sT 1941 Apr 7 23:00
1:00 C-Eur CE%sT 1945
- 1:00 Hungary CE%sT 1980 Sep 28 2:00s
+ 1:00 Hungary CE%sT 1984
1:00 EU CE%sT
# Iceland
@@ -1527,7 +1633,7 @@
#
# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
# behind GMT. Previously, local mean solar time was used in different parts
-# of Iceland, the almanak had been based on Reykjavik mean solar time which
+# of Iceland, the almanak had been based on Reykjavík mean solar time which
# was 1 hour and 28 minutes behind GMT.
#
# "first day of winter" referred to [below] means the first day of the 26 weeks
@@ -1549,7 +1655,7 @@
# The information below is taken from the 1988 Almanak; see
# http://www.almanak.hi.is/klukkan.html
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Iceland 1917 1919 - Feb 19 23:00 1:00 -
Rule Iceland 1917 only - Oct 21 1:00 0 -
Rule Iceland 1918 1919 - Nov 16 1:00 0 -
@@ -1569,7 +1675,7 @@
Rule Iceland 1949 only - Oct 30 1:00s 0 -
Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 -
Rule Iceland 1967 only - Oct 29 1:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Atlantic/Reykjavik -1:28 - LMT 1908
-1:00 Iceland -01/+00 1968 Apr 7 1:00s
0:00 - GMT
@@ -1583,6 +1689,25 @@
# But these events all occurred before the 1970 cutoff,
# so record only the time in Rome.
#
+# From Stephen Trainor (2019-05-06):
+# http://www.ac-ilsestante.it/MERIDIANE/ora_legale/ORA_LEGALE_ESTIVA_IN_ITALIA.htm
+# ... the [1866] law went into effect on 12 December 1866, rather than
+# the date of the decree (22 Sep 1866)
+# https://web.archive.org/web/20070824155341/http://www.iav.it/planetario/didastro/didastro/english.htm
+# ... "In Italy in 1866 there were 6 railway times (Torino, Verona, Firenze,
+# Roma, Napoli, Palermo). On that year it was decided to unify them, adopting
+# the average time of Rome (even if this city was not yet part of the
+# kingdom). On the 12th December 1866, on the starting of the winter time
+# table, it took effect in the railways, the post office and the telegraph,
+# not only for the internal service but also for the public.... Milano set
+# the public watches on the Rome time on the same day (12th December 1866),
+# Torino and Bologna on the 1st January 1867, Venezia the 1st May 1880 and the
+# last city was Cagliari in 1886."
+#
+# From Luigi Rosa (2019-05-07):
+# this is the scan of the decree:
+# http://www.radiomarconi.com/marconi/filopanti/1866c.jpg
+#
# From Michael Deckers (2016-10-24):
# http://www.ac-ilsestante.it/MERIDIANE/ora_legale quotes a law of 1893-08-10
# ... [translated as] "The preceding dispositions will enter into
@@ -1593,6 +1718,7 @@
# The authoritative source for time in Italy is the national metrological
# institute, which has a summary page of historical DST data at
# http://www.inrim.it/res/tf/ora_legale_i.shtml
+# [now at http://oldsite.inrim.it/res/tf/ora_legale_i.shtml as of 2017]
# (2016-10-24):
# http://www.renzobaldini.it/le-ore-legali-in-italia/
# has still different data for 1944. It divides Italy in two, as
@@ -1607,6 +1733,13 @@
# advanced to sixty minutes later starting at hour two on 1944-04-02; ...
# Starting at hour three on the date 1944-09-17 standard time will be resumed.
#
+# From Alois Triendl (2019-07-02):
+# I spent 6 Euros to buy two archive copies of Il Messaggero, a Roman paper,
+# for 1 and 2 April 1944. The edition of 2 April has this note: "Tonight at 2
+# am, put forward the clock by one hour. Remember that in the night between
+# today and Monday the 'ora legale' will come in force again." That makes it
+# clear that in Rome the change was on Monday, 3 April 1944 at 2 am.
+#
# From Paul Eggert (2016-10-27):
# Go with INRiM for DST rules, except as corrected by Inglis for 1944
# for the Kingdom of Italy. This is consistent with Renzo Baldini.
@@ -1614,7 +1747,7 @@
# to 1944-06-04; although Rome was an open city during this period, it
# was effectively controlled by Germany.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Italy 1916 only - Jun 3 24:00 1:00 S
Rule Italy 1916 1917 - Sep 30 24:00 0 -
Rule Italy 1917 only - Mar 31 24:00 1:00 S
@@ -1656,8 +1789,8 @@
Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 S
Rule Italy 1978 only - Oct 1 0:00s 0 -
Rule Italy 1979 only - Sep 30 0:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Europe/Rome 0:49:56 - LMT 1866 Sep 22
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Europe/Rome 0:49:56 - LMT 1866 Dec 12
0:49:56 - RMT 1893 Oct 31 23:49:56 # Rome Mean
1:00 Italy CE%sT 1943 Sep 10
1:00 C-Eur CE%sT 1944 Jun 4
@@ -1724,7 +1857,7 @@
# urged Lithuania and Estonia to adopt a similar time policy, but it
# appears that they will not do so....
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Latvia 1989 1996 - Mar lastSun 2:00s 1:00 S
Rule Latvia 1989 1996 - Sep lastSun 2:00s 0 -
@@ -1732,7 +1865,7 @@
# Byalokoz 1919 says Latvia was 1:36:34.
# Go with Byalokoz.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Riga 1:36:34 - LMT 1880
1:36:34 - RMT 1918 Apr 15 2:00 # Riga MT
1:36:34 1:00 LST 1918 Sep 16 3:00 # Latvian ST
@@ -1754,15 +1887,10 @@
# From Paul Eggert (2013-09-09):
# Shanks & Pottenger say Vaduz is like Zurich.
-# From Alois Treindl (2013-09-18):
-# http://www.eliechtensteinensia.li/LIJ/1978/1938-1978/1941.pdf
-# ... confirms on p. 6 that Liechtenstein followed Switzerland in 1941 and 1942.
-# I ... translate only the last two paragraphs:
-# ... during second world war, in the years 1941 and 1942, Liechtenstein
-# introduced daylight saving time, adapting to Switzerland. From 1943 on
-# central European time was in force throughout the year.
-# From a report of the duke's government to the high council,
-# regarding the introduction of a time law, of 31 May 1977.
+# From Alois Treindl (2019-07-04):
+# I was able to access the online archive of the Vaduz paper Vaterland ...
+# I could confirm from the paper that Liechtenstein did in fact follow
+# the same DST in 1941 and 1942 as Switzerland did.
Link Europe/Zurich Europe/Vaduz
@@ -1802,7 +1930,7 @@
# http://www.lrvk.lt/nut/11/n1749.htm
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Vilnius 1:41:16 - LMT 1880
1:24:00 - WMT 1917 # Warsaw Mean Time
1:35:36 - KMT 1919 Oct 10 # Kaunas Mean Time
@@ -1822,7 +1950,7 @@
# Luxembourg
# Whitman disagrees with most of these dates in minor ways;
# go with Shanks & Pottenger.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Lux 1916 only - May 14 23:00 1:00 S
Rule Lux 1916 only - Oct 1 1:00 0 -
Rule Lux 1917 only - Apr 28 23:00 1:00 S
@@ -1846,7 +1974,7 @@
Rule Lux 1927 only - Apr 9 23:00 1:00 S
Rule Lux 1928 only - Apr 14 23:00 1:00 S
Rule Lux 1929 only - Apr 20 23:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun
1:00 Lux CE%sT 1918 Nov 25
0:00 Lux WE%sT 1929 Oct 6 2:00s
@@ -1863,7 +1991,7 @@
# From Paul Eggert (2016-10-21):
# Assume 1900-1972 was like Rome, overriding Shanks.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Malta 1973 only - Mar 31 0:00s 1:00 S
Rule Malta 1973 only - Sep 29 0:00s 0 -
Rule Malta 1974 only - Apr 21 0:00s 1:00 S
@@ -1871,7 +1999,7 @@
Rule Malta 1975 1979 - Apr Sun>=15 2:00 1:00 S
Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 -
Rule Malta 1980 only - Mar 31 2:00 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta
1:00 Italy CE%sT 1973 Mar 31
1:00 Malta CE%sT 1981
@@ -1936,11 +2064,11 @@
# says the 2014-03-30 spring-forward transition was at 02:00 local time.
# Guess that since 1997 Moldova has switched one hour before the EU.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Moldova 1997 max - Mar lastSun 2:00 1:00 S
Rule Moldova 1997 max - Oct lastSun 3:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Chisinau 1:55:20 - LMT 1880
1:55 - CMT 1918 Feb 15 # Chisinau MT
1:44:24 - BMT 1931 Jul 24 # Bucharest MT
@@ -1954,11 +2082,24 @@
2:00 Moldova EE%sT
# Monaco
-# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
-# more precise 0:09:21.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
-Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
- 0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
+#
+# From Michael Deckers (2020-06-12):
+# In the "Journal de Monaco" of 1892-05-24, online at
+# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/b1c67c12c5af11b41ea888fb048e4fe8.pdf
+# we read: ...
+# [In virtue of a Sovereign Ordinance of the May 13 of the current [year],
+# legal time in the Principality will be set to, from the date of June 1,
+# 1892 onwards, to the meridian of Paris, as in France.]
+# In the "Journal de Monaco" of 1911-03-28, online at
+# https://journaldemonaco.gouv.mc/var/jdm/storage/original/application/de74ffb7db53d4f599059fe8f0ed482a.pdf
+# we read an ordinance of 1911-03-16: ...
+# [Legal time in the Principality will be set, from the date of promulgation
+# of the present ordinance, to legal time in France.... Consequently, legal
+# time will be retarded by 9 minutes and 21 seconds.]
+#
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
+Zone Europe/Monaco 0:29:32 - LMT 1892 Jun 1
+ 0:09:21 - PMT 1911 Mar 29 # Paris Mean Time
0:00 France WE%sT 1945 Sep 16 3:00
1:00 France CE%sT 1977
1:00 EU CE%sT
@@ -2006,7 +2147,7 @@
# The data entries before 1945 are taken from
# https://www.staff.science.uu.nl/~gent0113/wettijd/wettijd.htm
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
Rule Neth 1916 only - Oct 1 0:00 0 AMT # Amsterdam Mean Time
Rule Neth 1917 only - Apr 16 2:00s 1:00 NST
@@ -2031,8 +2172,8 @@
Rule Neth 1945 only - Sep 16 2:00s 0 -
#
# Amsterdam Mean Time was +00:19:32.13, but the .13 is omitted
-# below because the current format requires GMTOFF to be an integer.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# below because the current format requires STDOFF to be an integer.
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Amsterdam 0:19:32 - LMT 1835
0:19:32 Neth %s 1937 Jul 1
0:20 Neth +0020/+0120 1940 May 16 0:00
@@ -2043,7 +2184,7 @@
# Norway
# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
# Pottenger.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Norway 1916 only - May 22 1:00 1:00 S
Rule Norway 1916 only - Sep 30 0:00 0 -
Rule Norway 1945 only - Apr 2 2:00s 1:00 S
@@ -2051,7 +2192,7 @@
Rule Norway 1959 1964 - Mar Sun>=15 2:00s 1:00 S
Rule Norway 1959 1965 - Sep Sun>=15 2:00s 0 -
Rule Norway 1965 only - Apr 25 2:00s 1:00 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1
1:00 Norway CE%sT 1940 Aug 10 23:00
1:00 C-Eur CE%sT 1945 Apr 2 2:00
@@ -2112,7 +2253,7 @@
# The 1919 dates and times can be found in Tygodnik Urzędowy nr 1 (1919-03-20),
# <http://www.wbc.poznan.pl/publication/32156> pp 1-2.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Poland 1918 1919 - Sep 16 2:00s 0 -
Rule Poland 1919 only - Apr 15 2:00s 1:00 S
Rule Poland 1944 only - Apr 3 2:00s 1:00 S
@@ -2142,7 +2283,7 @@
Rule Poland 1960 only - Apr 3 1:00s 1:00 S
Rule Poland 1961 1964 - May lastSun 1:00s 1:00 S
Rule Poland 1962 1964 - Sep lastSun 1:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Warsaw 1:24:00 - LMT 1880
1:24:00 - WMT 1915 Aug 5 # Warsaw Mean Time
1:00 C-Eur CE%sT 1918 Sep 16 3:00
@@ -2183,7 +2324,7 @@
# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
# harmonized with EU rules), and that they stayed +0:00 that winter.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
# done every year, depending on what Spain did, because of railroad schedules.
# Go with Shanks & Pottenger.
@@ -2247,7 +2388,7 @@
Rule Port 1981 1982 - Mar lastSun 1:00s 1:00 S
Rule Port 1983 only - Mar lastSun 2:00s 1:00 S
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Lisbon -0:36:45 - LMT 1884
-0:36:45 - LMT 1912 Jan 1 0:00u # Lisbon MT
0:00 Port WE%sT 1966 Apr 3 2:00
@@ -2296,7 +2437,7 @@
# assume that Romania and Moldova switched to EU rules in 1997,
# the same year as Bulgaria.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Romania 1932 only - May 21 0:00s 1:00 S
Rule Romania 1932 1939 - Oct Sun>=1 0:00s 0 -
Rule Romania 1933 1939 - Apr Sun>=2 0:00s 1:00 S
@@ -2306,7 +2447,7 @@
Rule Romania 1980 only - Sep lastSun 1:00 0 -
Rule Romania 1991 1993 - Mar lastSun 0:00s 1:00 S
Rule Romania 1991 1993 - Sep lastSun 0:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
1:44:24 - BMT 1931 Jul 24 # Bucharest MT
2:00 Romania EE%sT 1981 Mar 29 2:00s
@@ -2470,6 +2611,12 @@
# Europe/Kaliningrad covers...
# 39 RU-KGD Kaliningrad Oblast
+# From Paul Eggert (2019-07-25):
+# Although Shanks lists 1945-01-01 as the date for transition from
+# +01/+02 to +02/+03, more likely this is a placeholder. Guess that
+# the transition occurred at 1945-04-10 00:00, which is about when
+# Königsberg surrendered to Soviet troops. (Thanks to Alois Triendl.)
+
# From Paul Eggert (2016-03-18):
# The 1989 transition is from USSR act No. 227 (1989-03-14).
@@ -2486,8 +2633,8 @@
# Moscow on 1991-11-03, switched to Moscow-1 on 1992-01-19.
Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
- 1:00 C-Eur CE%sT 1945
- 2:00 Poland CE%sT 1946
+ 1:00 C-Eur CE%sT 1945 Apr 10
+ 2:00 Poland EE%sT 1946 Apr 7
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
2:00 Russia EE%sT 2011 Mar 27 2:00s
3:00 - +03 2014 Oct 26 2:00s
@@ -3345,7 +3492,7 @@
# See Europe/Rome.
# Serbia
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Belgrade 1:22:00 - LMT 1884
1:00 - CET 1941 Apr 18 23:00
1:00 C-Eur CE%sT 1945
@@ -3388,14 +3535,14 @@
# fallback transition from the next day's 00:59... to 00:00.
# From Michael Deckers (2016-12-15):
-# The Royal Decree of 1900-06-26 quoted by Planesas, online at
+# The Royal Decree of 1900-07-26 quoted by Planesas, online at
# https://www.boe.es/datos/pdfs/BOE//1900/209/A00383-00384.pdf
# says in its article 5 (my translation):
# These dispositions will enter into force beginning with the
# instant at which, according to the time indicated in article 1,
# the 1st day of January of 1901 will begin.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Spain 1918 only - Apr 15 23:00 1:00 S
Rule Spain 1918 1919 - Oct 6 24:00s 0 -
Rule Spain 1919 only - Apr 6 23:00 1:00 S
@@ -3451,7 +3598,7 @@
Rule SpainAfrica 1977 only - Sep 28 0:00 0 -
Rule SpainAfrica 1978 only - Jun 1 0:00 1:00 S
Rule SpainAfrica 1978 only - Aug 4 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Madrid -0:14:44 - LMT 1900 Dec 31 23:45:16
0:00 Spain WE%sT 1940 Mar 16 23:00
1:00 Spain CE%sT 1979
@@ -3519,7 +3666,7 @@
#
# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Stockholm 1:12:12 - LMT 1879 Jan 1
1:00:14 - SET 1900 Jan 1 # Swedish Time
1:00 - CET 1916 May 14 23:00
@@ -3532,7 +3679,7 @@
# By the end of the 18th century clocks and watches became commonplace
# and their performance improved enormously. Communities began to keep
# mean time in preference to apparent time - Geneva from 1780 ....
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# From Whitman (who writes "Midnight?"):
# Rule Swiss 1940 only - Nov 2 0:00 1:00 S
# Rule Swiss 1940 only - Dec 31 0:00 0 -
@@ -3619,10 +3766,10 @@
# 1853-07-16, though it probably occurred at some other date in Zurich, and
# legal civil time probably changed at still some other transition date.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S
Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment.
0:29:46 - BMT 1894 Jun # Bern Mean Time
1:00 Swiss CE%sT 1981
@@ -3630,20 +3777,75 @@
# Turkey
+# From Alois Treindl (2019-08-12):
+# http://www.astrolojidergisi.com/yazsaati.htm has researched the time zone
+# history of Turkey, based on newspaper archives and official documents.
+# From Paul Eggert (2019-08-28):
+# That source (Oya Vulaş, "Türkiye'de Yaz Saati Uygulamaları")
+# is used for 1940/1972, where it seems more reliable than our other
+# sources.
+
+# From Kıvanç Yazan (2019-08-12):
+# http://www.resmigazete.gov.tr/arsiv/14539.pdf#page=24
+# 1973-06-03 01:00 -> 02:00, 1973-11-04 02:00 -> 01:00
+#
+# http://www.resmigazete.gov.tr/arsiv/14829.pdf#page=1
+# 1974-03-31 02:00 -> 03:00, 1974-11-03 02:00 -> 01:00
+#
+# http://www.resmigazete.gov.tr/arsiv/15161.pdf#page=1
+# 1975-03-22 02:00 -> 03:00, 1975-11-02 02:00 -> 01:00
+#
+# http://www.resmigazete.gov.tr/arsiv/15535_1.pdf#page=1
+# 1976-03-21 02:00 -> 03:00, 1976-10-31 02:00 -> 01:00
+#
+# http://www.resmigazete.gov.tr/arsiv/15778.pdf#page=5
+# 1977-04-03 02:00 -> 03:00, 1977-10-16 02:00 -> 01:00,
+# 1978-04-02 02:00 -> 03:00 (not applied, see below)
+# 1978-10-15 02:00 -> 01:00 (not applied, see below)
+# 1979-04-01 02:00 -> 03:00 (not applied, see below)
+# 1979-10-14 02:00 -> 01:00 (not applied, see below)
+#
+# http://www.resmigazete.gov.tr/arsiv/16245.pdf#page=17
+# This cancels the previous decision, and repeats it only for 1978.
+# 1978-04-02 02:00 -> 03:00, 1978-10-15 02:00 -> 01:00
+# (not applied due to standard TZ change below)
+#
+# http://www.resmigazete.gov.tr/arsiv/16331.pdf#page=3
+# This decision changes the default longitude for Turkish time zone from 30
+# degrees East to 45 degrees East. This means a standard TZ change, from +2
+# to +3. This is published & applied on 1978-06-29. At that time, Turkey was
+# already on summer time (already on 45E). Hence, this new law just meant an
+# "continuous summer time". Note that this was reversed in a few years.
+#
+# http://www.resmigazete.gov.tr/arsiv/18119_1.pdf#page=1
+# 1983-07-31 02:00 -> 03:00 (note that this jumps TZ to +4)
+# 1983-10-02 02:00 -> 01:00 (back to +3)
+#
+# http://www.resmigazete.gov.tr/arsiv/18561.pdf (page 1 and 34)
+# At this time, Turkey is still on +3 with no spring-forward on early
+# 1984. This decision is published on 10/31/1984. Page 1 declares
+# the decision of reverting the "default longitude change". So the
+# standard time should go back to +3 (30E). And page 34 explains when
+# that will happen: 1984-11-01 02:00 -> 01:00. You can think of this
+# as "end of continuous summer time, change of standard time zone".
+#
+# http://www.resmigazete.gov.tr/arsiv/18713.pdf#page=1
+# 1985-04-20 01:00 -> 02:00, 1985-09-28 02:00 -> 01:00
+
# From Kıvanç Yazan (2016-09-25):
# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with
# no exceptions.
# 2) 1994's lastSun was overridden with Mar 20 ...
# Here are official papers:
-# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986
-# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987
-# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988
-# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989
-# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992
-# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995
-# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994
-# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997
-# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000
+# http://www.resmigazete.gov.tr/arsiv/19032.pdf#page=2 for 1986
+# http://www.resmigazete.gov.tr/arsiv/19400.pdf#page=4 for 1987
+# http://www.resmigazete.gov.tr/arsiv/19752.pdf#page=15 for 1988
+# http://www.resmigazete.gov.tr/arsiv/20102.pdf#page=6 for 1989
+# http://www.resmigazete.gov.tr/arsiv/20464.pdf#page=1 for 1990 - 1992
+# http://www.resmigazete.gov.tr/arsiv/21531.pdf#page=15 for 1993 - 1995
+# http://www.resmigazete.gov.tr/arsiv/21879.pdf#page=1 for overriding 1994
+# http://www.resmigazete.gov.tr/arsiv/22588.pdf#page=1 for 1996, 1997
+# http://www.resmigazete.gov.tr/arsiv/23286.pdf#page=10 for 1998 - 2000
# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001
# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006
# From Paul Eggert (2016-09-25):
@@ -3713,7 +3915,7 @@
# Although Google Translate misfires on that source, it looks like
# Turkey reversed last month's decision, and so will stay at +03.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Turkey 1916 only - May 1 0:00 1:00 S
Rule Turkey 1916 only - Oct 1 0:00 0 -
Rule Turkey 1920 only - Mar 28 0:00 1:00 S
@@ -3727,56 +3929,46 @@
Rule Turkey 1924 only - May 13 0:00 1:00 S
Rule Turkey 1924 1925 - Oct 1 0:00 0 -
Rule Turkey 1925 only - May 1 0:00 1:00 S
-Rule Turkey 1940 only - Jun 30 0:00 1:00 S
-Rule Turkey 1940 only - Oct 5 0:00 0 -
+Rule Turkey 1940 only - Jul 1 0:00 1:00 S
+Rule Turkey 1940 only - Oct 6 0:00 0 -
Rule Turkey 1940 only - Dec 1 0:00 1:00 S
Rule Turkey 1941 only - Sep 21 0:00 0 -
Rule Turkey 1942 only - Apr 1 0:00 1:00 S
-# Whitman omits the next two transition and gives 1945 Oct 1;
-# go with Shanks & Pottenger.
-Rule Turkey 1942 only - Nov 1 0:00 0 -
-Rule Turkey 1945 only - Apr 2 0:00 1:00 S
Rule Turkey 1945 only - Oct 8 0:00 0 -
Rule Turkey 1946 only - Jun 1 0:00 1:00 S
Rule Turkey 1946 only - Oct 1 0:00 0 -
Rule Turkey 1947 1948 - Apr Sun>=16 0:00 1:00 S
-Rule Turkey 1947 1950 - Oct Sun>=2 0:00 0 -
+Rule Turkey 1947 1951 - Oct Sun>=2 0:00 0 -
Rule Turkey 1949 only - Apr 10 0:00 1:00 S
-Rule Turkey 1950 only - Apr 19 0:00 1:00 S
+Rule Turkey 1950 only - Apr 16 0:00 1:00 S
Rule Turkey 1951 only - Apr 22 0:00 1:00 S
-Rule Turkey 1951 only - Oct 8 0:00 0 -
+# DST for 15 months; unusual but we'll let it pass.
Rule Turkey 1962 only - Jul 15 0:00 1:00 S
-Rule Turkey 1962 only - Oct 8 0:00 0 -
+Rule Turkey 1963 only - Oct 30 0:00 0 -
Rule Turkey 1964 only - May 15 0:00 1:00 S
Rule Turkey 1964 only - Oct 1 0:00 0 -
-Rule Turkey 1970 1972 - May Sun>=2 0:00 1:00 S
-Rule Turkey 1970 1972 - Oct Sun>=2 0:00 0 -
Rule Turkey 1973 only - Jun 3 1:00 1:00 S
-Rule Turkey 1973 only - Nov 4 3:00 0 -
+Rule Turkey 1973 1976 - Oct Sun>=31 2:00 0 -
Rule Turkey 1974 only - Mar 31 2:00 1:00 S
-Rule Turkey 1974 only - Nov 3 5:00 0 -
-Rule Turkey 1975 only - Mar 30 0:00 1:00 S
-Rule Turkey 1975 1976 - Oct lastSun 0:00 0 -
-Rule Turkey 1976 only - Jun 1 0:00 1:00 S
-Rule Turkey 1977 1978 - Apr Sun>=1 0:00 1:00 S
-Rule Turkey 1977 only - Oct 16 0:00 0 -
-Rule Turkey 1979 1980 - Apr Sun>=1 3:00 1:00 S
-Rule Turkey 1979 1982 - Oct Mon>=11 0:00 0 -
-Rule Turkey 1981 1982 - Mar lastSun 3:00 1:00 S
-Rule Turkey 1983 only - Jul 31 0:00 1:00 S
-Rule Turkey 1983 only - Oct 2 0:00 0 -
-Rule Turkey 1985 only - Apr 20 0:00 1:00 S
-Rule Turkey 1985 only - Sep 28 0:00 0 -
+Rule Turkey 1975 only - Mar 22 2:00 1:00 S
+Rule Turkey 1976 only - Mar 21 2:00 1:00 S
+Rule Turkey 1977 1978 - Apr Sun>=1 2:00 1:00 S
+Rule Turkey 1977 1978 - Oct Sun>=15 2:00 0 -
+Rule Turkey 1978 only - Jun 29 0:00 0 -
+Rule Turkey 1983 only - Jul 31 2:00 1:00 S
+Rule Turkey 1983 only - Oct 2 2:00 0 -
+Rule Turkey 1985 only - Apr 20 1:00s 1:00 S
+Rule Turkey 1985 only - Sep 28 1:00s 0 -
Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S
Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 -
Rule Turkey 1994 only - Mar 20 1:00s 1:00 S
Rule Turkey 1995 2006 - Mar lastSun 1:00s 1:00 S
Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Europe/Istanbul 1:55:52 - LMT 1880
1:56:56 - IMT 1910 Oct # Istanbul Mean Time?
- 2:00 Turkey EE%sT 1978 Oct 15
- 3:00 Turkey +03/+04 1985 Apr 20
+ 2:00 Turkey EE%sT 1978 Jun 29
+ 3:00 Turkey +03/+04 1984 Nov 1 2:00
2:00 Turkey EE%sT 2007
2:00 EU EE%sT 2011 Mar 27 1:00u
2:00 - EET 2011 Mar 28 1:00u
@@ -3869,16 +4061,8 @@
# controversial, and some day "Kyiv" may become substantially more popular in
# English; in the meantime, stick with the traditional English "Kiev" as that
# means less disruption for our users.
-#
-# Anyway, none of the common English-language spellings (Kiev, Kyiv, Kieff,
-# Kijeff, Kijev, Kiyef, Kiyeff) do justice to the common pronunciation in
-# Ukrainian, namely [ˈkɪjiu̯] (IPA). This pronunciation has nothing like an
-# English "v" or "f", and instead trails off with what an English-speaker
-# would call a demure "oo" sound, and it would would be better anglicized as
-# "Kuiyu". Here's a sound file, if you would like to do as the Kuiyuvians do:
-# https://commons.wikimedia.org/wiki/File:Uk-Київ.ogg
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# This represents most of Ukraine. See above for the spelling of "Kiev".
Zone Europe/Kiev 2:02:04 - LMT 1880
2:02:04 - KMT 1924 May 2 # Kiev Mean Time
@@ -3889,7 +4073,7 @@
2:00 1:00 EEST 1991 Sep 29 3:00
2:00 E-Eur EE%sT 1995
2:00 EU EE%sT
-# Ruthenia used CET 1990/1991.
+# Transcarpathia used CET 1990/1991.
# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but
# "Uzhgorod" is more common in English.
Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct
diff --git a/tools/java/org/unicode/cldr/util/data/external/UnCodes.txt b/tools/java/org/unicode/cldr/util/data/external/UnCodes.txt
index 0ce17a2..31c9e15 100644
--- a/tools/java/org/unicode/cldr/util/data/external/UnCodes.txt
+++ b/tools/java/org/unicode/cldr/util/data/external/UnCodes.txt
@@ -1,250 +1,250 @@
-Global Code Global Name Region Code Region Name Sub-region Code Sub-region Name Intermediate Region Code Intermediate Region Name Country or Area M49 Code ISO-alpha3 Code Least Developed Countries (LDC) Land Locked Developing Countries (LLDC) Small Island Developing States (SIDS) Developed / Developing Countries
-001 World 002 Africa 015 Northern Africa Algeria 012 DZA Developing
-001 World 002 Africa 015 Northern Africa Egypt 818 EGY Developing
-001 World 002 Africa 015 Northern Africa Libya 434 LBY Developing
-001 World 002 Africa 015 Northern Africa Morocco 504 MAR Developing
-001 World 002 Africa 015 Northern Africa Sudan 729 SDN x Developing
-001 World 002 Africa 015 Northern Africa Tunisia 788 TUN Developing
-001 World 002 Africa 015 Northern Africa Western Sahara 732 ESH Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa British Indian Ocean Territory 086 IOT Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Burundi 108 BDI x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Comoros 174 COM x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Djibouti 262 DJI x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Eritrea 232 ERI x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Ethiopia 231 ETH x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa French Southern Territories 260 ATF Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Kenya 404 KEN Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Madagascar 450 MDG x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Malawi 454 MWI x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mauritius 480 MUS x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mayotte 175 MYT Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mozambique 508 MOZ x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Réunion 638 REU Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Rwanda 646 RWA x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Seychelles 690 SYC x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Somalia 706 SOM x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa South Sudan 728 SSD x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Uganda 800 UGA x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa United Republic of Tanzania 834 TZA x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Zambia 894 ZMB x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Zimbabwe 716 ZWE x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Angola 024 AGO x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Cameroon 120 CMR Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Central African Republic 140 CAF x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Chad 148 TCD x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Congo 178 COG Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Democratic Republic of the Congo 180 COD x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Equatorial Guinea 226 GNQ Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Gabon 266 GAB Developing
-001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Sao Tome and Principe 678 STP x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Botswana 072 BWA x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Eswatini 748 SWZ x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Lesotho 426 LSO x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Namibia 516 NAM Developing
-001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa South Africa 710 ZAF Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Benin 204 BEN x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Burkina Faso 854 BFA x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Cabo Verde 132 CPV x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Côte d’Ivoire 384 CIV Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Gambia 270 GMB x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Ghana 288 GHA Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Guinea 324 GIN x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Guinea-Bissau 624 GNB x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Liberia 430 LBR x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Mali 466 MLI x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Mauritania 478 MRT x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Niger 562 NER x x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Nigeria 566 NGA Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Saint Helena 654 SHN Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Senegal 686 SEN x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Sierra Leone 694 SLE x Developing
-001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Togo 768 TGO x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Anguilla 660 AIA x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Antigua and Barbuda 028 ATG x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Aruba 533 ABW x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Bahamas 044 BHS x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Barbados 052 BRB x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Bonaire, Sint Eustatius and Saba 535 BES x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean British Virgin Islands 092 VGB x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Cayman Islands 136 CYM Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Cuba 192 CUB x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Curaçao 531 CUW x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Dominica 212 DMA x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Dominican Republic 214 DOM x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Grenada 308 GRD x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Guadeloupe 312 GLP Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Haiti 332 HTI x x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Jamaica 388 JAM x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Martinique 474 MTQ Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Montserrat 500 MSR x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Puerto Rico 630 PRI x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Barthélemy 652 BLM Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Kitts and Nevis 659 KNA x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Lucia 662 LCA x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Martin (French Part) 663 MAF Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Vincent and the Grenadines 670 VCT x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Sint Maarten (Dutch part) 534 SXM x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Trinidad and Tobago 780 TTO x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Turks and Caicos Islands 796 TCA Developing
-001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean United States Virgin Islands 850 VIR x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Belize 084 BLZ x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Costa Rica 188 CRI Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America El Salvador 222 SLV Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Guatemala 320 GTM Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Honduras 340 HND Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Mexico 484 MEX Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Nicaragua 558 NIC Developing
-001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Panama 591 PAN Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Argentina 032 ARG Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Bolivia (Plurinational State of) 068 BOL x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Bouvet Island 074 BVT Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Brazil 076 BRA Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Chile 152 CHL Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Colombia 170 COL Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Ecuador 218 ECU Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Falkland Islands (Malvinas) 238 FLK Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America French Guiana 254 GUF Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Guyana 328 GUY x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Paraguay 600 PRY x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Peru 604 PER Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America South Georgia and the South Sandwich Islands 239 SGS Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Suriname 740 SUR x Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Uruguay 858 URY Developing
-001 World 019 Americas 419 Latin America and the Caribbean 005 South America Venezuela (Bolivarian Republic of) 862 VEN Developing
-001 World 019 Americas 021 Northern America Bermuda 060 BMU Developed
-001 World 019 Americas 021 Northern America Canada 124 CAN Developed
-001 World 019 Americas 021 Northern America Greenland 304 GRL Developed
-001 World 019 Americas 021 Northern America Saint Pierre and Miquelon 666 SPM Developed
-001 World 019 Americas 021 Northern America United States of America 840 USA Developed
-001 World Antarctica 010 ATA
-001 World 142 Asia 143 Central Asia Kazakhstan 398 KAZ x Developing
-001 World 142 Asia 143 Central Asia Kyrgyzstan 417 KGZ x Developing
-001 World 142 Asia 143 Central Asia Tajikistan 762 TJK x Developing
-001 World 142 Asia 143 Central Asia Turkmenistan 795 TKM x Developing
-001 World 142 Asia 143 Central Asia Uzbekistan 860 UZB x Developing
-001 World 142 Asia 030 Eastern Asia China 156 CHN Developing
-001 World 142 Asia 030 Eastern Asia China, Hong Kong Special Administrative Region 344 HKG Developing
-001 World 142 Asia 030 Eastern Asia China, Macao Special Administrative Region 446 MAC Developing
-001 World 142 Asia 030 Eastern Asia Democratic People's Republic of Korea 408 PRK Developing
-001 World 142 Asia 030 Eastern Asia Japan 392 JPN Developed
-001 World 142 Asia 030 Eastern Asia Mongolia 496 MNG x Developing
-001 World 142 Asia 030 Eastern Asia Republic of Korea 410 KOR Developing
-001 World 142 Asia 035 South-eastern Asia Brunei Darussalam 096 BRN Developing
-001 World 142 Asia 035 South-eastern Asia Cambodia 116 KHM x Developing
-001 World 142 Asia 035 South-eastern Asia Indonesia 360 IDN Developing
-001 World 142 Asia 035 South-eastern Asia Lao People's Democratic Republic 418 LAO x x Developing
-001 World 142 Asia 035 South-eastern Asia Malaysia 458 MYS Developing
-001 World 142 Asia 035 South-eastern Asia Myanmar 104 MMR x Developing
-001 World 142 Asia 035 South-eastern Asia Philippines 608 PHL Developing
-001 World 142 Asia 035 South-eastern Asia Singapore 702 SGP x Developing
-001 World 142 Asia 035 South-eastern Asia Thailand 764 THA Developing
-001 World 142 Asia 035 South-eastern Asia Timor-Leste 626 TLS x x Developing
-001 World 142 Asia 035 South-eastern Asia Viet Nam 704 VNM Developing
-001 World 142 Asia 034 Southern Asia Afghanistan 004 AFG x x Developing
-001 World 142 Asia 034 Southern Asia Bangladesh 050 BGD x Developing
-001 World 142 Asia 034 Southern Asia Bhutan 064 BTN x x Developing
-001 World 142 Asia 034 Southern Asia India 356 IND Developing
-001 World 142 Asia 034 Southern Asia Iran (Islamic Republic of) 364 IRN Developing
-001 World 142 Asia 034 Southern Asia Maldives 462 MDV x Developing
-001 World 142 Asia 034 Southern Asia Nepal 524 NPL x x Developing
-001 World 142 Asia 034 Southern Asia Pakistan 586 PAK Developing
-001 World 142 Asia 034 Southern Asia Sri Lanka 144 LKA Developing
-001 World 142 Asia 145 Western Asia Armenia 051 ARM x Developing
-001 World 142 Asia 145 Western Asia Azerbaijan 031 AZE x Developing
-001 World 142 Asia 145 Western Asia Bahrain 048 BHR Developing
-001 World 142 Asia 145 Western Asia Cyprus 196 CYP Developed
-001 World 142 Asia 145 Western Asia Georgia 268 GEO Developing
-001 World 142 Asia 145 Western Asia Iraq 368 IRQ Developing
-001 World 142 Asia 145 Western Asia Israel 376 ISR Developed
-001 World 142 Asia 145 Western Asia Jordan 400 JOR Developing
-001 World 142 Asia 145 Western Asia Kuwait 414 KWT Developing
-001 World 142 Asia 145 Western Asia Lebanon 422 LBN Developing
-001 World 142 Asia 145 Western Asia Oman 512 OMN Developing
-001 World 142 Asia 145 Western Asia Qatar 634 QAT Developing
-001 World 142 Asia 145 Western Asia Saudi Arabia 682 SAU Developing
-001 World 142 Asia 145 Western Asia State of Palestine 275 PSE Developing
-001 World 142 Asia 145 Western Asia Syrian Arab Republic 760 SYR Developing
-001 World 142 Asia 145 Western Asia Turkey 792 TUR Developing
-001 World 142 Asia 145 Western Asia United Arab Emirates 784 ARE Developing
-001 World 142 Asia 145 Western Asia Yemen 887 YEM x Developing
-001 World 150 Europe 151 Eastern Europe Belarus 112 BLR Developed
-001 World 150 Europe 151 Eastern Europe Bulgaria 100 BGR Developed
-001 World 150 Europe 151 Eastern Europe Czechia 203 CZE Developed
-001 World 150 Europe 151 Eastern Europe Hungary 348 HUN Developed
-001 World 150 Europe 151 Eastern Europe Poland 616 POL Developed
-001 World 150 Europe 151 Eastern Europe Republic of Moldova 498 MDA x Developed
-001 World 150 Europe 151 Eastern Europe Romania 642 ROU Developed
-001 World 150 Europe 151 Eastern Europe Russian Federation 643 RUS Developed
-001 World 150 Europe 151 Eastern Europe Slovakia 703 SVK Developed
-001 World 150 Europe 151 Eastern Europe Ukraine 804 UKR Developed
-001 World 150 Europe 154 Northern Europe Åland Islands 248 ALA Developed
-001 World 150 Europe 154 Northern Europe 830 Channel Islands Guernsey 831 GGY Developed
-001 World 150 Europe 154 Northern Europe 830 Channel Islands Jersey 832 JEY Developed
-001 World 150 Europe 154 Northern Europe 830 Channel Islands Sark 680 Developed
-001 World 150 Europe 154 Northern Europe Denmark 208 DNK Developed
-001 World 150 Europe 154 Northern Europe Estonia 233 EST Developed
-001 World 150 Europe 154 Northern Europe Faroe Islands 234 FRO Developed
-001 World 150 Europe 154 Northern Europe Finland 246 FIN Developed
-001 World 150 Europe 154 Northern Europe Iceland 352 ISL Developed
-001 World 150 Europe 154 Northern Europe Ireland 372 IRL Developed
-001 World 150 Europe 154 Northern Europe Isle of Man 833 IMN Developed
-001 World 150 Europe 154 Northern Europe Latvia 428 LVA Developed
-001 World 150 Europe 154 Northern Europe Lithuania 440 LTU Developed
-001 World 150 Europe 154 Northern Europe Norway 578 NOR Developed
-001 World 150 Europe 154 Northern Europe Svalbard and Jan Mayen Islands 744 SJM Developed
-001 World 150 Europe 154 Northern Europe Sweden 752 SWE Developed
-001 World 150 Europe 154 Northern Europe United Kingdom of Great Britain and Northern Ireland 826 GBR Developed
-001 World 150 Europe 039 Southern Europe Albania 008 ALB Developed
-001 World 150 Europe 039 Southern Europe Andorra 020 AND Developed
-001 World 150 Europe 039 Southern Europe Bosnia and Herzegovina 070 BIH Developed
-001 World 150 Europe 039 Southern Europe Croatia 191 HRV Developed
-001 World 150 Europe 039 Southern Europe Gibraltar 292 GIB Developed
-001 World 150 Europe 039 Southern Europe Greece 300 GRC Developed
-001 World 150 Europe 039 Southern Europe Holy See 336 VAT Developed
-001 World 150 Europe 039 Southern Europe Italy 380 ITA Developed
-001 World 150 Europe 039 Southern Europe Malta 470 MLT Developed
-001 World 150 Europe 039 Southern Europe Montenegro 499 MNE Developed
-001 World 150 Europe 039 Southern Europe North Macedonia 807 MKD x Developed
-001 World 150 Europe 039 Southern Europe Portugal 620 PRT Developed
-001 World 150 Europe 039 Southern Europe San Marino 674 SMR Developed
-001 World 150 Europe 039 Southern Europe Serbia 688 SRB Developed
-001 World 150 Europe 039 Southern Europe Slovenia 705 SVN Developed
-001 World 150 Europe 039 Southern Europe Spain 724 ESP Developed
-001 World 150 Europe 155 Western Europe Austria 040 AUT Developed
-001 World 150 Europe 155 Western Europe Belgium 056 BEL Developed
-001 World 150 Europe 155 Western Europe France 250 FRA Developed
-001 World 150 Europe 155 Western Europe Germany 276 DEU Developed
-001 World 150 Europe 155 Western Europe Liechtenstein 438 LIE Developed
-001 World 150 Europe 155 Western Europe Luxembourg 442 LUX Developed
-001 World 150 Europe 155 Western Europe Monaco 492 MCO Developed
-001 World 150 Europe 155 Western Europe Netherlands 528 NLD Developed
-001 World 150 Europe 155 Western Europe Switzerland 756 CHE Developed
-001 World 009 Oceania 053 Australia and New Zealand Australia 036 AUS Developed
-001 World 009 Oceania 053 Australia and New Zealand Christmas Island 162 CXR Developed
-001 World 009 Oceania 053 Australia and New Zealand Cocos (Keeling) Islands 166 CCK Developed
-001 World 009 Oceania 053 Australia and New Zealand Heard Island and McDonald Islands 334 HMD Developed
-001 World 009 Oceania 053 Australia and New Zealand New Zealand 554 NZL Developed
-001 World 009 Oceania 053 Australia and New Zealand Norfolk Island 574 NFK Developed
-001 World 009 Oceania 054 Melanesia Fiji 242 FJI x Developing
-001 World 009 Oceania 054 Melanesia New Caledonia 540 NCL x Developing
-001 World 009 Oceania 054 Melanesia Papua New Guinea 598 PNG x Developing
-001 World 009 Oceania 054 Melanesia Solomon Islands 090 SLB x x Developing
-001 World 009 Oceania 054 Melanesia Vanuatu 548 VUT x x Developing
-001 World 009 Oceania 057 Micronesia Guam 316 GUM x Developing
-001 World 009 Oceania 057 Micronesia Kiribati 296 KIR x x Developing
-001 World 009 Oceania 057 Micronesia Marshall Islands 584 MHL x Developing
-001 World 009 Oceania 057 Micronesia Micronesia (Federated States of) 583 FSM x Developing
-001 World 009 Oceania 057 Micronesia Nauru 520 NRU x Developing
-001 World 009 Oceania 057 Micronesia Northern Mariana Islands 580 MNP x Developing
-001 World 009 Oceania 057 Micronesia Palau 585 PLW x Developing
-001 World 009 Oceania 057 Micronesia United States Minor Outlying Islands 581 UMI Developing
-001 World 009 Oceania 061 Polynesia American Samoa 016 ASM x Developing
-001 World 009 Oceania 061 Polynesia Cook Islands 184 COK x Developing
-001 World 009 Oceania 061 Polynesia French Polynesia 258 PYF x Developing
-001 World 009 Oceania 061 Polynesia Niue 570 NIU x Developing
-001 World 009 Oceania 061 Polynesia Pitcairn 612 PCN Developing
-001 World 009 Oceania 061 Polynesia Samoa 882 WSM x Developing
-001 World 009 Oceania 061 Polynesia Tokelau 772 TKL Developing
-001 World 009 Oceania 061 Polynesia Tonga 776 TON x Developing
-001 World 009 Oceania 061 Polynesia Tuvalu 798 TUV x x Developing
-001 World 009 Oceania 061 Polynesia Wallis and Futuna Islands 876 WLF Developing
\ No newline at end of file
+Global Code Global Name Region Code Region Name Sub-region Code Sub-region Name Intermediate Region Code Intermediate Region Name Country or Area M49 Code ISO-alpha2 Code ISO-alpha3 Code Least Developed Countries (LDC) Land Locked Developing Countries (LLDC) Small Island Developing States (SIDS) Developed / Developing Countries
+001 World 002 Africa 015 Northern Africa Algeria 012 DZ DZA Developing
+001 World 002 Africa 015 Northern Africa Egypt 818 EG EGY Developing
+001 World 002 Africa 015 Northern Africa Libya 434 LY LBY Developing
+001 World 002 Africa 015 Northern Africa Morocco 504 MA MAR Developing
+001 World 002 Africa 015 Northern Africa Sudan 729 SD SDN x Developing
+001 World 002 Africa 015 Northern Africa Tunisia 788 TN TUN Developing
+001 World 002 Africa 015 Northern Africa Western Sahara 732 EH ESH Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa British Indian Ocean Territory 086 IO IOT Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Burundi 108 BI BDI x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Comoros 174 KM COM x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Djibouti 262 DJ DJI x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Eritrea 232 ER ERI x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Ethiopia 231 ET ETH x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa French Southern Territories 260 TF ATF Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Kenya 404 KE KEN Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Madagascar 450 MG MDG x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Malawi 454 MW MWI x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mauritius 480 MU MUS x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mayotte 175 YT MYT Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Mozambique 508 MZ MOZ x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Réunion 638 RE REU Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Rwanda 646 RW RWA x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Seychelles 690 SC SYC x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Somalia 706 SO SOM x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa South Sudan 728 SS SSD x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Uganda 800 UG UGA x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa United Republic of Tanzania 834 TZ TZA x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Zambia 894 ZM ZMB x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 014 Eastern Africa Zimbabwe 716 ZW ZWE x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Angola 024 AO AGO x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Cameroon 120 CM CMR Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Central African Republic 140 CF CAF x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Chad 148 TD TCD x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Congo 178 CG COG Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Democratic Republic of the Congo 180 CD COD x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Equatorial Guinea 226 GQ GNQ Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Gabon 266 GA GAB Developing
+001 World 002 Africa 202 Sub-Saharan Africa 017 Middle Africa Sao Tome and Principe 678 ST STP x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Botswana 072 BW BWA x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Eswatini 748 SZ SWZ x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Lesotho 426 LS LSO x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa Namibia 516 NA NAM Developing
+001 World 002 Africa 202 Sub-Saharan Africa 018 Southern Africa South Africa 710 ZA ZAF Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Benin 204 BJ BEN x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Burkina Faso 854 BF BFA x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Cabo Verde 132 CV CPV x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Côte d’Ivoire 384 CI CIV Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Gambia 270 GM GMB x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Ghana 288 GH GHA Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Guinea 324 GN GIN x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Guinea-Bissau 624 GW GNB x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Liberia 430 LR LBR x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Mali 466 ML MLI x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Mauritania 478 MR MRT x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Niger 562 NE NER x x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Nigeria 566 NG NGA Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Saint Helena 654 SH SHN Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Senegal 686 SN SEN x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Sierra Leone 694 SL SLE x Developing
+001 World 002 Africa 202 Sub-Saharan Africa 011 Western Africa Togo 768 TG TGO x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Anguilla 660 AI AIA x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Antigua and Barbuda 028 AG ATG x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Aruba 533 AW ABW x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Bahamas 044 BS BHS x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Barbados 052 BB BRB x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Bonaire, Sint Eustatius and Saba 535 BQ BES x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean British Virgin Islands 092 VG VGB x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Cayman Islands 136 KY CYM Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Cuba 192 CU CUB x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Curaçao 531 CW CUW x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Dominica 212 DM DMA x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Dominican Republic 214 DO DOM x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Grenada 308 GD GRD x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Guadeloupe 312 GP GLP Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Haiti 332 HT HTI x x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Jamaica 388 JM JAM x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Martinique 474 MQ MTQ Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Montserrat 500 MS MSR x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Puerto Rico 630 PR PRI x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Barthélemy 652 BL BLM Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Kitts and Nevis 659 KN KNA x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Lucia 662 LC LCA x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Martin (French Part) 663 MF MAF Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Saint Vincent and the Grenadines 670 VC VCT x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Sint Maarten (Dutch part) 534 SX SXM x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Trinidad and Tobago 780 TT TTO x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean Turks and Caicos Islands 796 TC TCA Developing
+001 World 019 Americas 419 Latin America and the Caribbean 029 Caribbean United States Virgin Islands 850 VI VIR x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Belize 084 BZ BLZ x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Costa Rica 188 CR CRI Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America El Salvador 222 SV SLV Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Guatemala 320 GT GTM Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Honduras 340 HN HND Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Mexico 484 MX MEX Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Nicaragua 558 NI NIC Developing
+001 World 019 Americas 419 Latin America and the Caribbean 013 Central America Panama 591 PA PAN Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Argentina 032 AR ARG Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Bolivia (Plurinational State of) 068 BO BOL x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Bouvet Island 074 BV BVT Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Brazil 076 BR BRA Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Chile 152 CL CHL Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Colombia 170 CO COL Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Ecuador 218 EC ECU Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Falkland Islands (Malvinas) 238 FK FLK Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America French Guiana 254 GF GUF Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Guyana 328 GY GUY x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Paraguay 600 PY PRY x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Peru 604 PE PER Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America South Georgia and the South Sandwich Islands 239 GS SGS Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Suriname 740 SR SUR x Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Uruguay 858 UY URY Developing
+001 World 019 Americas 419 Latin America and the Caribbean 005 South America Venezuela (Bolivarian Republic of) 862 VE VEN Developing
+001 World 019 Americas 021 Northern America Bermuda 060 BM BMU Developed
+001 World 019 Americas 021 Northern America Canada 124 CA CAN Developed
+001 World 019 Americas 021 Northern America Greenland 304 GL GRL Developed
+001 World 019 Americas 021 Northern America Saint Pierre and Miquelon 666 PM SPM Developed
+001 World 019 Americas 021 Northern America United States of America 840 US USA Developed
+001 World Antarctica 010 AQ ATA
+001 World 142 Asia 143 Central Asia Kazakhstan 398 KZ KAZ x Developing
+001 World 142 Asia 143 Central Asia Kyrgyzstan 417 KG KGZ x Developing
+001 World 142 Asia 143 Central Asia Tajikistan 762 TJ TJK x Developing
+001 World 142 Asia 143 Central Asia Turkmenistan 795 TM TKM x Developing
+001 World 142 Asia 143 Central Asia Uzbekistan 860 UZ UZB x Developing
+001 World 142 Asia 030 Eastern Asia China 156 CN CHN Developing
+001 World 142 Asia 030 Eastern Asia China, Hong Kong Special Administrative Region 344 HK HKG Developing
+001 World 142 Asia 030 Eastern Asia China, Macao Special Administrative Region 446 MO MAC Developing
+001 World 142 Asia 030 Eastern Asia Democratic People's Republic of Korea 408 KP PRK Developing
+001 World 142 Asia 030 Eastern Asia Japan 392 JP JPN Developed
+001 World 142 Asia 030 Eastern Asia Mongolia 496 MN MNG x Developing
+001 World 142 Asia 030 Eastern Asia Republic of Korea 410 KR KOR Developing
+001 World 142 Asia 035 South-eastern Asia Brunei Darussalam 096 BN BRN Developing
+001 World 142 Asia 035 South-eastern Asia Cambodia 116 KH KHM x Developing
+001 World 142 Asia 035 South-eastern Asia Indonesia 360 ID IDN Developing
+001 World 142 Asia 035 South-eastern Asia Lao People's Democratic Republic 418 LA LAO x x Developing
+001 World 142 Asia 035 South-eastern Asia Malaysia 458 MY MYS Developing
+001 World 142 Asia 035 South-eastern Asia Myanmar 104 MM MMR x Developing
+001 World 142 Asia 035 South-eastern Asia Philippines 608 PH PHL Developing
+001 World 142 Asia 035 South-eastern Asia Singapore 702 SG SGP x Developing
+001 World 142 Asia 035 South-eastern Asia Thailand 764 TH THA Developing
+001 World 142 Asia 035 South-eastern Asia Timor-Leste 626 TL TLS x x Developing
+001 World 142 Asia 035 South-eastern Asia Viet Nam 704 VN VNM Developing
+001 World 142 Asia 034 Southern Asia Afghanistan 004 AF AFG x x Developing
+001 World 142 Asia 034 Southern Asia Bangladesh 050 BD BGD x Developing
+001 World 142 Asia 034 Southern Asia Bhutan 064 BT BTN x x Developing
+001 World 142 Asia 034 Southern Asia India 356 IN IND Developing
+001 World 142 Asia 034 Southern Asia Iran (Islamic Republic of) 364 IR IRN Developing
+001 World 142 Asia 034 Southern Asia Maldives 462 MV MDV x Developing
+001 World 142 Asia 034 Southern Asia Nepal 524 NP NPL x x Developing
+001 World 142 Asia 034 Southern Asia Pakistan 586 PK PAK Developing
+001 World 142 Asia 034 Southern Asia Sri Lanka 144 LK LKA Developing
+001 World 142 Asia 145 Western Asia Armenia 051 AM ARM x Developing
+001 World 142 Asia 145 Western Asia Azerbaijan 031 AZ AZE x Developing
+001 World 142 Asia 145 Western Asia Bahrain 048 BH BHR Developing
+001 World 142 Asia 145 Western Asia Cyprus 196 CY CYP Developed
+001 World 142 Asia 145 Western Asia Georgia 268 GE GEO Developing
+001 World 142 Asia 145 Western Asia Iraq 368 IQ IRQ Developing
+001 World 142 Asia 145 Western Asia Israel 376 IL ISR Developed
+001 World 142 Asia 145 Western Asia Jordan 400 JO JOR Developing
+001 World 142 Asia 145 Western Asia Kuwait 414 KW KWT Developing
+001 World 142 Asia 145 Western Asia Lebanon 422 LB LBN Developing
+001 World 142 Asia 145 Western Asia Oman 512 OM OMN Developing
+001 World 142 Asia 145 Western Asia Qatar 634 QA QAT Developing
+001 World 142 Asia 145 Western Asia Saudi Arabia 682 SA SAU Developing
+001 World 142 Asia 145 Western Asia State of Palestine 275 PS PSE Developing
+001 World 142 Asia 145 Western Asia Syrian Arab Republic 760 SY SYR Developing
+001 World 142 Asia 145 Western Asia Turkey 792 TR TUR Developing
+001 World 142 Asia 145 Western Asia United Arab Emirates 784 AE ARE Developing
+001 World 142 Asia 145 Western Asia Yemen 887 YE YEM x Developing
+001 World 150 Europe 151 Eastern Europe Belarus 112 BY BLR Developed
+001 World 150 Europe 151 Eastern Europe Bulgaria 100 BG BGR Developed
+001 World 150 Europe 151 Eastern Europe Czechia 203 CZ CZE Developed
+001 World 150 Europe 151 Eastern Europe Hungary 348 HU HUN Developed
+001 World 150 Europe 151 Eastern Europe Poland 616 PL POL Developed
+001 World 150 Europe 151 Eastern Europe Republic of Moldova 498 MD MDA x Developed
+001 World 150 Europe 151 Eastern Europe Romania 642 RO ROU Developed
+001 World 150 Europe 151 Eastern Europe Russian Federation 643 RU RUS Developed
+001 World 150 Europe 151 Eastern Europe Slovakia 703 SK SVK Developed
+001 World 150 Europe 151 Eastern Europe Ukraine 804 UA UKR Developed
+001 World 150 Europe 154 Northern Europe Åland Islands 248 AX ALA Developed
+001 World 150 Europe 154 Northern Europe 830 Channel Islands Guernsey 831 GG GGY Developed
+001 World 150 Europe 154 Northern Europe 830 Channel Islands Jersey 832 JE JEY Developed
+001 World 150 Europe 154 Northern Europe 830 Channel Islands Sark 680 Developed
+001 World 150 Europe 154 Northern Europe Denmark 208 DK DNK Developed
+001 World 150 Europe 154 Northern Europe Estonia 233 EE EST Developed
+001 World 150 Europe 154 Northern Europe Faroe Islands 234 FO FRO Developed
+001 World 150 Europe 154 Northern Europe Finland 246 FI FIN Developed
+001 World 150 Europe 154 Northern Europe Iceland 352 IS ISL Developed
+001 World 150 Europe 154 Northern Europe Ireland 372 IE IRL Developed
+001 World 150 Europe 154 Northern Europe Isle of Man 833 IM IMN Developed
+001 World 150 Europe 154 Northern Europe Latvia 428 LV LVA Developed
+001 World 150 Europe 154 Northern Europe Lithuania 440 LT LTU Developed
+001 World 150 Europe 154 Northern Europe Norway 578 NO NOR Developed
+001 World 150 Europe 154 Northern Europe Svalbard and Jan Mayen Islands 744 SJ SJM Developed
+001 World 150 Europe 154 Northern Europe Sweden 752 SE SWE Developed
+001 World 150 Europe 154 Northern Europe United Kingdom of Great Britain and Northern Ireland 826 GB GBR Developed
+001 World 150 Europe 039 Southern Europe Albania 008 AL ALB Developed
+001 World 150 Europe 039 Southern Europe Andorra 020 AD AND Developed
+001 World 150 Europe 039 Southern Europe Bosnia and Herzegovina 070 BA BIH Developed
+001 World 150 Europe 039 Southern Europe Croatia 191 HR HRV Developed
+001 World 150 Europe 039 Southern Europe Gibraltar 292 GI GIB Developed
+001 World 150 Europe 039 Southern Europe Greece 300 GR GRC Developed
+001 World 150 Europe 039 Southern Europe Holy See 336 VA VAT Developed
+001 World 150 Europe 039 Southern Europe Italy 380 IT ITA Developed
+001 World 150 Europe 039 Southern Europe Malta 470 MT MLT Developed
+001 World 150 Europe 039 Southern Europe Montenegro 499 ME MNE Developed
+001 World 150 Europe 039 Southern Europe North Macedonia 807 MK MKD x Developed
+001 World 150 Europe 039 Southern Europe Portugal 620 PT PRT Developed
+001 World 150 Europe 039 Southern Europe San Marino 674 SM SMR Developed
+001 World 150 Europe 039 Southern Europe Serbia 688 RS SRB Developed
+001 World 150 Europe 039 Southern Europe Slovenia 705 SI SVN Developed
+001 World 150 Europe 039 Southern Europe Spain 724 ES ESP Developed
+001 World 150 Europe 155 Western Europe Austria 040 AT AUT Developed
+001 World 150 Europe 155 Western Europe Belgium 056 BE BEL Developed
+001 World 150 Europe 155 Western Europe France 250 FR FRA Developed
+001 World 150 Europe 155 Western Europe Germany 276 DE DEU Developed
+001 World 150 Europe 155 Western Europe Liechtenstein 438 LI LIE Developed
+001 World 150 Europe 155 Western Europe Luxembourg 442 LU LUX Developed
+001 World 150 Europe 155 Western Europe Monaco 492 MC MCO Developed
+001 World 150 Europe 155 Western Europe Netherlands 528 NL NLD Developed
+001 World 150 Europe 155 Western Europe Switzerland 756 CH CHE Developed
+001 World 009 Oceania 053 Australia and New Zealand Australia 036 AU AUS Developed
+001 World 009 Oceania 053 Australia and New Zealand Christmas Island 162 CX CXR Developed
+001 World 009 Oceania 053 Australia and New Zealand Cocos (Keeling) Islands 166 CC CCK Developed
+001 World 009 Oceania 053 Australia and New Zealand Heard Island and McDonald Islands 334 HM HMD Developed
+001 World 009 Oceania 053 Australia and New Zealand New Zealand 554 NZ NZL Developed
+001 World 009 Oceania 053 Australia and New Zealand Norfolk Island 574 NF NFK Developed
+001 World 009 Oceania 054 Melanesia Fiji 242 FJ FJI x Developing
+001 World 009 Oceania 054 Melanesia New Caledonia 540 NC NCL x Developing
+001 World 009 Oceania 054 Melanesia Papua New Guinea 598 PG PNG x Developing
+001 World 009 Oceania 054 Melanesia Solomon Islands 090 SB SLB x x Developing
+001 World 009 Oceania 054 Melanesia Vanuatu 548 VU VUT x x Developing
+001 World 009 Oceania 057 Micronesia Guam 316 GU GUM x Developing
+001 World 009 Oceania 057 Micronesia Kiribati 296 KI KIR x x Developing
+001 World 009 Oceania 057 Micronesia Marshall Islands 584 MH MHL x Developing
+001 World 009 Oceania 057 Micronesia Micronesia (Federated States of) 583 FM FSM x Developing
+001 World 009 Oceania 057 Micronesia Nauru 520 NR NRU x Developing
+001 World 009 Oceania 057 Micronesia Northern Mariana Islands 580 MP MNP x Developing
+001 World 009 Oceania 057 Micronesia Palau 585 PW PLW x Developing
+001 World 009 Oceania 057 Micronesia United States Minor Outlying Islands 581 UM UMI Developing
+001 World 009 Oceania 061 Polynesia American Samoa 016 AS ASM x Developing
+001 World 009 Oceania 061 Polynesia Cook Islands 184 CK COK x Developing
+001 World 009 Oceania 061 Polynesia French Polynesia 258 PF PYF x Developing
+001 World 009 Oceania 061 Polynesia Niue 570 NU NIU x Developing
+001 World 009 Oceania 061 Polynesia Pitcairn 612 PN PCN Developing
+001 World 009 Oceania 061 Polynesia Samoa 882 WS WSM x Developing
+001 World 009 Oceania 061 Polynesia Tokelau 772 TK TKL Developing
+001 World 009 Oceania 061 Polynesia Tonga 776 TO TON x Developing
+001 World 009 Oceania 061 Polynesia Tuvalu 798 TV TUV x x Developing
+001 World 009 Oceania 061 Polynesia Wallis and Futuna Islands 876 WF WLF Developing
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/data/external/alternate_country_names.txt b/tools/java/org/unicode/cldr/util/data/external/alternate_country_names.txt
index 0533b45..efcfd07 100644
--- a/tools/java/org/unicode/cldr/util/data/external/alternate_country_names.txt
+++ b/tools/java/org/unicode/cldr/util/data/external/alternate_country_names.txt
@@ -46,7 +46,7 @@
FM; Micronesia; Federated States of Micronesia
FM; Micronesia; Micronesia, Fed. Sts.
FM; Micronesia; Micronesia, Federated States of
-FM; ; Micronesia (Federated States of)
+FM; Micronesia; Micronesia (Federated States of)
FO; Faroe Islands; Faeroe Islands
@@ -75,11 +75,14 @@
KP; North Korea; Democratic People's Republic of Korea
KP; North Korea; Korea, Dem. Rep.
KP; North Korea; Korea, Democratic People's Republic of
+KP; North Korea; Korea, North
+KP; North Korea; Korea, Dem. People’s Rep.
KR; South Korea; Korea, Rep.
KR; South Korea; Korea, Republic of
KR; South Korea; Rep. Korea
KR; South Korea; Republic of Korea
+KR; South Korea; Korea, South
LA; Laos; Lao PDR
LA; Laos; Lao People's Democratic Republic
@@ -97,6 +100,7 @@
MK; Macedonia; The Former Yugoslav Rep. of Macedonia
MK; Macedonia; The Former Yugoslav Republic of Macedonia
MK; Macedonia; TFYR of Macedonia
+MK; Macedonia; Macedonia
MM; Myanmar; Burma
@@ -128,6 +132,7 @@
SY; Syria; Syrian Arab Republic
SZ; Eswatini; eSwatini; Swaziland
+SZ; Eswatini; Swaziland
SH; Saint Helena; Saint Helena, Ascension, and Tristan da Cunha
@@ -232,3 +237,4 @@
skip; skip; Sub-Saharan Africa (developing only)
skip; skip; Sudan (pre-secession)
skip; skip; Upper middle income
+skip; skip; Paracel Islands
diff --git a/tools/java/org/unicode/cldr/util/data/external/factbook_gdp_ppp.txt b/tools/java/org/unicode/cldr/util/data/external/factbook_gdp_ppp.txt
index 9ee94a0..4d86e3f 100644
--- a/tools/java/org/unicode/cldr/util/data/external/factbook_gdp_ppp.txt
+++ b/tools/java/org/unicode/cldr/util/data/external/factbook_gdp_ppp.txt
@@ -1,4 +1,4 @@
-1 China $23,210,000,000,000 2017 est.
+1 China $25,360,000,000,000 2018
2 United States $19,490,000,000,000 2017 est.
3 India $9,474,000,000,000 2017 est.
4 Japan $5,443,000,000,000 2017 est.
@@ -39,8 +39,8 @@
39 Switzerland $523,100,000,000 2017 est.
40 Sweden $518,000,000,000 2017 est.
41 Romania $483,400,000,000 2017 est.
-42 Kazakhstan $478,600,000,000 2017 est.
-43 Hong Kong $455,900,000,000 2017 est.
+42 Hong Kong $480,500,000,000 2018
+43 Kazakhstan $478,600,000,000 2017 est.
44 Chile $452,100,000,000 2017 est.
45 Austria $441,000,000,000 2017 est.
46 Peru $430,300,000,000 2017 est.
@@ -94,8 +94,8 @@
94 Bolivia $83,720,000,000 2017 est.
95 Nepal $79,190,000,000 2017 est.
96 Uruguay $78,160,000,000 2017 est.
-97 Yemen $73,630,000,000 2017 est.
-98 Macau $71,820,000,000 2017 est.
+97 Macau $77,330,000,000 2018
+98 Yemen $73,630,000,000 2017 est.
99 Slovenia $71,230,000,000 2017 est.
100 Bahrain $71,170,000,000 2017 est.
101 Afghanistan $69,450,000,000 2017 est.
@@ -111,13 +111,13 @@
111 Laos $49,340,000,000 2017 est.
112 Honduras $46,300,000,000 2017 est.
113 Bosnia and Herzegovina $44,830,000,000 2017 est.
-114 Trinidad and Tobago $42,850,000,000 2017 est.
-115 Estonia $41,650,000,000 2017 est.
-116 Mali $41,220,000,000 2017 est.
-117 Korea, North $40,000,000,000 2015 est.
-118 Georgia $39,850,000,000 2017 est.
-119 Madagascar $39,850,000,000 2017 est.
-120 Mongolia $39,730,000,000 2017 est.
+114 Mongolia $43,540,000,000 2018
+115 Trinidad and Tobago $42,850,000,000 2017 est.
+116 Estonia $41,650,000,000 2017 est.
+117 Mali $41,220,000,000 2017 est.
+118 Korea, North $40,000,000,000 2015 est.
+119 Georgia $39,850,000,000 2017 est.
+120 Madagascar $39,850,000,000 2017 est.
121 Botswana $39,010,000,000 2017 est.
122 Mozambique $37,090,000,000 2017 est.
123 Gabon $36,660,000,000 2017 est.
diff --git a/tools/java/org/unicode/cldr/util/data/external/factbook_population.txt b/tools/java/org/unicode/cldr/util/data/external/factbook_population.txt
index b8ce474..c22cc85 100644
--- a/tools/java/org/unicode/cldr/util/data/external/factbook_population.txt
+++ b/tools/java/org/unicode/cldr/util/data/external/factbook_population.txt
@@ -1,238 +1,238 @@
-1 China 1,384,688,986 July 2018 est.
-2 India 1,296,834,042 July 2018 est.
-3 United States 329,256,465 July 2018 est.
-4 Indonesia 262,787,403 July 2018 est.
-5 Brazil 208,846,892 July 2018 est.
-6 Pakistan 207,862,518 July 2018 est.
-7 Nigeria 203,452,505 July 2018 est.
-8 Bangladesh 159,453,001 July 2018 est.
-9 Russia 142,122,776 July 2018 est.
-10 Japan 126,168,156 July 2018 est.
-11 Mexico 125,959,205 July 2018 est.
-12 Ethiopia 108,386,391 July 2018 est.
-13 Philippines 105,893,381 July 2018 est.
-14 Egypt 99,413,317 July 2018 est.
-15 Vietnam 97,040,334 July 2018 est.
-16 Congo, Democratic Republic of the 85,281,024 July 2018 est.
-17 Iran 83,024,745 July 2018 est.
-18 Turkey 81,257,239 July 2018 est.
-19 Germany 80,457,737 July 2018 est.
-20 Thailand 68,615,858 July 2018 est.
-21 France 67,364,357 July 2018 est.
-22 United Kingdom 65,105,246 July 2018 est.
-23 Italy 62,246,674 July 2018 est.
-24 Burma 55,622,506 July 2018 est.
-25 Tanzania 55,451,343 July 2018 est.
-26 South Africa 55,380,210 July 2018 est.
-27 Korea, South 51,418,097 July 2018 est.
-28 Spain 49,331,076 July 2018 est.
-29 Kenya 48,397,527 July 2018 est.
-30 Colombia 48,168,996 July 2018 est.
-31 Argentina 44,694,198 July 2018 est.
-32 Ukraine 43,952,299 July 2018 est.
-33 Sudan 43,120,843 July 2018 est.
-34 Algeria 41,657,488 July 2018 est.
-35 Uganda 40,853,749 July 2018 est.
-36 Iraq 40,194,216 July 2018 est.
-37 Poland 38,420,687 July 2018 est.
-38 Canada 35,881,659 July 2018 est.
-39 Afghanistan 34,940,837 July 2018 est.
-40 Morocco 34,314,130 July 2018 est.
-41 Saudi Arabia 33,091,113 July 2018 est.
-42 Malaysia 31,809,660 July 2018 est.
-43 Venezuela 31,689,176 July 2018 est.
-44 Peru 31,331,228 July 2018 est.
-45 Angola 30,355,880 July 2018 est.
-46 Uzbekistan 30,023,709 July 2018 est.
-47 Nepal 29,717,587 July 2018 est.
-48 Yemen 28,667,230 July 2018 est.
-49 Ghana 28,102,471 July 2018 est.
-50 Mozambique 27,233,789 July 2018 est.
-51 Cote d'Ivoire 26,260,582 July 2018 est.
-52 Madagascar 25,683,610 July 2018 est.
-53 Cameroon 25,640,965 July 2018 est.
-54 Korea, North 25,381,085 July 2018 est.
-55 Taiwan 23,545,963 July 2018 est.
-56 Australia 23,470,145 July 2018 est.
-57 Sri Lanka 22,576,592 July 2018 est.
-58 Romania 21,457,116 July 2018 est.
-59 Niger 19,866,231 July 2018 est.
-60 Malawi 19,842,560 July 2018 est.
-61 Burkina Faso 19,742,715 July 2018 est.
-62 Syria 19,454,263 July 2018 est.
-63 Kazakhstan 18,744,548 July 2018 est.
-64 Mali 18,429,893 July 2018 est.
-65 Chile 17,925,262 July 2018 est.
-66 Netherlands 17,151,228 July 2018 est.
-67 Guatemala 16,581,273 July 2018 est.
-68 Ecuador 16,498,502 July 2018 est.
-69 Cambodia 16,449,519 July 2018 est.
-70 Zambia 16,445,079 July 2018 est.
-71 Chad 15,833,116 July 2018 est.
-72 Senegal 15,020,945 July 2018 est.
-73 Zimbabwe 14,030,368 July 2018 est.
-74 Rwanda 12,187,400 July 2018 est.
-75 Guinea 11,855,411 July 2018 est.
-76 Burundi 11,844,520 July 2018 est.
-77 Belgium 11,570,762 July 2018 est.
-78 Tunisia 11,516,189 July 2018 est.
-79 Benin 11,340,504 July 2018 est.
-80 Bolivia 11,306,341 July 2018 est.
-81 Somalia 11,259,029 July 2018 est.
-82 Cuba 11,116,396 July 2018 est.
-83 Haiti 10,788,440 July 2018 est.
-84 Greece 10,761,523 July 2018 est.
-85 Czechia 10,686,269 July 2018 est.
-86 Jordan 10,458,413 July 2018 est.
-87 Portugal 10,355,493 July 2018 est.
-88 Dominican Republic 10,298,756 July 2018 est.
-89 South Sudan 10,204,581 July 2018 est.
-90 Azerbaijan 10,046,516 July 2018 est.
-91 Sweden 10,040,995 July 2018 est.
-92 Hungary 9,825,704 July 2018 est.
-93 United Arab Emirates 9,701,315 July 2018 est.
-94 Belarus 9,527,543 July 2018 est.
-95 Honduras 9,182,766 July 2018 est.
-96 Austria 8,793,370 July 2018 est.
-97 Tajikistan 8,604,882 July 2018 est.
-98 Israel 8,424,904 July 2018 est.
-99 Switzerland 8,292,809 July 2018 est.
-100 Togo 8,176,449 July 2018 est.
-101 Laos 7,234,171 July 2018 est.
-102 Hong Kong 7,213,338 July 2018 est.
-103 Serbia 7,078,110 July 2018 est.
-104 Bulgaria 7,057,504 July 2018 est.
-105 Papua New Guinea 7,027,332 July 2018 est.
-106 Paraguay 7,025,763 July 2018 est.
-107 Libya 6,754,507 July 2018 est.
-108 Sierra Leone 6,312,212 July 2018 est.
-109 El Salvador 6,187,271 July 2018 est.
-110 Lebanon 6,100,075 July 2018 est.
-111 Nicaragua 6,085,213 July 2018 est.
-112 Singapore 5,995,991 July 2018 est.
-113 Eritrea 5,970,646 July 2018 est.
-114 Kyrgyzstan 5,849,296 July 2018 est.
-115 Denmark 5,809,502 July 2018 est.
-116 Central African Republic 5,745,062 July 2018 est.
-117 Finland 5,537,364 July 2018 est.
-118 Slovakia 5,445,040 July 2018 est.
-119 Turkmenistan 5,411,012 July 2018 est.
-120 Norway 5,372,191 July 2018 est.
-121 Ireland 5,068,050 July 2018 est.
-122 Congo, Republic of the 5,062,021 July 2018 est.
-123 Costa Rica 4,987,142 July 2018 est.
-124 Georgia 4,926,087 July 2018 est.
-125 Liberia 4,809,768 July 2018 est.
-126 New Zealand 4,545,627 July 2018 est.
-127 Croatia 4,270,480 July 2018 est.
-128 Bosnia and Herzegovina 3,849,891 July 2018 est.
-129 Mauritania 3,840,429 July 2018 est.
-130 Panama 3,800,644 July 2018 est.
-131 Oman 3,494,116 July 2018 est.
-132 Moldova 3,437,720 July 2018 est.
-133 Uruguay 3,369,299 July 2018 est.
-134 Puerto Rico 3,294,626 July 2018 est.
-135 Mongolia 3,103,428 July 2018 est.
-136 Albania 3,057,220 July 2018 est.
-137 Armenia 3,038,217 July 2018 est.
-138 Kuwait 2,916,467 July 2018 est.
-139 Jamaica 2,812,090 July 2018 est.
-140 West Bank 2,798,494 July 2018 est.
-141 Lithuania 2,793,284 July 2018 est.
-142 Namibia 2,533,224 July 2018 est.
-143 Qatar 2,363,569 July 2018 est.
-144 Botswana 2,249,104 July 2018 est.
-145 Gabon 2,119,036 July 2018 est.
-146 Macedonia 2,118,945 July 2018 est.
-147 Slovenia 2,102,126 July 2018 est.
-148 Gambia, The 2,092,731 July 2018 est.
-149 Lesotho 1,962,461 July 2018 est.
-150 Latvia 1,923,559 July 2018 est.
-151 Kosovo 1,907,592 July 2018 est.
-152 Gaza Strip 1,836,713 July 2018 est.
-153 Guinea-Bissau 1,833,247 July 2018 est.
-154 Bahrain 1,442,659 July 2018 est.
-155 Mauritius 1,364,283 July 2018 est.
-156 Timor-Leste 1,321,929 July 2018 est.
-157 Estonia 1,244,288 July 2018 est.
-158 Cyprus 1,237,088 July 2018 est.
-159 Trinidad and Tobago 1,215,527 July 2018 est.
-160 Eswatini 1,087,200 July 2018 est.
-161 Fiji 926,276 July 2018 est.
-162 Djibouti 884,017 July 2018 est.
-163 Comoros 821,164 July 2018 est.
-164 Equatorial Guinea 797,457 July 2018 est.
-165 Bhutan 766,397 July 2018 est.
-166 Guyana 740,685 July 2018 est.
-167 Solomon Islands 660,121 July 2018 est.
-168 Western Sahara 619,551 July 2018 est.
-169 Montenegro 614,249 July 2018 est.
-170 Macau 606,340 July 2018 est.
-171 Luxembourg 605,764 July 2018 est.
-172 Suriname 597,927 July 2018 est.
-173 Cabo Verde 568,373 July 2018 est.
-174 Brunei 450,565 July 2018 est.
-175 Malta 449,043 July 2018 est.
-176 Maldives 392,473 July 2018 est.
-177 Belize 385,854 July 2018 est.
-178 Iceland 343,518 July 2018 est.
-179 Bahamas, The 332,634 July 2018 est.
-180 Barbados 293,131 July 2018 est.
-181 French Polynesia 290,373 July 2018 est.
-182 Vanuatu 288,037 July 2018 est.
-183 New Caledonia 282,754 July 2018 est.
-184 Sao Tome and Principe 204,454 July 2018 est.
-185 Samoa 201,316 July 2018 est.
-186 Guam 167,772 July 2018 est.
-187 Saint Lucia 165,510 July 2018 est.
-188 Curacao 150,241 July 2018 est.
-189 Aruba 116,576 July 2018 est.
-190 Grenada 112,207 July 2018 est.
-191 Kiribati 109,367 July 2018 est.
-192 Virgin Islands 106,977 July 2018 est.
-193 Tonga 106,398 July 2018 est.
-194 Micronesia, Federated States of 103,643 July 2018 est.
-195 Saint Vincent and the Grenadines 101,844 July 2018 est.
-196 Jersey 99,602 July 2018 est.
-197 Antigua and Barbuda 95,882 July 2018 est.
-198 Seychelles 94,633 July 2018 est.
-199 Isle of Man 89,407 July 2018 est.
-200 Andorra 85,708 July 2018 est.
-201 Marshall Islands 75,684 July 2018 est.
-202 Dominica 74,027 July 2018 est.
-203 Bermuda 71,176 July 2018 est.
-204 Guernsey 66,697 July 2018 est.
-205 Cayman Islands 59,613 July 2018 est.
-206 Greenland 57,691 July 2018 est.
-207 Turks and Caicos Islands 53,701 July 2018 est.
-208 Saint Kitts and Nevis 53,094 July 2018 est.
-209 Northern Mariana Islands 51,994 July 2018 est.
-210 Faroe Islands 51,018 July 2018 est.
-211 American Samoa 50,826 July 2018 est.
-212 Sint Maarten 42,677 July 2018 est.
-213 Liechtenstein 38,547 July 2018 est.
-214 British Virgin Islands 35,802 July 2018 est.
-215 San Marino 33,779 July 2018 est.
-216 Saint Martin 32,284 July 2018 est.
-217 Monaco 30,727 July 2018 est.
-218 Gibraltar 29,461 July 2018 est.
-219 Palau 21,516 July 2018 est.
-220 Anguilla 17,422 July 2018 est.
-221 Wallis and Futuna 15,763 July 2018 est.
-222 Tuvalu 11,147 July 2018 est.
-223 Nauru 9,692 July 2018 est.
-224 Cook Islands 9,038 July 2018 est.
-225 Saint Helena, Ascension, and Tristan da Cunha 7,841 July 2018 est.
-226 Saint Barthelemy 7,160 July 2018 est.
-227 Saint Pierre and Miquelon 5,471 July 2018 est.
-228 Montserrat 5,315 July 2018 est.
+1 China 1,394,015,977 July 2020 est.
+2 India 1,326,093,247 July 2020 est.
+3 United States 332,639,102 July 2020 est.
+4 Indonesia 267,026,366 July 2020 est.
+5 Pakistan 233,500,636 July 2020 est.
+6 Nigeria 214,028,302 July 2020 est.
+7 Brazil 211,715,973 July 2020 est.
+8 Bangladesh 162,650,853 July 2020 est.
+9 Russia 141,722,205 July 2020 est.
+10 Mexico 128,649,565 July 2020 est.
+11 Japan 125,507,472 July 2020 est.
+12 Philippines 109,180,815 July 2020 est.
+13 Ethiopia 108,113,150 July 2020 est.
+14 Egypt 104,124,440 July 2020 est.
+15 Congo, Democratic Republic of the 101,780,263 July 2020 est.
+16 Vietnam 98,721,275 July 2020 est.
+17 Iran 84,923,314 July 2020 est.
+18 Turkey 82,017,514 July 2020 est.
+19 Germany 80,159,662 July 2020 est.
+20 Thailand 68,977,400 July 2020 est.
+21 France 67,848,156 July 2020 est.
+22 United Kingdom 65,761,117 July 2020 est.
+23 Italy 62,402,659 July 2020 est.
+24 Tanzania 58,552,845 July 2020 est.
+25 Burma 56,590,071 July 2020 est.
+26 South Africa 56,463,617 July 2020 est.
+27 Kenya 53,527,936 July 2020 est.
+28 Korea, South 51,835,110 July 2020 est.
+29 Spain 50,015,792 July 2020 est.
+30 Colombia 49,084,841 July 2020 est.
+31 Sudan 45,561,556 July 2020 est.
+32 Argentina 45,479,118 July 2020 est.
+33 Ukraine 43,922,939 July 2020 est.
+34 Uganda 43,252,966 July 2020 est.
+35 Algeria 42,972,878 July 2020 est.
+36 Iraq 38,872,655 July 2020 est.
+37 Poland 38,282,325 July 2020 est.
+38 Canada 37,694,085 July 2020 est.
+39 Afghanistan 36,643,815 July 2020 est.
+40 Morocco 35,561,654 July 2020 est.
+41 Saudi Arabia 34,173,498 July 2020 est.
+42 Malaysia 32,652,083 July 2020 est.
+43 Angola 32,522,339 July 2020 est.
+44 Peru 31,914,989 July 2020 est.
+45 Uzbekistan 30,565,411 July 2020 est.
+46 Nepal 30,327,877 July 2020 est.
+47 Mozambique 30,098,197 July 2020 est.
+48 Yemen 29,884,405 July 2020 est.
+49 Ghana 29,340,248 July 2020 est.
+50 Venezuela 28,644,603 July 2020 est.
+51 Cameroon 27,744,989 July 2020 est.
+52 Cote d'Ivoire 27,481,086 July 2020 est.
+53 Madagascar 26,955,737 July 2020 est.
+54 Korea, North 25,643,466 July 2020 est.
+55 Australia 25,466,459 July 2020 est.
+56 Taiwan 23,603,049 July 2020 est.
+57 Sri Lanka 22,889,201 July 2020 est.
+58 Niger 22,772,361 July 2020 est.
+59 Romania 21,302,893 July 2020 est.
+60 Malawi 21,196,629 July 2020 est.
+61 Burkina Faso 20,835,401 July 2020 est.
+62 Mali 19,553,397 July 2020 est.
+63 Syria 19,398,448 July 2020 est.
+64 Kazakhstan 19,091,949 July 2020 est.
+65 Chile 18,186,770 July 2020 est.
+66 Zambia 17,426,623 July 2020 est.
+67 Netherlands 17,280,397 July 2020 est.
+68 Guatemala 17,153,288 July 2020 est.
+69 Cambodia 16,926,984 July 2020 est.
+70 Ecuador 16,904,867 July 2020 est.
+71 Chad 16,877,357 July 2020 est.
+72 Senegal 15,736,368 July 2020 est.
+73 Zimbabwe 14,546,314 July 2020 est.
+74 Benin 12,864,634 July 2020 est.
+75 Rwanda 12,712,431 July 2020 est.
+76 Guinea 12,527,440 July 2020 est.
+77 Burundi 11,865,821 July 2020 est.
+78 Somalia 11,757,124 July 2020 est.
+79 Tunisia 11,721,177 July 2020 est.
+80 Belgium 11,720,716 July 2020 est.
+81 Bolivia 11,639,909 July 2020 est.
+82 Haiti 11,067,777 July 2020 est.
+83 Cuba 11,059,062 July 2020 est.
+84 Jordan 10,820,644 July 2020 est.
+85 Czechia 10,702,498 July 2020 est.
+86 Greece 10,607,051 July 2020 est.
+87 South Sudan 10,561,244 July 2020 est.
+88 Dominican Republic 10,499,707 July 2020 est.
+89 Portugal 10,302,674 July 2020 est.
+90 Azerbaijan 10,205,810 July 2020 est.
+91 Sweden 10,202,491 July 2020 est.
+92 United Arab Emirates 9,992,083 July 2020 est.
+93 Hungary 9,771,827 July 2020 est.
+94 Belarus 9,477,918 July 2020 est.
+95 Honduras 9,235,340 July 2020 est.
+96 Tajikistan 8,873,669 July 2020 est.
+97 Austria 8,859,449 July 2020 est.
+98 Israel 8,675,475 July 2020 est.
+99 Togo 8,608,444 July 2020 est.
+100 Switzerland 8,403,994 July 2020 est.
+101 Laos 7,447,396 July 2020 est.
+102 Papua New Guinea 7,259,456 July 2020 est.
+103 Hong Kong 7,249,907 July 2020 est.
+104 Paraguay 7,191,685 July 2020 est.
+105 Serbia 7,012,165 July 2020 est.
+106 Bulgaria 6,966,899 July 2020 est.
+107 Libya 6,890,535 July 2020 est.
+108 Sierra Leone 6,624,933 July 2020 est.
+109 El Salvador 6,481,102 July 2020 est.
+110 Singapore 6,209,660 July 2020 est.
+111 Nicaragua 6,203,441 July 2020 est.
+112 Eritrea 6,081,196 July 2020 est.
+113 Central African Republic 5,990,855 July 2020 est.
+114 Kyrgyzstan 5,964,897 July 2020 est.
+115 Denmark 5,869,410 July 2020 est.
+116 Finland 5,571,665 July 2020 est.
+117 Turkmenistan 5,528,627 July 2020 est.
+118 Lebanon 5,469,612 July 2020 est.
+119 Norway 5,467,439 July 2020 est.
+120 Slovakia 5,440,602 July 2020 est.
+121 Congo, Republic of the 5,293,070 July 2020 est.
+122 Ireland 5,176,569 July 2020 est.
+123 Costa Rica 5,097,988 July 2020 est.
+124 Liberia 5,073,296 July 2020 est.
+125 New Zealand 4,925,477 July 2020 est.
+126 Oman 4,664,844 December 2019 est.
+127 Croatia 4,227,746 July 2020 est.
+128 Mauritania 4,005,475 July 2020 est.
+129 Georgia 3,997,000 2019 est. est.
+130 Panama 3,894,082 July 2020 est.
+131 Bosnia and Herzegovina 3,835,586 July 2020 est.
+132 Uruguay 3,387,605 July 2020 est.
+133 Moldova 3,364,496 July 2020 est.
+134 Puerto Rico 3,189,068 July 2020 est.
+135 Mongolia 3,168,026 July 2020 est.
+136 Albania 3,074,579 July 2020 est.
+137 Armenia 3,021,324 July 2020 est.
+138 Kuwait 2,993,706 July 2020 est.
+139 West Bank 2,900,034 July 2020 est.
+140 Jamaica 2,808,570 July 2020 est.
+141 Lithuania 2,731,464 July 2020 est.
+142 Namibia 2,630,073 July 2020 est.
+143 Qatar 2,444,174 July 2020 est.
+144 Botswana 2,317,233 July 2020 est.
+145 Gabon 2,230,908 July 2020 est.
+146 Gambia, The 2,173,999 July 2020 est.
+147 Macedonia 2,125,971 July 2020 est.
+148 Slovenia 2,102,678 July 2020 est.
+149 Lesotho 1,969,334 July 2020 est.
+150 Kosovo 1,932,774 July 2020 est.
+151 Guinea-Bissau 1,927,104 July 2020 est.
+152 Gaza Strip 1,918,221 July 2020 est.
+153 Latvia 1,881,232 July 2020 est.
+154 Bahrain 1,505,003 July 2020 est.
+155 Timor-Leste 1,383,723 July 2020 est.
+156 Mauritius 1,379,365 July 2020 est.
+157 Cyprus 1,266,676 July 2020 est.
+158 Estonia 1,228,624 July 2020 est.
+159 Trinidad and Tobago 1,208,789 July 2020 est.
+160 Eswatini 1,104,479 July 2020 est.
+161 Fiji 935,974 July 2020 est.
+162 Djibouti 921,804 July 2020 est.
+163 Comoros 846,281 July 2020 est.
+164 Equatorial Guinea 836,178 July 2020 est.
+165 Bhutan 782,318 July 2020 est.
+166 Guyana 750,204 July 2020 est.
+167 Solomon Islands 685,097 July 2020 est.
+168 Western Sahara 652,271 July 2020 est.
+169 Luxembourg 628,381 July 2020 est.
+170 Macau 614,458 July 2020 est.
+171 Montenegro 609,859 July 2020 est.
+172 Suriname 609,569 July 2020 est.
+173 Cabo Verde 583,255 July 2020 est.
+174 Brunei 464,478 July 2020 est.
+175 Malta 457,267 July 2020 est.
+176 Belize 399,598 July 2020 est.
+177 Maldives 391,904 July 2020 est.
+178 Iceland 350,734 July 2020 est.
+179 Bahamas, The 337,721 July 2020 est.
+180 Vanuatu 298,333 July 2020 est.
+181 French Polynesia 295,121 July 2020 est.
+182 Barbados 294,560 July 2020 est.
+183 New Caledonia 290,009 July 2020 est.
+184 Sao Tome and Principe 211,122 July 2020 est.
+185 Samoa 203,774 July 2020 est.
+186 Guam 168,485 July 2020 est.
+187 Saint Lucia 166,487 July 2020 est.
+188 Curacao 151,345 July 2020 est.
+189 Aruba 119,428 July 2020 est.
+190 Grenada 113,094 July 2020 est.
+191 Kiribati 111,796 July 2020 est.
+192 Virgin Islands 106,235 July 2020 est.
+193 Tonga 106,095 July 2020 est.
+194 Micronesia, Federated States of 102,436 July 2020 est.
+195 Saint Vincent and the Grenadines 101,390 July 2020 est.
+196 Jersey 101,073 July 2020 est.
+197 Antigua and Barbuda 98,179 July 2020 est.
+198 Seychelles 95,981 July 2020 est.
+199 Isle of Man 90,499 July 2020 est.
+200 Marshall Islands 77,917 July 2020 est.
+201 Andorra 77,000 2019 est.
+202 Dominica 74,243 July 2020 est.
+203 Bermuda 71,750 July 2020 est.
+204 Guernsey 67,052 July 2020 est.
+205 Cayman Islands 61,944 July 2020 est.
+206 Greenland 57,616 July 2020 est.
+207 Turks and Caicos Islands 55,926 July 2020 est.
+208 Saint Kitts and Nevis 53,821 July 2020 est.
+209 Faroe Islands 51,628 July 2020 est.
+210 Northern Mariana Islands 51,433 July 2020 est.
+211 American Samoa 49,437 July 2020 est.
+212 Sint Maarten 43,847 July 2020 est.
+213 Liechtenstein 39,137 July 2020 est.
+214 Monaco 39,000 2019 est.
+215 British Virgin Islands 37,381 July 2020 est.
+216 San Marino 34,232 July 2020 est.
+217 Saint Martin 32,556 July 2020 est.
+218 Gibraltar 29,581 July 2020 est.
+219 Palau 21,685 July 2020 est.
+220 Anguilla 18,090 July 2020 est.
+221 Wallis and Futuna 15,854 July 2020 est.
+222 Tuvalu 11,342 July 2020 est.
+223 Nauru 11,000 2019 est.
+224 Cook Islands 8,574 July 2020 est.
+225 Saint Helena, Ascension, and Tristan da Cunha 7,862 July 2020 est.
+226 Saint Barthelemy 7,122 July 2020 est.
+227 Montserrat 5,373 July 2020 est.
+228 Saint Pierre and Miquelon 5,347 July 2020 est.
229 Falkland Islands (Islas Malvinas) 3,198 2016 est.
-230 Svalbard 2,583 July 2017 est.
-231 Christmas Island 2,205 July 2016 est.
-232 Norfolk Island 1,748 2016 est.
-233 Niue 1,618
-234 Paracel Islands 1,440 2014 est.
-235 Tokelau 1,285 2016 est.
-236 Holy See (Vatican City) 1,000 2017 est.
+230 Svalbard 2,926 July 2019 est.
+231 Christmas Island 2,205 2016 est.
+232 Niue 2,000 2019
+233 Norfolk Island 1,748 2016 est.
+234 Tokelau 1,647 2019 est. est.
+235 Paracel Islands 1,440 2014 est.
+236 Holy See (Vatican City) 1,000 2019 est.
237 Cocos (Keeling) Islands 596 July 2014 est.
-238 Pitcairn Islands 54 July 2016 est.
+238 Pitcairn Islands 50 2020 est. est.
diff --git a/tools/java/org/unicode/cldr/util/data/external/world_bank_data.csv b/tools/java/org/unicode/cldr/util/data/external/world_bank_data.csv
index 6bd8cc5..21108c5 100644
--- a/tools/java/org/unicode/cldr/util/data/external/world_bank_data.csv
+++ b/tools/java/org/unicode/cldr/util/data/external/world_bank_data.csv
@@ -1,440 +1,440 @@
-Country Name,Country Code,Series Name,Series Code,2000 [YR2000],2001 [YR2001],2003 [YR2003],2004 [YR2004],2005 [YR2005],2006 [YR2006],2007 [YR2007],2008 [YR2008],2009 [YR2009],2010 [YR2010],2011 [YR2011],2012 [YR2012],2013 [YR2013],2014 [YR2014],2015 [YR2015],2016 [YR2016],2017 [YR2017],2018 [YR2018]
-Afghanistan,AFG,"Population, total",SP.POP.TOTL,20779953,21606988,23680871,24726684,25654277,26433049,27100536,27722276,28394813,29185507,30117413,31161376,32269589,33370794,34413603,35383128,36296400,37172386
-Afghanistan,AFG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,41187103443.3845,47871884293.6593,48940525323.2712,56390324156.248,60708991115.4435,63314619107.9323,65514856446.4985,67454810885.6697,70565716023.9233,73001688109.4404
-Albania,ALB,"Population, total",SP.POP.TOTL,3089027,3060173,3039616,3026939,3011487,2992547,2970017,2947314,2927519,2913021,2905195,2900401,2895092,2889104,2880703,2876101,2873457,2866376
-Albania,ALB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12293735718.4436,13588494277.2045,15604575652.1344,16808178127.7723,18021157908.6102,20208383895.3056,22212143238.8402,24373992811.5679,25395358408.0744,27766379103.6691,29663196587.6265,30302943562.5374,31131401566.0843,32827750109.8841,33994825230.8321,34688535824.0403,37246076988.3066,..
-Algeria,DZA,"Population, total",SP.POP.TOTL,31042235,31451514,32264157,32692163,33149724,33641002,34166972,34730608,35333881,35977455,36661444,37383887,38140132,38923687,39728025,40551404,41389198,42228429
-Algeria,DZA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,240847042804.343,258953900194.902,301147404546.455,320879191791.856,347455283620.465,367577615802.966,400469724028.411,421055083319.919,430160648946.364,454249931830.917,473230115543.805,494561375122.083,515657493812.424,545163628933.778,568748825319.06,604332274131.786,622062721188.36,648218922858.433
-American Samoa,ASM,"Population, total",SP.POP.TOTL,57821,58494,59504,59681,59562,59107,58365,57492,56683,56079,55759,55667,55713,55791,55812,55741,55620,55465
-American Samoa,ASM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Andorra,AND,"Population, total",SP.POP.TOTL,65390,67341,73182,76244,78867,80993,82684,83862,84463,84449,83747,82427,80774,79213,78011,77297,77001,77006
-Andorra,AND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Angola,AGO,"Population, total",SP.POP.TOTL,16395473,16945753,18121479,18758145,19433602,20149901,20905363,21695634,22514281,23356246,24220661,25107931,26015780,26941779,27884381,28842484,29816748,30809762
-Angola,AGO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,41432320257.4578,44631778156.6396,59153300796.9656,66747074831.4785,78872049616.6002,89735714168.485,105235825479.428,114065240409.717,123862171068.308,131473655216.811,140379801774.149,156204906800.016,168450221056.073,182180193720.856,187823443879.841,184750703826.558,192229589021.421,189616871964.711
-Antigua and Barbuda,ATG,"Population, total",SP.POP.TOTL,76016,77212,79300,80336,81465,82704,84026,85397,86746,88028,89253,90409,91516,92562,93566,94527,95426,96286
-Antigua and Barbuda,ATG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1190196203.32966,1183738882.48401,1292971253.15573,1398355511.32609,1547122519.19418,1798189500.03371,2017971153.80148,2047011174.20589,1818817783.66208,1732805664.65561,1719331908.34641,1799451907.89683,1829414708.90545,1934629256.77702,2026376153.16037,2133947696.9783,2241317343.57867,2422667897.46612
-Argentina,ARG,"Population, total",SP.POP.TOTL,36870787,37275652,38087868,38491972,38892931,39289878,39684295,40080160,40482788,40788453,41261490,41733271,42202935,42669500,43131966,43590368,44044811,44494502
-Argentina,ARG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,427705048150.997,416872209387.703,413354380842.177,428636797132.618,479748541570.394,582662880615.78,656745628034.243,697740913973.265,657382734890.712,729853440301.322,794325172722.152,805324243204.842,841055034261.13,836246704582.003,869846606664.772,858301788492.153,894618626234.878,882055304190.25
-Armenia,ARM,"Population, total",SP.POP.TOTL,3069591,3050687,3017932,3000720,2981269,2958307,2932618,2907618,2888092,2877319,2876538,2884229,2897584,2912403,2925553,2936146,2944809,2951776
-Armenia,ARM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7341753228.37085,8241813497.77092,11041961836.8629,12482228102.3633,14826508319.3132,17378633258.8495,20429404287.0623,22374632459.1986,19030029139.0185,19826473931.4395,20909524017.3555,22940503025.162,24612813139.5648,25619970758.8355,26603930152.0472,26413124248.1733,29470204831.5341,30874335325.4599
-Aruba,ABW,"Population, total",SP.POP.TOTL,90853,92898,97017,98737,100031,100834,101222,101358,101455,101669,102046,102560,103159,103774,104341,104872,105366,105845
-Aruba,ABW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2970472655.79533,2894708670.85106,2964638017.53824,3261970667.64089,2798570070.13606,3506453356.63759,3268910746.68495,3737873634.66294,3394670605.26343,3228330191.03523,3271119262.41504,3474023747.15833,3614101656.7541,3812628574.9732,3805976195.5237,3820427669.79466,3894622535.52135,..
-Australia,AUS,"Population, total",SP.POP.TOTL,19153000,19413000,19895400,20127400,20394800,20697900,20827600,21249200,21691700,22031750,22340024,22733465,23128129,23475686,23815995,24190907,24601860,24992369
-Australia,AUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,489711413127.625,515790788888.379,574118315219.596,612540926403.141,639679592265.961,682417462603.499,727501373533.963,763437639656.731,843523436833.383,832727650434.187,899875053935.933,943990546160.514,1035222299693.94,1071746498596.55,1079442146587.8,1117959538341,1188350232405.51,1247800981122.18
-Austria,AUT,"Population, total",SP.POP.TOTL,8011566,8042293,8121423,8171966,8227829,8268641,8295487,8321496,8343323,8363404,8391643,8429991,8479823,8546356,8642699,8736668,8797566,8847037
-Austria,AUT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,233330541766.07,235710601203.751,260112151676.933,275367030046.229,287476798281.967,311818314868.547,326450890545.42,346680570770.484,341315238549.098,354252259996.343,374289188740.567,392030460346.489,407466618825.439,417609480255.935,426833867811.004,450782402035.056,472748078788.57,495047447918.144
-Azerbaijan,AZE,"Population, total",SP.POP.TOTL,8048600,8111200,8234100,8306500,8391850,8484550,8581300,8763400,8947243,9054332,9173082,9295784,9416801,9535079,9649341,9757812,9854033,9942334
-Azerbaijan,AZE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,27890741773.8115,31165506195.7203,38815679099.3703,42624012759.969,53573677595.1172,73926211543.0399,92409698737.5992,110454350788.85,125651565987.888,135207522670.053,134628001917.261,142008075004.82,154058450882.086,164941816041.667,166802300243.994,158856277839.449,165259398123.852,169700684215.302
-"Bahamas, The",BHS,"Population, total",SP.POP.TOTL,298051,302618,313129,318894,324859,331033,337389,343681,349604,354942,359577,363584,367168,370633,374206,377931,381761,385640
-"Bahamas, The",BHS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7684563693.1168,8005567844.99939,8457556517.94535,8775990074.4166,9329019111.32529,9823805270.66686,10229754525.1751,10354802856.2151,9913446535.2242,10116194477.567,10410677220.26,11030839920.1594,11189183308.9213,11232567643.069,11505214592.5499,11355346617.875,11803570163.2203,..
-Bahrain,BHR,"Population, total",SP.POP.TOTL,664611,697545,778708,829844,889164,958418,1035919,1114641,1185076,1240860,1278151,1299943,1315029,1336075,1371851,1425791,1494074,1569439
-Bahrain,BHR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,23181887375.0635,24003123098.6702,27037134374.4036,29728082326.4384,33339772771.7229,36759323081.3119,41173711008.1479,43593007828.8188,41831696735.3614,44761195892.4712,45304049174.4875,47505639506.5621,51198596069.0824,51403148391.9112,60768065805.2712,62902453486.3381,67210307748.7388,70032638646.8039
-Bangladesh,BGD,"Population, total",SP.POP.TOTL,127657854,130088702,134791603,136986432,139035505,140921167,142660376,144304167,145924797,147575430,149273778,151007807,152764676,154520167,156256276,157970840,159670593,161356039
-Bangladesh,BGD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,177501589107.713,190216327586.122,216113480986.406,234222604385.087,257564335974.797,286339559531.355,317096154489.783,346829582234.034,367894018813.755,393543966698.122,427013979840.347,465927032727.283,500667990244.608,534156898505.168,574312825139.83,617619591394.059,665863505839.485,736277003915.318
-Barbados,BRB,"Population, total",SP.POP.TOTL,271515,272500,274329,275284,276323,277477,278700,279946,281104,282131,282987,283700,284296,284825,285324,285796,286233,286641
-Barbados,BRB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3224061100.29193,3200910462.18595,3390337536.84034,3558768447.52558,3769503903.37933,4032928099.28547,4309491564.50863,4347179603.80469,4246247449.65225,4386882087.80267,4324432732.2635,4549068289.61974,4604489527.48221,4689234033.69038,4764205811.51648,4900393376.99176,5048878591.64545,..
-Belarus,BLR,"Population, total",SP.POP.TOTL,9979610,9928549,9796749,9730146,9663915,9604924,9560953,9527985,9506765,9490583,9473172,9464495,9465997,9474511,9489616,9501534,9498264,9485386
-Belarus,BLR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,59929813931.3254,64109648059.0482,75000898339.8437,85812437786.0409,96874116606.5884,109244804609.082,121096971174.94,135510385110.53,135579675351.416,148340015342.058,159291474012.518,164758720668.099,167062368805.543,174045560441.799,166909211944.387,164070342890.35,172913552615.231,182140614647.685
-Belgium,BEL,"Population, total",SP.POP.TOTL,10251250,10286570,10376133,10421137,10478617,10547958,10625700,10709973,10796493,10895586,11038264,11106932,11159407,11209057,11274196,11331422,11375158,11422068
-Belgium,BEL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,294129706029.74,303289750923.502,328189204226.733,340404729985.064,353373783903.798,378316386285.289,396938247806.661,417983366784.322,410867772241.407,450144088430.016,460300440792.344,482866602524.883,494697245976.635,503425208756.658,511108874396.087,535606213333.871,568689904076.892,587845828049.872
-Belize,BLZ,"Population, total",SP.POP.TOTL,247315,255063,269425,276504,283800,291329,299025,306823,314655,322464,330237,338000,345715,353366,360933,368400,375769,383071
-Belize,BLZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1281490860.95416,1355708076.31611,1588612225.62583,1669649667.75873,1781253643.88794,1918791686.68751,1947127088.11284,2054887277.77049,2209608399.59179,2233456109.61322,2416783291.38297,2504393852.56888,2577593003.52232,2701965174.72606,2908820355.72777,2900673252.16606,2927673337.46253,3142836138.99602
-Benin,BEN,"Population, total",SP.POP.TOTL,6865951,7076733,7520555,7750004,7982225,8216897,8454793,8696921,8944708,9199259,9460830,9729248,10004588,10286842,10575952,10872067,11175204,11485048
-Benin,BEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9061394080.76838,9747248118.99303,10869816378.3422,11675400197.9813,12300533208.638,13144165509.9234,14273000151.0649,15362653670.1788,15791734901.1014,16263307826.579,17192949487.5054,18252516153.2901,19921245682.0448,21614299952.5185,22267074395.2321,23485800655.1569,25258969764.8654,27579396195.717
-Bermuda,BMU,"Population, total",SP.POP.TOTL,61833,62504,63325,63740,64154,64523,64888,65273,65636,65124,64564,64798,65001,65139,65239,64555,63874,63968
-Bermuda,BMU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,4874709603.81217,4883611563.95876,4493986661.66987,4486492133.80261,4397668042.07143,4353813540.09437,4342781779.00351,..,..,..,..,..
-Bhutan,BTN,"Population, total",SP.POP.TOTL,591021,603640,627839,638815,648739,657410,664876,671613,678323,685503,693298,701583,710238,719056,727876,736709,745568,754394
-Bhutan,BTN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1612902561.929,1784628377.43451,2153573262.17452,2340616285.27569,2608204613.87499,2900795915.08911,3479598490.20946,3664847530.92176,3886195668.73874,4321727378.9197,4724439198.53529,4976425806.3104,5224337257.96111,5631169804.18937,6062828129.42368,6519439817.72226,6946174569.81108,7302869418.2261
-Bolivia,BOL,"Population, total",SP.POP.TOTL,8418264,8580235,8905823,9069039,9232306,9395446,9558439,9721454,9884781,10048590,10212954,10377676,10542376,10706517,10869730,11031813,11192854,11353142
-Bolivia,BOL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,28494081306.227,29637361230.4416,31901445380.5939,33896900159.0046,36667595010.9956,39784109142.6217,42601726576.2198,46346675902.6356,47934038028.4094,50224913689.1835,53690570370.3186,56814938219.9667,61604956111.0698,66958022381.5544,72255687987.0218,77411130756.5139,81357374859.8128,87068148574.0916
-Bosnia and Herzegovina,BIH,"Population, total",SP.POP.TOTL,3751176,3755512,3762173,3764194,3765331,3765424,3762786,3754271,3735938,3705472,3661175,3604972,3542605,3482104,3429361,3386267,3351527,3323929
-Bosnia and Herzegovina,BIH,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18888113490.7605,19514076371.5365,21501819532.818,24455953349.6249,25415425940.303,28737385275.7294,31727090298.9963,35149198233.1417,35036973814.8711,35200562506.6536,36818771791.7234,37436148115.081,39547115491.4598,40137280767.9655,41479305385.4522,43543777810.6381,45830055122.7931,..
-Botswana,BWA,"Population, total",SP.POP.TOTL,1643334,1674678,1734398,1765527,1799078,1835908,1875459,1915639,1953498,1987105,2015402,2039551,2062536,2088614,2120716,2159944,2205128,2254126
-Botswana,BWA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13163199317.0297,14000573201.4972,14917031257.6955,15527131343.583,17171389706.8418,19334145525.5894,21702666739.3183,23483010755.0489,22912336627.714,24654325590.0923,28287461044.4214,30328944489.6126,32793112048.4206,34939665420.1151,34938571824.1734,35957992764.8594,37910872565.5827,40501287706.2134
-Brazil,BRA,"Population, total",SP.POP.TOTL,174790340,177196054,181809246,184006481,186127103,188167356,190130443,192030362,193886508,195713635,197514534,199287296,201035903,202763735,204471769,206163058,207833831,209469333
-Brazil,BRA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1540368765613.1,1590003486350.46,1716024452202.36,1867943596031.27,1989110393890.28,2139017530786.08,2338840569873.03,2497400553648.12,2519438675896.58,2720411708683,2897463027103.88,3024656029489.04,3199962919896.06,3251231997139.54,3163684993443.51,3094875614934.33,3194803975798.16,3314554681344.12
-British Virgin Islands,VGB,"Population, total",SP.POP.TOTL,20311,20675,21672,22334,23107,24023,25047,26097,27039,27794,28319,28650,28847,28989,29152,29355,29577,29802
-British Virgin Islands,VGB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Brunei Darussalam,BRN,"Population, total",SP.POP.TOTL,333165,340034,353293,359433,365114,370263,374965,379421,383906,388646,393688,398989,404421,409769,414907,419800,424473,428962
-Brunei Darussalam,BRN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,21757595387.5637,22844964797.462,25265534701.315,26076585574.7821,26993052436.2145,29032919656.191,30011036245.709,29962287096.1965,29689532349.4039,30442433957.6725,31606484313.1479,32602767794.1838,32900229821.7524,33072023472.3853,34940106628.1506,35203717924.4574,35983277931.6873,36798927274.4061
-Bulgaria,BGR,"Population, total",SP.POP.TOTL,8170172,8009142,7775327,7716860,7658972,7601022,7545338,7492561,7444443,7395599,7348328,7305888,7265115,7223938,7177991,7127822,7075947,7024216
-Bulgaria,BGR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,50826870581.5954,55432393585.4017,65933680994.9292,71228300825.837,78428220367.59,83849648296.7282,89549457628.4035,102780291304.429,103337997492.533,108145857341.13,111573413931.629,116829221287.698,117730165442.304,125571222595.773,127919410135.324,138633873892.367,150172396188.648,..
-Burkina Faso,BFA,"Population, total",SP.POP.TOTL,11607942,11944587,12654621,13030569,13421930,13829176,14252021,14689725,15141098,15605217,16081911,16571246,17072775,17586017,18110624,18646378,19193284,19751535
-Burkina Faso,BFA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9832591705.75183,10728695676.5202,12520433890.8759,13429954207.0494,15086875196.4181,16571089015.8411,17938865069.3298,19621481229.7233,20345699589.3689,21187593812.4147,22811297843.1351,25190504768.1735,27182928647.3964,28551557605.0151,29876745182.078,31879121312.876,34649071647.232,37896902228.652
-Burundi,BDI,"Population, total",SP.POP.TOTL,6378871,6525545,6909154,7131693,7364862,7607849,7862214,8126102,8397668,8675602,8958406,9245988,9540289,9844297,10160030,10487998,10827024,11175378
-Burundi,BDI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3704285880.16384,3747523096.65912,3964808949.29116,4237687598.69005,4472569741.7261,4901475653.05734,5220309013.51051,5590015090.17318,5807080218.01085,6202122879.05249,6570554912.82426,7029661746.02521,7531802170.53453,7973808625.10938,7760115013.91579,7799828620.72967,7978021669.80344,8294583758.34418
-Cabo Verde,CPV,"Population, total",SP.POP.TOTL,428188,435709,449930,456617,463032,469170,475060,480842,486671,492654,498856,505235,511748,518269,524743,531146,537497,543767
-Cabo Verde,CPV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1293207596.79089,1372286568.76007,1545701419.14703,1745905490.57991,1895391660.16033,2095644327.28678,2529662321.80392,2734701253.68021,2723304769.56356,2742020635.00969,2924904081.15014,3001893188.52943,3104527113.72626,3133475338.66371,3242034700.9723,3436136922.33445,3646923347.08359,3986161735.14087
-Cambodia,KHM,"Population, total",SP.POP.TOTL,12155239,12405408,12856163,13066469,13273354,13477709,13679962,13883834,14093604,14312212,14541423,14780454,15026332,15274503,15521436,15766293,16009414,16249798
-Cambodia,KHM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12868479070.9558,14183970957.7662,16928137316.6049,19138828633.1319,22220648730.4693,25408076645.7823,28939842143.066,31363847750.0644,31557701852.2482,33742412860.3237,36844168821.8601,40079473097.8325,44201518188.1756,47768111054.9702,51200145872.7074,55390903969.686,60357035540.719,65982867616.5808
-Cameroon,CMR,"Population, total",SP.POP.TOTL,15513945,15928910,16800865,17259322,17733410,18223674,18730282,19252666,19789919,20341241,20906388,21485266,22077298,22681858,23298368,23926539,24566045,25216237
-Cameroon,CMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29784946287.2874,31489639338.7613,36692282358.0898,40778843753.0502,42717191728.8639,46196904357.7768,49292008982.3631,52362961169.8643,54538637175.3672,56734192040.501,60296571265.6458,63922317530.9718,68291651422.2592,74493977989.0852,79077043992.8754,83404598307.0597,87842575984.4576,93376236872.7406
-Canada,CAN,"Population, total",SP.POP.TOTL,30685730,31020902,31644028,31940655,32243753,32571174,32889025,33247118,33628895,34004889,34339328,34714222,35082954,35437435,35702908,36109487,36540268,37058856
-Canada,CAN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,877373999038.751,910874338016.658,998164950555.612,1059836385959.16,1147375177564.43,1221540158668.94,1281397532398.91,1322674357374.9,1285495001290.26,1336867766152.78,1403781260484.68,1442045561369.97,1530453431372.55,1595191805962.17,1570465319021.41,1609269140450.58,1691995086285.53,1752268065430.49
-Cayman Islands,CYM,"Population, total",SP.POP.TOTL,42303,43935,46632,47902,49261,50740,52280,53836,55322,56672,57878,58958,59932,60848,61724,62569,63382,64174
-Cayman Islands,CYM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,2541215495.36874,2488451119.18905,2419899586.5641,2820621361.65886,3160488838.68511,..,..
-Central African Republic,CAF,"Population, total",SP.POP.TOTL,3640427,3722018,3881181,3959875,4038382,4118069,4198010,4273366,4337625,4386768,4418636,4436415,4447942,4464175,4493170,4537687,4596028,4666377
-Central African Republic,CAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2428683088.96667,2608260346.17543,2661262336.62091,2872261271.44238,2998400830.96156,3235834043.75364,3481302169.57998,3602871867.91815,3976761129.71467,4240350991.17306,4508217574.11261,4829191120.69331,3139391067.74375,3204056182.92214,3387122495.80178,3584503154.73184,3820587814.87382,4076867549.85986
-Chad,TCD,"Population, total",SP.POP.TOTL,8355654,8678051,9373916,9734767,10096633,10457124,10818024,11183588,11560147,11952136,12360989,12784750,13220424,13663559,14110975,14561666,15016773,15477751
-Chad,TCD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,6510176644.24313,7424309539.64705,8069486532.76757,11204106940.1035,13606424993.018,13958834739.0032,15235341936.6637,15599363412.7911,18701630678.4715,21669474932.373,22309202431.6998,24801035521.5691,26089449333.1577,28485833422.9967,29990173537.8076,28769852476.2182,28595233431.7406,29783759318.1042
-Channel Islands,CHI,"Population, total",SP.POP.TOTL,148443,149097,150068,150716,151678,153008,154636,156433,158178,159734,160998,162056,163038,164100,165385,166923,168665,170499
-Channel Islands,CHI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Chile,CHL,"Population, total",SP.POP.TOTL,15342353,15516113,15849652,16014971,16182721,16354504,16530195,16708258,16886186,17062536,17233576,17400347,17571507,17758959,17969353,18209068,18470439,18729160
-Chile,CHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,141423037028.744,149617762745.183,161378822034.931,173667663199.091,188423173015.673,226393185292.021,248814945028.446,254260262604.88,254255791260.918,288017255793.192,329368731234.727,356585691606.824,377205694908.338,390604167246.858,395579058008.75,405214219662.615,429558689700.93,454118612950.936
-China,CHN,"Population, total",SP.POP.TOTL,1262645000,1271850000,1288400000,1296075000,1303720000,1311020000,1317885000,1324655000,1331260000,1337705000,1344130000,1350695000,1357380000,1364270000,1371220000,1378665000,1386395000,1392730000
-China,CHN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3662603190119.98,4046034590784.73,5068706002085.55,5751831145873.85,6577585539793.3,7678425081880.4,9044086945579.17,10150004548555.4,11101007524668.9,12392343555500.6,13789411919025.6,15265512570790.3,16642665962284.9,18367894560698.3,19745788935828.2,21301288667946.3,23201758384014.1,25266121027152.5
-Colombia,COL,"Population, total",SP.POP.TOTL,39629968,40255967,41483869,42075955,42647723,43200897,43737516,44254975,44750054,45222700,45663099,46076848,46497267,46969209,47520667,48171392,48901066,49648685
-Colombia,COL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,259586734057.021,268880433559.512,293466860030.716,317255941501.252,345909948770.272,380091416342.948,415298100534.322,435259797097.511,445664819593.585,467570978317.23,509202135891.139,541877098069.423,578364895671.285,620627242672.258,656167411094.747,679467444701.724,696337574182.417,719578612657.978
-Comoros,COM,"Population, total",SP.POP.TOTL,542357,555888,583211,597228,611627,626425,641620,657229,673252,689692,706569,723871,741505,759390,777424,795592,813892,832322
-Comoros,COM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1031838095.34828,1080052682.19543,1162471486.02659,1215532951.24305,1290073310.11827,1364974537.39941,1418534286.92375,1498113398.66379,1558739989.97505,1637542977.58824,1740585862.88447,1829092146.61347,1948568006.45096,2029399073.74845,2079006382.99097,2150571966.23367,2251529635.16738,2271446927.02763
-"Congo, Dem. Rep.",COD,"Population, total",SP.POP.TOTL,47105826,48428545,51425580,53068880,54785903,56578037,58453683,60411195,62448574,64563854,66755153,69020747,71358807,73767447,76244544,78789127,81398764,84068091
-"Congo, Dem. Rep.",COD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,21034807038.348,20394707403.7056,23545611988.7085,25687895915.5444,27751186945.9311,30424080748.4762,33011910345.0108,34660101260.5643,36886758779.0323,39965060256.6331,43243275549.0054,46982673967.31,50131412017.524,56000619571.3355,61244681428.4691,66982405715.3429,70294538060.5356,75448581499.4623
-"Congo, Rep.",COG,"Population, total",SP.POP.TOTL,3127411,3217933,3406922,3510468,3622775,3745141,3876119,4011486,4145391,4273731,4394844,4510198,4622761,4736974,4856095,4980999,5110702,5244363
-"Congo, Rep.",COG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8125981776.29668,8590549799.36123,9814544807.28123,9617925880.2185,10408743956.4426,11356621727.5642,11954999432.4044,13830199561.487,14735234321.3174,16747992729.5368,17474371156.6628,19184494729.9999,20553002317.6684,23602638777.4551,29270450660.5801,26944286775.3179,25916389541.8866,26494709250.2471
-Costa Rica,CRI,"Population, total",SP.POP.TOTL,3962372,4034074,4164053,4225155,4285502,4345412,4404628,4463125,4520740,4577378,4633086,4688000,4742107,4795396,4847804,4899345,4949954,4999441
-Costa Rica,CRI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29436005402.432,31130412536.7697,34678450968.4311,37304895912.9549,40152681647.7638,44750974000.0409,49875346251.8108,53570810616.763,52704716540.6093,56002520609.8941,59533347306.0666,63731636696.1587,65948353976.5911,69186596551.2043,72341900700.9045,76291513703.4709,79751485064.5815,83327166153.4076
-Cote d'Ivoire,CIV,"Population, total",SP.POP.TOTL,16454668,16853026,17599610,17970494,18354514,18754916,19171237,19605569,20059147,20532950,21028655,21547188,22087505,22647683,23226143,23822714,24437469,25069229
-Cote d'Ivoire,CIV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,35480054292.9691,35463648912.523,34180501166.4538,37259620830.2317,42151035636.1859,44007100639.015,45993257283.9786,48213752794.0334,50085984179.8494,51790826080.2524,50433570908.0155,57303471759.6721,62643767692.1327,70853912606.2592,77570059411.2709,87057194674.6245,91977457081.0906,101097524869.228
-Croatia,HRV,"Population, total",SP.POP.TOTL,4468302,4299642,4303399,4304600,4310145,4311159,4310217,4309705,4305181,4295427,4280622,4267558,4255689,4238389,4203604,4174349,4124531,4089400
-Croatia,HRV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,46712571361.0721,49269004466.6864,56396412998.335,61457781862.485,64523229646.6618,73333121308.7033,81659959331.0713,87346369787.3108,83484723025.6131,82587555603.4197,86432809934.0225,87590533181.6114,90916733610.9595,91712476553.0583,96090717568.439,99104675733.8454,106532253085.809,..
-Cuba,CUB,"Population, total",SP.POP.TOTL,11126430,11164667,11229183,11250365,11261582,11261248,11251122,11236971,11226709,11225832,11236670,11257101,11282720,11306902,11324781,11335109,11339259,11338138
-Cuba,CUB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Curacao,CUW,"Population, total",SP.POP.TOTL,133860,129047,131897,134192,137658,141239,144056,145880,146833,148703,150831,152088,153822,155909,157980,159664,160175,159849
-Curacao,CUW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,3576807867.17759,3753936937.4761,3950818825.06229,4028383214.39046,3979440641.03859,4083315886.40691,4190952876.22346,4224747984.36592,4250788721.52518,4318430855.74745,4416683751.74736,4390263974.04831,4456032332.31524,..
-Cyprus,CYP,"Population, total",SP.POP.TOTL,943290,960276,993563,1010408,1027662,1045507,1063713,1081563,1098083,1112612,1124833,1135046,1143866,1152285,1160985,1170187,1179680,1189265
-Cyprus,CYP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13508199013.3742,14900135043.6689,16710936982.4047,17808258546.8655,19438150076.4319,21269122586.5108,23585499461.0417,26828760166.2928,26047511325.8369,26724583726.5894,28202177534.2958,26677564030.0901,25281697880.5511,25028812233.5479,27105848270.8932,28102833113.9845,30232255651.3533,..
-Czech Republic,CZE,"Population, total",SP.POP.TOTL,10255063,10216605,10193998,10197101,10211216,10238905,10298828,10384603,10443936,10474410,10496088,10510785,10514272,10525347,10546059,10566332,10594438,10625695
-Czech Republic,CZE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,163000344162.592,174465600018.659,191474672302.247,202339797296.057,214084360418.233,228697026228.795,251865694517.321,270395387186.615,267930037450.393,268403859052.561,279370310382.565,286391051564.635,301403153675.82,316710658172.226,331373459943.474,348125885411.157,378005368627.907,402376187264.344
-Denmark,DNK,"Population, total",SP.POP.TOTL,5339616,5358783,5390574,5404523,5419432,5437272,5461438,5493621,5523095,5547683,5570572,5591572,5614932,5643475,5683483,5728010,5764980,5797446
-Denmark,DNK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,149560708541.011,155486337804.36,164469983410.812,178074345542.071,186566260237.836,205243068258.734,213892593685.525,229296531979.344,225023089962.946,242450184707.942,252568140433.285,256181670980.004,270675551874.234,280163778604.424,287382159288.342,297792837721.213,320311725561.574,333201235810.944
-Djibouti,DJI,"Population, total",SP.POP.TOTL,717584,733015,759641,771603,783254,794563,805451,816358,827823,840198,853674,868136,883293,898696,913993,929112,944097,958920
-Djibouti,DJI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Dominica,DMA,"Population, total",SP.POP.TOTL,69650,69661,70100,70382,70589,70718,70795,70827,70851,70878,70916,70965,71016,71085,71183,71307,71458,71625
-Dominica,DMA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,401854626.13162,430969292.907311,458398582.909263,478767669.499686,503054183.029804,566716313.577913,613740256.101501,674876230.978717,680580696.154226,699426352.369397,711041658.178211,704886225.182432,720074113.193201,763410589.590503,745317961.150396,783629128.326856,724664689.194033,764788991.62708
-Dominican Republic,DOM,"Population, total",SP.POP.TOTL,8471321,8598601,8850317,8974444,9097257,9218686,9338861,9458075,9576737,9695121,9813210,9930911,10048224,10165178,10281680,10397743,10513131,10627165
-Dominican Republic,DOM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,53481190272.1459,56010175780.0105,58385312272.7899,60475457591.4277,70258633460.8789,79369374913.6574,87413127513.4887,93243822579.6949,94972263207.1716,104077078762.039,109291187706.743,114284989019.255,120991895595.267,132394683034.872,144197222332.01,155041371100.503,164315674618.162,180204991045.454
-Ecuador,ECU,"Population, total",SP.POP.TOTL,12681123,12914667,13369678,13596388,13825847,14059384,14296557,14535739,14774424,15011117,15243883,15474102,15707474,15951838,16212020,16491115,16785361,17084357
-Ecuador,ECU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,69280703994.4372,74939826490.499,83293244502.3108,92144751696.0842,100732038310.192,108881841131.225,114310646556.442,125934606254.109,127980486903.701,134776770005.444,148275374796.055,159839411622.691,170731099834.796,180399188092.245,182104909146.231,181651987717.823,188691065639.306,194962984646.79
-"Egypt, Arab Rep.",EGY,"Population, total",SP.POP.TOTL,68831561,70152661,72826097,74172073,75523569,76873663,78232126,79636079,81134798,82761235,84529250,86422240,88404640,90424654,92442547,94447072,96442593,98423595
-"Egypt, Arab Rep.",EGY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,412961924858.391,437524824627.395,478069035113.576,511392198190.805,545955158075.548,605653097636.973,668709451792.424,730017558226.209,764204949234.673,796047078255.1,822212016133.083,858781638146.281,890690721696.348,935819929627.236,993888699426.081,1052381337220.99,1110453289615.67,1188986874332.94
-El Salvador,SLV,"Population, total",SP.POP.TOTL,5887936,5927006,5994077,6023797,6052123,6079399,6105810,6131764,6157686,6183875,6210568,6237923,6266070,6295128,6325124,6356143,6388122,6420744
-El Salvador,SLV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,25731066473.5272,26521930838.5172,28012601042.5023,28980662325.8934,30692505754.9181,33199904357.5669,34744757201.8196,36366993198.4304,35515642872.3809,36935914405.5762,39093487965.8727,40532482057.3802,41975930795.1175,43465486433.9427,44945203952.4876,46366870125.1147,48095933992.8021,50384982982.5379
-Equatorial Guinea,GNQ,"Population, total",SP.POP.TOTL,606181,631666,686664,716949,749535,784496,821687,860840,901599,943639,986853,1031191,1076413,1122276,1168568,1215179,1262001,1308974
-Equatorial Guinea,GNQ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3408755735.77416,3542649774.71665,4615157301.56908,5905936380.34294,10749871568.0903,18489395069.6507,22230972357.5893,24747690281.0513,22552090046.0557,18446060174.2367,22107638610.3946,25007608269.967,25150790163.8727,25590955292.7066,26082123067.2383,24699683680.3115,24569364957.0602,23787894046.6584
-Eritrea,ERI,"Population, total",SP.POP.TOTL,2292416,2374722,2600973,2719803,2826659,2918205,2996536,3062779,3119920,3170435,3213972,..,..,..,..,..,..,..
-Eritrea,ERI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4536444377.15044,5022663733.88327,5169227092.41034,5370835616.33827,5710735333.76666,5834714525.94245,6087351656.9654,5581576825.76507,5841037405.2831,6035304585.65003,6697806876.39949,..,..,..,..,..,..,..
-Estonia,EST,"Population, total",SP.POP.TOTL,1396985,1388115,1370720,1362550,1354775,1346810,1340680,1337090,1334515,1331475,1327439,1322696,1317997,1314545,1315407,1315790,1317384,1320884
-Estonia,EST,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12666789519.1477,13620908798.3207,16938221220.577,18679254764.7334,21499500921.8641,24589142619.2906,27420515302.2847,28710497105.7967,26528101753.5309,27211610932.9907,30946637998.4363,33031898254.1458,35403618516.7603,36991781965.8752,37581777179.0502,39736976808.2844,43192606524.7084,46293918876.6402
-Eswatini,SWZ,"Population, total",SP.POP.TOTL,1005435,1013609,1022802,1026286,1030579,1036092,1042652,1049945,1057467,1064837,1072032,1079288,1086839,1095021,1104044,1113984,1124753,1136191
-Eswatini,SWZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,5029264899.34808,5431482698.44771,5605403004.57176,6086729254.65741,7019450479.00059,7288925224.86084,7875801784.567,7987564619.30913,8014581048.60538,8158967274.51923,8915944430.94028,9529512409.33264,10469276662.0151,10797251156.7553,11037244994.8404,11374227169.1727,11622271561.2596,12136637596.5774
-Ethiopia,ETH,"Population, total",SP.POP.TOTL,66224804,68159423,72170584,74239505,76346311,78489206,80674348,82916235,85233913,87639964,90139927,92726971,95385785,98094253,100835458,103603501,106400024,109224559
-Ethiopia,ETH,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,32495282528.946,36003438063.3715,36945461559.3404,43150160761.3222,49922420935.5234,57027126353.4857,65479193349.3512,73955721823.1239,80915432771.973,91916910997.9935,104477152060.005,115683777824.005,130168120863.094,146161119852.496,162860949431.361,180317660195.581,200668362272.026,219041116378.24
-Faroe Islands,FRO,"Population, total",SP.POP.TOTL,46735,46997,47432,47600,47722,47792,47825,47820,47808,47814,47823,47843,47892,47960,48051,48173,48331,48497
-Faroe Islands,FRO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Fiji,FJI,"Population, total",SP.POP.TOTL,811006,813925,816076,817860,821604,827870,836190,845361,853637,859818,863449,865069,865608,866453,868627,872399,877459,883483
-Fiji,FJI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4393254619.3207,4453051339.64807,4845200477.65203,5237640320.607,5516418557.61792,5484022989.9694,5680895104.463,5836071536.20772,5922291857.24864,6001032787.66044,6297184005.93723,6463588707.59906,7012570122.84193,7339027928.56517,7784249415.98458,8089192085.39646,8493902568.48219,9055011599.64496
-Finland,FIN,"Population, total",SP.POP.TOTL,5176209,5188008,5213014,5228172,5246096,5266268,5288720,5313399,5338871,5363352,5388272,5413971,5438972,5461512,5479531,5495303,5508214,5518050
-Finland,FIN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,137615639231.006,144016223133.926,150203416763.615,163835671564.873,168542939523.638,182667559886.062,200030992177.147,212770179525.833,204559096213.621,210577337354.589,220207155805.574,221064507784.853,225363033587.855,228549068021.737,233624314603.572,243618103865.339,256023979623.249,267593673585.704
-France,FRA,"Population, total",SP.POP.TOTL,60912500,61357430,62244886,62704895,63179351,63621381,64016225,64374984,64707040,65027507,65342780,65659809,65998687,66316100,66593366,66859768,66865144,66987244
-France,FRA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1614576023391.81,1717847289338.03,1774911405322.66,1845778056986.32,1959874975176.17,2104837447257.03,2225555202100.65,2308471504999.58,2295992878907.82,2388528957528.96,2511515152235.48,2528096970156.38,2666951479899.41,2719730721366.08,2777946746850.25,2864118350983.51,3028054653714.54,3141673740932.97
-French Polynesia,PYF,"Population, total",SP.POP.TOTL,240686,244931,252703,255992,258780,261010,262721,264061,265254,266455,267698,268998,270328,271705,273124,274575,276103,277679
-French Polynesia,PYF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Gabon,GAB,"Population, total",SP.POP.TOTL,1228360,1258003,1319953,1353795,1390549,1430152,1472575,1518540,1568928,1624140,1684635,1749682,1817071,1883800,1947686,2007873,2064823,2119275
-Gabon,GAB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,14743976923.0787,15903706068.4965,17082555071.2646,16793995544.0597,18906714345.9991,18263730074.5878,19532052080.7454,19433217896.8406,20183177851.5666,21430282018.2387,23271285619.8072,26046345457.1258,28088314725.5367,31336428776.4089,31824807567.0167,33038652079.9311,34357763181.5816,35128039218.2989
-"Gambia, The",GMB,"Population, total",SP.POP.TOTL,1317703,1360074,1449925,1496527,1543741,1591445,1639848,1689285,1740279,1793196,1848147,1905011,1963711,2024042,2085860,2149139,2213894,2280102
-"Gambia, The",GMB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1460305030.96115,1567713255.37819,1675037890.78028,1862654425.3019,1901965596.91495,1976755395.91392,2116489675.95252,2295235445.62075,2450299619.41391,2639734098.21677,2568312969.26981,2773695558.53477,2989457824.2978,3013357990.55311,3221997583.89106,3285983120.13955,3501293882.52496,3820914013.16318
-Georgia,GEO,"Population, total",SP.POP.TOTL,4077131,4014373,3951736,3927340,3902469,3880347,3860158,3848449,3814419,3786695,3756441,3728874,3717668,3719414,3725276,3727505,3728004,3731000
-Georgia,GEO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,11883232471.1089,12379493447.6303,14905170087.7075,16386025523.1156,18414264662.5725,20992729768.6812,23860463088.4945,24481397760.1856,23828723929.4127,25096051756.829,27516505407.7668,30440439989.0537,31712240005.1967,34139735907.6908,34845666928.2224,35403391908.1103,37635016056.1621,40672983047.3946
-Germany,DEU,"Population, total",SP.POP.TOTL,82211508,82349925,82534176,82516260,82469422,82376451,82266372,82110097,81902307,81776930,80274983,80425823,80645605,80982500,81686611,82348669,82657002,82927922
-Germany,DEU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2229306920614.45,2325236478018.54,2452833554457.98,2610660824034.86,2659840888439.72,2869303616573.65,3042783013746.36,3152657054294.18,3102023577576.64,3267762589972.74,3513624912677.07,3585851182476.63,3730248688666.78,3896388130627.09,4003832048056.79,4192471673148,4437045277649.97,4627201990499.89
-Ghana,GHA,"Population, total",SP.POP.TOTL,19278856,19756928,20750299,21272323,21814642,22379055,22963946,23563825,24170940,24779619,25387710,25996449,26607642,27224472,27849205,28481946,29121471,29767108
-Ghana,GHA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,33041124698.1318,35447829634.3317,40268117260.6826,43636729883.9707,48143435859.0974,53092455658.9934,56922660249.067,63441044696.2121,67051659553.794,72238824482.4015,82867099335.8828,90428354238.5006,101805409495.635,105529255249.785,111140628609.372,115546836446.63,126358366839.609,138278565905.309
-Gibraltar,GIB,"Population, total",SP.POP.TOTL,31077,31602,32555,32928,33219,33417,33517,33559,33565,33585,33612,33646,33692,33725,33736,33737,33728,33718
-Gibraltar,GIB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Greece,GRC,"Population, total",SP.POP.TOTL,10805808,10862132,10928070,10955141,10987314,11020362,11048473,11077841,11107017,11121341,11104899,11045011,10965211,10892413,10820883,10775971,10754679,10727668
-Greece,GRC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,212362791183.849,229449400332.151,260110749576.068,275402356623.851,281471978035.928,308462945667.322,315293003593.82,331637075588.565,329782253257.55,306635432541.958,282370859957.681,281120340956.062,285824079577.244,294315512120.89,291510428686.154,293914047364.1,307963982617.238,317555841816.728
-Greenland,GRL,"Population, total",SP.POP.TOTL,56200,56350,56765,56911,56935,56774,56555,56328,56323,56905,56890,56810,56483,56295,56114,56186,56171,56025
-Greenland,GRL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Grenada,GRD,"Population, total",SP.POP.TOTL,102833,103249,104005,104347,104661,104933,105190,105456,105789,106233,106796,107446,108170,108902,109599,110261,110874,111454
-Grenada,GRD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,729811265.15908,719207633.336454,837267278.880919,832401495.777686,1046599571.84973,1034498226.37774,1112258858.89832,1147605013.5566,1045684105.2584,1086866790.28646,1130929356.42457,1136864040.03673,1193581768.79409,1230038983.89587,1288798453.88827,1386903789.0292,1482628608.61155,1590367855.17114
-Guam,GUM,"Population, total",SP.POP.TOTL,155329,156401,157717,158101,158402,158648,158847,159036,159226,159444,159692,159996,160407,161016,161853,162951,164281,165768
-Guam,GUM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Guatemala,GTM,"Population, total",SP.POP.TOTL,11650743,11924946,12500478,12796925,13096028,13397021,13700327,14006428,14316263,14630417,14948803,15270778,15595821,15923243,16252429,16583060,16914936,17247807
-Guatemala,GTM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,55670407578.2359,58592404276.6108,63914458725.1716,67524765789.2827,71846055582.6138,77630468469.7081,84550742390.1576,89318548902.2149,90100659907.1463,93663004820.6312,99115991862.8735,105000268304.332,111062522252.135,117381193104.522,123805715663.505,129027379861.915,135651416286.548,143265987313.624
-Guinea,GIN,"Population, total",SP.POP.TOTL,8240730,8417081,8753093,8925743,9109581,9307425,9518162,9738792,9964469,10192176,10420471,10652029,10892810,11150977,11432088,11738441,12067539,12414318
-Guinea,GIN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9714681942.18454,10223876592.2695,10793657280.2056,11310143455.9914,11738592829.3469,12702764437.6512,14019561423.5639,14572001285.1311,14469336767.5771,15564483972.121,16709591204.9151,18226230564.6896,19388743012.716,20929260871.3135,22037069336.4195,24981832527.4242,29235939634.075,30815844547.9741
-Guinea-Bissau,GNB,"Population, total",SP.POP.TOTL,1201301,1227106,1283305,1313492,1344930,1377581,1411543,1446936,1483921,1522599,1562989,1604979,1648257,1692439,1737202,1782437,1828146,1874309
-Guinea-Bissau,GNB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1303568154.81999,1351450773.91591,1417672696.40107,1501774707.87463,1614416902.49896,1719111566.4626,1830976569.57275,1905808393.40688,1991758387.90641,2125076307.89134,2368745194.2087,2371847802.79503,2431090805.80576,2640173335.44153,2801908133.752,3012345990.2243,3177784274.85024,3361320232.54189
-Guyana,GUY,"Population, total",SP.POP.TOTL,746715,745206,745143,745737,746163,746343,746474,746817,747718,749436,752028,755399,759285,763380,767432,771366,775221,779004
-Guyana,GUY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2574022868.95956,2660767356.67047,2809147435.49711,2983766588.80754,3065920166.23635,3507705657.38875,3818897828.95477,3920016679.67017,4092161389.32798,4252394193.28401,4576050795.78135,4925516995.187,5214463681.44254,5522469580.64164,5763653914.22797,6074741356.5651,6347780648.34287,6673977598.72941
-Haiti,HTI,"Population, total",SP.POP.TOTL,8463806,8608819,8900104,9047077,9195288,9344785,9495328,9646580,9798046,9949322,10100320,10250930,10400673,10549008,10695542,10839970,10982366,11123176
-Haiti,HTI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,11871793651.3325,11967713678.45,12330135027.7823,12239278169.7267,12782391307.2109,13585630071.2796,14416830037.4507,14828336585.8573,15418932671.4302,14761919937.5217,15929101063.5587,16734290649.9261,17692824275.928,18568600471.9952,18976764384.1355,19489166076.5331,20100047326.4725,20839429278.5109
-Honduras,HND,"Population, total",SP.POP.TOTL,6574509,6751912,7106319,7282953,7458985,7634298,7808518,7980955,8150775,8317470,8480671,8640691,8798521,8955589,9112916,9270795,9429013,9587522
-Honduras,HND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16745044650.4654,17527860759.1041,19452942814.8251,21071163401.126,23151121210.4402,25366517128.4012,28137057298.8321,29731089809.976,29052515217.776,30403154608.708,31919842263.2935,33394732910.8996,34746750371.4101,36163368560.6401,38507393808.5759,40381159265.7035,43055112035.1209,45874972260.0696
-"Hong Kong SAR, China",HKG,"Population, total",SP.POP.TOTL,6665000,6714300,6730800,6783500,6813200,6857100,6916300,6957800,6972800,7024200,7071600,7150100,7178900,7229500,7291300,7336600,7391700,7451000
-"Hong Kong SAR, China",HKG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,181863075151.109,189678635096.846,206127089270.754,229105534445.727,249731534679.926,280406109927.013,309059710499.735,330153972492.621,315642283460.738,338009531468.805,363860139557.707,372426704794.752,392445199025.727,411590656586.16,425040649368.666,441897493082.683,475913471225.503,504413709964.83
-Hungary,HUN,"Population, total",SP.POP.TOTL,10210971,10187576,10129552,10107146,10087065,10071370,10055780,10038188,10022650,10000023,9971727,9920362,9893082,9866468,9843028,9814023,9787966,9768785
-Hungary,HUN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,115476509619.814,128234581482.817,149701017212.796,155564507283.733,163043381710.731,174893868356.71,178804208012.421,194929993510.571,197636041917.122,205400698171.896,217225711544.167,219991325197.41,235706216043.613,241274846603.145,247987272728.343,257095437398.458,270624996605.58,291009192490.907
-Iceland,ISL,"Population, total",SP.POP.TOTL,281205,284968,289521,292074,296734,303782,311566,317414,318499,318041,319014,320716,323764,327386,330815,335439,343400,353574
-Iceland,ISL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8062152412.1613,8781651582.61127,9381323150.38087,10025195030.4832,10526296722.7951,11028043033.0308,12073945245.9316,10807260433.594,10700033108.4016,10229377123.8514,11022605832.7629,11766282593.5493,13631427233.6515,14240759323.4076,15376113336.7176,16880864403.5238,18591462282.2833,..
-India,IND,"Population, total",SP.POP.TOTL,1056575549,1075000085,1111523144,1129623456,1147609927,1165486291,1183209472,1200669765,1217726215,1234281170,1250288729,1265782790,1280846129,1295604184,1310152403,1324509589,1338658835,1352617328
-India,IND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2254497994239.14,2419864321502.12,2806869697760.35,3112043076824.13,3462656489680.63,3852594313588.19,4274711167203.71,4484328708574.98,4873764181835.93,5323989186781.73,5731191285361.23,6141496500296.88,6643581440003.42,7275510313097.29,7938517560724.76,8687007292198.3,9493084548460.84,10391783229262.5
-Indonesia,IDN,"Population, total",SP.POP.TOTL,211513823,214427417,220309469,223285676,226289470,229318262,232374245,235469762,238620563,241834215,245116206,248452413,251806402,255129004,258383256,261554226,264645886,267663435
-Indonesia,IDN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,912499951057.57,996748906491.408,1127645769819.18,1206846828606.79,1311456277050.35,1434543531179.9,1568967281843.51,1705556503990.61,1799110414075.65,1950129436855.68,2111380501435.95,2280382863217.34,2445162210216.79,2606343176808.9,2763690452519.22,2938047210877.73,3144087539232.47,3386415495500.02
-"Iran, Islamic Rep.",IRN,"Population, total",SP.POP.TOTL,65623405,66449112,68122938,68951281,69762347,70554760,71336475,72120604,72924837,73762519,74634956,75539862,76481943,77465753,78492215,79564016,80673951,81800269
-"Iran, Islamic Rep.",IRN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,690556206758.097,712169708326.653,860740196807.758,919360289229.462,978053488236.995,1060394782313.09,1180402772538.67,1207057336697.93,1224125332145.1,1310788556897.82,1373456121278.43,1304594056709.51,1324649207072.65,1406451697334.4,1402082301470.5,1608229808602.6,1698218039348.97,..
-Iraq,IRQ,"Population, total",SP.POP.TOTL,23497585,24208180,25644499,26313838,26922284,27448124,27911248,28385746,28973162,29741976,30725300,31890011,33157050,34411951,35572261,36610632,37552781,38433600
-Iraq,IRQ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,226902159991.146,237027400829.002,154014842848.652,243897135800.009,266069273154.233,301650947119.667,314980662228.171,360045168708.816,365882657677.608,387625292654.885,420294877136.849,490956774975.036,529592015081.426,546302103233.509,564282698932.659,647723901003.798,646563104355.44,664345140348.102
-Ireland,IRL,"Population, total",SP.POP.TOTL,3805174,3866243,3996521,4070262,4159914,4273591,4398942,4489544,4535375,4560155,4580084,4599533,4623816,4657740,4701957,4755335,4807388,4853506
-Ireland,IRL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,100089405584.551,107469355619.18,124853550921.398,135840159124.082,145668071091.729,165676630536.902,177850339150.471,172166895124.872,157804241154.413,165411181538.896,166937837412.043,171626952198.593,187172886537.447,201368611217.265,249135028148.082,275448712001.61,294054946448.367,324263630749.361
-Isle of Man,IMN,"Population, total",SP.POP.TOTL,76941,77703,78884,79520,80305,81285,82408,83508,84376,84857,84886,84533,83976,83488,83234,83287,83598,84077
-Isle of Man,IMN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Israel,ISR,"Population, total",SP.POP.TOTL,6289000,6439000,6689700,6809000,6930100,7053700,7180100,7308800,7485600,7623600,7765800,7910500,8059500,8215700,8380100,8546000,8713300,8883800
-Israel,ISR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,146891357221.145,153669223845.463,153399675971.541,166564745049.532,170449240893.779,180345200458.033,196864272630.799,196461441247.619,200933910084.109,215702839804.238,234196033247.118,244505617038.963,269867621392.626,279789763568.908,295058945359.525,317686454500.238,335193804201.287,362437028915.231
-Italy,ITA,"Population, total",SP.POP.TOTL,56942108,56974100,57313203,57685327,57969484,58143979,58438310,58826731,59095365,59277417,59379449,59539717,60233948,60789140,60730582,60627498,60536709,60431283
-Italy,ITA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1533082189484.25,1586538671240.85,1658662756415.48,1695832590542.32,1744720332016.2,1887221742001.9,1988274225959.19,2063595995375.75,2038366547193.59,2071050453316.78,2152592702919.65,2154531375588.28,2172610704748.01,2192796128948.52,2225001252547.41,2372736136365.55,2491347733670.36,2567974254467.98
-Jamaica,JAM,"Population, total",SP.POP.TOTL,2654701,2674702,2709437,2725015,2740003,2754407,2768227,2781876,2795837,2810460,2825929,2842132,2858709,2875136,2891021,2906238,2920853,2934855
-Jamaica,JAM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16132454466.796,16547694687.474,17876474575.387,18643625969.6867,19335604200.4298,20686757639.8361,21551036065.748,22026724163.9566,20922077237.2541,21248551806.6578,22101414941.4774,22870830677.9019,23139310158.4967,23721074081.5176,23941578871.5546,24238489019.968,25314880413.8532,26213482151.1758
-Japan,JPN,"Population, total",SP.POP.TOTL,126843000,127149000,127718000,127761000,127773000,127854000,128001000,128063000,128047000,128070000,127833000,127629000,127445000,127276000,127141000,126994511,126785797,126529100
-Japan,JPN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3452930586529.41,3546345207550.25,3752540629883.33,3950154009958.02,4133438974348.17,4341515713395.91,4548813775507.34,4573202767880.07,4354890214696.97,4596530742002.53,4702730270932.62,4873844260962.84,5133797407300.4,5166025961476.02,5333311667417.55,5396926080206.59,5514385495607.58,5693329186714.86
-Jordan,JOR,"Population, total",SP.POP.TOTL,5122493,5217336,5434030,5580244,5765635,5991540,6255280,6556478,6893260,7261539,7663131,8090872,8520420,8920049,9266575,9551467,9779173,9956011
-Jordan,JOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29781418130.4024,32232494190.1203,36557399707.156,41060925526.7765,45797659875.1787,51186766060.0581,57386465978.9692,61817072574.4817,65515235566.7773,66222988729.5046,69281067836.4756,72233540271.4316,75770153716.5835,79474255916.8684,82257831669.9514,85133386168.5754,88831873562.4639,92628702339.1399
-Kazakhstan,KAZ,"Population, total",SP.POP.TOTL,14883626,14858335,14909018,15012985,15147029,15308084,15484192,15674000,16092822,16321872,16557201,16792089,17035550,17288285,17542806,17794055,18037776,18276499
-Kazakhstan,KAZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,109782273989.869,129074822591.256,160140046529.332,178384355938.742,195819542275.122,217723759594.57,241575088708.378,248231027073.925,263596957161.343,279261900779.44,301583512406.376,325435632564.894,362720166985.819,386842311951.103,414348263500.891,408008276019.153,424596357129.541,442767958630.541
-Kenya,KEN,"Population, total",SP.POP.TOTL,31964557,32848564,34678779,35635271,36624895,37649033,38705932,39791981,40901792,42030676,43178257,44343410,45519889,46699981,47878336,49051686,50221473,51393010
-Kenya,KEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,52813995170.6039,55947811915.7323,59924694217.6918,64832513562.5916,71405468636.6949,78141195418.8126,85582764482.0683,87768971233.4377,91333029718.9188,99914764428.8247,108655317520.867,115251383514.772,123367615240.565,132001732909.451,141535003711.004,152276363203.295,162227087231.766,176420478135.16
-Kiribati,KIR,"Population, total",SP.POP.TOTL,84396,85849,88835,90499,92325,94343,96527,98761,100930,102927,104728,106370,107890,109391,110930,112524,114158,115847
-Kiribati,KIR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,217156131.679699,232653434.252912,222507516.800126,225167332.318293,231498586.867625,232628480.66327,248005509.182338,252582083.047309,243191331.126092,258637330.477255,254926735.893375,295962984.145689,345978021.428474,399192673.872255,479825866.063915,484149995.971851,498690300.698936,510549381.924241
-"Korea, Dem. People’s Rep.",PRK,"Population, total",SP.POP.TOTL,22929075,23132980,23542426,23732731,23904167,24054864,24188331,24310142,24428341,24548836,24673385,24800612,24929452,25057752,25183833,25307744,25429985,25549819
-"Korea, Dem. People’s Rep.",PRK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-"Korea, Rep.",KOR,"Population, total",SP.POP.TOTL,47008111,47370164,47892330,48082519,48184561,48438292,48683638,49054708,49307835,49554112,49936638,50199853,50428893,50746659,51014947,51245707,51466201,51635256
-"Korea, Rep.",KOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,843929272354.612,901776576929.781,1019822288361.57,1100600666573.17,1156781985289.3,1246052587393.16,1350379136115.63,1405611759231.35,1393348976504.33,1506236849977.5,1568631167033.9,1627811703472.46,1656512685183.14,1709830640018.39,1829299733915.32,1908538437723.28,1998202358354.7,2088780026386.59
-Kosovo,XKX,"Population, total",SP.POP.TOTL,1700000,1701154,1703466,1704622,1705780,1719536,1733404,1747383,1761474,1775680,1791000,1805200,1824100,1821800,1801800,1816200,1830700,1845300
-Kosovo,XKX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,11333490148.2231,12745735745.0873,13178834168.8881,13366887903.8259,13972080236.1477,15064908212.123,15910577393.1932,16622579155.1294,17100206064.1015,17911461812.0703,18793325797.96,20224688998.8495,21368646478.0585
-Kuwait,KWT,"Population, total",SP.POP.TOTL,2045123,2103282,2161626,2200492,2270198,2373672,2504019,2656009,2821045,2991884,3168060,3348853,3526378,3690942,3835591,3956873,4056097,4137309
-Kuwait,KWT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,134366986554.57,133950658454.194,157166964311.593,181616976393.264,206446429990.09,232698753156.174,253302473215.996,256215543296.024,243412517555.733,237046895717.794,261909682318.451,288203878837.211,297506214978.566,310334239041.657,319716442961.854,339888752714.972,342743643130.856,344992137141.301
-Kyrgyz Republic,KGZ,"Population, total",SP.POP.TOTL,4898400,4945100,5043300,5104700,5162600,5218400,5268400,5318700,5383300,5447900,5514600,5607200,5719600,5835500,5956900,6079500,6198200,6315800
-Kyrgyz Republic,KGZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7602141456.85009,8366008139.41657,9325142721.13729,10104597978.0189,10511255443.4932,11383537453.3525,12731183780.1648,13690544980.9526,14215870379.7178,13942138178.2375,14393401502.2784,15962043776.9596,17420375928.3299,18783851119.3135,19776488545.2834,20558444178.3441,22025333361.309,23862030091.6635
-Lao PDR,LAO,"Population, total",SP.POP.TOTL,5323700,5409582,5576640,5662208,5751676,5846074,5944948,6046620,6148623,6249165,6347567,6444530,6541304,6639756,6741164,6845846,6953035,7061507
-Lao PDR,LAO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,10107541300.8073,10944742167.1709,12496963016.2619,13866791059.5909,15585867397.6811,16884961048.5644,19055186702.5762,20685659241.1533,22845158845.7875,24175906769.4227,26541063220.8385,29473799369.3601,32601161038.6543,36112362744.3456,39137328494.4602,42409610302.7425,45704405341.0543,50094763456.8897
-Latvia,LVA,"Population, total",SP.POP.TOTL,2367550,2337170,2287955,2263122,2238799,2218357,2200325,2177322,2141669,2097555,2059709,2034319,2012647,1993782,1977527,1959537,1942248,1926542
-Latvia,LVA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18962509797.4388,21180500225.2368,25105426714.9969,27069993124.6461,30679837261.8891,34066030259.3661,38699573363.3915,41769625912.017,38689587918.7077,37293375812.7765,40716218188.3451,42941376174.3867,45544119509.2039,47298973906.1904,48617091181.9267,50503936883.6885,54704958845.6954,..
-Lebanon,LBN,"Population, total",SP.POP.TOTL,3842778,3991001,4388375,4569378,4698763,4759753,4767344,4764741,4813026,4953061,5202343,5538634,5914621,6262410,6532678,6711121,6811873,6848925
-Lebanon,LBN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,33069608028.3763,34307414777.8157,31762931885.6568,39940911996.1475,43606658858.6349,46431223607.1029,53328612759.9013,58520968919.4407,63541981247.6059,68968538834.3693,71578309882.1387,75037729797.1026,78350884775.3785,80741563368.3889,82091107221.021,83828417819.6471,87221100692.5972,86338436893.423
-Lesotho,LSO,"Population, total",SP.POP.TOTL,2032804,2035740,2018348,2005940,1996114,1989939,1986922,1987129,1990131,1995581,2003787,2014990,2028519,2043437,2059021,2075001,2091412,2108132
-Lesotho,LSO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3374636405.66938,4054653044.61798,4365749850.42696,4375286661.28503,4416751209.4495,4554400335.95669,5452401490.72242,5803961888.63355,5778542043.87086,6004180785.42078,6103484710.24303,6438442137.1208,6581117356.53085,6717129755.48522,7006631361.35657,7425001291.86165,7355866701.56858,7618226994.21345
-Liberia,LBR,"Population, total",SP.POP.TOTL,2848456,2953927,3077058,3135651,3218116,3329211,3461911,3607860,3754133,3891356,4017443,4135659,4248334,4359505,4472230,4586788,4702228,4818977
-Liberia,LBR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2640595556.19249,2599118711.48849,1874637193.15939,2022760489.5612,2253700761.7781,2593071426.45679,2996032003.098,3345705050.12496,3591682233.09205,3821574855.61568,4396321822.5236,4613111881.87455,5091205724.36084,5179789064.89213,5339301968.34643,5325361708.85642,5521235843.05053,5448420408.16613
-Libya,LBY,"Population, total",SP.POP.TOTL,5357891,5443248,5620547,5710154,5798614,5886872,5974787,6058748,6133984,6197663,6247439,6285750,6320359,6362037,6418315,6492164,6580724,6678567
-Libya,LBY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,110851580842.784,115660686294.502,133595871383.002,149945963360.283,163057953847.585,169949584037.157,170066053014.484,178982808764.256,69433530943.1827,153938014847.876,137725462934.214,108849271687.94,103084072263.745,99936446542.6964,127502666207.123,140194689272.7
-Liechtenstein,LIE,"Population, total",SP.POP.TOTL,33184,33552,34175,34452,34713,34970,35217,35471,35727,35994,36293,36615,36934,37223,37470,37658,37800,37910
-Liechtenstein,LIE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Lithuania,LTU,"Population, total",SP.POP.TOTL,3499536,3470818,3415213,3377075,3322528,3269909,3231294,3198231,3162916,3097282,3028115,2987773,2957689,2932367,2904910,2868231,2828403,2789533
-Lithuania,LTU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29066641542.0027,32362015094.2703,40192899281.2295,43151528711.0143,47617999575.7175,52874111973.7666,59380024580.9173,64082365384.7112,58465472219.3645,61067979410.1967,66665174610.9159,71449836203.4754,76802302249.8664,81544930490.511,80563029769.1673,83390381426.9729,90284616069.8659,..
-Luxembourg,LUX,"Population, total",SP.POP.TOTL,436300,441525,451630,458095,465158,472637,479993,488650,497783,506953,518347,530946,543360,556319,569604,582014,596336,607728
-Luxembourg,LUX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,21397795484.033,22205166172.3317,22110800022.7794,26867967158.084,29304952011.0148,29989597043.7305,34893624479.4315,34990188934.9977,27740237256.596,31304552603.8336,32928110626.5723,33825803107.6655,34690043272.6355,37434314552.7056,39571975823.6145,41524878233.4819,45501546147.6316,49005972521.9818
-"Macao SAR, China",MAC,"Population, total",SP.POP.TOTL,427782,437938,460165,471597,482858,493799,504511,515239,526400,538219,550832,564039,577372,590208,602085,612836,622585,631636
-"Macao SAR, China",MAC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13261814737.2147,15120392779.3178,18703092519.2485,23491755347.2338,25893417735.2766,29016015488.1451,37781008038.107,35772886087.6703,36985305900.8053,46054934668.0489,55491749223.7671,60786996630.9249,68078848712.2094,69700477607.8845,59258610934.6941,59302303196.3941,66384362123.0823,71048761222.4765
-Madagascar,MDG,"Population, total",SP.POP.TOTL,15766806,16260932,17279141,17802997,18336724,18880269,19433530,19996473,20569117,21151640,21743967,22346641,22961253,23589887,24234088,24894380,25570540,26262368
-Madagascar,MDG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,17787981809.7922,19371452168.417,19187662545.1756,20664344516.4182,22343187384.259,24206345297.2602,26591230363.6127,29109530044.1563,28001757650.6127,28403846785.2973,29269019629.4989,30234305623.1348,31459323764.7446,33242122239.6743,34267948692.8519,36003225418.3941,38669145892.0113,41502374020.3303
-Malawi,MWI,"Population, total",SP.POP.TOTL,11148758,11432000,12000181,12301838,12625952,12973699,13341806,13727890,14128155,14539612,14962112,15396005,15839269,16289540,16745303,17205289,17670260,18143315
-Malawi,MWI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7675711837.3976,7465557035.92044,8358043220.1841,9045906269.5679,9655011699.94683,10429830333.778,11794246147.5378,12948987598.5105,14059005920.6046,15107228006.2224,16190322193.7146,16674059803.5724,17724330143.8248,19143990258.0733,19877664205.5886,21000772834.135,22350074266.6398,23679251738.4444
-Malaysia,MYS,"Population, total",SP.POP.TOTL,23194257,23709119,24698819,25190652,25690611,26201961,26720370,27236006,27735040,28208035,28650955,29068159,29468872,29866559,30270962,30684804,31105028,31528585
-Malaysia,MYS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,276511247597.855,286648241786.312,337396365587.509,370897824009.659,406000115629.869,448608785015.053,493689284107.513,522815482707.643,524162388641.605,562742398692.932,609984394638.503,646837213390.49,691621282361.017,747231627999.146,798092433362.512,840564720127.579,908209029994.026,964892167330.823
-Maldives,MDV,"Population, total",SP.POP.TOTL,279398,286306,302683,311265,319608,327487,335169,343452,353398,365734,380495,397237,415593,435015,454915,475513,496402,515696
-Maldives,MDV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2074724089.74808,2079421190.15457,2610105860.57456,2859849366.12669,2564550517.33916,3334540929.21807,3217434085.71816,3701329488.13027,3520151707.00356,3771091529.8934,4246953323.89474,4495964487.39301,4820801680.31486,5357002395.3425,5663753679.97491,6149402399.9939,6681140567.74926,7280531637.53956
-Mali,MLI,"Population, total",SP.POP.TOTL,10946445,11271600,11982695,12369070,12775516,13203378,13651464,14113577,14581429,15049353,15514591,15979499,16449864,16934220,17438778,17965429,18512394,19077690
-Mali,MLI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12637675755.258,14332743018.0601,16928889171.3409,17666936572.9257,19413471971.7199,20842129194.293,22384188440.6376,24012436341.3596,25317355585.235,26558297998.0927,28098046145.1435,28258107010.4343,29651213111.356,32536272274.1027,34996054071.3443,37271364470.4048,40235949676.2657,42628405044.2918
-Malta,MLT,"Population, total",SP.POP.TOTL,390087,393028,398582,401268,403834,405308,406724,409379,412477,414508,416268,420028,425967,434558,445053,455356,467999,483530
-Malta,MLT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7416730354.72626,7781719999.27636,8300802305.3859,8567727845.80559,8691934651.95767,9072505167.46522,9806526578.42836,10452871326.1673,10046638184.757,10922703876.2926,11518038385.1712,11865075995.8909,12660912764.5358,13938958432.6615,15241676974.8232,16000129601.1775,17642646378.4658,..
-Marshall Islands,MHL,"Population, total",SP.POP.TOTL,50753,51422,53456,54476,55258,55767,56051,56174,56250,56366,56531,56717,56938,57179,57439,57735,58058,58413
-Marshall Islands,MHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,159372263.682023,171375491.967875,176345019.337342,182160868.230212,194870432.571348,201190921.182381,213594156.504861,212486483.387177,209564508.968457,215837694.867121,224872243.117792,224896705.32908,242465313.505051,261405395.533568,286814875.242065,285170011.31744,297455656.308723,309152175.291262
-Mauritania,MRT,"Population, total",SP.POP.TOTL,2630219,2702400,2857148,2939247,3024194,3111906,3202517,3296238,3393409,3494195,3598648,3706554,3817494,3930896,4046301,4163534,4282574,4403319
-Mauritania,MRT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,5994593548.77092,6029468935.30645,7077234761.4822,7677067588.67896,8574548788.36373,9950092445.36214,10573370033.5039,11033118866.5592,11221261166.6747,11541482862.3094,12159105951.5901,13023658634.3721,14091672296.703,14961212131.0017,15487710279.0572,16180049720.71,17139712310.7015,18338304392.2712
-Mauritius,MUS,"Population, total",SP.POP.TOTL,1186873,1196287,1213370,1221003,1228254,1233996,1239630,1244121,1247429,1250400,1252404,1255882,1258653,1260934,1262605,1263473,1264613,1265303
-Mauritius,MUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,10617515621.3045,11286709556.8228,12468928483.4984,13399035861.7567,14074783217.0636,15336823736.3582,16984504942.1612,18065054709.5941,18593829589.8139,19344371280.1605,20348324460.3273,22656735233.8577,24779578454.9634,26210178363.5307,27617418147.7797,28902816684.7503,31103660910.6077,32941433788.2864
-Mexico,MEX,"Population, total",SP.POP.TOTL,98899845,100298153,103081020,104514932,106005203,107560153,109170502,110815271,112463887,114092963,115695473,117274155,118827161,120355128,121858258,123333376,124777324,126190788
-Mexico,MEX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1073235252932.68,1095604356342.78,1162592493945.24,1244336610909.76,1313762682229.57,1462385582249.25,1533815706563.18,1630569413184.12,1609779367702.41,1720422018790.8,1880967839882.46,1973881601912.17,2004429620594.39,2121554563909.1,2173135864192.38,2256695695490.18,2367563358669.2,2453499545623.9
-"Micronesia, Fed. Sts.",FSM,"Population, total",SP.POP.TOTL,107402,107173,106901,106625,106129,105371,104444,103543,102975,102911,103450,104506,105926,107446,108895,110215,111459,112640
-"Micronesia, Fed. Sts.",FSM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,273865306.482655,283292165.399691,298708944.111178,301010703.888955,318282975.271613,327591429.216848,331921205.890066,326769944.477178,343299138.252052,346621432.331691,363992378.548973,369353303.037803,372915897.687879,371488284.306122,433571286.999935,432601542.08109,453681439.751159,468875049.059012
-Moldova,MDA,"Population, total",SP.POP.TOTL,3639592,3631462,3612874,3603945,3595187,3585209,3576910,3570108,3565604,3562045,3559986,3559519,3558566,3556397,3554108,3551954,3549196,3545883
-Moldova,MDA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8273919638.3622,9394464931.84608,11730953414.5939,13069543152.5556,14366282349.6957,15479698584.2789,16012376377.5953,17676694162.009,16105054622.6774,17716757058.5917,19070103890.518,19762030868.5765,21950243919.4287,23318794667.5221,22873699879.5217,24105440442.0759,25744713174.265,27239259406.8586
-Monaco,MCO,"Population, total",SP.POP.TOTL,32147,32470,33153,33500,33843,34190,34525,34872,35226,35612,36024,36460,36901,37322,37718,38070,38392,38682
-Monaco,MCO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Mongolia,MNG,"Population, total",SP.POP.TOTL,2397418,2419588,2468762,2496391,2526424,2558856,2593820,2631898,2673796,2719896,2770362,2824699,2881792,2940108,2998439,3056359,3113779,3170208
-Mongolia,MNG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8840043328.25003,9328613613.55979,10756146158.1435,12239786618.9279,13332724148.9083,15033700186.4011,16838009172.1979,18543231594.3704,18222064352.5225,18830827982.8334,22505271782.4175,25907966118.9676,30095521824.0444,32212668337.3446,33305435938.7394,34050986842.8843,34214520546.7214,38730283154.5754
-Montenegro,MNE,"Population, total",SP.POP.TOTL,604950,607389,612267,613353,614261,615025,615875,616969,618294,619428,620079,620601,621207,621810,622159,622303,622373,622345
-Montenegro,MNE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3814904119.20082,4319603258.67465,4750999723.89398,5053918086.19129,5163052137.93945,6533002239.64013,7755118395.73308,8650203872.02627,8067633322.45214,8387152628.06267,9046278024.32469,8749518176.35713,9417544509.54189,9684825043.10986,10387006821.5362,11215578351.7613,12291909178.9014,..
-Morocco,MAR,"Population, total",SP.POP.TOTL,28793679,29126330,29782884,30115214,30455561,30804683,31163673,31536811,31929087,32343389,32781850,33241898,33715693,34192347,34663603,35126296,35581294,36029138
-Morocco,MAR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,102010825249.01,112002444659.838,127309722355.802,137522691076.474,147242457886.876,163004374672.501,173633392959.661,187768902967.097,194922130959.992,204722476904.136,219272498095.561,229426454360.794,245673549341.505,254452822995.977,270023803663.464,276208170402.192,292035730876.82,307917644907.411
-Mozambique,MOZ,"Population, total",SP.POP.TOTL,17711927,18221888,19331100,19910552,20493925,21080110,21673316,22276596,22894710,23531574,24187487,24862648,25560725,26286163,27042002,27829942,28649007,29495962
-Mozambique,MOZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7764008154.73268,8860708145.43318,10821137443.1884,11804290903.8941,13195412756.3488,14468111876.9882,16187632861.3213,17774921652.0909,19662755747.8563,21043557560.5127,23467220531.9072,25886687423.7055,28258643826.8721,30680589573.1927,32780627481.5208,34257053759.336,35938970153.8062,38325739237.233
-Myanmar,MMR,"Population, total",SP.POP.TOTL,46719701,47225120,48148902,48564484,48949924,49301050,49621475,49929642,50250367,50600818,50990615,51413698,51852451,52280807,52680726,53045226,53382581,53708395
-Myanmar,MMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,47904754328.5407,54474563913.5047,71911041827.1102,83873469554.4196,98204988183.5936,114430752945.893,131611960353.816,147923721579.978,164788848094.366,182777066086.485,197034773408.762,207016903785.437,230347100703.954,251222632100.564,273608118647.366,295225416037.595,319689147106.347,348267777660.622
-Namibia,NAM,"Population, total",SP.POP.TOTL,1794571,1823672,1879117,1907745,1938320,1971317,2006514,2043394,2081044,2118874,2156701,2194784,2233510,2273430,2314904,2358041,2402603,2448255
-Namibia,NAM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9599951926.47433,9846610950.33889,11701067394.1324,12987329785.4002,13351328384.0319,14843641575.3014,15580496587.9276,16341872671.5051,16472660655.5543,17319706741.9298,18802155661.2605,19861929395.2274,22085379921.4938,24045365505.8596,25717732943.7318,25935418136.5738,25946708005.2242,26743217645.4258
-Nauru,NRU,"Population, total",SP.POP.TOTL,10337,10215,9994,9902,9849,9828,9842,9891,9939,10005,10057,10279,10821,11853,12475,13049,12876,12704
-Nauru,NRU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,52318624.1842833,55355429.413001,66412206.8549804,75399514.6247926,82081790.6299374,99253045.105455,138270035.31654,187764643.676273,202552414.124231,228782945.422036,245712728.953084,247430858.537037
-Nepal,NPL,"Population, total",SP.POP.TOTL,23941110,24347106,25080872,25419344,25744500,26066693,26382581,26666576,26883535,27013212,27041437,26989862,26917906,26906926,27015031,27261131,27627124,28087871
-Nepal,NPL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29193952088.1698,31272964179.003,33499171097.0346,35948289241.3339,38585247704.4497,41287192744.9373,43957278828.3509,47525900164.5571,50165383327.5956,52971111624.854,55810345453.6615,59749932067.4397,63287990355.454,68954731000.9289,71965662508.5457,73110080061.9841,80123183958.0798,86766055438.168
-Netherlands,NLD,"Population, total",SP.POP.TOTL,15925513,16046180,16225302,16281779,16319868,16346101,16381696,16445593,16530388,16615394,16693074,16754962,16804432,16865008,16939923,17030314,17131296,17231017
-Netherlands,NLD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,516730737050.876,530132960173.846,559362955719.681,585811906174.302,605553877381.32,674915016939.327,718773191673.703,741916192385.952,729474044118.514,750559058860.995,788764031504.728,805602323121.561,838682680044.001,828263670286.029,852766433552.616,861382557874.013,936142168836.245,988728471393.01
-New Caledonia,NCL,"Population, total",SP.POP.TOTL,213230,217324,225296,228750,232250,235750,239250,242750,245950,249750,254350,259000,263650,268050,272400,276550,280350,284060
-New Caledonia,NCL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-New Zealand,NZL,"Population, total",SP.POP.TOTL,3857700,3880500,4027200,4087500,4133900,4184600,4223800,4259800,4302600,4350700,4384000,4408100,4442100,4509700,4595700,4693200,4793900,4885500
-New Zealand,NZL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,78307273345.7529,82896112656.6419,91935081407.6595,96741486060.1028,99289747947.8827,108362075586.43,115275210779.586,117980470098.457,126673091579.436,129216413916.087,137009721215.547,139353582322.271,154545145745.547,161245340209.477,166416913074.36,177711160689.378,186322763044.727,196617826030.157
-Nicaragua,NIC,"Population, total",SP.POP.TOTL,5069302,5145366,5292118,5364935,5438690,5513763,5590055,5667432,5745526,5824065,5903039,5982526,6062454,6142733,6223240,6303974,6384855,6465513
-Nicaragua,NIC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13234062434.0928,13843145732.2614,14917486850.825,16201452319.1247,17591219952.4595,18717691406.3282,20312150080.2265,21424134343.2137,20774682545.1085,21997130354.4595,23889868976.4057,25877921327.3473,27631179742.4444,29604210288.398,31332291498.2149,33127839244.8432,35356006181.0361,34871068838.5647
-Niger,NER,"Population, total",SP.POP.TOTL,11331557,11751365,12647984,13125916,13624467,14143971,14685399,15250908,15843133,16464025,17114761,17795191,18504255,19240157,20001663,20788838,21602472,22442948
-Niger,NER,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,6744389137.37875,7392613882.43327,8280292530.24133,8557754003.36708,9234685029.63312,10097541732.6818,10690394636.2713,11902316049.3128,11872418864.4991,12999311944.578,13570109302.3365,15289470053.825,16300688426.7988,17963106181.4506,18889341929.1776,20027049503.986,21401512143.8106,23023299169.8065
-Nigeria,NGA,"Population, total",SP.POP.TOTL,122283850,125394046,131900631,135320422,138865016,142538308,146339977,150269623,154324933,158503197,162805071,167228767,171765769,176404902,181137448,185960289,190873311,195874740
-Nigeria,NGA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,272237365304.707,305408365488.648,383889979119.231,431032971660.202,471233785317.813,546242686740.069,583662704421.514,633952854814.733,686562919481.372,747157588327.684,801705676642.964,858362337374.682,930244490066.291,1024812945686.1,1071013376452.98,1070483907138.51,1089408631299.67,1117357615381.16
-North Macedonia,MKD,"Population, total",SP.POP.TOTL,2034819,2042842,2053426,2057048,2060273,2063131,2065426,2067313,2069039,2070741,2072487,2074278,2076067,2077775,2079328,2080745,2081996,2082958
-North Macedonia,MKD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12236063852.3798,12225504142.035,13190902919.4165,14473693449.0636,15708191534.0353,17640679622.7456,18199312528.9794,21277065284.6007,22422006087.6806,23019910314.3112,23634676433.2941,24026918587.3653,25647335799.7619,27256445382.969,27852689323.7841,29596869469.0366,30587985821.7142,..
-Northern Mariana Islands,MNP,"Population, total",SP.POP.TOTL,57453,58321,57947,57246,56542,55882,55219,54625,54193,53971,54012,54311,54784,55305,55780,56188,56562,56882
-Northern Mariana Islands,MNP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Norway,NOR,"Population, total",SP.POP.TOTL,4490967,4513751,4564855,4591910,4623291,4660677,4709153,4768212,4828726,4889252,4953088,5018573,5079623,5137232,5188607,5234519,5276968,5314336
-Norway,NOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,163770504415.98,170709729197.097,176973690998.335,195461164599.457,223283670197.81,252226786011.118,262412431409.036,293138235484.347,269175461487.219,286431243846.263,310701643205.307,331152578513.979,344244308199.849,349842613934.341,327034783599.997,317190195930.174,341753036923.303,352806336064.975
-Oman,OMN,"Population, total",SP.POP.TOTL,2267973,2294962,2386166,2445517,2511251,2580758,2657158,2750963,2876186,3041434,3251108,3498029,3764805,4027260,4267348,4479219,4665935,4829483
-Oman,OMN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,76283995660.358,81639141689.4553,81915434447.1139,86072244892.9401,89183913382.4279,89919769043.441,105477843075.077,113743500323.404,119697824073.202,126815582623.35,128052701201.132,143101833937.005,155059396184.617,159802582988.165,175204865563.217,186721282734.978,189867271106.12,199129993013.676
-Pakistan,PAK,"Population, total",SP.POP.TOTL,142343578,145978402,153093373,156664697,160304008,164022627,167808105,171648986,175525609,179424641,183340592,187281475,191262919,195306825,199426964,203627284,207896686,212215030
-Pakistan,PAK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,380414596368.088,396302237157.834,463599143835.025,506665049113.847,561744793404.374,613026119699.131,659148244378.884,685135435873.558,714498766609.023,742921165303.42,784383239309.486,832836990634.807,884900125558.411,948146857713.489,1007691153841.51,1075305111567.42,1150857602740.17,1238655718492.63
-Palau,PLW,"Population, total",SP.POP.TOTL,19105,19386,19809,19867,19781,19540,19158,18704,18285,17955,17745,17640,17606,17626,17665,17725,17808,17907
-Palau,PLW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,173413557.025324,188508988.13951,199579454.576896,218349988.939459,242651950.848121,238875786.456385,248185736.216059,234956338.382056,236297200.545431,238010632.943729,257474030.810622,267939252.910452,259794738.458722,280628664.342167,302761816.939988,312943012.969342,313253091.031982,337001831.266009
-Panama,PAN,"Population, total",SP.POP.TOTL,3030328,3089648,3209048,3269356,3330217,3391666,3453675,3516204,3579215,3642687,3706483,3770624,3835437,3901315,3968487,4037078,4106771,4176873
-Panama,PAN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,24617236333.936,25167687790.4057,27803738205.8466,30218367611.6983,33275968165.8457,37285308381.053,42382458725.1339,47800780271.9796,48550680173.3423,50664513340.7021,59623957560.3279,66256672071.4167,71406876954.0465,74409207116.9117,79521692323.7662,84328335987.2376,91132004593.2409,98209495824.7493
-Papua New Guinea,PNG,"Population, total",SP.POP.TOTL,5847586,5974629,6223377,6354245,6494903,6646895,6808514,6976201,7144776,7310507,7472200,7631002,7788379,7946731,8107775,8271760,8438029,8606316
-Papua New Guinea,PNG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,11415714885.1077,11417153953.2986,11603412689.3502,12533849227.3034,14111808452.9516,14433547778.0271,16858638313.14,17509587093.666,18874284567.7519,20433885499.141,21528235915.6271,22921528062.1084,22885506360.5583,29131887801.4752,32371739387.867,34024536289.4017,34947446232.5309,35686201002.1286
-Paraguay,PRY,"Population, total",SP.POP.TOTL,5323201,5428444,5632983,5730549,5824096,5913209,5998427,6081296,6163972,6248020,6333976,6421512,6510276,6599526,6688746,6777872,6867062,6956071
-Paraguay,PRY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29566734715.991,30548438942.8955,31465899563.8046,34257928507.6827,36296493301.7347,40524409849.0054,45944518023.2786,50423143771.835,50502917058.4348,56781915635.9032,61234461362.9057,61551132363.3546,68120922210.6357,73054362969.0075,76017250450.8179,79908793399.4092,86329284684.2607,91673690186.5964
-Peru,PER,"Population, total",SP.POP.TOTL,26459944,26799285,27372226,27624213,27866145,28102056,28333052,28562317,28792655,29027674,29264318,29506788,29773987,30090359,30470734,30926032,31444297,31989256
-Peru,PER,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,132311065806.754,136898967225.551,153154594809.028,161871902838.188,175238918143.11,190272895163.564,212837005886.272,238926210073.83,245136398715.501,265434336951.343,288011099798.528,315202339931.674,343655000797.249,360875207358.153,380941499360.719,397350638004.847,413067177906.791,441729721115.06
-Philippines,PHL,"Population, total",SP.POP.TOTL,77991755,79672873,83051971,84710542,86326250,87888675,89405482,90901965,92414158,93966780,95570047,97212638,98871552,100513138,102113212,103663927,105173264,106651922
-Philippines,PHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,307266905874.579,325644530880.963,366464266539.535,400660232558.19,435530290054.878,469124496785.035,510438160400.225,543507816982.147,572567297191.892,619360884922.166,651365770270.708,712508653943.462,782590070514.536,844227037625.567,903327817907.275,971348273329.357,1054684160650.47,1143475479908.14
-Poland,POL,"Population, total",SP.POP.TOTL,38258629,38248076,38204570,38182222,38165445,38141267,38120560,38125759,38151603,38042794,38063255,38063164,38040196,38011735,37986412,37970087,37974826,37978548
-Poland,POL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,405837268783.226,423263782652.58,463748003006.976,493170877112.912,521089422492.564,565363690053.952,618483086700.698,685875316122.792,712241133620.83,772076263228.14,838338447805.736,873280227684.715,908791205672.954,937524545282.722,983075896937.794,1011543377920.57,1089328331985.86,1181683639597.3
-Portugal,PRT,"Population, total",SP.POP.TOTL,10289898,10362722,10458821,10483861,10503330,10522288,10542964,10558177,10568247,10573100,10557560,10514844,10457295,10401062,10358076,10325452,10300300,10281762
-Portugal,PRT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,190642521300.286,198431114549.93,215235219375.429,221775640807.786,235163261619.338,251189099608.159,262377471649.97,270235611838.754,269489654831.545,279021597568.569,277286324614.859,271419092894.261,287821374657.946,293878003275.358,299027088356.504,313124513364.535,327996402375.673,341311554070.018
-Puerto Rico,PRI,"Population, total",SP.POP.TOTL,3810605,3818774,3826095,3826878,3821362,3805214,3782995,3760866,3740410,3721525,3678732,3634488,3593077,3534874,3473166,3406495,3325001,3195153
-Puerto Rico,PRI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,63110527870.4644,65008338839.8526,67711280858.8863,76894233182.4255,78743928423.7732,81097374980.9148,84108128240.9035,83198037782.9508,81018565089.8033,80818766544.2656,82384682729.5865,85972407212.1532,87550251997.3456,87959882648.7313,88195802406.3875,87703351105.7796,87085696075.7118,84860222430.7098
-Qatar,QAT,"Population, total",SP.POP.TOTL,592468,615012,681788,753334,865416,1022711,1218434,1436665,1654950,1856327,2035871,2196074,2336574,2459198,2565710,2654374,2724724,2781677
-Qatar,QAT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,47029745913.7751,52030807570.4577,61247174618.6688,70942487715.4779,73750406204.5297,104057603622.712,126164839679.596,150461039511.636,162958609476.022,195585487769.004,232525547675.419,251919641445.884,271293954342.382,289563538552.867,310688350704.823,325612488601.927,338672704408.003,345284638402.724
-Romania,ROU,"Population, total",SP.POP.TOTL,22442971,22131970,21574326,21451748,21319685,21193760,20882982,20537875,20367487,20246871,20147528,20058035,19983693,19908979,19815481,19702332,19587491,19473936
-Romania,ROU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,130343921116.754,143428551191.977,159111162645.822,184591741299.765,198699851308.829,236507598260.514,276575612214.484,336010559834.82,333675769775.451,338278063140.017,354760744636.693,373162401068.813,387062772540.858,405392968242.733,418649937601.288,457928719559.42,508054887689.337,..
-Russian Federation,RUS,"Population, total",SP.POP.TOTL,146596557,145976083,144648257,144067054,143518523,143049528,142805088,142742350,142785342,142849449,142960868,143201676,143506911,143819666,144096870,144342396,144496740,144478050
-Russian Federation,RUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,974629347999.371,1059732532867.18,1297685806670.6,1441505984835.48,1655585941894.52,2071121854636.68,2324721058626.26,2797649362802.82,2678612246973.08,2836588884248.56,3373072144878.87,3579360949693.82,3635166063636.87,3637938277083.81,3425169707911.52,3433083740516.52,3682841546246.9,3886717268560.01
-Rwanda,RWA,"Population, total",SP.POP.TOTL,7933681,8231156,8557161,8680524,8840215,9043337,9273757,9524534,9782770,10039338,10293331,10549678,10811543,11083635,11369071,11668818,11980937,12301939
-Rwanda,RWA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,5028800937.88533,5550298210.85677,6626255304.95316,7313992993.5446,8291933560.4003,9337794176.11331,10377191933.6109,11727112538.1117,12559007315.0086,13630337776.9131,14979823165.0363,16538899546.978,17537385277.7867,19144211206.6161,21025790743.5166,22509785473.3452,24399374004.2019,27136999372.655
-Samoa,WSM,"Population, total",SP.POP.TOTL,174454,175392,177484,178590,179727,180876,182046,183263,184556,185949,187469,189088,190717,192221,193513,194535,195352,196130
-Samoa,WSM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,687891532.523661,742703931.816799,791412817.828341,836255353.570398,917622569.975988,943859412.455098,918834268.141881,954480504.334988,1023455876.63548,1051884135.26276,1048945739.50976,1080511751.8989,1127517805.08547,1217049046.39002,1262918752.22524,1298464125.90263
-San Marino,SMR,"Population, total",SP.POP.TOTL,27462,27812,28562,28940,29324,29700,30063,30434,30816,31229,31661,32105,32553,32948,33272,33504,33671,33785
-San Marino,SMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Sao Tome and Principe,STP,"Population, total",SP.POP.TOTL,142262,144755,150415,153737,157472,161681,166300,171120,175876,180371,184524,188404,192087,195727,199432,203227,207089,211028
-Sao Tome and Principe,STP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,222725685.505551,255842515.580943,272139585.118446,302242117.540873,354597598.259078,379196214.738748,405880831.80304,418424162.651445,453578787.233489,483633760.429585,497239655.961804,544987670.177864,596234707.196571,613460754.676843,649919979.161183,684002632.49163,724355990.336117
-Saudi Arabia,SAU,"Population, total",SP.POP.TOTL,20663843,21202642,22456649,23132682,23816183,24498310,25184597,25888541,26630303,27421461,28267685,29155187,30052518,30916994,31717667,32442572,33099147,33699947
-Saudi Arabia,SAU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,715027078085.935,725401346914.642,806419345955.473,896900151496.543,977955856483.062,1037607231515.14,1090750615872.03,1184084855036.63,1171416111047.43,1236491758373.8,1390008608968.98,1494069835614.45,1566298505766.78,1660211841410.18,1754667365922.02,1799929798354.06,1804815255232.94,1875395761287.99
-Senegal,SEN,"Population, total",SP.POP.TOTL,9797734,10036104,10541467,10810083,11090116,11382268,11687080,12004701,12335084,12678148,13033809,13401991,13782420,14174731,14578459,14993528,15419381,15854360
-Senegal,SEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18562402626.4463,19892716322.0909,22141595365.7388,24120438459.5496,26289892248.3954,27829730344.4734,29994189755.8527,31892890780.9432,32557745169.4623,34151872959.6453,35141864992.7798,37604256123.1945,39339330785.1955,42644878052.2165,45707326046.7718,48935774935.213,53309901826.6201,58141537237.0997
-Serbia,SRB,"Population, total",SP.POP.TOTL,7516346,7503433,7480591,7463157,7440769,7411569,7381579,7350222,7320807,7291436,7234099,7199077,7164132,7130576,7095383,7058322,7020858,6982084
-Serbia,SRB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,43038071972.5298,46076898125.2704,53500701805.4094,59663244715.1845,67521965480.3202,74624622026.0803,81286836385.3215,90438303309.8633,90355638492.0918,91320875216.673,97317351470.9349,97051140117.2252,100741107826.015,100573330094.5,100963137996.871,104148505796.327,107809144178.294,..
-Seychelles,SYC,"Population, total",SP.POP.TOTL,81131,81202,82781,82475,82858,84600,85033,86956,87298,89770,87441,88303,89949,91359,93419,94677,95843,96762
-Seychelles,SYC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1130040472.51602,1156473295.75382,1101211704.80475,1183052056.50651,1329012962.31028,1497299651.4751,1563629594.30702,1533562018.71259,1561026670.28986,1690587174.47586,1835493986.51847,1920513227.11824,2073252787.60011,2185436714.50922,2330151800.08164,2419602232.03578,2576139447.37754,2812831725.39246
-Sierra Leone,SLE,"Population, total",SP.POP.TOTL,4584571,4754072,5201070,5433991,5645624,5829237,5989633,6133603,6272734,6415634,6563240,6712581,6863980,7017144,7171914,7328838,7488431,7650154
-Sierra Leone,SLE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3212015673.61562,3093804179.48975,4448301801.64614,4856126881.89251,5228361116.37041,5632574708.82399,6688886833.14579,7384809159.02604,7736233095.55139,7675560429.50167,8124629823.32337,9983644365.54614,11816553927.3429,12357594121.6436,10021603553.8153,9711990378.56826,11225289124.7576,11649248742.0068
-Singapore,SGP,"Population, total",SP.POP.TOTL,4027887,4138012,4114826,4166664,4265762,4401365,4588599,4839396,4987573,5076732,5183688,5312437,5399162,5469724,5535002,5607283,5612253,5638676
-Singapore,SGP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,166786994835.372,168525749847.204,185622195444.804,202045222805.602,224600922762.136,260111505022.112,291441235894.44,299403373313.377,297320545558.469,359395846514.951,380595114593.581,400912679585.028,423387410598.2,457261400731.951,459041115688.593,477097148685.861,504191316889.121,532874932442.445
-Sint Maarten (Dutch part),SXM,"Population, total",SP.POP.TOTL,30519,30600,31472,32488,33011,33441,33811,33964,34238,34056,33435,34640,36607,37685,38825,39969,40574,40654
-Sint Maarten (Dutch part),SXM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,1050471795.71762,1095375487.5315,1169642633.22038,1214932496.3034,1265517172.41925,1281607844.62052,1295959821.65772,1331696352.27259,..,..
-Slovak Republic,SVK,"Population, total",SP.POP.TOTL,5388720,5378867,5373374,5372280,5372807,5373054,5374622,5379233,5386406,5391428,5398384,5407579,5413393,5418649,5423801,5430798,5439232,5447011
-Slovak Republic,SVK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,60878240594.602,66560523575.0346,72182735695.5029,78339548639.5647,86800343536.12,98320841108.7014,110380551616.639,125077405429.544,123364618193.176,131564298602.343,134396744120.836,141334374541.664,149610025166.76,154769445337.157,156995390879.843,164646665730.209,172573528282.663,183019215742.057
-Slovenia,SVN,"Population, total",SP.POP.TOTL,1988925,1992060,1995733,1997012,2000474,2006868,2018122,2021316,2039669,2048583,2052843,2057159,2059953,2061980,2063531,2065042,2066388,2067372
-Slovenia,SVN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,35811112904.9107,37726264664.393,41725666116.1914,44847489163.8984,47449318593.426,51051764902.5015,54429002733.8643,58308080449.4871,55108934487.4501,56066453379.6483,58323557222.3024,58528575642.7645,60556023217.8819,63021879513.8337,63261512455.9346,66722547671.2003,73355374944.8381,78665817256.0743
-Solomon Islands,SLB,"Population, total",SP.POP.TOTL,412660,423944,447017,458539,469918,481078,492132,503360,515181,527861,541521,556064,571335,587079,603118,619437,636038,652858
-Solomon Islands,SLB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,597042722.094692,564444259.10272,599190484.836551,653597296.222304,706272880.009252,782325074.041119,793884366.73137,788273460.495396,648372857.135353,705271648.238904,806095347.634751,1043039413.06714,1162171492.47891,1220489336.37122,1309260650.02284,1328179237.93601,1378229349.15824,1488554995.92136
-Somalia,SOM,"Population, total",SP.POP.TOTL,8872254,9186725,9815412,10130243,10446863,10763905,11080121,11397188,11717692,12043883,12376302,12715510,13063706,13423576,13797201,14185613,14589119,15008154
-Somalia,SOM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-South Africa,ZAF,"Population, total",SP.POP.TOTL,44967708,45571274,46719196,47291610,47880601,48489459,49119759,49779471,50477011,51216964,52004172,52834005,53689236,54545991,55386367,56203654,57000451,57779622
-South Africa,ZAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,339038714212.139,353103767410.159,391835826058.322,423926533545.353,460054016648.078,500671933036.669,534107180375.945,562707576285.645,563340719609.082,587871679526.887,617169274162.823,641889866600.465,670031361682.697,694979468341.252,712795969722.202,722495117256.704,744150305035.439,764274746876.32
-South Sudan,SSD,"Population, total",SP.POP.TOTL,6199394,6447793,6935676,7213351,7535932,7907406,8315139,8736939,9142259,9508364,9830698,10113647,10355036,10554883,10715658,10832512,10910759,10975920
-South Sudan,SSD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,23408770628.8712,19134728365.1381,21256663094.279,21581062744.0566,20027566142.8048,16758778832.8953,..,..
-Spain,ESP,"Population, total",SP.POP.TOTL,40567864,40850412,42187645,42921895,43653155,44397319,45226803,45954106,46362946,46576897,46742697,46773055,46620045,46480882,46444832,46483569,46593236,46723749
-Spain,ESP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,870339079278.909,926012841387.855,1048509023741.43,1113376833108.53,1191810871361.96,1344294825594.73,1438612883601.28,1496522755014.04,1474196731395.77,1466033546910.38,1472969169435.77,1485648425269.36,1512101363366.92,1561678787485.34,1622470138226.38,1708196861360.75,1816892534659.95,1908425782274.45
-Sri Lanka,LKA,"Population, total",SP.POP.TOTL,18777601,18911730,19224037,19387153,19544988,19695972,19842044,19983984,20123508,20261737,20398670,20425000,20585000,20778000,20970000,21203000,21444000,21670000
-Sri Lanka,LKA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,81231731001.7837,81845586893.3426,94108861425.2964,101818045285.657,111279704785.342,123250682051.474,135553322946.861,144502858287.468,152652820998.826,166922138704.492,184899504319.22,204066421101.056,213423870287.922,228432858317.209,241865358317.728,255072385398.301,268906141542.722,283553944760.855
-St. Kitts and Nevis,KNA,"Population, total",SP.POP.TOTL,44074,44599,45746,46324,46857,47339,47778,48185,48599,49016,49447,49887,50331,50774,51203,51625,52045,52441
-St. Kitts and Nevis,KNA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,717605715.282215,771064068.325787,774670017.299226,842871790.597918,966440760.648414,1037411439.47025,1071970364.17649,1163375693.99179,1131377359.19286,1135019924.02587,1181669934.0039,1204508205.08158,1309285362.98676,1333478713.24897,1383406059.09471,1443281927.82908,1505168355.96279,1579326417.0023
-St. Lucia,LCA,"Population, total",SP.POP.TOTL,156729,158179,160530,161816,163417,165381,167639,170011,172221,174085,175544,176646,177513,178296,179126,180024,180955,181889
-St. Lucia,LCA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1180310583.89127,1146421989.88097,1245245054.46002,1353995039.62696,1392150585.59261,1676299704.61545,1747428141.79681,1864242209.71027,1891417795.40332,1933271263.94371,2085626540.52268,2093137479.7437,2117457120.35477,2032294137.71285,2004809882.1399,2165554802.31558,2309176736.07982,2358987376.63006
-St. Martin (French part),MAF,"Population, total",SP.POP.TOTL,28935,29853,32053,33186,34248,35237,36137,36885,37377,37582,37446,37009,36453,36015,35858,36065,36560,37264
-St. Martin (French part),MAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-St. Vincent and the Grenadines,VCT,"Population, total",SP.POP.TOTL,107784,107896,108326,108512,108614,108603,108518,108393,108287,108255,108316,108435,108622,108861,109148,109459,109827,110210
-St. Vincent and the Grenadines,VCT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,617277633.21013,648367408.749169,759215129.009289,805897389.245346,854319319.480292,959550903.434341,978148616.500377,1064662788.54208,1064995229.22257,1042604944.47307,1058714670.73699,1109137452.21251,1125774152.2779,1211823306.35394,1340166695.55457,1339804965.08149,1369323786.76058,1456393997.60871
-Sudan,SDN,"Population, total",SP.POP.TOTL,27275015,27971082,29460519,30214193,30949516,31661823,32360621,33060837,33783788,34545013,35349681,36193783,37072550,37977655,38902950,39847440,40813396,41801533
-Sudan,SDN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,58204598494.1571,62717111892.7847,73440248976.7778,78472120960.0788,87406101784.5942,100377799364.389,113954521966.819,125473615444.848,129516478874.195,135121347373.573,140669381805.509,137689646920.219,99543400929.5034,150880174180.657,161019855428.19,169817606644.374,182050561921.82,184812195498.885
-Suriname,SUR,"Population, total",SP.POP.TOTL,470949,476579,487942,493679,499464,505295,511181,517123,523111,529131,535179,541245,547291,553273,559143,564888,570496,575991
-Suriname,SUR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3487018727.62043,3411968012.55991,4251609002.36723,4716785630.40814,5187159003.676,5667495816.22412,6240562581.99931,6670094091.66944,6892514352.09145,7149055549.66979,7445199966.48529,7962873754.58475,8454454231.11553,8743490839.39209,8627571864.68756,7801864055.28579,7285079482.71772,7732438168.09743
-Sweden,SWE,"Population, total",SP.POP.TOTL,8872109,8895960,8958229,8993531,9029572,9080505,9148092,9219637,9298515,9378126,9449213,9519374,9600379,9696110,9799186,9923085,10057698,10183175
-Sweden,SWE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,260292854412.149,264225381059.931,287088129924.05,303595516995.513,311259347061.803,349055863199.825,382859381220.805,399729535962.354,377875126472.825,401175334832.15,422540394991.34,436106779523.148,448963505391.745,461209989858.064,479473809784.176,490412896873.017,524923424628.347,549781346877.935
-Switzerland,CHE,"Population, total",SP.POP.TOTL,7184250,7229854,7339001,7389625,7437115,7483934,7551117,7647675,7743831,7824909,7912398,7996861,8089346,8188649,8282396,8373338,8451840,8516543
-Switzerland,CHE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,273950109496.662,276465060981.54,294963563483.934,307426397098.295,327059401274.082,362758817325.499,377924536160.99,375881421641.219,408518497645.874,439637085444.547,449676395959.064,472965119580.052,496497257704.326,509076701038.649,542121799886.034,541546466635.944,552518795011.746,589517252051.173
-Syrian Arab Republic,SYR,"Population, total",SP.POP.TOTL,16410848,16766561,17415214,17827825,18361176,19059258,19878254,20664038,21205873,21362529,21082966,20442541,19584274,18715672,17997408,17453933,17068002,16906283
-Syrian Arab Republic,SYR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-Tajikistan,TJK,"Population, total",SP.POP.TOTL,6216341,6318513,6541547,6662389,6789321,6922587,7062672,7209930,7364753,7527394,7697510,7874835,8059769,8252833,8454028,8663579,8880268,9100837
-Tajikistan,TJK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,5616711696.84365,6257582059.0158,7867604500.35423,9117453924.84111,10056499174.174,11069899096.7866,12411002384.4993,13832695517.3304,14421351026.6284,19475989946.3203,22041323704.1279,24175222758.1379,27527118638.9227,28199381049.3682,28792579571.914,30589305252.138,32898638764.0078,36803752386.7329
-Tanzania,TZA,"Population, total",SP.POP.TOTL,33499180,34385856,36337782,37379767,38450320,39548663,40681414,41853944,43073834,44346525,45673338,47052481,48482266,49959822,51482633,53050790,54663906,56318348
-Tanzania,TZA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,40131263164.2706,42890967017.4586,51260374827.9552,56532928080.5228,62301972662.4298,69639969981.9492,75457683612.8265,81436994687.305,86469735714.9226,92287061442.5689,101382077998.843,108433518875.264,117702796605.002,127866407214.704,136847491706.678,147347550142.609,160259345083.565,172644497888.404
-Thailand,THA,"Population, total",SP.POP.TOTL,62952642,63539196,64549866,64995299,65416189,65812536,66182067,66530984,66866839,67195028,67518382,67835957,68144501,68438730,68714511,68971331,69209858,69428524
-Thailand,THA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,451283702840.35,473052313029.769,549513025914.586,598187297135.216,641715816482.417,699548696696.576,759856396711.913,786016710555.066,787702816639.472,850674941293.243,891983915185.034,953255445289.917,977159884690.597,1018838162769.1,1061851114398.43,1114754047934.98,1184686898226.15,1261083617625.96
-Timor-Leste,TLS,"Population, total",SP.POP.TOTL,884366,901214,947108,971893,995135,1016432,1036392,1055431,1074277,1093523,1113151,1132994,1153295,1174331,1196302,1219288,1243261,1267972
-Timor-Leste,TLS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3066262141.77418,3329603441.66001,3208410665.01415,2608107795.30357,2695791703.29278,4123924732.23076,6227822907.50796,7620466547.61641,7625361551.99389,8051089483.19185,8875837189.7171,7657562962.62111,7842321791.69017,6633140820.71888,8841911079.17208,9007130427.468,8397550542.78817,8867293994.48867
-Togo,TGO,"Population, total",SP.POP.TOTL,4924402,5062567,5330639,5467766,5611640,5762880,5920359,6083420,6250835,6421679,6595943,6773807,6954721,7137997,7323158,7509952,7698475,7889094
-Togo,TGO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4746988526.01444,4770513430.40532,5178364347.87939,5409771619.23566,5640859747.15146,6043144705.06634,6377973278.71089,6812889958.68794,7236961060.24104,7758514395.16101,8997810959.96775,9228336453.33507,10007045002.6137,10845638359.1361,11861370721.2505,12291346174.8177,12968144782.5965,13874399525.314
-Tonga,TON,"Population, total",SP.POP.TOTL,97973,98487,99589,100218,100905,101706,102581,103379,103890,103986,103562,102737,101768,101028,100781,101133,101998,103197
-Tonga,TON,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,357784199.307633,377866597.727289,419272791.528134,430706598.862551,445193709.255631,463102117.302958,458561607.979409,480222408.822255,500093429.136062,524842935.728248,548648424.397204,564662549.708014,554335176.245479,566434537.234914,595653508.203939,620025178.093263,654945658.3823,671334890.179322
-Trinidad and Tobago,TTO,"Population, total",SP.POP.TOTL,1267153,1271632,1283559,1290123,1296502,1302561,1308451,1314443,1320930,1328147,1336178,1344817,1353700,1362342,1370328,1377564,1384072,1389858
-Trinidad and Tobago,TTO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,17063783146.5871,18479180938.9587,23640091953.1461,27051783646.6118,29024713064.6748,33765881285.5085,36600614721.0584,38606616565.3602,36842674421.7033,38686808501.7608,36805736895.769,38927371182.6903,41793944640.6051,41951847664.019,45602103500.0885,42914629945.5215,43833081066.4904,44558094284.6672
-Tunisia,TUN,"Population, total",SP.POP.TOTL,9708350,9793903,9945277,10022277,10106771,10201214,10304726,10414433,10525694,10635244,10741880,10847002,10952951,11063201,11179949,11303946,11433443,11565204
-Tunisia,TUN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,55874653480.8964,59444943584.9895,65472551480.1344,71282291341.216,75216530469.8522,81962829758.4308,89074239337.9617,94213875881.3911,98887456919.5009,103665263133.272,103777406437.032,110558871563.759,115457701288.41,122252854745.413,125649679137.34,129010325482.275,133382093298.423,139437407211.764
-Turkey,TUR,"Population, total",SP.POP.TOTL,63240194,64192243,66089402,67010930,67903469,68756810,69581848,70418604,71321399,72326988,73443863,74653016,75928564,77231907,78529409,79821724,81101892,82319724
-Turkey,TUR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,597194480777.628,576770257410.937,623403566203.274,717658274429.54,798582176668.912,926423152215.623,1023644289517.37,1119242568656.94,1091637399326.7,1249722041104.58,1430728379426.73,1527509826303.98,1675523371057.61,1834768262142.98,1989688670333.99,2065177040421.12,2231683996936.37,2335891857745.33
-Turkmenistan,TKM,"Population, total",SP.POP.TOTL,4516133,4564083,4655743,4703401,4754646,4810109,4870141,4935767,5007954,5087213,5174085,5267900,5366375,5466328,5565287,5662372,5757669,5850908
-Turkmenistan,TKM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,17995828773.5322,19829653440.6324,21607205861.5466,23237124635.2335,25604577781.7961,29541576895.1685,34842921623.3447,39694640317.475,42059204115.3116,45389111073.3959,52404098571.8364,59471193613.567,67243320645.3257,75327130249.2869,83896500237.0947,93145567321.2999,99514725506.7201,107998142279.311
-Turks and Caicos Islands,TCA,"Population, total",SP.POP.TOTL,20164,21573,25011,26700,28180,29391,30385,31202,31934,32660,33377,34066,34731,35369,35981,36559,37115,37665
-Turks and Caicos Islands,TCA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,739208799.015112,791603965.497346,836301132.697549,870903710.245997,924247506.254097
-Tuvalu,TUV,"Population, total",SP.POP.TOTL,9394,9484,9726,9869,10000,10120,10221,10314,10424,10530,10633,10739,10857,10972,11099,11225,11370,11508
-Tuvalu,TUV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,44816713.8307151,39423211.9666701,44008233.8177605,44010714.0272282,44669035.2114286,52633356.120253,52851720.347888,54738734.1186393,49291845.54984,50436773.521359,43459568.1162693,54547258.7193721,48534841.9572943,63000995.29202,63492051.2981101,63480552.6312282,70026777.9863552
-Uganda,UGA,"Population, total",SP.POP.TOTL,23650172,24388968,25980552,26821297,27684585,28571475,29486338,30431736,31411096,32428167,33476919,34559168,35695246,36912148,38225453,39647506,41162465,42723139
-Uganda,UGA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,19732383544.7386,20917812976.4608,25320235179.1238,27593443638.7927,30179770024.2155,34607073932.2648,38752364028.8124,42992717000.3962,46328477998.4323,49517211875.1275,55370715714.0034,58334813062.0023,61413436958.8149,65691305456.3805,70135540030.1019,74169884040.4857,78179776479.0386,84120132480.5213
-Ukraine,UKR,"Population, total",SP.POP.TOTL,49175848,48683865,47812950,47451600,47105150,46787750,46509350,46258200,46053300,45870700,45706100,45593300,45489600,45271947,45154029,45004645,44831135,44622516
-Ukraine,UKR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,182072492832.991,205824005600.269,246961108216.491,284111016778.532,302009955387.397,332759661169.771,368074483732.517,386328007065.453,327715414234.499,346378307650.733,369725094277.308,380182095141.185,386744692746.068,370198321926.394,337410409059.683,350194278767.123,359434925554.07,381130336464.312
-United Arab Emirates,ARE,"Population, total",SP.POP.TOTL,3134062,3302719,3711932,4068570,4588225,5300174,6168838,7089487,7917372,8549988,8946777,9141596,9197910,9214175,9262900,9360980,9487203,9630959
-United Arab Emirates,ARE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,270242667599.528,280093094632.057,307756311720.631,348086541069.833,380547512895.163,432900052128.142,463684570499.24,478150719176.58,455747333779.102,463507876122.492,506316326003.741,539427339215.772,578506553034.284,613900012254.438,653992484368.492,681583821989.914,700994461992.456,725234231707.214
-United Kingdom,GBR,"Population, total",SP.POP.TOTL,58892514,59119673,59647577,59987905,60401206,60846820,61322463,61806995,62276270,62766365,63258918,63700300,64128226,64613160,65128861,65595565,66058859,66488991
-United Kingdom,GBR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1552125294884.13,1638390131222.71,1820054546759.49,1926984154650.84,1989351614357.44,2104804714785.05,2161203171043.66,2230618605625.55,2149068637946.38,2261925476186.07,2338452408604.47,2389589159020.23,2481085885899.71,2586417808729.12,2676110144215.84,2748394004282.66,2910875444407.31,3035742387684.41
-United States,USA,"Population, total",SP.POP.TOTL,282162411,284968955,290107933,292805298,295516599,298379912,301231207,304093966,306771529,309326085,311580009,313874218,316057727,318386421,320742673,323071342,325147121,327167434
-United States,USA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,10383859000000,10743709000000,11530268000000,12313988000000,13169702000000,14072966000000,14543216000000,14684602000000,14398708000000,15126736000000,15832207000000,16670651000000,17175898000000,18062432000000,18700478000000,19049435000000,19872232000000,20738399000000
-Uruguay,URY,"Population, total",SP.POP.TOTL,3319736,3325473,3323668,3321476,3321803,3325401,3331749,3340221,3349676,3359275,3368934,3378974,3389439,3400434,3412009,3424132,3436646,3449299
-Uruguay,URY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,33927712317.2044,33327120691.8604,30867334852.4273,33199602522.5985,37340746298.4527,40315016314.1386,44113794682.749,47817999407.611,50075569089.2715,54357702760.8174,58558594372.8545,59350552262.5048,64464340387.3184,67120595545.5464,69425897371.4788,71036907660.1062,73460303105.1559,75547716669.6862
-Uzbekistan,UZB,"Population, total",SP.POP.TOTL,24650400,24964450,25567650,25864350,26167000,26488250,26868000,27302800,27767400,28562400,29339400,29774500,30243200,30757700,31298900,31847900,32388600,32955400
-Uzbekistan,UZB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,48635223892.606,51662869159.4908,58316569444.3101,64826910518.5812,71663116363.2661,79060176222.7707,93060930669.2329,105080292797.382,110984250184.11,122243219889.066,136295408676.256,150970348121.118,167821848139.923,180201974897.96,191860837851.123,204483734624.537,219626679050.298,238335475647.897
-Vanuatu,VUT,"Population, total",SP.POP.TOTL,184972,189219,198959,204127,209282,214370,219472,224704,230247,236211,242653,249499,256635,263888,271130,278330,285510,292680
-Vanuatu,VUT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,395845637.995294,403652721.333649,399573849.218806,425394093.205076,454841786.626822,518923916.182845,556611911.565058,637642070.41798,643469996.481578,657929082.677382,684302150.005901,686703133.695767,754198448.017536,791353492.972593,775558828.856362,826169514.857148,878783296.543725,924015342.200343
-"Venezuela, RB",VEN,"Population, total",SP.POP.TOTL,24192446,24646472,25551624,25996594,26432447,26850194,27247610,27635832,28031009,28439940,28888369,29362449,29783571,30045134,30081829,29846179,29390409,28870195
-"Venezuela, RB",VEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,277520368039.487,291862603179.054,251406204671.029,303860229304.044,351328246706.003,401591261263.823,455701484920.927,485017855005.818,468236198904.863,464636976153.772,487696163869.793,524373119462.894,537842486515.487,537773535522.688,..,..,..,..
-Vietnam,VNM,"Population, total",SP.POP.TOTL,79910412,80742499,82301656,83062821,83832661,84617540,85419591,86243413,87092252,87967651,88871561,89802487,90753472,91714595,92677076,93638724,94596642,95540395
-Vietnam,VNM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,174297736400.7,189421988946.299,222286668252.391,246657402340.845,251128099702.306,275899297905.399,301475951746.669,324169424138.899,309977115099.669,367460152029.961,396482343535.126,426615145409.605,456333610654.877,490398087868.146,526614845522.342,571097036200.103,617508003652.825,671245082248.009
-Virgin Islands (U.S.),VIR,"Population, total",SP.POP.TOTL,108642,108549,108506,108467,108454,108371,108339,108399,108405,108358,108292,108191,108044,107884,107710,107510,107268,106977
-Virgin Islands (U.S.),VIR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
-West Bank and Gaza,PSE,"Population, total",SP.POP.TOTL,2922153,2997784,3154969,3236626,3320396,3406334,3494496,3591977,3689099,3786161,3882986,3979998,4076708,4173398,4270092,4367088,4454805,4569087
-West Bank and Gaza,PSE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9581562025.40581,8581893437.62694,8711891032.15408,9788488506.83217,11390702945.9231,11423201836.8576,12667760475.4543,13702056362.7755,14629247819.8148,15909009847.3924,18332734924.1935,19940193572.0569,21067508757.4605,21889445151.3666,23261462034.2339,24755871266.2101,25930907577.1221,27376726511.647
-"Yemen, Rep.",YEM,"Population, total",SP.POP.TOTL,17409072,17918373,18985000,19540098,20107409,20687646,21282515,21892146,22516460,23154855,23807588,24473178,25147109,25823485,26497889,27168210,27834821,28498687
-"Yemen, Rep.",YEM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,50945731957.021,54635896876.3459,59836847910.4749,63193375067.7939,68857560184.7989,75755105734.0369,80592513596.264,84356835620.827,90617952570.448,97470105229.5594,85694098679.7649,92035976558.7977,98108265892.9489,98134775321.8416,85199170571.8447,76663697942.8642,73537752886.0791,73255533964.395
-Zambia,ZMB,"Population, total",SP.POP.TOTL,10415944,10692193,11256743,11550642,11856247,12173514,12502958,12848530,13215139,13605984,14023193,14465121,14926504,15399753,15879361,16363507,16853688,17351822
-Zambia,ZMB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16859317973.0349,18203447793.9742,21293945093.7292,22563622104.5323,24637111130.0717,26921161038.7427,29350744715.8496,33399420896.3917,38781297276.5569,41496562802.8305,45584354103.5952,51890087558.0177,53897710078.9259,58818095450.7059,61347525118.4727,63987993435.1516,65878916452.6281,71062540099.1249
-Zimbabwe,ZWE,"Population, total",SP.POP.TOTL,11881477,11923914,11982224,12019912,12076699,12155491,12255922,12379549,12526968,12697723,12894316,13115131,13350356,13586681,13814629,14030390,14236745,14439018
-Zimbabwe,ZWE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,26350189272.7886,27467955150.4053,21725309056.2701,20786127560.7269,20233468879.9595,19918084138.1566,19474943345.3475,15786137784.2068,17214601829.981,21138050914.4065,23990800679.1528,28941591239.3131,31104347021.3766,32566365115.0374,33341554454.358,34446760780.9698,36771043359.7364,43477936211.9703
-,,,,,,,,,,,,,,,,,,,,,
-,,,,,,,,,,,,,,,,,,,,,
-,,,,,,,,,,,,,,,,,,,,,
-Data from database: World Development Indicators,,,,,,,,,,,,,,,,,,,,,
-Last Updated: 07/10/2019,,,,,,,,,,,,,,,,,,,,,
+Country Name,Country Code,Series Name,Series Code,2000 [YR2000],2001 [YR2001],2002 [YR2002],2003 [YR2003],2004 [YR2004],2005 [YR2005],2006 [YR2006],2007 [YR2007],2008 [YR2008],2009 [YR2009],2010 [YR2010],2011 [YR2011],2012 [YR2012],2013 [YR2013],2014 [YR2014],2015 [YR2015],2016 [YR2016],2017 [YR2017],2018 [YR2018],2019 [YR2019]
+Afghanistan,AFG,"Population, total",SP.POP.TOTL,20779953,21606988,22600770,23680871,24726684,25654277,26433049,27100536,27722276,28394813,29185507,30117413,31161376,32269589,33370794,34413603,35383128,36296400,37172386,38041754
+Afghanistan,AFG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,43028339584.2827,50011958158.0176,51128371918.0527,59761402458.6644,65266760640.6549,69050351838.9108,72481076025.8795,76028794220.7415,80928557850.552,84153433613.6912,88625369464.1162
+Albania,ALB,"Population, total",SP.POP.TOTL,3089027,3060173,3051010,3039616,3026939,3011487,2992547,2970017,2947314,2927519,2913021,2905195,2900401,2895092,2889104,2880703,2876101,2873457,2866376,2854191
+Albania,ALB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12295329934.0871,13662030955.6943,14638785105.4615,15646789482.4405,16815675369.8153,18045171250.16,20207327771.9002,22210992539.7718,24354670853.9274,25412668725.7731,27785785416.5398,29662729114.3582,30304812913.2324,31131654485.7363,32829902894.5929,33990559188.9825,35083764553.2169,37559230695.0488,39608393973.6197,40948001863.9295
+Algeria,DZA,"Population, total",SP.POP.TOTL,31042235,31451514,31855109,32264157,32692163,33149724,33641002,34166972,34730608,35333881,35977455,36661444,37383887,38140132,38923687,39728025,40551404,41389198,42228429,43053054
+Algeria,DZA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,249239806875.697,267956340953.41,284631758231.333,311583719636.453,331993919386.156,359464197320.959,380479524575.988,414482847146.861,435958233181.566,445244775226.9,470023755816.768,489716726450.96,488121977761.001,487240917216.145,494779232360.141,464696482682.72,466748869735.932,470665607922.597,483634986014.434,496317405228.713
+American Samoa,ASM,"Population, total",SP.POP.TOTL,57821,58494,59080,59504,59681,59562,59107,58365,57492,56683,56079,55759,55667,55713,55791,55812,55741,55620,55465,55312
+American Samoa,ASM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Andorra,AND,"Population, total",SP.POP.TOTL,65390,67341,70049,73182,76244,78867,80993,82684,83862,84463,84449,83747,82427,80774,79213,78011,77297,77001,77006,77142
+Andorra,AND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Angola,AGO,"Population, total",SP.POP.TOTL,16395473,16945753,17519417,18121479,18758145,19433602,20149901,20905363,21695634,22514281,23356246,24220661,25107931,26015780,26941779,27884381,28842484,29816748,30809762,31825295
+Angola,AGO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,45625455853.6001,49027450511.5838,58964860623.3629,62549385841.7304,70579130516.6148,83400219381.4952,94887584187.4675,111277581531.289,120613907210.438,130973295234.436,139021737564.205,148439198180.964,170976257471.015,185392055550.407,206980822098.846,194201091488.512,194190315018.69,204590018767.271,201768990921.183,203208993772.894
+Antigua and Barbuda,ATG,"Population, total",SP.POP.TOTL,76016,77212,78295,79300,80336,81465,82704,84026,85397,86746,88028,89253,90409,91516,92562,93566,94527,95426,96286,97118
+Antigua and Barbuda,ATG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1217115229.2722,1210511861.26921,1216713026.6122,1322214773.35562,1429982539.02744,1582114255.11667,1838859693.47553,2063612215.07978,2093309042.37265,1859954533.20297,1770640004.07869,1760071676.80133,1713287781.8074,1663882354.66843,1672367226.25589,1673163663.24582,1740563149.3915,1805710260.31236,1974378899.13692,2088020637.75117
+Argentina,ARG,"Population, total",SP.POP.TOTL,36870787,37275652,37681749,38087868,38491972,38892931,39289878,39684295,40080160,40482788,40788453,41261490,41733271,42202935,42669500,43131966,43590368,44044811,44494502,44938712
+Argentina,ARG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,417017017009.874,406454882837.983,359568619973.832,403024962214.876,417925482320.917,467759982214.622,567943867286.977,640200578583.143,680128095943.174,640783010735.511,711419160863.447,774596879587.266,799048894124.435,829354154809.18,821363404158.217,849527597209.511,865869191296.284,1011372465447.42,998830800603.003,991400568035.896
+Armenia,ARM,"Population, total",SP.POP.TOTL,3069591,3050687,3033978,3017932,3000720,2981269,2958307,2932618,2907618,2888092,2877319,2876538,2884229,2897584,2912403,2925553,2936146,2944809,2951776,2957731
+Armenia,ARM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8411785419.15044,9413974116.05656,10873948357.9474,12607269792.8155,14422298034.6708,16947791947.5762,19865408956.9072,23342625648.8472,25565242042.8503,21756361158.8814,22666908341.8519,23905121367.1988,28085043286.0165,30249264888.7339,30546350169.5525,30350856297.5626,32159779382.3082,36937299281.0249,38914323976.9806,42759114791.1952
+Aruba,ABW,"Population, total",SP.POP.TOTL,90853,92898,94992,97017,98737,100031,100834,101222,101358,101455,101669,102046,102560,103159,103774,104341,104872,105366,105845,106314
+Aruba,ABW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2872847338.94668,2799573363.68339,2637127972.53136,2867204478.72712,3154765184.77508,2706594377.7855,3391212936.23979,3161477224.08529,3615027525.56263,3283103911.55257,3122230322.67618,3163613120.68283,3285168875.60645,3533775695.47509,3641308245.23705,3672197163.04349,3739360304.0678,3824342328.82359,..,..
+Australia,AUS,"Population, total",SP.POP.TOTL,19153000,19413000,19651400,19895400,20127400,20394800,20697900,20827600,21249200,21691700,22031750,22340024,22733465,23128129,23475686,23815995,24190907,24601860,24982688,25364307
+Australia,AUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,489520624813.209,516165308478.963,549012712403.385,574857353021.546,612002674935.358,639679592265.961,682096652760.495,727224136964.806,763437639656.731,843557963001.247,832245554168.474,899875053935.933,943990546160.514,1035222299693.94,1071746498596.55,1079583930033.6,1118334918553.7,1170453615167.99,1235210799693.42,1307710525895.41
+Austria,AUT,"Population, total",SP.POP.TOTL,8011566,8042293,8081957,8121423,8171966,8227829,8268641,8295487,8321496,8343323,8363404,8391643,8429991,8479823,8546356,8642699,8736668,8797566,8840521,8877067
+Austria,AUT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,233385834582.488,235712900139.037,250522395607.009,260116247290.919,275368283316.74,287476798281.967,311765805754.051,326427226000.799,346680570770.484,341573577563.707,354517435256.432,374289188740.567,392030460346.489,407466618825.439,417609480255.935,426846890617.193,459804635718.973,476401858847.048,501391213443.661,524255318588.868
+Azerbaijan,AZE,"Population, total",SP.POP.TOTL,8048600,8111200,8171950,8234100,8306500,8391850,8484550,8581300,8763400,8947243,9054332,9173082,9295784,9416801,9535079,9649341,9757812,9854033,9939771,10023318
+Azerbaijan,AZE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,25945541164.1045,29117470035.1167,32461373835.4051,36476110641.4663,40054525091.6411,50348316038.8448,69470177011.273,86839747098.6742,103214559007.322,117359000512.606,126293927378.347,125796646904.165,139255987866.21,152856083251.662,160621518912.437,138638584391.013,131075186140.226,133161462622.119,137025867661.274,143908317720.303
+"Bahamas, The",BHS,"Population, total",SP.POP.TOTL,298051,302618,307660,313129,318894,324859,331033,337389,343681,349604,354942,359577,363584,367168,370633,374206,377931,381761,385640,389482
+"Bahamas, The",BHS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8212039357.49644,8555735052.74748,8954646677.20319,9038072662.66086,9378191119.25278,9969505538.47152,10498621829.1727,10932504061.2488,11064073036.999,10593508696.2367,10810983134.6064,11125447356.4103,11592317459.2316,11657745330.0293,11584144607.0395,12121659219.4026,12442626567.74,13079239093.8042,13243975035.1448,13926793002.7071
+Bahrain,BHR,"Population, total",SP.POP.TOTL,664611,697545,735146,778708,829844,889164,958418,1035919,1114641,1185076,1240860,1278151,1299943,1315029,1336075,1371851,1425791,1494074,1569439,1641172
+Bahrain,BHR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,27342775275.6308,28311147154.8213,29139543394.9118,31890130714.0216,35064369649.6128,39326073357.5737,43358665294.0685,48563603277.495,51417086000.4558,49339407229.793,52795240416.4259,52634201219.1065,63717186823.4415,65227977632.6593,64937397694.8038,59179331108.336,60305919955.802,67183271708.1063,70191027889.9976,72447496887.6035
+Bangladesh,BGD,"Population, total",SP.POP.TOTL,127657854,130088702,132478086,134791603,136986432,139035505,140921167,142660376,144304167,145924797,147575430,149273778,151007807,152764676,154520167,156256276,157970840,159670593,161356039,163046161
+Bangladesh,BGD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,175498887965.454,188070169582.154,200208777958.829,213675132590.599,231579935778.308,254658309092.687,283108869793.188,313518446629.288,342916400364.922,363743172757.142,389103719400.951,422196099681.023,481140590082.247,518842425889.083,555106922287.902,591636233914.118,643070206340.889,692953262569.39,767013742002.338,845445644078.841
+Barbados,BRB,"Population, total",SP.POP.TOTL,271515,272500,273425,274329,275284,276323,277477,278700,279946,281104,282131,282987,283700,284296,284825,285324,285796,286233,286641,287025
+Barbados,BRB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3342299166.77654,3318357276.51927,3388898330.18903,3514294102.71811,3689684927.88694,3906413102.97208,4195291318.44247,4499475767.81716,4565169179.79777,4407087551.19392,4437707800.42561,4316589791.49889,4181013706.50134,4178206525.47126,4140648057.77415,4225737707.64073,4350024546.28767,4316152743.33284,4390758125.54967,4514195345.96069
+Belarus,BLR,"Population, total",SP.POP.TOTL,9979610,9928549,9865548,9796749,9730146,9663915,9604924,9560953,9527985,9506765,9490583,9473172,9464495,9465997,9474511,9489616,9501534,9498264,9483499,9466856
+Belarus,BLR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,57705302050.6981,61790137574.8412,65964081580.8031,72232043481.186,82600707462.355,93036490620.998,105319045370.782,116797714121.373,131252203713.056,131452902107.079,142835099051.391,153208172866.978,167125617328.764,172894457423.035,173994190973.455,163630254654.451,160606261472.775,167024751964.679,176773092587.249,183086223605.112
+Belgium,BEL,"Population, total",SP.POP.TOTL,10251250,10286570,10332785,10376133,10421137,10478617,10547958,10625700,10709973,10796493,10895586,11038264,11106932,11159407,11209057,11274196,11331422,11375158,11427054,11484055
+Belgium,BEL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,292276530740.395,301798939308.354,318307798007.558,326734665722.615,338466279472.564,352001708926.337,376805872104.647,395958458302.032,415597849908.875,415541297928.157,441038357059.041,452655752838.946,480620383220.801,499349513623.745,514186705056.397,528391165614.716,556214648760.066,583765893496.913,601270822533.095,628536700011.253
+Belize,BLZ,"Population, total",SP.POP.TOTL,247315,255063,262378,269425,276504,283800,291329,299025,306823,314655,322464,330237,338000,345715,353366,360933,368400,375769,383071,390353
+Belize,BLZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1287387950.12441,1357116298.17213,1450626199.39274,1584055478.8119,1666953268.63775,1766477586.79562,1908375872.74665,1922371073.92628,2034622477.42642,2179676578.6101,2193777170.18317,2368973885.92935,2264265317.53936,2309881069.2432,2316370287.0878,2469910477.61929,2483171941.55207,2445227377.72736,2521543358.43644,2586290005.7404
+Benin,BEN,"Population, total",SP.POP.TOTL,6865951,7076733,7295394,7520555,7750004,7982225,8216897,8454793,8696921,8944708,9199259,9460830,9729248,10004588,10286842,10575952,10872067,11175204,11485048,11801151
+Benin,BEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12039933514.299,12953894834.0906,13731587220.5999,14462457150.2043,15527659080.1207,16339425050.7319,17469806798.1607,18981657972.5593,20396010410.2284,20980955406.4862,21626033958.7697,22827277379.615,24162896617.311,26561886938.3552,29012509444.3848,30282958642.7141,32384504143.6299,33647417490.4049,36780159249.1225,39999046350.9209
+Bermuda,BMU,"Population, total",SP.POP.TOTL,61833,62504,62912,63325,63740,64154,64523,64888,65273,65636,65124,64564,64798,65001,65138,65237,64554,63873,63920,63918
+Bermuda,BMU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,5456799919.71736,5466764865.19812,5030614754.06481,5022225302.70077,4922794703.56838,4798405145.34744,4915286607.50308,..,..,..,..,..,..
+Bhutan,BTN,"Population, total",SP.POP.TOTL,591021,603640,616018,627839,638815,648739,657410,664876,671613,678323,685503,693298,701583,710238,719056,727876,736709,745568,754394,763092
+Bhutan,BTN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1591736072.85988,1763611969.90641,1958737241.04163,2135036176.14072,2322903181.89559,2593205499.03799,2889013893.97406,3477490674.9173,3662361807.20907,3885527852.17577,4327633174.10703,4733983718.26042,5108157657.00653,5275721526.07621,5790544513.85152,6422593662.27931,7042038049.76,7585887017.97289,7972462732.6997,..
+Bolivia,BOL,"Population, total",SP.POP.TOTL,8418264,8580235,8742814,8905823,9069039,9232306,9395446,9558439,9721454,9884781,10048590,10212954,10377676,10542376,10706517,10869730,11031813,11192854,11353142,11513100
+Bolivia,BOL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,28161612877.8653,29291553032.7892,30495792099.2688,31529219889.622,33501391737.5381,36239758171.9237,39319908872.8557,42104650396.6538,45805903721.7166,47374744534.9209,49638890299.5505,53064109761.1359,57756234328.9259,65495334433.2076,71666096824.1971,74894854676.5673,81222638727.5769,91619577813.6129,98159504441.3777,102575988110.502
+Bosnia and Herzegovina,BIH,"Population, total",SP.POP.TOTL,3751176,3755512,3759387,3762173,3764194,3765331,3765424,3762786,3754271,3735938,3705472,3661175,3604972,3542605,3482104,3429361,3386267,3351527,3323929,3301000
+Bosnia and Herzegovina,BIH,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18893960441.6454,19495377630.5613,20785260181.9174,21502942338.8847,24451805360.4885,25418813434.2621,28733747408.2105,31724715828.6723,35149095739.1769,35063480682.5581,35226791593.2155,36818838481.123,37436322971.8998,39547015864.6682,40137098277.2587,41479053647.328,44046396490.1261,46045036414.2516,49490888672.9277,52045375795.3886
+Botswana,BWA,"Population, total",SP.POP.TOTL,1643334,1674678,1704642,1734398,1765527,1799078,1835908,1875459,1915639,1953498,1987105,2015402,2039551,2062536,2088614,2120716,2159944,2205128,2254126,2303697
+Botswana,BWA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13557098416.7967,14419530134.1595,13889154137.087,15363412458.1537,15991769327.3531,17685230941.2731,19912705651.2361,22352103231.3717,24185722744.8361,23597971610.0522,25205768180.1838,28096540791.5689,27303359705.3918,29010795919.8094,33058030162.8137,31933338415.3736,34254769280.8652,35240910553.464,37601959311.8403,39418398509.3185
+Brazil,BRA,"Population, total",SP.POP.TOTL,174790340,177196054,179537520,181809246,184006481,186127103,188167356,190130443,192030362,193886508,195713635,197514534,199287296,201035903,202763735,204471769,206163058,207833831,209469333,211049527
+Brazil,BRA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1538129202525.13,1587691758684.04,1660196184117.21,1713529500931.72,1865227767451.45,1986218399261.88,2135907584142.05,2335440097782.97,2493769549044.97,2515775629776.84,2712167338494.9,2894294561187.89,2923719823241.04,3090347659210.83,3127764536961.12,2958026429307.17,2876740136507.09,2961280980576.57,3041123356393.52,3134970431394.81
+British Virgin Islands,VGB,"Population, total",SP.POP.TOTL,20311,20675,21129,21672,22334,23107,24023,25047,26097,27039,27794,28319,28650,28847,28989,29152,29355,29577,29802,30030
+British Virgin Islands,VGB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Brunei Darussalam,BRN,"Population, total",SP.POP.TOTL,333165,340034,346782,353293,359433,365114,370263,374965,379421,383906,388646,393688,398989,404421,409769,414907,419800,424473,428962,433285
+Brunei Darussalam,BRN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,22135261424.3605,23241505277.578,24523299248.4977,25704091177.3781,26529220186.0059,27461594982.2529,29536870001.5476,30531964635.0643,30482369303.0034,30204880108.3032,30970850502.8798,32155106321.3359,34364760477.9712,33509559006.4759,33313972350.929,27254603848.3947,25364170400.1577,27428959648.7296,26679679555.1299,28773188263.1097
+Bulgaria,BGR,"Population, total",SP.POP.TOTL,8170172,8009142,7837161,7775327,7716860,7658972,7601022,7545338,7492561,7444443,7395599,7348328,7305888,7265115,7223938,7177991,7127822,7075947,7025037,6975761
+Bulgaria,BGR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,51206887192.224,55857030666.9347,62301080894.9876,66436197074.9398,71770858373.6766,79042444991.263,84464686591.4914,89506772467.2668,102296594159.52,102238446938.669,107687535635.403,111463649283.489,117073102231.176,117808231142.742,125723697399.701,127548541849.325,137386319097.664,147551916573.944,160249850986.115,166588293364.132
+Burkina Faso,BFA,"Population, total",SP.POP.TOTL,11607942,11944587,12293100,12654621,13030569,13421930,13829176,14252021,14689725,15141098,15605217,16081911,16571246,17072775,17586017,18110624,18646378,19193284,19751535,20321378
+Burkina Faso,BFA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,29691629052.1441,33038518525.3481,37940356284.1784,41816222358.4319,45106161376.3608
+Burundi,BDI,"Population, total",SP.POP.TOTL,6378871,6525545,6704113,6909154,7131693,7364862,7607849,7862214,8126102,8397668,8675602,8958406,9245988,9540289,9844297,10160030,10487998,10827024,11175378,11530580
+Burundi,BDI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3417413481.01147,3457302261.58827,3658729575.30679,3657760764.51363,3909506770.43672,4126198847.68812,4521888837.8659,4816030666.91283,5157105457.38349,5357360329.22675,5721809553.46122,6061708967.24937,6368259239.23793,7074395514.84014,7630235753.1728,8546596103.6737,8355961626.26465,8362807306.07259,8728640031.72276,9047917503.70175
+Cabo Verde,CPV,"Population, total",SP.POP.TOTL,428188,435709,442951,449930,456617,463032,469170,475060,480842,486671,492654,498856,505235,511748,518269,524743,531146,537497,543767,549935
+Cabo Verde,CPV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1266782277.89099,1342798431.14331,1418151673.32053,1513235208.56818,1709455198.73134,1857808134.49154,2054984867.8792,2473476172.30508,2673960999.08434,2662817641.47333,2681117810.15862,2859939245.12912,2814067315.42606,2860973891.1569,2830720284.50257,3029167495.53556,3238655861.9396,3447518124.1818,3730549246.95491,4019648413.84286
+Cambodia,KHM,"Population, total",SP.POP.TOTL,12155239,12405408,12637727,12856163,13066469,13273354,13477709,13679962,13883834,14093604,14312212,14541423,14780454,15026332,15274503,15521436,15766293,16009414,16249798,16486542
+Cambodia,KHM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12642116508.8615,13934468278.6169,14956236448.0484,16630363468.4016,18802167691.3012,21829777132.6337,24961136701.0952,28430776792.2456,30812143007.5767,31002587125.5977,33148868045.7431,36196062670.2364,40199856424.6254,43802730490.9686,46099725658.5717,49377507801.9442,54385763728.0482,58986036499.7482,64519125861.4293,68852453802.8108
+Cameroon,CMR,"Population, total",SP.POP.TOTL,15513945,15928910,16357602,16800865,17259322,17733410,18223674,18730282,19252666,19789919,20341241,20906388,21485266,22077298,22681858,23298368,23926539,24566045,25216237,25876380
+Cameroon,CMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,28350592041.0371,29973192155.9005,32043132678.9502,34925291392.5026,38815056169.6922,40660059083.8955,43972199123.2327,46918252733.0472,49841317015.4953,51912218948.8495,54002042434.8693,57392868093.6708,60411127308.0801,65020260624.0553,71651218352.3963,74891827392.5734,80077228864.7195,85671150257.2736,91043062688.824,96515454551.2549
+Canada,CAN,"Population, total",SP.POP.TOTL,30685730,31020902,31360079,31644028,31940655,32243753,32571174,32889025,33247118,33628895,34004889,34339328,34714222,35082954,35437435,35702908,36109487,36543321,37057765,37589262
+Canada,CAN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,877403072641.854,910889240475.231,946440061399.149,997997291124.232,1059801620831.76,1147390008931.78,1221437024738.28,1281770753021.91,1322673547258.16,1285413680532.32,1337096249937.57,1403781260484.68,1442044757903.5,1530453431372.55,1595196682591.57,1570466921580.38,1657881697068.52,1756595635890.34,1831814016986.74,1910033900633.52
+Cayman Islands,CYM,"Population, total",SP.POP.TOTL,42303,43935,45351,46632,47902,49261,50740,52280,53836,55322,56672,57878,58958,59932,60848,61724,62569,63382,64174,64948
+Cayman Islands,CYM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,3395040409.33341,3579426001.18982,2506666954.65396,2247527709.29713,2213929718.77153,2351877741.07651,2496908670.53074,2639134540.57074,..,..
+Central African Republic,CAF,"Population, total",SP.POP.TOTL,3640427,3722018,3802128,3881181,3959875,4038382,4118069,4198010,4273366,4337625,4386768,4418636,4436415,4447942,4464175,4493170,4537687,4596028,4666377,4745185
+Central African Republic,CAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2420173859.83915,2599121943.16844,2733617163.78552,2651938233.75056,2862197904.44427,2987895516.47448,3224496848.98221,3469104943.0554,3590248705.0439,3962827993.80464,4225494331.49768,4492422406.61788,4910903587.89207,3314143517.70327,3249088436.38074,3580087008.65921,3910067806.77701,4409011233.54022,4789641939.89765,5017902834.17048
+Chad,TCD,"Population, total",SP.POP.TOTL,8355654,8678051,9019233,9373916,9734767,10096633,10457124,10818024,11183588,11560147,11952136,12360989,12784750,13220424,13663559,14110975,14561666,15016773,15477751,15946876
+Chad,TCD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,6319492732.6608,7207018150.40711,7812304544.90587,7891811202.81306,10951344124.8321,13201164727.507,13543078133.2229,14781565230.2795,15134744516.7814,18144612371.4748,21024060933.5094,21644734483.3347,21591587636.4981,19796873664.8052,21921934523.2352,24904346467.7966,23791406629.63,23520168178.8231,24608840263.1903,25830796904.5155
+Channel Islands,CHI,"Population, total",SP.POP.TOTL,148443,149097,149596,150068,150716,151678,153008,154636,156433,158178,159734,160998,162056,163038,164100,165385,166923,168665,170499,172259
+Channel Islands,CHI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Chile,CHL,"Population, total",SP.POP.TOTL,15342353,15516113,15684409,15849652,16014971,16182721,16354504,16530195,16708258,16886186,17062536,17233576,17400347,17571507,17758959,17969353,18209068,18470439,18729160,18952038
+Chile,CHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,141423035548.287,149617763772.581,155784421760.061,161378820974.511,173667662655.791,188423173015.673,226393185292.021,248814945028.446,254260262604.88,254255791260.918,288017255793.192,329368731234.727,356585691606.824,374348201436.925,389162444827.984,395407468276.445,400624301817.111,419006172363.607,443885470333.679,457579908141.733
+China,CHN,"Population, total",SP.POP.TOTL,1262645000,1271850000,1280400000,1288400000,1296075000,1303720000,1311020000,1317885000,1324655000,1331260000,1337705000,1344130000,1350695000,1357380000,1364270000,1371220000,1378665000,1386395000,1392730000,1397715000
+China,CHN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3642929495002.62,4024301291629.47,4480003695003.27,5041479417259.67,5720935150218.09,6542253999453.47,7637180375337.52,8995506578057.3,10095483737974.6,11041378395911.4,12325778007443,13715342009909,15089408602884,16053444960087.1,17143015127789.3,17729511091167.2,18637218188518.7,19871384311878.3,21650459382664.6,23403178554979.1
+Colombia,COL,"Population, total",SP.POP.TOTL,39629968,40255967,40875360,41483869,42075955,42647723,43200897,43737516,44254975,44750054,45222700,45663099,46076848,46497267,46969209,47520667,48171392,48901066,49648685,50339443
+Colombia,COL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,259414591428.19,268702127899.533,279161165812.221,293272250099.694,317045556052.753,346110876184.377,380086886997.642,414864274101.021,434915143665.748,444985677687.291,467552032493.6,507216374248.229,532681024405.232,571015950345.544,606448118177.276,621482821087.166,664816412490.902,687298469474.748,724232953004.369,762425730871.469
+Comoros,COM,"Population, total",SP.POP.TOTL,542357,555888,569479,583211,597228,611627,626425,641620,657229,673252,689692,706569,723871,741505,759390,777424,795592,813892,832322,850886
+Comoros,COM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,978152950.778042,1023858997.70425,1060344930.375,1101989662.31587,1152290411.05479,1222952535.58608,1293956753.02818,1344729861.00691,1420168578.88456,1477640850.41601,1552343824.85307,1650025527.79945,1814962014.89785,1955354402.02042,2065846271.75344,2114908310.93723,2290518423.87202,2481555639.3609,2627949548.30045,2741496615.1196
+"Congo, Dem. Rep.",COD,"Population, total",SP.POP.TOTL,47105826,48428545,49871666,51425580,53068880,54785903,56578037,58453683,60411195,62448574,64563854,66755153,69020747,71358807,73767447,76244544,78789127,81398764,84068091,86790567
+"Congo, Dem. Rep.",COD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,20631804485.1208,20003968418.718,21282755743.5173,23094505319.2151,25195745565.8829,27219506328.6504,29841190580.1695,32379440357.0365,33996053842.4646,36180051180.7136,39199375965.1633,42414784447.7013,43696967208.4135,49142683507.8545,57377953169.2351,63954295208.2057,74312567452.9388,83831229357.8051,90885907472.5688,96218912373.4924
+"Congo, Rep.",COG,"Population, total",SP.POP.TOTL,3127411,3217933,3310387,3406922,3510468,3622775,3745141,3876119,4011486,4145391,4273731,4394844,4510198,4622761,4736974,4856095,4980999,5110702,5244363,5380508
+"Congo, Rep.",COG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7601711583.97746,8036306716.03473,8724482325.33339,9181332300.17183,8997398787.066,9737195047.57814,10623917862.3278,11183689574.246,12937905979.856,13784549918.7088,15667449650.5169,16346963764.2037,17025078803.1975,17267296875.4012,18436509734.9793,16048228148.5409,15691634236.6015,15977607409.9916,16215340249.7365,16463559986.7425
+Costa Rica,CRI,"Population, total",SP.POP.TOTL,3962372,4034074,4100925,4164053,4225155,4285502,4345412,4404628,4463125,4520740,4577378,4633086,4688000,4742107,4795396,4847804,4899345,4949954,4999441,5047561
+Costa Rica,CRI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29623300811.7384,31328489119.4728,32869977672.8924,34899103009.3252,37542259497.0707,40408165122.6785,45035715488.8468,50192693094.6612,53911670959.4287,53040066100.438,56358853436.7787,59912146076.3814,63956459017.0707,66885378676.1451,71737908299.0027,76862312605.2469,84399345453.2129,89894854940.6111,93960595206.229,97152868665.4819
+Cote d'Ivoire,CIV,"Population, total",SP.POP.TOTL,16454668,16853026,17231539,17599610,17970494,18354514,18754916,19171237,19605569,20059147,20532950,21028655,21547188,22087505,22647683,23226143,23822714,24437469,25069229,25716544
+Cote d'Ivoire,CIV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,34179810556.9689,34164006387.8496,33728201147.5087,32927882380.6959,35894161009.2635,40606319284.1736,42394364749.2328,44307734365.2147,46446854989.2683,48250474385.1245,49892838647.0563,48585323041.8884,54762839531.1921,59653079619.2815,69008798623.8581,105692768632.425,110081941651.056,114536013131.385,124763689653.615,135958136117.795
+Croatia,HRV,"Population, total",SP.POP.TOTL,4468302,4299642,4302174,4303399,4304600,4310145,4311159,4310217,4309705,4305181,4295427,4280622,4267558,4255689,4238389,4203604,4174349,4124531,4087843,4067500
+Croatia,HRV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,46499890107.2711,48896198711.9351,53482270125.2327,56353884454.221,61475698987.1059,64372129540.5663,73190743911.4847,81487123907.0063,86614855154.6138,82943218058.2524,82051671965.4988,85889523327.2529,87138270730.1742,90772432088.2814,91550495934.9966,96134586878.9095,100097233590.908,108081346537.34,112930965650.021,120055262820.192
+Cuba,CUB,"Population, total",SP.POP.TOTL,11126430,11164667,11199651,11229183,11250365,11261582,11261248,11251122,11236971,11226709,11225832,11236670,11257101,11282720,11306902,11324781,11335109,11339259,11338138,11333483
+Cuba,CUB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Curacao,CUW,"Population, total",SP.POP.TOTL,133860,129047,129205,131897,134192,137658,141239,144056,145880,146833,148703,150831,152088,153822,155909,157980,159664,160175,159800,157538
+Curacao,CUW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,3489211680.43107,3662002831.67272,3854063142.65658,3929727908.71205,3881983960.51665,3983315325.96962,4081824563.38638,3923707213.22909,3917983606.61816,3915994347.36562,3961320244.31667,3940250307.57778,4115499635.2035,4132584601.47828,..
+Cyprus,CYP,"Population, total",SP.POP.TOTL,943290,960276,976964,993563,1010408,1027662,1045507,1063713,1081563,1098083,1112612,1124833,1135046,1143866,1152285,1160985,1170187,1179680,1189265,1198575
+Cyprus,CYP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13511436832.2251,14900268382.8294,15854031078.158,16711119936.0921,17808359787.8131,19438218852.3815,21265557155.9929,23583728079.5028,26949305682.2092,27330223334.2122,27345454292.8436,29092538227.0754,27312721127.3054,25872169801.1677,24927082983.1203,26713635284.3923,28930812841.8969,31471920977.0666,33356593562.1506,35125093140.5641
+Czech Republic,CZE,"Population, total",SP.POP.TOTL,10255063,10216605,10196916,10193998,10197101,10211216,10238905,10298828,10384603,10443936,10474410,10496088,10510785,10514272,10525347,10546059,10566332,10594438,10629928,10669709
+Czech Republic,CZE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,163038832898.852,174467305667.327,179046170022.093,191477640584.699,202340708154.596,214084360418.233,228658408144.147,251847307853.256,270395387186.615,268132912244.783,268604766055.741,279370310382.565,286391051564.635,301403153675.82,316710658172.226,331373073380.675,354511276940.125,382709527241.609,405816971330.564,433853854330.091
+Denmark,DNK,"Population, total",SP.POP.TOTL,5339616,5358783,5375931,5390574,5404523,5419432,5437272,5461438,5493621,5523095,5547683,5570572,5591572,5614932,5643475,5683483,5728010,5764980,5793636,5818553
+Denmark,DNK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,149596143354.486,155487973617.73,162670765274.646,164472529117.583,178075165724.772,186566260237.836,205208412175.99,213876992045.586,229296531979.344,225193495345.495,242631692386.991,252568140433.285,256181803182.809,270675687839.011,280163778604.424,287382159288.342,305006431683.768,324192732266.205,340112252681.597,357320214235.544
+Djibouti,DJI,"Population, total",SP.POP.TOTL,717584,733015,746942,759641,771603,783254,794563,805451,816358,827823,840198,853674,868136,883293,898696,913993,929112,944097,958920,973560
+Djibouti,DJI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,3715087653.66217,4036230825.66616,4429309389.07182,4597475415.7157,4817795003.66086,5289280458.10073,5819929455.04377
+Dominica,DMA,"Population, total",SP.POP.TOTL,69650,69661,69837,70100,70382,70589,70718,70795,70827,70851,70878,70916,70965,71016,71085,71183,71307,71458,71625,71808
+Dominica,DMA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,400344100.039402,429313346.655132,419179922.578869,456635202.274809,476896541.72058,501085760.596008,564432283.057511,611226901.228168,672058787.445127,677696725.862907,696454257.626208,708014383.213069,679255897.176842,700295621.02101,750737430.525807,761036723.992605,829614493.990179,789737770.599692,847596135.862176,895005759.185567
+Dominican Republic,DOM,"Population, total",SP.POP.TOTL,8471321,8598601,8724975,8850317,8974444,9097257,9218686,9338861,9458075,9576737,9695121,9813210,9930911,10048224,10165178,10281680,10397743,10513131,10627165,10738958
+Dominican Republic,DOM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,54857959234.1973,57451823519.1937,61018030270.1061,59914230879.4222,62079258329.0088,72081412996.4997,81421833744.7993,89627113600.64,95624024360.2622,97332284097.8779,106666390183.348,111949190660.718,113509281387.312,119476175474.504,130354685235.318,145306712788.837,160308245051.641,167596990082.089,184008614926.158,196349641425.533
+Ecuador,ECU,"Population, total",SP.POP.TOTL,12681123,12914667,13143465,13369678,13596388,13825847,14059384,14296557,14535739,14774424,15011117,15243883,15474102,15707474,15951838,16212020,16491115,16785361,17084357,17373662
+Ecuador,ECU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,69098046172.0833,74742259805.639,79574768087.9565,83073642541.6052,91901802521.3136,100466458726.895,108594774592.686,114009264818.594,125602173796.277,127642774663.478,134421320332.912,147884749634.534,157237893147.298,172690001154.939,184012416071.378,176187957730.396,178667364050.045,190676356240.484,196867951562.893,199871447137.298
+"Egypt, Arab Rep.",EGY,"Population, total",SP.POP.TOTL,68831561,70152661,71485043,72826097,74172073,75523569,76873663,78232126,79636079,81134798,82761235,84529250,86422240,88404640,90424654,92442547,94447072,96442593,98423595,100388073
+"Egypt, Arab Rep.",EGY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,400684181257.648,424516803084.269,442195029596.355,463855596342.298,496188030671.872,529723401474.72,587646465573.459,648828095446.349,708313454619.035,741484422581.662,772379855382.843,807504032637.098,935460226221.456,969791269904.67,961833673783.757,1045884282029.13,1042793009640.79,1041539732767.9,1116365583862.3,1185110320142.05
+El Salvador,SLV,"Population, total",SP.POP.TOTL,5887936,5927006,5962136,5994077,6023797,6052123,6079399,6105810,6131764,6157686,6183875,6210568,6237923,6266070,6295128,6325124,6356143,6388122,6420744,6453553
+El Salvador,SLV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,25625057193.2798,26412663278.8683,27145840513.0776,27897191944.0943,28861264893.0732,30566055698.3285,33063124163.0323,34601612380.5593,36374477944.3703,35521962609.6281,36783889176.141,38933283619.5548,39143379884.8551,41152360828.005,43447081739.4438,45817642299.8659,48462178672.0867,51005491573.6496,53436355129.8483,56132584584.232
+Equatorial Guinea,GNQ,"Population, total",SP.POP.TOTL,606181,631666,658384,686664,716949,749535,784496,821687,860840,901599,943639,986853,1031191,1076413,1122276,1168568,1215179,1262001,1308974,1355986
+Equatorial Guinea,GNQ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3569476980.42644,4055894873.55833,5418769255.37622,5380816669.01491,7063285944.27882,10643726530.0438,18306829396.1913,22011462069.2607,24503329731.2202,22329409017.6862,18263922392.6939,21889346128.883,25687593216.8693,25581464599.311,25707960045.8039,21190569158.2367,19263632756.1753,20954718048.321,20599465392.7533,19797708447.4125
+Eritrea,ERI,"Population, total",SP.POP.TOTL,2292416,2374722,2481058,2600973,2719803,2826659,2918205,2996536,3062779,3119920,3170435,3213972,..,..,..,..,..,..,..,..
+Eritrea,ERI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3506504683.54086,3882334366.44965,4040941341.42888,3995622452.95127,4151458428.13569,4414188410.48932,4510019766.93467,4705298978.88769,4314353633.37809,4514907120.14248,4650579875.09612,5164760114.43522,..,..,..,..,..,..,..,..
+Estonia,EST,"Population, total",SP.POP.TOTL,1396985,1388115,1379350,1370720,1362550,1354775,1346810,1340680,1337090,1334515,1331475,1327439,1322696,1317997,1314545,1315407,1315790,1317384,1321977,1326590
+Estonia,EST,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12669789053.2999,13621048412.8871,15237944246.2133,16938465034.2173,18679330374.4002,21499500921.8641,24584992712.209,27418527426.1221,28932126115.7131,26675790036.0418,27494601909.1167,31230453479.2807,33215561266.1041,35556368007.5954,37217445766.6686,37821991827.8642,40170713503.6427,43497799024.4122,47162932030.7337,50421445033.1002
+Eswatini,SWZ,"Population, total",SP.POP.TOTL,1005435,1013609,1019059,1022802,1026286,1030579,1036092,1042652,1049945,1057467,1064837,1072032,1079288,1086839,1095021,1104044,1113984,1124753,1136191,1148130
+Eswatini,SWZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4841044260.53071,5228208996.89649,5210477318.31103,5395620373.05508,5858932937.73412,6756746959.2949,7016136628.35619,7581049283.3852,7688629392.01527,7714634747.85168,7853617337.89829,8582264516.31715,8878105091.60812,9553826836.30231,9655682182.88881,9859047731.37133,9239799764.31969,8992934215.72979,9167414979.72843,9119639409.78686
+Ethiopia,ETH,"Population, total",SP.POP.TOTL,66224804,68159423,70142091,72170584,74239505,76346311,78489206,80674348,82916235,85233913,87639964,90139927,92726971,95385785,98094253,100835458,103603501,106400024,109224559,112078730
+Ethiopia,ETH,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,31745647141.6655,35172872840.3776,36248505406.0944,36093164761.2695,42154727413.4637,48770757910.6299,55711564489.7698,63968650234.7454,72249633206.4247,79048790246.6279,89796474832.5446,102066962975.689,112283190021.582,122160040713.247,148077681634.81,166439956275.808,194015746732.547,213816795462.579,234123795699.233,257833627636.733
+Faroe Islands,FRO,"Population, total",SP.POP.TOTL,46735,46997,47233,47432,47600,47722,47792,47825,47820,47808,47814,47823,47843,47892,47960,48051,48173,48331,48497,48678
+Faroe Islands,FRO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Fiji,FJI,"Population, total",SP.POP.TOTL,811006,813925,815257,816076,817860,821604,827870,836190,845361,853637,859818,863449,865069,865608,866453,868627,872399,877459,883483,889953
+Fiji,FJI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4827120096.51656,4892822205.4524,5214236792.19288,5323698866.83316,5754894934.23974,6061204526.3355,6025609709.78998,6241924312.93759,6412425532.57076,6507160715.10832,6593677900.24856,6919076183.45899,7364413511.27213,8093191221.57648,9375290977.58611,10308984097.0623,10552450502.8774,11065468557.7563,11639696514.4538,11799710852.3755
+Finland,FIN,"Population, total",SP.POP.TOTL,5176209,5188008,5200598,5213014,5228172,5246096,5266268,5288720,5313399,5338871,5363352,5388272,5413971,5438972,5461512,5479531,5495303,5508214,5515525,5520314
+Finland,FIN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,137831205768.922,144213025306.481,149214583627.633,150389244509.753,164126870712.683,168848220995.197,182879915808.363,200493060394.021,213338084144.169,205444151668.081,211781871684.258,221315089725.945,222320431042.548,226606741870.886,230341376307.58,235221001780.708,248155471609.02,261590094221.63,273274599947.778,282682864368.635
+France,FRA,"Population, total",SP.POP.TOTL,60912500,61357430,61805267,62244886,62704895,63179351,63621381,64016225,64374984,64707040,65027507,65342780,65659809,65998687,66312067,66548272,66724104,66864379,66965912,67059887
+France,FRA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1614956006369.75,1717864359700.64,1781288096300.79,1774939575254.32,1845786479339.73,1959874866060.42,2104482410624.18,2225392718411.68,2308471504999.58,2297731448402.57,2390316382553.47,2511515271090.53,2528097207038.72,2666950863865.02,2719730300347.34,2777946957121.9,2924396537469.08,3065793971593.25,3180957643991.66,3379235791179.85
+French Polynesia,PYF,"Population, total",SP.POP.TOTL,240686,244931,248972,252703,255992,258780,261010,262721,264061,265254,266455,267698,268998,270328,271705,273124,274575,276103,277679,279287
+French Polynesia,PYF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Gabon,GAB,"Population, total",SP.POP.TOTL,1228360,1258003,1288315,1319953,1353795,1390549,1430152,1472575,1518540,1568928,1624140,1684635,1749682,1817071,1883800,1947686,2007873,2064823,2119275,2172579
+Gabon,GAB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,14560360616.8048,15533771682.1043,16373734921.2765,16685199605.6481,16403352230.3776,18466927308.8567,17838899425.0902,19077719130.1454,18981183917.5181,19713699134.9328,20931794546.4329,22729974762.4942,24187166236.5611,24803028471.2847,27448373201.6419,26252661543.3818,26457471076.3386,29027529828.7639,29882361204.4177,31328419269.158
+"Gambia, The",GMB,"Population, total",SP.POP.TOTL,1317703,1360074,1404261,1449925,1496527,1543741,1591445,1639848,1689285,1740279,1793196,1848147,1905011,1963711,2024042,2085860,2149139,2213894,2280102,2347706
+"Gambia, The",GMB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2391096788.02665,2579595445.05702,2507399451.28304,2780913260.15132,3137919845.09736,3158295371.00478,3229331373.09398,3429568507.91704,3729476358.48792,3996504312.8178,4281627558.09595,4002461735.10188,4103967194.68281,4076131550.67062,4006121655.97443,4207793058.65318,4362686911.60081,4502345653.44125,4914925185.03292,5304139529.51512
+Georgia,GEO,"Population, total",SP.POP.TOTL,4077131,4014373,3978515,3951736,3927340,3902469,3880347,3860158,3848449,3814419,3786695,3756441,3728874,3717668,3719414,3725276,3727505,3728004,3726549,3720382
+Georgia,GEO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12812347844.1636,13640959575.383,14569475526.9638,16469948371.4657,18107946265.3463,20363417437.7528,23213208401.1407,26381442604.0567,27320718279.6863,26539639982.1387,28134208151.5415,30519613226.4118,36257009738.4886,38723289569.7477,42492961933.5167,44015459770.8487,45709833895.1989,48180654829.8018,52267983795.5271,55865774651.3008
+Germany,DEU,"Population, total",SP.POP.TOTL,82211508,82349925,82488495,82534176,82516260,82469422,82376451,82266372,82110097,81902307,81776930,80274983,80425823,80645605,80982500,81686611,82348669,82657002,82905782,83132799
+Germany,DEU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2224328583943.71,2320728939186.94,2381368004844.2,2440703477248.71,2598811221466.52,2643689105682.11,2858148381212.31,3025439825143.71,3133424995825.21,3086256642388.37,3251502171529.72,3502470398953.27,3570904139239.83,3712581829258.22,3883389666513.64,3983765536763.11,4266415919562.53,4493919482771.19,4641067663123.44,4795662518549.85
+Ghana,GHA,"Population, total",SP.POP.TOTL,19278856,19756928,20246381,20750299,21272323,21814642,22379055,22963946,23563825,24170940,24779619,25387710,25996449,26607642,27224472,27849205,28481946,29121471,29767108,30417856
+Ghana,GHA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,33524661532.0692,35837806716.777,38027118472.8837,40731393775.2881,44150796112.8559,48520510267.9119,53260838519.3104,57103190612.7684,63642248133.0456,67264314065.1944,72467930100.5584,83129912555.5813,93322034398.2884,136957246170.144,143670731901.313,140624612115.26,136623482244.943,141646107789.028,155166742061.052,167736159566.294
+Gibraltar,GIB,"Population, total",SP.POP.TOTL,31077,31602,32102,32555,32928,33219,33417,33517,33559,33565,33585,33612,33646,33692,33725,33736,33737,33728,33718,33701
+Gibraltar,GIB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Greece,GRC,"Population, total",SP.POP.TOTL,10805808,10862132,10902022,10928070,10955141,10987314,11020362,11048473,11077841,11107017,11121341,11104899,11045011,10965211,10892413,10820883,10775971,10754679,10732882,10716322
+Greece,GRC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,212412906521.369,229451460132.503,246506012516.46,260114542212.294,275403545164.743,281471978035.928,308410889366.803,315270202791.407,331637075588.565,330031550468.558,306864932903.115,282370859957.681,281120340956.062,285824079577.244,294315512120.89,291510428686.154,299834879612.122,313451120014.443,324064779565.834,335971429806.141
+Greenland,GRL,"Population, total",SP.POP.TOTL,56200,56350,56609,56765,56911,56935,56774,56555,56328,56323,56905,56890,56810,56483,56295,56114,56186,56172,56023,56225
+Greenland,GRL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Grenada,GRD,"Population, total",SP.POP.TOTL,102833,103249,103634,104005,104347,104661,104933,105190,105456,105789,106233,106796,107446,108170,108902,109599,110261,110874,111454,112003
+Grenada,GRD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,734808668.997312,724132428.505397,753881927.286094,843000490.898453,838101389.203375,1053766192.82723,1041581983.0442,1119875083.74834,1155463272.22854,1052844457.55335,1094309142.21063,1138673428.05649,1148161514.25938,1240710384.87123,1291198872.90021,1373363286.20348,1505284098.72797,1631169567.08909,1734364871.14465,1820223209.9485
+Guam,GUM,"Population, total",SP.POP.TOTL,155329,156401,157176,157717,158101,158402,158648,158847,159036,159226,159444,159692,159996,160407,161016,161853,162951,164281,165768,167294
+Guam,GUM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Guatemala,GTM,"Population, total",SP.POP.TOTL,11589761,11871565,12147518,12415334,12682108,12948292,13213330,13477017,13739299,14000190,14259687,14521515,14781942,15043981,15306316,15567419,15827690,16087418,16346950,16604026
+Guatemala,GTM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,55436071588.0517,58423901749.5849,60973451961.9998,63730651285.231,67330576884.2977,71639439847.8173,77407216882.2785,84307587083.0798,89061029301.2988,89842025531.9565,93393580375.0718,98829682628.6572,105811146465.384,109413614487.413,115639774376.543,124517142887.857,127323281385.564,131000150292.011,138427160736.326,146879602730.045
+Guinea,GIN,"Population, total",SP.POP.TOTL,8240730,8417081,8586074,8753093,8925743,9109581,9307425,9518162,9738792,9964469,10192176,10420471,10652029,10892810,11150977,11432088,11738441,12067539,12414318,12771246
+Guinea,GIN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9920558236.99188,10462436057.565,11331156275.4814,11199918764.5244,11747323939.0738,12286336393.9249,13567930368.8496,14877927221.0885,15745640858.2095,15497677235.8985,16665347006.9948,17815489449.8391,18819737532.167,18776195192.1864,19471089653.3749,20460340883.3828,24108942384.3006,29066574011.7813,29963997150.6944,32168440980.3898
+Guinea-Bissau,GNB,"Population, total",SP.POP.TOTL,1201301,1227106,1254453,1283305,1313492,1344930,1377581,1411543,1446936,1483921,1522599,1562989,1604979,1648257,1692439,1737202,1782437,1828146,1874309,1920922
+Guinea-Bissau,GNB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1245250077.79105,1290990559.36951,1324865081.05661,1354249893.99777,1434589411.30001,1542192301.95513,1642203212.75516,1749063681.3057,1820547733.8338,1902652560.45922,2030006201.0127,2262774007.23512,2187093803.73918,2205787895.62385,2415238570.21739,2842389875.31444,3191999767.76646,3526798653.49018,3734300631.46878,4267587492.64397
+Guyana,GUY,"Population, total",SP.POP.TOTL,746715,745206,744789,745143,745737,746163,746343,746474,746817,747718,749436,752028,755399,759285,763380,767432,771366,775221,779004,782766
+Guyana,GUY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3009699061.64372,3124587257.8627,3202193511.38486,3279330998.25765,3458833622.83972,3532228541.45415,4003249323.3272,4358404507.89151,4473814101.71071,4670274719.11104,4853150909.08941,5222514849.01609,5572885371.12253,5942399128.49836,6287536367.09898,6469630294.56216,6722036893.02856,6806377196.40416,7235915307.07568,7746391573.0876
+Haiti,HTI,"Population, total",SP.POP.TOTL,8463806,8608819,8754150,8900104,9047077,9195288,9344785,9495328,9646580,9798046,9949322,10100320,10250930,10400673,10549008,10695542,10839970,10982366,11123176,11263077
+Haiti,HTI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,11964700189.2746,12061370869.5294,12173079053.8234,12426628463.5777,12335060575.9589,12882424019.9465,13705750370.178,14529693062.1158,14944372403.3397,15539598839.4582,15251416680.2375,16464253341.1231,16440541937.5505,17548110518.666,18234505008.3534,18308690377.402,19153302075.9352,19492773518.3174,20230734762.7718,20153439276.3162
+Honduras,HND,"Population, total",SP.POP.TOTL,6574509,6751912,6929265,7106319,7282953,7458985,7634298,7808518,7980955,8150775,8317470,8480671,8640691,8798521,8955589,9112916,9270795,9429013,9587522,9746117
+Honduras,HND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16508738719.9366,17280507734.3576,18133692998.8405,19178423048.0611,20773807318.9273,22824412781.0451,25008545050.3809,27739987380.8685,29311524918.5336,28642526365.4201,29729364273.93,31469455075.9805,32447867601.1165,33761586548.5521,36611449125.7829,40945953789.8257,44383060571.3461,49235457099.1837,51275999310.5713,53703314264.4892
+"Hong Kong SAR, China",HKG,"Population, total",SP.POP.TOTL,6665000,6714300,6744100,6730800,6783500,6813200,6857100,6916300,6957800,6972800,7024200,7071600,7150100,7178900,7229500,7291300,7336600,7391700,7451000,7507400
+"Hong Kong SAR, China",HKG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,189820368906.922,197977937213.81,201127217069.696,215146200495.275,239130027430.84,260658394780.65,292675217844.809,322582288590.381,344599699656.119,329453225166.724,352799114972.927,379780810643.688,378882956243.058,392752239125.688,404211342098.222,418904765973.878,430361863158.585,461609726417.992,487933404311.381,492465939619.043
+Hungary,HUN,"Population, total",SP.POP.TOTL,10210971,10187576,10158608,10129552,10107146,10087065,10071370,10055780,10038188,10022650,10000023,9971727,9920362,9893082,9866468,9843028,9814023,9787966,9775564,9769949
+Hungary,HUN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,114045211135.924,126801506496.016,139177319914.304,148325802239.665,154021963134.902,161419505675.344,173625083151.775,177597007603.051,194072486578.888,198356724319.117,206068856612.511,217312698268.979,219987870432.761,235501990439.515,241704812304.023,250589735184.109,264903551296.285,277433118025.225,296328671701.857,319980967377.16
+Iceland,ISL,"Population, total",SP.POP.TOTL,281205,284968,287523,289521,292074,296734,303782,311566,317414,318499,318041,319014,320716,323764,327386,330815,335439,343400,352721,361313
+Iceland,ISL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8064056447.99737,8781736929.05093,9390431859.41103,9381468561.22915,10025240340.2104,10526296722.7951,11026180884.6178,12073064240.4066,10807260433.594,10708134789.6414,10237034204.2611,11022605832.7629,11766282593.5493,13631427233.6515,14240759323.4076,15376113336.7176,17103762803.3958,18673233568.213,19724344190.2306,22101273413.3938
+India,IND,"Population, total",SP.POP.TOTL,1056575549,1075000085,1093317189,1111523144,1129623456,1147609927,1165486291,1183209472,1200669765,1217726215,1234281170,1250288729,1265782790,1280846129,1295604184,1310152403,1324509589,1338658835,1352617328,1366417754
+India,IND,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2190686809323.87,2351372617361.02,2484358366592.28,2727424215141.91,3023959793295.09,3364649501516.79,3743550659626.91,4153719586236.6,4357404051268.08,4735817203686.97,5173298943912.42,5568976388344.3,6080904818549.95,6396857208684.85,6700838434194.09,7076731493413.66,7577059418948.02,8191428149143.83,8899126431645.27,9507241234000.71
+Indonesia,IDN,"Population, total",SP.POP.TOTL,211513823,214427417,217357793,220309469,223285676,226289470,229318262,232374245,235469762,238620563,241834215,245116206,248452413,251806402,255129004,258383256,261554226,264645886,267663435,270625568
+Indonesia,IDN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,936869323318.277,1023368245083.65,1094409163250.38,1157760861349.83,1239077076507.84,1346480241917.56,1472854684302.26,1610868377528.11,1751105373682.55,1847157749729.14,2002209911115.04,2167767372892.09,2345311900455.84,2459271038444.92,2534329758163.13,2559879525286.4,2657025035196.4,2802422575187.42,3026018847669.79,3229572832486.22
+"Iran, Islamic Rep.",IRN,"Population, total",SP.POP.TOTL,65623405,66449112,67284796,68122938,68951281,69762347,70554760,71336475,72120604,72924837,73762519,74634956,75539862,76481943,77465753,78492215,79564016,80673951,81800269,82913906
+"Iran, Islamic Rep.",IRN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,675841187412.547,696994128225.243,761316821245.031,842398737386.086,899769697896.238,957212207172.177,1037798895728.35,1155249643133.39,1181336226840.72,1198040521436.13,1282857044909.04,1344189230057.48,1213336909094.26,1176150169010.8,1183766862250.56,1069286038839.47,1118284077512.34,1174847753747.62,..,..
+Iraq,IRQ,"Population, total",SP.POP.TOTL,23497585,24208180,24931919,25644499,26313838,26922284,27448124,27911248,28385746,28973162,29741976,30725300,31890011,33157050,34411951,35572261,36610632,37552781,38433600,39309783
+Iraq,IRQ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,223945695599.99,233939007709.488,219010054391.258,152008077472.552,240719232174.42,235318954839.301,277698213537.278,295172176352.744,346250555535.968,361115320741.941,382579570985.527,414739424314.827,485908441354.314,512778489299.524,488228998508.139,366501386393.93,359100794117.949,408986068274.349,416090939901.668,443346809470.494
+Ireland,IRL,"Population, total",SP.POP.TOTL,3805174,3866243,3931947,3996521,4070262,4159914,4273591,4398942,4489544,4535375,4560155,4580084,4599533,4623816,4657740,4701957,4755335,4807388,4867316,4941444
+Ireland,IRL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,100113059734.314,107470352532.356,116072235760.394,124855538574.355,135840842759.092,145668071091.729,165648719283.898,177837354517,172166896183.693,157923766321.604,165548185550.13,166561101149.351,171504812215.699,186850967298.959,200789098958.416,249588740149.407,278957902309.884,298263305224.758,322469887775.013,336252300615.224
+Isle of Man,IMN,"Population, total",SP.POP.TOTL,76941,77703,78318,78884,79520,80305,81285,82408,83508,84376,84857,84886,84533,83976,83488,83234,83287,83598,84077,84584
+Isle of Man,IMN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Israel,ISR,"Population, total",SP.POP.TOTL,6289000,6439000,6570000,6689700,6809000,6930100,7053700,7180100,7308800,7485600,7623600,7765800,7910500,8059500,8215700,8380100,8546000,8713300,8882800,9053300
+Israel,ISR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,146996682279.526,153795709264.995,159684729036.156,153577205649.943,166628609112.852,170591268132.874,180310175239.801,196904817585.902,196595302964.286,200830172172.911,215667488792.448,233970859364.682,244257169060.297,269603510735.328,279377873188.598,294407526010.901,320477649412.972,336098643414.734,357819136573.777,381508561013.861
+Italy,ITA,"Population, total",SP.POP.TOTL,56942108,56974100,57059007,57313203,57685327,57969484,58143979,58438310,58826731,59095365,59277417,59379449,59539717,60233948,60789140,60730582,60627498,60536709,60421760,60297396
+Italy,ITA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1536251752977.11,1592989057386.54,1632366431124.16,1663483685393.26,1700508305410.16,1749401793158.77,1892183143469.26,1994618888873.8,2070619017116.37,2045551343726.36,2081077565453.29,2167673493812.34,2169728284637.12,2183586713124.53,2200447377386.96,2226028747655.71,2427375662810.54,2543341126089.71,2615143671973.54,2687760563023.36
+Jamaica,JAM,"Population, total",SP.POP.TOTL,2654701,2674702,2692845,2709437,2725015,2740003,2754407,2768227,2781876,2795837,2810460,2825929,2842132,2858709,2875136,2891021,2906238,2920853,2934855,2948279
+Jamaica,JAM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16228041675.6903,16645742257.0425,16954752900.4538,17982395364.7117,18754092245.9084,19450170551.3636,20809329777.3449,21678729182.2425,22157235803.6987,21046043678.58,21372671662.9003,22231524588.9226,22956406890.3935,23565528689.09,24045139424.8735,24640731094.2126,25588822115.0276,27208298032.1934,27920525731.4864,28799949401.4959
+Japan,JPN,"Population, total",SP.POP.TOTL,126843000,127149000,127445000,127718000,127761000,127773000,127854000,128001000,128063000,128047000,128070000,127833000,127629000,127445000,127276000,127141000,126994511,126785797,126529100,126264931
+Japan,JPN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3452930586529.41,3546345231235.99,3639730784809.42,3752540602986.5,3950153980558.91,4133438974348.17,4341515713395.91,4548813737724.68,4573202767880.07,4354890214696.97,4596530742002.53,4702730270932.62,4873844260962.84,5133797407300.4,5166025961476.02,5333311667417.55,5246871690810.19,5364983572337.73,5420858766097.59,5654421763505.28
+Jordan,JOR,"Population, total",SP.POP.TOTL,5122493,5217336,5317506,5434030,5580244,5765635,5991540,6255280,6556478,6893260,7261539,7663131,8090872,8520420,8920049,9266575,9551467,9779173,9956011,10101694
+Jordan,JOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,30393012055.2555,32891728661.6786,34974460374.9464,37307713592.1815,41899452079.2101,46732800031.6403,52229398474.1985,58548112453.5047,63092518458.0793,66862417266.3191,67599734908.1306,70723209041.2385,72809011999.9602,77738120211.2599,79805909438.9503,85486442885.3451,87984422971.6304,95750703564.1376,99946566925.5574,103465944256.527
+Kazakhstan,KAZ,"Population, total",SP.POP.TOTL,14883626,14858335,14858948,14909018,15012985,15147029,15308084,15484192,15674000,16092822,16321872,16557201,16792089,17035550,17288285,17542806,17794055,18037776,18276498.5,18513930
+Kazakhstan,KAZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,107939394934.675,126916049786.246,142962263860.528,157161146492.615,174829230289.961,190542280469.363,212938577584.93,235954730059.164,242322806772.202,257942621312.301,272722282122.584,294494040831.081,319954479748.818,373088584433.754,383650191926.991,381745816548.317,382306984208.955,399678715598.354,419091035222.809,445227412201.649
+Kenya,KEN,"Population, total",SP.POP.TOTL,31964557,32848564,33751739,34678779,35635271,36624895,37649033,38705932,39791981,40901792,42030676,43178257,44343410,45519889,46699981,47878336,49051686,50221473,51393010,52573973
+Kenya,KEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,51242963036.4607,54291635343.8476,55555143737.2785,58149160259.5733,62892402118.2424,69193318822.4205,75717180970.7134,82927905459.9744,85046293991.7905,88499791982.3419,96815313092.1344,105284725887.098,111702555544.44,124600115565.074,139107161405.764,158922253444.329,175712039306.777,199324373582.831,217492984098.153,232294328998.953
+Kiribati,KIR,"Population, total",SP.POP.TOTL,84396,85849,87305,88835,90499,92325,94343,96527,98761,100930,102927,104728,106370,107890,109391,110930,112524,114158,115847,117606
+Kiribati,KIR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,217156131.67745,232653434.252958,227221872.952441,222507516.798848,217292400.466397,228478024.025504,232628480.663213,248005509.18067,252582083.045832,243191331.125525,258637330.475909,254926735.893375,295962984.145106,341023661.572294,394689227.134109,481818499.250186,443604706.489874,489406598.949437,495003038.427024,546379236.403899
+"Korea, Dem. People’s Rep.",PRK,"Population, total",SP.POP.TOTL,22929075,23132980,23339453,23542426,23732731,23904167,24054864,24188331,24310142,24428341,24548836,24673385,24800612,24929452,25057752,25183833,25307744,25429985,25549819,25666161
+"Korea, Dem. People’s Rep.",PRK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+"Korea, Rep.",KOR,"Population, total",SP.POP.TOTL,47008111,47370164,47644736,47892330,48082519,48184561,48438292,48683638,49054708,49307835,49554112,49936638,50199853,50428893,50746659,51014947,51217803,51361911,51606633,51709098
+"Korea, Rep.",KOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,866224637084.584,926568183291.801,1015663096721.17,1053487194629.71,1141674348593.57,1205046439840.2,1298121837175.56,1411147965489.67,1469369248901.13,1459437700151.26,1575219821834.69,1635336002448.05,1702177999918.46,1737909546523.48,1801276221059.28,1939898096852.87,2033944222873.06,2114477220937.47,2180192386669,2245536234863.2
+Kosovo,XKX,"Population, total",SP.POP.TOTL,1700000,1701154,1702310,1703466,1704622,1705780,1719536,1733404,1747383,1761474,1775680,1791000,1807106,1818117,1812771,1788196,1777557,1791003,1797085,1794248
+Kosovo,XKX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,9448780718.94259,10319967010.2791,11159472454.892,12328905773.4844,13202725427.3682,13420011280.9226,14032931934.7061,15065975384.9805,15786623490.4927,16375362781.983,16729091063.4254,17396818269.5142,18103723637.3237,19243542089.8682,20379566169.0025,21688653507.3278
+Kuwait,KWT,"Population, total",SP.POP.TOTL,2045123,2103282,2136997,2161626,2200492,2270198,2373672,2504019,2656009,2821045,2991884,3168060,3348853,3526376,3690941,3835591,3956875,4056099,4137312,4207083
+Kuwait,KWT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,135299805296.8,134200916856.49,133934535618.162,157473075417.704,181118682877.255,206878546765.969,233175724142.53,253816914309.589,256739472146.302,240304338140.048,237522519195.452,262429662609.487,297080892082.726,296212485278.017,282130555688.171,204641979189.488,206128302066.468,240345871255.75,247070912844.791,..
+Kyrgyz Republic,KGZ,"Population, total",SP.POP.TOTL,4898400,4945100,4990700,5043300,5104700,5162600,5218400,5268400,5318700,5383300,5447900,5514600,5607200,5719600,5835500,5956900,6079500,6198200,6322800,6456900
+Kyrgyz Republic,KGZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8582788124.17997,9445299068.39432,9620514406.97036,10528230099.1611,11405670075.3493,11867795448.6145,12852625677.4441,14379148851.6645,15456671499.0971,16049689287.6332,15740559548.7582,16250508927.3612,19767684145.2302,21790220340.6309,23953408501.6723,24127188673.9971,26964623071.125,29771394476.3694,32213584892.4963,32743237340.9162
+Lao PDR,LAO,"Population, total",SP.POP.TOTL,5323700,5409582,5493246,5576640,5662208,5751676,5846074,5944948,6046620,6148623,6249165,6347567,6444530,6541304,6639756,6741164,6845846,6953035,7061507,7169455
+Lao PDR,LAO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9354054066.72607,10128844090.9953,10925727062.9119,11565351478.2267,12833062902.6013,14423987196.9701,15626237268.1888,17634679034.541,19143604679.9074,21142119992.2366,22373664603.9142,24562505654.9469,29339581968.1696,32738513911.9639,37279715377.7992,39733495399.3774,44835845958.1785,47800441427.6112,52320902374.4912,57060254694.0481
+Latvia,LVA,"Population, total",SP.POP.TOTL,2367550,2337170,2310173,2287955,2263122,2238799,2218357,2200325,2177322,2141669,2097555,2059709,2034319,2012647,1993782,1977527,1959537,1942248,1927174,1912789
+Latvia,LVA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18958427819.7615,21141588611.7692,23262996772.4508,25069950348.6161,27035534506.2247,30655830475.7041,34043840581.1906,38692429651.4441,41843251555.0613,38815194342.2175,37290854957.7853,40718164748.9288,43009656243.271,45570135257.205,47389285714.2857,48824891694.3922,51608651149.5449,55079441674.1518,58231115700.1278,60766842719.0905
+Lebanon,LBN,"Population, total",SP.POP.TOTL,3842778,3991001,4182205,4388375,4569378,4698763,4759753,4767344,4764741,4813026,4953061,5202343,5538634,5914621,6262410,6532678,6711121,6811873,6848925,6855713
+Lebanon,LBN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,35040734794.1739,36352321493.6295,36609276889.7272,33656173715.177,42476313044.2458,46345388708.0947,49273874854.1886,56580458896.5347,61987320720.5013,67409785454.3513,73126239449.1207,75853128476.6476,81684754405.0447,88008051378.2797,93092365035.804,97376540515.4046,102281959781.688,108596513314.89,108823275394.388,104646451621.174
+Lesotho,LSO,"Population, total",SP.POP.TOTL,2032804,2035740,2029829,2018348,2005940,1996114,1989939,1986922,1987129,1990131,1995581,2003787,2014990,2028519,2043437,2059021,2075001,2091412,2108132,2125268
+Lesotho,LSO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3256788969.27872,3913059198.29636,4007732093.07968,4213292015.02062,4222495514.4261,4262511673.4545,4395353578.81672,5261996070.51886,5601279294.0217,5576746839.8704,5732442949.77979,5867436520.2687,5807263380.73409,6324234618.26154,6791590360.36545,7160368698.95524,7170407008.26459,6588747322.30217,6739409120.09678,6986676687.08345
+Liberia,LBR,"Population, total",SP.POP.TOTL,2848456,2953927,3024729,3077058,3135651,3218116,3329211,3461911,3607860,3754133,3891356,4017443,4135659,4248334,4359505,4472230,4586788,4702228,4818977,4937374
+Liberia,LBR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2501365581.1216,2462075674.93199,2582706058.45283,1775793699.67672,1916106938.6771,2134870484.98442,2456347243.47831,2838061025.64274,3169296955.52172,3402304565.41736,3620075701.16098,4164518138.61442,4387996479.62735,5130477809.93594,5386476328.91385,5269268962.54026,5783171659.71288,6469862956.51871,6395618956.68225,6497975683.41754
+Libya,LBY,"Population, total",SP.POP.TOTL,5357891,5443248,5531089,5620547,5710154,5798614,5886872,5974787,6058748,6133984,6197663,6247439,6285750,6320359,6362037,6418315,6492164,6580724,6678567,6777452
+Libya,LBY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,98907556524.4814,114707180069.975,119683554072.231,138242554223.013,155161329132.711,168729376086.617,175860708442.341,175981228401.748,185208123495.146,71848542675.5916,149054487640.829,124785429204.8,92283833247.2583,81779062375.7705,74186507345.4983,90063923226.6159,104447488316.605,109021556569.616
+Liechtenstein,LIE,"Population, total",SP.POP.TOTL,33184,33552,33879,34175,34452,34713,34970,35217,35471,35727,35994,36293,36615,36934,37223,37470,37658,37800,37910,38019
+Liechtenstein,LIE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Lithuania,LTU,"Population, total",SP.POP.TOTL,3499536,3470818,3443067,3415213,3377075,3322528,3269909,3231294,3198231,3162916,3097282,3028115,2987773,2957689,2932367,2904910,2868231,2828403,2801543,2786844
+Lithuania,LTU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,29073456226.9132,32362510660.0322,35750858862.3134,40193556163.8145,43151663312.5329,47618000652.6305,52865536898.9319,59375969176.707,64082336397.9652,58509746215.4088,61707606732.2113,67086687879.9077,71326873608.2146,77165315430.1258,81588368630.5696,80707965908.1476,85447564215.7165,92095203351.2039,97160699030.8492,103153905292.877
+Luxembourg,LUX,"Population, total",SP.POP.TOTL,436300,441525,446175,451630,458095,465158,472637,479993,488650,497783,506953,518347,530946,543360,556319,569604,582014,596336,607950,619896
+Luxembourg,LUX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,21402834237.7511,22205396698.8394,22170831121.5512,22111143439.9495,26868080040.165,29304952011.0148,29984532326.2853,34891089859.2331,34990188934.9977,27761239146.6041,31327971287.1073,32928110626.5723,33825803107.6655,34690043272.6355,37434314552.7056,38500383076.5302,41001079837.5551,43381072945.2113,45229329379.7453,48082741436.7121
+"Macao SAR, China",MAC,"Population, total",SP.POP.TOTL,427782,437938,448821,460165,471597,482858,493799,504511,515239,526400,538219,550832,564039,577372,590208,602085,612836,622585,631636,640445
+"Macao SAR, China",MAC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13706107536.5062,15627085786.6657,17267184835.5279,19329615484.4758,24278902454.7137,26760633799.454,29988063964.298,39046721018.6114,36971369691.5926,38224456299.8988,47597861283.4551,57350950643.267,64100909366.4591,74713533743.9956,77917473234.3904,64809126006.3126,65773504327.3786,72268933052.8813,77872092849.4063,..
+Madagascar,MDG,"Population, total",SP.POP.TOTL,15766806,16260932,16765117,17279141,17802997,18336724,18880269,19433530,19996473,20569117,21151640,21743967,22346641,22961253,23589887,24234088,24894380,25570540,26262368,26969307
+Madagascar,MDG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,20000324221.3427,21719978128.7289,19333172594.0745,21648258647.6888,23466060029.0376,25169793768.2069,27272882274.5452,30029763756.3776,32703464533.5358,31515710894.3531,31981783671.9735,33215344356.2567,33270003412.2222,34214331592.4778,35835765900.7156,36248277778.3637,38589859315.1109,39408585195.5646,42114816931.3737,44744349303.4543
+Malawi,MWI,"Population, total",SP.POP.TOTL,11148758,11432000,11713664,12000181,12301838,12625952,12973699,13341806,13727890,14128155,14539612,14962112,15396005,15839269,16289540,16745303,17205289,17670260,18143315,18628747
+Malawi,MWI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7468702620.06217,7261461674.75702,7517169630.58197,8091700822.89291,8757644017.49567,9347339330.45314,10097467130.9573,11418403655.3996,12536347425.6092,13610993240.9149,14625812055.4388,15674391716.7311,15561165076.6142,17042708429.6565,17109325958.1925,16473997716.5332,17560554548.0402,17887349679.4659,18899964803.5179,20072440824.3269
+Malaysia,MYS,"Population, total",SP.POP.TOTL,23194257,23709119,24208391,24698819,25190652,25690611,26201961,26720370,27236006,27735040,28208035,28650955,29068159,29468872,29866559,30270962,30684804,31105028,31528585,31949777
+Malaysia,MYS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,275216955851.54,285306500876.983,307840083267.587,335817083278.505,369162507040.03,404099396996.24,446508519665.673,491378118390.59,520367694890.533,521709642166.794,560108318399.07,607129184341.237,643498757192.916,668794343781.363,710620293507.506,730292560312.552,762175793250.096,805535724414.304,857003074416.584,916167930850.023
+Maldives,MDV,"Population, total",SP.POP.TOTL,279398,286306,294186,302683,311265,319608,327487,335169,343452,353398,365734,380495,397237,415593,435015,454915,475513,496402,515696,530953
+Maldives,MDV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,2253180771.23407,2257030705.29697,2466212611.27598,2830947399.42371,3101821749.0097,2781537609.64207,3616677052.30743,3489661777.15557,4014499658.82216,3817992392.22995,4090164279.80897,4606288827.99661,4925577794.19348,5462304304.18157,6289083101.74374,7011178133.5159,7611970620.07724,8222612688.896,8867339111.63474,9491560182.08956
+Mali,MLI,"Population, total",SP.POP.TOTL,10946445,11271600,11616887,11982695,12369070,12775516,13203378,13651464,14113577,14581429,15049353,15514591,15979499,16449864,16934220,17438778,17965429,18512394,19077690,19658031
+Mali,MLI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12292742587.3803,13941544624.6624,14389781143.677,16466831473.1814,17184734582.9409,18883602839.9178,20273266451.7546,21559100729.8093,23141943944.9032,24091169427.4465,25839494612.5296,27331464772.5263,27142665899.9272,28848666641.2997,31565335369.9749,34647080536.5333,38259683413.4737,40265008470.82,43400282213.7382,46409879473.0827
+Malta,MLT,"Population, total",SP.POP.TOTL,390087,393028,395969,398582,401268,403834,405308,406724,409379,412477,414508,416268,420028,425967,434558,445053,455356,467999,484630,502653
+Malta,MLT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,7418506646.99118,7781794445.5462,8182922609.86114,8300895889.19964,8567771015.99112,8691958769.47538,9070977858.96685,9805802592.27267,10452841112.9785,10054235517.1331,10930839608.3118,11519839400.3933,11856532171.4899,12659130736.1534,13946172710.9629,15205171356.2142,16149880438.2282,17705167517.0901,19337863104.5485,20956607516.0043
+Marshall Islands,MHL,"Population, total",SP.POP.TOTL,50753,51422,52370,53456,54476,55258,55767,56051,56174,56250,56366,56531,56717,56938,57179,57439,57735,58058,58413,58791
+Marshall Islands,MHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,165195612.572103,178858139.279194,183887750.523852,185037714.030403,192632495.991304,205190881.691055,208725029.405694,220098824.178841,208418571.232958,212534146.256352,223890702.074199,225123576.183362,214374318.110595,232239330.227536,245267634.124603,271674728.831819,271055072.124151,282007133.915327,297369192.405849,..
+Mauritania,MRT,"Population, total",SP.POP.TOTL,2630219,2702400,2778099,2857148,2939247,3024194,3111906,3202517,3296238,3393409,3494195,3598648,3706554,3817494,3930896,4046301,4163534,4282574,4403319,4525696
+Mauritania,MRT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8062494581.35486,7954577709.2746,8621231271.65362,9358823794.11214,10061624427.466,11199079617.1087,13089954032.4626,13245639969.6864,13593241977.7643,13929125581.5186,14118200542.0269,14841521503.2747,15331799325.0023,16624623434.4163,16238197197.5205,16498775890.9074,19213092379.4616,21432474968.9306,22603330085.99,24201598237.4835
+Mauritius,MUS,"Population, total",SP.POP.TOTL,1186873,1196287,1204621,1213370,1221003,1228254,1233996,1239630,1244121,1247429,1250400,1252404,1255882,1258653,1260934,1262605,1263473,1264613,1265303,1265711
+Mauritius,MUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,10676157583.7624,11349047487.8424,11712469983.9639,12537796070.2914,13473040517.5956,14152520099.7114,15421530885.5241,17078312574.2382,18164830360.8768,18696525733.535,19451212765.7378,20460710909.864,22061568419.1301,24215842266.8622,25119627939.9348,26339259783.019,28287860057.6668,29764244947.5412,31591720797.2744,33423662610.0243
+Mexico,MEX,"Population, total",SP.POP.TOTL,98899845,100298153,101684758,103081020,104514932,106005203,107560153,109170502,110815271,112463887,114092963,115695473,117274155,118827161,120355128,121858258,123333376,124777324,126190788,127575529
+Mexico,MEX,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1073235252932.68,1095604356342.78,1117965544638.39,1162592493945.24,1244336432872.96,1313762682229.57,1462385582249.25,1533815706563.18,1630569413184.12,1609779367702.41,1720422018790.8,1880967839882.46,1973881601912.17,2004429620594.39,2121554563909.11,2173135864192.38,2319313166992.63,2408228099476.71,2507773305576.86,2526976501908.53
+"Micronesia, Fed. Sts.",FSM,"Population, total",SP.POP.TOTL,107402,107173,107030,106901,106625,106129,105371,104444,103543,102975,102911,103450,104506,105926,107446,108895,110215,111459,112640,113815
+"Micronesia, Fed. Sts.",FSM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,274330744.626663,284999418.801453,290109959.616858,299484123.110739,301947436.818278,319226676.36372,328724559.481847,333493224.758921,327679791.649598,343956873.213831,348030813.436505,364901630.785689,370710582.107805,374936332.76615,372922660.936786,433804248.940122,433988685.906055,442919835.259949,410132530.440214,..
+Moldova,MDA,"Population, total",SP.POP.TOTL,2923783,2917252,2910504,2902320,2895147,2888111,2880095,2873429,2867964,2864346,2861487,2859833,2859458,2858692,2856950,2834530,2802170,2755158,2706049,2657637
+Moldova,MDA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9167195706.78059,10408612000.934,11713688802.0024,12978142527.6396,14581781329.8495,16164636204.0076,17155634623.328,17763757379.5845,19615837382.5472,17892763278.7317,19629333604.2239,21128784190.6961,23013074857.4494,26216545799.9271,27399046984.958,27755535456.2499,31375154264.0507,33952683757.4524,35940478464.6157,..
+Monaco,MCO,"Population, total",SP.POP.TOTL,32147,32470,32806,33153,33500,33843,34190,34525,34872,35226,35612,36024,36460,36901,37322,37718,38070,38392,38682,38964
+Monaco,MCO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Mongolia,MNG,"Population, total",SP.POP.TOTL,2397418,2419588,2443271,2468762,2496391,2526424,2558856,2593820,2631898,2673796,2719896,2770362,2824699,2881792,2940108,2998439,3056359,3113779,3170208,3225167
+Mongolia,MNG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8899686949.80145,9391553610.59174,9975244443.39951,10828717692.8553,12322368250.5191,13422679811.4135,15135132305.2825,16951614932.9388,18668342461.7305,18345008310.043,18957879258.1345,22657114467.4965,26658538159.65,28685437151.1049,29864062852.7761,29636387676.1811,30129523615.8258,30263180633.1592,34703168653.3306,36685712934.8347
+Montenegro,MNE,"Population, total",SP.POP.TOTL,604950,607389,609828,612267,613353,614261,615025,615875,616969,618294,619428,620079,620601,621207,621810,622159,622303,622373,622227,622137
+Montenegro,MNE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3815820961.53465,4319638788.8936,4572037360.65309,4751054728.33324,5053944157.5054,5163071370.90954,6531914408.90913,7754226149.23701,8651061175.76346,8073045361.63993,8396291053.15587,9043804769.49049,8750795311.96759,9418324721.96317,9681732511.98603,10387848814.9118,11349484804.517,12469071660.1303,13368506304.4132,14351582083.5051
+Morocco,MAR,"Population, total",SP.POP.TOTL,28793679,29126330,29454768,29782884,30115214,30455561,30804683,31163673,31536811,31929087,32343389,32781850,33241898,33715693,34192347,34663603,35126296,35581294,36029138,36471769
+Morocco,MAR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,102139393685.103,112143605945.752,117850272775.3,127470176032.388,137696016577.266,147428033609.745,163209815787.65,173852230262.43,188005555834.369,195167799335.246,204980497057.706,219548856240.118,221558465714.716,233442913596.092,224028206132.59,242479228111.022,248808416563.671,259109842934.255,272757048440.112,284421831344.95
+Mozambique,MOZ,"Population, total",SP.POP.TOTL,17711927,18221888,18764155,19331100,19910552,20493925,21080110,21673316,22276596,22894710,23531574,24187487,24862648,25560725,26286163,27042002,27829942,28649007,29495962,30366036
+Mozambique,MOZ,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8177278563.09204,9291411717.77773,9617646908.39962,11422907502.7249,12491543387.1564,13695474387.5857,15041398362.5616,16864703666.6215,18557527238.3764,20461548618.2714,21874221272.845,24418498649.582,25627038662.8078,27637299640.6561,29600102418.1981,34268684504.4287,37128572437.6555,35680284784.8543,38152005615.3217,39514921646.4828
+Myanmar,MMR,"Population, total",SP.POP.TOTL,46719701,47225120,47702171,48148902,48564484,48949924,49301050,49621475,49929642,50250367,50600818,50990615,51413698,51852451,52280807,52680726,53045226,53382581,53708395,54045420
+Myanmar,MMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,42998704281.2578,48895682639.9269,55658008629.222,64546445659.4268,75283770159.7116,88147560822.8466,102711602963.393,118133238390.898,132774469874.273,147912395072.948,164058393039.433,176855931603.602,184010746021.877,201685064985.604,213072891301.063,225644892096.516,231990221765.927,245826346688.426,266686901622.871,278799517936.018
+Namibia,NAM,"Population, total",SP.POP.TOTL,1794571,1823672,1851523,1879117,1907745,1938320,1971317,2006514,2043394,2081044,2118874,2156701,2194784,2233510,2273430,2314904,2358041,2402603,2448255,2494530
+Namibia,NAM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,9461417729.10618,9704517286.30121,10497547733.6128,11532212592.3895,12799913294.0378,13158659131.6424,14629437172.4061,15355658838.1761,16106047718.351,16234948337.9654,17069770941.2428,18530827058.6351,19680724579.4145,21629943604.1853,23507845287.3846,24438808197.0287,23975062172.4607,23704551385.4182,24124209500.1929,24332228767.2588
+Nauru,NRU,"Population, total",SP.POP.TOTL,10337,10215,10102,9994,9902,9849,9828,9842,9891,9939,10005,10057,10279,10821,11853,12475,13049,12876,12704,12581
+Nauru,NRU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,48522152.1314013,54333382.4566256,62796220.0520194,72021093.9621256,82081790.6299373,92329590.9487578,126031537.580759,158718129.621484,186738281.898791,194764542.336288,192543303.233466,200349004.70439,223877727.761513
+Nepal,NPL,"Population, total",SP.POP.TOTL,23941110,24347106,24725627,25080872,25419344,25744500,26066693,26382581,26666576,26883535,27013212,27041437,26989862,26917906,26906926,27015031,27261131,27627124,28087871,28608710
+Nepal,NPL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,28462645242.8133,30497155115.9188,30857012519.5828,32668135049.4057,35056496303.3967,37628037997.5669,40262954104.2367,42866801599.5967,46346893790.9807,48920897553.2459,51657022296.6501,54425821378.1911,59206619399.8804,63735009673.0611,70944811652.5188,72284863170.6641,71476639814.489,86617232592.1683,94213081915.6352,102978116883.077
+Netherlands,NLD,"Population, total",SP.POP.TOTL,15925513,16046180,16148929,16225302,16281779,16319868,16346101,16381696,16445593,16530388,16615394,16693074,16754962,16804432,16865008,16939923,17030314,17131296,17231624,17332850
+Netherlands,NLD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,516852632560.376,530138233974.21,554795790258.896,559371407910.287,585814485091.078,605553877381.32,674800594293.726,718720604254.588,741916192385.952,730026618589.592,751121005301.854,788764031504.728,805602323121.561,838682680044.001,828263670286.029,852766433552.616,877231222533.962,955329960975.533,1001782586018.43,1038101146971.03
+New Caledonia,NCL,"Population, total",SP.POP.TOTL,213230,217324,221490,225296,228750,232250,235750,239250,242750,245950,249750,254350,259000,263650,268050,272400,276550,280350,284060,287800
+New Caledonia,NCL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+New Zealand,NZL,"Population, total",SP.POP.TOTL,3857700,3880500,3948500,4027200,4087500,4133900,4184600,4223800,4259800,4302600,4350700,4384000,4408100,4442100,4509700,4595700,4693200,4793900,4841000,4917000
+New Zealand,NZL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,78297997495.1371,82895606558.8895,87389067382.274,91938827508.2597,96743282770.2947,99289747947.8827,108365512926.595,115278120752.581,117980470098.457,126670076884.423,129222027987.92,137009721215.547,139353582322.271,154545145745.547,161245340209.477,166416913074.36,181297312894.525,188551971011.741,196320021186.878,209984738791.131
+Nicaragua,NIC,"Population, total",SP.POP.TOTL,5069302,5145366,5219328,5292118,5364935,5438690,5513763,5590055,5667432,5745526,5824065,5903039,5982526,6062454,6142733,6223240,6303974,6384855,6465513,6545502
+Nicaragua,NIC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,13551689562.5361,14175391303.2217,14595236258.185,15275517390.3171,16590298964.1512,18013422032.0332,19166977602.7244,20799600129.2365,21938409049.3694,21273341014.7148,22524861033.4143,24463198980.6977,25699434373.9683,27117096696.4901,29554114307.5316,32052201357.1565,34930273712.1284,37321575970.9361,36795945821.0625,35912875866.6251
+Niger,NER,"Population, total",SP.POP.TOTL,11331557,11751365,12189983,12647984,13125916,13624467,14143971,14685399,15250908,15843133,16464025,17114761,17795191,18504255,19240157,20001663,20788838,21602472,22442948,23310715
+Niger,NER,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8714860645.95476,9552399306.82228,10138387467.8598,10594090476.5142,10964936351.8009,12128424678.4221,13255769670.171,14029535704.455,15375100180.8419,15746564890.2164,17256415648.2066,18029695404.0462,20177762093.9889,20344757760.6248,21572931440.3123,22505341600.1021,23343586015.5258,24686639908.752,27072874800.407,29152889262.2637
+Nigeria,NGA,"Population, total",SP.POP.TOTL,122283850,125394046,128596076,131900631,135320422,138865016,142538308,146339977,150269623,154324933,158503197,162805071,167228767,171765769,176404902,181137448,185960289,190873311,195874740,200963599
+Nigeria,NGA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,255167279361.791,287090811451.007,333028660553.987,360317164880.447,404128100283.132,441651874500.752,514815673971.723,548857256333.924,596032621496.002,645180793759.501,705437181551.46,756939368351.467,793230176344.865,853026950842.773,939073115447.917,957051778143.622,952515802712.001,960398587580.009,985893533546.953,1039633150748.45
+North Macedonia,MKD,"Population, total",SP.POP.TOTL,2034819,2042842,2048928,2053426,2057048,2060273,2063131,2065426,2067313,2069039,2070741,2072487,2074278,2076067,2077775,2079328,2080745,2081996,2082958,2083459
+North Macedonia,MKD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,12238988709.6306,12225602597.4537,12773034002.9162,13191014714.2916,14473791893.2768,15708331655.17,17637727880.3566,18197783997.2061,21276861035.5934,22438920029.9913,23036881953.5352,23634727508.5267,24027034149.675,25647250304.1644,27256380190.9792,27852753382.988,29935058684.5946,31050642917.5775,32956753946.2663,35649539595.7626
+Northern Mariana Islands,MNP,"Population, total",SP.POP.TOTL,57453,58321,58420,57947,57246,56542,55882,55219,54625,54193,53971,54012,54311,54784,55305,55780,56188,56562,56882,57216
+Northern Mariana Islands,MNP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Norway,NOR,"Population, total",SP.POP.TOTL,4490967,4513751,4538159,4564855,4591910,4623291,4660677,4709153,4768212,4828726,4889252,4953088,5018573,5079623,5137232,5188607,5234519,5276968,5311916,5347896
+Norway,NOR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,163809179058.287,170711385468.446,172786645952.789,176976439531.853,195462041977.103,223283670197.81,252184206505.928,262393276835.26,293138235484.347,269379259626.725,286645665285.929,310701643205.307,331152578513.979,344244308199.849,349842613934.341,327034783599.997,323725133589.202,346868275225.434,374631286747.306,372280312640
+Oman,OMN,"Population, total",SP.POP.TOTL,2267973,2294962,2334858,2386166,2445517,2511251,2580758,2657158,2750963,2876186,3041434,3251108,3498029,3764805,4027260,4267348,4479219,4665935,4829483,4974986
+Oman,OMN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,79235959658.9843,84792834710.2019,83788314286.2636,85062122358.5598,89353502794.7445,92634966923.2222,93601614783.524,109511564811.834,118168477362.654,124411096039.846,135387404024.282,132708609162.248,146975065405.124,152666415184.438,147843100201.919,130046463464.616,125897322209.259,130111645478.941,131938237838.467,142211422700.939
+Pakistan,PAK,"Population, total",SP.POP.TOTL,142343578,145978402,149549700,153093373,156664697,160304008,164022627,167808105,171648986,175525609,179424641,183340592,187281475,191262919,195306825,199426964,203627284,207896686,212215030,216565318
+Pakistan,PAK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,369404406240.034,390735821486.68,413800532806.37,456384783128.01,499973931899.76,548501914890.354,597908005939.994,642892692086.748,668239001725.966,696878190114.575,724599627456.603,765039210300.823,791513506615.346,825590569865.228,874802211343.66,925319864050.729,953080148747.716,1002293170997.4,1084494813277.11,1129050343318.84
+Palau,PLW,"Population, total",SP.POP.TOTL,19105,19386,19637,19809,19867,19781,19540,19158,18704,18285,17955,17745,17640,17606,17626,17665,17725,17808,17907,18008
+Palau,PLW,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,211174302.999241,231341383.494551,243185969.15795,234267703.220008,248076627.110369,277293585.650191,280418827.087255,297040146.220095,281668462.888573,261976812.537098,264596331.229319,284241777.903655,291833954.423022,288531087.6412,304879733.34836,343944205.490429,348201991.112564,334258725.644689,349137795.900517,..
+Panama,PAN,"Population, total",SP.POP.TOTL,3030328,3089648,3149188,3209048,3269356,3330217,3391666,3453675,3516204,3579215,3642687,3706483,3770624,3835437,3901315,3968487,4037078,4106771,4176873,4246439
+Panama,PAN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,24364003728.1015,24908792800.3642,26735195721.2458,27517726690.2089,29907517284.4004,32560340306.6999,36430564546.1268,42470623777.3447,47512762926.5939,48805783548.6948,50865949437.0556,59266837875.6713,65663109755.6884,74726193766.6597,81538689297.7009,94068749851.9453,104322439879.142,117512813377.254,122715775285.123,129953036259.725
+Papua New Guinea,PNG,"Population, total",SP.POP.TOTL,5847586,5974629,6098621,6223377,6354245,6494903,6646895,6808514,6976201,7144776,7310507,7472200,7631002,7788379,7946731,8107775,8271760,8438029,8606316,8776109
+Papua New Guinea,PNG,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,11689909083.4728,11782139184.0131,11994999914.5765,12150356962.7707,13004301436.2799,14494469656.1726,14951336412.6804,16961711049.4465,17553793000.7478,18537466557.8058,20624546301.5549,20754466387.4553,23205469528.6527,23757281549.9278,29386596489.9702,32487579217.8286,34430674713.5218,36008809638.6283,36332291730.6946,39228382939.1454
+Paraguay,PRY,"Population, total",SP.POP.TOTL,5323201,5428444,5531962,5632983,5730549,5824096,5913209,5998427,6081296,6163972,6248020,6333976,6421512,6510276,6599526,6688746,6777872,6867062,6956071,7044636
+Paraguay,PRY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,30966339106.0611,31994514394.7487,33425791560.7727,32955404968.9342,35879600552.2512,38014665154.8201,42442719141.0924,48119399684.98,52810030726.6891,52893580251.9813,59469808606.6031,64133125073.6599,61591935539.7893,69297872980.2731,72664615483.7895,73852324239.6658,78266222662.4423,83809237145.5088,88410573254.3939,89650321681.415
+Peru,PER,"Population, total",SP.POP.TOTL,26459944,26799285,27100968,27372226,27624213,27866145,28102056,28333052,28562317,28792655,29027674,29264318,29506788,29773987,30090359,30470734,30926032,31444297,31989256,32510453
+Peru,PER,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,130452271472.573,134975718985.549,143784908887.532,151002976641.214,159597818097.476,172777044632.864,187599814291.07,209846929295.68,235569614896.216,241692558655.719,261705337880.59,283964927266.9,297710295468.343,318997109857.16,330667402340.409,340543090251.254,356119980475.884,375165985596.124,397984077099.888,414709560947.683
+Philippines,PHL,"Population, total",SP.POP.TOTL,77991755,79672873,81365258,83051971,84710542,86326250,87888675,89405482,90901965,92414158,93966780,95570047,97212638,98871552,100513138,102113212,103663927,105173264,106651922,108116615
+Philippines,PHL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,293546466765.911,309550000698.454,326006799824.386,348562292415.459,381170730382.479,414099437803.561,447011843666.261,487974807198.051,520920551839.16,543111526839.69,588000732556.72,621050497570.767,679680535110.927,730910824409.234,780292861533.854,817730803198.514,887291422586.415,948319217869.441,1028799416150.81,1102793818348.89
+Poland,POL,"Population, total",SP.POP.TOTL,38258629,38248076,38230364,38204570,38182222,38165445,38141267,38120560,38125759,38151603,38042794,38063255,38063164,38040196,38011735,37986412,37970087,37974826,37974750,37970874
+Poland,POL,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,405928263952.82,423264851972.431,447988845729.653,462987927844.742,493324802124.358,521485118561.573,565480839451.024,620520684705.345,684955242060.901,714162622184.593,775270582482.123,841563674071.179,878904423194.261,912005652523.057,940604094068.281,985374945527.231,1029371304856.61,1098727031189.92,1159006118404.7,1242060092704.4
+Portugal,PRT,"Population, total",SP.POP.TOTL,10289898,10362722,10419631,10458821,10483861,10503330,10522288,10542964,10558177,10568247,10573100,10557560,10514844,10457295,10401062,10358076,10325452,10300300,10283822,10269417
+Portugal,PRT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,191162333476.579,198946163123.708,208897263871.468,215655339291.813,222139978722.147,235520718575.134,252037472169.304,263235461915.183,272098077805.794,270543878824.239,279258685479.183,278041334782.043,271411027125.957,288230115471.542,292835641286.096,299068874296.756,318403967634.571,332797030443.435,344450702228.985,365570407715.063
+Puerto Rico,PRI,"Population, total",SP.POP.TOTL,3810605,3818774,3823701,3826095,3826878,3821362,3805214,3782995,3760866,3740410,3721525,3678732,3634488,3593077,3534874,3473232,3406672,3325286,3193354,3193694
+Puerto Rico,PRI,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,58733761399.7069,60499957634.4599,61323055387.3295,63015448424.3178,71561555530.5919,73282972901.7744,75473206025.0908,78275161095.6972,77428186151.7523,75399861663.9094,75213919309.895,76671237933.7386,79385642494.7194,80211595023.5961,79957879558.6487,79546562680.8065,78484982368.6929,76274336611.4748,74901136510.2749,77400156028.063
+Qatar,QAT,"Population, total",SP.POP.TOTL,592468,615012,640868,681788,753334,865416,1022711,1218434,1436665,1654950,1856327,2035871,2196074,2336574,2459198,2565710,2654374,2724724,2781677,2832067
+Qatar,QAT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,52844271826.9036,58463640090.606,63242264101.0028,68819473320.729,79713467127.8268,82868542815.173,116922772698.625,141763238425.186,169063300616.692,183106008515.175,219766713179.047,261273859967.584,290855609268.645,306141143057.52,303091258041.229,233271012036.937,218972340599.152,258357181046.802,263812622499.6,266700904932.535
+Romania,ROU,"Population, total",SP.POP.TOTL,22442971,22131970,21730496,21574326,21451748,21319685,21193760,20882982,20537875,20367487,20246871,20147528,20058035,19983693,19908979,19815616,19702267,19587290,19472545,19356544
+Romania,ROU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,130472172572.504,143525926780.149,154082024275.708,159114026184.779,184591713992.08,198702374392.595,236462450561.554,276553017265.441,337097295551.8,334769233393.309,339699138901.25,356201879783.7,373165708242.957,389853277154.31,408658360571.476,424138786650.093,469815748811.334,525047398922.873,558400088938.719,616613186039.27
+Russian Federation,RUS,"Population, total",SP.POP.TOTL,146596869,145976482,145306497,144648618,144067316,143518814,143049637,142805114,142742366,142785349,142849468,142960908,143201721,143506995,143819666,144096870,144342396,144496740,144477860,144373535
+Russian Federation,RUS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,974627421657.533,1059732182384.88,1145642785078.87,1297686739857.67,1441505486256.06,1655585780417.93,2071121544039.89,2324720237537.22,2797648415289.07,2678612196782.56,2836588557941.65,3163098238397.45,3373670140327.24,3611852783384.38,3639329873431.79,3428605724107.56,3440199770765.34,3716761165251.31,4117644726224.44,4147418036811.93
+Rwanda,RWA,"Population, total",SP.POP.TOTL,7933681,8231156,8427060,8557161,8680524,8840215,9043337,9273757,9524534,9782770,10039338,10293331,10549678,10811543,11083635,11369071,11668818,11980937,12301939,12626950
+Rwanda,RWA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4984792289.7506,5500814446.43183,6338268240.37365,6563522975.55199,7246003555.12871,8218101871.06816,9266024423.53704,10286566958.1852,11627479925.1191,12451755242.7965,13514588518.7971,14874456674.8466,15585133904.4704,16472104845.2448,18592434064.2187,20138529720.0947,21541809782.4229,22875986390.5019,25446588408.2789,28336853127.1914
+Samoa,WSM,"Population, total",SP.POP.TOTL,174454,175392,176407,177484,178590,179727,180876,182046,183263,184556,185949,187469,189088,190717,192221,193513,194535,195352,196130,197097
+Samoa,WSM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,656129200.01375,696240495.485358,751718146.21322,801018193.39023,846404986.284917,928759783.297955,955315073.519703,929986181.882017,966999334.423705,1020029218.05116,999743394.357344,1012610226.03282,1028640510.18319,1105495733.50317,1204016754.89651,1228314510.95016,1224208932.24003,1279066000.93285
+San Marino,SMR,"Population, total",SP.POP.TOTL,27462,27812,28175,28562,28940,29324,29700,30063,30434,30816,31229,31661,32105,32553,32948,33272,33504,33671,33785,33860
+San Marino,SMR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Sao Tome and Principe,STP,"Population, total",SP.POP.TOTL,142262,144755,147447,150415,153737,157472,161681,166300,171120,175876,180371,184524,188404,192087,195727,199432,203227,207089,211028,215056
+Sao Tome and Principe,STP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,255566703.745449,266396208.879123,293566638.415525,312266708.951805,346807903.39736,406883199.131625,435108912.704917,465728182.537504,480121037.051648,520459226.461073,554945829.681376,546308664.914749,642962268.2136,759370095.927575,762889548.330079,792597147.710333,808509263.027399,857082098.90257,879111457.332912
+Saudi Arabia,SAU,"Population, total",SP.POP.TOTL,20663843,21202642,21805313,22456649,23132682,23816183,24498310,25184597,25888541,26630303,27421461,28267685,29155187,30052518,30916994,31717667,32442572,33099147,33699947,34268528
+Saudi Arabia,SAU,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,828007290113.436,840020779517.361,826977992567.345,933840294734.223,1038617818410.17,1132480997433.1,1201557784745.03,1263098264835.91,1371180088329.22,1356509577662.19,1431867717296.31,1609641504262.52,1697441893442.77,1710674757214.71,1760505609319.99,1582553691883.64,1511656088328.92,1590219406270.97,1656706098593.48,1692868359986.68
+Senegal,SEN,"Population, total",SP.POP.TOTL,9797734,10036104,10283699,10541467,10810083,11090116,11382268,11687080,12004701,12335084,12678148,13033809,13401991,13782420,14174731,14578459,14993528,15419381,15854360,16296364
+Senegal,SEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18178582368.0147,19481388776.3261,19869524048.5466,21683767086.4729,23621693059.632,25746288414.5148,27254286825.51,29373991072.7734,31233432098.6014,31884539097.273,33445704638.302,34415226315.3097,36427222864.5151,37245933448.3051,39358815590.1772,42363282419.3143,44911708617.1489,48020557391.9318,52402629738.2478,56113568116.7654
+Serbia,SRB,"Population, total",SP.POP.TOTL,7516346,7503433,7496522,7480591,7463157,7440769,7411569,7381579,7350222,7320807,7291436,7234099,7199077,7164132,7130576,7095383,7058322,7020858,6982604,6944975
+Serbia,SRB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,45257309352.7367,48680377685.7187,53939449146.4194,56788712102.6038,62763575041.0969,67522226305.9422,74612237515.9374,81280923359.4795,90437964699.0743,90424045371.6504,91388968100.1562,97317586786.9039,97051558828.03,100740901038.093,100572891480.162,100962636045.149,104942550019.958,108471457604.254,116392549752.424,124763538712.68
+Seychelles,SYC,"Population, total",SP.POP.TOTL,81131,81202,83723,82781,82475,82858,84600,85033,86956,87298,89770,87441,88303,89949,91359,93419,94677,95843,96762,97625
+Seychelles,SYC,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1098286181.45465,1123976238.77417,1072994332.88678,1070267506.04422,1149808132.7252,1291667524.3807,1455225335.13926,1520789181.16357,1496927786.61198,1517612379.40579,1646832585.13231,1704881468.35025,1796647364.37891,1907297426.10617,2048795965.28169,2112360163.7696,2245383379.7948,2417588949.83326,2642281618.23683,2860121340.79797
+Sierra Leone,SLE,"Population, total",SP.POP.TOTL,4584571,4754072,4965766,5201070,5433991,5645624,5829237,5989633,6133603,6272734,6415634,6563240,6712581,6863980,7017144,7171914,7328838,7488431,7650154,7813215
+Sierra Leone,SLE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3078355090.61565,2965062693.69484,3811355840.48297,4263196038.6237,4654050423.97535,5010794994.08064,5398188175.35187,6410544320.37155,7077507452.6414,7414307697.09276,7356159783.30807,7786542195.82346,9738223472.1891,11922760797.3981,12246518774.9448,11226733103.7828,10434653657.3075,11938865734.8629,12110858455.1451,13013830059.0806
+Singapore,SGP,"Population, total",SP.POP.TOTL,4027887,4138012,4175950,4114826,4166664,4265762,4401365,4588599,4839396,4987573,5076732,5183688,5312437,5399162,5469724,5535002,5607283,5612253,5638676,5703569
+Singapore,SGP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,175475990155.213,177305489495.705,184670988377.651,195292440542.546,212571173695.197,236301952480.521,273662417679.57,306624365777.701,315001406844.762,312810004079.337,378119206245.336,400707778808.442,416578549823.047,424002358121.386,445708256666.976,448557736908.24,469524071593.093,492395261470.978,509997637667.539,524841789129.782
+Sint Maarten (Dutch part),SXM,"Population, total",SP.POP.TOTL,30519,30600,30777,31472,32488,33011,33441,33811,33964,34238,34056,33435,34640,36607,37685,38825,39969,40574,40654,40733
+Sint Maarten (Dutch part),SXM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,1076306314.50851,1122314269.16244,1198407915.49339,1102057764.20802,1162505139.99796,1190232152.72171,1202403006.88066,1249433536.30347,1271575989.66521,..,..
+Slovak Republic,SVK,"Population, total",SP.POP.TOTL,5388720,5378867,5376912,5373374,5372280,5372807,5373054,5374622,5379233,5386406,5391428,5398384,5407579,5413393,5418649,5423801,5430798,5439232,5446771,5454073
+Slovak Republic,SVK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,61083993049.9732,66695266134.4753,71403065665.9981,72449990182.4595,78596910447.9461,87124402574.7501,98687707671.112,110791194181.167,125448397000.54,123782220565.48,132884290981.565,135779454075.477,143192037531.068,150266637346.169,155347191663.989,158380009238.59,156843605003.527,164629105049.078,174577152157.9,183677613789.773
+Slovenia,SVN,"Population, total",SP.POP.TOTL,1988925,1992060,1994530,1995733,1997012,2000474,2006868,2018122,2021316,2039669,2048583,2052843,2057159,2059953,2061980,2063531,2065042,2066388,2073894,2087946
+Slovenia,SVN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,35729557107.8743,37731226284.5409,40019698741.2693,41640522811.3764,44778206419.9901,47268194743.7862,50908423708.2664,54304531861.8556,58273321247.2921,55289538407.1433,56288187891.8793,58585332628.1712,58814142549.4361,60918129358.2224,63069203941.5599,63269913868.7162,68163693508.2576,74364570119.803,79094983841.5059,83673941284.5428
+Solomon Islands,SLB,"Population, total",SP.POP.TOTL,412660,423944,435432,447017,458539,469918,481078,492132,503360,515181,527861,541521,556064,571335,587079,603118,619437,636038,652858,669823
+Solomon Islands,SLB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,597042746.99174,564444388.911496,550780216.702815,599190432.338696,653597529.487548,706272886.359672,782325081.078124,793884373.867199,788273467.581486,648372862.966105,705271651.226785,806095347.634749,1043039428.16338,1162171508.2969,1220489346.74271,1309260656.27858,1331857667.45131,1415196530.19378,1511697179.24996,1571505892.80681
+Somalia,SOM,"Population, total",SP.POP.TOTL,8872254,9186725,9501342,9815412,10130243,10446863,10763905,11080121,11397188,11717692,12043883,12376302,12715510,13063706,13423576,13797201,14185613,14589119,15008154,15442905
+Somalia,SOM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+South Africa,ZAF,"Population, total",SP.POP.TOTL,44967708,45571274,46150913,46719196,47291610,47880601,48489459,49119759,49779471,50477011,51216964,52004172,52834005,53689236,54545991,55386367,56203654,57000451,57779622,58558270
+South Africa,ZAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,338847762431.791,352904893533.235,374285459134.666,391615137940.236,423687771963.7,459794907520.686,500389947330.619,533806362211.562,562391385126.517,563023437602.228,587540655891.057,616821696796.998,619739350156.296,650936442976.243,664730482950.131,677999059197.49,688184240521.716,702384466248.083,723410417860.139,739743880215.4
+South Sudan,SSD,"Population, total",SP.POP.TOTL,6199394,6447793,6688226,6935676,7213351,7535932,7907406,8315139,8736939,9142259,9508364,9830698,10113647,10355036,10554883,10715658,10832512,10910759,10975920,11062113
+South Sudan,SSD,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,16038626934.766,14790639635.8154,20542512085.5034,13514791883.5209,..,..,..,..,..
+Spain,ESP,"Population, total",SP.POP.TOTL,40567864,40850412,41431558,42187645,42921895,43653155,44397319,45226803,45954106,46362946,46576897,46742697,46773055,46620045,46480882,46444832,46484062,46593236,46797754,47076781
+Spain,ESP,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,869690668123.322,924904237114.657,998316071948.184,1046820524829.82,1110664109889.25,1188490567999.29,1337056206794.54,1430968449422.51,1486151637639.11,1460812824691.15,1455146268303.33,1463308449873.9,1471780320471.5,1501976882039.12,1552593080187.63,1621139938786.75,1737321244918,1843525333993.54,1898750653984.1,1991315629473.24
+Sri Lanka,LKA,"Population, total",SP.POP.TOTL,18777601,18911730,19062482,19224037,19387153,19544988,19695972,19842044,19983984,20123508,20261737,20398670,20425000,20585000,20778000,20970000,21203000,21444000,21670000,21803000
+Sri Lanka,LKA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,80219612592.163,80707690509.369,85438265093.8054,92694593586.4605,100298785212.344,109652264522.375,121471812831.66,133547831409.968,142604716518.666,150406486461.344,164223838599.756,181910599698.272,206950552659.399,218124451812.083,228565788492.023,236279911702.493,252283568160.724,262709274806.972,277615620224.671,288411260724.197
+St. Kitts and Nevis,KNA,"Population, total",SP.POP.TOTL,44074,44599,45165,45746,46324,46857,47339,47778,48185,48599,49016,49447,49887,50331,50774,51203,51625,52045,52441,52823
+St. Kitts and Nevis,KNA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,668626627.030419,718436252.546109,744762582.945911,721796119.49235,785342872.453035,900477813.981571,946785397.017441,983506390.046433,1063395727.80758,1028244449.31807,1041414759.68333,1085010859.5522,1040073570.95555,1095520084.77226,1126413064.05166,1138913288.5063,1209135630.0354,1253585607.5405,1313202217.63159,1369275749.82975
+St. Lucia,LCA,"Population, total",SP.POP.TOTL,156729,158179,159392,160530,161816,163417,165381,167639,170011,172221,174085,175544,176646,177513,178296,179126,180024,180955,181889,182790
+St. Lucia,LCA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1305855310.53088,1270824912.50597,1312264068.35251,1379897600.78669,1502713457.62692,1544835895.79416,1839801165.1013,1904808814.05479,2039871225.17556,2034633287.52068,2103475539.04643,2297809125.759,2256310219.44242,2340104825.45271,2304068263.59932,2220169455.30641,2413769769.05196,2558643206.97483,2670955788.03675,2767313822.83397
+St. Martin (French part),MAF,"Population, total",SP.POP.TOTL,28935,29853,30910,32053,33186,34248,35237,36137,36885,37377,37582,37446,37009,36453,36015,35858,36065,36560,37264,38002
+St. Martin (French part),MAF,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+St. Vincent and the Grenadines,VCT,"Population, total",SP.POP.TOTL,107784,107896,108097,108326,108512,108614,108603,108518,108393,108287,108255,108316,108435,108622,108861,109148,109459,109827,110210,110589
+St. Vincent and the Grenadines,VCT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,638159376.525602,670314466.444616,724127161.498021,784916407.357878,833178925.141251,883240113.601914,992034020.254062,1063625110.3998,1100704108.7646,1101047803.34189,1077900540.92904,1094556250.36243,1127672288.17059,1178894343.25033,1180712569.46047,1240035784.97745,1354300475.1646,1335277351.37259,1392156097.48341,1424298575.54419
+Sudan,SDN,"Population, total",SP.POP.TOTL,27275015,27971082,28704778,29460519,30214193,30949516,31661823,32360621,33060837,33783788,34545013,35349681,36193783,37072550,37977655,38902950,39847440,40813396,41801533,42813238
+Sudan,SDN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,58212531297.298,63680735170.4652,68910959486.9048,74978164139.573,79768301290.8968,88320710528.3167,93942762350.271,112239021245.355,119548408750.404,127090687572.071,130164486506.18,138252289994.32,142798888417.107,147780281950.933,177192917844.649,193305122554.049,173012156095.499,171572486184.966,165149037086.917,170741468621.492
+Suriname,SUR,"Population, total",SP.POP.TOTL,470949,476579,482235,487942,493679,499464,505295,511181,517123,523111,529131,535179,541245,547291,553273,559143,564888,570496,575991,581372
+Suriname,SUR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,3455101779.96144,3452172053.5285,3869264165.22239,4192975496.85693,4655634374.65597,5102119078.97652,5547176744.27413,6108812235.51674,6528902952.26631,6746376489.35332,6997716781.20293,7287563034.49645,8213418033.82234,8968094623.77967,9422022464.70498,8961754691.65336,7598415769.13654,8178387430.85907,8695356897.78605,8836767171.57063
+Sweden,SWE,"Population, total",SP.POP.TOTL,8872109,8895960,8924958,8958229,8993531,9029572,9080505,9148092,9219637,9298515,9378126,9449213,9519374,9600379,9696110,9799186,9923085,10057698,10175214,10285453
+Sweden,SWE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,261536194358.147,265039091713.136,275242719220.112,287729555181.962,303981183172.221,311479619232.968,348755955764.149,382516435235.849,400366853301.737,382465021963.24,406622962140.547,429144502027.467,441172311031.33,452932249986.944,465812418766.259,483754081559.8,503345052823.841,539004902592.682,557021173354.563,589328987811.607
+Switzerland,CHE,"Population, total",SP.POP.TOTL,7184250,7229854,7284753,7339001,7389625,7437115,7483934,7551117,7647675,7743831,7824909,7912398,7996861,8089346,8188649,8282396,8373338,8451840,8514329,8574832
+Switzerland,CHE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,274014758779.276,276467718717.679,282083618928.972,294968201481.081,307427849499.894,327059401274.082,362697631526.67,377896938305.799,375881421641.219,408827811088.838,439965969368.288,449676395959.064,472965119580.052,496497257704.326,509076701038.649,542121799886.034,553301058576.508,573779624920.909,597120517941.947,620733021180.849
+Syrian Arab Republic,SYR,"Population, total",SP.POP.TOTL,16410848,16766561,17084632,17415214,17827825,18361176,19059258,19878254,20664038,21205873,21362529,21082966,20442541,19584274,18715672,17997408,17453933,17068002,16906283,17070135
+Syrian Arab Republic,SYR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+Tajikistan,TJK,"Population, total",SP.POP.TOTL,6216341,6318513,6426867,6541547,6662389,6789321,6922587,7062672,7209930,7364753,7527394,7697510,7874835,8059769,8252833,8454028,8663579,8880268,9100837,9321018
+Tajikistan,TJK,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,6243952520.11311,6956391457.58099,7940888916.07205,8865335640.46874,10232161892.1305,13315140659.5813,15606010070.8765,17958659371.2663,20015975062.9807,19445730700.2787,21650983633.0307,24502585880.9376,27649805633.739,32099463306.2014,33792660554.7335,30205900190.8183,31326779891.4301,32094206010.1166,35042775748.5525,38186407402.8905
+Tanzania,TZA,"Population, total",SP.POP.TOTL,33499180,34385856,35334788,36337782,37379767,38450320,39548663,40681414,41853944,43073834,44346525,45673338,47052481,48482266,49959822,51482633,53050790,54663906,56318348,58005463
+Tanzania,TZA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,38397497776.3668,41037773111.773,45408862707.0621,49045752787.4878,54090494683.7852,59610581601.6123,66631583817.7983,72197977275.5116,77918987309.6057,82734318300.1854,88300340612.0959,97002460359.7256,94529738375.3637,101725607824.693,107031002837.467,115147236257.427,124836678462.57,131217326623.384,140452391887.359,152044786430.903
+Thailand,THA,"Population, total",SP.POP.TOTL,62952642,63539196,64069087,64549866,64995299,65416189,65812536,66182067,66530984,66866839,67195028,67518382,67835957,68144501,68438730,68714511,68971331,69209858,69428524,69625582
+Thailand,THA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,450671563297.021,472410644012.811,505623430896.062,548768048123.199,597376671474.052,640844956966.608,698598604407.005,758824843683.545,784949891095.53,786634662277.215,849519757331.666,890774204971.964,962565591015.47,982839168917.538,1004937587069.8,1031139449774.92,1092384223464.17,1151656441215.65,1223157479632.06,1289400494111.78
+Timor-Leste,TLS,"Population, total",SP.POP.TOTL,884366,901214,922694,947108,971893,995135,1016432,1036392,1055431,1074277,1093523,1113151,1132994,1153295,1174331,1196302,1219288,1243261,1267972,1293119
+Timor-Leste,TLS,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1574774048.15707,1767734817.44826,2044643608.94684,1699848000.03095,2006516904.24496,2521021245.83139,3906319048.15135,5595452624.68354,8809236374.25167,6735167351.45591,8100273342.80888,10105478690.9941,9860410997.89224,8520034074.72098,7368662501.18337,6107945596.37407,5170878011.18355,5580941212.39929,5730167599.59686,6112136222.45617
+Togo,TGO,"Population, total",SP.POP.TOTL,4924402,5062567,5197031,5330639,5467766,5611640,5762880,5920359,6083420,6250835,6421679,6595943,6773807,6954721,7137997,7323158,7509952,7698475,7889094,8082366
+Togo,TGO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,4695495615.47244,4836298686.31055,5137495675.78138,5593950603.09644,5666656648.11381,5567283011.38162,5883941545.60747,5999557769.79647,6408670137.09282,6807580411.75893,7298190564.58075,8463956228.3191,8325342477.13935,8921364449.72602,9577642653.30672,10577120513.5998,11023673694.766,11687035212.7357,12582724939.5682,13484391446.6806
+Tonga,TON,"Population, total",SP.POP.TOTL,97973,98487,99022,99589,100218,100905,101706,102581,103379,103890,103986,103562,102737,101768,101028,100781,101133,101998,103197,104494
+Tonga,TON,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,357784199.303927,377866597.727363,406910565.468162,419272791.525725,430706598.859729,445193709.253949,463102117.302844,458561607.97632,480222408.819444,500093429.134895,524842935.725519,548648424.397204,564662549.7069,554335176.241438,566434537.234819,595653508.202184,620025178.090875,654945658.379999,672020199.921711,..
+Trinidad and Tobago,TTO,"Population, total",SP.POP.TOTL,1267153,1271632,1277213,1283559,1290123,1296502,1302561,1308451,1314443,1320930,1328147,1336178,1344817,1353700,1362342,1370328,1377564,1384072,1389858,1394973
+Trinidad and Tobago,TTO,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,17012875951.3096,18424051120.37,20369750460.5276,23569565343.3526,26971078774.8305,28938122258.8779,33665145927.3679,36491422367.7205,38491439611.4192,36732759920.3182,38571392278.7278,36695932591.946,36835904408.0776,38353998987.3133,37934914092.36,37337641618.7473,35493336828.6125,36681957170.3557,36326373324.7135,37591615894.1119
+Tunisia,TUN,"Population, total",SP.POP.TOTL,9708350,9793903,9871251,9945277,10022277,10106771,10201214,10304726,10414433,10525694,10635244,10741880,10847002,10952951,11063201,11179949,11303946,11433443,11565204,11694719
+Tunisia,TUN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,55482145961.9188,59027355540.4305,60767940056.2163,65012620775.8729,70781548453.9982,74688150392.4089,81387058368.2445,88448511812.3066,93552043505.7407,98192793634.6049,102937036778.887,103048392300.402,106139515924.993,107073102533.151,111432879156.612,110536919999.913,113664872520.447,117404469799.969,123100895158.534,126246204651.811
+Turkey,TUR,"Population, total",SP.POP.TOTL,63240194,64192243,65145367,66089402,67010930,67903469,68756810,69581848,70418604,71321399,72326988,73443863,74653016,75928564,77231907,78529409,79821724,81101892,82319724,83429615
+Turkey,TUR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,597334483200.142,576775800988.776,596184974340.906,623412870993.991,717661896581.309,798582177973.32,926267066261.931,1023569815490.45,1119242568185.42,1092463594830.04,1250656923762.77,1430728376610.47,1527509825602.83,1675523365075.39,1834768262767.73,1989695683312.09,2079317383660.83,2236042743568.31,2280595352742.52,2287042822851.61
+Turkmenistan,TKM,"Population, total",SP.POP.TOTL,4516133,4564083,4610005,4655743,4703401,4754646,4810109,4870141,4935767,5007954,5087213,5174085,5267900,5366375,5466328,5565287,5662372,5757669,5850908,5942089
+Turkmenistan,TKM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,18608125797.2421,20168709626.6258,20512405888.362,21796071376.3924,23408021444.9088,25792885962.1902,29758839630.028,35099172955.5778,39986573484.7062,42368527403.7033,45722924073.0519,52789503109.1211,57503025651.6309,62407231340.9251,67102532122.3818,71735322172.8103,76445710804.7088,78393490626.9716,85163219714.7608,..
+Turks and Caicos Islands,TCA,"Population, total",SP.POP.TOTL,20164,21573,23232,25011,26700,28180,29391,30385,31202,31934,32660,33377,34066,34731,35369,35981,36559,37115,37665,38191
+Turks and Caicos Islands,TCA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,764731910.157113,823917422.181535,889386727.130543,929417556.78184,987352323.619838,..
+Tuvalu,TUV,"Population, total",SP.POP.TOTL,9394,9484,9596,9726,9869,10000,10120,10221,10314,10424,10530,10633,10739,10857,10972,11099,11225,11370,11508,11646
+Tuvalu,TUV,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,44816713.8307238,55987016.7823781,39423211.9664439,44008233.8174725,44010714.0270621,44669035.2114179,52633356.1198989,52851720.3475787,54738734.1185112,49291845.5495836,50436773.5213591,43459568.1161838,54547258.7189745,48534841.957286,63000995.2918348,63492051.2978658,63480552.6310055,70098267.5235555,71863891.2861822
+Uganda,UGA,"Population, total",SP.POP.TOTL,23650172,24388968,25167257,25980552,26821297,27684585,28571475,29486338,30431736,31411096,32428167,33476919,34559168,35695246,36912148,38225453,39647506,41162465,42723139,44269594
+Uganda,UGA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,26499505401.6939,28241217363.4276,31376554570.7417,34048226950.8195,37196648518.9452,40721832209.1975,46612393718.0096,52079100131.2783,57754070635.1758,62115766422.6747,66348768277.3103,74180430678.1867,67861747681.2255,70028337871.091,75027330101.7947,79484445119.7673,80837873387.1188,83396734294.2227,90179159679.8365,97886334387.587
+Ukraine,UKR,"Population, total",SP.POP.TOTL,49176500,48662400,48202470,47812949,47451626,47105171,46787786,46509355,46258189,46053331,45870741,45706086,45593342,45489648,45272156,45154036,45004674,44831135,44622518,44385155
+Ukraine,UKR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,195874159423.066,221426068987.724,237520547089.596,265681569588.845,306381587636.351,324903125739.448,357983817517.623,400086017392.992,415612966587.664,352557246526.279,372634874968.387,397751382057.074,418808180763.59,478317354943.168,456689210728.162,437283649075.699,483248219684.615,515944166360.639,547484803864.72,578031775037.061
+United Arab Emirates,ARE,"Population, total",SP.POP.TOTL,3134062,3302719,3478777,3711932,4068570,4588225,5300174,6168838,7089487,7917372,8549988,8946777,9141596,9197910,9214175,9262900,9360980,9487203,9630959,9770529
+United Arab Emirates,ARE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,323322696221.062,335107906366.934,335185283543.408,368204626489.547,416456364855.637,455293178482.826,517928620572.751,554759716006.904,572067250142.766,545263477685.039,554578548603.043,605808769081.988,632212172329.896,648063820753.781,679448062185.081,604104698714.526,602327541485.937,641975592252.713,662414696568.075,686306904138.687
+United Kingdom,GBR,"Population, total",SP.POP.TOTL,58892514,59119673,59370479,59647577,59987905,60401206,60846820,61322463,61806995,62276270,62766365,63258810,63700215,64128273,64602298,65116219,65611593,66058859,66460344,66834405
+United Kingdom,GBR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,1561407145331.57,1652810760601.11,1748086977823.58,1828070205658.89,1937447618826.28,1999826177646.45,2117185886698.94,2172625553539.84,2244862767229.45,2165272748033.17,2284296653908.52,2360144861851.54,2415126689983.67,2510996076220.28,2611439141863.92,2705282618272.15,2827976162817.73,3000838547377.93,3072868018494.63,3210886653457.9
+United States,USA,"Population, total",SP.POP.TOTL,282162411,284968955,287625193,290107933,292805298,295516599,298379912,301231207,304093966,306771529,309321666,311556874,313830990,315993715,318301008,320635163,322941311,324985539,326687501,328239523
+United States,USA,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,10383859000000,10743709000000,11054325000000,11530268000000,12313988000000,13169702000000,14072966000000,14543216000000,14684602000000,14398708000000,15126736000000,15832207000000,16670651000000,17175898000000,18057489000000,18704317000000,19045164000000,19830277000000.1,20837347000000.1,21624995749999.9
+Uruguay,URY,"Population, total",SP.POP.TOTL,3319736,3325473,3326040,3323668,3321476,3321803,3325401,3331749,3340221,3349676,3359275,3368934,3378974,3389439,3400434,3412009,3424132,3436646,3449299,3461734
+Uruguay,URY,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,33945443247.5938,33344537747.9671,31533824762.6923,30883466401.9197,33216952936.3271,37360260911.6236,40336085307.9769,44136848952.393,47842989528.3195,50101739036.5721,54386110589.9181,58589197626.3659,57034863431.4258,61370940005.0751,64012672369.2185,65894817067.7221,67291572981.5448,68924690398.7391,70955584945.7829,73121453897.6351
+Uzbekistan,UZB,"Population, total",SP.POP.TOTL,24650400,24964450,25271850,25567650,25864350,26167000,26488250,26868000,27302800,27767400,28562400,29339400,29774500,30243200,30757700,31298900,31847900,32388600,32956100,33580650
+Uzbekistan,UZB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,60490019864.9866,64255651188.6571,68073816741.291,72531185462.2683,80628416840.1209,89130942254.7757,98331029398.2857,115744456269.22,130693528066.927,138036570231.641,146731919200.689,161559906176.939,170707243416.585,180556615900.712,192173670374.64,201986598838.056,207853080775.075,215456449592.35,234703033130.301,248452283977.245
+Vanuatu,VUT,"Population, total",SP.POP.TOTL,184972,189219,193920,198959,204127,209282,214370,219472,224704,230247,236211,242653,249499,256635,263888,271130,278330,285510,292680,299882
+Vanuatu,VUT,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,395845637.991194,403652721.333728,377866769.674181,399573849.216512,425394093.202289,454841786.625104,518923916.182719,556611911.561311,637642070.414252,643469996.480078,657929082.673957,684302150.005902,686703133.694412,754198448.012038,795660594.778998,802937429.465799,835331693.633886,880102798.798113,946508379.529688,991320396.983575
+"Venezuela, RB",VEN,"Population, total",SP.POP.TOTL,24192446,24646472,25100408,25551624,25996594,26432447,26850194,27247610,27635832,28031009,28439940,28888369,29362449,29783571,30045134,30081829,29846179,29390409,28870195,28515829
+"Venezuela, RB",VEN,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,280855847538.954,295370460052.072,269834466478.442,254427821599.432,307512284009.188,355550813047.347,406417931932.049,461178498993.92,490847218537.909,473863865999.872,470221384679.447,493557717634.178,..,..,..,..,..,..,..,..
+Vietnam,VNM,"Population, total",SP.POP.TOTL,79910412,80742499,81534407,82301656,83062821,83832661,84617540,85419591,86243413,87092252,87967651,88871561,89802487,90753472,91714595,92677076,93638724,94596642,95540395,96462106
+Vietnam,VNM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,169101978301.367,183775381863.24,198446295952.172,215660375905.614,239304626439.798,243642053786.487,267674830733.176,292489052948.076,314506040405.064,300736799423.602,356506285960.339,384663335500.307,434659185242.371,465497570616.946,501888463952.615,536539130014.396,589741573548.919,625899825382.239,690000277848.292,747220006779.353
+Virgin Islands (U.S.),VIR,"Population, total",SP.POP.TOTL,108642,108549,108510,108506,108467,108454,108371,108339,108399,108405,108358,108292,108191,108044,107884,107710,107510,107268,106977,106631
+Virgin Islands (U.S.),VIR,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..,..
+West Bank and Gaza,PSE,"Population, total",SP.POP.TOTL,2922153,2997784,3075373,3154969,3236626,3320396,3406334,3494496,3591977,3689099,3786161,3882986,3979998,4076708,4173398,4270092,4367088,4454805,4569087,4685306
+West Bank and Gaza,PSE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,8722138455.78828,7812135701.68618,6828082613.95172,7930473089.15384,8910504550.65981,10369007468.7528,10398591353.509,11531518608.2507,12473042746.9752,13317069247.2852,14482042303.3576,16688370002.6944,19833587676.5149,21072559191.4526,23338783134.8549,26177201049.1117,27386949786.2061,29158617677.1035,30815829709.4169,..
+"Yemen, Rep.",YEM,"Population, total",SP.POP.TOTL,17409072,17918373,18443691,18985000,19540098,20107409,20687646,21282515,21892146,22516460,23154855,23807588,24473178,25147109,25823485,26497889,27168210,27834821,28498687,29161922
+"Yemen, Rep.",YEM,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,47407469489.7263,50841346561.1139,53305582982.396,55681083237.4228,58804494221.7735,64075292634.3902,70493792627.0925,74995234785.3653,78498118632.1159,84324391008.1339,90700650718.9413,79742574005.5175,81652542720.9669,88588654788.721,..,..,..,..,..,..
+Zambia,ZMB,"Population, total",SP.POP.TOTL,10415944,10692193,10971698,11256743,11550642,11856247,12173514,12502958,12848530,13215139,13605984,14023193,14465121,14926504,15399753,15879361,16363507,16853688,17351822,17861030
+Zambia,ZMB,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,16390516773.1936,17697270843.1887,18873338727.6239,20701831757.7299,21936203300.825,23952035537.2028,26172573663.3931,28534598750.7941,32470694798.8824,37702919211.7603,40342714903.8491,44313413076.5895,48670115552.996,51231499045.8015,53398340681.0049,53416147657.3537,53991782699.8614,56136005389.7561,61604252695.0115,63886639446.6947
+Zimbabwe,ZWE,"Population, total",SP.POP.TOTL,11881477,11923914,11954290,11982224,12019912,12076699,12155491,12255922,12379549,12526968,12697723,12894316,13115131,13350356,13586681,13814629,14030390,14236745,14439018,14645468
+Zimbabwe,ZWE,"GNI, PPP (current international $)",NY.GNP.MKTP.PP.CD,26072084507.4236,27121623088.7881,25202095917.1133,21365454472.375,20525176748.7229,19970617965.9813,19735282220.6704,19382201999.971,15921801862.8195,16688304055.5788,20491802499.1171,23257335849.2756,27130426246.4164,30824982317.5151,32122394049.3391,33340681206.5211,35973034626.7689,39276020087.4136,43207113913.4029,40017364504.5875
+,,,,,,,,,,,,,,,,,,,,,,,
+,,,,,,,,,,,,,,,,,,,,,,,
+,,,,,,,,,,,,,,,,,,,,,,,
+Data from database: World Development Indicators,,,,,,,,,,,,,,,,,,,,,,,
+Last Updated: 08/18/2020,,,,,,,,,,,,,,,,,,,,,,,
diff --git a/tools/java/org/unicode/cldr/util/data/iso-639-3-macrolanguages.tab b/tools/java/org/unicode/cldr/util/data/iso-639-3-macrolanguages.tab
old mode 100755
new mode 100644
index 1a79cb8..d8dba02
--- a/tools/java/org/unicode/cldr/util/data/iso-639-3-macrolanguages.tab
+++ b/tools/java/org/unicode/cldr/util/data/iso-639-3-macrolanguages.tab
@@ -27,7 +27,7 @@
ara ayl A
ara ayn A
ara ayp A
-ara bbz A
+ara bbz R
ara pga A
ara shu A
ara ssh A
@@ -437,7 +437,9 @@
zho cdo A
zho cjy A
zho cmn A
+zho cnp A
zho cpx A
+zho csp A
zho czh A
zho czo A
zho gan A
diff --git a/tools/java/org/unicode/cldr/util/data/iso-639-3-version.tab b/tools/java/org/unicode/cldr/util/data/iso-639-3-version.tab
index 58ff2f2..f5415f7 100755
--- a/tools/java/org/unicode/cldr/util/data/iso-639-3-version.tab
+++ b/tools/java/org/unicode/cldr/util/data/iso-639-3-version.tab
@@ -1 +1 @@
-20190408
+20200130
diff --git a/tools/java/org/unicode/cldr/util/data/iso-639-3.tab b/tools/java/org/unicode/cldr/util/data/iso-639-3.tab
old mode 100755
new mode 100644
index 0d13023..30f7732
--- a/tools/java/org/unicode/cldr/util/data/iso-639-3.tab
+++ b/tools/java/org/unicode/cldr/util/data/iso-639-3.tab
@@ -70,7 +70,7 @@
acy I L Cypriot Arabic
acz I L Acheron
ada ada ada I L Adangme
-adb I L Adabe
+adb I L Atauran
add I L Lidzonka
ade I L Adele
adf I L Dhofari Arabic
@@ -297,7 +297,6 @@
aoe I L Angal Enen
aof I L Bragat
aog I L Angoram
-aoh I E Arma
aoi I L Anindilyakwa
aoj I L Mufian
aok I L Arhö
@@ -497,7 +496,6 @@
ays I L Sorsogon Ayta
ayt I L Magbukun Ayta
ayu I L Ayu
-ayy I E Tayabas Ayta
ayz I L Mai Brat
aza I L Azha
azb I L South Azerbaijani
@@ -556,7 +554,6 @@
bbw I L Baba
bbx I L Bubia
bby I L Befang
-bbz I L Babalia Creole Arabic
bca I L Central Bai
bcb I L Bainouk-Samik
bcc I L Southern Balochi
@@ -879,7 +876,6 @@
boy I L Bodo (Central African Republic)
boz I L Tiéyaxo Bozo
bpa I L Daakaka
-bpb I E Barbacoas
bpd I L Banda-Banda
bpg I L Bonggo
bph I L Botlikh
@@ -931,7 +927,7 @@
brc I E Berbice Creole Dutch
brd I L Baraamu
bre bre bre br I L Breton
-brf I L Bera
+brf I L Bira
brg I L Baure
brh I L Brahui
bri I L Mokpwe
@@ -1189,7 +1185,6 @@
cbv I L Cacua
cbw I L Kinabalian
cby I L Carabayo
-cca I E Cauca
ccc I L Chamicuro
ccd I L Cafundo Creole
cce I L Chopi
@@ -1204,7 +1199,6 @@
cda I L Choni
cde I L Chenchu
cdf I L Chiru
-cdg I L Chamari
cdh I L Chambeali
cdi I L Chodri
cdj I L Churahi
@@ -1283,6 +1277,7 @@
ckb I L Central Kurdish
ckh I L Chak
ckl I L Cibak
+ckm I L Chakavian
ckn I L Kaang Chin
cko I L Anufo
ckq I L Kajakse
@@ -1329,6 +1324,7 @@
cnk I L Khumi Chin
cnl I L Lalana Chinantec
cno I L Con
+cnp I L Northern Ping Chinese
cnr cnr cnr I L Montenegrin
cns I L Central Asmat
cnt I L Tepetotutla Chinantec
@@ -1410,6 +1406,7 @@
csm I L Central Sierra Miwok
csn I L Colombian Sign Language
cso I L Sochiapam Chinantec
+csp I L Southern Ping Chinese
csq I L Croatia Sign Language
csr I L Costa Rican Sign Language
css I E Southern Ohlone
@@ -1556,7 +1553,6 @@
dgr dgr dgr I L Dogrib
dgs I L Dogoso
dgt I E Ndra'ngith
-dgu I L Degaru
dgw I E Daungwurrung
dgx I L Doghoro
dgz I L Daga
@@ -1626,6 +1622,7 @@
dmc I L Gavak
dmd I E Madhi Madhi
dme I L Dugwor
+dmf I E Medefaidrin
dmg I L Upper Kinabatangan
dmk I L Domaaki
dml I L Dameli
@@ -1685,7 +1682,6 @@
drn I L West Damar
dro I L Daro-Matu Melanau
drq I E Dura
-drr I E Dororo
drs I L Gedeo
drt I L Drents
dru I L Rukai
@@ -1738,6 +1734,7 @@
duz I E Duli-Gey
dva I L Duau
dwa I L Diri
+dwk I L Dawik Kui
dwr I L Dawro
dws I C Dutton World Speedwords
dwu I L Dhuwal
@@ -1761,6 +1758,7 @@
dzn I L Dzando
dzo dzo dzo dz I L Dzongkha
eaa I E Karenggapa
+ebc I L Beginci
ebg I L Ebughu
ebk I L Eastern Bontok
ebo I L Teke-Ebo
@@ -1783,7 +1781,6 @@
eiv I L Askopan
eja I L Ejamat
eka eka eka I L Ekajuk
-ekc I E Eastern Karnic
eke I L Ekit
ekg I L Ekari
eki I L Eki
@@ -2058,6 +2055,7 @@
geb I L Kire
gec I L Gboloo Grebo
ged I L Gade
+gef I L Gerai
geg I L Gengle
geh I L Hutterite German
gei I L Gebe
@@ -2133,7 +2131,6 @@
gle gle gle ga I L Irish
glg glg glg gl I L Galician
glh I L Northwest Pashai
-gli I E Guliguli
glj I L Gula Iro
glk I L Gilaki
gll I E Garlali
@@ -2151,6 +2148,7 @@
gml I H Middle Low German
gmm I L Gbaya-Mbodomo
gmn I L Gimnime
+gmr I L Mirning
gmu I L Gumalu
gmv I L Gamo
gmx I L Magoma
@@ -2280,7 +2278,7 @@
gvy I E Guyani
gwa I L Mbato
gwb I L Gwa
-gwc I L Kalami
+gwc I L Gawri
gwd I L Gawwada
gwe I L Gweno
gwf I L Gowro
@@ -2417,6 +2415,7 @@
hna I L Mina (Cameroon)
hnd I L Southern Hindko
hne I L Chhattisgarhi
+hng I L Hungu
hnh I L ǁAni
hni I L Hani
hnj I L Hmong Njua
@@ -3039,7 +3038,6 @@
kjc I L Coastal Konjo
kjd I L Southern Kiwai
kje I L Kisar
-kjf I L Khalaj
kjg I L Khmu
kjh I L Khakas
kji I L Zabana
@@ -3075,7 +3073,7 @@
kkn I L Kon Keu
kko I L Karko
kkp I L Gugubera
-kkq I L Kaiku
+kkq I L Kaeku
kkr I L Kir-Balar
kks I L Giiwo
kkt I L Koi
@@ -3094,7 +3092,7 @@
klg I L Tagakaulo
klh I L Weliki
kli I L Kalumpang
-klj I L Turkic Khalaj
+klj I L Khalaj
klk I L Kono (Nigeria)
kll I L Kagan Kalagan
klm I L Migum
@@ -3394,7 +3392,6 @@
kxi I L Keningau Murut
kxj I L Kulfa
kxk I L Zayein Karen
-kxl I L Nepali Kurux
kxm I L Northern Khmer
kxn I L Kanowit-Tanjong Melanau
kxo I E Kanoé
@@ -3403,7 +3400,6 @@
kxr I L Koro (Papua New Guinea)
kxs I L Kangjia
kxt I L Koiwat
-kxu I L Kui (India)
kxv I L Kuvi
kxw I L Konai
kxx I L Likuba
@@ -3671,7 +3667,6 @@
lmw I L Lake Miwok
lmx I L Laimbue
lmy I L Lamboya
-lmz I E Lumbee
lna I L Langbashe
lnb I L Mbalanhu
lnd I L Lundayeh
@@ -4149,7 +4144,7 @@
moa I L Mwan
moc I L Mocoví
mod I E Mobilian
-moe I L Montagnais
+moe I L Innu
mog I L Mongondow
moh moh moh I L Mohawk
moi I L Mboi
@@ -4803,6 +4798,7 @@
nrx I E Ngurmbur
nrz I L Lala
nsa I L Sangtam Naga
+nsb I E Lower Nossob
nsc I L Nshi
nsd I L Southern Nisu
nse I L Nsenga
@@ -4892,7 +4888,6 @@
nxo I L Ndambomo
nxq I L Naxi
nxr I L Ninggerum
-nxu I E Narau
nxx I L Nafri
nya nya nya ny I L Nyanja
nyb I L Nyangbo
@@ -5184,7 +5179,7 @@
pey I L Petjo
pez I L Eastern Penan
pfa I L Pááfang
-pfe I L Peere
+pfe I L Pere
pfl I L Pfaelzisch
pga I L Sudanese Creole Arabic
pgd I H Gāndhārī
@@ -5261,7 +5256,6 @@
pll I L Shwe Palaung
pln I L Palenquero
plo I L Oluta Popoluca
-plp I L Palpa
plq I A Palaic
plr I L Palaka Senoufo
pls I L San Marcos Tlacoyalco Popoloca
@@ -5735,10 +5729,10 @@
sdj I L Suundi
sdk I L Sos Kundi
sdl I L Saudi Arabian Sign Language
-sdm I L Semandang
sdn I L Gallurese Sardinian
sdo I L Bukar-Sadung Bidayuh
sdp I L Sherdukpen
+sdq I L Semandang
sdr I L Oraon Sadri
sds I E Sened
sdt I E Shuadit
@@ -6200,7 +6194,6 @@
tay I L Atayal
taz I L Tocho
tba I L Aikanã
-tbb I E Tapeba
tbc I L Takia
tbd I L Kaki Ae
tbe I L Tanimbili
@@ -6730,6 +6723,7 @@
uka I L Kaburi
ukg I L Ukuriguma
ukh I L Ukhwejo
+uki I L Kui (India)
ukk I L Muak Sa-aak
ukl I L Ukrainian Sign Language
ukp I L Ukpe-Bayobiri
@@ -6737,6 +6731,7 @@
ukr ukr ukr uk I L Ukrainian
uks I L Urubú-Kaapor Sign Language
uku I L Ukue
+ukv I L Kuku
ukw I L Ukwuani-Aboh-Ndoni
uky I E Kuuk-Yak
ula I L Fungwa
@@ -7023,6 +7018,7 @@
wlc I L Mwali Comorian
wle I L Wolane
wlg I L Kunbarlang
+wlh I L Welaun
wli I L Waioli
wlk I E Wailaki
wll I L Wali (Sudan)
@@ -7308,6 +7304,7 @@
xnh I L Kuanhua
xni I E Ngarigu
xnk I E Nganakarti
+xnm I E Ngumbarl
xnn I L Northern Kankanay
xno I H Anglo-Norman
xnr I L Kangri
@@ -7328,12 +7325,17 @@
xor I L Korubo
xow I L Kowaki
xpa I E Pirriya
+xpb I E Northeastern Tasmanian
xpc I H Pecheneg
+xpd I E Oyster Bay Tasmanian
xpe I L Liberia Kpelle
+xpf I E Southeast Tasmanian
xpg I A Phrygian
+xph I E North Midlands Tasmanian
xpi I H Pictish
xpj I E Mpalitjanh
xpk I L Kulina Pano
+xpl I E Port Sorell Tasmanian
xpm I E Pumpokol
xpn I E Kapinawá
xpo I E Pochutec
@@ -7343,7 +7345,11 @@
xps I A Pisidian
xpt I E Punthamara
xpu I A Punic
+xpv I E Northern Tasmanian
+xpw I E Northwestern Tasmanian
+xpx I E Southwestern Tasmanian
xpy I A Puyo
+xpz I E Bruny Island Tasmanian
xqa I H Karakhanid
xqt I A Qatabanian
xra I L Krahô
@@ -7354,7 +7360,6 @@
xri I L Krikati-Timbira
xrm I A Armazic
xrn I E Arin
-xrq I E Karranga
xrr I A Raetic
xrt I E Aranama-Tamique
xru I L Marriammu
@@ -7400,7 +7405,6 @@
xtv I E Thawa
xtw I L Tawandê
xty I L Yoloxochitl Mixtec
-xtz I E Tasmanian
xua I L Alu Kurumba
xub I L Betta Kurumba
xud I E Umiida
@@ -7706,6 +7710,7 @@
zax I L Xadani Zapotec
zay I L Zayse-Zergulla
zaz I L Zari
+zba I C Balaibalan
zbc I L Central Berawan
zbe I L East Berawan
zbl zbl zbl I C Blissymbols
@@ -7736,8 +7741,7 @@
zik I L Zimakani
zil I L Zialo
zim I L Mesme
-zin I L Zinza
-zir I E Ziriya
+zin I L Zinza
ziw I L Zigula
ziz I L Zizilivakan
zka I L Kaimbulawa
diff --git a/tools/java/org/unicode/cldr/util/data/iso-639-3_Name_Index.tab b/tools/java/org/unicode/cldr/util/data/iso-639-3_Name_Index.tab
old mode 100755
new mode 100644
index 9cf57b1..ccb7344
--- a/tools/java/org/unicode/cldr/util/data/iso-639-3_Name_Index.tab
+++ b/tools/java/org/unicode/cldr/util/data/iso-639-3_Name_Index.tab
@@ -70,7 +70,7 @@
acy Cypriot Arabic Arabic, Cypriot
acz Acheron Acheron
ada Adangme Adangme
-adb Adabe Adabe
+adb Atauran Atauran
add Dzodinka Dzodinka
add Lidzonka Lidzonka
ade Adele Adele
@@ -303,7 +303,6 @@
aoe Angal Enen Angal Enen
aof Bragat Bragat
aog Angoram Angoram
-aoh Arma Arma
aoi Anindilyakwa Anindilyakwa
aoj Mufian Mufian
aok Arhö Arhö
@@ -512,7 +511,6 @@
ays Sorsogon Ayta Ayta, Sorsogon
ayt Magbukun Ayta Ayta, Magbukun
ayu Ayu Ayu
-ayy Tayabas Ayta Ayta, Tayabas
ayz Mai Brat Mai Brat
aza Azha Azha
azb South Azerbaijani Azerbaijani, South
@@ -572,7 +570,6 @@
bbw Baba Baba
bbx Bubia Bubia
bby Befang Befang
-bbz Babalia Creole Arabic Creole Arabic, Babalia
bca Central Bai Bai, Central
bcb Bainouk-Samik Bainouk-Samik
bcc Southern Balochi Balochi, Southern
@@ -907,7 +904,6 @@
boy Bodo (Central African Republic) Bodo (Central African Republic)
boz Tiéyaxo Bozo Bozo, Tiéyaxo
bpa Daakaka Daakaka
-bpb Barbacoas Barbacoas
bpd Banda-Banda Banda-Banda
bpg Bonggo Bonggo
bph Botlikh Botlikh
@@ -962,7 +958,7 @@
brc Berbice Creole Dutch Creole Dutch, Berbice
brd Baraamu Baraamu
bre Breton Breton
-brf Bera Bera
+brf Bira Bira
brg Baure Baure
brh Brahui Brahui
bri Mokpwe Mokpwe
@@ -1230,7 +1226,6 @@
cbv Cacua Cacua
cbw Kinabalian Kinabalian
cby Carabayo Carabayo
-cca Cauca Cauca
ccc Chamicuro Chamicuro
ccd Cafundo Creole Creole, Cafundo
cce Chopi Chopi
@@ -1245,7 +1240,6 @@
cda Choni Choni
cde Chenchu Chenchu
cdf Chiru Chiru
-cdg Chamari Chamari
cdh Chambeali Chambeali
cdi Chodri Chodri
cdj Churahi Churahi
@@ -1331,6 +1325,7 @@
ckb Central Kurdish Kurdish, Central
ckh Chak Chak
ckl Cibak Cibak
+ckm Chakavian Chakavian
ckn Kaang Chin Chin, Kaang
cko Anufo Anufo
ckq Kajakse Kajakse
@@ -1378,6 +1373,8 @@
cnk Khumi Chin Chin, Khumi
cnl Lalana Chinantec Chinantec, Lalana
cno Con Con
+cnp Northern Ping Chinese Chinese, Northern Ping
+cnp Northern Pinghua Pinghua, Northern
cnr Montenegrin Montenegrin
cns Central Asmat Asmat, Central
cnt Tepetotutla Chinantec Chinantec, Tepetotutla
@@ -1464,6 +1461,8 @@
csn Colombian Sign Language Colombian Sign Language
cso Sochiapam Chinantec Chinantec, Sochiapam
cso Sochiapan Chinantec Chinantec, Sochiapan
+csp Southern Ping Chinese Chinese, Southern Ping
+csp Southern Pinghua Pinghua, Southern
csq Croatia Sign Language Croatia Sign Language
csr Costa Rican Sign Language Costa Rican Sign Language
css Southern Ohlone Ohlone, Southern
@@ -1614,9 +1613,9 @@
dgn Dagoman Dagoman
dgo Dogri (individual language) Dogri (individual language)
dgr Dogrib Dogrib
+dgr Tłı̨chǫ Tłı̨chǫ
dgs Dogoso Dogoso
dgt Ndra'ngith Ndra'ngith
-dgu Degaru Degaru
dgw Daungwurrung Daungwurrung
dgx Doghoro Doghoro
dgz Daga Daga
@@ -1697,6 +1696,7 @@
dmc Gavak Gavak
dmd Madhi Madhi Madhi Madhi
dme Dugwor Dugwor
+dmf Medefaidrin Medefaidrin
dmg Upper Kinabatangan Kinabatangan, Upper
dmk Domaaki Domaaki
dml Dameli Dameli
@@ -1759,7 +1759,6 @@
drn West Damar Damar, West
dro Daro-Matu Melanau Melanau, Daro-Matu
drq Dura Dura
-drr Dororo Dororo
drs Gedeo Gedeo
drt Drents Drents
dru Rukai Rukai
@@ -1815,6 +1814,7 @@
duz Duli-Gey Duli-Gey
dva Duau Duau
dwa Diri Diri
+dwk Dawik Kui Kui, Dawik
dwr Dawro Dawro
dws Dutton World Speedwords Dutton World Speedwords
dwu Dhuwal Dhuwal
@@ -1840,6 +1840,7 @@
dzn Dzando Dzando
dzo Dzongkha Dzongkha
eaa Karenggapa Karenggapa
+ebc Beginci Beginci
ebg Ebughu Ebughu
ebk Eastern Bontok Bontok, Eastern
ebo Teke-Ebo Teke-Ebo
@@ -1863,7 +1864,6 @@
eiv Askopan Askopan
eja Ejamat Ejamat
eka Ekajuk Ekajuk
-ekc Eastern Karnic Karnic, Eastern
eke Ekit Ekit
ekg Ekari Ekari
eki Eki Eki
@@ -2128,6 +2128,7 @@
gdf Guduf-Gava Guduf-Gava
gdg Ga'dang Ga'dang
gdh Gadjerawang Gadjerawang
+gdh Gajirrabeng Gajirrabeng
gdi Gundi Gundi
gdj Gurdjar Gurdjar
gdk Gadang Gadang
@@ -2145,6 +2146,7 @@
geb Kire Kire
gec Gboloo Grebo Grebo, Gboloo
ged Gade Gade
+gef Gerai Gerai
geg Gengle Gengle
geh Hutterisch Hutterisch
geh Hutterite German German, Hutterite
@@ -2226,7 +2228,6 @@
glg Galician Galician
glh Northwest Pashai Pashai, Northwest
glh Northwest Pashayi Pashayi, Northwest
-gli Guliguli Guliguli
glj Gula Iro Gula Iro
glk Gilaki Gilaki
gll Garlali Garlali
@@ -2244,6 +2245,8 @@
gml Middle Low German German, Middle Low
gmm Gbaya-Mbodomo Gbaya-Mbodomo
gmn Gimnime Gimnime
+gmr Mirning Mirning
+gmr Mirniny Mirniny
gmu Gumalu Gumalu
gmv Gamo Gamo
gmx Magoma Magoma
@@ -2377,6 +2380,7 @@
gvy Guyani Guyani
gwa Mbato Mbato
gwb Gwa Gwa
+gwc Gawri Gawri
gwc Kalami Kalami
gwd Gawwada Gawwada
gwe Gweno Gweno
@@ -2531,6 +2535,7 @@
hna Mina (Cameroon) Mina (Cameroon)
hnd Southern Hindko Hindko, Southern
hne Chhattisgarhi Chhattisgarhi
+hng Hungu Hungu
hnh ǁAni ǁAni
hni Hani Hani
hnj Hmong Njua Hmong Njua
@@ -2588,6 +2593,7 @@
htu Hitu Hitu
htx Middle Hittite Hittite, Middle
hub Huambisa Huambisa
+huc ǂ'Amkhoe ǂ'Amkhoe
huc ǂHua ǂHua
hud Huaulu Huaulu
hue San Francisco Del Mar Huave Huave, San Francisco Del Mar
@@ -2944,6 +2950,7 @@
jya Jiarong Jiarong
jye Judeo-Yemeni Arabic Arabic, Judeo-Yemeni
jyy Jaya Jaya
+kaa Karakalpak Karakalpak
kaa Kara-Kalpak Kara-Kalpak
kab Kabyle Kabyle
kac Jingpho Jingpho
@@ -3187,7 +3194,6 @@
kjc Coastal Konjo Konjo, Coastal
kjd Southern Kiwai Kiwai, Southern
kje Kisar Kisar
-kjf Khalaj Khalaj
kjg Khmu Khmu
kjh Khakas Khakas
kji Zabana Zabana
@@ -3224,7 +3230,7 @@
kko Karko Karko
kkp Gugubera Gugubera
kkp Koko-Bera Koko-Bera
-kkq Kaiku Kaiku
+kkq Kaeku Kaeku
kkr Kir-Balar Kir-Balar
kks Giiwo Giiwo
kkt Koi Koi
@@ -3244,7 +3250,7 @@
klg Tagakaulo Tagakaulo
klh Weliki Weliki
kli Kalumpang Kalumpang
-klj Turkic Khalaj Khalaj, Turkic
+klj Khalaj Khalaj
klk Kono (Nigeria) Kono (Nigeria)
kll Kagan Kalagan Kalagan, Kagan
klm Migum Migum
@@ -3474,6 +3480,7 @@
kuf Western Katu Katu, Western
kug Kupa Kupa
kuh Kushi Kushi
+kui Kalapalo Kalapalo
kui Kuikúro-Kalapálo Kuikúro-Kalapálo
kuj Kuria Kuria
kuk Kepo' Kepo'
@@ -3556,7 +3563,6 @@
kxi Keningau Murut Murut, Keningau
kxj Kulfa Kulfa
kxk Zayein Karen Karen, Zayein
-kxl Nepali Kurux Kurux, Nepali
kxm Northern Khmer Khmer, Northern
kxn Kanowit-Tanjong Melanau Melanau, Kanowit-Tanjong
kxo Kanoé Kanoé
@@ -3565,7 +3571,6 @@
kxr Koro (Papua New Guinea) Koro (Papua New Guinea)
kxs Kangjia Kangjia
kxt Koiwat Koiwat
-kxu Kui (India) Kui (India)
kxv Kuvi Kuvi
kxw Konai Konai
kxx Likuba Likuba
@@ -3844,7 +3849,6 @@
lmw Lake Miwok Miwok, Lake
lmx Laimbue Laimbue
lmy Lamboya Lamboya
-lmz Lumbee Lumbee
lna Langbashe Langbashe
lnb Mbalanhu Mbalanhu
lnd Lun Bawang Lun Bawang
@@ -4342,6 +4346,7 @@
moa Mwan Mwan
moc Mocoví Mocoví
mod Mobilian Mobilian
+moe Innu Innu
moe Montagnais Montagnais
mog Mongondow Mongondow
moh Mohawk Mohawk
@@ -5019,6 +5024,7 @@
nrx Ngurmbur Ngurmbur
nrz Lala Lala
nsa Sangtam Naga Naga, Sangtam
+nsb Lower Nossob Lower Nossob
nsc Nshi Nshi
nsd Southern Nisu Nisu, Southern
nse Nsenga Nsenga
@@ -5113,7 +5119,6 @@
nxo Ndambomo Ndambomo
nxq Naxi Naxi
nxr Ninggerum Ninggerum
-nxu Narau Narau
nxx Nafri Nafri
nya Chewa Chewa
nya Chichewa Chichewa
@@ -5417,7 +5422,7 @@
pey Petjo Petjo
pez Eastern Penan Penan, Eastern
pfa Pááfang Pááfang
-pfe Peere Peere
+pfe Pere Pere
pfl Pfaelzisch Pfaelzisch
pga Sudanese Creole Arabic Creole Arabic, Sudanese
pgd Gāndhārī Gāndhārī
@@ -5497,7 +5502,6 @@
pll Shwe Palaung Palaung, Shwe
pln Palenquero Palenquero
plo Oluta Popoluca Popoluca, Oluta
-plp Palpa Palpa
plq Palaic Palaic
plr Palaka Senoufo Senoufo, Palaka
pls San Marcos Tlacoyalco Popoloca Popoloca, San Marcos Tlacoyalco
@@ -5993,10 +5997,10 @@
sdj Suundi Suundi
sdk Sos Kundi Sos Kundi
sdl Saudi Arabian Sign Language Saudi Arabian Sign Language
-sdm Semandang Semandang
sdn Gallurese Sardinian Sardinian, Gallurese
sdo Bukar-Sadung Bidayuh Bidayuh, Bukar-Sadung
sdp Sherdukpen Sherdukpen
+sdq Semandang Semandang
sdr Oraon Sadri Sadri, Oraon
sds Sened Sened
sdt Shuadit Shuadit
@@ -6470,7 +6474,6 @@
tay Atayal Atayal
taz Tocho Tocho
tba Aikanã Aikanã
-tbb Tapeba Tapeba
tbc Takia Takia
tbd Kaki Ae Kaki Ae
tbe Tanimbili Tanimbili
@@ -7016,6 +7019,7 @@
uka Kaburi Kaburi
ukg Ukuriguma Ukuriguma
ukh Ukhwejo Ukhwejo
+uki Kui (India) Kui (India)
ukk Muak Sa-aak Muak Sa-aak
ukl Ukrainian Sign Language Ukrainian Sign Language
ukp Ukpe-Bayobiri Ukpe-Bayobiri
@@ -7024,6 +7028,7 @@
uks Kaapor Sign Language Kaapor Sign Language
uks Urubú-Kaapor Sign Language Urubú-Kaapor Sign Language
uku Ukue Ukue
+ukv Kuku Kuku
ukw Ukwuani-Aboh-Ndoni Ukwuani-Aboh-Ndoni
uky Kuuk-Yak Kuuk-Yak
ula Fungwa Fungwa
@@ -7328,6 +7333,7 @@
wlc Mwali Comorian Comorian, Mwali
wle Wolane Wolane
wlg Kunbarlang Kunbarlang
+wlh Welaun Welaun
wli Waioli Waioli
wlk Wailaki Wailaki
wll Wali (Sudan) Wali (Sudan)
@@ -7623,6 +7629,7 @@
xnh Kuanhua Kuanhua
xni Ngarigu Ngarigu
xnk Nganakarti Nganakarti
+xnm Ngumbarl Ngumbarl
xnn Northern Kankanay Kankanay, Northern
xno Anglo-Norman Anglo-Norman
xnr Kangri Kangri
@@ -7644,12 +7651,20 @@
xor Korubo Korubo
xow Kowaki Kowaki
xpa Pirriya Pirriya
+xpb Northeastern Tasmanian Tasmanian, Northeastern
+xpb Pyemmairrener Pyemmairrener
xpc Pecheneg Pecheneg
+xpd Oyster Bay Tasmanian Tasmanian, Oyster Bay
xpe Liberia Kpelle Kpelle, Liberia
+xpf Nuenonne Nuenonne
+xpf Southeast Tasmanian Tasmanian, Southeast
xpg Phrygian Phrygian
+xph North Midlands Tasmanian Tasmanian, North Midlands
+xph Tyerrenoterpanner Tyerrenoterpanner
xpi Pictish Pictish
xpj Mpalitjanh Mpalitjanh
xpk Kulina Pano Pano, Kulina
+xpl Port Sorell Tasmanian Tasmanian, Port Sorell
xpm Pumpokol Pumpokol
xpn Kapinawá Kapinawá
xpo Pochutec Pochutec
@@ -7659,7 +7674,14 @@
xps Pisidian Pisidian
xpt Punthamara Punthamara
xpu Punic Punic
+xpv Northern Tasmanian Tasmanian, Northern
+xpv Tommeginne Tommeginne
+xpw Northwestern Tasmanian Tasmanian, Northwestern
+xpw Peerapper Peerapper
+xpx Southwestern Tasmanian Tasmanian, Southwestern
+xpx Toogee Toogee
xpy Puyo Puyo
+xpz Bruny Island Tasmanian Tasmanian, Bruny Island
xqa Karakhanid Karakhanid
xqt Qatabanian Qatabanian
xra Krahô Krahô
@@ -7670,7 +7692,6 @@
xri Krikati-Timbira Krikati-Timbira
xrm Armazic Armazic
xrn Arin Arin
-xrq Karranga Karranga
xrr Raetic Raetic
xrt Aranama-Tamique Aranama-Tamique
xru Marriammu Marriammu
@@ -7716,13 +7737,13 @@
xtv Thawa Thawa
xtw Tawandê Tawandê
xty Yoloxochitl Mixtec Mixtec, Yoloxochitl
-xtz Tasmanian Tasmanian
xua Alu Kurumba Kurumba, Alu
xub Betta Kurumba Kurumba, Betta
xud Umiida Umiida
xug Kunigami Kunigami
xuj Jennu Kurumba Kurumba, Jennu
xul Ngunawal Ngunawal
+xul Nunukul Nunukul
xum Umbrian Umbrian
xun Unggaranggu Unggaranggu
xuo Kuo Kuo
@@ -8030,6 +8051,7 @@
zay Zaysete Zaysete
zay Zayse-Zergulla Zayse-Zergulla
zaz Zari Zari
+zba Balaibalan Balaibalan
zbc Central Berawan Berawan, Central
zbe East Berawan Berawan, East
zbl Bliss Bliss
@@ -8064,7 +8086,6 @@
zil Zialo Zialo
zim Mesme Mesme
zin Zinza Zinza
-zir Ziriya Ziriya
ziw Zigula Zigula
ziz Zizilivakan Zizilivakan
zka Kaimbulawa Kaimbulawa
diff --git a/tools/java/org/unicode/cldr/util/data/iso-639-3_Retirements.tab b/tools/java/org/unicode/cldr/util/data/iso-639-3_Retirements.tab
old mode 100755
new mode 100644
index f7d9355..1f02313
--- a/tools/java/org/unicode/cldr/util/data/iso-639-3_Retirements.tab
+++ b/tools/java/org/unicode/cldr/util/data/iso-639-3_Retirements.tab
@@ -323,10 +323,31 @@
ncp Ndaktup M kdz 2018-01-23
ais Nataoran Amis S Split by part going to Amis [ami] and creating Sakizaya [szy] with the remaining part 2019-01-25
asd Asas M snz 2019-01-25
-dit Diyari M dif 2019-01-25
+dit Dirari M dif 2019-01-25
dud Hun-Saare S Split into ut-Hun [uth] and us-Saare [uss] 2019-01-25
lba Lui N 2019-01-25
llo Khlor D ngt 2019-01-25
myd Maramba M aog 2019-01-25
myi Mina (India) N 2019-01-25
-nns Ningye M nbr 2019-01-25
\ No newline at end of file
+nns Ningye M nbr 2019-01-25
+aoh Arma N 2020-01-23
+ayy Tayabas Ayta N 2020-01-23
+bbz Babalia Creole Arabic N 2020-01-23
+bpb Barbacoas N 2020-01-23
+cca Cauca N 2020-01-23
+cdg Chamari N 2020-01-23
+dgu Degaru N 2020-01-23
+drr Dororo M kzk 2020-01-23
+ekc Eastern Karnic N 2020-01-23
+gli Guliguli M kzk 2020-01-23
+kjf Khalaj N 2020-01-23
+kxl Nepali Kurux M kru 2020-01-23
+kxu Kui (India) S Split into [dwk] Dawik Kui and [uki] Kui (India) 2020-01-23
+lmz Lumbee N 2020-01-23
+nxu Narau M bpp 2020-01-23
+plp Palpa N 2020-01-23
+sdm Semandang S Split into Semandang [sdq], Beginci [ebc] and Gerai [gef] 2020-01-23
+tbb Tapeba N 2020-01-23
+xrq Karranga M dmw 2020-01-23
+xtz Tasmanian S Split into [xpv] Northern Tasman, [xph] North Midlands Tasman, [xpb] Northeastern Tasman, [xpd] Oyster Bay Tasmanian, [xpf] Southeast Tasma, [xpx] Southwestern Tasman, [xpw] Northwestern Tasman., [xpl] Port Sorell Tasman. and [xpz] Bruny Island Tasman. 2020-01-23
+zir Ziriya D scv 2020-01-23
\ No newline at end of file
diff --git a/tools/java/org/unicode/cldr/util/data/langtagRegex.txt b/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
index 8096de1..cceeec2 100644
--- a/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
+++ b/tools/java/org/unicode/cldr/util/data/langtagRegex.txt
@@ -35,14 +35,14 @@
$privateUse = $x (?: $s $alphanum{1,8} )+ ; # "x" 1*("-" (1*8alphanum))
-# Define certain grandfathered codes, since otherwise the regex is pretty useless.
+# Define certain legacy codes (marked as “Type: grandfathered” in BCP 47), since otherwise the regex is pretty useless.
# Since these are limited, this is safe even later changes to the registry --
# the only oddity is that it might change the type of the tag, and thus
# the results from the capturing groups.
# http://www.iana.org/assignments/language-subtag-registry
# Note that these have to be compared case insensitively, requiring (?i) below.
-$grandfathered = en $s GB $s oed
+$legacy = en $s GB $s oed
| i $s (?: ami | bnn | default | enochian | hak | klingon | lux | mingo | navajo | pwn | tao | tay | tsu )
| no $s (?: bok | nyn )
| sgn $s (?: BE $s (?: fr | nl) | CH $s de )
@@ -52,7 +52,7 @@
# For well-formedness, we don't need the ones that would otherwise pass.
# For validity, they need to be checked.
-# $grandfatheredWellFormed = (?:
+# $legacyWellFormed = (?:
# art $s lojban
# | cel $s gaulish
# | zh $s (?: guoyu | hakka | xiang )
@@ -75,12 +75,12 @@
(?: $s ( $privateUse ) )? 5%);
# Here is the final breakdown, with capturing groups for each of these components
-# The variants, extensions, grandfathered, and private-use may have interior '-'
+# The variants, extensions, legacy, and private-use may have interior '-'
$root = (?i) # case-insensitive
(?:
$langtag 90%
| ( $privateUse ) 5%
- | ( $grandfathered ) 5%)
+ | ( $legacy ) 5%)
# (?: \@ $keywords )? 5%
- ;
\ No newline at end of file
+ ;
diff --git a/tools/java/org/unicode/cldr/util/data/langtagTest.txt b/tools/java/org/unicode/cldr/util/data/langtagTest.txt
index 436824b..4378a77 100644
--- a/tools/java/org/unicode/cldr/util/data/langtagTest.txt
+++ b/tools/java/org/unicode/cldr/util/data/langtagTest.txt
@@ -50,21 +50,22 @@
fr-Latn-FR
fr-shadok # Variant
fr-y-myext-myext2
-i-default # grandfathered
-i-default # grandfathered
-i-enochian # Grand fathered
-i-klingon # grandfathered
-i-klingon # grandfathered with singleton
+i-default # legacy (marked as “Type: grandfathered” in BCP 47)
+i-default # legacy
+i-enochian # legacy
+i-klingon # legacy
+i-klingon # legacy with singleton
mn-Cyrl-MN
mN-cYrL-Mn
-no-bok # grandfathered without singleton
+no-bok # legacy without singleton
sl-IT-nedis
sl-nedis
sr-Latn-CS
x-12345678-a
x-fr-CH
-#all of the grandfathered codes; first the really goofy ones. Cased oddly for an extra test.
+#all of the legacy codes (marked as “Type: grandfathered” in BCP 47); first the really goofy ones.
+#Cased oddly for an extra test.
En-Gb-Oed
I-Ami
I-Bnn
@@ -264,7 +265,7 @@
overlongone
tlh-a-b-foo
-i-notexist # grandfathered but not registered: invalid, even if we only test well-formedness
+i-notexist # legacy but not registered: invalid, even if we only test well-formedness
en-enx # Extended tag
en-enx-eny-enz-latn-us # Extended tag
diff --git a/tools/java/org/unicode/cldr/util/data/language-subtag-registry b/tools/java/org/unicode/cldr/util/data/language-subtag-registry
index c970025..4b6b653 100644
--- a/tools/java/org/unicode/cldr/util/data/language-subtag-registry
+++ b/tools/java/org/unicode/cldr/util/data/language-subtag-registry
@@ -1,4 +1,4 @@
-File-Date: 2019-09-16
+File-Date: 2020-07-17
%%
Type: language
Subtag: aa
@@ -1530,7 +1530,7 @@
%%
Type: language
Subtag: adb
-Description: Adabe
+Description: Atauran
Added: 2009-07-29
%%
Type: language
@@ -2707,6 +2707,7 @@
Subtag: aoh
Description: Arma
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: aoi
@@ -3770,6 +3771,7 @@
Subtag: ayy
Description: Tayabas Ayta
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: ayz
@@ -4085,6 +4087,7 @@
Subtag: bbz
Description: Babalia Creole Arabic
Added: 2009-07-29
+Deprecated: 2020-03-28
Macrolanguage: ar
%%
Type: language
@@ -5755,6 +5758,7 @@
Subtag: bpb
Description: Barbacoas
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: bpd
@@ -6011,7 +6015,7 @@
%%
Type: language
Subtag: brf
-Description: Bera
+Description: Bira
Added: 2009-07-29
%%
Type: language
@@ -7374,6 +7378,7 @@
Subtag: cca
Description: Cauca
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: ccc
@@ -7480,6 +7485,7 @@
Subtag: cdg
Description: Chamari
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: cdh
@@ -7875,6 +7881,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: ckm
+Description: Chakavian
+Added: 2020-03-28
+%%
+Type: language
Subtag: ckn
Description: Kaang Chin
Added: 2013-09-10
@@ -8121,6 +8132,13 @@
Added: 2009-07-29
%%
Type: language
+Subtag: cnp
+Description: Northern Ping Chinese
+Description: Northern Pinghua
+Added: 2020-03-28
+Macrolanguage: zh
+%%
+Type: language
Subtag: cnr
Description: Montenegrin
Added: 2018-01-23
@@ -8564,6 +8582,13 @@
Added: 2009-07-29
%%
Type: language
+Subtag: csp
+Description: Southern Ping Chinese
+Description: Southern Pinghua
+Added: 2020-03-28
+Macrolanguage: zh
+%%
+Type: language
Subtag: csq
Description: Croatia Sign Language
Added: 2009-07-29
@@ -9318,6 +9343,7 @@
Type: language
Subtag: dgr
Description: Dogrib
+Description: Tłı̨chǫ
Added: 2005-10-16
%%
Type: language
@@ -9334,6 +9360,7 @@
Subtag: dgu
Description: Degaru
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: dgw
@@ -9720,6 +9747,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: dmf
+Description: Medefaidrin
+Added: 2020-03-28
+%%
+Type: language
Subtag: dmg
Description: Upper Kinabatangan
Added: 2009-07-29
@@ -10041,6 +10073,8 @@
Subtag: drr
Description: Dororo
Added: 2009-07-29
+Deprecated: 2020-03-28
+Preferred-Value: kzk
%%
Type: language
Subtag: drs
@@ -10330,6 +10364,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: dwk
+Description: Dawik Kui
+Added: 2020-03-28
+%%
+Type: language
Subtag: dwl
Description: Walo Kumbe Dogon
Added: 2009-07-29
@@ -10455,6 +10494,11 @@
Added: 2013-09-10
%%
Type: language
+Subtag: ebc
+Description: Beginci
+Added: 2020-03-28
+%%
+Type: language
Subtag: ebg
Description: Ebughu
Added: 2009-07-29
@@ -10576,6 +10620,7 @@
Subtag: ekc
Description: Eastern Karnic
Added: 2013-09-10
+Deprecated: 2020-03-28
%%
Type: language
Subtag: eke
@@ -11215,6 +11260,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: fif
+Description: Faifi
+Added: 2020-06-08
+%%
+Type: language
Subtag: fil
Description: Filipino
Description: Pilipino
@@ -11881,6 +11931,7 @@
Type: language
Subtag: gdh
Description: Gadjerawang
+Description: Gajirrabeng
Added: 2009-07-29
%%
Type: language
@@ -11970,6 +12021,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: gef
+Description: Gerai
+Added: 2020-03-28
+%%
+Type: language
Subtag: geg
Description: Gengle
Added: 2009-07-29
@@ -12381,6 +12437,8 @@
Subtag: gli
Description: Guliguli
Added: 2009-07-29
+Deprecated: 2020-03-28
+Preferred-Value: kzk
%%
Type: language
Subtag: glj
@@ -12476,6 +12534,12 @@
Scope: collection
%%
Type: language
+Subtag: gmr
+Description: Mirning
+Description: Mirniny
+Added: 2020-03-28
+%%
+Type: language
Subtag: gmu
Description: Gumalu
Added: 2009-07-29
@@ -13155,6 +13219,7 @@
%%
Type: language
Subtag: gwc
+Description: Gawri
Description: Kalami
Added: 2009-07-29
%%
@@ -13859,6 +13924,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: hng
+Description: Hungu
+Added: 2020-03-28
+%%
+Type: language
Subtag: hnh
Description: ǁAni
Added: 2009-07-29
@@ -14140,6 +14210,7 @@
Type: language
Subtag: huc
Description: ǂHua
+Description: ǂʼAmkhoe
Added: 2009-07-29
%%
Type: language
@@ -15910,6 +15981,7 @@
Type: language
Subtag: kaa
Description: Kara-Kalpak
+Description: Karakalpak
Added: 2005-10-16
%%
Type: language
@@ -17067,8 +17139,9 @@
%%
Type: language
Subtag: kjf
-Description: Khalaj
+Description: Khalaj [Indo-Iranian]
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: kjg
@@ -17248,7 +17321,7 @@
%%
Type: language
Subtag: kkq
-Description: Kaiku
+Description: Kaeku
Added: 2009-07-29
%%
Type: language
@@ -17344,7 +17417,7 @@
%%
Type: language
Subtag: klj
-Description: Turkic Khalaj
+Description: Khalaj
Added: 2009-07-29
%%
Type: language
@@ -18497,6 +18570,7 @@
Type: language
Subtag: kui
Description: Kuikúro-Kalapálo
+Description: Kalapalo
Added: 2009-07-29
%%
Type: language
@@ -18908,6 +18982,8 @@
Subtag: kxl
Description: Nepali Kurux
Added: 2009-07-29
+Deprecated: 2020-03-28
+Preferred-Value: kru
%%
Type: language
Subtag: kxm
@@ -18953,6 +19029,8 @@
Subtag: kxu
Description: Kui (India)
Added: 2009-07-29
+Deprecated: 2020-03-28
+Comments: see dwk, uki
%%
Type: language
Subtag: kxv
@@ -20337,6 +20415,7 @@
Subtag: lmz
Description: Lumbee
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: lna
@@ -22788,6 +22867,7 @@
%%
Type: language
Subtag: moe
+Description: Innu
Description: Montagnais
Added: 2009-07-29
%%
@@ -26199,6 +26279,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: nsb
+Description: Lower Nossob
+Added: 2020-03-28
+%%
+Type: language
Subtag: nsc
Description: Nshi
Added: 2009-07-29
@@ -26667,6 +26752,8 @@
Subtag: nxu
Description: Narau
Added: 2009-07-29
+Deprecated: 2020-03-28
+Preferred-Value: bpp
%%
Type: language
Subtag: nxx
@@ -28166,7 +28253,7 @@
%%
Type: language
Subtag: pfe
-Description: Peere
+Description: Pere
Added: 2009-07-29
%%
Type: language
@@ -28572,6 +28659,7 @@
Subtag: plp
Description: Palpa
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: plq
@@ -31132,6 +31220,8 @@
Subtag: sdm
Description: Semandang
Added: 2009-07-29
+Deprecated: 2020-03-28
+Comments: see ebc, gef, sdq
%%
Type: language
Subtag: sdn
@@ -31150,6 +31240,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: sdq
+Description: Semandang
+Added: 2020-03-28
+%%
+Type: language
Subtag: sdr
Description: Oraon Sadri
Added: 2009-07-29
@@ -33502,6 +33597,7 @@
Subtag: tbb
Description: Tapeba
Added: 2009-07-29
+Deprecated: 2020-03-28
%%
Type: language
Subtag: tbc
@@ -34219,6 +34315,8 @@
Subtag: thw
Description: Thudam
Added: 2009-07-29
+Deprecated: 2020-06-08
+Preferred-Value: ola
%%
Type: language
Subtag: thx
@@ -36240,6 +36338,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: uki
+Description: Kui (India)
+Added: 2020-03-28
+%%
+Type: language
Subtag: ukk
Description: Muak Sa-aak
Added: 2017-02-23
@@ -36271,6 +36374,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: ukv
+Description: Kuku
+Added: 2020-03-28
+%%
+Type: language
Subtag: ukw
Description: Ukwuani-Aboh-Ndoni
Added: 2009-07-29
@@ -37760,6 +37868,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: wlh
+Description: Welaun
+Added: 2020-03-28
+%%
+Type: language
Subtag: wli
Description: Waioli
Added: 2009-07-29
@@ -39232,6 +39345,11 @@
Added: 2013-09-10
%%
Type: language
+Subtag: xnm
+Description: Ngumbarl
+Added: 2020-03-28
+%%
+Type: language
Subtag: xnn
Description: Northern Kankanay
Added: 2009-07-29
@@ -39334,22 +39452,45 @@
Added: 2013-09-10
%%
Type: language
+Subtag: xpb
+Description: Northeastern Tasmanian
+Description: Pyemmairrener
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpc
Description: Pecheneg
Added: 2009-07-29
%%
Type: language
+Subtag: xpd
+Description: Oyster Bay Tasmanian
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpe
Description: Liberia Kpelle
Added: 2009-07-29
Macrolanguage: kpe
%%
Type: language
+Subtag: xpf
+Description: Southeast Tasmanian
+Description: Nuenonne
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpg
Description: Phrygian
Added: 2009-07-29
%%
Type: language
+Subtag: xph
+Description: North Midlands Tasmanian
+Description: Tyerrenoterpanner
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpi
Description: Pictish
Added: 2009-07-29
@@ -39365,6 +39506,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: xpl
+Description: Port Sorell Tasmanian
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpm
Description: Pumpokol
Added: 2009-07-29
@@ -39410,11 +39556,34 @@
Added: 2009-07-29
%%
Type: language
+Subtag: xpv
+Description: Northern Tasmanian
+Description: Tommeginne
+Added: 2020-03-28
+%%
+Type: language
+Subtag: xpw
+Description: Northwestern Tasmanian
+Description: Peerapper
+Added: 2020-03-28
+%%
+Type: language
+Subtag: xpx
+Description: Southwestern Tasmanian
+Description: Toogee
+Added: 2020-03-28
+%%
+Type: language
Subtag: xpy
Description: Puyo
Added: 2009-07-29
%%
Type: language
+Subtag: xpz
+Description: Bruny Island Tasmanian
+Added: 2020-03-28
+%%
+Type: language
Subtag: xqa
Description: Karakhanid
Added: 2009-07-29
@@ -39468,6 +39637,8 @@
Subtag: xrq
Description: Karranga
Added: 2013-09-10
+Deprecated: 2020-03-28
+Preferred-Value: dmw
%%
Type: language
Subtag: xrr
@@ -39700,6 +39871,8 @@
Subtag: xtz
Description: Tasmanian
Added: 2009-07-29
+Deprecated: 2020-03-28
+Comments: see xpb, xpd, xpf, xph, xpl, xpv, xpw, xpx, xpz
%%
Type: language
Subtag: xua
@@ -39729,6 +39902,7 @@
Type: language
Subtag: xul
Description: Ngunawal
+Description: Nunukul
Added: 2013-09-10
%%
Type: language
@@ -41321,6 +41495,11 @@
Added: 2009-07-29
%%
Type: language
+Subtag: zba
+Description: Balaibalan
+Added: 2020-03-28
+%%
+Type: language
Subtag: zbc
Description: Central Berawan
Added: 2009-07-29
@@ -41486,6 +41665,8 @@
Subtag: zir
Description: Ziriya
Added: 2009-07-29
+Deprecated: 2020-03-28
+Preferred-Value: scv
%%
Type: language
Subtag: ziw
@@ -42463,6 +42644,7 @@
Subtag: bbz
Description: Babalia Creole Arabic
Added: 2009-07-29
+Deprecated: 2020-03-28
Preferred-Value: bbz
Prefix: ar
Macrolanguage: ar
@@ -42580,6 +42762,15 @@
Macrolanguage: zh
%%
Type: extlang
+Subtag: cnp
+Description: Northern Ping Chinese
+Description: Northern Pinghua
+Added: 2020-03-28
+Preferred-Value: cnp
+Prefix: zh
+Macrolanguage: zh
+%%
+Type: extlang
Subtag: coa
Description: Cocos Islands Malay
Added: 2009-07-29
@@ -42647,6 +42838,15 @@
Prefix: sgn
%%
Type: extlang
+Subtag: csp
+Description: Southern Ping Chinese
+Description: Southern Pinghua
+Added: 2020-03-28
+Preferred-Value: csp
+Prefix: zh
+Macrolanguage: zh
+%%
+Type: extlang
Subtag: csq
Description: Croatia Sign Language
Added: 2009-07-29
@@ -44928,6 +45128,11 @@
Added: 2011-08-16
%%
Type: script
+Subtag: Toto
+Description: Toto
+Added: 2020-05-12
+%%
+Type: script
Subtag: Ugar
Description: Ugaritic
Added: 2005-10-16
@@ -46630,6 +46835,12 @@
Letras in 1943 and generally used in Brazil until 2009
%%
Type: variant
+Subtag: akuapem
+Description: Akuapem Twi
+Added: 2017-06-05
+Prefix: tw
+%%
+Type: variant
Subtag: alalc97
Description: ALA-LC Romanization, 1997 edition
Added: 2009-12-09
@@ -46648,12 +46859,6 @@
continuum in Eastern Suriname and Western French Guiana
%%
Type: variant
-Subtag: akuapem
-Description: Akuapem Twi
-Added: 2017-06-05
-Prefix: tw
-%%
-Type: variant
Subtag: ao1990
Description: Portuguese Language Orthographic Agreement of 1990 (Acordo
Ortográfico da Língua Portuguesa de 1990)
@@ -47129,6 +47334,16 @@
Creole continuum in Eastern Suriname and Western French Guiana
%%
Type: variant
+Subtag: peano
+Description: Latino Sine Flexione
+Description: Interlingua de API
+Description: Interlingua de Peano
+Prefix: la
+Comments: Peano’s Interlingua, created in 1903 by Giuseppe Peano as an
+ international auxiliary language
+Added: 2020-03-12
+%%
+Type: variant
Subtag: petr1708
Description: Petrine orthography
Added: 2010-10-10
@@ -47266,6 +47481,23 @@
Miensk 2005).
%%
Type: variant
+Subtag: tongyong
+Description: Tongyong Pinyin romanization
+Added: 2020-06-08
+Prefix: zh-Latn
+Comments: Former official transcription standard for Mandarin Chinese in
+ Taiwan.
+%%
+Type: variant
+Subtag: tunumiit
+Description: Tunumiisiut
+Description: East Greenlandic
+Description: Østgrønlandsk
+Added: 2020-07-16
+Prefix: kl
+Comments: Also known as Tunumiit oraasiat
+%%
+Type: variant
Subtag: uccor
Description: Unified Cornish orthography of Revived Cornish
Added: 2008-10-14
diff --git a/tools/java/org/unicode/cldr/util/data/language_script_raw.txt b/tools/java/org/unicode/cldr/util/data/language_script_raw.txt
index 4660a44..1b963c4 100644
--- a/tools/java/org/unicode/cldr/util/data/language_script_raw.txt
+++ b/tools/java/org/unicode/cldr/util/data/language_script_raw.txt
@@ -1,4 +1,7 @@
#Lcode LanguageName Status Scode ScriptName References
+#######
+#WARNING: this file is in TSV format (for pasting from a spreadsheet); make sure you maintain tabs!
+#######
aa Afar primary Latn Latin
ab Abkhazian primary Cyrl Cyrillic
abq Abaza primary Cyrl Cyrillic
@@ -183,7 +186,8 @@
dje Zarma primary Latn Latin
dng Dungan primary Cyrl Cyrillic
dnj Dan primary Latn Latin
-doi Dogri primary Arab Arabic
+doi Dogri primary Deva Devanagari
+doi Dogri secondary Arab Arabic
doi Dogri secondary Takr Takri
dsb Lower Sorbian primary Latn Latin
dtm Tomo Kan Dogon primary Latn Latin
@@ -804,6 +808,7 @@
tru Turoyo primary Latn Latin
tru Turoyo secondary Syrc Syriac
trv Taroko primary Latn Latin
+trw Torwali primary Arab Arabic
ts Tsonga primary Latn Latin
tsd Tsakonian primary Grek Greek
tsg Tausug primary Latn Latin
diff --git a/tools/java/org/unicode/cldr/util/data/leapseconds b/tools/java/org/unicode/cldr/util/data/leapseconds
index 886ae27..3b9cc7b 100644
--- a/tools/java/org/unicode/cldr/util/data/leapseconds
+++ b/tools/java/org/unicode/cldr/util/data/leapseconds
@@ -3,36 +3,39 @@
# This file is in the public domain.
# This file is generated automatically from the data in the public-domain
-# leap-seconds.list file, which can be copied from
+# NIST format leap-seconds.list file, which can be copied from
# <ftp://ftp.nist.gov/pub/time/leap-seconds.list>
-# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>
-# or <ftp://tycho.usno.navy.mil/pub/ntp/leap-seconds.list>.
+# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>.
# For more about leap-seconds.list, please see
# The NTP Timescale and Leap Seconds
# <https://www.eecis.udel.edu/~mills/leap.html>.
-# The International Earth Rotation and Reference Systems Service
+# The rules for leap seconds are specified in Annex 1 (Time scales) of:
+# Standard-frequency and time-signal emissions.
+# International Telecommunication Union - Radiocommunication Sector
+# (ITU-R) Recommendation TF.460-6 (02/2002)
+# <https://www.itu.int/rec/R-REC-TF.460-6-200202-I/>.
+# The International Earth Rotation and Reference Systems Service (IERS)
# periodically uses leap seconds to keep UTC to within 0.9 s of UT1
-# (which measures the true angular orientation of the earth in space)
+# (a proxy for Earth's angle in space as measured by astronomers)
# and publishes leap second data in a copyrighted file
# <https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat>.
# See: Levine J. Coordinated Universal Time and the leap second.
# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995
# <https://ieeexplore.ieee.org/document/7909995>.
-# There were no leap seconds before 1972, because the official mechanism
-# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist. The first ("1 Jan 1972") data line in leap-seconds.list
+# There were no leap seconds before 1972, as no official mechanism
+# accounted for the discrepancy between atomic time (TAI) and the earth's
+# rotation. The first ("1 Jan 1972") data line in leap-seconds.list
# does not denote a leap second; it denotes the start of the current definition
# of UTC.
-# The correction (+ or -) is made at the given time, so lines
-# will typically look like:
-# Leap YEAR MON DAY 23:59:60 + R/S
-# or
-# Leap YEAR MON DAY 23:59:59 - R/S
-
-# If the leap second is Rolling (R) the given time is local time (unused here).
+# All leap-seconds are Stationary (S) at the given UTC time.
+# The correction (+ or -) is made at the given time, so in the unlikely
+# event of a negative leap second, a line would look like this:
+# Leap YEAR MON DAY 23:59:59 - S
+# Typical lines look like this:
+# Leap YEAR MON DAY 23:59:60 + S
Leap 1972 Jun 30 23:59:60 + S
Leap 1972 Dec 31 23:59:60 + S
Leap 1973 Dec 31 23:59:60 + S
@@ -61,9 +64,15 @@
Leap 2015 Jun 30 23:59:60 + S
Leap 2016 Dec 31 23:59:60 + S
-# POSIX timestamps for the data in this file:
-#updated 1467936000
-#expires 1577491200
+# UTC timestamp when this leap second list expires.
+# Any additional leap seconds will come after this.
+# This Expires line is commented out for now,
+# so that pre-2020a zic implementations do not reject this file.
+#Expires 2020 Dec 28 00:00:00
-# Updated through IERS Bulletin C57
-# File expires on: 28 December 2019
+# POSIX timestamps for the data in this file:
+#updated 1467936000 (2016-07-08 00:00:00 UTC)
+#expires 1609113600 (2020-12-28 00:00:00 UTC)
+
+# Updated through IERS Bulletin C59
+# File expires on: 28 December 2020
diff --git a/tools/java/org/unicode/cldr/util/data/lstreg.txt b/tools/java/org/unicode/cldr/util/data/lstreg.txt
deleted file mode 100644
index 9013ca5..0000000
--- a/tools/java/org/unicode/cldr/util/data/lstreg.txt
+++ /dev/null
@@ -1,1010 +0,0 @@
-# IANA Language Subtag Registry
-# This registry lists all valid subtags for language tags
-# created under RFC 3066bis.
-#
-# Format (except for date record):
-#
-# type | subtag | description | date | canonical_value | recommended_prefix # comments
-#
-# where:
-# - 'type' is the type of subtag (language, extlang, script, region, variant, grandfathered, redundant)
-# - 'subtag' is the subtag (or tag, if grandfathered or redundant) defined by this record
-# - 'description' is an English-language description of the subtag
-# - 'date' is the date this record was added to the registry (ISO 8601)
-# - 'canonical_value', if present, is the canonical subtag for which this subtag is an alias
-# - 'recommended_prefix' is an informative list of language-ranges considered most appropriate for this (variant) subtag
-# - 'comments' are informative only
-
-date | 2005-01-06
-
-# language codes: ISO 639 and registered codes
-
-# ISO 639-1 (alpha-2) codes
-language | aa | Afar | 2004-07-06 | |
-language | ab | Abkhazian | 2004-07-06 | |
-language | ae | Avestan | 2004-07-06 | |
-language | af | Afrikaans | 2004-07-06 | |
-language | ak | Akan | 2004-07-06 | |
-language | am | Amharic | 2004-07-06 | |
-language | an | Aragonese | 2004-07-06 | |
-language | ar | Arabic | 2004-07-06 | |
-language | as | Assamese | 2004-07-06 | |
-language | av | Avaric | 2004-07-06 | |
-language | ay | Aymara | 2004-07-06 | |
-language | az | Azerbaijani | 2004-07-06 | |
-language | ba | Bashkir | 2004-07-06 | |
-language | be | Belarusian | 2004-07-06 | |
-language | bg | Bulgarian | 2004-07-06 | |
-language | bh | Bihari | 2004-07-06 | |
-language | bi | Bislama | 2004-07-06 | |
-language | bm | Bambara | 2004-07-06 | |
-language | bn | Bengali | 2004-07-06 | |
-language | bo | Tibetan | 2004-07-06 | |
-language | br | Breton | 2004-07-06 | |
-language | bs | Bosnian | 2004-07-06 | |
-language | ca | Catalan; Valencian | 2004-07-06 | |
-language | ce | Chechen | 2004-07-06 | |
-language | ch | Chamorro | 2004-07-06 | |
-language | co | Corsican | 2004-07-06 | |
-language | cr | Cree | 2004-07-06 | |
-language | cs | Czech | 2004-07-06 | |
-language | cu | Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic | 2004-07-06 | |
-language | cv | Chuvash | 2004-07-06 | |
-language | cy | Welsh | 2004-07-06 | |
-language | da | Danish | 2004-07-06 | |
-language | de | German | 2004-07-06 | |
-language | dv | Divehi | 2004-07-06 | |
-language | dz | Dzongkha | 2004-07-06 | |
-language | ee | Ewe | 2004-07-06 | |
-language | el | Greek, Modern (1453-) | 2004-07-06 | |
-language | en | English | 2004-07-06 | |
-language | eo | Esperanto | 2004-07-06 | |
-language | es | Spanish; Castilian | 2004-07-06 | |
-language | et | Estonian | 2004-07-06 | |
-language | eu | Basque | 2004-07-06 | |
-language | fa | Persian | 2004-07-06 | |
-language | ff | Fulah | 2004-07-06 | |
-language | fi | Finnish | 2004-07-06 | |
-language | fj | Fijian | 2004-07-06 | |
-language | fo | Faroese | 2004-07-06 | |
-language | fr | French | 2004-07-06 | |
-language | fy | Frisian | 2004-07-06 | |
-language | ga | Irish | 2004-07-06 | |
-language | gd | Gaelic; Scottish Gaelic | 2004-07-06 | |
-language | gl | Gallegan | 2004-07-06 | |
-language | gn | Guarani | 2004-07-06 | |
-language | gu | Gujarati | 2004-07-06 | |
-language | gv | Manx | 2004-07-06 | |
-language | ha | Hausa | 2004-07-06 | |
-language | he | Hebrew | 2004-07-06 | |
-language | hi | Hindi | 2004-07-06 | |
-language | ho | Hiri Motu | 2004-07-06 | |
-language | hr | Croatian | 2004-07-06 | |
-language | ht | Haitian; Haitian Creole | 2004-07-06 | |
-language | hu | Hungarian | 2004-07-06 | |
-language | hy | Armenian | 2004-07-06 | |
-language | hz | Herero | 2004-07-06 | |
-language | ia | Interlingua (International Auxiliary Language Association) | 2004-07-06 | |
-language | id | Indonesian | 2004-07-06 | |
-language | ie | Interlingue | 2004-07-06 | |
-language | ig | Igbo | 2004-07-06 | |
-language | ii | Sichuan Yi | 2004-07-06 | |
-language | ik | Inupiaq | 2004-07-06 | |
-language | in | Indonesian | 2004-07-06 | id | # deprecated 1989
-language | io | Ido | 2004-07-06 | |
-language | is | Icelandic | 2004-07-06 | |
-language | it | Italian | 2004-07-06 | |
-language | iu | Inuktitut | 2004-07-06 | |
-language | iw | Hebrew | 2004-07-06 | he | # deprecated 1989
-language | ja | Japanese | 2004-07-06 | |
-language | ji | Yiddish | 2004-07-06 | yi | # deprecated 1989
-language | jv | Javanese | 2004-07-06 | |
-language | jw | Javanese | 2004-07-06 | jv |
-language | ka | Georgian | 2004-07-06 | |
-language | kg | Kongo | 2004-07-06 | |
-language | ki | Kikuyu; Gikuyu | 2004-07-06 | |
-language | kj | Kuanyama; Kwanyama | 2004-07-06 | |
-language | kk | Kazakh | 2004-07-06 | |
-language | kl | Kalaallisut; Greenlandic | 2004-07-06 | |
-language | km | Khmer | 2004-07-06 | |
-language | kn | Kannada | 2004-07-06 | |
-language | ko | Korean | 2004-07-06 | |
-language | kr | Kanuri | 2004-07-06 | |
-language | ks | Kashmiri | 2004-07-06 | |
-language | ku | Kurdish | 2004-07-06 | |
-language | kv | Komi | 2004-07-06 | |
-language | kw | Cornish | 2004-07-06 | |
-language | ky | Kirghiz | 2004-07-06 | |
-language | la | Latin | 2004-07-06 | |
-language | lb | Luxembourgish; Letzeburgesch | 2004-07-06 | |
-language | lg | Ganda | 2004-07-06 | |
-language | li | Limburgan; Limburger; Limburgish | 2004-07-06 | |
-language | ln | Lingala | 2004-07-06 | |
-language | lo | Lao | 2004-07-06 | |
-language | lt | Lithuanian | 2004-07-06 | |
-language | lu | Luba-Katanga | 2004-07-06 | |
-language | lv | Latvian | 2004-07-06 | |
-language | mg | Malagasy | 2004-07-06 | |
-language | mh | Marshallese | 2004-07-06 | |
-language | mi | Maori | 2004-07-06 | |
-language | mk | Macedonian | 2004-07-06 | |
-language | ml | Malayalam | 2004-07-06 | |
-language | mn | Mongolian | 2004-07-06 | |
-language | mo | Moldavian | 2004-07-06 | |
-language | mr | Marathi | 2004-07-06 | |
-language | ms | Malay | 2004-07-06 | |
-language | mt | Maltese | 2004-07-06 | |
-language | my | Burmese | 2004-07-06 | |
-language | na | Nauru | 2004-07-06 | |
-language | nb | Norwegian Bokmal | 2004-07-06 | |
-language | nd | Ndebele, North; North Ndebele | 2004-07-06 | |
-language | ne | Nepali | 2004-07-06 | |
-language | ng | Ndonga | 2004-07-06 | |
-language | nl | Dutch; Flemish | 2004-07-06 | |
-language | nn | Norwegian Nynorsk | 2004-07-06 | |
-language | no | Norwegian | 2004-07-06 | |
-language | nr | Ndebele, South; South Ndebele | 2004-07-06 | |
-language | nv | Navajo; Navaho | 2004-07-06 | |
-language | ny | Chichewa; Chewa; Nyanja | 2004-07-06 | |
-language | oc | Occitan (post 1500); Provencal | 2004-07-06 | |
-language | oj | Ojibwa | 2004-07-06 | |
-language | om | Oromo | 2004-07-06 | |
-language | or | Oriya | 2004-07-06 | |
-language | os | Ossetian; Ossetic | 2004-07-06 | |
-language | pa | Panjabi; Punjabi | 2004-07-06 | |
-language | pi | Pali | 2004-07-06 | |
-language | pl | Polish | 2004-07-06 | |
-language | ps | Pushto | 2004-07-06 | |
-language | pt | Portuguese | 2004-07-06 | |
-language | qu | Quechua | 2004-07-06 | |
-language | rm | Raeto-Romance | 2004-07-06 | |
-language | rn | Rundi | 2004-07-06 | |
-language | ro | Romanian | 2004-07-06 | |
-language | ru | Russian | 2004-07-06 | |
-language | rw | Kinyarwanda | 2004-07-06 | |
-language | sa | Sanskrit | 2004-07-06 | |
-language | sc | Sardinian | 2004-07-06 | |
-language | sd | Sindhi | 2004-07-06 | |
-language | se | Northern Sami | 2004-07-06 | |
-language | sg | Sango | 2004-07-06 | |
-language | sh | Serbo-Croatian | 2004-07-06 | | # deprecated 2000-02-18
-language | si | Sinhala; Sinhalese | 2004-07-06 | |
-language | sk | Slovak | 2004-07-06 | |
-language | sl | Slovenian | 2004-07-06 | |
-language | sm | Samoan | 2004-07-06 | |
-language | sn | Shona | 2004-07-06 | |
-language | so | Somali | 2004-07-06 | |
-language | sq | Albanian | 2004-07-06 | |
-language | sr | Serbian | 2004-07-06 | |
-language | ss | Swati | 2004-07-06 | |
-language | st | Sotho, Southern | 2004-07-06 | |
-language | su | Sundanese | 2004-07-06 | |
-language | sv | Swedish | 2004-07-06 | |
-language | sw | Swahili | 2004-07-06 | |
-language | ta | Tamil | 2004-07-06 | |
-language | te | Telugu | 2004-07-06 | |
-language | tg | Tajik | 2004-07-06 | |
-language | th | Thai | 2004-07-06 | |
-language | ti | Tigrinya | 2004-07-06 | |
-language | tk | Turkmen | 2004-07-06 | |
-language | tl | Tagalog | 2004-07-06 | |
-language | tn | Tswana | 2004-07-06 | |
-language | to | Tonga (Tonga Islands) | 2004-07-06 | |
-language | tr | Turkish | 2004-07-06 | |
-language | ts | Tsonga | 2004-07-06 | |
-language | tt | Tatar | 2004-07-06 | |
-language | tw | Twi | 2004-07-06 | |
-language | ty | Tahitian | 2004-07-06 | |
-language | ug | Uighur; Uyghur | 2004-07-06 | |
-language | uk | Ukrainian | 2004-07-06 | |
-language | ur | Urdu | 2004-07-06 | |
-language | uz | Uzbek | 2004-07-06 | |
-language | ve | Venda | 2004-07-06 | |
-language | vi | Vietnamese | 2004-07-06 | |
-language | vo | Volapuk | 2004-07-06 | |
-language | wa | Walloon | 2004-07-06 | |
-language | wo | Wolof | 2004-07-06 | |
-language | xh | Xhosa | 2004-07-06 | |
-language | yi | Yiddish | 2004-07-06 | |
-language | yo | Yoruba | 2004-07-06 | |
-language | za | Zhuang; Chuang | 2004-07-06 | |
-language | zh | Chinese | 2004-07-06 | |
-language | zu | Zulu | 2004-07-06 | |
-
-# ISO 639-2 (alpha-3) codes
-language | ace | Achinese | 2004-07-06 | |
-language | ach | Acoli | 2004-07-06 | |
-language | ada | Adangme | 2004-07-06 | |
-language | ady | Adyghe; Adygei | 2004-07-06 | |
-language | afa | Afro-Asiatic (Other) | 2004-07-06 | |
-language | afh | Afrihili | 2004-07-06 | |
-language | akk | Akkadian | 2004-07-06 | |
-language | ale | Aleut | 2004-07-06 | |
-language | alg | Algonquian languages | 2004-07-06 | |
-language | alt | Southern Altai | 2004-07-06 | |
-language | ang | English, Old (ca. 450-1100) | 2004-07-06 | |
-language | apa | Apache languages | 2004-07-06 | |
-language | arc | Aramaic | 2004-07-06 | |
-language | arn | Araucanian | 2004-07-06 | |
-language | arp | Arapaho | 2004-07-06 | |
-language | art | Artificial (Other) | 2004-07-06 | |
-language | arw | Arawak | 2004-07-06 | |
-language | ast | Asturian; Bable | 2004-07-06 | |
-language | ath | Athapascan languages | 2004-07-06 | |
-language | aus | Australian languages | 2004-07-06 | |
-language | awa | Awadhi | 2004-07-06 | |
-language | bad | Banda | 2004-07-06 | |
-language | bai | Bamileke languages | 2004-07-06 | |
-language | bal | Baluchi | 2004-07-06 | |
-language | ban | Balinese | 2004-07-06 | |
-language | bas | Basa | 2004-07-06 | |
-language | bat | Baltic (Other) | 2004-07-06 | |
-language | bej | Beja | 2004-07-06 | |
-language | bem | Bemba | 2004-07-06 | |
-language | ber | Berber (Other) | 2004-07-06 | |
-language | bho | Bhojpuri | 2004-07-06 | |
-language | bik | Bikol | 2004-07-06 | |
-language | bin | Bini | 2004-07-06 | |
-language | bla | Siksika | 2004-07-06 | |
-language | bnt | Bantu (Other) | 2004-07-06 | |
-language | bra | Braj | 2004-07-06 | |
-language | btk | Batak (Indonesia) | 2004-07-06 | |
-language | bua | Buriat | 2004-07-06 | |
-language | bug | Buginese | 2004-07-06 | |
-language | byn | Blin; Bilin | 2004-07-06 | |
-language | cad | Caddo | 2004-07-06 | |
-language | cai | Central American Indian (Other) | 2004-07-06 | |
-language | car | Carib | 2004-07-06 | |
-language | cau | Caucasian (Other) | 2004-07-06 | |
-language | ceb | Cebuano | 2004-07-06 | |
-language | cel | Celtic (Other) | 2004-07-06 | |
-language | chb | Chibcha | 2004-07-06 | |
-language | chg | Chagatai | 2004-07-06 | |
-language | chk | Chuukese | 2004-07-06 | |
-language | chm | Mari | 2004-07-06 | |
-language | chn | Chinook jargon | 2004-07-06 | |
-language | cho | Choctaw | 2004-07-06 | |
-language | chp | Chipewyan | 2004-07-06 | |
-language | chr | Cherokee | 2004-07-06 | |
-language | chy | Cheyenne | 2004-07-06 | |
-language | cmc | Chamic languages | 2004-07-06 | |
-language | cop | Coptic | 2004-07-06 | |
-language | cpe | Creoles and pidgins, English-based (Other) | 2004-07-06 | |
-language | cpf | Creoles and pidgins, French-based (Other) | 2004-07-06 | |
-language | cpp | Creoles and pidgins, Portuguese-based (Other) | 2004-07-06 | |
-language | crh | Crimean Tatar; Crimean Turkish | 2004-07-06 | |
-language | crp | Creoles and pidgins (Other) | 2004-07-06 | |
-language | csb | Kashubian | 2004-07-06 | |
-language | cus | Cushitic (Other) | 2004-07-06 | |
-language | dak | Dakota | 2004-07-06 | |
-language | dar | Dargwa | 2004-07-06 | |
-language | day | Dayak | 2004-07-06 | |
-language | del | Delaware | 2004-07-06 | |
-language | den | Slave (Athapascan) | 2004-07-06 | |
-language | dgr | Dogrib | 2004-07-06 | |
-language | din | Dinka | 2004-07-06 | |
-language | doi | Dogri | 2004-07-06 | |
-language | dra | Dravidian (Other) | 2004-07-06 | |
-language | dsb | Lower Sorbian | 2004-07-06 | |
-language | dua | Duala | 2004-07-06 | |
-language | dum | Dutch, Middle (ca. 1050-1350) | 2004-07-06 | |
-language | dyu | Dyula | 2004-07-06 | |
-language | efi | Efik | 2004-07-06 | |
-language | egy | Egyptian (Ancient) | 2004-07-06 | |
-language | eka | Ekajuk | 2004-07-06 | |
-language | elx | Elamite | 2004-07-06 | |
-language | enm | English, Middle (1100-1500) | 2004-07-06 | |
-language | ewo | Ewondo | 2004-07-06 | |
-language | fan | Fang | 2004-07-06 | |
-language | fat | Fanti | 2004-07-06 | |
-language | fil | Filipino; Pilipino | 2004-09-21 | |
-language | fiu | Finno-Ugrian (Other) | 2004-07-06 | |
-language | fon | Fon | 2004-07-06 | |
-language | frm | French, Middle (ca. 1400-1800) | 2004-07-06 | |
-language | fro | French, Old (842-ca. 1400) | 2004-07-06 | |
-language | fur | Friulian | 2004-07-06 | |
-language | gaa | Ga | 2004-07-06 | |
-language | gay | Gayo | 2004-07-06 | |
-language | gba | Gbaya | 2004-07-06 | |
-language | gem | Germanic (Other) | 2004-07-06 | |
-language | gez | Geez | 2004-07-06 | |
-language | gil | Gilbertese | 2004-07-06 | |
-language | gmh | German, Middle High (ca. 1050-1500) | 2004-07-06 | |
-language | goh | German, Old High (ca. 750-1050) | 2004-07-06 | |
-language | gon | Gondi | 2004-07-06 | |
-language | gor | Gorontalo | 2004-07-06 | |
-language | got | Gothic | 2004-07-06 | |
-language | grb | Grebo | 2004-07-06 | |
-language | grc | Greek, Ancient (to 1453) | 2004-07-06 | |
-language | gwi | Gwich'in | 2004-07-06 | |
-language | hai | Haida | 2004-07-06 | |
-language | haw | Hawaiian | 2004-07-06 | |
-language | hil | Hiligaynon | 2004-07-06 | |
-language | him | Himachali | 2004-07-06 | |
-language | hit | Hittite | 2004-07-06 | |
-language | hmn | Hmong | 2004-07-06 | |
-language | hsb | Upper Sorbian | 2004-07-06 | |
-language | hup | Hupa | 2004-07-06 | |
-language | iba | Iban | 2004-07-06 | |
-language | ijo | Ijo | 2004-07-06 | |
-language | ilo | Iloko | 2004-07-06 | |
-language | inc | Indic (Other) | 2004-07-06 | |
-language | ine | Indo-European (Other) | 2004-07-06 | |
-language | inh | Ingush | 2004-07-06 | |
-language | ira | Iranian (Other) | 2004-07-06 | |
-language | iro | Iroquoian languages | 2004-07-06 | |
-language | jbo | Lojban | 2004-07-06 | |
-language | jpr | Judeo-Persian | 2004-07-06 | |
-language | jrb | Judeo-Arabic | 2004-07-06 | |
-language | kaa | Kara-Kalpak | 2004-07-06 | |
-language | kab | Kabyle | 2004-07-06 | |
-language | kac | Kachin | 2004-07-06 | |
-language | kam | Kamba | 2004-07-06 | |
-language | kar | Karen | 2004-07-06 | |
-language | kaw | Kawi | 2004-07-06 | |
-language | kbd | Kabardian | 2004-07-06 | |
-language | kha | Khasi | 2004-07-06 | |
-language | khi | Khoisan (Other) | 2004-07-06 | |
-language | kho | Khotanese | 2004-07-06 | |
-language | kmb | Kimbundu | 2004-07-06 | |
-language | kok | Konkani | 2004-07-06 | |
-language | kos | Kosraean | 2004-07-06 | |
-language | kpe | Kpelle | 2004-07-06 | |
-language | krc | Karachay-Balkar | 2004-07-06 | |
-language | kro | Kru | 2004-07-06 | |
-language | kru | Kurukh | 2004-07-06 | |
-language | kum | Kumyk | 2004-07-06 | |
-language | kut | Kutenai | 2004-07-06 | |
-language | lad | Ladino | 2004-07-06 | |
-language | lah | Lahnda | 2004-07-06 | |
-language | lam | Lamba | 2004-07-06 | |
-language | lez | Lezghian | 2004-07-06 | |
-language | lol | Mongo | 2004-07-06 | |
-language | loz | Lozi | 2004-07-06 | |
-language | lua | Luba-Lulua | 2004-07-06 | |
-language | lui | Luiseno | 2004-07-06 | |
-language | lun | Lunda | 2004-07-06 | |
-language | luo | Luo (Kenya and Tanzania) | 2004-07-06 | |
-language | lus | Lushai | 2004-07-06 | |
-language | mad | Madurese | 2004-07-06 | |
-language | mag | Magahi | 2004-07-06 | |
-language | mai | Maithili | 2004-07-06 | |
-language | mak | Makasar | 2004-07-06 | |
-language | man | Mandingo | 2004-07-06 | |
-language | map | Austronesian (Other) | 2004-07-06 | |
-language | mas | Masai | 2004-07-06 | |
-language | mdf | Moksha | 2004-07-06 | |
-language | mdr | Mandar | 2004-07-06 | |
-language | men | Mende | 2004-07-06 | |
-language | mga | Irish, Middle (900-1200) | 2004-07-06 | |
-language | mic | Mi'kmaq; Micmac | 2004-07-06 | |
-language | min | Minangkabau | 2004-07-06 | |
-language | mis | Miscellaneous languages | 2004-07-06 | |
-language | mkh | Mon-Khmer (Other) | 2004-07-06 | |
-language | mnc | Manchu | 2004-07-06 | |
-language | mni | Manipuri | 2004-07-06 | |
-language | mno | Manobo languages | 2004-07-06 | |
-language | moh | Mohawk | 2004-07-06 | |
-language | mos | Mossi | 2004-07-06 | |
-language | mul | Multiple languages | 2004-07-06 | |
-language | mun | Munda languages | 2004-07-06 | |
-language | mus | Creek | 2004-07-06 | |
-language | mwl | Mirandese | 2004-09-21 | |
-language | mwr | Marwari | 2004-07-06 | |
-language | myn | Mayan languages | 2004-07-06 | |
-language | myv | Erzya | 2004-07-06 | |
-language | nah | Nahuatl | 2004-07-06 | |
-language | nai | North American Indian | 2004-07-06 | |
-language | nap | Neapolitan | 2004-07-06 | |
-language | nds | Low German; Low Saxon; German, Low; Saxon, Low | 2004-07-06 | |
-language | new | Nepal Bhasa; Newari | 2004-07-06 | |
-language | nia | Nias | 2004-07-06 | |
-language | nic | Niger-Kordofanian (Other) | 2004-07-06 | |
-language | niu | Niuean | 2004-07-06 | |
-language | nog | Nogai | 2004-07-06 | |
-language | non | Norse, Old | 2004-07-06 | |
-language | nso | Northern Sotho; Pedi; Sepedi | 2004-07-06 | |
-language | nub | Nubian languages | 2004-07-06 | |
-language | nwc | Classical Newari; Old Newari; Classical Nepal Bhasa | 2004-07-06 | |
-language | nym | Nyamwezi | 2004-07-06 | |
-language | nyn | Nyankole | 2004-07-06 | |
-language | nyo | Nyoro | 2004-07-06 | |
-language | nzi | Nzima | 2004-07-06 | |
-language | osa | Osage | 2004-07-06 | |
-language | ota | Turkish, Ottoman (1500-1928) | 2004-07-06 | |
-language | oto | Otomian languages | 2004-07-06 | |
-language | paa | Papuan (Other) | 2004-07-06 | |
-language | pag | Pangasinan | 2004-07-06 | |
-language | pal | Pahlavi | 2004-07-06 | |
-language | pam | Pampanga | 2004-07-06 | |
-language | pap | Papiamento | 2004-07-06 | |
-language | pau | Palauan | 2004-07-06 | |
-language | peo | Persian, Old (ca. 600-400 B.C.) | 2004-07-06 | |
-language | phi | Philippine (Other) | 2004-07-06 | |
-language | phn | Phoenician | 2004-07-06 | |
-language | pon | Pohnpeian | 2004-07-06 | |
-language | pra | Prakrit languages | 2004-07-06 | |
-language | pro | Provencal, Old (to 1500) | 2004-07-06 | |
-language | qaa..qtz | PRIVATE USE | 2004-08-01 | |
-language | raj | Rajasthani | 2004-07-06 | |
-language | rap | Rapanui | 2004-07-06 | |
-language | rar | Rarotongan | 2004-07-06 | |
-language | roa | Romance (Other) | 2004-07-06 | |
-language | rom | Romany | 2004-07-06 | |
-language | sad | Sandawe | 2004-07-06 | |
-language | sah | Yakut | 2004-07-06 | |
-language | sai | South American Indian (Other) | 2004-07-06 | |
-language | sal | Salishan languages | 2004-07-06 | |
-language | sam | Samaritan Aramaic | 2004-07-06 | |
-language | sas | Sasak | 2004-07-06 | |
-language | sat | Santali | 2004-07-06 | |
-language | scn | Sicilian | 2004-09-21 | |
-language | sco | Scots | 2004-07-06 | |
-language | sel | Selkup | 2004-07-06 | |
-language | sem | Semitic (Other) | 2004-07-06 | |
-language | sga | Irish, Old (to 900) | 2004-07-06 | |
-language | sgn | Sign Languages | 2004-07-06 | |
-language | shn | Shan | 2004-07-06 | |
-language | sid | Sidamo | 2004-07-06 | |
-language | sio | Siouan languages | 2004-07-06 | |
-language | sit | Sino-Tibetan (Other) | 2004-07-06 | |
-language | sla | Slavic (Other) | 2004-07-06 | |
-language | sma | Southern Sami | 2004-07-06 | |
-language | smi | Sami languages (Other) | 2004-07-06 | |
-language | smj | Lule Sami | 2004-07-06 | |
-language | smn | Inari Sami | 2004-07-06 | |
-language | sms | Skolt Sami | 2004-07-06 | |
-language | snk | Soninke | 2004-07-06 | |
-language | sog | Sogdian | 2004-07-06 | |
-language | son | Songhai | 2004-07-06 | |
-language | srn | Sranan Tongo | 2004-11-30 | |
-language | srr | Serer | 2004-07-06 | |
-language | ssa | Nilo-Saharan (Other) | 2004-07-06 | |
-language | suk | Sukuma | 2004-07-06 | |
-language | sus | Susu | 2004-07-06 | |
-language | sux | Sumerian | 2004-07-06 | |
-language | syr | Syriac | 2004-07-06 | |
-language | tai | Tai (Other) | 2004-07-06 | |
-language | tem | Timne | 2004-07-06 | |
-language | ter | Tereno | 2004-07-06 | |
-language | tet | Tetum | 2004-07-06 | |
-language | tig | Tigre | 2004-07-06 | |
-language | tiv | Tiv | 2004-07-06 | |
-language | tkl | Tokelau | 2004-07-06 | |
-language | tlh | Klingon; tlhIngan-Hol | 2004-07-06 | |
-language | tli | Tlingit | 2004-07-06 | |
-language | tmh | Tamashek | 2004-07-06 | |
-language | tog | Tonga (Nyasa) | 2004-07-06 | |
-language | tpi | Tok Pisin | 2004-07-06 | |
-language | tsi | Tsimshian | 2004-07-06 | |
-language | tum | Tumbuka | 2004-07-06 | |
-language | tup | Tupi languages | 2004-07-06 | |
-language | tut | Altaic (Other) | 2004-07-06 | |
-language | tvl | Tuvalu | 2004-07-06 | |
-language | tyv | Tuvinian | 2004-07-06 | |
-language | udm | Udmurt | 2004-07-06 | |
-language | uga | Ugaritic | 2004-07-06 | |
-language | umb | Umbundu | 2004-07-06 | |
-language | und | Undetermined | 2004-07-06 | |
-language | vai | Vai | 2004-07-06 | |
-language | vot | Votic | 2004-07-06 | |
-language | wak | Wakashan languages | 2004-07-06 | |
-language | wal | Walamo | 2004-07-06 | |
-language | war | Waray | 2004-07-06 | |
-language | was | Washo | 2004-07-06 | |
-language | wen | Sorbian languages | 2004-07-06 | |
-language | xal | Kalmyk | 2004-07-06 | |
-language | yao | Yao | 2004-07-06 | |
-language | yap | Yapese | 2004-07-06 | |
-language | ypk | Yupik languages | 2004-07-06 | |
-language | zap | Zapotec | 2004-07-06 | |
-language | zen | Zenaga | 2004-07-06 | |
-language | znd | Zande | 2004-07-06 | |
-language | zun | Zuni | 2004-07-06 | |
-
-# script codes: ISO 15924
-
-script | Arab | Arabic | 2004-07-06 | |
-script | Armn | Armenian | 2004-07-06 | |
-script | Bali | Balinese | 2004-07-06 | |
-script | Batk | Batak | 2004-07-06 | |
-script | Beng | Bengali | 2004-07-06 | |
-script | Blis | Blissymbols | 2004-07-06 | |
-script | Bopo | Bopomofo | 2004-07-06 | |
-script | Brah | Brahmi | 2004-07-06 | |
-script | Brai | Braille | 2004-07-06 | |
-script | Bugi | Buginese | 2004-07-06 | |
-script | Buhd | Buhid | 2004-07-06 | |
-script | Cans | Unified Canadian Aboriginal Syllabics | 2004-07-06 | |
-script | Cham | Cham | 2004-07-06 | |
-script | Cher | Cherokee | 2004-07-06 | |
-script | Cirt | Cirth | 2004-07-06 | |
-script | Copt | Coptic | 2004-07-06 | |
-script | Cprt | Cypriot | 2004-07-06 | |
-script | Cyrl | Cyrillic | 2004-07-06 | |
-script | Cyrs | Cyrillic (Old Church Slavonic variant) | 2004-07-06 | |
-script | Deva | Devanagari (Nagari) | 2004-07-06 | |
-script | Dsrt | Deseret (Mormon) | 2004-07-06 | |
-script | Egyd | Egyptian demotic | 2004-07-06 | |
-script | Egyh | Egyptian hieratic | 2004-07-06 | |
-script | Egyp | Egyptian hieroglyphs | 2004-07-06 | |
-script | Ethi | Ethiopic (Ge'ez) | 2004-07-06 | |
-script | Geor | Georgian (Mkhedruli) | 2004-07-06 | |
-script | Geok | Khutsuri (Asomtavruli and Nuskhuri) | 2004-10-25 | |
-script | Glag | Glagolitic | 2004-07-06 | |
-script | Goth | Gothic | 2004-07-06 | |
-script | Grek | Greek | 2004-07-06 | |
-script | Gujr | Gujarati | 2004-07-06 | |
-script | Guru | Gurmukhi | 2004-07-06 | |
-script | Hang | Hangul (Hangeul) | 2004-07-06 | |
-script | Hani | Han (Hanzi, Kanji, Hanja) | 2004-07-06 | |
-script | Hano | Hanunoo | 2004-07-06 | |
-script | Hans | Han (Simplified variant) | 2004-07-06 | |
-script | Hant | Han (Traditional variant) | 2004-07-06 | |
-script | Hebr | Hebrew | 2004-07-06 | |
-script | Hira | Hiragana | 2004-07-06 | |
-script | Hmng | Pahawh Hmong | 2004-07-06 | |
-script | Hrkt | (alias for Hiragana + Katakana) | 2004-07-06 | |
-script | Hung | Old Hungarian | 2004-07-06 | |
-script | Inds | Indus (Harappan) | 2004-07-06 | |
-script | Ital | Old Italic (Etruscan, Oscan, etc.) | 2004-07-06 | |
-script | Java | Javanese | 2004-07-06 | |
-script | Kali | Kayah Li | 2004-07-06 | |
-script | Kana | Katakana | 2004-07-06 | |
-script | Khar | Kharoshthi | 2004-07-06 | |
-script | Khmr | Khmer | 2004-07-06 | |
-script | Knda | Kannada | 2004-07-06 | |
-script | Laoo | Lao | 2004-07-06 | |
-script | Latf | Latin (Fraktur variant) | 2004-07-06 | |
-script | Latg | Latin (Gaelic variant) | 2004-07-06 | |
-script | Latn | Latin | 2004-07-06 | |
-script | Lepc | Lepcha (Rong) | 2004-07-06 | |
-script | Limb | Limbu | 2004-07-06 | |
-script | Lina | Linear A | 2004-07-06 | |
-script | Linb | Linear B | 2004-07-06 | |
-script | Mand | Mandaean | 2004-07-06 | |
-script | Maya | Mayan hieroglyphs | 2004-07-06 | |
-script | Mero | Meroitic | 2004-07-06 | |
-script | Mlym | Malayalam | 2004-07-06 | |
-script | Mong | Mongolian | 2004-07-06 | |
-script | Mymr | Myanmar (Burmese) | 2004-07-06 | |
-script | Nkoo | N’Ko | 2004-10-25 | |
-script | Ogam | Ogham | 2004-07-06 | |
-script | Orkh | Orkhon | 2004-07-06 | |
-script | Orya | Oriya | 2004-07-06 | |
-script | Osma | Osmanya | 2004-07-06 | |
-script | Perm | Old Permic | 2004-07-06 | |
-script | Phag | Phags-pa | 2004-07-06 | |
-script | Phnx | Phoenician | 2004-07-06 | |
-script | Plrd | Pollard Phonetic | 2004-07-06 | |
-script | Qaaa..Qabx | PRIVATE USE | 2004-08-01 | |
-script | Roro | Rongorongo | 2004-07-06 | |
-script | Runr | Runic | 2004-07-06 | |
-script | Sara | Sarati | 2004-07-06 | |
-script | Shaw | Shavian (Shaw) | 2004-07-06 | |
-script | Sinh | Sinhala | 2004-07-06 | |
-script | Sylo | Syloti Nagri | 2004-07-06 | |
-script | Syrc | Syriac | 2004-07-06 | |
-script | Syre | Syriac (Estrangelo variant) | 2004-07-06 | |
-script | Syrj | Syriac (Western variant) | 2004-07-06 | |
-script | Syrn | Syriac (Eastern variant) | 2004-07-06 | |
-script | Tagb | Tagbanwa | 2004-07-06 | |
-script | Tale | Tai Le | 2004-07-06 | |
-script | Talu | Tai Lue | 2004-07-06 | |
-script | Taml | Tamil | 2004-07-06 | |
-script | Telu | Telugu | 2004-07-06 | |
-script | Teng | Tengwar | 2004-07-06 | |
-script | Tfng | Tifinagh (Berber) | 2004-07-06 | |
-script | Tglg | Tagalog | 2004-07-06 | |
-script | Thaa | Thaana | 2004-07-06 | |
-script | Thai | Thai | 2004-07-06 | |
-script | Tibt | Tibetan | 2004-07-06 | |
-script | Ugar | Ugaritic | 2004-07-06 | |
-script | Vaii | Vai | 2004-07-06 | |
-script | Visp | Visible Speech | 2004-07-06 | |
-script | Xpeo | Old Persian | 2004-07-06 | |
-script | Xsux | Cuneiform, Sumero-Akkadian | 2004-07-06 | |
-script | Yiii | Yi | 2004-07-06 | |
-script | Zxxx | Code for unwritten languages | 2004-07-06 | |
-script | Zyyy | Code for undetermined script | 2004-07-06 | |
-script | Zzzz | Code for uncoded script | 2004-07-06 | |
-
-# region codes: ISO 3166 and UN codes
-
-# ISO 3166-1 (alpha-2) codes
-region | AA | PRIVATE USE | 2004-08-01 | |
-region | AD | Andorra | 2004-07-06 | |
-region | AE | United Arab Emirates | 2004-07-06 | |
-region | AF | Afghanistan | 2004-07-06 | |
-region | AG | Antigua and Barbuda | 2004-07-06 | |
-region | AI | Anguilla | 2004-07-06 | |
-region | AL | Albania | 2004-07-06 | |
-region | AM | Armenia | 2004-07-06 | |
-region | AN | Netherlands Antilles | 2004-07-06 | |
-region | AO | Angola | 2004-07-06 | |
-region | AQ | Antarctica | 2004-07-06 | |
-region | AR | Argentina | 2004-07-06 | |
-region | AS | American Samoa | 2004-07-06 | |
-region | AT | Austria | 2004-07-06 | |
-region | AU | Australia | 2004-07-06 | |
-region | AW | Aruba | 2004-07-06 | |
-region | AX | Aland Islands | 2004-07-06 | |
-region | AZ | Azerbaijan | 2004-07-06 | |
-region | BA | Bosnia and Herzegovina | 2004-07-06 | |
-region | BB | Barbados | 2004-07-06 | |
-region | BD | Bangladesh | 2004-07-06 | |
-region | BE | Belgium | 2004-07-06 | |
-region | BF | Burkina Faso | 2004-07-06 | |
-region | BG | Bulgaria | 2004-07-06 | |
-region | BH | Bahrain | 2004-07-06 | |
-region | BI | Burundi | 2004-07-06 | |
-region | BJ | Benin | 2004-07-06 | |
-region | BM | Bermuda | 2004-07-06 | |
-region | BN | Brunei Darussalam | 2004-07-06 | |
-region | BO | Bolivia | 2004-07-06 | |
-region | BQ | British Antarctic Territory | 2004-07-06 | | # deprecated 1979
-region | BR | Brazil | 2004-07-06 | |
-region | BS | Bahamas | 2004-07-06 | |
-region | BT | Bhutan | 2004-07-06 | |
-region | BU | Myanmar | 2004-07-06 | MM | # changed 1989-12-05, formerly Burma
-region | BV | Bouvet Island | 2004-07-06 | |
-region | BW | Botswana | 2004-07-06 | |
-region | BY | Belarus | 2004-07-06 | |
-region | BZ | Belize | 2004-07-06 | |
-region | CA | Canada | 2004-07-06 | |
-region | CC | Cocos (Keeling) Islands | 2004-07-06 | |
-region | CD | Congo, The Democratic Republic of the | 2004-07-06 | |
-region | CF | Central African Republic | 2004-07-06 | |
-region | CG | Congo | 2004-07-06 | |
-region | CH | Switzerland | 2004-07-06 | |
-region | CI | Cote d'Ivoire | 2004-07-06 | |
-region | CK | Cook Islands | 2004-07-06 | |
-region | CL | Chile | 2004-07-06 | |
-region | CM | Cameroon | 2004-07-06 | |
-region | CN | China | 2004-07-06 | |
-region | CO | Colombia | 2004-07-06 | |
-region | CR | Costa Rica | 2004-07-06 | |
-region | CS | Serbia and Montenegro | 2004-12-19 | |
-region | CT | Canton and Enderbury Islands | 2004-07-06 | | # deprecated 1984
-region | CU | Cuba | 2004-07-06 | |
-region | CV | Cape Verde | 2004-07-06 | |
-region | CX | Christmas Island | 2004-07-06 | |
-region | CY | Cyprus | 2004-07-06 | |
-region | CZ | Czech Republic | 2004-07-06 | |
-region | DD | East Germany | 2004-07-06 | | # deprecated 1990-10-30
-region | DE | Germany | 2004-07-06 | |
-region | DJ | Djibouti | 2004-07-06 | |
-region | DK | Denmark | 2004-07-06 | |
-region | DM | Dominica | 2004-07-06 | |
-region | DO | Dominican Republic | 2004-07-06 | |
-region | DY | Benin | 2004-07-06 | BJ | # changed 1977, formerly Dahomey
-region | DZ | Algeria | 2004-07-06 | |
-region | EC | Ecuador | 2004-07-06 | |
-region | EE | Estonia | 2004-07-06 | |
-region | EG | Egypt | 2004-07-06 | |
-region | EH | Western Sahara | 2004-07-06 | |
-region | ER | Eritrea | 2004-07-06 | |
-region | ES | Spain | 2004-07-06 | |
-region | ET | Ethiopia | 2004-07-06 | |
-region | FI | Finland | 2004-07-06 | |
-region | FJ | Fiji | 2004-07-06 | |
-region | FK | Falkland Islands (Malvinas) | 2004-07-06 | |
-region | FM | Micronesia, Federated States of | 2004-07-06 | |
-region | FO | Faroe Islands | 2004-07-06 | |
-region | FQ | French Southern and Antarctic Territories | 2004-07-06 | | # deprecated 1979
-region | FR | France | 2004-07-06 | |
-region | FX | Metropolitan France | 2004-07-06 | | # deprecated 1997-07-14
-region | GA | Gabon | 2004-07-06 | |
-region | GB | United Kingdom | 2004-07-06 | |
-region | GD | Grenada | 2004-07-06 | |
-region | GE | Georgia | 2004-07-06 | |
-region | GF | French Guiana | 2004-07-06 | |
-region | GH | Ghana | 2004-07-06 | |
-region | GI | Gibraltar | 2004-07-06 | |
-region | GL | Greenland | 2004-07-06 | |
-region | GM | Gambia | 2004-07-06 | |
-region | GN | Guinea | 2004-07-06 | |
-region | GP | Guadeloupe | 2004-07-06 | |
-region | GQ | Equatorial Guinea | 2004-07-06 | |
-region | GR | Greece | 2004-07-06 | |
-region | GS | South Georgia and the South Sandwich Islands | 2004-07-06 | |
-region | GT | Guatemala | 2004-07-06 | |
-region | GU | Guam | 2004-07-06 | |
-region | GW | Guinea-Bissau | 2004-07-06 | |
-region | GY | Guyana | 2004-07-06 | |
-region | HK | Hong Kong | 2004-07-06 | |
-region | HM | Heard Island and McDonald Islands | 2004-07-06 | |
-region | HN | Honduras | 2004-07-06 | |
-region | HR | Croatia | 2004-07-06 | |
-region | HT | Haiti | 2004-07-06 | |
-region | HU | Hungary | 2004-07-06 | |
-region | HV | Burkina Faso | 2004-07-06 | BF | # changed 1984, formerly Upper Volta
-region | ID | Indonesia | 2004-07-06 | |
-region | IE | Ireland | 2004-07-06 | |
-region | IL | Israel | 2004-07-06 | |
-region | IN | India | 2004-07-06 | |
-region | IO | British Indian Ocean Territory | 2004-07-06 | |
-region | IQ | Iraq | 2004-07-06 | |
-region | IR | Iran, Islamic Republic of | 2004-07-06 | |
-region | IS | Iceland | 2004-07-06 | |
-region | IT | Italy | 2004-07-06 | |
-region | JM | Jamaica | 2004-07-06 | |
-region | JO | Jordan | 2004-07-06 | |
-region | JP | Japan | 2004-07-06 | |
-region | JT | Johnston Island | 2004-07-06 | | # deprecated 1986
-region | KE | Kenya | 2004-07-06 | |
-region | KG | Kyrgyzstan | 2004-07-06 | |
-region | KH | Cambodia | 2004-07-06 | |
-region | KI | Kiribati | 2004-07-06 | |
-region | KM | Comoros | 2004-07-06 | |
-region | KN | Saint Kitts and Nevis | 2004-07-06 | |
-region | KP | Korea, Democratic People's Republic of | 2004-07-06 | |
-region | KR | Korea, Republic of | 2004-07-06 | |
-region | KW | Kuwait | 2004-07-06 | |
-region | KY | Cayman Islands | 2004-07-06 | |
-region | KZ | Kazakhstan | 2004-07-06 | |
-region | LA | Lao People's Democratic Republic | 2004-07-06 | |
-region | LB | Lebanon | 2004-07-06 | |
-region | LC | Saint Lucia | 2004-07-06 | |
-region | LI | Liechtenstein | 2004-07-06 | |
-region | LK | Sri Lanka | 2004-07-06 | |
-region | LR | Liberia | 2004-07-06 | |
-region | LS | Lesotho | 2004-07-06 | |
-region | LT | Lithuania | 2004-07-06 | |
-region | LU | Luxembourg | 2004-07-06 | |
-region | LV | Latvia | 2004-07-06 | |
-region | LY | Libyan Arab Jamahiriya | 2004-07-06 | |
-region | MA | Morocco | 2004-07-06 | |
-region | MC | Monaco | 2004-07-06 | |
-region | MD | Moldova, Republic of | 2004-07-06 | |
-region | MG | Madagascar | 2004-07-06 | |
-region | MH | Marshall Islands | 2004-07-06 | |
-region | MI | Midway Islands | 2004-07-06 | | # deprecated 1986
-region | MK | Macedonia, The Former Yugoslav Republic of | 2004-07-06 | |
-region | ML | Mali | 2004-07-06 | |
-region | MM | Myanmar | 2004-07-06 | |
-region | MN | Mongolia | 2004-07-06 | |
-region | MO | Macao | 2004-07-06 | |
-region | MP | Northern Mariana Islands | 2004-07-06 | |
-region | MQ | Martinique | 2004-07-06 | |
-region | MR | Mauritania | 2004-07-06 | |
-region | MS | Montserrat | 2004-07-06 | |
-region | MT | Malta | 2004-07-06 | |
-region | MU | Mauritius | 2004-07-06 | |
-region | MV | Maldives | 2004-07-06 | |
-region | MW | Malawi | 2004-07-06 | |
-region | MX | Mexico | 2004-07-06 | |
-region | MY | Malaysia | 2004-07-06 | |
-region | MZ | Mozambique | 2004-07-06 | |
-region | NA | Namibia | 2004-07-06 | |
-region | NC | New Caledonia | 2004-07-06 | |
-region | NE | Niger | 2004-07-06 | |
-region | NF | Norfolk Island | 2004-07-06 | |
-region | NG | Nigeria | 2004-07-06 | |
-region | NH | Vanuatu | 2004-07-06 | VU | # changed 1980, formerly New Hebrides
-region | NI | Nicaragua | 2004-07-06 | |
-region | NL | Netherlands | 2004-07-06 | |
-region | NO | Norway | 2004-07-06 | |
-region | NP | Nepal | 2004-07-06 | |
-region | NQ | Dronning Maud Land | 2004-07-06 | | # deprecated 1983
-region | NR | Nauru | 2004-07-06 | |
-region | NT | Neutral Zone | 2004-07-06 | | # deprecated 1993-07-12
-region | NU | Niue | 2004-07-06 | |
-region | NZ | New Zealand | 2004-07-06 | |
-region | OM | Oman | 2004-07-06 | |
-region | PA | Panama | 2004-07-06 | |
-region | PC | Pacific Islands Trust Territory | 2004-07-06 | | # deprecated 1986
-region | PE | Peru | 2004-07-06 | |
-region | PF | French Polynesia | 2004-07-06 | |
-region | PG | Papua New Guinea | 2004-07-06 | |
-region | PH | Philippines | 2004-07-06 | |
-region | PK | Pakistan | 2004-07-06 | |
-region | PL | Poland | 2004-07-06 | |
-region | PM | Saint Pierre and Miquelon | 2004-07-06 | |
-region | PN | Pitcairn | 2004-07-06 | |
-region | PR | Puerto Rico | 2004-07-06 | |
-region | PS | Palestinian Territory, Occupied | 2004-07-06 | |
-region | PT | Portugal | 2004-07-06 | |
-region | PU | U.S. Miscellaneous Pacific Islands | 2004-07-06 | | # deprecated 1986
-region | PW | Palau | 2004-07-06 | |
-region | PY | Paraguay | 2004-07-06 | |
-region | PZ | Panama Canal Zone | 2004-07-06 | | # deprecated 1980
-region | QA | Qatar | 2004-07-06 | |
-region | QM..QZ | PRIVATE USE | 2004-08-01 | |
-region | RE | Reunion | 2004-07-06 | |
-region | RH | Zimbabwe | 2004-07-06 | ZW | # changed 1980, formerly Southern Rhodesia
-region | RO | Romania | 2004-07-06 | |
-region | RU | Russian Federation | 2004-07-06 | |
-region | RW | Rwanda | 2004-07-06 | |
-region | SA | Saudi Arabia | 2004-07-06 | |
-region | SB | Solomon Islands | 2004-07-06 | |
-region | SC | Seychelles | 2004-07-06 | |
-region | SD | Sudan | 2004-07-06 | |
-region | SE | Sweden | 2004-07-06 | |
-region | SG | Singapore | 2004-07-06 | |
-region | SH | Saint Helena | 2004-07-06 | |
-region | SI | Slovenia | 2004-07-06 | |
-region | SJ | Svalbard and Jan Mayen | 2004-07-06 | |
-region | SK | Slovakia | 2004-07-06 | |
-region | SL | Sierra Leone | 2004-07-06 | |
-region | SM | San Marino | 2004-07-06 | |
-region | SN | Senegal | 2004-07-06 | |
-region | SO | Somalia | 2004-07-06 | |
-region | SR | Suriname | 2004-07-06 | |
-region | ST | Sao Tome and Principe | 2004-07-06 | |
-region | SU | Union of Soviet Socialist Republics | 2004-07-06 | | # deprecated 1992-08-30
-region | SV | El Salvador | 2004-07-06 | |
-region | SY | Syrian Arab Republic | 2004-07-06 | |
-region | SZ | Swaziland | 2004-07-06 | |
-region | TC | Turks and Caicos Islands | 2004-07-06 | |
-region | TD | Chad | 2004-07-06 | |
-region | TF | French Southern Territories | 2004-07-06 | |
-region | TG | Togo | 2004-07-06 | |
-region | TH | Thailand | 2004-07-06 | |
-region | TJ | Tajikistan | 2004-07-06 | |
-region | TK | Tokelau | 2004-07-06 | |
-region | TL | Timor-Leste | 2004-07-06 | |
-region | TM | Turkmenistan | 2004-07-06 | |
-region | TN | Tunisia | 2004-07-06 | |
-region | TO | Tonga | 2004-07-06 | |
-region | TL | Timor-Leste | 2004-07-06 | TP | # changed 2002-11-15, formerly East Timor
-region | TR | Turkey | 2004-07-06 | |
-region | TT | Trinidad and Tobago | 2004-07-06 | |
-region | TV | Tuvalu | 2004-07-06 | |
-region | TW | Taiwan, Province of China | 2004-07-06 | |
-region | TZ | Tanzania, United Republic of | 2004-07-06 | |
-region | UA | Ukraine | 2004-07-06 | |
-region | UG | Uganda | 2004-07-06 | |
-region | UM | United States Minor Outlying Islands | 2004-07-06 | |
-region | US | United States | 2004-07-06 | |
-region | UY | Uruguay | 2004-07-06 | |
-region | UZ | Uzbekistan | 2004-07-06 | |
-region | VA | Holy See (Vatican City State) | 2004-07-06 | |
-region | VC | Saint Vincent and the Grenadines | 2004-07-06 | |
-region | VD | North Vietnam | 2004-07-06 | | # deprecated 1977
-region | VE | Venezuela | 2004-07-06 | |
-region | VG | Virgin Islands, British | 2004-07-06 | |
-region | VI | Virgin Islands, U.S. | 2004-07-06 | |
-region | VN | Viet Nam | 2004-07-06 | |
-region | VU | Vanuatu | 2004-07-06 | |
-region | WF | Wallis and Futuna | 2004-07-06 | |
-region | WK | Wake Island | 2004-07-06 | | # deprecated 1986
-region | WS | Samoa | 2004-07-06 | |
-region | XA..XZ | PRIVATE USE | 2004-08-01 | |
-region | YD | People's Democratic Republic of Yemen | 2004-07-06 | | # deprecated 1990-08-14
-region | YE | Yemen | 2004-07-06 | |
-region | YT | Mayotte | 2004-07-06 | |
-region | YU | Serbia and Montenegro | 2005-01-01 | CS | # changed 2003-07-23, formerly Yugoslavia
-region | ZA | South Africa | 2004-07-06 | |
-region | ZM | Zambia | 2004-07-06 | |
-region | ZR | Congo, The Democratic Republic of the | 2004-07-06 | CD | # changed 1997-07-14, formerly Zaire
-region | ZW | Zimbabwe | 2004-07-06 | |
-region | ZZ | PRIVATE USE | 2004-08-01 | |
-
-# United Nations M.49 (numeric) codes
-region | 001 | World | 2004-07-06 | |
-region | 002 | Africa | 2004-07-06 | |
-region | 003 | North America | 2004-07-06 | |
-region | 005 | South America | 2004-07-06 | |
-region | 009 | Oceania | 2004-07-06 | |
-region | 011 | Western Africa | 2004-07-06 | |
-region | 013 | Central America | 2004-07-06 | |
-region | 014 | Eastern Africa | 2004-07-06 | |
-region | 015 | Northern Africa | 2004-07-06 | |
-region | 017 | Middle Africa | 2004-07-06 | |
-region | 018 | Southern Africa | 2004-07-06 | |
-region | 019 | Americas | 2004-07-06 | |
-region | 021 | Northern America | 2004-07-06 | |
-region | 029 | Caribbean | 2004-07-06 | |
-region | 030 | Eastern Asia | 2004-07-06 | |
-region | 035 | South-eastern Asia | 2004-07-06 | |
-region | 039 | Southern Europe | 2004-07-06 | |
-region | 053 | Australia and New Zealand | 2004-07-06 | |
-region | 054 | Melanesia | 2004-07-06 | |
-region | 057 | Micronesia | 2004-07-06 | |
-region | 061 | Polynesia | 2004-07-06 | |
-region | 062 | South-central Asia | 2004-07-06 | |
-region | 142 | Asia | 2004-07-06 | |
-region | 145 | Western Asia | 2004-07-06 | |
-region | 150 | Europe | 2004-07-06 | |
-region | 151 | Eastern Europe | 2004-07-06 | |
-region | 154 | Northern Europe | 2004-07-06 | |
-region | 155 | Western Europe | 2004-07-06 | |
-region | 172 | Commonwealth of Independent States | 2004-07-06 | |
-region | 200 | Czechoslovakia | 2004-12-19 | |
-region | 419 | Latin America and the Caribbean | 2004-07-06 | |
-region | 830 | Channel Islands | 2004-07-06 | |
-region | 833 | Isle of Man | 2004-07-06 | |
-
-# registered variants
-
-variant | 1901 | Traditional German orthography | 2004-09-09 | | de
-variant | 1996 | German orthography of 1996 | 2004-09-09 | | de
-variant | boont | Boontling | 2003-02-14 | | en
-variant | gaulish | Gaulish | 2001-05-25 | | cel
-variant | guoyu | Mandarin or Standard Chinese | 1999-12-18 | | zh
-variant | hakka | Hakka | 1999-12-18 | | zh
-variant | lojban | Lojban | 2001-11-11 | | art # deprecated 2003-09-20, use language jbo
-variant | nedis | Natisone dialect; Nadiza dialect | 2004-06-01 | | sl
-variant | rozaj | Resian; Resianic; Rezijan | 2003-10-09 | | sl
-variant | scouse | Scouse | 2000-05-25 | | en
-variant | xiang | Xiang or Hunanese | 1999-12-18 | | zh
-
-# grandfathered from RFC 3066
-
-grandfathered | en-GB-oed | English, Oxford English Dictionary spelling | 2003-07-09 | |
-grandfathered | i-ami | 'Amis | 1999-05-25 | |
-grandfathered | i-bnn | Bunun | 1999-05-25 | |
-grandfathered | i-default | Default Language | 1998-03-10 | |
-grandfathered | i-enochian | Enochian | 2002-07-03 | |
-grandfathered | i-hak | Hakka | 1999-01-31 | | # deprecated 2000-01-10, use variant hakka
-grandfathered | i-klingon | Klingon | 1999-05-26 | | # deprecated 2004-02-24, use language tlh
-grandfathered | i-lux | Luxembourgish | 1997-09-19 | | # deprecated 1998-09-09, use language lb
-grandfathered | i-mingo | Mingo | 1997-09-19 | |
-grandfathered | i-navajo | Navajo | 1997-09-19 | | # deprecated 2000-02-18, use language nv
-grandfathered | i-pwn | Paiwan | 1999-05-25 | |
-grandfathered | i-tao | Tao | 1999-05-25 | |
-grandfathered | i-tay | Tayal | 1999-05-25 | |
-grandfathered | i-tsu | Tsou | 1999-05-25 | |
-grandfathered | no-bok | Norwegian Bokmal | 1995-08-23 | | # deprecated 2000-02-18, use language nb
-grandfathered | no-nyn | Norwegian Nynorsk | 1995-08-23 | | # deprecated 2000-02-18, use language nn
-grandfathered | sgn-BE-fr | Belgian-French Sign Language | 2001-11-11 | |
-grandfathered | sgn-BE-nl | Belgian-Flemish Sign Language | 2001-11-11 | |
-grandfathered | sgn-CH-de | Swiss German Sign Language | 2001-11-11 | |
-grandfathered | zh-gan | Kan or Gan | 1999-12-18 | |
-grandfathered | zh-min | Min, Fuzhou, Hokkien, Amoy, or Taiwanese | 1999-12-18 | |
-grandfathered | zh-min-nan | Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo | 2001-03-26 | |
-grandfathered | zh-wuu | Shanghaiese or Wu | 1999-12-18 | |
-grandfathered | zh-yue | Cantonese | 1999-12-18 | |
-
-# redundant
-# The following codes were registered as complete tags, but can now be
-# composed of registered subtags and do not require registration.
-
-redundant | art-lojban | Lojban | 2001-11-11 | | # use language art + variant lojban
-redundant | az-Arab | Azerbaijani in Arabic script | 2003-05-30 | | # use language az + script Arab
-redundant | az-Cyrl | Azerbaijani in Cyrillic script | 2003-05-30 | | # use language az + script Cyrl
-redundant | az-Latn | Azerbaijani in Latin script | 2003-05-30 | | # use language az + script Latn
-redundant | be-Latn | Belarusian in Latin script | 2005-01-06 | | # use language be + script Latn
-redundant | cel-gaulish | Gaulish | 2001-05-25 | | # use language cel + variant gaulish
-redundant | de-1901 | German, traditional orthography | 2001-07-17 | | # use language de + variant 1901
-redundant | de-1996 | German, orthography of 1996 | 2001-07-17 | | # use language de + variant 1996
-redundant | de-AT-1901 | German, Austrian variant, traditional orthography | 2001-07-17 | | # use language de + region AT + variant 1901
-redundant | de-AT-1996 | German, Austrian variant, orthography of 1996 | 2001-07-17 | | # use language de + region AT + variant 1996
-redundant | de-CH-1901 | German, Swiss variant, traditional orthography | 2001-07-17 | | # use language de + region CH + variant 1901
-redundant | de-CH-1996 | German, Swiss variant, orthography of 1996 | 2001-07-17 | | # use language de + region CH + variant 1996
-redundant | de-DE-1901 | German, German variant, traditional orthography | 2001-07-17 | | # use language de + region DE + variant 1901
-redundant | de-DE-1996 | German, German variant, orthography of 1996 | 2001-07-17 | | # use language de + region DE + variant 1996
-redundant | en-boont | Boontling | 2003-02-14 | | # use language en + variant boont
-redundant | en-scouse | Scouse | 2000-05-25 | | # use language en + variant scouse
-redundant | sgn-BR | Brazilian Sign Language | 2001-11-11 | | # use language sgn + region BR
-redundant | sgn-CO | Colombian Sign Language | 2001-11-11 | | # use language sgn + region CO
-redundant | sgn-DE | German Sign Language | 2001-11-11 | | # use language sgn + region DE
-redundant | sgn-DK | Danish Sign Language | 2001-11-11 | | # use language sgn + region DK
-redundant | sgn-ES | Spanish Sign Language | 2001-11-11 | | # use language sgn + region ES
-redundant | sgn-FR | French Sign Language | 2001-11-11 | | # use language sgn + region FR
-redundant | sgn-GB | British Sign Language | 2001-03-02 | | # use language sgn + region GB
-redundant | sgn-GR | Greek Sign Language | 2001-11-11 | | # use language sgn + region GR
-redundant | sgn-IE | Irish Sign Language | 2001-03-02 | | # use language sgn + region IE
-redundant | sgn-IT | Italian Sign Language | 2001-11-11 | | # use language sgn + region IT
-redundant | sgn-JP | Japanese Sign Language | 2001-11-11 | | # use language sgn + region JP
-redundant | sgn-MX | Mexican Sign Language | 2001-11-11 | | # use language sgn + region MX
-redundant | sgn-NI | Nicaraguan Sign Language | 2001-03-02 | | # use language sgn + region NI
-redundant | sgn-NL | Dutch Sign Language | 2001-11-11 | | # use language sgn + region NL
-redundant | sgn-NO | Norwegian Sign Language | 2001-11-11 | | # use language sgn + region NO
-redundant | sgn-PT | Portuguese Sign Language | 2001-11-11 | | # use language sgn + region PT
-redundant | sgn-SE | Swedish Sign Language | 2001-11-11 | | # use language sgn + region SE
-redundant | sgn-US | American Sign Language | 2001-03-02 | | # use language sgn + region US
-redundant | sgn-ZA | South African Sign Language | 2001-11-11 | | # use language sgn + region ZA
-redundant | sl-nedis | Natisone dialect, Nadiza dialect | 2004-06-01 | | # use language sl + variant nedis
-redundant | sl-rozaj | Resian, Resianic, Rezijan | 2003-10-09 | | # use language sl + variant rozaj
-redundant | sr-Cyrl | Serbian in Cyrillic script | 2003-05-30 | | # use language sr + script Cyrl
-redundant | sr-Latn | Serbian in Latin script | 2003-05-30 | | # use language sr + script Latn
-redundant | uz-Cyrl | Uzbek in Cyrillic script | 2003-05-30 | | # use language uz + script Cyrl
-redundant | uz-Latn | Uzbek in Latin script | 2003-05-30 | | # use language uz + script Latn
-redundant | yi-latn | Yiddish, in Latin script | 2003-01-07 | | # use language yi + script Latn
-redundant | zh-Hans | simplified Chinese | 2003-05-30 | | # use language zh + script Hans
-redundant | zh-Hant | traditional Chinese | 2003-05-30 | | # use language zh + script Hant
-redundant | zh-guoyu | Mandarin or Standard Chinese | 1999-12-18 | | # use language zh + variant guoyu
-redundant | zh-hakka | Hakka | 1999-12-18 | | # use language zh + variant hakka
-redundant | zh-xiang | Xiang or Hunanese | 1999-12-18 | | # use language zh + variant xiang
diff --git a/tools/java/org/unicode/cldr/util/data/northamerica b/tools/java/org/unicode/cldr/util/data/northamerica
index eee8de0..675c648 100644
--- a/tools/java/org/unicode/cldr/util/data/northamerica
+++ b/tools/java/org/unicode/cldr/util/data/northamerica
@@ -86,17 +86,40 @@
# For more about the first ten years of DST in the United States, see
# Robert Garland, Ten years of daylight saving from the Pittsburgh standpoint
# (Carnegie Library of Pittsburgh, 1927).
-# http://www.clpgh.org/exhibit/dst.html
+# https://web.archive.org/web/20160517155308/http://www.clpgh.org/exhibit/dst.html
#
# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
# However, DST was imposed by the Standard Time Act of 1918, which
# was the first nationwide legal time standard, and apparently
# time was just called "Standard Time" or "Daylight Saving Time".
-# From Arthur David Olson:
-# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
-# See, for example, the front page of the Saturday, 1974-10-26
-# and Sunday, 1974-10-27 editions of the Washington Post.
+# From Paul Eggert (2019-06-04):
+# Here is the legal basis for the US federal rules.
+# * Public Law 65-106 (1918-03-19) implemented standard and daylight saving
+# time for the first time across the US, springing forward on March's last
+# Sunday and falling back on October's last Sunday.
+# https://www.loc.gov/law/help/statutes-at-large/65th-congress/session-2/c65s2ch24.pdf
+# * Public Law 66-40 (1919-08-20) repealed DST on October 1919's last Sunday.
+# https://www.loc.gov/law/help/statutes-at-large/66th-congress/session-1/c66s1ch51.pdf
+# * Public Law 77-403 (1942-01-20) started wartime DST on 1942-02-09.
+# https://www.loc.gov/law/help/statutes-at-large/77th-congress/session-2/c77s2ch7.pdf
+# * Public Law 79-187 (1945-09-25) ended wartime DST on 1945-09-30.
+# https://www.loc.gov/law/help/statutes-at-large/79th-congress/session-1/c79s1ch388.pdf
+# * Public Law 89-387 (1966-04-13) reinstituted a national standard for DST,
+# from April's last Sunday to October's last Sunday, effective 1967.
+# https://www.govinfo.gov/content/pkg/STATUTE-80/pdf/STATUTE-80-Pg107.pdf
+# * Public Law 93-182 (1973-12-15) moved the 1974 spring-forward to 01-06.
+# https://www.govinfo.gov/content/pkg/STATUTE-87/pdf/STATUTE-87-Pg707.pdf
+# * Public Law 93-434 (1974-10-05) moved the 1975 spring-forward to
+# February's last Sunday.
+# https://www.govinfo.gov/content/pkg/STATUTE-88/pdf/STATUTE-88-Pg1209.pdf
+# * Public Law 99-359 (1986-07-08) moved the spring-forward to April's first
+# Sunday.
+# https://www.govinfo.gov/content/pkg/STATUTE-100/pdf/STATUTE-100-Pg764.pdf
+# * Public Law 109-58 (2005-08-08), effective 2007, moved the spring-forward
+# to March's second Sunday and the fall-back to November's first Sunday.
+# https://www.govinfo.gov/content/pkg/PLAW-109publ58/pdf/PLAW-109publ58.pdf
+# All transitions are at 02:00 local time.
# From Arthur David Olson:
# Before the Uniform Time Act of 1966 took effect in 1967, observance of
@@ -147,16 +170,16 @@
# U.S. government action. So even though the "US" rules have changed
# in the latest release, other countries won't be affected.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule US 1918 1919 - Mar lastSun 2:00 1:00 D
Rule US 1918 1919 - Oct lastSun 2:00 0 S
Rule US 1942 only - Feb 9 2:00 1:00 W # War
Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace
-Rule US 1945 only - Sep lastSun 2:00 0 S
+Rule US 1945 only - Sep 30 2:00 0 S
Rule US 1967 2006 - Oct lastSun 2:00 0 S
Rule US 1967 1973 - Apr lastSun 2:00 1:00 D
Rule US 1974 only - Jan 6 2:00 1:00 D
-Rule US 1975 only - Feb 23 2:00 1:00 D
+Rule US 1975 only - Feb lastSun 2:00 1:00 D
Rule US 1976 1986 - Apr lastSun 2:00 1:00 D
Rule US 1987 2006 - Apr Sun>=1 2:00 1:00 D
Rule US 2007 max - Mar Sun>=8 2:00 1:00 D
@@ -173,7 +196,7 @@
# increase the chances that they'll actually get compiled and to
# avoid the need to duplicate the US rules in another file.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone EST -5:00 - EST
Zone MST -7:00 - MST
Zone HST -10:00 - HST
@@ -324,13 +347,13 @@
# Eastern time (i.e., -4:56:01.6) just before the 1883 switch. Round to the
# nearest second.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule NYC 1920 only - Mar lastSun 2:00 1:00 D
Rule NYC 1920 only - Oct lastSun 2:00 0 S
Rule NYC 1921 1966 - Apr lastSun 2:00 1:00 D
Rule NYC 1921 1954 - Sep lastSun 2:00 0 S
Rule NYC 1955 1966 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/New_York -4:56:02 - LMT 1883 Nov 18 12:03:58
-5:00 US E%sT 1920
-5:00 NYC E%sT 1942
@@ -383,14 +406,39 @@
# From Paul Eggert (2015-12-25):
# Assume this practice predates 1970, so Fort Pierre can use America/Chicago.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# From Paul Eggert (2015-04-06):
+# In 1950s Nashville a public clock had dueling faces, one for conservatives
+# and the other for liberals; the two sides didn't agree about the time of day.
+# I haven't found a photo of this clock, nor have I tracked down the TIME
+# magazine report cited below, but here's the story as told by the late
+# American journalist John Seigenthaler, who was there:
+#
+# "The two [newspaper] owners held strongly contrasting political and
+# ideological views. Evans was a New South liberal, Stahlman an Old South
+# conservative, and their two papers frequently clashed editorially, often on
+# the same day.... In the 1950s as the state legislature was grappling with
+# the question of whether to approve daylight saving time for the entire state,
+# TIME magazine reported:
+#
+# "'The Nashville Banner and The Nashville Tennessean rarely agree on anything
+# but the time of day - and last week they couldn't agree on that.'
+#
+# "It was all too true. The clock on the front of the building had two faces -
+# The Tennessean side of the building facing west, the other, east. When it
+# was high noon Banner time, it was 11 a.m. Tennessean time."
+#
+# Seigenthaler J. For 100 years, Tennessean had it covered.
+# The Tennessean 2007-05-11, republished 2015-04-06.
+# https://www.tennessean.com/story/insider/extras/2015/04/06/archives-seigenthaler-for-100-years-the-tennessean-had-it-covered/25348545/
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Chicago 1920 only - Jun 13 2:00 1:00 D
Rule Chicago 1920 1921 - Oct lastSun 2:00 0 S
Rule Chicago 1921 only - Mar lastSun 2:00 1:00 D
Rule Chicago 1922 1966 - Apr lastSun 2:00 1:00 D
Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S
Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24
-6:00 US C%sT 1920
-6:00 Chicago C%sT 1936 Mar 1 2:00
@@ -452,13 +500,13 @@
# El Paso Times. 2018-10-24 06:40 -06.
# https://www.elpasotimes.com/story/news/local/el-paso/2018/10/24/el-pasoans-were-time-rebels-fought-stay-mountain-zone/1744509002/
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Denver 1920 1921 - Mar lastSun 2:00 1:00 D
Rule Denver 1920 only - Oct lastSun 2:00 0 S
Rule Denver 1921 only - May 22 2:00 0 S
Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D
Rule Denver 1965 1966 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
-7:00 US M%sT 1920
-7:00 Denver M%sT 1942
@@ -505,13 +553,13 @@
# https://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props
# https://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule CA 1948 only - Mar 14 2:01 1:00 D
Rule CA 1949 only - Jan 1 2:00 0 S
Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
-8:00 US P%sT 1946
-8:00 CA P%sT 1967
@@ -619,7 +667,7 @@
# So they won't be waiting for Alaska to join them on 2019-03-10, but will
# rather change their clocks twice in seven weeks.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32
-8:57:41 - LMT 1900 Aug 20 12:00
-8:00 - PST 1942
@@ -739,7 +787,7 @@
# Note that 1933-05-21 was a Sunday.
# We're left to guess the time of day when Act 163 was approved; guess noon.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Pacific/Honolulu -10:31:26 - LMT 1896 Jan 13 12:00
-10:30 - HST 1933 Apr 30 2:00
-10:30 1:00 HDT 1933 May 21 12:00
@@ -769,7 +817,7 @@
# Shanks says the 1944 experiment came to an end on 1944-03-17.
# Go with the Arizona State Library instead.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42
-7:00 US M%sT 1944 Jan 1 0:01
-7:00 - MST 1944 Apr 1 0:01
@@ -795,7 +843,7 @@
# quarter of Idaho county) and eastern Oregon (most of Malheur County)
# switched four weeks late in 1974.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11
-8:00 US P%sT 1923 May 13 2:00
-7:00 US M%sT 1974
@@ -863,11 +911,11 @@
# going to switch from Central to Eastern Time on March 11, 2007....
# http://www.indystar.com/apps/pbcs.dll/article?AID=/20070207/LOCAL190108/702070524/0/LOCAL
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Indianapolis 1941 only - Jun 22 2:00 1:00 D
Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S
Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
-6:00 US C%sT 1920
-6:00 Indianapolis C%sT 1942
@@ -882,12 +930,12 @@
#
# Eastern Crawford County, Indiana, left its clocks alone in 1974,
# as well as from 1976 through 2005.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Marengo 1951 only - Apr lastSun 2:00 1:00 D
Rule Marengo 1951 only - Sep lastSun 2:00 0 S
Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D
Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37
-6:00 US C%sT 1951
-6:00 Marengo C%sT 1961 Apr 30 2:00
@@ -901,7 +949,7 @@
# Daviess, Dubois, Knox, and Martin Counties, Indiana,
# switched from eastern to central time in April 2006, then switched back
# in November 2007.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Vincennes 1946 only - Apr lastSun 2:00 1:00 D
Rule Vincennes 1946 only - Sep lastSun 2:00 0 S
Rule Vincennes 1953 1954 - Apr lastSun 2:00 1:00 D
@@ -911,7 +959,7 @@
Rule Vincennes 1960 only - Oct lastSun 2:00 0 S
Rule Vincennes 1961 only - Sep lastSun 2:00 0 S
Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
-6:00 US C%sT 1946
-6:00 Vincennes C%sT 1964 Apr 26 2:00
@@ -922,33 +970,33 @@
-5:00 US E%sT
#
# Perry County, Indiana, switched from eastern to central time in April 2006.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
-Rule Perry 1946 only - Apr lastSun 2:00 1:00 D
-Rule Perry 1946 only - Sep lastSun 2:00 0 S
-Rule Perry 1953 1954 - Apr lastSun 2:00 1:00 D
-Rule Perry 1953 1959 - Sep lastSun 2:00 0 S
+# From Alois Triendl (2019-07-09):
+# The Indianapolis News, Friday 27 October 1967 states that Perry County
+# returned to CST. It went again to EST on 27 April 1969, as documented by the
+# Indianapolis star of Saturday 26 April.
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Perry 1955 only - May 1 0:00 1:00 D
+Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
-Rule Perry 1960 only - Oct lastSun 2:00 0 S
-Rule Perry 1961 only - Sep lastSun 2:00 0 S
-Rule Perry 1962 1963 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
-6:00 US C%sT 1946
-6:00 Perry C%sT 1964 Apr 26 2:00
- -5:00 - EST 1969
+ -5:00 - EST 1967 Oct 29 2:00
+ -6:00 US C%sT 1969 Apr 27 2:00
-5:00 US E%sT 1971
-5:00 - EST 2006 Apr 2 2:00
-6:00 US C%sT
#
# Pike County, Indiana moved from central to eastern time in 1977,
# then switched back in 2006, then switched back again in 2007.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Pike 1955 only - May 1 0:00 1:00 D
Rule Pike 1955 1960 - Sep lastSun 2:00 0 S
Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D
Rule Pike 1961 1964 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53
-6:00 US C%sT 1955
-6:00 Pike C%sT 1965 Apr 25 2:00
@@ -964,13 +1012,13 @@
# An article on page A3 of the Sunday, 1991-10-27 Washington Post
# notes that Starke County switched from Central time to Eastern time as of
# 1991-10-27.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Starke 1947 1961 - Apr lastSun 2:00 1:00 D
Rule Starke 1947 1954 - Sep lastSun 2:00 0 S
Rule Starke 1955 1956 - Oct lastSun 2:00 0 S
Rule Starke 1957 1958 - Sep lastSun 2:00 0 S
Rule Starke 1959 1961 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30
-6:00 US C%sT 1947
-6:00 Starke C%sT 1962 Apr 29 2:00
@@ -981,12 +1029,12 @@
#
# Pulaski County, Indiana, switched from eastern to central time in
# April 2006 and then switched back in March 2007.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Pulaski 1946 1960 - Apr lastSun 2:00 1:00 D
Rule Pulaski 1946 1954 - Sep lastSun 2:00 0 S
Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S
Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35
-6:00 US C%sT 1946
-6:00 Pulaski C%sT 1961 Apr 30 2:00
@@ -997,7 +1045,7 @@
-5:00 US E%sT
#
# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
-6:00 US C%sT 1954 Apr 25 2:00
-5:00 - EST 1969
@@ -1012,17 +1060,28 @@
# clear how this matched civil time in Louisville, so for now continue
# to assume Louisville switched at noon new local time, like New York.
#
+# From Michael Deckers (2019-08-06):
+# From the contemporary source given by Alois Treindl,
+# the switch in Louisville on 1946-04-28 was on 00:01
+# From Paul Eggert (2019-08-26):
+# That source was the Louisville Courier-Journal, 1946-04-27, p 4.
+# Shanks gives 02:00 for all 20th-century transition times in Louisville.
+# Evidently this is wrong for spring 1946. Although also likely wrong
+# for other dates, we have no data.
+#
# Part of Kentucky left its clocks alone in 1974.
# This also includes Clark, Floyd, and Harrison counties in Indiana.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Louisville 1921 only - May 1 2:00 1:00 D
Rule Louisville 1921 only - Sep 1 2:00 0 S
-Rule Louisville 1941 1961 - Apr lastSun 2:00 1:00 D
+Rule Louisville 1941 only - Apr lastSun 2:00 1:00 D
Rule Louisville 1941 only - Sep lastSun 2:00 0 S
+Rule Louisville 1946 only - Apr lastSun 0:01 1:00 D
Rule Louisville 1946 only - Jun 2 2:00 0 S
+Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
-Rule Louisville 1956 1960 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
-6:00 US C%sT 1921
-6:00 Louisville C%sT 1942
@@ -1111,41 +1170,44 @@
# one hour in 1914." This change is not in Shanks. We have no more
# info, so omit this for now.
#
-# From Paul Eggert (2017-07-26):
-# Although Shanks says Detroit observed DST in 1967 from 06-14 00:01
-# until 10-29 00:01, I now see multiple reports that this is incorrect.
-# For example, according to a 50-year anniversary report about the 1967
-# Detroit riots and a major-league doubleheader on 1967-07-23, "By the time
-# the last fly ball of the doubleheader settled into the glove of leftfielder
-# Lenny Green, it was after 7 p.m. Detroit did not observe daylight saving
-# time, so light was already starting to fail. Twilight was made even deeper
-# by billowing columns of smoke that ascended in an unbroken wall north of the
-# ballpark." See: Dow B. Detroit '67: As violence unfolded, Tigers played two
-# at home vs. Yankees. Detroit Free Press 2017-07-23.
-# https://www.freep.com/story/sports/mlb/tigers/2017/07/23/detroit-tigers-1967-riot-new-york-yankees/499951001/
+# From Paul Eggert (2019-07-06):
+# Due to a complicated set of legal maneuvers, in 1967 Michigan did
+# not start daylight saving time when the rest of the US did.
+# Instead, it began DST on Jun 14 at 00:01. This was big news:
+# the Detroit Free Press reported it at the top of Page 1 on
+# 1967-06-14, in an article "State Adjusting to Switch to Fast Time"
+# by Gary Blonston, above an article about Thurgood Marshall's
+# confirmation to the US Supreme Court. Although Shanks says Detroit
+# observed DST until 1967-10-29 00:01, that time of day seems to be
+# incorrect, as the Free Press later said DST ended in Michigan at the
+# same time as the rest of the US. Also, although Shanks reports no DST in
+# Detroit in 1968, it did observe DST that year; in the November 1968
+# election Michigan voters narrowly repealed DST, effective 1969.
#
# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Detroit 1948 only - Apr lastSun 2:00 1:00 D
Rule Detroit 1948 only - Sep lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Detroit -5:32:11 - LMT 1905
-6:00 - CST 1915 May 15 2:00
-5:00 - EST 1942
-5:00 US E%sT 1946
- -5:00 Detroit E%sT 1973
+ -5:00 Detroit E%sT 1967 Jun 14 0:01
+ -5:00 US E%sT 1969
+ -5:00 - EST 1973
-5:00 US E%sT 1975
-5:00 - EST 1975 Apr 27 2:00
-5:00 US E%sT
#
# Dickinson, Gogebic, Iron, and Menominee Counties, Michigan,
# switched from EST to CST/CDT in 1973.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
+# Rule NAME FROM TO - IN ON AT SAVE LETTER
Rule Menominee 1946 only - Apr lastSun 2:00 1:00 D
Rule Menominee 1946 only - Sep lastSun 2:00 0 S
Rule Menominee 1966 only - Apr lastSun 2:00 1:00 D
Rule Menominee 1966 only - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
-6:00 US C%sT 1946
-6:00 Menominee C%sT 1969 Apr 27 2:00
@@ -1182,6 +1244,12 @@
#
# Other sources occasionally used include:
#
+# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
+# <https://www.jstor.org/stable/1774359>.
+#
+# Pearce C. The Great Daylight Saving Time Controversy.
+# Australian Ebook Publisher. 2017. ISBN 978-1-925516-96-8.
+#
# Edward W. Whitman, World Time Differences,
# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
# which I found in the UCLA library.
@@ -1190,9 +1258,6 @@
# <http://cs.ucla.edu/~eggert/The-Waste-of-Daylight-19th.pdf>
# [PDF] (1914-03)
#
-# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
-# <https://www.jstor.org/stable/1774359>.
-#
# See the 'europe' file for Greenland.
# Canada
@@ -1307,7 +1372,7 @@
# Oct 31, to Oct 27, 1918 (and Sunday is a more likely transition day
# than Thursday) in all Canadian rulesets.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Canada 1918 only - Apr 14 2:00 1:00 D
Rule Canada 1918 only - Oct 27 2:00 0 S
Rule Canada 1942 only - Feb 9 2:00 1:00 W # War
@@ -1330,7 +1395,7 @@
# that follows the rules is the southeast corner, including Port Hope
# Simpson and Mary's Harbour, but excluding, say, Black Tickle.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule StJohns 1917 only - Apr 8 2:00 1:00 D
Rule StJohns 1917 only - Sep 17 2:00 0 S
# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks & Pottenger.
@@ -1379,7 +1444,7 @@
Rule StJohns 2007 2010 - Nov Sun>=1 0:01 0 S
#
# St John's has an apostrophe, but Posix file names can't have apostrophes.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/St_Johns -3:30:52 - LMT 1884
-3:30:52 StJohns N%sT 1918
-3:30:52 Canada N%sT 1919
@@ -1392,7 +1457,7 @@
# most of east Labrador
# The name 'Happy Valley-Goose Bay' is too long; use 'Goose Bay'.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Goose_Bay -4:01:40 - LMT 1884 # Happy Valley-Goose Bay
-3:30:52 - NST 1918
-3:30:52 Canada N%sT 1919
@@ -1405,7 +1470,8 @@
-4:00 Canada A%sT
-# west Labrador, Nova Scotia, Prince Edward I
+# west Labrador, Nova Scotia, Prince Edward I,
+# Îles-de-la-Madeleine, Listuguj reserve
# From Brian Inglis (2015-07-20):
# From the historical weather station records available at:
@@ -1424,7 +1490,14 @@
# in Canada to observe DST in 1971 but not 1970; for now we'll assume
# this is a typo.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Jeffery Nichols (2020-01-09):
+# America/Halifax ... also applies to Îles-de-la-Madeleine and the Listuguj
+# reserve in Quebec. Officially, this came into effect on January 1, 2007
+# (Legal Time Act, CQLR c T-5.1), but the legislative debates surrounding that
+# bill say that it is "accommodating the customs and practices" of those
+# regions, which suggests that they have always been in-line with Halifax.
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Halifax 1916 only - Apr 1 0:00 1:00 D
Rule Halifax 1916 only - Oct 1 0:00 0 S
Rule Halifax 1920 only - May 9 0:00 1:00 D
@@ -1466,7 +1539,7 @@
Rule Halifax 1956 1959 - Sep lastSun 2:00 0 S
Rule Halifax 1962 1973 - Apr lastSun 2:00 1:00 D
Rule Halifax 1962 1973 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Halifax -4:14:24 - LMT 1902 Jun 15
-4:00 Halifax A%sT 1918
-4:00 Canada A%sT 1919
@@ -1490,7 +1563,7 @@
# clear that this was the case since at least 1993.
# For now, assume it started in 1993.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Moncton 1933 1935 - Jun Sun>=8 1:00 1:00 D
Rule Moncton 1933 1935 - Sep Sun>=8 1:00 0 S
Rule Moncton 1936 1938 - Jun Sun>=1 1:00 1:00 D
@@ -1504,7 +1577,7 @@
Rule Moncton 1957 1972 - Oct lastSun 2:00 0 S
Rule Moncton 1993 2006 - Apr Sun>=1 0:01 1:00 D
Rule Moncton 1993 2006 - Oct lastSun 0:01 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Moncton -4:19:08 - LMT 1883 Dec 9
-5:00 - EST 1902 Jun 15
-4:00 Canada A%sT 1933
@@ -1517,23 +1590,24 @@
# Quebec
-# From Paul Eggert (2015-03-24):
+# From Paul Eggert (2020-01-10):
# See America/Toronto for most of Quebec, including Montreal.
+# See America/Halifax for the Îles de la Madeleine and the Listuguj reserve.
#
# Matthews and Vincent (1998) also write that Quebec east of the -63
# meridian is supposed to observe AST, but residents as far east as
# Natashquan use EST/EDT, and residents east of Natashquan use AST.
# The Quebec department of justice writes in
# "The situation in Minganie and Basse-Côte-Nord"
-# http://www.justice.gouv.qc.ca/english/publications/generale/temps-minganie-a.htm
+# https://www.justice.gouv.qc.ca/en/department/ministre/functions-and-responsabilities/legal-time-in-quebec/the-situation-in-minganie-and-basse-cote-nord/
# that the coastal strip from just east of Natashquan to Blanc-Sablon
# observes Atlantic standard time all year round.
-# https://www.assnat.qc.ca/Media/Process.aspx?MediaId=ANQ.Vigie.Bll.DocumentGenerique_8845en
-# says this common practice was codified into law as of 2007.
+# This common practice was codified into law as of 2007; see Legal Time Act,
+# CQLR c T-5.1 <http://legisquebec.gouv.qc.ca/en/ShowDoc/cs/T-5.1>.
# For lack of better info, guess this practice began around 1970, contra to
# Shanks & Pottenger who have this region observing AST/ADT.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Blanc-Sablon -3:48:28 - LMT 1884
-4:00 Canada A%sT 1970
-4:00 - AST
@@ -1548,6 +1622,15 @@
# Nipigon (EST) and Rainy River (CST) are the largest that we know of.
# Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
+# From Jeffery Nichols (2020-02-06):
+# According to the [Shanks] atlas, those western Ontario zones are huge,
+# covering most of Ontario northwest of Sault Ste Marie and Timmins.
+# The zones seem to include towns bigger than the ones they're named after,
+# like Dryden in America/Rainy_River and Wawa (and maybe Attawapiskat) in
+# America/Nipigon. I assume it's too much trouble to change the name of the
+# zone (like when you found out that America/Glace_Bay includes Sydney, Nova
+# Scotia)....
+
# From Mark Brader (2003-07-26):
# [According to the Toronto Star] Orillia, Ontario, adopted DST
# effective Saturday, 1912-06-22, 22:00; the article mentions that
@@ -1689,7 +1772,7 @@
# With some exceptions, the use of daylight saving may be said to be limited
# to those cities and towns lying between Quebec city and Windsor, Ont.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Toronto 1919 only - Mar 30 23:30 1:00 D
Rule Toronto 1919 only - Oct 26 0:00 0 S
Rule Toronto 1920 only - May 2 2:00 1:00 D
@@ -1701,19 +1784,10 @@
# was meant.
Rule Toronto 1922 1926 - Sep Sun>=15 2:00 0 S
Rule Toronto 1924 1927 - May Sun>=1 2:00 1:00 D
-# The 1927-to-1939 rules can be expressed more simply as
-# Rule Toronto 1927 1937 - Sep Sun>=25 2:00 0 S
-# Rule Toronto 1928 1937 - Apr Sun>=25 2:00 1:00 D
-# Rule Toronto 1938 1940 - Apr lastSun 2:00 1:00 D
-# Rule Toronto 1938 1939 - Sep lastSun 2:00 0 S
-# The rules below avoid use of Sun>=25
-# (which pre-2004 versions of zic cannot handle).
-Rule Toronto 1927 1932 - Sep lastSun 2:00 0 S
-Rule Toronto 1928 1931 - Apr lastSun 2:00 1:00 D
-Rule Toronto 1932 only - May 1 2:00 1:00 D
-Rule Toronto 1933 1940 - Apr lastSun 2:00 1:00 D
-Rule Toronto 1933 only - Oct 1 2:00 0 S
-Rule Toronto 1934 1939 - Sep lastSun 2:00 0 S
+Rule Toronto 1927 1937 - Sep Sun>=25 2:00 0 S
+Rule Toronto 1928 1937 - Apr Sun>=25 2:00 1:00 D
+Rule Toronto 1938 1940 - Apr lastSun 2:00 1:00 D
+Rule Toronto 1938 1939 - Sep lastSun 2:00 0 S
Rule Toronto 1945 1946 - Sep lastSun 2:00 0 S
Rule Toronto 1946 only - Apr lastSun 2:00 1:00 D
Rule Toronto 1947 1949 - Apr lastSun 0:00 1:00 D
@@ -1746,7 +1820,7 @@
# War,... [t]he cities agreed to implement DST during the summer
# months for the remainder of the war years.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Toronto -5:17:32 - LMT 1895
-5:00 Canada E%sT 1919
-5:00 Toronto E%sT 1942 Feb 9 2:00s
@@ -1796,7 +1870,7 @@
# starting 1966. Since 02:00s is clearly correct for 1967 on, assume
# it was also 02:00s in 1966.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Winn 1916 only - Apr 23 0:00 1:00 D
Rule Winn 1916 only - Sep 17 0:00 0 S
Rule Winn 1918 only - Apr 14 2:00 1:00 D
@@ -1821,7 +1895,7 @@
Rule Winn 1966 1986 - Apr lastSun 2:00s 1:00 D
Rule Winn 1966 2005 - Oct lastSun 2:00s 0 S
Rule Winn 1987 2005 - Apr Sun>=1 2:00s 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16
-6:00 Winn C%sT 2006
-6:00 Canada C%sT
@@ -1843,6 +1917,12 @@
# Willett (1914-03) notes that DST "has been in operation ... in the
# City of Moose Jaw, Saskatchewan, for one year."
+# From Paul Eggert (2019-07-25):
+# Pearce's book says Regina observed DST in 1914-1917. No dates and times,
+# unfortunately. It also says that in 1914 Saskatoon observed DST
+# from 1 June to 6 July, and that DST was also tried out in Davidson,
+# Melfort, and Prince Albert.
+
# From Paul Eggert (2006-03-22):
# Shanks & Pottenger say that since 1970 this region has mostly been as Regina.
# Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
@@ -1881,7 +1961,7 @@
# long and rather painful to read.
# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Regina 1918 only - Apr 14 2:00 1:00 D
Rule Regina 1918 only - Oct 27 2:00 0 S
Rule Regina 1930 1934 - May Sun>=1 0:00 1:00 D
@@ -1905,7 +1985,7 @@
Rule Swift 1959 1961 - Apr lastSun 2:00 1:00 D
Rule Swift 1959 only - Oct lastSun 2:00 0 S
Rule Swift 1960 1961 - Sep lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Regina -6:58:36 - LMT 1905 Sep
-7:00 Regina M%sT 1960 Apr lastSun 2:00
-6:00 - CST
@@ -1918,7 +1998,20 @@
# Alberta
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Alois Triendl (2019-07-19):
+# There was no DST in Alberta in 1967... Calgary Herald, 29 April 1967.
+# 1969, no DST, from Edmonton Journal 18 April 1969
+#
+# From Paul Eggert (2019-07-25):
+# Pearce's book says that Alberta's 1948 Daylight Saving Act required
+# Mountain Standard Time without DST, and that "anyone who broke that law
+# could be fined up to $25 and costs". There seems to be no record of
+# anybody paying the fine. The law was not changed until an August 1971
+# plebiscite reinstituted DST in 1972. This story is also mentioned in:
+# Boyer JP. Forcing Choice: The Risky Reward of Referendums. Dundum. 2017.
+# ISBN 978-1459739123.
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Edm 1918 1919 - Apr Sun>=8 2:00 1:00 D
Rule Edm 1918 only - Oct 27 2:00 0 S
Rule Edm 1919 only - May 27 2:00 0 S
@@ -1930,13 +2023,9 @@
Rule Edm 1945 only - Sep lastSun 2:00 0 S
Rule Edm 1947 only - Apr lastSun 2:00 1:00 D
Rule Edm 1947 only - Sep lastSun 2:00 0 S
-Rule Edm 1967 only - Apr lastSun 2:00 1:00 D
-Rule Edm 1967 only - Oct lastSun 2:00 0 S
-Rule Edm 1969 only - Apr lastSun 2:00 1:00 D
-Rule Edm 1969 only - Oct lastSun 2:00 0 S
Rule Edm 1972 1986 - Apr lastSun 2:00 1:00 D
Rule Edm 1972 2006 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Edmonton -7:33:52 - LMT 1906 Sep
-7:00 Edm M%sT 1987
-7:00 Canada M%sT
@@ -2016,20 +2105,32 @@
# been on MST (-0700) like Dawson Creek since it advanced its clocks on
# 2015-03-08.
#
-# From Paul Eggert (2015-09-23):
+# From Paul Eggert (2019-07-25):
# Shanks says Fort Nelson did not observe DST in 1946, unlike Vancouver.
+# Alois Triendl confirmed this on 07-22, citing the 1946-04-27 Vancouver Daily
+# Province. He also cited the 1946-09-28 Victoria Daily Times, which said
+# that Vancouver, Victoria, etc. "change at midnight Saturday"; for now,
+# guess they meant 02:00 Sunday since 02:00 was common practice in Vancouver.
+#
+# Early Vancouver, Volume Four, by Major J.S. Matthews, V.D., 2011 edition
+# says that a 1922 plebiscite adopted DST, but a 1923 plebiscite rejected it.
+# http://former.vancouver.ca/ctyclerk/archives/digitized/EarlyVan/SearchEarlyVan/Vol4pdf/MatthewsEarlyVancouverVol4_DaylightSavings.pdf
+# A catalog entry for a newspaper clipping seems to indicate that Vancouver
+# observed DST in 1941 from 07-07 through 09-27; see
+# https://searcharchives.vancouver.ca/daylight-saving-1918-starts-again-july-7-1941-start-d-s-sept-27-end-of-d-s-1941
+# We have no further details, so omit them for now.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Vanc 1918 only - Apr 14 2:00 1:00 D
Rule Vanc 1918 only - Oct 27 2:00 0 S
Rule Vanc 1942 only - Feb 9 2:00 1:00 W # War
Rule Vanc 1945 only - Aug 14 23:00u 1:00 P # Peace
Rule Vanc 1945 only - Sep 30 2:00 0 S
Rule Vanc 1946 1986 - Apr lastSun 2:00 1:00 D
-Rule Vanc 1946 only - Oct 13 2:00 0 S
+Rule Vanc 1946 only - Sep 29 2:00 0 S
Rule Vanc 1947 1961 - Sep lastSun 2:00 0 S
Rule Vanc 1962 2006 - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Vancouver -8:12:28 - LMT 1884
-8:00 Vanc P%sT 1987
-8:00 Canada P%sT
@@ -2100,7 +2201,7 @@
# varying the manner of reckoning standard time.
#
# * Yukon Territory Commissioner's Order 1966-20 Interpretation Ordinance
-# http://? - no online source found
+# [no online source found]
#
# * Standard Time and Time Zones in Canada; Thomson, Malcolm M.; JRASC,
# Vol. 64, pp.129-162; June 1970; SAO/NASA Astrophysics Data System (ADS)
@@ -2133,7 +2234,7 @@
# to say eight hours behind Greenwich Time.
#
# * O.I.C. 1980/02 INTERPRETATION ACT
-# http://? - no online source found
+# [no online source found]
#
# * Yukon Daylight Saving Time, YOIC 1987/56
# https://www.canlii.org/en/yk/laws/regu/yoic-1987-56/latest/yoic-1987-56.html
@@ -2336,7 +2437,31 @@
# obtained in November 2008 should be ignored...
# I apologize for reporting incorrect information in 2008.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# From Tim Parenti (2020-03-05):
+# The government of Yukon announced [yesterday] the cessation of seasonal time
+# changes. "After clocks are pushed ahead one hour on March 8, the territory
+# will remain on [UTC-07]. ... [The government] found 93 per cent of
+# respondents wanted to end seasonal time changes and, of that group, 70 per
+# cent wanted 'permanent Pacific Daylight Saving Time.'"
+# https://www.cbc.ca/news/canada/north/yukon-end-daylight-saving-time-1.5486358
+#
+# Although the government press release prefers PDT, we prefer MST for
+# consistency with nearby Dawson Creek, Creston, and Fort Nelson.
+# https://yukon.ca/en/news/yukon-end-seasonal-time-change
+
+# From Andrew G. Smith (2020-09-24):
+# Yukon has completed its regulatory change to be on UTC -7 year-round....
+# http://www.gov.yk.ca/legislation/regs/oic2020_125.pdf
+# What we have done is re-defined Yukon Standard Time, as we are
+# authorized to do under section 33 of our Interpretation Act:
+# http://www.gov.yk.ca/legislation/acts/interpretation_c.pdf
+#
+# From Paul Eggert (2020-09-24):
+# tzdb uses the obsolete YST abbreviation for standard time in Yukon through
+# about 1970, and uses PST for standard time in Yukon since then. Consistent
+# with that, use MST for -07, the new standard time in Yukon effective Nov. 1.
+
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule NT_YK 1918 only - Apr 14 2:00 1:00 D
Rule NT_YK 1918 only - Oct 27 2:00 0 S
Rule NT_YK 1919 only - May 25 2:00 1:00 D
@@ -2349,7 +2474,7 @@
Rule NT_YK 1980 1986 - Apr lastSun 2:00 1:00 D
Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S
Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# aka Panniqtuuq
Zone America/Pangnirtung 0 - -00 1921 # trading post est.
-4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00
@@ -2390,11 +2515,13 @@
Zone America/Whitehorse -9:00:12 - LMT 1900 Aug 20
-9:00 NT_YK Y%sT 1967 May 28 0:00
-8:00 NT_YK P%sT 1980
- -8:00 Canada P%sT
+ -8:00 Canada P%sT 2020 Nov 1
+ -7:00 - MST
Zone America/Dawson -9:17:40 - LMT 1900 Aug 20
-9:00 NT_YK Y%sT 1973 Oct 28 0:00
-8:00 NT_YK P%sT 1980
- -8:00 Canada P%sT
+ -8:00 Canada P%sT 2020 Nov 1
+ -7:00 - MST
###############################################################################
@@ -2496,7 +2623,7 @@
# From Paul Eggert (2001-03-03):
#
-# http://www.latimes.com/news/nation/20010303/t000018766.html
+# https://www.latimes.com/archives/la-xpm-2001-mar-03-mn-32561-story.html
# James F. Smith writes in today's LA Times
# * Sonora will continue to observe standard time.
# * Last week Mexico City's mayor Andrés Manuel López Obrador decreed that
@@ -2608,7 +2735,7 @@
# 5- The islands, reefs and keys shall take their timezone from the
# longitude they are located at.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Mexico 1939 only - Feb 5 0:00 1:00 D
Rule Mexico 1939 only - Jun 25 0:00 0 S
Rule Mexico 1940 only - Dec 9 0:00 1:00 D
@@ -2623,7 +2750,7 @@
Rule Mexico 2001 only - Sep lastSun 2:00 0 S
Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D
Rule Mexico 2002 max - Oct lastSun 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
# Quintana Roo; represented by Cancún
Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56
-6:00 - CST 1981 Dec 23
@@ -2813,10 +2940,10 @@
# rules to sync with the U.S. starting in 2007....
# http://www.jonesbahamas.com/?c=45&a=10412
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Bahamas 1964 1975 - Oct lastSun 2:00 0 S
Rule Bahamas 1964 1975 - Apr lastSun 2:00 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Nassau -5:09:30 - LMT 1912 Mar 2
-5:00 Bahamas E%sT 1976
-5:00 US E%sT
@@ -2825,27 +2952,27 @@
# For 1899 Milne gives -3:58:29.2; round that.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Barb 1977 only - Jun 12 2:00 1:00 D
Rule Barb 1977 1978 - Oct Sun>=1 2:00 0 S
Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D
Rule Barb 1979 only - Sep 30 2:00 0 S
Rule Barb 1980 only - Sep 25 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Barbados -3:58:29 - LMT 1924 # Bridgetown
-3:58:29 - BMT 1932 # Bridgetown Mean Time
-4:00 Barb A%sT
# Belize
# Whitman entirely disagrees with Shanks; go with Shanks & Pottenger.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Belize 1918 1942 - Oct Sun>=2 0:00 0:30 -0530
Rule Belize 1919 1943 - Feb Sun>=9 0:00 0 CST
Rule Belize 1973 only - Dec 5 0:00 1:00 CDT
Rule Belize 1974 only - Feb 9 0:00 0 CST
Rule Belize 1982 only - Dec 18 0:00 1:00 CDT
Rule Belize 1983 only - Feb 12 0:00 0 CST
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Belize -5:52:48 - LMT 1912 Apr
-6:00 Belize %s
@@ -2862,7 +2989,7 @@
# Friday, the same thing will happen in Bermuda.
# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Atlantic/Bermuda -4:19:18 - LMT 1930 Jan 1 2:00 # Hamilton
-4:00 - AST 1974 Apr 28 2:00
-4:00 Canada A%sT 1976
@@ -2875,7 +3002,7 @@
# Milne gives -5:36:13.3 as San José mean time; round to nearest.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule CR 1979 1980 - Feb lastSun 0:00 1:00 D
Rule CR 1979 1980 - Jun Sun>=1 0:00 0 S
Rule CR 1991 1992 - Jan Sat>=15 0:00 1:00 D
@@ -2884,7 +3011,7 @@
Rule CR 1991 only - Jul 1 0:00 0 S
Rule CR 1992 only - Mar 15 0:00 0 S
# There are too many San Josés elsewhere, so we'll use 'Costa Rica'.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José
-5:36:13 - SJMT 1921 Jan 15 # San José Mean Time
-6:00 CR C%sT
@@ -3049,7 +3176,7 @@
# From Paul Eggert (2012-11-03):
# For now, assume the future rule is first Sunday in November.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Cuba 1928 only - Jun 10 0:00 1:00 D
Rule Cuba 1928 only - Oct 10 0:00 0 S
Rule Cuba 1940 1942 - Jun Sun>=1 0:00 1:00 D
@@ -3090,7 +3217,7 @@
Rule Cuba 2012 max - Nov Sun>=1 0:00s 0 S
Rule Cuba 2013 max - Mar Sun>=8 0:00s 1:00 D
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Havana -5:29:28 - LMT 1890
-5:29:36 - HMT 1925 Jul 19 12:00 # Havana MT
-5:00 Cuba C%sT
@@ -3118,14 +3245,14 @@
# decided to revert.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule DR 1966 only - Oct 30 0:00 1:00 EDT
Rule DR 1967 only - Feb 28 0:00 0 EST
Rule DR 1969 1973 - Oct lastSun 0:00 0:30 -0430
Rule DR 1970 only - Feb 21 0:00 0 EST
Rule DR 1971 only - Jan 20 0:00 0 EST
Rule DR 1972 1974 - Jan 21 0:00 0 EST
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Santo_Domingo -4:39:36 - LMT 1890
-4:40 - SDMT 1933 Apr 1 12:00 # S. Dom. MT
-5:00 DR %s 1974 Oct 27
@@ -3135,12 +3262,12 @@
# El Salvador
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Salv 1987 1988 - May Sun>=1 0:00 1:00 D
Rule Salv 1987 1988 - Sep lastSun 0:00 0 S
# There are too many San Salvadors elsewhere, so use America/El_Salvador
# instead of America/San_Salvador.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/El_Salvador -5:56:48 - LMT 1921 # San Salvador
-6:00 Salv C%sT
@@ -3164,7 +3291,7 @@
# (2006-04-19), says DST ends at 24:00. See
# http://www.sieca.org.gt/Sitio_publico/Energeticos/Doc/Medidas/Cambio_Horario_Nac_190406.pdf
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Guat 1973 only - Nov 25 0:00 1:00 D
Rule Guat 1974 only - Feb 24 0:00 0 S
Rule Guat 1983 only - May 21 0:00 1:00 D
@@ -3173,7 +3300,7 @@
Rule Guat 1991 only - Sep 7 0:00 0 S
Rule Guat 2006 only - Apr 30 0:00 1:00 D
Rule Guat 2006 only - Oct 1 0:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5
-6:00 Guat C%sT
@@ -3245,7 +3372,7 @@
# I have not been able to find a more authoritative source:
# https://www.haitilibre.com/en/news-20319-haiti-notices-time-change-in-haiti.html
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Haiti 1983 only - May 8 0:00 1:00 D
Rule Haiti 1984 1987 - Apr lastSun 0:00 1:00 D
Rule Haiti 1983 1987 - Oct lastSun 0:00 0 S
@@ -3259,7 +3386,7 @@
Rule Haiti 2012 2015 - Nov Sun>=1 2:00 0 S
Rule Haiti 2017 max - Mar Sun>=8 2:00 1:00 D
Rule Haiti 2017 max - Nov Sun>=1 2:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Port-au-Prince -4:49:20 - LMT 1890
-4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT
-5:00 Haiti E%sT
@@ -3293,12 +3420,12 @@
# http://www.laprensahn.com/pais_nota.php?id04962=7386
# So it seems that Honduras will not enter DST this year....
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Hond 1987 1988 - May Sun>=1 0:00 1:00 D
Rule Hond 1987 1988 - Sep lastSun 0:00 0 S
Rule Hond 2006 only - May Sun>=1 0:00 1:00 D
Rule Hond 2006 only - Aug Mon>=1 0:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr
-6:00 Hond C%sT
#
@@ -3319,7 +3446,7 @@
# Neita L. The politician in all of us. Jamaica Observer 2014-09-20
# http://www.jamaicaobserver.com/columns/The-politician-in-all-of-us_17573647
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Jamaica -5:07:10 - LMT 1890 # Kingston
-5:07:10 - KMT 1912 Feb # Kingston Mean Time
-5:00 - EST 1974
@@ -3327,7 +3454,7 @@
-5:00 - EST
# Martinique
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France
-4:04:20 - FFMT 1911 May # Fort-de-France MT
-4:00 - AST 1980 Apr 6
@@ -3384,14 +3511,14 @@
# The natural sun time is restored in all the national territory, in that the
# time is returned one hour at 01:00 am of October 1 of 2006.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Nic 1979 1980 - Mar Sun>=16 0:00 1:00 D
Rule Nic 1979 1980 - Jun Mon>=23 0:00 0 S
Rule Nic 2005 only - Apr 10 0:00 1:00 D
Rule Nic 2005 only - Oct Sun>=1 0:00 0 S
Rule Nic 2006 only - Apr 30 2:00 1:00 D
Rule Nic 2006 only - Oct Sun>=1 1:00 0 S
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Managua -5:45:08 - LMT 1890
-5:45:12 - MMT 1934 Jun 23 # Managua Mean Time?
-6:00 - CST 1973 May
@@ -3403,7 +3530,7 @@
-6:00 Nic C%sT
# Panama
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Panama -5:18:08 - LMT 1890
-5:19:36 - CMT 1908 Apr 22 # Colón Mean Time
-5:00 - EST
@@ -3411,7 +3538,7 @@
# Puerto Rico
# There are too many San Juans elsewhere, so we'll use 'Puerto_Rico'.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12:00 # San Juan
-4:00 - AST 1942 May 3
-4:00 US A%sT 1946
@@ -3423,7 +3550,7 @@
# St Pierre and Miquelon
# There are too many St Pierres elsewhere, so we'll use 'Miquelon'.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre
-4:00 - AST 1980 May
-3:00 - -03 1987
@@ -3469,7 +3596,7 @@
# by March 2018 for TCI. Magnetic Media. 2017-08-25.
# http://magneticmediatv.com/2017/08/time-change-back-by-march-2018-for-tci/
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Grand_Turk -4:44:32 - LMT 1890
-5:07:10 - KMT 1912 Feb # Kingston Mean Time
-5:00 - EST 1979
diff --git a/tools/java/org/unicode/cldr/util/data/pacificnew b/tools/java/org/unicode/cldr/util/data/pacificnew
deleted file mode 100644
index 0e6cf07..0000000
--- a/tools/java/org/unicode/cldr/util/data/pacificnew
+++ /dev/null
@@ -1,29 +0,0 @@
-# tzdb data for proposed US election time (this file is obsolete)
-
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# From Arthur David Olson (1989-04-05):
-# On 1989-04-05, the U. S. House of Representatives passed (238-154) a bill
-# establishing "Pacific Presidential Election Time"; it was not acted on
-# by the Senate or signed into law by the President.
-# You might want to change the "PE" (Presidential Election) below to
-# "Q" (Quadrennial) to maintain three-character zone abbreviations.
-# If you're really conservative, you might want to change it to "D".
-# Avoid "L" (Leap Year), which won't be true in 2100.
-
-# If Presidential Election Time is ever established, replace "XXXX" below
-# with the year the law takes effect and uncomment the "##" lines.
-
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-## Rule Twilite XXXX max - Apr Sun>=1 2:00 1:00 D
-## Rule Twilite XXXX max uspres Oct lastSun 2:00 1:00 PE
-## Rule Twilite XXXX max uspres Nov Sun>=7 2:00 0 S
-## Rule Twilite XXXX max nonpres Oct lastSun 2:00 0 S
-
-# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
-## Zone America/Los_Angeles-PET -8:00 US P%sT XXXX
-## -8:00 Twilite P%sT
-
-# For now...
-Link America/Los_Angeles US/Pacific-New ##
diff --git a/tools/java/org/unicode/cldr/util/data/southamerica b/tools/java/org/unicode/cldr/util/data/southamerica
index b66cb88..aad8b2d 100644
--- a/tools/java/org/unicode/cldr/util/data/southamerica
+++ b/tools/java/org/unicode/cldr/util/data/southamerica
@@ -48,7 +48,7 @@
# I am sending modifications to the Argentine time zone table...
# AR was chosen because they are the ISO letters that represent Argentina.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Arg 1930 only - Dec 1 0:00 1:00 -
Rule Arg 1931 only - Apr 1 0:00 0 -
Rule Arg 1931 only - Oct 15 0:00 1:00 -
@@ -396,7 +396,7 @@
# plus is that this silences a zic complaint that there's no POSIX TZ
# setting for timestamps past 2038.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
#
# Buenos Aires (BA), Capital Federal (CF),
Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
@@ -577,7 +577,7 @@
Link America/Curacao America/Aruba
# Bolivia
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/La_Paz -4:32:36 - LMT 1890
-4:32:36 - CMT 1931 Oct 15 # Calamarca MT
-4:32:36 1:00 BST 1932 Mar 21 # Bolivia ST
@@ -769,7 +769,7 @@
# From Paul Eggert (2013-10-17):
# For now, assume western Amazonas will change as well.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
# Decree 20,466 <http://pcdsh01.on.br/HV20466.htm> (1931-10-01)
# Decree 21,896 <http://pcdsh01.on.br/HV21896.htm> (1932-01-10)
Rule Brazil 1931 only - Oct 3 11:00 1:00 -
@@ -920,14 +920,13 @@
# removed Tocantins.
Rule Brazil 2013 2014 - Feb Sun>=15 0:00 0 -
Rule Brazil 2015 only - Feb Sun>=22 0:00 0 -
-Rule Brazil 2016 2022 - Feb Sun>=15 0:00 0 -
+Rule Brazil 2016 2019 - Feb Sun>=15 0:00 0 -
# From Steffen Thorsen (2017-12-18):
# According to many media sources, next year's DST start in Brazil will move to
-# the first Sunday of November, and it will stay like that for the years after.
+# the first Sunday of November
# ... https://www.timeanddate.com/news/time/brazil-delays-dst-2018.html
# From Steffen Thorsen (2017-12-20):
# http://www.planalto.gov.br/ccivil_03/_ato2015-2018/2017/decreto/D9242.htm
-#
# From Fábio Gomes (2018-10-04):
# The Brazilian president just announced a new change on this year DST.
# It was scheduled to start on November 4th and it was changed to November 18th.
@@ -935,22 +934,21 @@
# The Brazilian government just announced that the change in DST was
# canceled.... Maybe the president Michel Temer also woke up one hour
# earlier today. :)
-Rule Brazil 2018 max - Nov Sun>=1 0:00 1:00 -
-Rule Brazil 2023 only - Feb Sun>=22 0:00 0 -
-Rule Brazil 2024 2025 - Feb Sun>=15 0:00 0 -
-Rule Brazil 2026 only - Feb Sun>=22 0:00 0 -
-Rule Brazil 2027 2033 - Feb Sun>=15 0:00 0 -
-Rule Brazil 2034 only - Feb Sun>=22 0:00 0 -
-Rule Brazil 2035 2036 - Feb Sun>=15 0:00 0 -
-Rule Brazil 2037 only - Feb Sun>=22 0:00 0 -
-# From Arthur David Olson (2008-09-29):
-# The next is wrong in some years but is better than nothing.
-Rule Brazil 2038 max - Feb Sun>=15 0:00 0 -
-
-# The latest ruleset listed above says that the following states observe DST:
+Rule Brazil 2018 only - Nov Sun>=1 0:00 1:00 -
+# The last ruleset listed above says that the following states observed DST:
# DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
+#
+# From Steffen Thorsen (2019-04-05):
+# According to multiple sources the Brazilian president wants to get rid of DST.
+# https://gmconline.com.br/noticias/politica/bolsonaro-horario-de-verao-deve-acabar-este-ano
+# https://g1.globo.com/economia/noticia/2019/04/05/governo-anuncia-fim-do-horario-de-verao.ghtml
+# From Marcus Diniz (2019-04-25):
+# Brazil no longer has DST changes - decree signed today
+# https://g1.globo.com/politica/noticia/2019/04/25/bolsonaro-assina-decreto-que-acaba-com-o-horario-de-verao.ghtml
+# From Daniel Soares de Oliveira (2019-04-26):
+# http://www.planalto.gov.br/ccivil_03/_Ato2019-2022/2019/Decreto/D9772.htm
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
#
# Fernando de Noronha (administratively part of PE)
Zone America/Noronha -2:09:40 - LMT 1914
@@ -1232,14 +1230,8 @@
# From Juan Correa (2016-12-04):
# Magallanes region ... will keep DST (UTC -3) all year round....
# http://www.soychile.cl/Santiago/Sociedad/2016/12/04/433428/Bachelet-firmo-el-decreto-para-establecer-un-horario-unico-para-la-Region-de-Magallanes.aspx
-#
# From Deborah Goldsmith (2017-01-19):
# http://www.diariooficial.interior.gob.cl/publicaciones/2017/01/17/41660/01/1169626.pdf
-# From Paul Eggert (2017-01-19):
-# The above says the Magallanes change expires 2019-05-11 at 24:00,
-# so in theory, they will revert to -04/-03 after that, which means
-# they will switch from -03 to -04 one hour after Santiago does that day.
-# For now, assume that they will not revert.
# From Juan Correa (2018-08-13):
# As of moments ago, the Ministry of Energy in Chile has announced the new
@@ -1258,8 +1250,15 @@
# https://twitter.com/MinEnergia/status/1029009354001973248
# "We will keep the new time policy unchanged for at least the next 4 years."
# So we extend the new rules on Saturdays at 24:00 mainland time indefinitely.
+# From Juan Correa (2019-02-04):
+# http://www.diariooficial.interior.gob.cl/publicaciones/2018/11/23/42212/01/1498738.pdf
+# From Paul Eggert (2019-09-01):
+# The above says the Magallanes exception expires 2022-04-02 at 24:00,
+# so in theory, they will revert to -04/-03 after that.
+# For now, assume that they will not revert,
+# since they have extended the expiration date once already.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
Rule Chile 1928 1932 - Apr 1 0:00 0 -
Rule Chile 1968 only - Nov 3 4:00u 1:00 -
@@ -1298,7 +1297,7 @@
Rule Chile 2019 max - Sep Sun>=2 4:00u 1:00 -
# IATA SSIM anomalies: (1992-02) says 1992-03-14;
# (1996-09) says 1998-03-08. Ignore these.
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Santiago -4:42:46 - LMT 1890
-4:42:46 - SMT 1910 Jan 10 # Santiago Mean Time
-5:00 - -05 1916 Jul 1
@@ -1347,7 +1346,7 @@
# Palmer has followed Chile. Prior to that, before the Falklands War,
# Palmer used to be supplied from Argentina.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Antarctica/Palmer 0 - -00 1965
-4:00 Arg -04/-03 1969 Oct 5
-3:00 Arg -03/-02 1982 May
@@ -1359,10 +1358,10 @@
# Milne gives 4:56:16.4 for Bogotá time in 1899; round to nearest. He writes,
# "A variation of fifteen minutes in the public clocks of Bogota is not rare."
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule CO 1992 only - May 3 0:00 1:00 -
Rule CO 1993 only - Apr 4 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Bogota -4:56:16 - LMT 1884 Mar 13
-4:56:16 - BMT 1914 Nov 23 # Bogotá Mean Time
-5:00 CO -05/-04
@@ -1387,7 +1386,7 @@
# Netherlands as Kingdom Islands. This won't affect their time zones
# though, as far as we know.
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Curacao -4:35:47 - LMT 1912 Feb 12 # Willemstad
-4:30 - -0430 1965
-4:00 - AST
@@ -1419,11 +1418,11 @@
# (Not one step back), the clocks went back in 1993 and the experiment was not
# repeated. For now, assume transitions were at 00:00 local time country-wide.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Ecuador 1992 only - Nov 28 0:00 1:00 -
Rule Ecuador 1993 only - Feb 5 0:00 0 -
#
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Guayaquil -5:19:20 - LMT 1890
-5:14:00 - QMT 1931 # Quito Mean Time
-5:00 Ecuador -05/-04
@@ -1513,7 +1512,7 @@
# For now we will assume permanent -03 for the Falklands
# until advised differently (to apply for 2012 and beyond, after the 2011
# experiment was apparently successful.)
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Falk 1937 1938 - Sep lastSun 0:00 1:00 -
Rule Falk 1938 1942 - Mar Sun>=19 0:00 0 -
Rule Falk 1939 only - Oct 1 0:00 1:00 -
@@ -1526,7 +1525,7 @@
Rule Falk 1986 2000 - Apr Sun>=16 0:00 0 -
Rule Falk 2001 2010 - Apr Sun>=15 2:00 0 -
Rule Falk 2001 2010 - Sep Sun>=1 2:00 1:00 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Atlantic/Stanley -3:51:24 - LMT 1890
-3:51:24 - SMT 1912 Mar 12 # Stanley Mean Time
-4:00 Falk -04/-03 1983 May
@@ -1535,13 +1534,13 @@
-3:00 - -03
# French Guiana
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Cayenne -3:29:20 - LMT 1911 Jul
-4:00 - -04 1967 Oct
-3:00 - -03
# Guyana
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Guyana -3:52:40 - LMT 1915 Mar # Georgetown
-3:45 - -0345 1975 Jul 31
-3:00 - -03 1991
@@ -1559,7 +1558,7 @@
# No time of the day is established for the adjustment, so people normally
# adjust their clocks at 0 hour of the given dates.
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Para 1975 1988 - Oct 1 0:00 1:00 -
Rule Para 1975 1978 - Mar 1 0:00 0 -
Rule Para 1979 1991 - Apr 1 0:00 0 -
@@ -1635,7 +1634,7 @@
# http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf
Rule Para 2013 max - Mar Sun>=22 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Asuncion -3:50:40 - LMT 1890
-3:50:40 - AMT 1931 Oct 10 # Asunción Mean Time
-4:00 - -04 1972 Oct
@@ -1652,7 +1651,7 @@
# From Paul Eggert (2006-03-22):
# Shanks & Pottenger don't have this transition. Assume 1986 was like 1987.
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Peru 1938 only - Jan 1 0:00 1:00 -
Rule Peru 1938 only - Apr 1 0:00 0 -
Rule Peru 1938 1939 - Sep lastSun 0:00 1:00 -
@@ -1664,13 +1663,13 @@
# IATA is ambiguous for 1993/1995; go with Shanks & Pottenger.
Rule Peru 1994 only - Jan 1 0:00 1:00 -
Rule Peru 1994 only - Apr 1 0:00 0 -
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Lima -5:08:12 - LMT 1890
-5:08:36 - LMT 1908 Jul 28 # Lima Mean Time?
-5:00 Peru -05/-04
# South Georgia
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Atlantic/South_Georgia -2:26:08 - LMT 1890 # Grytviken
-2:00 - -02
@@ -1678,7 +1677,7 @@
# uninhabited; scientific personnel have wintered
# Suriname
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Paramaribo -3:40:40 - LMT 1911
-3:40:52 - PMT 1935 # Paramaribo Mean Time
-3:40:36 - PMT 1945 Oct # The capital moved?
@@ -1686,7 +1685,7 @@
-3:00 - -03
# Trinidad and Tobago
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2
-4:00 - AST
@@ -1748,7 +1747,7 @@
# https://www.impo.com.uy/diariooficial/1926/03/10/2
# https://www.impo.com.uy/diariooficial/1926/03/18/2
#
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
+# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule Uruguay 1923 1925 - Oct 1 0:00 0:30 -
Rule Uruguay 1924 1926 - Apr 1 0:00 0 -
# From Tim Parenti (2018-02-15):
@@ -1957,7 +1956,7 @@
# ... published in the official Gazette [2016-04-18], here:
# http://historico.tsj.gob.ve/gaceta_ext/abril/1842016/E-1842016-4551.pdf
-# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone America/Caracas -4:27:44 - LMT 1890
-4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time?
-4:30 - -0430 1965 Jan 1 0:00
diff --git a/tools/java/org/unicode/cldr/util/data/st_sysmsg.html b/tools/java/org/unicode/cldr/util/data/st_sysmsg.html
index 5a82330..e384fc0 100644
--- a/tools/java/org/unicode/cldr/util/data/st_sysmsg.html
+++ b/tools/java/org/unicode/cldr/util/data/st_sysmsg.html
@@ -65,7 +65,7 @@
<hr> <a href='http://www.unicode.org'>Unicode</a> | <a
href='http://www.unicode.org/cldr/'>Common Locale Data
Repository</a> | <a
- href='http://www.unicode.org/cldr/trac/newticket?component=survey&summary=Feedback+on+BOOTING+%3F'>Report
+ href='http://cldr.unicode.org/index/bug-reports#TOC-Filing-a-Ticket'>Report
Problem in Tool</a>
</td>
diff --git a/tools/java/org/unicode/cldr/util/data/systemv b/tools/java/org/unicode/cldr/util/data/systemv
deleted file mode 100644
index 24c8f64..0000000
--- a/tools/java/org/unicode/cldr/util/data/systemv
+++ /dev/null
@@ -1,39 +0,0 @@
-# tzdb data for System V rules (this file is obsolete)
-
-# This file is in the public domain, so clarified as of
-# 2009-05-17 by Arthur David Olson.
-
-# Old rules, should the need arise.
-# No attempt is made to handle Newfoundland, since it cannot be expressed
-# using the System V "TZ" scheme (half-hour offset), or anything outside
-# North America (no support for non-standard DST start/end dates), nor
-# the changes in the DST rules in the US after 1976 (which occurred after
-# the old rules were written).
-#
-# If you need the old rules, uncomment ## lines.
-# Compile this *without* leap second correction for true conformance.
-
-# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
-Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D
-Rule SystemV min 1973 - Oct lastSun 2:00 0 S
-Rule SystemV 1974 only - Jan 6 2:00 1:00 D
-Rule SystemV 1974 only - Nov lastSun 2:00 0 S
-Rule SystemV 1975 only - Feb 23 2:00 1:00 D
-Rule SystemV 1975 only - Oct lastSun 2:00 0 S
-Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D
-Rule SystemV 1976 max - Oct lastSun 2:00 0 S
-
-# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
-## Zone SystemV/AST4ADT -4:00 SystemV A%sT
-## Zone SystemV/EST5EDT -5:00 SystemV E%sT
-## Zone SystemV/CST6CDT -6:00 SystemV C%sT
-## Zone SystemV/MST7MDT -7:00 SystemV M%sT
-## Zone SystemV/PST8PDT -8:00 SystemV P%sT
-## Zone SystemV/YST9YDT -9:00 SystemV Y%sT
-## Zone SystemV/AST4 -4:00 - AST
-## Zone SystemV/EST5 -5:00 - EST
-## Zone SystemV/CST6 -6:00 - CST
-## Zone SystemV/MST7 -7:00 - MST
-## Zone SystemV/PST8 -8:00 - PST
-## Zone SystemV/YST9 -9:00 - YST
-## Zone SystemV/HST10 -10:00 - HST
diff --git a/tools/java/org/unicode/cldr/util/data/tlds-alpha-by-domain.txt b/tools/java/org/unicode/cldr/util/data/tlds-alpha-by-domain.txt
index 02ac0c4..bd1ecaf 100644
--- a/tools/java/org/unicode/cldr/util/data/tlds-alpha-by-domain.txt
+++ b/tools/java/org/unicode/cldr/util/data/tlds-alpha-by-domain.txt
@@ -1,4 +1,4 @@
-# Version 2019120500, Last Updated Thu Dec 5 07:07:01 2019 UTC
+# Version 2020082200, Last Updated Sat Aug 22 07:07:01 2020 UTC
AAA
AARP
ABARTH
@@ -33,7 +33,6 @@
AGENCY
AI
AIG
-AIGO
AIRBUS
AIRFORCE
AIRTEL
@@ -48,6 +47,7 @@
ALSACE
ALSTOM
AM
+AMAZON
AMERICANEXPRESS
AMERICANFAMILY
AMEX
@@ -392,7 +392,6 @@
ES
ESQ
ESTATE
-ESURANCE
ET
ETISALAT
EU
@@ -712,7 +711,6 @@
LEXUS
LGBT
LI
-LIAISON
LIDL
LIFE
LIFEINSURANCE
@@ -731,6 +729,7 @@
LIXIL
LK
LLC
+LLP
LOAN
LOANS
LOCKER
@@ -820,7 +819,6 @@
MOTORCYCLES
MOV
MOVIE
-MOVISTAR
MP
MQ
MR
@@ -839,7 +837,6 @@
MZ
NA
NAB
-NADEX
NAGOYA
NAME
NATIONWIDE
@@ -1022,7 +1019,6 @@
RICH
RICHARDLI
RICOH
-RIGHTATHOME
RIL
RIO
RIP
@@ -1073,7 +1069,6 @@
SCHWARZ
SCIENCE
SCJOHNSON
-SCOR
SCOT
SD
SE
@@ -1172,7 +1167,6 @@
SX
SY
SYDNEY
-SYMANTEC
SYSTEMS
SZ
TAB
@@ -1193,7 +1187,6 @@
TECH
TECHNOLOGY
TEL
-TELEFONICA
TEMASEK
TENNIS
TEVA
@@ -1286,7 +1279,6 @@
VIRGIN
VISA
VISION
-VISTAPRINT
VIVA
VIVO
VLAANDEREN
@@ -1380,6 +1372,7 @@
XN--C1AVG
XN--C2BR7G
XN--CCK2B3B
+XN--CCKWCXETD
XN--CG4BKI
XN--CLCHC0EA0B2G2A9GCD
XN--CZR694B
@@ -1390,7 +1383,6 @@
XN--E1A4C
XN--ECKVDTC9D
XN--EFVY88H
-XN--ESTV75G
XN--FCT429K
XN--FHBEI
XN--FIQ228C5HS
@@ -1416,12 +1408,12 @@
XN--J1AEF
XN--J1AMH
XN--J6W193G
+XN--JLQ480N2RG
XN--JLQ61U9W7B
XN--JVR189M
XN--KCRX77D1X4A
XN--KPRW13D
XN--KPRY57D
-XN--KPU716F
XN--KPUT3I
XN--L1ACC
XN--LGBBAT1AD8J
@@ -1439,6 +1431,7 @@
XN--MGBBH1A71E
XN--MGBC0A9AZCG
XN--MGBCA7DZDO
+XN--MGBCPQ6GPA1A
XN--MGBERP4A5D4AR
XN--MGBGU82A
XN--MGBI4ECEXP
@@ -1461,9 +1454,9 @@
XN--OTU796D
XN--P1ACF
XN--P1AI
-XN--PBT977C
XN--PGBS0DH
XN--PSSY2U
+XN--Q7CE6A
XN--Q9JYB4C
XN--QCKA1PMC
XN--QXA6A
diff --git a/tools/java/org/unicode/cldr/util/data/tzdb-version.txt b/tools/java/org/unicode/cldr/util/data/tzdb-version.txt
index c5bbdc4..f3edeca 100644
--- a/tools/java/org/unicode/cldr/util/data/tzdb-version.txt
+++ b/tools/java/org/unicode/cldr/util/data/tzdb-version.txt
@@ -1 +1 @@
-2017b
+2020b
diff --git a/tools/java/org/unicode/cldr/util/data/zone.tab b/tools/java/org/unicode/cldr/util/data/zone.tab
index 27e1dee..8d056e3 100644
--- a/tools/java/org/unicode/cldr/util/data/zone.tab
+++ b/tools/java/org/unicode/cldr/util/data/zone.tab
@@ -131,8 +131,8 @@
CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
-CA +6043-13503 America/Whitehorse Pacific - Yukon (south)
-CA +6404-13925 America/Dawson Pacific - Yukon (north)
+CA +6043-13503 America/Whitehorse Pacific - Yukon (east)
+CA +6404-13925 America/Dawson Pacific - Yukon (west)
CC -1210+09655 Indian/Cocos
CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west)
CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east)
@@ -189,7 +189,7 @@
GG +492717-0023210 Europe/Guernsey
GH +0533-00013 Africa/Accra
GI +3608-00521 Europe/Gibraltar
-GL +6411-05144 America/Godthab Greenland (most areas)
+GL +6411-05144 America/Nuuk Greenland (most areas)
GL +7646-01840 America/Danmarkshavn National Park (east coast)
GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit
GL +7634-06847 America/Thule Thule/Pituffik
@@ -332,7 +332,10 @@
RS +4450+02030 Europe/Belgrade
RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad
RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area
-RU +4457+03406 Europe/Simferopol MSK+00 - Crimea
+# The obsolescent zone.tab format cannot represent Europe/Simferopol well.
+# Put it in RU section and list as UA. See "territorial claims" above.
+# Programs should use zone1970.tab instead; see above.
+UA +4457+03406 Europe/Simferopol Crimea
RU +5836+04939 Europe/Kirov MSK+00 - Kirov
RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
@@ -396,8 +399,8 @@
TW +2503+12130 Asia/Taipei
TZ -0648+03917 Africa/Dar_es_Salaam
UA +5026+03031 Europe/Kiev Ukraine (most areas)
-UA +4837+02218 Europe/Uzhgorod Ruthenia
-UA +4750+03510 Europe/Zaporozhye Zaporozh'ye/Zaporizhia; Lugansk/Luhansk (east)
+UA +4837+02218 Europe/Uzhgorod Transcarpathia
+UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk
UG +0019+03225 Africa/Kampala
UM +2813-17722 Pacific/Midway Midway Islands
UM +1917+16637 Pacific/Wake Wake Island
diff --git a/tools/java/org/unicode/cldr/util/props/BagFormatter.java b/tools/java/org/unicode/cldr/util/props/BagFormatter.java
index 4e898f6..faff758 100644
--- a/tools/java/org/unicode/cldr/util/props/BagFormatter.java
+++ b/tools/java/org/unicode/cldr/util/props/BagFormatter.java
@@ -114,7 +114,7 @@
UnicodeSet set1,
String name2,
UnicodeSet set2,
- int flags)
+ int flags)
{
if (pw == null) pw = FileUtilities.CONSOLE;
String[] names = { name1, name2 };
@@ -231,6 +231,7 @@
}
static class NullRelation extends Relation {
+ @Override
public String getRelation(String a, String b) { return ""; }
}
@@ -323,6 +324,7 @@
noncharacter = source.getSet("noncharactercodepoint=yes");
}
+ @Override
public String getValue(int codePoint, boolean isShort) {
String hcp = !isShort
? "U+" + Utility.hex(codePoint, 4) + " "
@@ -565,15 +567,18 @@
return result;
}
+ @Override
protected void doBefore(Object container, Object o) {
if (showSetAlso && container instanceof UnicodeSet) {
toOutput("#" + container);
}
}
+ @Override
protected void doBetween(Object container, Object lastItem, Object nextItem) {
}
+ @Override
protected void doAfter(Object container, Object o) {
if (fullTotal != -1 && fullTotal != counter) {
if (showTotal) {
@@ -588,6 +593,7 @@
}
}
+ @Override
protected void doSimpleAt(Object o) {
if (o instanceof Map.Entry) {
Map.Entry oo = (Map.Entry)o;
@@ -765,8 +771,8 @@
if (DEBUG && limit > 0x9FD4) {
System.out.println(Utility.hex(limit) + ", *Label: " + s + ", Value: " + v + ", Break: " + b);
}
- if (!equalTo(s, label)
- || !equalTo(v, value)
+ if (!equalTo(s, label)
+ || !equalTo(v, value)
|| !equalTo(b, breaker)) {
break;
}
@@ -831,6 +837,7 @@
/**
* @deprecated
*/
+ @Deprecated
public static void addAll(UnicodeSet source, Collection target) {
source.addAllTo(target);
}
@@ -865,17 +872,21 @@
doAt(o);
return output.toString();
}
+ @Override
protected void doBefore(Object container, Object item) {
++depth;
output.append(prefix);
}
+ @Override
protected void doAfter(Object container, Object item) {
output.append(suffix);
--depth;
}
+ @Override
protected void doBetween(Object container, Object lastItem, Object nextItem) {
output.append(separator);
}
+ @Override
protected void doSimpleAt(Object o) {
if (o != null) output.append(o.toString());
}
diff --git a/tools/java/org/unicode/cldr/util/props/ICUPropertyFactory.java b/tools/java/org/unicode/cldr/util/props/ICUPropertyFactory.java
index c269b8f..30bf552 100644
--- a/tools/java/org/unicode/cldr/util/props/ICUPropertyFactory.java
+++ b/tools/java/org/unicode/cldr/util/props/ICUPropertyFactory.java
@@ -20,7 +20,7 @@
import java.util.TreeMap;
import java.util.TreeSet;
-import com.ibm.icu.dev.util.CollectionUtilities;
+import com.google.common.base.Joiner;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
@@ -54,6 +54,7 @@
boolean shownException = false;
+ @Override
public String _getValue(int codePoint) {
switch (propEnum) {
case UProperty.AGE:
@@ -111,7 +112,7 @@
case isCased:
return String.valueOf(UCharacter.toLowerCase(Locale.ENGLISH, UTF16.valueOf(codePoint)).equals(
UTF16.valueOf(codePoint)));
- case UProperty.SCRIPT_EXTENSIONS:
+ case UProperty.SCRIPT_EXTENSIONS:
return getStringScriptExtensions(codePoint);
}
if (propEnum < UProperty.INT_LIMIT) {
@@ -220,6 +221,7 @@
return newValue;
}
+ @Override
public List _getNameAliases(List result) {
if (result == null)
result = new ArrayList();
@@ -259,6 +261,7 @@
}
}
+ @Override
public List _getAvailableValues(List result) {
if (result == null)
result = new ArrayList();
@@ -309,6 +312,7 @@
return AGES;
}
+ @Override
public List _getValueAliases(String valueAlias, List result) {
if (result == null)
result = new ArrayList();
@@ -383,9 +387,10 @@
/*
* (non-Javadoc)
- *
+ *
* @see com.ibm.icu.dev.test.util.UnicodeProperty#getVersion()
*/
+ @Override
public String _getVersion() {
return VersionInfo.ICU_VERSION.toString();
}
@@ -459,12 +464,12 @@
if (result >= 0) {
return UScript.getName(result);
}
- TreeMap<String,String> sorted = new TreeMap<String,String>();
+ TreeMap<String,String> sorted = new TreeMap<>();
for (int scriptCode = BITSET.nextSetBit(0); scriptCode >= 0; scriptCode = BITSET.nextSetBit(scriptCode+1)) {
// sort by short form
sorted.put(UScript.getShortName(scriptCode), UScript.getName(scriptCode));
}
- return CollectionUtilities.join(sorted.values(), " ");
+ return Joiner.on(" ").join(sorted.values());
}
private static ICUPropertyFactory singleton = null;
@@ -518,7 +523,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see com.ibm.icu.dev.test.util.UnicodePropertySource#getProperty(java.lang.String)
*/
// TODO file bug on getPropertyValueName for Canonical_Combining_Class
diff --git a/tools/java/org/unicode/cldr/util/props/RandomStringGenerator.java b/tools/java/org/unicode/cldr/util/props/RandomStringGenerator.java
index 4b1d0ce..50c3fd7 100644
--- a/tools/java/org/unicode/cldr/util/props/RandomStringGenerator.java
+++ b/tools/java/org/unicode/cldr/util/props/RandomStringGenerator.java
@@ -19,7 +19,7 @@
public class RandomStringGenerator {
private static final UnicodeSet SUPPLEMENTARIES = new UnicodeSet(0x10000, 0x10FFFF);
-
+
/**
* If not null, masks off the character properties so the UnicodeSets are easier to use when debugging.
*/
@@ -77,6 +77,7 @@
}
static UnicodeMap.Composer MyComposer = new UnicodeMap.Composer() {
+ @Override
public Object compose(int codePoint, String string, Object a, Object b) {
if (a == null) return b;
if (b == null) return a;
diff --git a/tools/java/org/unicode/cldr/util/props/UnicodeLabel.java b/tools/java/org/unicode/cldr/util/props/UnicodeLabel.java
index b284985..b47b2a1 100644
--- a/tools/java/org/unicode/cldr/util/props/UnicodeLabel.java
+++ b/tools/java/org/unicode/cldr/util/props/UnicodeLabel.java
@@ -10,17 +10,17 @@
import com.ibm.icu.text.UTF16;
public abstract class UnicodeLabel implements com.ibm.icu.text.Transform<Integer, String> {
-
+
public abstract String getValue(int codepoint, boolean isShort);
@Override
public String transform(Integer codepoint) {
return getValue(codepoint, true);
}
-
+
public String getValue(String s, String separator, boolean withCodePoint) {
if (s.length() == 1) { // optimize simple case
- return getValue(s.charAt(0), withCodePoint);
+ return getValue(s.charAt(0), withCodePoint);
}
StringBuffer sb = new StringBuffer();
int cp;
@@ -31,19 +31,19 @@
}
return sb.toString();
}
-
+
public int getMaxWidth(boolean isShort) {
return 0;
}
-
+
private static class Hex extends UnicodeLabel {
@Override
public String getValue(int codepoint, boolean isShort) {
if (isShort) return Utility.hex(codepoint,4);
return "U+" + Utility.hex(codepoint,4);
- }
+ }
}
-
+
public static class Constant extends UnicodeLabel {
private String value;
public Constant(String value) {
@@ -56,7 +56,7 @@
}
@Override
public int getMaxWidth(boolean isShort) {
- return value.length();
+ return value.length();
}
}
public static final UnicodeLabel NULL = new Constant("");
diff --git a/tools/java/org/unicode/cldr/util/props/UnicodeProperty.java b/tools/java/org/unicode/cldr/util/props/UnicodeProperty.java
index 077cb53..0faf70a 100644
--- a/tools/java/org/unicode/cldr/util/props/UnicodeProperty.java
+++ b/tools/java/org/unicode/cldr/util/props/UnicodeProperty.java
@@ -20,10 +20,9 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.function.Predicate;
import java.util.regex.Pattern;
-import com.ibm.icu.dev.util.CollectionUtilities.InverseMatcher;
-import com.ibm.icu.dev.util.CollectionUtilities.ObjectMatcher;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.SymbolTable;
@@ -142,7 +141,7 @@
/*
* Name: Unicode_1_Name Name: ISO_Comment Name: Name Name: Unicode_1_Name
- *
+ *
*/
public static final int UNKNOWN = 0, BINARY = 2, EXTENDED_BINARY = 3,
@@ -261,6 +260,7 @@
return getAvailableValues(null);
}
+ @Override
public final String getValue(int codepoint, boolean getShortest) {
String result = getValue(codepoint);
if (type >= MISC || result == null || !getShortest)
@@ -270,7 +270,7 @@
public final String getFirstNameAlias() {
if (firstNameAlias == null) {
- firstNameAlias = (String) getNameAliases().get(0);
+ firstNameAlias = getNameAliases().get(0);
}
return firstNameAlias;
}
@@ -288,7 +288,7 @@
Iterator it = getAvailableValues().iterator();
while (it.hasNext()) {
String value = (String) it.next();
- String first = (String) getValueAliases(value).get(0);
+ String first = getValueAliases(value).get(0);
if (first == null) { // internal error
throw new IllegalArgumentException(
"Value not in value aliases: " + value);
@@ -312,6 +312,7 @@
private int maxFirstValueAliasWidth = -1;
+ @Override
public int getMaxWidth(boolean getShortest) {
if (maxValueWidth < 0)
_getFirstValueAliasCache();
@@ -352,7 +353,7 @@
}
}
}
- ObjectMatcher<String> matcher = isType(STRING_OR_MISC_MASK) ?
+ Predicate<String> matcher = isType(STRING_OR_MISC_MASK) ?
new StringEqualityMatcher(propertyValue) : new NameMatcher(propertyValue);
return getSet(matcher, result);
}
@@ -386,7 +387,7 @@
public static final String UNUSED = "??";
- public UnicodeSet getSet(ObjectMatcher matcher, UnicodeSet result) {
+ public UnicodeSet getSet(Predicate matcher, UnicodeSet result) {
if (result == null)
result = new UnicodeSet();
boolean uniformUnassigned = hasUniformUnassigned();
@@ -394,7 +395,7 @@
for (UnicodeSetIterator usi = getStuffToTest(uniformUnassigned); usi.next();) { // int i = 0; i <= 0x10FFFF; ++i
int i = usi.codepoint;
String value = getValue(i);
- if (value != null && matcher.matches(value)) {
+ if (value != null && matcher.test(value)) {
result.add(i);
}
}
@@ -405,7 +406,7 @@
Iterator it = um.getAvailableValues(null).iterator();
main: while (it.hasNext()) {
String value = (String) it.next();
- if (matcher.matches(value)) { // fastpath
+ if (matcher.test(value)) { // fastpath
um.keySet(value, result);
continue main;
}
@@ -414,8 +415,8 @@
while (it2.hasNext()) {
String value2 = (String) it2.next();
// System.out.println("Values:" + value2);
- if (matcher.matches(value2)
- || matcher.matches(toSkeleton(value2))) {
+ if (matcher.test(value2)
+ || matcher.test(toSkeleton(value2))) {
um.keySet(value, result);
continue main;
}
@@ -427,7 +428,7 @@
/*
* public UnicodeSet getMatchSet(UnicodeSet result) { if (result == null)
* result = new UnicodeSet(); addAll(matchIterator, result); return result; }
- *
+ *
* public void setMatchSet(UnicodeSet set) { matchIterator = new
* UnicodeSetIterator(set); }
*/
@@ -463,18 +464,22 @@
}
}
+ @Override
public int compareTo(Object o) {
return skeleton.compareTo(((Name) o).skeleton);
}
+ @Override
public boolean equals(Object o) {
return skeleton.equals(((Name) o).skeleton);
}
+ @Override
public int hashCode() {
return skeleton.hashCode();
}
+ @Override
public String toString() {
return pretty;
}
@@ -492,7 +497,7 @@
*/
public UnicodeMap getUnicodeMap(boolean getShortest) {
if (!getShortest)
- return (UnicodeMap) getUnicodeMap_internal().cloneAsThawed();
+ return getUnicodeMap_internal().cloneAsThawed();
UnicodeMap result = new UnicodeMap();
boolean uniformUnassigned = hasUniformUnassigned();
@@ -575,6 +580,7 @@
* Utility for managing property & non-string value aliases
*/
public static final Comparator PROPERTY_COMPARATOR = new Comparator() {
+ @Override
public int compare(Object o1, Object o2) {
return compareNames((String) o1, (String) o2);
}
@@ -582,7 +588,7 @@
/**
* Utility for managing property & non-string value aliases
- *
+ *
*/
// TODO optimize
public static boolean equalNames(String a, String b) {
@@ -716,7 +722,7 @@
/**
* Utility function for comparing codepoint to string without generating new
* string.
- *
+ *
* @param codepoint
* @param other
* @return true if the codepoint equals the string
@@ -744,7 +750,7 @@
/**
* Utility that should be on UnicodeSet
- *
+ *
* @param source
* @param result
*/
@@ -783,7 +789,7 @@
static public class Factory {
static boolean DEBUG = false;
- Map<String, UnicodeProperty> canonicalNames = new TreeMap<String, UnicodeProperty>();
+ Map<String, UnicodeProperty> canonicalNames = new TreeMap<>();
Map skeletonNames = new TreeMap();
@@ -890,6 +896,7 @@
}
private class MyXSymbolTable extends UnicodeSet.XSymbolTable {
+ @Override
public boolean applyPropertyAlias(String propertyName,
String propertyValue, UnicodeSet result) {
if (false)
@@ -918,6 +925,7 @@
this.prefix = prefix;
}
+ @Override
public char[] lookup(String s) {
if (DEBUG)
System.out.println("\t(" + prefix + ")Looking up " + s);
@@ -969,10 +977,12 @@
return result.toString();
}
+ @Override
public UnicodeMatcher lookupMatcher(int ch) {
return null;
}
+ @Override
public String parseReference(String text, ParsePosition pos,
int limit) {
if (DEBUG)
@@ -1064,20 +1074,24 @@
List temp = new ArrayList(1);
+ @Override
public List _getAvailableValues(List result) {
temp.clear();
return filter.addUnique(property.getAvailableValues(temp), result);
}
+ @Override
public List _getNameAliases(List result) {
temp.clear();
return filter.addUnique(property.getNameAliases(temp), result);
}
+ @Override
public String _getValue(int codepoint) {
return filter.remap(property.getValue(codepoint));
}
+ @Override
public List _getValueAliases(String valueAlias, List result) {
if (backmap == null) {
backmap = new HashMap(1);
@@ -1101,6 +1115,7 @@
result);
}
+ @Override
public String _getVersion() {
return property.getVersion();
}
@@ -1142,6 +1157,7 @@
this.valueMap = valueMap;
}
+ @Override
public String remap(String original) {
Object changed = valueMap.get(original);
return changed == null ? original : (String) changed;
@@ -1153,7 +1169,7 @@
}
/** Matches using .equals(). */
- private static final class StringEqualityMatcher implements ObjectMatcher<String> {
+ private static final class StringEqualityMatcher implements Predicate<String> {
private final String pattern;
StringEqualityMatcher(String pattern) {
@@ -1161,13 +1177,13 @@
}
@Override
- public boolean matches(String value) {
+ public boolean test(String value) {
return pattern.equals(value);
}
}
/** Matches skeleton strings. Computes the pattern skeleton only once. */
- private static final class NameMatcher implements ObjectMatcher<String> {
+ private static final class NameMatcher implements Predicate<String> {
private final String pattern;
private final String skeleton;
@@ -1177,19 +1193,18 @@
}
@Override
- public boolean matches(String value) {
+ public boolean test(String value) {
return pattern.equals(value) || skeleton.equals(toSkeleton(value));
}
}
private static final NameMatcher YES_MATCHER = new NameMatcher("Yes");
- public interface PatternMatcher extends ObjectMatcher {
- public PatternMatcher set(String pattern);
+ public interface PatternMatcher extends Predicate {
+ PatternMatcher set(String pattern);
}
- public static class InversePatternMatcher extends InverseMatcher implements
- PatternMatcher {
+ public static class InversePatternMatcher implements PatternMatcher {
PatternMatcher other;
public PatternMatcher set(PatternMatcher toInverse) {
@@ -1197,10 +1212,12 @@
return this;
}
- public boolean matches(Object value) {
- return !other.matches(value);
+ @Override
+ public boolean test(Object value) {
+ return !other.test(value);
}
+ @Override
public PatternMatcher set(String pattern) {
other.set(pattern);
return this;
@@ -1217,12 +1234,14 @@
this.pattern = pattern;
}
- public boolean matches(Object value) {
+ @Override
+ public boolean test(Object value) {
if (comparator == null)
return pattern.equals(value);
return comparator.compare(pattern, value) == 0;
}
+ @Override
public PatternMatcher set(String pattern) {
this.pattern = pattern;
return this;
@@ -1232,12 +1251,14 @@
public static class RegexMatcher implements UnicodeProperty.PatternMatcher {
private java.util.regex.Matcher matcher;
+ @Override
public UnicodeProperty.PatternMatcher set(String pattern) {
matcher = Pattern.compile(pattern).matcher("");
return this;
}
UFormat foo;
- public boolean matches(Object value) {
+ @Override
+ public boolean test(Object value) {
matcher.reset(value.toString());
return matcher.find();
}
@@ -1251,7 +1272,7 @@
private static final String[] YES_VALUES = {"Yes", "Y", "T", "True"};
/**
- *
+ *
*/
private static final String[][] YES_NO_ALIASES = new String[][] {YES_VALUES, NO_VALUES};
@@ -1274,10 +1295,12 @@
return this;
}
+ @Override
public String _getVersion() {
return version;
}
+ @Override
public List _getNameAliases(List result) {
addAllUnique(propertyAliases, result);
return result;
@@ -1303,7 +1326,7 @@
switch(aliasAddAction) {
case IGNORE_IF_MISSING: return;
case REQUIRE_MAIN_ALIAS: throw new IllegalArgumentException("Can't add alias for mising value: " + value);
- case ADD_MAIN_ALIAS:
+ case ADD_MAIN_ALIAS:
toValueAliases.put(value, result = new ArrayList(0));
break;
}
@@ -1312,6 +1335,7 @@
addUnique(valueAlias, result);
}
+ @Override
protected List _getValueAliases(String valueAlias, List result) {
if (toValueAliases == null)
_fixValueAliases();
@@ -1362,6 +1386,7 @@
public static abstract class SimpleProperty extends BaseProperty {
LinkedHashSet values;
+ @Override
public UnicodeProperty addName(String alias) {
propertyAliases.add(alias);
return this;
@@ -1398,6 +1423,7 @@
return this;
}
+ @Override
public List _getAvailableValues(List result) {
if (values == null)
_fillValues();
@@ -1458,6 +1484,7 @@
*/
protected UnicodeMap unicodeMap;
+ @Override
protected UnicodeMap _getUnicodeMap() {
return unicodeMap;
}
@@ -1467,6 +1494,7 @@
return this;
}
+ @Override
protected String _getValue(int codepoint) {
return (String) unicodeMap.getValue(codepoint);
}
@@ -1476,7 +1504,8 @@
result.add(valueAlias);
return result; // no other aliases
}
- */protected List _getAvailableValues(List result) {
+ */@Override
+ protected List _getAvailableValues(List result) {
unicodeMap.getAvailableValues(result);
if (toValueAliases != null) {
for (Object s : toValueAliases.keySet()) {
@@ -1493,7 +1522,7 @@
if (isType(STRING_OR_MISC_MASK)) {
return true;
}
- Collection<String> values = (Collection<String>) getAvailableValues();
+ Collection<String> values = getAvailableValues();
for (String valueAlias : values) {
if (UnicodeProperty.compareNames(valueAlias, propertyValue) == 0) {
return true;
@@ -1512,7 +1541,7 @@
if (isType(STRING_OR_MISC_MASK)) {
return result;
}
- Collection<String> values = (Collection<String>) getAvailableValues();
+ Collection<String> values = getAvailableValues();
for (String valueAlias : values) {
UnicodeProperty.addAllUnique(getValueAliases(valueAlias), result);
}
@@ -1583,7 +1612,7 @@
return equals(cp, value);
}
String defaultValue = getValue(getSAMPLE_UNASSIGNED());
- return defaultValue == null ? value == null : defaultValue.equals(value);
+ return defaultValue == null ? value == null : defaultValue.equals(value);
}
public boolean hasUniformUnassigned() {
@@ -1609,10 +1638,12 @@
return set(new UnicodeSet(string).freeze());
}
+ @Override
protected String _getValue(int codepoint) {
return YESNO_ARRAY[unicodeSet.contains(codepoint) ? 0 : 1];
}
+ @Override
protected List _getAvailableValues(List result) {
return YESNO;
}
diff --git a/tools/java/org/unicode/cldr/util/props/UnicodePropertySymbolTable.java b/tools/java/org/unicode/cldr/util/props/UnicodePropertySymbolTable.java
index f4cd9b2..91bb317 100644
--- a/tools/java/org/unicode/cldr/util/props/UnicodePropertySymbolTable.java
+++ b/tools/java/org/unicode/cldr/util/props/UnicodePropertySymbolTable.java
@@ -23,7 +23,7 @@
* Unassigned characters (gc=Cn) are different than in ICU other than in ICU, you MUST call
* {@code UnicodeProperty.ResetCacheProperties} afterwards. If you then call {@code UnicodeSet.setDefaultXSymbolTable}
* with null to clear the value, you MUST also call {@code UnicodeProperty.ResetCacheProperties}.
- *
+ *
* @author markdavis
*/
public class UnicodePropertySymbolTable extends UnicodeSet.XSymbolTable {
@@ -44,11 +44,12 @@
// String[] propertyNames = propertyName.split("[*]");
// for (int i = propertyNames.length - 1; i >= 0; ++i) {
// String pname = propertyNames[i];
- //
+ //
// }
// return null;
// }
+ @Override
public boolean applyPropertyAlias(String propertyName,
String propertyValue, UnicodeSet result) {
boolean status = false;
@@ -59,7 +60,7 @@
if (posNotEqual < 0) posNotEqual = propertyName.length();
if (posColon < 0) posColon = propertyName.length();
int opPos = posNotEqual < posColon ? posNotEqual : posColon;
- propertyValue = propertyValue.length() == 0 ? propertyName.substring(opPos+1)
+ propertyValue = propertyValue.length() == 0 ? propertyName.substring(opPos+1)
: propertyName.substring(opPos+1) + "=" + propertyValue;
propertyName = propertyName.substring(0,opPos);
if (posNotEqual < posColon) {
@@ -76,15 +77,15 @@
} else {
try {
status = applyPropertyAlias0("gc", propertyName, result);
- } catch (Exception e) {};
+ } catch (Exception e) {}
if (!status) {
try {
status = applyPropertyAlias0("sc", propertyName, result);
- } catch (Exception e) {};
+ } catch (Exception e) {}
if (!status) {
try {
status = applyPropertyAlias0(propertyName, "Yes", result);
- } catch (Exception e) {};
+ } catch (Exception e) {}
if (!status) {
status = applyPropertyAlias0(propertyName, "", result);
}
@@ -101,30 +102,30 @@
{
GC_REMAP.put("c", "Cc Cf Cn Co Cs".split(" "));
GC_REMAP.put("other", GC_REMAP.get("c"));
-
+
GC_REMAP.put("l", "Ll Lm Lo Lt Lu".split(" "));
GC_REMAP.put("letter", GC_REMAP.get("l"));
-
+
GC_REMAP.put("lc", "Ll Lt Lu".split(" "));
GC_REMAP.put("casedletter", GC_REMAP.get("lc"));
-
+
GC_REMAP.put("m", "Mc Me Mn".split(" "));
GC_REMAP.put("mark", GC_REMAP.get("m"));
-
+
GC_REMAP.put("n", "Nd Nl No".split(" "));
GC_REMAP.put("number", GC_REMAP.get("n"));
-
+
GC_REMAP.put("p", "Pc Pd Pe Pf Pi Po Ps".split(" "));
GC_REMAP.put("punctuation", GC_REMAP.get("p"));
GC_REMAP.put("punct", GC_REMAP.get("p"));
-
+
GC_REMAP.put("s", "Sc Sk Sm So".split(" "));
GC_REMAP.put("symbol", GC_REMAP.get("s"));
-
+
GC_REMAP.put("z", "Zl Zp Zs".split(" "));
GC_REMAP.put("separator", GC_REMAP.get("z"));
}
-
+
public boolean applyPropertyAlias0(String propertyName,
String propertyValue, UnicodeSet result) {
result.clear();
@@ -191,7 +192,7 @@
set = new UnicodeSet();
List<String> values = prop.getAvailableValues();
for (String value : values) {
- if (patternMatcher.matches(value)) {
+ if (patternMatcher.test(value)) {
for (String other : values) {
if (other.compareTo(value) <= 0) {
set.addAll(prop.getSet(other));
@@ -208,7 +209,7 @@
throw new IllegalArgumentException("Illegal property: " + propertyName);
}
-
+
private boolean isValid(UnicodeProperty prop, String propertyValue) {
// if (prop.getName().equals("General_Category")) {
@@ -234,7 +235,8 @@
this.comparator = comparator;
}
- public boolean matches(Object value) {
+ @Override
+ public boolean test(Object value) {
int comp = comparator.compare(pattern, value.toString());
switch (relation) {
case less: return comp < 0;
@@ -245,12 +247,13 @@
}
}
+ @Override
public PatternMatcher set(String pattern) {
this.pattern = pattern;
return this;
}
}
-
+
/**
* Special parser for doubles. Anything not parsable is higher than everything else.
*/
@@ -272,11 +275,11 @@
if (Double.isNaN(d1) || Double.isNaN(d2)) {
throw new IllegalArgumentException();
}
-
- return d1 > d2 ? 1
+
+ return d1 > d2 ? 1
: d1 < d2 ? -1
: 0;
}
-
+
};
}
diff --git a/tools/java/pom.xml b/tools/java/pom.xml
new file mode 100644
index 0000000..f604b6a
--- /dev/null
+++ b/tools/java/pom.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>cldr</artifactId>
+
+ <name>CLDR Java Tools</name>
+
+ <url>https://unicode.org/cldr</url>
+
+ <properties>
+ <mainClass>org.unicode.cldr.tool.Main</mainClass>
+ </properties>
+
+ <scm>
+ <connection>scm:git:https://github.com/unicode-org/cldr.git</connection>
+ </scm>
+
+ <parent>
+ <groupId>org.unicode.cldr</groupId>
+ <artifactId>cldr-all</artifactId>
+ <version>38.0-SNAPSHOT</version>
+ </parent>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>icu4j-for-cldr</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>utilities-for-cldr</artifactId>
+ </dependency>
+
+ <!-- test -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.myanmartools</groupId>
+ <artifactId>myanmar-tools</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <testSourceDirectory>${project.basedir}/../cldr-unittest/src</testSourceDirectory>
+ <sourceDirectory>.</sourceDirectory> <!-- TODO: fix by refactoring source dirs, CLDR-11585 -->
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>org/unicode/cldr/icu/*.html</include>
+ <include>org/unicode/cldr/icu/*.txt</include>
+ <include>org/unicode/cldr/json/*.txt</include>
+ <include>org/unicode/cldr/tool/*.css</include>
+ <include>org/unicode/cldr/tool/*.html</include>
+ <include>org/unicode/cldr/tool/*.txt</include>
+ <include>org/unicode/cldr/tool/*.xml</include>
+ <include>org/unicode/cldr/util/data/**/*</include>
+ </includes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>${project.basedir}/../cldr-unittest/src</directory>
+ <includes>
+ <include>org/unicode/cldr/unittest/*.txt</include>
+ <include>org/unicode/cldr/unittest/data/**/*</include>
+ </includes>
+ </testResource>
+ </testResources>
+
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <!-- TODO: fix by refactoring source dirs, CLDR-11585 -->
+ <includes>
+ <include>com/**/*.java</include>
+ <include>org/**/*.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>${mainClass}</mainClass>
+ </manifest>
+ <manifestEntries>
+ <Built-By>${user.name}</Built-By>
+ <Build-Time>${maven.build.timestamp}</Build-Time>
+ <CLDR-Tools-Git-Commit>${buildNumber}</CLDR-Tools-Git-Commit>
+ <CLDR-Tools-Git-Branch>${scmBranch}</CLDR-Tools-Git-Branch>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>${mainClass}</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tools/pom.xml b/tools/pom.xml
new file mode 100644
index 0000000..f5a1b86
--- /dev/null
+++ b/tools/pom.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.unicode.cldr</groupId>
+ <artifactId>cldr-all</artifactId>
+ <version>38.0-SNAPSHOT</version>
+ <name>CLDR Parent</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ <!--
+ Note: see https://github.com/unicode-org/icu/packages/411079/versions for the
+ icu4j.version tag to use
+ -->
+ <icu4j.version>68.1-cldr-2020-10-21</icu4j.version>
+ <junit.version>4.13.1</junit.version>
+ <junit.jupiter.version>5.5.1</junit.jupiter.version>
+ <maven-surefire-plugin-version>2.22.1</maven-surefire-plugin-version>
+ <assertj-version>3.11.1</assertj-version>
+ </properties>
+
+ <modules>
+ <module>java</module>
+ <module>cldr-apps</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- CLDR -->
+ <dependency>
+ <groupId>org.unicode.cldr</groupId>
+ <artifactId>cldr</artifactId>
+ <version>${project.version}</version> <!-- this seems to work -->
+ </dependency>
+
+ <!-- ICU -->
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>icu4j-for-cldr</artifactId>
+ <version>${icu4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.ibm.icu</groupId>
+ <artifactId>utilities-for-cldr</artifactId>
+ <version>${icu4j.version}</version>
+ </dependency>
+
+ <!-- Misc Libs -->
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>29.0-jre</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.10.8</version>
+ </dependency>
+
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ <version>2.12.0</version>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>1.4.01</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.myanmartools</groupId>
+ <artifactId>myanmar-tools</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <!-- codec/util -->
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.9</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-fileupload</groupId>
+ <artifactId>commons-fileupload</artifactId>
+ <version>1.3.3</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+
+
+ <!-- API -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>javax.servlet.jsp-api</artifactId>
+ <version>2.3.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.3.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- mail / rss -->
+ <dependency>
+ <groupId>rome</groupId>
+ <artifactId>rome</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.5.0-b01</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.sun.activation</groupId>
+ <artifactId>javax.activation</artifactId>
+ <version>1.2.0</version>
+ </dependency>
+
+ <!-- https://mvnrepository.com/artifact/org.json/json -->
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20190722</version>
+ </dependency>
+
+ <!-- scm -->
+ <dependency>
+ <groupId>org.tmatesoft.svnkit</groupId>
+ <artifactId>svnkit</artifactId>
+ <version>1.7.4-v1</version>
+ </dependency>
+
+
+
+ <!-- db connectors -->
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.10.1.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>8.0.21</version>
+ </dependency>
+ <!-- test -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>${junit.jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>${junit.jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <repositories>
+ <repository>
+ <id>githubicu</id>
+ <name>GitHub unicode-org/icu Apache Maven Packages</name>
+ <url>https://maven.pkg.github.com/unicode-org/icu</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.1.0</version>
+ </plugin>
+ <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin-version}</version>
+ <configuration>
+ <systemPropertyVariables>
+ <CLDR_DIR>${project.basedir}/../../</CLDR_DIR> <!-- this is valid for tools/java and tools/cldr-apps-->
+ <CLDR_ENVIRONMENT>UNITTEST</CLDR_ENVIRONMENT>
+ <java.awt.headless>true</java.awt.headless>
+ </systemPropertyVariables>
+ <argLine>-Xmx6g -enableassertions</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>3.2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.3.0</version>
+ </plugin>
+ <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.7.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ <version>1.4</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <getRevisionOnlyOnce>true</getRevisionOnlyOnce>
+ <attach>true</attach>
+ <addOutputDirectoryToResources>true</addOutputDirectoryToResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/tools/scripts/ansible/.gitignore b/tools/scripts/ansible/.gitignore
new file mode 100644
index 0000000..a30471c
--- /dev/null
+++ b/tools/scripts/ansible/.gitignore
@@ -0,0 +1,3 @@
+/local-*
+/.vagrant
+/*.log
diff --git a/tools/scripts/ansible/README.md b/tools/scripts/ansible/README.md
new file mode 100644
index 0000000..dfd8eda
--- /dev/null
+++ b/tools/scripts/ansible/README.md
@@ -0,0 +1,147 @@
+# Ansible for Survey Tool
+
+These are ansible scripts for setup and maintenance of the Survey Tool.
+
+## Scope
+
+Right now, the test setup mostly controls Tomcat, but not the nginx proxy
+due to public port issues (https).
+
+## Setup
+
+### Setup: Control system
+
+This is your local system, where you control the others from.
+
+- Install Ansible <https://ansible.com>
+- Install some prereqs:
+
+```shell
+ansible-galaxy install -r roles.yml
+```
+
+- Make sure you can `ssh` into all of the needed systems. For example,
+`ssh cldr-ref.unicode.org` should succeed without needing a password.
+
+- You should be able to run `ansible all -m ping` and get something back
+like the following:
+
+```shell
+cldr-ref.unicode.org | SUCCESS => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": false,
+ "ping": "pong"
+}
+```
+
+### Setup: Managed systems
+
+- Install python3. Make sure `python --version`
+or `python3 --version` returns "Python 3…"
+
+- TODO: these shouldn't be needed, but they are. Here's the entire
+install command:
+
+```shell
+sudo apt-get update && sudo apt-get install python3 python-apt python3-pymysql
+```
+
+### Setup: surveytool keypair
+
+Create a RSA keypair with no password for the buildbot:
+
+```shell
+mkdir -p ./local-vars
+ssh-keygen -t rsa -b 4096 -f ./local-vars/surveytool -P '' -C 'surveytool deploy'
+```
+
+The contents of the `local-vars/surveytool.pub` file is used for the
+`key:` parameter below in `local.yml`. The `local-vars/surveytool`
+private key is used in the secret `RSA_KEY_SURVEYTOOL`.
+
+Then setup github secrets as shown:
+
+- `SMOKETEST_HOST` -
+ hostname of smoketest
+- `SMOKETEST_PORT` -
+ port of smoketest
+- `RSA_KEY_SURVEYTOOL` -
+ contents of `local-vars/surveytool` (the secret key)
+- `SMOKETEST_KNOWNHOSTS` -
+ run `ssh-keyscan smoketest.example.com` where _smoketest.example.com_
+ is the name of the smoketest server. Put the results into this
+ secret. One of these lines should match `~/.ssh/known_hosts` on your
+ own system when you ssh into smoketest.
+ Try `grep -i smoke ~/.ssh/known_hosts`
+
+Create a folder "cldrbackup" inside local-vars
+```shell
+mkdir -p ./local-vars/cldrbackup
+```
+
+Add three files inside local-vars/cldrbackup-vars: id_rsa, id_rsa.pub, and known_hosts. These must correspond to the public key for cldrbackup on corp.unicode.org. Copy existing versions if you have them. Otherwise, create new ones with `ssh-keygen -t rsa` and copy the public key to corp.unicode.org with `ssh-copy-id -i ~/.ssh/id_rsa [email protected]`
+
+### Setup: Config file
+
+- Create a file `local-vars/local.yml` matching the example values in [test-local-vars/local.yml](test-local-vars/local.yml) (but with a secure password instead of `hunter42`!.)
+
+```yaml
+mysql_users:
+ - name: surveytool
+ host: localhost
+ password: hunter42
+ priv: 'cldrdb.*:ALL'
+surveytooldeploy:
+ password: hunter43
+ vap: hunter44
+ testpw: hunter45
+ oldversion: 36
+ newversion: 37
+ key: ssh-rsa … ( SSH key goes here)
+```
+
+## Configure
+
+Run the setup playbook.
+
+```shell
+ansible-playbook --check setup-playbook.yml
+```
+
+This is in dry run mode. When it looks good to you, take the
+`--check` out and run it again.
+
+You can also use the `-l cldr-smoke.unicode.org` option to limit
+the operation to a single host.
+
+## Local Test
+
+- install vagrant and some provider such as virtualbox or libvirt
+
+```shell
+vagrant up
+```
+
+- To log into the new host, run `vagrant ssh`
+
+- To iterate, trying to reapply ansible, run `vagrant provision --provision-with=ansible`
+
+- to deploy ST to this, use the following:
+
+```shell
+(cd ../../cldr-apps ; ant war) # to build ST if not already built
+vagrant ssh -- sudo -u surveytool /usr/local/bin/deploy-to-tomcat.sh $(git rev-parse HEAD) < ../../cldr-apps/cldr-apps.war
+```
+
+- Now you should be able to login at <http://127.0.0.1:8880/cldr-apps/>
+
+- If you need to get directly to the tomcat server, use:
+
+```shell
+vagrant ssh -- -L 8080:127.0.0.1:8080
+# leave this shell window open.
+```
+
+Then, you can go to <http://127.0.0.1:8080> and directly access tomcat.
diff --git a/tools/scripts/ansible/Vagrantfile b/tools/scripts/ansible/Vagrantfile
new file mode 100644
index 0000000..7172fe9
--- /dev/null
+++ b/tools/scripts/ansible/Vagrantfile
@@ -0,0 +1,18 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure("2") do |config|
+ config.vm.box = "ubuntu/bionic64"
+ config.vm.define "surveytool"
+ config.vm.hostname = "surveytool"
+ # forward http and https
+ config.vm.network "forwarded_port", guest: 80, host: 8880
+ # Just the minimum to get ansible going
+ config.vm.provision "shell", inline: <<-SHELL
+ apt-get update
+ apt-get install -y python3 sudo
+ SHELL
+ config.vm.provision "ansible" do |ansible|
+ ansible.playbook = "setup-playbook.yml"
+ end
+end
diff --git a/tools/scripts/ansible/ansible.cfg b/tools/scripts/ansible/ansible.cfg
new file mode 100644
index 0000000..17abc8e
--- /dev/null
+++ b/tools/scripts/ansible/ansible.cfg
@@ -0,0 +1,3 @@
+[defaults]
+inventory = ./hosts
+deprecation_warnings=False
diff --git a/tools/scripts/ansible/backup-db-playbook.yml b/tools/scripts/ansible/backup-db-playbook.yml
new file mode 100644
index 0000000..c2d969a
--- /dev/null
+++ b/tools/scripts/ansible/backup-db-playbook.yml
@@ -0,0 +1,75 @@
+- hosts: backupdb
+ become: yes
+ vars_files:
+ - vars/main.yml
+ - local-vars/local.yml
+ tasks:
+ - name: ensure cldrbackup group is there
+ group:
+ name: cldrbackup
+ state: present
+ - name: ensure cldrbackup user is there
+ user:
+ name: cldrbackup
+ groups:
+ - cldrbackup
+ append: yes # add to the groups, do not remove
+ state: present
+ create_home: true
+ - name: set up /home/cldrbackup/.my.cnf
+ no_log: true
+ template:
+ src: templates/mycnf.j2
+ dest: /home/cldrbackup/.my.cnf
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up /home/cldrbackup/.ssh/
+ file:
+ path: /home/cldrbackup/.ssh/
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0700'
+ state: directory
+ - name: set up /home/cldrbackup/.ssh/config
+ template:
+ src: templates/cldrbackup/config.j2
+ dest: /home/cldrbackup/.ssh/config.j2
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up /home/cldrbackup/.ssh/id_rsa
+ no_log: true
+ copy:
+ src: local-vars/cldrbackup/id_rsa
+ dest: /home/cldrbackup/.ssh/id_rsa
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up /home/cldrbackup/.ssh/id_rsa.pub
+ copy:
+ src: local-vars/cldrbackup/id_rsa.pub
+ dest: /home/cldrbackup/.ssh/id_rsa.pub
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up /home/cldrbackup/.ssh/known_hosts
+ copy:
+ src: local-vars/cldrbackup/known_hosts
+ dest: /home/cldrbackup/.ssh/known_hosts
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up /home/cldrbackup/backup.sh
+ template:
+ src: templates/cldrbackup/backup_sh.j2
+ dest: /home/cldrbackup/.ssh/backup.sh
+ owner: cldrbackup
+ group: cldrbackup
+ mode: '0640'
+ - name: set up daily db backup cron job
+ cron:
+ name: "backup db"
+ minute: "37"
+ hour: "7"
+ job: "sh /home/cldrbackup/backup.sh >/dev/null 2>&1"
diff --git a/tools/scripts/ansible/hosts b/tools/scripts/ansible/hosts
new file mode 100644
index 0000000..6bbe1a4
--- /dev/null
+++ b/tools/scripts/ansible/hosts
@@ -0,0 +1,18 @@
+[staging]
+cldr-smoke.unicode.org
+
+[prod]
+st.unicode.org
+
+# "surveytool" includes both prod and staging
+[surveytool:children]
+staging
+prod
+
+# encrypt all of the surveytool hosts
+[letsencrypt:children]
+surveytool
+
+# auto-backup cldr db only for production
+[backupdb:children]
+prod
diff --git a/tools/scripts/ansible/requirements.yml b/tools/scripts/ansible/requirements.yml
new file mode 100644
index 0000000..c4e26ac
--- /dev/null
+++ b/tools/scripts/ansible/requirements.yml
@@ -0,0 +1,3 @@
+sprylab.tomcat-ubuntu
+geerlingguy.mysql
+derjd.journald
diff --git a/tools/scripts/ansible/roles.yml b/tools/scripts/ansible/roles.yml
new file mode 100644
index 0000000..b0db652
--- /dev/null
+++ b/tools/scripts/ansible/roles.yml
@@ -0,0 +1,8 @@
+- src: geerlingguy.mysql
+ version: 3.3.0
+- src: geerlingguy.nginx
+ version: 2.8.0
+- src: derjd.journald
+ version: 0.0.1
+# - src: geerlingguy.certbot
+# version: 3.1.0
\ No newline at end of file
diff --git a/tools/scripts/ansible/setup-playbook.yml b/tools/scripts/ansible/setup-playbook.yml
new file mode 100644
index 0000000..580ac0c
--- /dev/null
+++ b/tools/scripts/ansible/setup-playbook.yml
@@ -0,0 +1,201 @@
+- hosts: surveytool
+ become: yes
+ vars_files:
+ - vars/main.yml
+ - local-vars/local.yml
+ roles:
+ - { role: geerlingguy.mysql }
+ - { role: geerlingguy.nginx }
+ tasks:
+ - name: Install server packages
+ apt:
+ pkg:
+ - tomcat8
+ - tomcat8-admin # needed for deploy
+ - unzip # needed for deploy
+ # for monitoring
+ - prometheus-mysqld-exporter
+ # - prometheus-nginx-exporter # (not there yet)
+ - name: Setup Server Context
+ template:
+ src: templates/context.j2
+ dest: /etc/tomcat8/context.xml
+ owner: root
+ group: tomcat8
+ mode: '0640'
+ notify: Restart Tomcat
+ - name: Setup tomcat8/server.xml
+ copy:
+ src: templates/server.xml
+ dest: /etc/tomcat8/server.xml
+ owner: root
+ group: tomcat8
+ mode: '0640'
+ notify: Restart Tomcat
+ - name: Setup Server Users
+ template:
+ src: templates/users.j2
+ dest: /etc/tomcat8/tomcat-users.xml
+ owner: root
+ group: tomcat8
+ mode: '0640'
+ notify: Restart Tomcat
+ - name: Create CLDR dir
+ file:
+ path: /var/lib/tomcat8/cldr
+ state: directory
+ owner: tomcat8
+ group: tomcat8
+ mode: 0775
+ - name: Create cldr.properties
+ template:
+ dest: /var/lib/tomcat8/cldr/cldr.properties
+ src: templates/cldr-properties.j2
+ force: no
+ owner: tomcat8
+ group: tomcat8
+ mode: "0644"
+ notify: Restart Tomcat
+ - name: Checkout CLDR trunk
+ git:
+ repo: https://github.com/unicode-org/cldr.git
+ dest: /var/lib/tomcat8/cldr/cldr-trunk
+ force: no
+ update: no
+ version: master
+ # this is deep because we will need to keep updating
+ # it with history. It does not include LFS as that
+ # is not needed for the surveytool.
+ - name: Setup index.html
+ copy:
+ src: templates/index.html
+ dest: /var/www/html
+ owner: root
+ group: root
+ mode: '0644'
+ - name: Setup reverse proxy
+ blockinfile:
+ path: /etc/nginx/sites-enabled/default
+ block: |
+ # proxy /cldr-apps/ to tomcat
+ location /cldr-apps/ {
+ rewrite ^/(.+)\._[\da-f]+_\.(js|css)$ /$1.$2 break;
+ allow all;
+ proxy_pass http://localhost:8080/cldr-apps/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ }
+ marker: '# {mark} ANSIBLE MANAGED BLOCK'
+ insertafter: '^[\s]*server_name' # the LAST uncommented server block
+ notify: 'Restart Nginx'
+ - name: Setup surveytool user for deploy
+ user:
+ name: surveytool
+ shell: /bin/bash
+ - name: Give access to surveytool user
+ file:
+ path: /var/lib/tomcat8/cldr/cldr-trunk
+ owner: surveytool
+ recurse: yes
+ - name: Setup surveytool auth
+ authorized_key:
+ user: surveytool
+ key: '{{ surveytooldeploy.key }}'
+ - name: Setup deploy-to-tomcat.sh
+ template:
+ src: templates/deploy-sh.j2
+ dest: /usr/local/bin/deploy-to-tomcat.sh
+ owner: root
+ group: root
+ mode: '0755'
+ - name: ensure cldradmin group is there
+ group:
+ name: cldradmin
+ state: present
+ - name: ensure cldradmin user is there
+ user:
+ name: cldradmin
+ comment: CLDR Admin
+ groups:
+ - cldradmin
+ append: yes # add to the groups, do not remove
+ state: present
+ create_home: true
+ - name: Setup /home/cldradmin/.my.cnf
+ template:
+ src: templates/mycnf.j2
+ dest: /home/cldradmin/.my.cnf
+ owner: cldradmin
+ group: cldradmin
+ mode: '0640'
+ - name: make sure /home/cldradmin/.ssh/ exists
+ file:
+ path: /home/cldradmin/.ssh/
+ owner: cldradmin
+ group: cldradmin
+ mode: '0700'
+ state: directory
+ - name: make sure /home/cldradmin/.ssh/authorized_keys exists
+ file:
+ dest: /home/cldradmin/.ssh/authorized_keys
+ owner: cldradmin
+ group: cldradmin
+ mode: '0600'
+ state: touch #https://github.com/ansible/ansible/issues/7490#issuecomment-497373505
+ modification_time: preserve
+ access_time: preserve
+ - name: add cldradmin to sudoers
+ template:
+ dest: /etc/sudoers.d/55-cldradmin-users
+ owner: root
+ group: root
+ mode: '440'
+ src: templates/55-cldradmin.conf
+ handlers:
+ - name: Restart Tomcat
+ service:
+ name: tomcat8
+ state: restarted
+ - name: Restart Nginx
+ service:
+ name: nginx
+ state: restarted
+
+- hosts: all
+ become: yes
+ roles:
+ - role: derJD.journald
+ vars:
+ journald_options:
+ SystemMaxUse: 512M #reduce logfile use
+ tasks:
+ - name: Install some packages
+ apt:
+ pkg:
+ # these are for convenience of the user
+ - mosh
+ - emacs-nox
+ - byobu
+ # these are for monitoring
+ - prometheus-node-exporter
+
+- hosts: letsencrypt
+ become: yes
+ vars_files:
+ - vars/main.yml
+ - local-vars/local.yml
+ tasks:
+ - name: Install certbot packages
+ apt:
+ pkg:
+ - python3-certbot-nginx
+ - name: setup certbot
+ command: >
+ sudo certbot --nginx --agree-tos -m {{ certbot_admin_email }}
+ -d {{ inventory_hostname }} --non-interactive
+ --keep --redirect --uir --hsts --staple-ocsp --must-staple
+ args:
+ creates: /etc/letsencrypt/renewal/{{ inventory_hostname }}.conf
+
+- import_playbook: backup-db-playbook.yml
diff --git a/tools/scripts/ansible/templates/55-cldradmin.conf b/tools/scripts/ansible/templates/55-cldradmin.conf
new file mode 100644
index 0000000..933a1e2
--- /dev/null
+++ b/tools/scripts/ansible/templates/55-cldradmin.conf
@@ -0,0 +1,2 @@
+# managed by ansible setup-playbook.yml
+cldradmin ALL=(ALL) NOPASSWD:ALL
diff --git a/tools/scripts/ansible/templates/cldr-properties.j2 b/tools/scripts/ansible/templates/cldr-properties.j2
new file mode 100644
index 0000000..8124458
--- /dev/null
+++ b/tools/scripts/ansible/templates/cldr-properties.j2
@@ -0,0 +1,32 @@
+CLDR_MAINTENANCE=false
+
+## your password. Login as user 'admin@' and this password for admin access.
+CLDR_VAP={{ surveytooldeploy.vap }}
+
+## Special Test Enablement.
+CLDR_TESTPW={{ surveytooldeploy.testpw }}
+
+## Special message shown to users as to why survey tool is down.
+## Comment out for normal start-up.
+#CLDR_MESSAGE=
+
+## Special message shown to users.
+CLDR_HEADER=Welcome to SurveyTool@surveytool. Please edit /var/lib/tomcat8/cldr/cldr.properties to change CLDR_HEADER (to change this message), or comment it out entirely. Also see /var/lib/tomcat8/cldr/admin.html to get to the admin panel.
+
+## Current SurveyTool phase
+CLDR_PHASE=BETA
+
+## 'old' (previous) version
+CLDR_OLDVERSION={{ surveytooldeploy.oldversion }}
+
+## 'new' version
+CLDR_NEWVERSION={{ surveytooldeploy.newversion }}
+
+## Current SurveyTool phase
+CLDR_PHASE=BETA
+
+## CLDR trunk. Default value shown
+CLDR_DIR=/var/lib/tomcat8/cldr/cldr-trunk
+
+## SMTP server. Mail is disabled by default.
+#CLDR_SMTP=127.0.0.1
diff --git a/tools/scripts/ansible/templates/cldrbackup/backup_sh.j2 b/tools/scripts/ansible/templates/cldrbackup/backup_sh.j2
new file mode 100644
index 0000000..33e85cf
--- /dev/null
+++ b/tools/scripts/ansible/templates/cldrbackup/backup_sh.j2
@@ -0,0 +1,13 @@
+#!/bin/bash
+#
+# A cron job may call this with a line such as:
+# 37 7 * * * sh /home/cldrbackup/backup.sh >/dev/null 2>&1
+
+DATABASE_NAME={{ cldr_database_name }}
+FNAME={{ cldr_database_name }}-DUMP-`date +%Y-%m-%d`
+RSYNC_DEST={{ cldr_db_backup_destination }}
+
+cd /home/cldrbackup
+mysqldump ${DATABASE_NAME} --add-drop-table --create-options --default-character-set=utf8mb4 > ${FNAME}.sql
+xz ${FNAME}.sql
+rsync -q ${FNAME}.sql.xz ${RSYNC_DEST}
diff --git a/tools/scripts/ansible/templates/cldrbackup/config.j2 b/tools/scripts/ansible/templates/cldrbackup/config.j2
new file mode 100644
index 0000000..ed38142
--- /dev/null
+++ b/tools/scripts/ansible/templates/cldrbackup/config.j2
@@ -0,0 +1,3 @@
+Host {{ cldr_db_backup_host }}
+ User {{ cldr_db_backup_user }}
+ IdentityFile ~/.ssh/id_rsa
diff --git a/tools/scripts/ansible/templates/context.j2 b/tools/scripts/ansible/templates/context.j2
new file mode 100644
index 0000000..dbe5e51
--- /dev/null
+++ b/tools/scripts/ansible/templates/context.j2
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context>
+<WatchedResource>WEB-INF/web.xml</WatchedResource>
+<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
+<Resource name="jdbc/SurveyTool"
+ auth="Container" type="javax.sql.DataSource"
+ username="surveytool"
+ driverClassName="com.mysql.jdbc.Driver"
+ password="{{ mysql_users[0].password }}"
+ url="jdbc:mysql://localhost:3306/cldrdb?ConnectionRetryCount=5&ConnectionRetryDelay=20&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC"
+ maxActive="8" maxIdle="4" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" defaultAutoCommit="false"
+ poolPreparedStatements="true" maxOpenPreparedStatements="150"
+/>
+</Context>
\ No newline at end of file
diff --git a/tools/scripts/ansible/templates/deploy-sh.j2 b/tools/scripts/ansible/templates/deploy-sh.j2
new file mode 100644
index 0000000..2881e74
--- /dev/null
+++ b/tools/scripts/ansible/templates/deploy-sh.j2
@@ -0,0 +1,64 @@
+#!/bin/bash
+# Note: this is managed by Ansible, as deploy-sh.j2
+# Don't modify this file.
+GITHUB_SHA=$1
+UNLOCK=$2
+WORKDIR=${TMPDIR-/tmp} # keep all random files here
+export TPASS={{ surveytooldeploy.password }} # from surveytooldeploy.password
+export TUSER=surveytooldeploy # fixed for now
+
+dogit() {
+ rm -f ${WORKDIR}/git-list.txt
+ if [[ ${GITHUB_SHA} = "master" ]];
+ then
+ echo "changing 'master' to 'origin/master' to get the latest"
+ GITHUB_SHA=origin/master
+ fi
+ git fetch -p || exit 1
+ git clean -f -d || echo 'warning: err on cleanup'
+ # what are we deploying?
+
+ echo "cldr-trunk was at :" $(git rev-parse --short HEAD)
+ echo -n "you want to move to:"
+ git rev-parse --short "${GITHUB_SHA}" || exit 1 # fail on err
+ if [[ $(git rev-parse --short HEAD) = $(git rev-parse --short "${GITHUB_SHA}") ]];
+ then
+ echo "No checkout needed. Continuing with redeploy."
+ else
+ echo "Deploy will include these new items:"
+ echo "---"
+ (git log --oneline HEAD..${GITHUB_SHA} | tee ${WORKDIR}/git-list.txt) || exit 1
+ echo "---"
+ if [[ ! -s ${WORKDIR}/git-list.txt ]]; # if empty..
+ then
+ echo "Note, ${GITHUB_SHA} is not ahead of HEAD" $(git rev-parse --short HEAD)
+ echo "Checking for items that would be REVERTED if we proceed:"
+ echo "---"
+ git log --oneline ${GITHUB_SHA}..HEAD
+ echo "---"
+ if [[ "${UNLOCK}" = "--override" ]];
+ then
+ echo ".. continuing anyway! due to " "${UNLOCK}"
+ else
+ echo "STOP. Check the override box if you really want to do this"
+ exit 1
+ fi
+ fi
+ git checkout -f ${GITHUB_SHA}
+ echo "HEAD is now at" $(git rev-parse --short HEAD) "!"
+ fi
+}
+
+# Check git first, before undeploying. Want to exit early
+(cd /var/lib/tomcat8/cldr/cldr-trunk/ && dogit ) || exit 1
+# undeploy old ST
+curl -u ${TUSER}:${TPASS} 'http://localhost:8080/manager/text/undeploy?path=/cldr-apps'
+# reset last deploy status
+rm -fv ${WORKDIR}/cldr-apps.war ${WORKDIR}/deploystatus
+# copy cldr-apps.war from action runner to server
+dd bs=1024000 status=progress of=${WORKDIR}/cldr-apps.war
+# this counts the # of files to make sure it's not too short, but also verifies that unzip is OK
+echo ; echo -n 'Unzip check, # of files in cldr-apps.war: '
+(unzip -l ${WORKDIR}/cldr-apps.war | wc -l ) || exit 1
+# Now, do the deployment!
+curl -q -u ${TUSER}:${TPASS} 'http://localhost:8080/manager/text/deploy?path=/cldr-apps&tag=cldr-apps&update=true' -T ${WORKDIR}/cldr-apps.war | tee ${WORKDIR}/deploystatus
diff --git a/tools/scripts/ansible/templates/index.html b/tools/scripts/ansible/templates/index.html
new file mode 100644
index 0000000..6141ed1
--- /dev/null
+++ b/tools/scripts/ansible/templates/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset='utf-8'>
+ <meta http-equiv="refresh" content="0; url=./cldr-apps/v" />
+ <title>CLDR Survey Tool</title>
+</head>
+<body>
+ Redirecting to CLDR Survey Tool (cldr-apps/v)...
+</body>
+</html>
diff --git a/tools/scripts/ansible/templates/mycnf.j2 b/tools/scripts/ansible/templates/mycnf.j2
new file mode 100644
index 0000000..3fd9c7f
--- /dev/null
+++ b/tools/scripts/ansible/templates/mycnf.j2
@@ -0,0 +1,5 @@
+# managed by ansible setup-playboook.yml
+[client]
+user=cldradmin
+database={{ cldr_database_name }}
+password={{ cldradmin_pw }}
diff --git a/tools/scripts/ansible/templates/server.xml b/tools/scripts/ansible/templates/server.xml
new file mode 100644
index 0000000..f58cdd8
--- /dev/null
+++ b/tools/scripts/ansible/templates/server.xml
@@ -0,0 +1,145 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Note: A "Server" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/server.html
+ -->
+<Server address="127.0.0.1" port="8005" shutdown="SHUTDOWN">
+ <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
+ <!-- Security listener. Documentation at /docs/config/listeners.html
+ <Listener className="org.apache.catalina.security.SecurityListener" />
+ -->
+ <!--APR library loader. Documentation at /docs/apr.html -->
+ <!--
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+ -->
+ <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+ <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+ <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
+
+ <!-- Global JNDI resources
+ Documentation at /docs/jndi-resources-howto.html
+ -->
+ <GlobalNamingResources>
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users
+ -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" Note: A "Service" is not itself a "Container",
+ so you may not define subcomponents such as "Valves" at this level.
+ Documentation at /docs/config/service.html
+ -->
+ <Service name="Catalina">
+
+ <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+ <!--
+ <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
+ maxThreads="150" minSpareThreads="4"/>
+ -->
+
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Documentation at :
+ Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
+ Java AJP Connector: /docs/config/ajp.html
+ APR (HTTP/AJP) Connector: /docs/apr.html
+ Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
+ -->
+ <Connector address="127.0.0.1" port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ URIEncoding="UTF-8"
+ redirectPort="8443" />
+ <!-- A "Connector" using the shared thread pool-->
+ <!--
+ <Connector executor="tomcatThreadPool"
+ address="127.0.0.1" port="8080" protocol="HTTP/1.1"
+ connectionTimeout="20000"
+ redirectPort="8443" />
+ -->
+ <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
+ This connector uses the NIO implementation that requires the JSSE
+ style configuration. When using the APR/native implementation, the
+ OpenSSL style configuration is required as described in the APR/native
+ documentation -->
+ <!--
+ <Connector address="127.0.0.1" port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
+ maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port 8009 -->
+ <Connector address="127.0.0.1" port="8009" protocol="AJP/1.3" redirectPort="8443" />
+
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host).
+ Documentation at /docs/config/engine.html -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!--For clustering, please take a look at documentation at:
+ /docs/cluster-howto.html (simple how to)
+ /docs/config/cluster.html (reference documentation) -->
+ <!--
+ <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
+ -->
+
+ <!-- Use the LockOutRealm to prevent attempts to guess user passwords
+ via a brute-force attack -->
+ <Realm className="org.apache.catalina.realm.LockOutRealm">
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+ </Realm>
+
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="true">
+
+ <!-- SingleSignOn valve, share authentication between web applications
+ Documentation at: /docs/config/valve.html -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all example.
+ Documentation at: /docs/config/valve.html
+ Note: The pattern used is equivalent to using pattern="common" -->
+ <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
+ prefix="localhost_access_log" suffix=".txt"
+ pattern="%h %l %u %t "%r" %s %b" />
+
+ </Host>
+ </Engine>
+ </Service>
+</Server>
diff --git a/tools/scripts/ansible/templates/users.j2 b/tools/scripts/ansible/templates/users.j2
new file mode 100644
index 0000000..11496eb
--- /dev/null
+++ b/tools/scripts/ansible/templates/users.j2
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tomcat-users xmlns="http://tomcat.apache.org/xml"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
+ version="1.0">
+<!-- user for deploying cldr-apps -->
+<user username="surveytooldeploy" password="{{ surveytooldeploy.password }}" roles="standard,manager-script" />
+</tomcat-users>
\ No newline at end of file
diff --git a/tools/scripts/ansible/test-local-vars/local.yml b/tools/scripts/ansible/test-local-vars/local.yml
new file mode 100644
index 0000000..22004a4
--- /dev/null
+++ b/tools/scripts/ansible/test-local-vars/local.yml
@@ -0,0 +1,24 @@
+# these are used for CI testing
+# and, they also serve as an example of how to
+# configure local-vars/local.yml
+
+cldradmin_pw: hunter46 # needs to match cldradmin pw below
+mysql_users:
+ # this is the account used by the survey tool itself
+ - name: surveytool
+ host: localhost
+ password: hunter42
+ priv: 'cldrdb.*:ALL'
+ # this is the account used for administrative tasks
+ - name: cldradmin
+ password: hunter46
+ priv: 'cldrdb.*:ALL/*.*:PROCESS'
+ append_privs: yes
+# this is the account used for deployment
+surveytooldeploy:
+ password: hunter43
+ vap: hunter44
+ testpw: hunter45
+ oldversion: 36
+ newversion: 37
+ key: ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ5TcIs3HNzv6PIlkJVifUTaWj8CEJmLngvE45F/sL4+oHdOSBHyG/rU04psIuvDjukrQY8a0ZhohGkpcwl1WIY= dummy value just for test
diff --git a/tools/scripts/ansible/upgrade-playbook.yml b/tools/scripts/ansible/upgrade-playbook.yml
new file mode 100644
index 0000000..859e857
--- /dev/null
+++ b/tools/scripts/ansible/upgrade-playbook.yml
@@ -0,0 +1,7 @@
+# A playbook for upgrading packages
+- hosts: all
+ become: yes
+ tasks:
+ - name: Update all packages to the latest version
+ apt:
+ upgrade: dist
diff --git a/tools/scripts/ansible/vars/main.yml b/tools/scripts/ansible/vars/main.yml
new file mode 100644
index 0000000..2655aa3
--- /dev/null
+++ b/tools/scripts/ansible/vars/main.yml
@@ -0,0 +1,11 @@
+cldr_database_name: cldrdb
+cldr_db_backup_host: corp.unicode.org
+cldr_db_backup_user: cldrbackup
+cldr_db_backup_destination: "{{ cldr_db_backup_host }}:/home/users/{{ cldr_db_backup_user }}"
+mysql_databases:
+ - name: "{{ cldr_database_name }}"
+ encoding: latin1
+ collation: latin1_bin
+mysql_enabled_on_startup: true
+mysql_bind_address: localhost
+ansible_python_interpreter: python3
diff --git a/tools/st-prom-exporter/.gitignore b/tools/st-prom-exporter/.gitignore
new file mode 100644
index 0000000..c01727e
--- /dev/null
+++ b/tools/st-prom-exporter/.gitignore
@@ -0,0 +1,2 @@
+/node_modules
+/config.json
diff --git a/tools/st-prom-exporter/README.md b/tools/st-prom-exporter/README.md
new file mode 100644
index 0000000..086ef38
--- /dev/null
+++ b/tools/st-prom-exporter/README.md
@@ -0,0 +1,32 @@
+# Prom exporter for SurveyTool
+
+What is this? An exporter for <https://prometheus.io> that reads from the
+Survey Tool.
+
+## Config/Installation
+
+1. `npm i`
+
+2. setup `config.json` as below:
+
+```json
+{
+ "instances": {
+ "cldr-smoke.unicode.org": "https://cldr-smoke.unicode.org/cldr-apps/SurveyAjax?what=status",
+ "st.unicode.org": "https://st.unicode.org/cldr-apps/SurveyAjax?what=status"
+ },
+ "port": 9099
+}
+```
+
+3. `node index.js`
+
+Now, the exporter is listening on port 9099 and re-exporting ST metrics as Prometheus metrics.
+
+## License and Copyright
+
+©2020 Unicode, Inc. All Rights Reserved.
+
+For license and copyright see
+https://www.unicode.org/copyright.html
+or [../../unicode-license.txt](../../unicode-license.txt)
\ No newline at end of file
diff --git a/tools/st-prom-exporter/index.js b/tools/st-prom-exporter/index.js
new file mode 100644
index 0000000..d37c24d
--- /dev/null
+++ b/tools/st-prom-exporter/index.js
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2929, Unicode, Inc.
+ * For terms of use, see http://www.unicode.org/terms_of_use.html
+ */
+
+const express = require('express');
+const process = require('process');
+const server = express();
+const client = require('prom-client');
+const bent = require('bent');
+const getJson = bent('json');
+const config = require('./config.json');
+const {register} = client; // global registry
+
+const items = {
+ responses: new client.Counter({
+ name: 'surveytool_exporter_responses',
+ help: 'Number of pages served by this exporter'
+ }),
+ oks: new client.Counter({
+ name: 'surveytool_exporter_oks',
+ help: 'Number of OK fetches',
+ labelNames: ['instance']
+ }),
+ fails: new client.Counter({
+ name: 'surveytool_exporter_fails',
+ help: 'Number of failed fetches',
+ labelNames: ['instance']
+ }),
+ ok: new client.Gauge({
+ name: 'surveytool_ok',
+ help: '1 if the surveytool is ok, otherwise 0',
+ labelNames: ['instance']
+ }),
+ isSetup: new client.Gauge({
+ name: 'surveytool_setup',
+ help: '1 if the surveytool is setup, otherwise 0',
+ labelNames: ['instance']
+ }),
+ isBusted: new client.Gauge({
+ name: 'surveytool_busted',
+ help: '1 if the surveytool is busted, otherwise 0',
+ labelNames: ['instance'/*, 'err'*/]
+ }),
+ fetchTime: new client.Gauge({
+ name: 'surveytool_fetchTime',
+ help: 'time of successful fetch',
+ labelNames: ['instance']
+ }),
+ fetchErr: new client.Gauge({
+ name: 'surveytool_fetchErr',
+ help: 'error code on failed fetch, or 200',
+ labelNames: ['instance'/*, 'err'*/]
+ }),
+ pages: new client.Gauge({
+ name: 'surveytool_pages',
+ help: 'page count',
+ labelNames: ['instance']
+ }),
+ users: new client.Gauge({
+ name: 'surveytool_users',
+ help: 'user count',
+ labelNames: ['instance']
+ }),
+ stamp: new client.Gauge({
+ name: 'surveytool_stamp',
+ help: 'survey running stamp',
+ labelNames: ['instance' /*,
+ 'phase', 'sysprocs', 'environment', 'currev', 'newVersion'*/]
+ }),
+ memtotal: new client.Gauge({
+ name: 'surveytool_memtotal',
+ help: 'total memory in process',
+ labelNames: ['instance']
+ }),
+ memfree: new client.Gauge({
+ name: 'surveytool_memfree',
+ help: 'total free memory',
+ labelNames: ['instance']
+ }),
+ dbused: new client.Gauge({
+ name: 'surveytool_dbused',
+ help: 'db queries used',
+ labelNames: ['instance']
+ }),
+ sysload: new client.Gauge({
+ name: 'surveytool_sysload',
+ help: 'system load, if available',
+ labelNames: ['instance']
+ }),
+};
+
+async function update(e) {
+ const [instance, url] = e;
+ try {
+ const res = await getJson(url);
+ items.oks.inc({instance});
+ items.fetchErr.set({ instance }, 200);
+ items.fetchTime.set({ instance }, new Date().getTime()/1000);
+ items.ok.set({instance}, Number(res.SurveyOK));
+ items.isSetup.set({instance}, Number(res.isSetup));
+ if(res.status) {
+ const{phase, memtotal, sysprocs, isBusted, isUnofficial, lockOut,
+ users, uptime, memfree, environment, pages, specialHeader, currev,
+ dbopen, surveyRunningStamp, guests, dbused,sysload, isSetup, newVersion} = res.status;
+ items.pages.set({instance}, Number(pages));
+ items.users.set({instance}, Number(users));
+ items.memtotal.set({instance}, Number(memtotal));
+ items.memfree.set({instance}, Number(memfree));
+ items.dbused.set({instance}, Number(dbused));
+ items.sysload.set({instance}, Number(sysload));
+ items.stamp.set({instance /*,
+ phase, sysprocs, environment, currev, newVersion*/},
+ surveyRunningStamp);
+ if(isBusted) {
+ items.isBusted.set({instance/*, err: isBusted*/}, Number(1));
+ } else {
+ items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted));
+ }
+ } else {
+ items.isBusted.set({instance/*, err: (res.err || '')*/}, Number(res.isBusted));
+ }
+ } catch(ex) {
+ items.fails.inc({instance});
+ items.fetchErr.set({ instance /*, err: ex.toString()*/ }, 999);
+ }
+}
+
+async function updateAll() {
+ return Promise.all(Object.entries(config.instances)
+ .map(e => update(e)));
+}
+
+server.get('/metrics', async (req, res) => {
+ items.responses.inc();
+ res.contentType(register.contentType);
+ await updateAll();
+ res.end(register.metrics());
+});
+
+const port = process.env.PORT || config.port || 3000;
+
+server.listen(port, () => {
+ console.log('ST exporter listening on port ' + port);
+});
\ No newline at end of file
diff --git a/tools/st-prom-exporter/package-lock.json b/tools/st-prom-exporter/package-lock.json
new file mode 100644
index 0000000..34c7eaf
--- /dev/null
+++ b/tools/st-prom-exporter/package-lock.json
@@ -0,0 +1,420 @@
+{
+ "name": "@unicode-org/st-prom-exporter",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "bent": {
+ "version": "7.3.10",
+ "resolved": "https://registry.npmjs.org/bent/-/bent-7.3.10.tgz",
+ "integrity": "sha512-X2P2nGRWejGn6IjJfL4usOuAVMng1DdyuRhXLGOcUvEblBcLZenrSjlkgS8ob1s3tbq3mo1FDxKhCRNvcf0y0Q==",
+ "requires": {
+ "bytesish": "^0.4.1",
+ "caseless": "~0.12.0",
+ "is-stream": "^2.0.0"
+ }
+ },
+ "bintrees": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz",
+ "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ="
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ }
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ },
+ "bytesish": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/bytesish/-/bytesish-0.4.3.tgz",
+ "integrity": "sha512-OuwahLpcvvYfFnxZL0E/Gx6D7U2A72JM8cXL+5uiiZP/x84B/arG5kL8QfRLCLKb/Ttp1Jk2bPDLeltP96dtbw=="
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
+ },
+ "mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "requires": {
+ "mime-db": "1.44.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "prom-client": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-12.0.0.tgz",
+ "integrity": "sha512-JbzzHnw0VDwCvoqf8y1WDtq4wSBAbthMB1pcVI/0lzdqHGJI3KBJDXle70XK+c7Iv93Gihqo0a5LlOn+g8+DrQ==",
+ "requires": {
+ "tdigest": "^0.1.1"
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+ "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "tdigest": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz",
+ "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=",
+ "requires": {
+ "bintrees": "1.0.1"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ }
+ }
+}
diff --git a/tools/st-prom-exporter/package.json b/tools/st-prom-exporter/package.json
new file mode 100644
index 0000000..57b2379
--- /dev/null
+++ b/tools/st-prom-exporter/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@unicode-org/st-prom-exporter",
+ "version": "1.0.0",
+ "description": "Reads Survey Tool status JSON and exports as Prometheus",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node index.js"
+ },
+ "keywords": [],
+ "author": "Steven R. Loomis <[email protected]>",
+ "license": "Unicode-DFS-2016",
+ "dependencies": {
+ "bent": "^7.3.10",
+ "express": "^4.17.1",
+ "prom-client": "^12.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/unicode-org/cldr.git"
+ }
+}