summaryrefslogtreecommitdiff
path: root/icu4j/main/tests
diff options
context:
space:
mode:
authorNikita Iashchenko <nikitai@google.com>2019-06-13 19:36:45 +0100
committerNikita Iashchenko <nikitai@google.com>2019-07-22 20:13:33 +0100
commitda0990f87c650bff952ed877c4bdf899de2c52c9 (patch)
treec8289a25e5e498c7633a217a889e1203ad026538 /icu4j/main/tests
parent2d812be337fb8afc7b63ec229e1994c911f03847 (diff)
downloadicu-da0990f87c650bff952ed877c4bdf899de2c52c9.tar.gz
Copy ICU release-64-2 into aosp/icu64
Copy the files with the following commands: 1. Obtain ICU sources: $ cd /tmp $ git clone --branch release-64-2 --depth 1 https://github.com/unicode-org/icu.git $ cd icu $ git lfs pull $ git lfs ls-files # ensure that all lfs-stored files are checked out 2. Update ICU: $ find icu4j/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\|adjust_icudt_path.mk\|liblayout-jarjar-rules.txt\)" -delete $ find icu4c/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\)" -delete $ cp -r /tmp/icu/icu4j/* ./icu4j/ $ cp -r /tmp/icu/icu4c/* ./icu4c/ $ git checkout HEAD -- icu4c/.gitignore icu4j/.gitignore $ git add -A $ git commit Test: n/a Change-Id: I4712daffcb3d5bda562a411167387e6a099aa18b
Diffstat (limited to 'icu4j/main/tests')
-rw-r--r--icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestCharset.java16
-rw-r--r--icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestConversion.java65
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_NON_IGNORABLE_SHORT.txt3349
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_SHIFTED_SHORT.txt3852
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationAPITest.java6
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationCreationMethodTest.java4
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java12
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationServiceTest.java4
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationTest.java4
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/G7CollationTest.java16
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/format/GlobalizationPreferencesTest.java4
-rw-r--r--icu4j/main/tests/collate/src/com/ibm/icu/dev/test/util/ICUResourceBundleCollationTest.java41
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt23
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/BidiTest.txt6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/CompositionExclusions.txt6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/IdnaTestV2.txt73
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationCorrections.txt6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationTest.txt34
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/SpecialCasing.txt6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/UnicodeData.txt565
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/confusables.txt8
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_64BitBCD.java10
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_ByteArrayBCD.java13
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java40
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegressionTest.java20
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java4
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java24
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/JapaneseTest.java130
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java32
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java10
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java736
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java47
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/FormattedValueTest.java287
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/IntlTestDateFormatSymbols.java29
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ListFormatterTest.java20
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java299
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java18
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatSpecificationTest.java10
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java347
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatTest.java7
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java102
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfRoundTripTest.java13
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java20
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java155
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TestMessageFormat.java62
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/TestUScript.java4
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java18
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterTest.java46
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java143
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java25
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java8
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java460
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java48
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java132
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberStringBuilderTest.java4
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PatternStringTest.java16
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITestMonkey.java144
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line.txt42
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_cj.txt213
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose.txt42
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose_cj.txt50
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal.txt42
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal_cj.txt51
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word.txt2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word_POSIX.txt2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt23
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/FormatHandler.java31
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.IllegalIcuArgumentException.datbin858 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.InvalidFormatException.datbin2821 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.locale.LocaleSyntaxException.datbin873 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.number.Properties.datbin573 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ArabicShapingException.datbin2821 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat.datbin92668 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormatSymbols.datbin39549 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat.datbin47117 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormatSymbols.datbin31766 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormat.datbin11041 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormatSymbols.datbin7109 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MeasureFormat.datbin3171 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat.datbin3751 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralFormat.datbin2943 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SimpleDateFormat.datbin90993 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.StringPrepParseException.datbin7356 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeUnitFormat.datbin2587 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.BuddhistCalendar.datbin2672 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ChineseCalendar.datbin3152 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.EthiopicCalendar.datbin2621 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUCloneNotSupportedException.datbin1393 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUException.datbin1298 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUUncheckedIOException.datbin1331 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IllformedLocaleException.datbin923 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IndianCalendar.datbin2493 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.JapaneseCalendar.datbin2750 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.PersianCalendar.datbin3664 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TaiwanCalendar.datbin2821 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.UResourceTypeMismatchException.datbin2886 -> 0 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.DateNumberFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.DateNumberFormat.dat)bin2602 -> 2602 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.IllegalIcuArgumentException.datbin0 -> 1114 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.InvalidFormatException.datbin0 -> 3177 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.JavaTimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.JavaTimeZone.dat)bin2543 -> 2551 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.OlsonTimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.OlsonTimeZone.dat)bin20881 -> 20907 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.RelativeDateFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.RelativeDateFormat.dat)bin11745 -> 11745 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat)bin277 -> 277 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneAdapter.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneAdapter.dat)bin21314 -> 21340 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneGenericNames.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneGenericNames.dat)bin407 -> 407 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat)bin237 -> 237 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat)bin383 -> 383 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.locale.LocaleSyntaxException.datbin0 -> 1134 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.CustomSymbolCurrency.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Currency.dat)bin345 -> 345 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.DecimalFormatProperties.datbin0 -> 586 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.LocalizedNumberFormatterAsFormat.datbin0 -> 187 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.Properties.datbin0 -> 106 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.BigDecimal.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.BigDecimal.dat)bin520 -> 520 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.MathContext.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.MathContext.dat)bin595 -> 595 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.number.SkeletonSyntaxException.datbin0 -> 1149 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ArabicShapingException.datbin0 -> 3177 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat$Field.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat$Field.dat)bin312 -> 312 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat.datbin0 -> 92515 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormatSymbols.datbin0 -> 39832 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CompactDecimalFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CompactDecimalFormat.dat)bin65 -> 65 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CurrencyPluralInfo.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CurrencyPluralInfo.dat)bin1186 -> 1170 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat$Field.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat$Field.dat)bin792 -> 792 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat.datbin0 -> 46758 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormatSymbols.datbin0 -> 31396 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat$SpanField.datbin0 -> 303 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalFormat.dat)bin10974 -> 12001 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat)bin270 -> 270 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo.dat)bin568 -> 568 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormat.datbin0 -> 11287 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormatSymbols.datbin0 -> 7258 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MeasureFormat.datbin0 -> 3245 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat$Field.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat$Field.dat)bin249 -> 249 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat.dat)bin382 -> 382 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat$Field.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat$Field.dat)bin449 -> 449 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat.datbin0 -> 3757 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralFormat.datbin0 -> 3003 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralRules.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralRules.dat)bin872 -> 872 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RelativeDateTimeFormatter$Field.datbin0 -> 246 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RuleBasedNumberFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.RuleBasedNumberFormat.dat)bin44502 -> 44502 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SelectFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SelectFormat.dat)bin202 -> 202 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SimpleDateFormat.datbin0 -> 90634 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.StringPrepParseException.datbin0 -> 7712 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeUnitFormat.datbin0 -> 2649 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeZoneFormat.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeZoneFormat.dat)bin774 -> 774 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.AnnualTimeZoneRule.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.AnnualTimeZoneRule.dat)bin898 -> 898 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.BuddhistCalendar.datbin0 -> 2672 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Calendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Calendar.dat)bin4090 -> 4090 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ChineseCalendar.datbin0 -> 3242 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.CopticCalendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.CopticCalendar.dat)bin3328 -> 3328 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Currency.datbin0 -> 345 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DangiCalendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DangiCalendar.dat)bin3538 -> 3538 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateInterval.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateInterval.dat)bin139 -> 139 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateTimeRule.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateTimeRule.dat)bin324 -> 324 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.EthiopicCalendar.datbin0 -> 2621 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.GregorianCalendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.GregorianCalendar.dat)bin4099 -> 4099 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.HebrewCalendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.HebrewCalendar.dat)bin3647 -> 3647 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUCloneNotSupportedException.datbin0 -> 1674 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUException.datbin0 -> 1579 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUUncheckedIOException.datbin0 -> 1612 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IllformedLocaleException.datbin0 -> 1184 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IndianCalendar.datbin0 -> 2511 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.InitialTimeZoneRule.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.InitialTimeZoneRule.dat)bin241 -> 241 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IslamicCalendar.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IslamicCalendar.dat)bin3876 -> 3876 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.JapaneseCalendar.datbin0 -> 2750 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.MeasureUnit.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.MeasureUnit.dat)bin173 -> 173 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.NoUnit.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeUnit.dat)bin173 -> 173 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.PersianCalendar.datbin0 -> 4600 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.RuleBasedTimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.RuleBasedTimeZone.dat)bin1401 -> 1401 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.SimpleTimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.SimpleTimeZone.dat)bin1152 -> 1152 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TaiwanCalendar.datbin0 -> 2911 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat)bin312 -> 312 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeUnit.datbin0 -> 173 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeZone.dat)bin1588 -> 1606 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ULocale.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ULocale.dat)bin365 -> 365 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.UResourceTypeMismatchException.datbin0 -> 3242 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.VTimeZone.dat (renamed from icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.VTimeZone.dat)bin2676 -> 2676 bytes
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/BytesTrieTest.java70
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CharsTrieTest.java70
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java25
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java2
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java6
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleBuilderTest.java8
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java4
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TestLocaleValidity.java4
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java334
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleDistanceTest.java109
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java470
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt2052
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/text/DecimalFormat_ICU58.java6286
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitList.java842
-rw-r--r--icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitListTest.java47
195 files changed, 20898 insertions, 1524 deletions
diff --git a/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestCharset.java b/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestCharset.java
index 64cb4a256..5ffdd41a2 100644
--- a/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestCharset.java
+++ b/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestCharset.java
@@ -645,9 +645,7 @@ public class TestCharset extends TestFmwk {
logln("finish: " + hex(finishArray));
}
} catch (CharacterCodingException ex) {
- // Android patch: Skip tests that fail with customized data.
- logln(converter + " roundtrip test failed: " + ex.getMessage());
- // Android patch end.
+ errln(converter + " roundtrip test failed: " + ex.getMessage());
ex.printStackTrace(System.err);
}
@@ -679,9 +677,7 @@ public class TestCharset extends TestFmwk {
}
} else {
if (result.isError()) {
- // Android patch: Skip tests that fail with customized data.
- logln("Error should not have occurred while encoding HZ.(" + i + ")");
- // Android patch end.
+ errln("Error should not have occurred while encoding HZ.(" + i + ")");
}
}
}
@@ -832,9 +828,7 @@ public class TestCharset extends TestFmwk {
return;
} catch (RuntimeException ex) {
if (!currentlybad) {currentlybad = true; badcount++; logln(""); }
- // Android patch: Skip tests that fail with customized data.
- logln(converter + " " + ex.getClass().getName() + ": " + ex.getMessage());
- // Android patch end.
+ errln(converter + " " + ex.getClass().getName() + ": " + ex.getMessage());
continue outer;
}
@@ -2383,10 +2377,8 @@ public class TestCharset extends TestFmwk {
if(!result.isError()){
byte[] expected = {(byte)0xA9, (byte)0xA5, (byte)0xAF, (byte)0xFE, (byte)0xA2, (byte)0xAE};
if(!equals(expected, out.array())){
- // Android patch: Skip tests that fail with customized data.
- logln("Did not get the expected result for substitution bytes. Got: "+
+ errln("Did not get the expected result for substitution bytes. Got: "+
hex(out.array()));
- // Android patch end.
}
logln("Output: "+ hex(out.array()));
}else{
diff --git a/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestConversion.java b/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestConversion.java
index 8e6fd4bab..67c1cf641 100644
--- a/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestConversion.java
+++ b/icu4j/main/tests/charset/src/com/ibm/icu/dev/test/charset/TestConversion.java
@@ -162,35 +162,9 @@ public class TestConversion extends TestFmwk {
* This feature is not in ICU4J.
* See #9601
*/
- // Android patch: Skip tests that fail with customized data.
String [] testsToSkip = {
- "*test2",
- "EUC-TW",
- "gb18030",
- "ibm-1386",
- "ibm-1390",
- "ibm-1390,swaplfnl",
- "ibm-1399",
- "ibm-16684",
- "ibm-25546",
- "ibm-930",
- "ibm-943",
- "ibm-970",
- "ibm-971",
- "IBM-eucJP",
- "iso-2022-cn",
- "iso-2022-jp",
- "ISO-2022-JP-2",
- "iso-2022-kr",
- "ISO-2022-KR",
- "JIS",
- "JIS7",
- "JIS8",
- "lmbcs",
- "windows-936",
- "x11-compound-text",
+ "*test2"
};
- // Android patch end.
for (int i = 0; i < testsToSkip.length; i++) {
if (cc.charset.equals(testsToSkip[i])) {
logln("");
@@ -491,20 +465,6 @@ public class TestConversion extends TestFmwk {
return;
}
- // Android patch: Skip tests that fail with customized data.
- String [] testsToSkip = {
- "ibm-1390,swaplfnl",
- };
- for (int i = 0; i < testsToSkip.length; i++) {
- if (cc.charset.equals(testsToSkip[i])) {
- logln("");
- logln("Skipping: " + cc.charset);
- logln("...............................................");
- return;
- }
- }
- // Android patch end.
-
// ----for debugging only
logln("");
logln("TestToUnicode[" + caseNr + "] " + cc.charset + " ");
@@ -943,29 +903,6 @@ public class TestConversion extends TestFmwk {
cc.which = ((ICUResourceBundle) testcase.getObject("which")).getInt(); // only checking for ROUNDTRIP_SET
- // Android patch: Skip tests that fail with customized data.
- String [] testsToSkip = {
- "HZ",
- "ibm-1390",
- "ibm-16684",
- "ibm-25546",
- "ibm-971",
- "ISO-2022-CN",
- "ISO-2022-JP",
- "ISO-2022-JP-2",
- "ISO-2022-KR",
- "JIS7",
- };
- for (int i = 0; i < testsToSkip.length; i++) {
- if (cc.charset.equals(testsToSkip[i])) {
- logln("");
- logln("Skipping: " + cc.charset);
- logln("...............................................");
- return;
- }
- }
- // Android patch end.
-
// ----for debugging only
logln("");
logln("TestGetUnicodeSet[" + cc.charset + "] ");
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_NON_IGNORABLE_SHORT.txt b/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_NON_IGNORABLE_SHORT.txt
index 58b3110aa..488aa673c 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_NON_IGNORABLE_SHORT.txt
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_NON_IGNORABLE_SHORT.txt
@@ -1,10 +1,10 @@
# CollationTest_CLDR_NON_IGNORABLE_SHORT.txt
-# Date: 2018-05-21, 23:52:51 GMT
-# © 2018 Unicode®, Inc.
+# Date: 2019-04-01, 20:17:34 GMT
+# © 2019 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
-# UCA Version: 11.0.0
-# UCD Version: 11.0.0
+# UCA Version: 12.1.0
+# UCD Version: 12.1.0
# For a description of the format and usage, see
# http://www.unicode.org/reports/tr35/tr35-collation.html#Root_Data_Files
@@ -1183,18 +1183,40 @@ A92D 0334
193B 0334
0334 16B30
16B30 0334
+0334 1E131
+1E131 0334
0334 16B31
16B31 0334
+0334 1E136
+1E136 0334
0334 16B32
16B32 0334
+0334 1E132
+1E132 0334
0334 16B33
16B33 0334
+0334 1E133
+1E133 0334
0334 16B34
16B34 0334
+0334 1E130
+1E130 0334
0334 16B35
16B35 0334
+0334 1E134
+1E134 0334
0334 16B36
16B36 0334
+0334 1E135
+1E135 0334
+0334 1E2EC
+1E2EC 0334
+0334 1E2ED
+1E2ED 0334
+0334 1E2EE
+1E2EE 0334
+0334 1E2EF
+1E2EF 0334
0334 302A
302A 0334
0334 302B
@@ -1622,6 +1644,11 @@ FE10 0062
2E4E 0061
2E4E 0041
2E4E 0062
+2E4F 0021
+2E4F 003F
+2E4F 0061
+2E4F 0041
+2E4F 0062
055D 0021
055D 003F
055D 0061
@@ -1712,6 +1739,11 @@ FE46 003F
FE46 0061
FE46 0041
FE46 0062
+16FE2 0021
+16FE2 003F
+16FE2 0061
+16FE2 0041
+16FE2 0062
003B 0021
037E 0021
FF1B 0021
@@ -2299,6 +2331,15 @@ FFFB 0021
11372 0021
11373 0021
11374 0021
+13430 0021
+13431 0021
+13432 0021
+13433 0021
+13434 0021
+13435 0021
+13436 0021
+13437 0021
+13438 0021
1BCA0 0021
1BCA1 0021
1BCA2 0021
@@ -3277,6 +3318,7 @@ A981 0021
1163D 0021
116AB 0021
11837 0021
+119DE 0021
11A38 0021
11A96 0021
11C3D 0021
@@ -3313,6 +3355,7 @@ A983 0021
1163E 0021
116AC 0021
11838 0021
+119DF 0021
11A39 0021
11A97 0021
11C3E 0021
@@ -3369,12 +3412,23 @@ A92D 0021
193A 0021
193B 0021
16B30 0021
+1E131 0021
16B31 0021
+1E136 0021
16B32 0021
+1E132 0021
16B33 0021
+1E133 0021
16B34 0021
+1E130 0021
16B35 0021
+1E134 0021
16B36 0021
+1E135 0021
+1E2EC 0021
+1E2ED 0021
+1E2EE 0021
+1E2EF 0021
302A 0021
302B 0021
302C 0021
@@ -3774,6 +3828,15 @@ FFFB 003F
11372 003F
11373 003F
11374 003F
+13430 003F
+13431 003F
+13432 003F
+13433 003F
+13434 003F
+13435 003F
+13436 003F
+13437 003F
+13438 003F
1BCA0 003F
1BCA1 003F
1BCA2 003F
@@ -4752,6 +4815,7 @@ A981 003F
1163D 003F
116AB 003F
11837 003F
+119DE 003F
11A38 003F
11A96 003F
11C3D 003F
@@ -4788,6 +4852,7 @@ A983 003F
1163E 003F
116AC 003F
11838 003F
+119DF 003F
11A39 003F
11A97 003F
11C3E 003F
@@ -4844,12 +4909,23 @@ A92D 003F
193A 003F
193B 003F
16B30 003F
+1E131 003F
16B31 003F
+1E136 003F
16B32 003F
+1E132 003F
16B33 003F
+1E133 003F
16B34 003F
+1E130 003F
16B35 003F
+1E134 003F
16B36 003F
+1E135 003F
+1E2EC 003F
+1E2ED 003F
+1E2EE 003F
+1E2EF 003F
302A 003F
302B 003F
302C 003F
@@ -8042,6 +8118,11 @@ A8FC 0062
0AF0 0061
0AF0 0041
0AF0 0062
+0C77 0021
+0C77 003F
+0C77 0061
+0C77 0041
+0C77 0062
0C84 0021
0C84 003F
0C84 0061
@@ -8377,11 +8458,6 @@ AADF 0062
1AAD 0061
1AAD 0041
1AAD 0062
-166D 0021
-166D 003F
-166D 0061
-166D 0041
-166D 0062
1CC0 0021
1CC0 003F
1CC0 0061
@@ -8822,6 +8898,16 @@ AA5C 0062
1183B 0061
1183B 0041
1183B 0062
+119E2 0021
+119E2 003F
+119E2 0061
+119E2 0041
+119E2 0062
+11FFF 0021
+11FFF 003F
+11FFF 0061
+11FFF 0041
+11FFF 0062
16B37 0021
16B37 003F
16B37 0061
@@ -9795,6 +9881,131 @@ FBC1 0062
0BFA 0061
0BFA 0041
0BFA 0062
+11FD5 0021
+11FD5 003F
+11FD5 0061
+11FD5 0041
+11FD5 0062
+11FD6 0021
+11FD6 003F
+11FD6 0061
+11FD6 0041
+11FD6 0062
+11FD7 0021
+11FD7 003F
+11FD7 0061
+11FD7 0041
+11FD7 0062
+11FD8 0021
+11FD8 003F
+11FD8 0061
+11FD8 0041
+11FD8 0062
+11FD9 0021
+11FD9 003F
+11FD9 0061
+11FD9 0041
+11FD9 0062
+11FDA 0021
+11FDA 003F
+11FDA 0061
+11FDA 0041
+11FDA 0062
+11FDB 0021
+11FDB 003F
+11FDB 0061
+11FDB 0041
+11FDB 0062
+11FDC 0021
+11FDC 003F
+11FDC 0061
+11FDC 0041
+11FDC 0062
+11FE1 0021
+11FE1 003F
+11FE1 0061
+11FE1 0041
+11FE1 0062
+11FE2 0021
+11FE2 003F
+11FE2 0061
+11FE2 0041
+11FE2 0062
+11FE3 0021
+11FE3 003F
+11FE3 0061
+11FE3 0041
+11FE3 0062
+11FE4 0021
+11FE4 003F
+11FE4 0061
+11FE4 0041
+11FE4 0062
+11FE5 0021
+11FE5 003F
+11FE5 0061
+11FE5 0041
+11FE5 0062
+11FE6 0021
+11FE6 003F
+11FE6 0061
+11FE6 0041
+11FE6 0062
+11FE7 0021
+11FE7 003F
+11FE7 0061
+11FE7 0041
+11FE7 0062
+11FE8 0021
+11FE8 003F
+11FE8 0061
+11FE8 0041
+11FE8 0062
+11FE9 0021
+11FE9 003F
+11FE9 0061
+11FE9 0041
+11FE9 0062
+11FEA 0021
+11FEA 003F
+11FEA 0061
+11FEA 0041
+11FEA 0062
+11FEB 0021
+11FEB 003F
+11FEB 0061
+11FEB 0041
+11FEB 0062
+11FEC 0021
+11FEC 003F
+11FEC 0061
+11FEC 0041
+11FEC 0062
+11FED 0021
+11FED 003F
+11FED 0061
+11FED 0041
+11FED 0062
+11FEE 0021
+11FEE 003F
+11FEE 0061
+11FEE 0041
+11FEE 0062
+11FEF 0021
+11FEF 003F
+11FEF 0061
+11FEF 0041
+11FEF 0062
+11FF0 0021
+11FF0 003F
+11FF0 0061
+11FF0 0041
+11FF0 0062
+11FF1 0021
+11FF1 003F
+11FF1 0061
+11FF1 0041
+11FF1 0062
0C7F 0021
0C7F 003F
0C7F 0061
@@ -10025,6 +10236,11 @@ A839 0062
0FD8 0061
0FD8 0041
0FD8 0062
+166D 0021
+166D 003F
+166D 0061
+166D 0041
+166D 0062
1940 0021
1940 003F
1940 0061
@@ -21145,6 +21361,11 @@ FFEE 0062
2BC8 0061
2BC8 0041
2BC8 0062
+2BC9 0021
+2BC9 003F
+2BC9 0061
+2BC9 0041
+2BC9 0062
2BCA 0021
2BCA 003F
2BCA 0061
@@ -21410,6 +21631,11 @@ FFEE 0062
2BFE 0061
2BFE 0041
2BFE 0062
+2BFF 0021
+2BFF 003F
+2BFF 0061
+2BFF 0041
+2BFF 0062
2CE5 0021
2CE5 003F
2CE5 0061
@@ -24290,6 +24516,11 @@ A4C6 0062
16B45 0061
16B45 0041
16B45 0062
+1E14F 0021
+1E14F 003F
+1E14F 0061
+1E14F 0041
+1E14F 0062
1D000 0021
1D000 003F
1D000 0061
@@ -26893,6 +27124,11 @@ A4C6 0062
1ECAC 0061
1ECAC 0041
1ECAC 0062
+1ED2E 0021
+1ED2E 003F
+1ED2E 0061
+1ED2E 0041
+1ED2E 0062
1F000 0021
1F000 003F
1F000 0061
@@ -28023,6 +28259,426 @@ A4C6 0062
1F0F5 0061
1F0F5 0041
1F0F5 0062
+1FA00 0021
+1FA00 003F
+1FA00 0061
+1FA00 0041
+1FA00 0062
+1FA01 0021
+1FA01 003F
+1FA01 0061
+1FA01 0041
+1FA01 0062
+1FA02 0021
+1FA02 003F
+1FA02 0061
+1FA02 0041
+1FA02 0062
+1FA03 0021
+1FA03 003F
+1FA03 0061
+1FA03 0041
+1FA03 0062
+1FA04 0021
+1FA04 003F
+1FA04 0061
+1FA04 0041
+1FA04 0062
+1FA05 0021
+1FA05 003F
+1FA05 0061
+1FA05 0041
+1FA05 0062
+1FA06 0021
+1FA06 003F
+1FA06 0061
+1FA06 0041
+1FA06 0062
+1FA07 0021
+1FA07 003F
+1FA07 0061
+1FA07 0041
+1FA07 0062
+1FA08 0021
+1FA08 003F
+1FA08 0061
+1FA08 0041
+1FA08 0062
+1FA09 0021
+1FA09 003F
+1FA09 0061
+1FA09 0041
+1FA09 0062
+1FA0A 0021
+1FA0A 003F
+1FA0A 0061
+1FA0A 0041
+1FA0A 0062
+1FA0B 0021
+1FA0B 003F
+1FA0B 0061
+1FA0B 0041
+1FA0B 0062
+1FA0C 0021
+1FA0C 003F
+1FA0C 0061
+1FA0C 0041
+1FA0C 0062
+1FA0D 0021
+1FA0D 003F
+1FA0D 0061
+1FA0D 0041
+1FA0D 0062
+1FA0E 0021
+1FA0E 003F
+1FA0E 0061
+1FA0E 0041
+1FA0E 0062
+1FA0F 0021
+1FA0F 003F
+1FA0F 0061
+1FA0F 0041
+1FA0F 0062
+1FA10 0021
+1FA10 003F
+1FA10 0061
+1FA10 0041
+1FA10 0062
+1FA11 0021
+1FA11 003F
+1FA11 0061
+1FA11 0041
+1FA11 0062
+1FA12 0021
+1FA12 003F
+1FA12 0061
+1FA12 0041
+1FA12 0062
+1FA13 0021
+1FA13 003F
+1FA13 0061
+1FA13 0041
+1FA13 0062
+1FA14 0021
+1FA14 003F
+1FA14 0061
+1FA14 0041
+1FA14 0062
+1FA15 0021
+1FA15 003F
+1FA15 0061
+1FA15 0041
+1FA15 0062
+1FA16 0021
+1FA16 003F
+1FA16 0061
+1FA16 0041
+1FA16 0062
+1FA17 0021
+1FA17 003F
+1FA17 0061
+1FA17 0041
+1FA17 0062
+1FA18 0021
+1FA18 003F
+1FA18 0061
+1FA18 0041
+1FA18 0062
+1FA19 0021
+1FA19 003F
+1FA19 0061
+1FA19 0041
+1FA19 0062
+1FA1A 0021
+1FA1A 003F
+1FA1A 0061
+1FA1A 0041
+1FA1A 0062
+1FA1B 0021
+1FA1B 003F
+1FA1B 0061
+1FA1B 0041
+1FA1B 0062
+1FA1C 0021
+1FA1C 003F
+1FA1C 0061
+1FA1C 0041
+1FA1C 0062
+1FA1D 0021
+1FA1D 003F
+1FA1D 0061
+1FA1D 0041
+1FA1D 0062
+1FA1E 0021
+1FA1E 003F
+1FA1E 0061
+1FA1E 0041
+1FA1E 0062
+1FA1F 0021
+1FA1F 003F
+1FA1F 0061
+1FA1F 0041
+1FA1F 0062
+1FA20 0021
+1FA20 003F
+1FA20 0061
+1FA20 0041
+1FA20 0062
+1FA21 0021
+1FA21 003F
+1FA21 0061
+1FA21 0041
+1FA21 0062
+1FA22 0021
+1FA22 003F
+1FA22 0061
+1FA22 0041
+1FA22 0062
+1FA23 0021
+1FA23 003F
+1FA23 0061
+1FA23 0041
+1FA23 0062
+1FA24 0021
+1FA24 003F
+1FA24 0061
+1FA24 0041
+1FA24 0062
+1FA25 0021
+1FA25 003F
+1FA25 0061
+1FA25 0041
+1FA25 0062
+1FA26 0021
+1FA26 003F
+1FA26 0061
+1FA26 0041
+1FA26 0062
+1FA27 0021
+1FA27 003F
+1FA27 0061
+1FA27 0041
+1FA27 0062
+1FA28 0021
+1FA28 003F
+1FA28 0061
+1FA28 0041
+1FA28 0062
+1FA29 0021
+1FA29 003F
+1FA29 0061
+1FA29 0041
+1FA29 0062
+1FA2A 0021
+1FA2A 003F
+1FA2A 0061
+1FA2A 0041
+1FA2A 0062
+1FA2B 0021
+1FA2B 003F
+1FA2B 0061
+1FA2B 0041
+1FA2B 0062
+1FA2C 0021
+1FA2C 003F
+1FA2C 0061
+1FA2C 0041
+1FA2C 0062
+1FA2D 0021
+1FA2D 003F
+1FA2D 0061
+1FA2D 0041
+1FA2D 0062
+1FA2E 0021
+1FA2E 003F
+1FA2E 0061
+1FA2E 0041
+1FA2E 0062
+1FA2F 0021
+1FA2F 003F
+1FA2F 0061
+1FA2F 0041
+1FA2F 0062
+1FA30 0021
+1FA30 003F
+1FA30 0061
+1FA30 0041
+1FA30 0062
+1FA31 0021
+1FA31 003F
+1FA31 0061
+1FA31 0041
+1FA31 0062
+1FA32 0021
+1FA32 003F
+1FA32 0061
+1FA32 0041
+1FA32 0062
+1FA33 0021
+1FA33 003F
+1FA33 0061
+1FA33 0041
+1FA33 0062
+1FA34 0021
+1FA34 003F
+1FA34 0061
+1FA34 0041
+1FA34 0062
+1FA35 0021
+1FA35 003F
+1FA35 0061
+1FA35 0041
+1FA35 0062
+1FA36 0021
+1FA36 003F
+1FA36 0061
+1FA36 0041
+1FA36 0062
+1FA37 0021
+1FA37 003F
+1FA37 0061
+1FA37 0041
+1FA37 0062
+1FA38 0021
+1FA38 003F
+1FA38 0061
+1FA38 0041
+1FA38 0062
+1FA39 0021
+1FA39 003F
+1FA39 0061
+1FA39 0041
+1FA39 0062
+1FA3A 0021
+1FA3A 003F
+1FA3A 0061
+1FA3A 0041
+1FA3A 0062
+1FA3B 0021
+1FA3B 003F
+1FA3B 0061
+1FA3B 0041
+1FA3B 0062
+1FA3C 0021
+1FA3C 003F
+1FA3C 0061
+1FA3C 0041
+1FA3C 0062
+1FA3D 0021
+1FA3D 003F
+1FA3D 0061
+1FA3D 0041
+1FA3D 0062
+1FA3E 0021
+1FA3E 003F
+1FA3E 0061
+1FA3E 0041
+1FA3E 0062
+1FA3F 0021
+1FA3F 003F
+1FA3F 0061
+1FA3F 0041
+1FA3F 0062
+1FA40 0021
+1FA40 003F
+1FA40 0061
+1FA40 0041
+1FA40 0062
+1FA41 0021
+1FA41 003F
+1FA41 0061
+1FA41 0041
+1FA41 0062
+1FA42 0021
+1FA42 003F
+1FA42 0061
+1FA42 0041
+1FA42 0062
+1FA43 0021
+1FA43 003F
+1FA43 0061
+1FA43 0041
+1FA43 0062
+1FA44 0021
+1FA44 003F
+1FA44 0061
+1FA44 0041
+1FA44 0062
+1FA45 0021
+1FA45 003F
+1FA45 0061
+1FA45 0041
+1FA45 0062
+1FA46 0021
+1FA46 003F
+1FA46 0061
+1FA46 0041
+1FA46 0062
+1FA47 0021
+1FA47 003F
+1FA47 0061
+1FA47 0041
+1FA47 0062
+1FA48 0021
+1FA48 003F
+1FA48 0061
+1FA48 0041
+1FA48 0062
+1FA49 0021
+1FA49 003F
+1FA49 0061
+1FA49 0041
+1FA49 0062
+1FA4A 0021
+1FA4A 003F
+1FA4A 0061
+1FA4A 0041
+1FA4A 0062
+1FA4B 0021
+1FA4B 003F
+1FA4B 0061
+1FA4B 0041
+1FA4B 0062
+1FA4C 0021
+1FA4C 003F
+1FA4C 0061
+1FA4C 0041
+1FA4C 0062
+1FA4D 0021
+1FA4D 003F
+1FA4D 0061
+1FA4D 0041
+1FA4D 0062
+1FA4E 0021
+1FA4E 003F
+1FA4E 0061
+1FA4E 0041
+1FA4E 0062
+1FA4F 0021
+1FA4F 003F
+1FA4F 0061
+1FA4F 0041
+1FA4F 0062
+1FA50 0021
+1FA50 003F
+1FA50 0061
+1FA50 0041
+1FA50 0062
+1FA51 0021
+1FA51 003F
+1FA51 0061
+1FA51 0041
+1FA51 0062
+1FA52 0021
+1FA52 003F
+1FA52 0061
+1FA52 0041
+1FA52 0062
+1FA53 0021
+1FA53 003F
+1FA53 0061
+1FA53 0041
+1FA53 0062
1FA60 0021
1FA60 003F
1FA60 0061
@@ -32023,6 +32679,21 @@ A4C6 0062
1F90B 0061
1F90B 0041
1F90B 0062
+1F90D 0021
+1F90D 003F
+1F90D 0061
+1F90D 0041
+1F90D 0062
+1F90E 0021
+1F90E 003F
+1F90E 0061
+1F90E 0041
+1F90E 0062
+1F90F 0021
+1F90F 003F
+1F90F 0061
+1F90F 0041
+1F90F 0062
1F910 0021
1F910 003F
1F910 0061
@@ -32258,6 +32929,11 @@ A4C6 0062
1F93E 0061
1F93E 0041
1F93E 0062
+1F93F 0021
+1F93F 003F
+1F93F 0061
+1F93F 0041
+1F93F 0062
1F940 0021
1F940 003F
1F940 0061
@@ -32503,6 +33179,11 @@ A4C6 0062
1F970 0061
1F970 0041
1F970 0062
+1F971 0021
+1F971 003F
+1F971 0061
+1F971 0041
+1F971 0062
1F973 0021
1F973 003F
1F973 0061
@@ -32528,6 +33209,11 @@ A4C6 0062
1F97A 0061
1F97A 0041
1F97A 0062
+1F97B 0021
+1F97B 003F
+1F97B 0061
+1F97B 0041
+1F97B 0062
1F97C 0021
1F97C 003F
1F97C 0061
@@ -32723,6 +33409,46 @@ A4C6 0062
1F9A2 0061
1F9A2 0041
1F9A2 0062
+1F9A5 0021
+1F9A5 003F
+1F9A5 0061
+1F9A5 0041
+1F9A5 0062
+1F9A6 0021
+1F9A6 003F
+1F9A6 0061
+1F9A6 0041
+1F9A6 0062
+1F9A7 0021
+1F9A7 003F
+1F9A7 0061
+1F9A7 0041
+1F9A7 0062
+1F9A8 0021
+1F9A8 003F
+1F9A8 0061
+1F9A8 0041
+1F9A8 0062
+1F9A9 0021
+1F9A9 003F
+1F9A9 0061
+1F9A9 0041
+1F9A9 0062
+1F9AA 0021
+1F9AA 003F
+1F9AA 0061
+1F9AA 0041
+1F9AA 0062
+1F9AE 0021
+1F9AE 003F
+1F9AE 0061
+1F9AE 0041
+1F9AE 0062
+1F9AF 0021
+1F9AF 003F
+1F9AF 0061
+1F9AF 0041
+1F9AF 0062
1F9B0 0021
1F9B0 003F
1F9B0 0061
@@ -32773,6 +33499,36 @@ A4C6 0062
1F9B9 0061
1F9B9 0041
1F9B9 0062
+1F9BA 0021
+1F9BA 003F
+1F9BA 0061
+1F9BA 0041
+1F9BA 0062
+1F9BB 0021
+1F9BB 003F
+1F9BB 0061
+1F9BB 0041
+1F9BB 0062
+1F9BC 0021
+1F9BC 003F
+1F9BC 0061
+1F9BC 0041
+1F9BC 0062
+1F9BD 0021
+1F9BD 003F
+1F9BD 0061
+1F9BD 0041
+1F9BD 0062
+1F9BE 0021
+1F9BE 003F
+1F9BE 0061
+1F9BE 0041
+1F9BE 0062
+1F9BF 0021
+1F9BF 003F
+1F9BF 0061
+1F9BF 0041
+1F9BF 0062
1F9C0 0021
1F9C0 003F
1F9C0 0061
@@ -32788,6 +33544,61 @@ A4C6 0062
1F9C2 0061
1F9C2 0041
1F9C2 0062
+1F9C3 0021
+1F9C3 003F
+1F9C3 0061
+1F9C3 0041
+1F9C3 0062
+1F9C4 0021
+1F9C4 003F
+1F9C4 0061
+1F9C4 0041
+1F9C4 0062
+1F9C5 0021
+1F9C5 003F
+1F9C5 0061
+1F9C5 0041
+1F9C5 0062
+1F9C6 0021
+1F9C6 003F
+1F9C6 0061
+1F9C6 0041
+1F9C6 0062
+1F9C7 0021
+1F9C7 003F
+1F9C7 0061
+1F9C7 0041
+1F9C7 0062
+1F9C8 0021
+1F9C8 003F
+1F9C8 0061
+1F9C8 0041
+1F9C8 0062
+1F9C9 0021
+1F9C9 003F
+1F9C9 0061
+1F9C9 0041
+1F9C9 0062
+1F9CA 0021
+1F9CA 003F
+1F9CA 0061
+1F9CA 0041
+1F9CA 0062
+1F9CD 0021
+1F9CD 003F
+1F9CD 0061
+1F9CD 0041
+1F9CD 0062
+1F9CE 0021
+1F9CE 003F
+1F9CE 0061
+1F9CE 0041
+1F9CE 0062
+1F9CF 0021
+1F9CF 003F
+1F9CF 0061
+1F9CF 0041
+1F9CF 0062
1F9D0 0021
1F9D0 003F
1F9D0 0061
@@ -33028,6 +33839,86 @@ A4C6 0062
1F9FF 0061
1F9FF 0041
1F9FF 0062
+1FA70 0021
+1FA70 003F
+1FA70 0061
+1FA70 0041
+1FA70 0062
+1FA71 0021
+1FA71 003F
+1FA71 0061
+1FA71 0041
+1FA71 0062
+1FA72 0021
+1FA72 003F
+1FA72 0061
+1FA72 0041
+1FA72 0062
+1FA73 0021
+1FA73 003F
+1FA73 0061
+1FA73 0041
+1FA73 0062
+1FA78 0021
+1FA78 003F
+1FA78 0061
+1FA78 0041
+1FA78 0062
+1FA79 0021
+1FA79 003F
+1FA79 0061
+1FA79 0041
+1FA79 0062
+1FA7A 0021
+1FA7A 003F
+1FA7A 0061
+1FA7A 0041
+1FA7A 0062
+1FA80 0021
+1FA80 003F
+1FA80 0061
+1FA80 0041
+1FA80 0062
+1FA81 0021
+1FA81 003F
+1FA81 0061
+1FA81 0041
+1FA81 0062
+1FA82 0021
+1FA82 003F
+1FA82 0061
+1FA82 0041
+1FA82 0062
+1FA90 0021
+1FA90 003F
+1FA90 0061
+1FA90 0041
+1FA90 0062
+1FA91 0021
+1FA91 003F
+1FA91 0061
+1FA91 0041
+1FA91 0062
+1FA92 0021
+1FA92 003F
+1FA92 0061
+1FA92 0041
+1FA92 0062
+1FA93 0021
+1FA93 003F
+1FA93 0061
+1FA93 0041
+1FA93 0062
+1FA94 0021
+1FA94 003F
+1FA94 0061
+1FA94 0041
+1FA94 0062
+1FA95 0021
+1FA95 003F
+1FA95 0061
+1FA95 0041
+1FA95 0062
1F600 0021
1F600 003F
1F600 0061
@@ -34093,6 +34984,11 @@ A4C6 0062
1F6D4 0061
1F6D4 0041
1F6D4 0062
+1F6D5 0021
+1F6D5 003F
+1F6D5 0061
+1F6D5 0041
+1F6D5 0062
1F6E0 0021
1F6E0 003F
1F6E0 0061
@@ -34208,6 +35104,11 @@ A4C6 0062
1F6F9 0061
1F6F9 0041
1F6F9 0062
+1F6FA 0021
+1F6FA 003F
+1F6FA 0061
+1F6FA 0041
+1F6FA 0062
1F700 0021
1F700 003F
1F700 0061
@@ -35233,6 +36134,66 @@ A4C6 0062
1F7D8 0061
1F7D8 0041
1F7D8 0062
+1F7E0 0021
+1F7E0 003F
+1F7E0 0061
+1F7E0 0041
+1F7E0 0062
+1F7E1 0021
+1F7E1 003F
+1F7E1 0061
+1F7E1 0041
+1F7E1 0062
+1F7E2 0021
+1F7E2 003F
+1F7E2 0061
+1F7E2 0041
+1F7E2 0062
+1F7E3 0021
+1F7E3 003F
+1F7E3 0061
+1F7E3 0041
+1F7E3 0062
+1F7E4 0021
+1F7E4 003F
+1F7E4 0061
+1F7E4 0041
+1F7E4 0062
+1F7E5 0021
+1F7E5 003F
+1F7E5 0061
+1F7E5 0041
+1F7E5 0062
+1F7E6 0021
+1F7E6 003F
+1F7E6 0061
+1F7E6 0041
+1F7E6 0062
+1F7E7 0021
+1F7E7 003F
+1F7E7 0061
+1F7E7 0041
+1F7E7 0062
+1F7E8 0021
+1F7E8 003F
+1F7E8 0061
+1F7E8 0041
+1F7E8 0062
+1F7E9 0021
+1F7E9 003F
+1F7E9 0061
+1F7E9 0041
+1F7E9 0062
+1F7EA 0021
+1F7EA 003F
+1F7EA 0061
+1F7EA 0041
+1F7EA 0062
+1F7EB 0021
+1F7EB 003F
+1F7EB 0061
+1F7EB 0041
+1F7EB 0062
1F800 0021
1F800 003F
1F800 0061
@@ -39048,6 +40009,16 @@ AAF4 0062
16B43 0061
16B43 0041
16B43 0062
+1E13C 0021
+1E13C 003F
+1E13C 0061
+1E13C 0041
+1E13C 0062
+1E13D 0021
+1E13D 003F
+1E13D 0061
+1E13D 0041
+1E13D 0062
3005 0021
3005 003F
3005 0061
@@ -39068,6 +40039,11 @@ AAF4 0062
16FE1 0061
16FE1 0041
16FE1 0062
+16FE3 0021
+16FE3 003F
+16FE3 0061
+16FE3 0041
+16FE3 0062
3031 0021
3032 0021
3031 003F
@@ -39229,6 +40205,26 @@ A838 0062
0BF9 0061
0BF9 0041
0BF9 0062
+11FDD 0021
+11FDD 003F
+11FDD 0061
+11FDD 0041
+11FDD 0062
+11FDE 0021
+11FDE 003F
+11FDE 0061
+11FDE 0041
+11FDE 0062
+11FDF 0021
+11FDF 003F
+11FDF 0061
+11FDF 0041
+11FDF 0062
+11FE0 0021
+11FE0 003F
+11FE0 0061
+11FE0 0041
+11FE0 0062
0E3F 0021
0E3F 003F
0E3F 0061
@@ -39239,6 +40235,11 @@ A838 0062
17DB 0061
17DB 0041
17DB 0062
+1E2FF 0021
+1E2FF 003F
+1E2FF 0061
+1E2FF 0041
+1E2FF 0062
20A0 0021
20A0 003F
20A0 0061
@@ -39519,6 +40520,111 @@ A835 0062
0BF2 0061
0BF2 0041
0BF2 0062
+11FC0 0021
+11FC0 003F
+11FC0 0061
+11FC0 0041
+11FC0 0062
+11FC1 0021
+11FC1 003F
+11FC1 0061
+11FC1 0041
+11FC1 0062
+11FC2 0021
+11FC2 003F
+11FC2 0061
+11FC2 0041
+11FC2 0062
+11FC3 0021
+11FC3 003F
+11FC3 0061
+11FC3 0041
+11FC3 0062
+11FC4 0021
+11FC4 003F
+11FC4 0061
+11FC4 0041
+11FC4 0062
+11FC5 0021
+11FC5 003F
+11FC5 0061
+11FC5 0041
+11FC5 0062
+11FC6 0021
+11FC6 003F
+11FC6 0061
+11FC6 0041
+11FC6 0062
+11FC7 0021
+11FC7 003F
+11FC7 0061
+11FC7 0041
+11FC7 0062
+11FC8 0021
+11FC8 003F
+11FC8 0061
+11FC8 0041
+11FC8 0062
+11FC9 0021
+11FC9 003F
+11FC9 0061
+11FC9 0041
+11FC9 0062
+11FCA 0021
+11FCA 003F
+11FCA 0061
+11FCA 0041
+11FCA 0062
+11FCB 0021
+11FCB 003F
+11FCB 0061
+11FCB 0041
+11FCB 0062
+11FCC 0021
+11FCC 003F
+11FCC 0061
+11FCC 0041
+11FCC 0062
+11FCD 0021
+11FCD 003F
+11FCD 0061
+11FCD 0041
+11FCD 0062
+11FCE 0021
+11FCE 003F
+11FCE 0061
+11FCE 0041
+11FCE 0062
+11FCF 0021
+11FCF 003F
+11FCF 0061
+11FCF 0041
+11FCF 0062
+11FD0 0021
+11FD0 003F
+11FD0 0061
+11FD0 0041
+11FD0 0062
+11FD1 0021
+11FD1 003F
+11FD1 0061
+11FD1 0041
+11FD1 0062
+11FD2 0021
+11FD2 003F
+11FD2 0061
+11FD2 0041
+11FD2 0062
+11FD3 0021
+11FD3 003F
+11FD3 0061
+11FD3 0041
+11FD3 0062
+11FD4 0021
+11FD4 003F
+11FD4 0061
+11FD4 0041
+11FD4 0062
0D58 0021
0D58 003F
0D58 0061
@@ -41149,6 +42255,221 @@ A835 0062
1ECB4 0061
1ECB4 0041
1ECB4 0062
+1ED0A 0021
+1ED0A 003F
+1ED0A 0061
+1ED0A 0041
+1ED0A 0062
+1ED0B 0021
+1ED0B 003F
+1ED0B 0061
+1ED0B 0041
+1ED0B 0062
+1ED0C 0021
+1ED0C 003F
+1ED0C 0061
+1ED0C 0041
+1ED0C 0062
+1ED0D 0021
+1ED0D 003F
+1ED0D 0061
+1ED0D 0041
+1ED0D 0062
+1ED0E 0021
+1ED0E 003F
+1ED0E 0061
+1ED0E 0041
+1ED0E 0062
+1ED0F 0021
+1ED0F 003F
+1ED0F 0061
+1ED0F 0041
+1ED0F 0062
+1ED10 0021
+1ED10 003F
+1ED10 0061
+1ED10 0041
+1ED10 0062
+1ED11 0021
+1ED11 003F
+1ED11 0061
+1ED11 0041
+1ED11 0062
+1ED12 0021
+1ED12 003F
+1ED12 0061
+1ED12 0041
+1ED12 0062
+1ED13 0021
+1ED13 003F
+1ED13 0061
+1ED13 0041
+1ED13 0062
+1ED14 0021
+1ED14 003F
+1ED14 0061
+1ED14 0041
+1ED14 0062
+1ED15 0021
+1ED15 003F
+1ED15 0061
+1ED15 0041
+1ED15 0062
+1ED16 0021
+1ED16 003F
+1ED16 0061
+1ED16 0041
+1ED16 0062
+1ED17 0021
+1ED17 003F
+1ED17 0061
+1ED17 0041
+1ED17 0062
+1ED18 0021
+1ED18 003F
+1ED18 0061
+1ED18 0041
+1ED18 0062
+1ED19 0021
+1ED19 003F
+1ED19 0061
+1ED19 0041
+1ED19 0062
+1ED1A 0021
+1ED1A 003F
+1ED1A 0061
+1ED1A 0041
+1ED1A 0062
+1ED1B 0021
+1ED1B 003F
+1ED1B 0061
+1ED1B 0041
+1ED1B 0062
+1ED1C 0021
+1ED1C 003F
+1ED1C 0061
+1ED1C 0041
+1ED1C 0062
+1ED1D 0021
+1ED1D 003F
+1ED1D 0061
+1ED1D 0041
+1ED1D 0062
+1ED1E 0021
+1ED1E 003F
+1ED1E 0061
+1ED1E 0041
+1ED1E 0062
+1ED1F 0021
+1ED1F 003F
+1ED1F 0061
+1ED1F 0041
+1ED1F 0062
+1ED20 0021
+1ED20 003F
+1ED20 0061
+1ED20 0041
+1ED20 0062
+1ED21 0021
+1ED21 003F
+1ED21 0061
+1ED21 0041
+1ED21 0062
+1ED22 0021
+1ED22 003F
+1ED22 0061
+1ED22 0041
+1ED22 0062
+1ED23 0021
+1ED23 003F
+1ED23 0061
+1ED23 0041
+1ED23 0062
+1ED24 0021
+1ED24 003F
+1ED24 0061
+1ED24 0041
+1ED24 0062
+1ED25 0021
+1ED25 003F
+1ED25 0061
+1ED25 0041
+1ED25 0062
+1ED26 0021
+1ED26 003F
+1ED26 0061
+1ED26 0041
+1ED26 0062
+1ED27 0021
+1ED27 003F
+1ED27 0061
+1ED27 0041
+1ED27 0062
+1ED28 0021
+1ED28 003F
+1ED28 0061
+1ED28 0041
+1ED28 0062
+1ED29 0021
+1ED29 003F
+1ED29 0061
+1ED29 0041
+1ED29 0062
+1ED2A 0021
+1ED2A 003F
+1ED2A 0061
+1ED2A 0041
+1ED2A 0062
+1ED2B 0021
+1ED2B 003F
+1ED2B 0061
+1ED2B 0041
+1ED2B 0062
+1ED2C 0021
+1ED2C 003F
+1ED2C 0061
+1ED2C 0041
+1ED2C 0062
+1ED2D 0021
+1ED2D 003F
+1ED2D 0061
+1ED2D 0041
+1ED2D 0062
+1ED37 0021
+1ED37 003F
+1ED37 0061
+1ED37 0041
+1ED37 0062
+1ED38 0021
+1ED38 003F
+1ED38 0061
+1ED38 0041
+1ED38 0062
+1ED39 0021
+1ED39 003F
+1ED39 0061
+1ED39 0041
+1ED39 0062
+1ED3A 0021
+1ED3A 003F
+1ED3A 0061
+1ED3A 0041
+1ED3A 0062
+1ED3B 0021
+1ED3B 003F
+1ED3B 0061
+1ED3B 0041
+1ED3B 0062
+1ED3C 0021
+1ED3C 003F
+1ED3C 0061
+1ED3C 0041
+1ED3C 0062
+1ED3D 0021
+1ED3D 003F
+1ED3D 0061
+1ED3D 0041
+1ED3D 0062
109C9 0021
109C9 003F
109C9 0061
@@ -41619,6 +42940,8 @@ ABF0 0021
16B50 0021
16E80 0021
1D2E0 0021
+1E140 0021
+1E2F0 0021
1E950 0021
FF10 0021
0F33 0021
@@ -41693,6 +43016,8 @@ ABF0 003F
16B50 003F
16E80 003F
1D2E0 003F
+1E140 003F
+1E2F0 003F
1E950 003F
FF10 003F
0F33 003F
@@ -41777,6 +43102,8 @@ ABF0 0061
16B50 0061
16E80 0061
1D2E0 0061
+1E140 0061
+1E2F0 0061
1E950 0061
0030 0041
0660 0041
@@ -41838,6 +43165,8 @@ ABF0 0041
16B50 0041
16E80 0041
1D2E0 0041
+1E140 0041
+1E2F0 0041
1E950 0041
FF10 0061
FF10 0041
@@ -41925,6 +43254,8 @@ ABF0 0062
16B50 0062
16E80 0062
1D2E0 0062
+1E140 0062
+1E2F0 0062
1E950 0062
FF10 0062
0F33 0062
@@ -42048,10 +43379,13 @@ ABF1 0021
1D360 0021
1D372 0021
1D377 0021
+1E141 0021
+1E2F1 0021
1E8C7 0021
1E951 0021
1EC71 0021
1ECA3 0021
+1ED01 0021
FF11 0021
0F2A 0021
1D7CF 0021
@@ -42167,10 +43501,13 @@ ABF1 003F
1D360 003F
1D372 003F
1D377 003F
+1E141 003F
+1E2F1 003F
1E8C7 003F
1E951 003F
1EC71 003F
1ECA3 003F
+1ED01 003F
FF11 003F
0F2A 003F
1D7CF 003F
@@ -42631,10 +43968,13 @@ ABF1 0061
1D360 0061
1D372 0061
1D377 0061
+1E141 0061
+1E2F1 0061
1E8C7 0061
1E951 0061
1EC71 0061
1ECA3 0061
+1ED01 0061
0031 0041
0661 0041
06F1 0041
@@ -42734,10 +44074,13 @@ ABF1 0041
1D360 0041
1D372 0041
1D377 0041
+1E141 0041
+1E2F1 0041
1E8C7 0041
1E951 0041
1EC71 0041
1ECA3 0041
+1ED01 0041
FF11 0061
FF11 0041
0F2A 0061
@@ -42869,10 +44212,13 @@ ABF1 0062
1D360 0062
1D372 0062
1D377 0062
+1E141 0062
+1E2F1 0062
1E8C7 0062
1E951 0062
1EC71 0062
1ECA3 0062
+1ED01 0062
FF11 0062
0F2A 0062
1D7CF 0062
@@ -43003,10 +44349,13 @@ ABF2 0021
1D2E2 0021
1D361 0021
1D373 0021
+1E142 0021
+1E2F2 0021
1E8C8 0021
1E952 0021
1EC72 0021
1ECA4 0021
+1ED02 0021
FF12 0021
0F2B 0021
1D7D0 0021
@@ -43023,6 +44372,7 @@ FF12 0021
2082 0021
16E95 0021
1ECB2 0021
+1ED2F 0021
0032 003F
0662 003F
06F2 003F
@@ -43117,10 +44467,13 @@ ABF2 003F
1D2E2 003F
1D361 003F
1D373 003F
+1E142 003F
+1E2F2 003F
1E8C8 003F
1E952 003F
1EC72 003F
1ECA4 003F
+1ED02 003F
FF12 003F
0F2B 003F
1D7D0 003F
@@ -43137,6 +44490,7 @@ FF12 003F
2082 003F
16E95 003F
1ECB2 003F
+1ED2F 003F
2489 0021
2489 003F
2489 0061
@@ -43391,10 +44745,13 @@ ABF2 0061
1D2E2 0061
1D361 0061
1D373 0061
+1E142 0061
+1E2F2 0061
1E8C8 0061
1E952 0061
1EC72 0061
1ECA4 0061
+1ED02 0061
0032 0041
0662 0041
06F2 0041
@@ -43489,10 +44846,13 @@ ABF2 0041
1D2E2 0041
1D361 0041
1D373 0041
+1E142 0041
+1E2F2 0041
1E8C8 0041
1E952 0041
1EC72 0041
1ECA4 0041
+1ED02 0041
FF12 0061
FF12 0041
0F2B 0061
@@ -43523,8 +44883,10 @@ FF12 0041
2082 0041
16E95 0061
1ECB2 0061
+1ED2F 0061
16E95 0041
1ECB2 0041
+1ED2F 0041
0032 0062
0662 0062
06F2 0062
@@ -43619,10 +44981,13 @@ ABF2 0062
1D2E2 0062
1D361 0062
1D373 0062
+1E142 0062
+1E2F2 0062
1E8C8 0062
1E952 0062
1EC72 0062
1ECA4 0062
+1ED02 0062
FF12 0062
0F2B 0062
1D7D0 0062
@@ -43639,6 +45004,7 @@ FF12 0062
2082 0062
16E95 0062
1ECB2 0062
+1ED2F 0062
1F19D 0021
1F19D 003F
1F19D 0061
@@ -43763,10 +45129,13 @@ ABF3 0021
1D2E3 0021
1D362 0021
1D374 0021
+1E143 0021
+1E2F3 0021
1E8C9 0021
1E953 0021
1EC73 0021
1ECA5 0021
+1ED03 0021
FF13 0021
0F2C 0021
1D7D1 0021
@@ -43782,6 +45151,7 @@ FF13 0021
00B3 0021
2083 0021
16E96 0021
+1ED30 0021
0033 003F
0663 003F
06F3 003F
@@ -43876,10 +45246,13 @@ ABF3 003F
1D2E3 003F
1D362 003F
1D374 003F
+1E143 003F
+1E2F3 003F
1E8C9 003F
1E953 003F
1EC73 003F
1ECA5 003F
+1ED03 003F
FF13 003F
0F2C 003F
1D7D1 003F
@@ -43895,6 +45268,7 @@ FF13 003F
00B3 003F
2083 003F
16E96 003F
+1ED30 003F
248A 0021
248A 003F
248A 0061
@@ -44074,10 +45448,13 @@ ABF3 0061
1D2E3 0061
1D362 0061
1D374 0061
+1E143 0061
+1E2F3 0061
1E8C9 0061
1E953 0061
1EC73 0061
1ECA5 0061
+1ED03 0061
0033 0041
0663 0041
06F3 0041
@@ -44172,10 +45549,13 @@ ABF3 0041
1D2E3 0041
1D362 0041
1D374 0041
+1E143 0041
+1E2F3 0041
1E8C9 0041
1E953 0041
1EC73 0041
1ECA5 0041
+1ED03 0041
FF13 0061
FF13 0041
0F2C 0061
@@ -44206,6 +45586,8 @@ FF13 0041
2083 0041
16E96 0061
16E96 0041
+1ED30 0061
+1ED30 0041
0033 0062
0663 0062
06F3 0062
@@ -44300,10 +45682,13 @@ ABF3 0062
1D2E3 0062
1D362 0062
1D374 0062
+1E143 0062
+1E2F3 0062
1E8C9 0062
1E953 0062
1EC73 0062
1ECA5 0062
+1ED03 0062
FF13 0062
0F2C 0062
1D7D1 0062
@@ -44319,6 +45704,7 @@ FF13 0062
00B3 0062
2083 0062
16E96 0062
+1ED30 0062
1F19B 0021
1F19B 003F
1F19B 0061
@@ -44436,10 +45822,13 @@ ABF4 0021
1D2E4 0021
1D363 0021
1D375 0021
+1E144 0021
+1E2F4 0021
1E8CA 0021
1E954 0021
1EC74 0021
1ECA6 0021
+1ED04 0021
FF14 0021
0F2D 0021
1D7D2 0021
@@ -44454,6 +45843,7 @@ FF14 0021
278D 0021
2074 0021
2084 0021
+1ED31 0021
0034 003F
0664 003F
06F4 003F
@@ -44546,10 +45936,13 @@ ABF4 003F
1D2E4 003F
1D363 003F
1D375 003F
+1E144 003F
+1E2F4 003F
1E8CA 003F
1E954 003F
1EC74 003F
1ECA6 003F
+1ED04 003F
FF14 003F
0F2D 003F
1D7D2 003F
@@ -44564,6 +45957,7 @@ FF14 003F
278D 003F
2074 003F
2084 003F
+1ED31 003F
248B 0021
248B 003F
248B 0061
@@ -44721,10 +46115,13 @@ ABF4 0061
1D2E4 0061
1D363 0061
1D375 0061
+1E144 0061
+1E2F4 0061
1E8CA 0061
1E954 0061
1EC74 0061
1ECA6 0061
+1ED04 0061
0034 0041
0664 0041
06F4 0041
@@ -44817,10 +46214,13 @@ ABF4 0041
1D2E4 0041
1D363 0041
1D375 0041
+1E144 0041
+1E2F4 0041
1E8CA 0041
1E954 0041
1EC74 0041
1ECA6 0041
+1ED04 0041
FF14 0061
FF14 0041
0F2D 0061
@@ -44849,6 +46249,8 @@ FF14 0041
2074 0041
2084 0061
2084 0041
+1ED31 0061
+1ED31 0041
0034 0062
0664 0062
06F4 0062
@@ -44941,10 +46343,13 @@ ABF4 0062
1D2E4 0062
1D363 0062
1D375 0062
+1E144 0062
+1E2F4 0062
1E8CA 0062
1E954 0062
1EC74 0062
1ECA6 0062
+1ED04 0062
FF14 0062
0F2D 0062
1D7D2 0062
@@ -44959,6 +46364,7 @@ FF14 0062
278D 0062
2074 0062
2084 0062
+1ED31 0062
1F19E 0021
1F19E 003F
1F19E 0061
@@ -45077,10 +46483,13 @@ ABF5 0021
1D364 0021
1D376 0021
1D378 0021
+1E145 0021
+1E2F5 0021
1E8CB 0021
1E955 0021
1EC75 0021
1ECA7 0021
+1ED05 0021
FF15 0021
0F2E 0021
1D7D3 0021
@@ -45095,6 +46504,7 @@ FF15 0021
278E 0021
2075 0021
2085 0021
+1ED32 0021
0035 003F
0665 003F
06F5 003F
@@ -45188,10 +46598,13 @@ ABF5 003F
1D364 003F
1D376 003F
1D378 003F
+1E145 003F
+1E2F5 003F
1E8CB 003F
1E955 003F
1EC75 003F
1ECA7 003F
+1ED05 003F
FF15 003F
0F2E 003F
1D7D3 003F
@@ -45206,6 +46619,7 @@ FF15 003F
278E 003F
2075 003F
2085 003F
+1ED32 003F
248C 0021
248C 003F
1F1A0 0021
@@ -45329,10 +46743,13 @@ ABF5 0061
1D364 0061
1D376 0061
1D378 0061
+1E145 0061
+1E2F5 0061
1E8CB 0061
1E955 0061
1EC75 0061
1ECA7 0061
+1ED05 0061
0035 0041
0665 0041
06F5 0041
@@ -45426,10 +46843,13 @@ ABF5 0041
1D364 0041
1D376 0041
1D378 0041
+1E145 0041
+1E2F5 0041
1E8CB 0041
1E955 0041
1EC75 0041
1ECA7 0041
+1ED05 0041
FF15 0061
FF15 0041
0F2E 0061
@@ -45458,6 +46878,8 @@ FF15 0041
2075 0041
2085 0061
2085 0041
+1ED32 0061
+1ED32 0041
0035 0062
0665 0062
06F5 0062
@@ -45551,10 +46973,13 @@ ABF5 0062
1D364 0062
1D376 0062
1D378 0062
+1E145 0062
+1E2F5 0062
1E8CB 0062
1E955 0062
1EC75 0062
1ECA7 0062
+1ED05 0062
FF15 0062
0F2E 0062
1D7D3 0062
@@ -45569,6 +46994,7 @@ FF15 0062
278E 0062
2075 0062
2085 0062
+1ED32 0062
33E4 0021
33E4 003F
33E4 0061
@@ -45665,10 +47091,13 @@ ABF6 0021
16E86 0021
1D2E6 0021
1D365 0021
+1E146 0021
+1E2F6 0021
1E8CC 0021
1E956 0021
1EC76 0021
1ECA8 0021
+1ED06 0021
FF16 0021
0F2F 0021
1D7D4 0021
@@ -45683,6 +47112,7 @@ FF16 0021
278F 0021
2076 0021
2086 0021
+1ED33 0021
0036 003F
0666 003F
06F6 003F
@@ -45759,10 +47189,13 @@ ABF6 003F
16E86 003F
1D2E6 003F
1D365 003F
+1E146 003F
+1E2F6 003F
1E8CC 003F
1E956 003F
1EC76 003F
1ECA8 003F
+1ED06 003F
FF16 003F
0F2F 003F
1D7D4 003F
@@ -45777,6 +47210,7 @@ FF16 003F
278F 003F
2076 003F
2086 003F
+1ED33 003F
248D 0021
248D 003F
248D 0061
@@ -45868,10 +47302,13 @@ ABF6 0061
16E86 0061
1D2E6 0061
1D365 0061
+1E146 0061
+1E2F6 0061
1E8CC 0061
1E956 0061
1EC76 0061
1ECA8 0061
+1ED06 0061
0036 0041
0666 0041
06F6 0041
@@ -45948,10 +47385,13 @@ ABF6 0041
16E86 0041
1D2E6 0041
1D365 0041
+1E146 0041
+1E2F6 0041
1E8CC 0041
1E956 0041
1EC76 0041
1ECA8 0041
+1ED06 0041
FF16 0061
FF16 0041
0F2F 0061
@@ -45980,6 +47420,8 @@ FF16 0041
2076 0041
2086 0061
2086 0041
+1ED33 0061
+1ED33 0041
0036 0062
0666 0062
06F6 0062
@@ -46056,10 +47498,13 @@ ABF6 0062
16E86 0062
1D2E6 0062
1D365 0062
+1E146 0062
+1E2F6 0062
1E8CC 0062
1E956 0062
1EC76 0062
1ECA8 0062
+1ED06 0062
FF16 0062
0F2F 0062
1D7D4 0062
@@ -46074,6 +47519,7 @@ FF16 0062
278F 0062
2076 0062
2086 0062
+1ED33 0062
33E5 0021
33E5 003F
33E5 0061
@@ -46170,10 +47616,13 @@ ABF7 0021
16E87 0021
1D2E7 0021
1D366 0021
+1E147 0021
+1E2F7 0021
1E8CD 0021
1E957 0021
1EC77 0021
1ECA9 0021
+1ED07 0021
FF17 0021
0F30 0021
1D7D5 0021
@@ -46188,6 +47637,7 @@ FF17 0021
2790 0021
2077 0021
2087 0021
+1ED34 0021
0037 003F
0667 003F
06F7 003F
@@ -46264,10 +47714,13 @@ ABF7 003F
16E87 003F
1D2E7 003F
1D366 003F
+1E147 003F
+1E2F7 003F
1E8CD 003F
1E957 003F
1EC77 003F
1ECA9 003F
+1ED07 003F
FF17 003F
0F30 003F
1D7D5 003F
@@ -46282,6 +47735,7 @@ FF17 003F
2790 003F
2077 003F
2087 003F
+1ED34 003F
248E 0021
248E 003F
1F1A1 0021
@@ -46378,10 +47832,13 @@ ABF7 0061
16E87 0061
1D2E7 0061
1D366 0061
+1E147 0061
+1E2F7 0061
1E8CD 0061
1E957 0061
1EC77 0061
1ECA9 0061
+1ED07 0061
0037 0041
0667 0041
06F7 0041
@@ -46458,10 +47915,13 @@ ABF7 0041
16E87 0041
1D2E7 0041
1D366 0041
+1E147 0041
+1E2F7 0041
1E8CD 0041
1E957 0041
1EC77 0041
1ECA9 0041
+1ED07 0041
FF17 0061
FF17 0041
0F30 0061
@@ -46490,6 +47950,8 @@ FF17 0041
2077 0041
2087 0061
2087 0041
+1ED34 0061
+1ED34 0041
0037 0062
0667 0062
06F7 0062
@@ -46566,10 +48028,13 @@ ABF7 0062
16E87 0062
1D2E7 0062
1D366 0062
+1E147 0062
+1E2F7 0062
1E8CD 0062
1E957 0062
1EC77 0062
1ECA9 0062
+1ED07 0062
FF17 0062
0F30 0062
1D7D5 0062
@@ -46584,6 +48049,7 @@ FF17 0062
2790 0062
2077 0062
2087 0062
+1ED34 0062
33E6 0021
33E6 003F
33E6 0061
@@ -46679,10 +48145,13 @@ ABF8 0021
16E88 0021
1D2E8 0021
1D367 0021
+1E148 0021
+1E2F8 0021
1E8CE 0021
1E958 0021
1EC78 0021
1ECAA 0021
+1ED08 0021
FF18 0021
0F31 0021
1D7D6 0021
@@ -46697,6 +48166,7 @@ FF18 0021
2791 0021
2078 0021
2088 0021
+1ED35 0021
0038 003F
0668 003F
06F8 003F
@@ -46772,10 +48242,13 @@ ABF8 003F
16E88 003F
1D2E8 003F
1D367 003F
+1E148 003F
+1E2F8 003F
1E8CE 003F
1E958 003F
1EC78 003F
1ECAA 003F
+1ED08 003F
FF18 003F
0F31 003F
1D7D6 003F
@@ -46790,6 +48263,7 @@ FF18 003F
2791 003F
2078 003F
2088 003F
+1ED35 003F
248F 0021
248F 003F
248F 0061
@@ -46875,10 +48349,13 @@ ABF8 0061
16E88 0061
1D2E8 0061
1D367 0061
+1E148 0061
+1E2F8 0061
1E8CE 0061
1E958 0061
1EC78 0061
1ECAA 0061
+1ED08 0061
0038 0041
0668 0041
06F8 0041
@@ -46954,10 +48431,13 @@ ABF8 0041
16E88 0041
1D2E8 0041
1D367 0041
+1E148 0041
+1E2F8 0041
1E8CE 0041
1E958 0041
1EC78 0041
1ECAA 0041
+1ED08 0041
FF18 0061
FF18 0041
0F31 0061
@@ -46986,6 +48466,8 @@ FF18 0041
2078 0041
2088 0061
2088 0041
+1ED35 0061
+1ED35 0041
0038 0062
0668 0062
06F8 0062
@@ -47061,10 +48543,13 @@ ABF8 0062
16E88 0062
1D2E8 0062
1D367 0062
+1E148 0062
+1E2F8 0062
1E8CE 0062
1E958 0062
1EC78 0062
1ECAA 0062
+1ED08 0062
FF18 0062
0F31 0062
1D7D6 0062
@@ -47079,6 +48564,7 @@ FF18 0062
2791 0062
2078 0062
2088 0062
+1ED35 0062
1F19F 0021
1F19F 003F
1F19F 0061
@@ -47181,10 +48667,13 @@ ABF9 0021
16E89 0021
1D2E9 0021
1D368 0021
+1E149 0021
+1E2F9 0021
1E8CF 0021
1E959 0021
1EC79 0021
1ECAB 0021
+1ED09 0021
FF19 0021
0F32 0021
1D7D7 0021
@@ -47199,6 +48688,7 @@ FF19 0021
2792 0021
2079 0021
2089 0021
+1ED36 0021
0039 003F
0669 003F
06F9 003F
@@ -47276,10 +48766,13 @@ ABF9 003F
16E89 003F
1D2E9 003F
1D368 003F
+1E149 003F
+1E2F9 003F
1E8CF 003F
1E959 003F
1EC79 003F
1ECAB 003F
+1ED09 003F
FF19 003F
0F32 003F
1D7D7 003F
@@ -47294,6 +48787,7 @@ FF19 003F
2792 003F
2079 003F
2089 003F
+1ED36 003F
2490 0021
2490 003F
2490 0061
@@ -47376,10 +48870,13 @@ ABF9 0061
16E89 0061
1D2E9 0061
1D368 0061
+1E149 0061
+1E2F9 0061
1E8CF 0061
1E959 0061
1EC79 0061
1ECAB 0061
+1ED09 0061
0039 0041
0669 0041
06F9 0041
@@ -47457,10 +48954,13 @@ ABF9 0041
16E89 0041
1D2E9 0041
1D368 0041
+1E149 0041
+1E2F9 0041
1E8CF 0041
1E959 0041
1EC79 0041
1ECAB 0041
+1ED09 0041
FF19 0061
FF19 0041
0F32 0061
@@ -47489,6 +48989,8 @@ FF19 0041
2079 0041
2089 0061
2089 0041
+1ED36 0061
+1ED36 0041
0039 0062
0669 0062
06F9 0062
@@ -47566,10 +49068,13 @@ ABF9 0062
16E89 0062
1D2E9 0062
1D368 0062
+1E149 0062
+1E2F9 0062
1E8CF 0062
1E959 0062
1EC79 0062
1ECAB 0062
+1ED09 0062
FF19 0062
0F32 0062
1D7D7 0062
@@ -47584,6 +49089,7 @@ FF19 0062
2792 0062
2079 0062
2089 0062
+1ED36 0062
33E8 0021
33E8 003F
33E8 0061
@@ -47921,6 +49427,15 @@ FFFB 0061
11372 0061
11373 0061
11374 0061
+13430 0061
+13431 0061
+13432 0061
+13433 0061
+13434 0061
+13435 0061
+13436 0061
+13437 0061
+13438 0061
1BCA0 0061
1BCA1 0061
1BCA2 0061
@@ -48759,6 +50274,15 @@ FFFB 0041
11372 0041
11373 0041
11374 0041
+13430 0041
+13431 0041
+13432 0041
+13433 0041
+13434 0041
+13435 0041
+13436 0041
+13437 0041
+13438 0041
1BCA0 0041
1BCA1 0041
1BCA2 0041
@@ -50373,6 +51897,7 @@ A981 0061
1163D 0061
116AB 0061
11837 0061
+119DE 0061
11A38 0061
11A96 0061
11C3D 0061
@@ -50416,6 +51941,7 @@ A981 0041
1163D 0041
116AB 0041
11837 0041
+119DE 0041
11A38 0041
11A96 0041
11C3D 0041
@@ -50452,6 +51978,7 @@ A983 0061
1163E 0061
116AC 0061
11838 0061
+119DF 0061
11A39 0061
11A97 0061
11C3E 0061
@@ -50487,6 +52014,7 @@ A983 0041
1163E 0041
116AC 0041
11838 0041
+119DF 0041
11A39 0041
11A97 0041
11C3E 0041
@@ -50593,19 +52121,41 @@ A92D 0041
193B 0061
193B 0041
16B30 0061
+1E131 0061
16B30 0041
+1E131 0041
16B31 0061
+1E136 0061
16B31 0041
+1E136 0041
16B32 0061
+1E132 0061
16B32 0041
+1E132 0041
16B33 0061
+1E133 0061
16B33 0041
+1E133 0041
16B34 0061
+1E130 0061
16B34 0041
+1E130 0041
16B35 0061
+1E134 0061
16B35 0041
+1E134 0041
16B36 0061
+1E135 0061
16B36 0041
+1E135 0041
+1E2EC 0061
+1E2EC 0041
+1E2ED 0061
+1E2ED 0041
+1E2EE 0061
+1E2EE 0041
+1E2EF 0061
+1E2EF 0041
302A 0061
302A 0041
302B 0061
@@ -51355,6 +52905,16 @@ A73C 0062
1D8F 0061
1D8F 0041
1D8F 0062
+A7BB 0021
+A7BA 0021
+A7BB 003F
+A7BA 003F
+A7BB 0061
+A7BB 0041
+A7BA 0061
+A7BA 0041
+A7BB 0062
+A7BA 0062
1D01 0021
1D01 003F
1D01 0061
@@ -51764,6 +53324,15 @@ FFFB 0062
11372 0062
11373 0062
11374 0062
+13430 0062
+13431 0062
+13432 0062
+13433 0062
+13434 0062
+13435 0062
+13436 0062
+13437 0062
+13438 0062
1BCA0 0062
1BCA1 0062
1BCA2 0062
@@ -52762,6 +54331,7 @@ A981 0062
1163D 0062
116AB 0062
11837 0062
+119DE 0062
11A38 0062
11A96 0062
11C3D 0062
@@ -52798,6 +54368,7 @@ A983 0062
1163E 0062
116AC 0062
11838 0062
+119DF 0062
11A39 0062
11A97 0062
11C3E 0062
@@ -52854,12 +54425,23 @@ A92D 0062
193A 0062
193B 0062
16B30 0062
+1E131 0062
16B31 0062
+1E136 0062
16B32 0062
+1E132 0062
16B33 0062
+1E133 0062
16B34 0062
+1E130 0062
16B35 0062
+1E134 0062
16B36 0062
+1E135 0062
+1E2EC 0062
+1E2ED 0062
+1E2EE 0062
+1E2EF 0062
302A 0062
302B 0062
302C 0062
@@ -53594,10 +55176,15 @@ A792 0041
A793 0062
A792 0062
A794 0021
+A7C4 0021
A794 003F
+A7C4 003F
A794 0061
A794 0041
+A7C4 0061
+A7C4 0041
A794 0062
+A7C4 0062
0188 0021
0187 0021
0188 003F
@@ -54075,6 +55662,11 @@ A779 0062
01C6 0062
01C5 0062
01C4 0062
+AB66 0021
+AB66 003F
+AB66 0061
+AB66 0041
+AB66 0062
02A5 0021
02A5 003F
02A5 0061
@@ -56813,6 +58405,16 @@ A7F7 0062
1D96 0061
1D96 0041
1D96 0062
+A7BD 0021
+A7BC 0021
+A7BD 003F
+A7BC 003F
+A7BD 0061
+A7BD 0041
+A7BC 0061
+A7BC 0041
+A7BD 0062
+A7BC 0062
0269 0021
0196 0021
1DA5 0021
@@ -58521,6 +60123,11 @@ FF2D 0062
33AB 0061
33AB 0041
33AB 0062
+1F16C 0021
+1F16C 003F
+1F16C 0061
+1F16C 0041
+1F16C 0062
33B3 0021
33B3 003F
33B3 0061
@@ -61891,14 +63498,19 @@ A731 0062
1D8A 0041
1D8A 0062
0282 0021
+A7C5 0021
1DB3 0021
0282 003F
+A7C5 003F
1DB3 003F
0282 0061
0282 0041
+A7C5 0061
+A7C5 0041
1DB3 0061
1DB3 0041
0282 0062
+A7C5 0062
1DB3 0062
023F 0021
2C7E 0021
@@ -62334,6 +63946,11 @@ A786 0062
02A6 0041
01BE 0062
02A6 0062
+AB67 0021
+AB67 003F
+AB67 0061
+AB67 0041
+AB67 0062
02A7 0021
02A7 003F
02A7 0061
@@ -63261,6 +64878,16 @@ AB5F 0061
AB5F 0041
AB52 0062
AB5F 0062
+A7BF 0021
+A7BE 0021
+A7BF 003F
+A7BE 003F
+A7BF 0061
+A7BF 0041
+A7BE 0061
+A7BE 0041
+A7BF 0062
+A7BE 0062
0265 0021
A78D 0021
1DA3 0021
@@ -64030,6 +65657,16 @@ FF37 0062
1D21 0061
1D21 0041
1D21 0062
+A7C3 0021
+A7C2 0021
+A7C3 003F
+A7C2 003F
+A7C3 0061
+A7C3 0041
+A7C2 0061
+A7C2 0041
+A7C3 0062
+A7C2 0062
2C73 0021
2C72 0021
2C73 003F
@@ -65041,10 +66678,15 @@ FF3A 0062
1D76 0041
1D76 0062
1D8E 0021
+A7C6 0021
1D8E 003F
+A7C6 003F
1D8E 0061
1D8E 0041
+A7C6 0061
+A7C6 0041
1D8E 0062
+A7C6 0062
0225 0021
0224 0021
0225 003F
@@ -84828,6 +86470,7 @@ A8FE 0062
1CEF 0021
1CF0 0021
1CF1 0021
+1CFA 0021
1CE9 003F
1CEA 003F
1CEB 003F
@@ -84836,6 +86479,7 @@ A8FE 0062
1CEF 003F
1CF0 003F
1CF1 003F
+1CFA 003F
1CE9 0061
1CE9 0041
1CEA 0061
@@ -84845,6 +86489,7 @@ A8FE 0062
1CEF 0061
1CF0 0061
1CF1 0061
+1CFA 0061
1CEA 0041
1CEB 0041
1CEC 0041
@@ -84852,6 +86497,7 @@ A8FE 0062
1CEF 0041
1CF0 0041
1CF1 0041
+1CFA 0041
1CE9 0062
1CEA 0062
1CEB 0062
@@ -84860,6 +86506,7 @@ A8FE 0062
1CEF 0062
1CF0 0062
1CF1 0062
+1CFA 0062
1CF5 0021
1CF5 003F
1CF5 0061
@@ -91497,6 +93144,11 @@ A8C4 0062
11448 0061
11448 0041
11448 0062
+1145F 0021
+1145F 003F
+1145F 0061
+1145F 0041
+1145F 0062
11435 0021
11435 003F
11435 0061
@@ -92665,6 +94317,11 @@ A8C4 0062
1168B 0061
1168B 0041
1168B 0062
+116B8 0021
+116B8 003F
+116B8 0061
+116B8 0041
+116B8 0062
1168C 0021
1168C 003F
1168C 0061
@@ -92857,6 +94514,318 @@ A8C4 0062
116B6 0061
116B6 0041
116B6 0062
+119A0 0021
+119A0 003F
+119A0 0061
+119A0 0041
+119A0 0062
+119A1 0021
+119A1 003F
+119A1 0061
+119A1 0041
+119A1 0062
+119A2 0021
+119A2 003F
+119A2 0061
+119A2 0041
+119A2 0062
+119A3 0021
+119A3 003F
+119A3 0061
+119A3 0041
+119A3 0062
+119A4 0021
+119A4 003F
+119A4 0061
+119A4 0041
+119A4 0062
+119A5 0021
+119A5 003F
+119A5 0061
+119A5 0041
+119A5 0062
+119A6 0021
+119A6 003F
+119A6 0061
+119A6 0041
+119A6 0062
+119A7 0021
+119A7 003F
+119A7 0061
+119A7 0041
+119A7 0062
+119AA 0021
+119AA 003F
+119AA 0061
+119AA 0041
+119AA 0062
+119AB 0021
+119AB 003F
+119AB 0061
+119AB 0041
+119AB 0062
+119AC 0021
+119AC 003F
+119AC 0061
+119AC 0041
+119AC 0062
+119AD 0021
+119AD 003F
+119AD 0061
+119AD 0041
+119AD 0062
+119AE 0021
+119AE 003F
+119AE 0061
+119AE 0041
+119AE 0062
+119AF 0021
+119AF 003F
+119AF 0061
+119AF 0041
+119AF 0062
+119B0 0021
+119B0 003F
+119B0 0061
+119B0 0041
+119B0 0062
+119B1 0021
+119B1 003F
+119B1 0061
+119B1 0041
+119B1 0062
+119B2 0021
+119B2 003F
+119B2 0061
+119B2 0041
+119B2 0062
+119B3 0021
+119B3 003F
+119B3 0061
+119B3 0041
+119B3 0062
+119B4 0021
+119B4 003F
+119B4 0061
+119B4 0041
+119B4 0062
+119B5 0021
+119B5 003F
+119B5 0061
+119B5 0041
+119B5 0062
+119B6 0021
+119B6 003F
+119B6 0061
+119B6 0041
+119B6 0062
+119B7 0021
+119B7 003F
+119B7 0061
+119B7 0041
+119B7 0062
+119B8 0021
+119B8 003F
+119B8 0061
+119B8 0041
+119B8 0062
+119B9 0021
+119B9 003F
+119B9 0061
+119B9 0041
+119B9 0062
+119BA 0021
+119BA 003F
+119BA 0061
+119BA 0041
+119BA 0062
+119BB 0021
+119BB 003F
+119BB 0061
+119BB 0041
+119BB 0062
+119BC 0021
+119BC 003F
+119BC 0061
+119BC 0041
+119BC 0062
+119BD 0021
+119BD 003F
+119BD 0061
+119BD 0041
+119BD 0062
+119BE 0021
+119BE 003F
+119BE 0061
+119BE 0041
+119BE 0062
+119BF 0021
+119BF 003F
+119BF 0061
+119BF 0041
+119BF 0062
+119C0 0021
+119C0 003F
+119C0 0061
+119C0 0041
+119C0 0062
+119C1 0021
+119C1 003F
+119C1 0061
+119C1 0041
+119C1 0062
+119C2 0021
+119C2 003F
+119C2 0061
+119C2 0041
+119C2 0062
+119C3 0021
+119C3 003F
+119C3 0061
+119C3 0041
+119C3 0062
+119C4 0021
+119C4 003F
+119C4 0061
+119C4 0041
+119C4 0062
+119C5 0021
+119C5 003F
+119C5 0061
+119C5 0041
+119C5 0062
+119C6 0021
+119C6 003F
+119C6 0061
+119C6 0041
+119C6 0062
+119C7 0021
+119C7 003F
+119C7 0061
+119C7 0041
+119C7 0062
+119C8 0021
+119C8 003F
+119C8 0061
+119C8 0041
+119C8 0062
+119C9 0021
+119C9 003F
+119C9 0061
+119C9 0041
+119C9 0062
+119CA 0021
+119CA 003F
+119CA 0061
+119CA 0041
+119CA 0062
+119CB 0021
+119CB 003F
+119CB 0061
+119CB 0041
+119CB 0062
+119CC 0021
+119CC 003F
+119CC 0061
+119CC 0041
+119CC 0062
+119CD 0021
+119CD 003F
+119CD 0061
+119CD 0041
+119CD 0062
+119CE 0021
+119CE 003F
+119CE 0061
+119CE 0041
+119CE 0062
+119CF 0021
+119CF 003F
+119CF 0061
+119CF 0041
+119CF 0062
+119D0 0021
+119D0 003F
+119D0 0061
+119D0 0041
+119D0 0062
+119E1 0021
+119E1 003F
+119E1 0061
+119E1 0041
+119E1 0062
+119E3 0021
+119E3 003F
+119E3 0061
+119E3 0041
+119E3 0062
+119D1 0021
+119D1 003F
+119D1 0061
+119D1 0041
+119D1 0062
+119D2 0021
+119D2 003F
+119D2 0061
+119D2 0041
+119D2 0062
+119D3 0021
+119D3 003F
+119D3 0061
+119D3 0041
+119D3 0062
+119D4 0021
+119D4 003F
+119D4 0061
+119D4 0041
+119D4 0062
+119D5 0021
+119D5 003F
+119D5 0061
+119D5 0041
+119D5 0062
+119D6 0021
+119D6 003F
+119D6 0061
+119D6 0041
+119D6 0062
+119D7 0021
+119D7 003F
+119D7 0061
+119D7 0041
+119D7 0062
+119DA 0021
+119DA 003F
+119DA 0061
+119DA 0041
+119DA 0062
+119E4 0021
+119E4 003F
+119E4 0061
+119E4 0041
+119E4 0062
+119DB 0021
+119DB 003F
+119DB 0061
+119DB 0041
+119DB 0062
+119DC 0021
+119DC 003F
+119DC 0061
+119DC 0041
+119DC 0062
+119DD 0021
+119DD 003F
+119DD 0061
+119DD 0041
+119DD 0062
+0334 119E0
+119E0 0334
+119E0 0021
+119E0 003F
+119E0 0061
+119E0 0041
+119E0 0062
11800 0021
11800 003F
11800 0061
@@ -97343,6 +99312,36 @@ A8C4 0062
0EC4 0E84 0061
0EC4 0E84 0041
0EC4 0E84 0062
+0E86 0021
+0E86 003F
+0E86 0061
+0E86 0041
+0E86 0062
+0EC0 0E86 0021
+0EC0 0E86 003F
+0EC0 0E86 0061
+0EC0 0E86 0041
+0EC0 0E86 0062
+0EC1 0E86 0021
+0EC1 0E86 003F
+0EC1 0E86 0061
+0EC1 0E86 0041
+0EC1 0E86 0062
+0EC2 0E86 0021
+0EC2 0E86 003F
+0EC2 0E86 0061
+0EC2 0E86 0041
+0EC2 0E86 0062
+0EC3 0E86 0021
+0EC3 0E86 003F
+0EC3 0E86 0061
+0EC3 0E86 0041
+0EC3 0E86 0062
+0EC4 0E86 0021
+0EC4 0E86 003F
+0EC4 0E86 0061
+0EC4 0E86 0041
+0EC4 0E86 0062
0E87 0021
0E87 003F
0E87 0061
@@ -97403,6 +99402,36 @@ A8C4 0062
0EC4 0E88 0061
0EC4 0E88 0041
0EC4 0E88 0062
+0E89 0021
+0E89 003F
+0E89 0061
+0E89 0041
+0E89 0062
+0EC0 0E89 0021
+0EC0 0E89 003F
+0EC0 0E89 0061
+0EC0 0E89 0041
+0EC0 0E89 0062
+0EC1 0E89 0021
+0EC1 0E89 003F
+0EC1 0E89 0061
+0EC1 0E89 0041
+0EC1 0E89 0062
+0EC2 0E89 0021
+0EC2 0E89 003F
+0EC2 0E89 0061
+0EC2 0E89 0041
+0EC2 0E89 0062
+0EC3 0E89 0021
+0EC3 0E89 003F
+0EC3 0E89 0061
+0EC3 0E89 0041
+0EC3 0E89 0062
+0EC4 0E89 0021
+0EC4 0E89 003F
+0EC4 0E89 0061
+0EC4 0E89 0041
+0EC4 0E89 0062
0EAA 0021
0EAA 003F
0EAA 0061
@@ -97463,6 +99492,66 @@ A8C4 0062
0EC4 0E8A 0061
0EC4 0E8A 0041
0EC4 0E8A 0062
+0E8C 0021
+0E8C 003F
+0E8C 0061
+0E8C 0041
+0E8C 0062
+0EC0 0E8C 0021
+0EC0 0E8C 003F
+0EC0 0E8C 0061
+0EC0 0E8C 0041
+0EC0 0E8C 0062
+0EC1 0E8C 0021
+0EC1 0E8C 003F
+0EC1 0E8C 0061
+0EC1 0E8C 0041
+0EC1 0E8C 0062
+0EC2 0E8C 0021
+0EC2 0E8C 003F
+0EC2 0E8C 0061
+0EC2 0E8C 0041
+0EC2 0E8C 0062
+0EC3 0E8C 0021
+0EC3 0E8C 003F
+0EC3 0E8C 0061
+0EC3 0E8C 0041
+0EC3 0E8C 0062
+0EC4 0E8C 0021
+0EC4 0E8C 003F
+0EC4 0E8C 0061
+0EC4 0E8C 0041
+0EC4 0E8C 0062
+0E8E 0021
+0E8E 003F
+0E8E 0061
+0E8E 0041
+0E8E 0062
+0EC0 0E8E 0021
+0EC0 0E8E 003F
+0EC0 0E8E 0061
+0EC0 0E8E 0041
+0EC0 0E8E 0062
+0EC1 0E8E 0021
+0EC1 0E8E 003F
+0EC1 0E8E 0061
+0EC1 0E8E 0041
+0EC1 0E8E 0062
+0EC2 0E8E 0021
+0EC2 0E8E 003F
+0EC2 0E8E 0061
+0EC2 0E8E 0041
+0EC2 0E8E 0062
+0EC3 0E8E 0021
+0EC3 0E8E 003F
+0EC3 0E8E 0061
+0EC3 0E8E 0041
+0EC3 0E8E 0062
+0EC4 0E8E 0021
+0EC4 0E8E 003F
+0EC4 0E8E 0061
+0EC4 0E8E 0041
+0EC4 0E8E 0062
0EDF 0021
0EDF 003F
0EDF 0061
@@ -97523,6 +99612,156 @@ A8C4 0062
0EC4 0E8D 0061
0EC4 0E8D 0041
0EC4 0E8D 0062
+0E8F 0021
+0E8F 003F
+0E8F 0061
+0E8F 0041
+0E8F 0062
+0EC0 0E8F 0021
+0EC0 0E8F 003F
+0EC0 0E8F 0061
+0EC0 0E8F 0041
+0EC0 0E8F 0062
+0EC1 0E8F 0021
+0EC1 0E8F 003F
+0EC1 0E8F 0061
+0EC1 0E8F 0041
+0EC1 0E8F 0062
+0EC2 0E8F 0021
+0EC2 0E8F 003F
+0EC2 0E8F 0061
+0EC2 0E8F 0041
+0EC2 0E8F 0062
+0EC3 0E8F 0021
+0EC3 0E8F 003F
+0EC3 0E8F 0061
+0EC3 0E8F 0041
+0EC3 0E8F 0062
+0EC4 0E8F 0021
+0EC4 0E8F 003F
+0EC4 0E8F 0061
+0EC4 0E8F 0041
+0EC4 0E8F 0062
+0E90 0021
+0E90 003F
+0E90 0061
+0E90 0041
+0E90 0062
+0EC0 0E90 0021
+0EC0 0E90 003F
+0EC0 0E90 0061
+0EC0 0E90 0041
+0EC0 0E90 0062
+0EC1 0E90 0021
+0EC1 0E90 003F
+0EC1 0E90 0061
+0EC1 0E90 0041
+0EC1 0E90 0062
+0EC2 0E90 0021
+0EC2 0E90 003F
+0EC2 0E90 0061
+0EC2 0E90 0041
+0EC2 0E90 0062
+0EC3 0E90 0021
+0EC3 0E90 003F
+0EC3 0E90 0061
+0EC3 0E90 0041
+0EC3 0E90 0062
+0EC4 0E90 0021
+0EC4 0E90 003F
+0EC4 0E90 0061
+0EC4 0E90 0041
+0EC4 0E90 0062
+0E91 0021
+0E91 003F
+0E91 0061
+0E91 0041
+0E91 0062
+0EC0 0E91 0021
+0EC0 0E91 003F
+0EC0 0E91 0061
+0EC0 0E91 0041
+0EC0 0E91 0062
+0EC1 0E91 0021
+0EC1 0E91 003F
+0EC1 0E91 0061
+0EC1 0E91 0041
+0EC1 0E91 0062
+0EC2 0E91 0021
+0EC2 0E91 003F
+0EC2 0E91 0061
+0EC2 0E91 0041
+0EC2 0E91 0062
+0EC3 0E91 0021
+0EC3 0E91 003F
+0EC3 0E91 0061
+0EC3 0E91 0041
+0EC3 0E91 0062
+0EC4 0E91 0021
+0EC4 0E91 003F
+0EC4 0E91 0061
+0EC4 0E91 0041
+0EC4 0E91 0062
+0E92 0021
+0E92 003F
+0E92 0061
+0E92 0041
+0E92 0062
+0EC0 0E92 0021
+0EC0 0E92 003F
+0EC0 0E92 0061
+0EC0 0E92 0041
+0EC0 0E92 0062
+0EC1 0E92 0021
+0EC1 0E92 003F
+0EC1 0E92 0061
+0EC1 0E92 0041
+0EC1 0E92 0062
+0EC2 0E92 0021
+0EC2 0E92 003F
+0EC2 0E92 0061
+0EC2 0E92 0041
+0EC2 0E92 0062
+0EC3 0E92 0021
+0EC3 0E92 003F
+0EC3 0E92 0061
+0EC3 0E92 0041
+0EC3 0E92 0062
+0EC4 0E92 0021
+0EC4 0E92 003F
+0EC4 0E92 0061
+0EC4 0E92 0041
+0EC4 0E92 0062
+0E93 0021
+0E93 003F
+0E93 0061
+0E93 0041
+0E93 0062
+0EC0 0E93 0021
+0EC0 0E93 003F
+0EC0 0E93 0061
+0EC0 0E93 0041
+0EC0 0E93 0062
+0EC1 0E93 0021
+0EC1 0E93 003F
+0EC1 0E93 0061
+0EC1 0E93 0041
+0EC1 0E93 0062
+0EC2 0E93 0021
+0EC2 0E93 003F
+0EC2 0E93 0061
+0EC2 0E93 0041
+0EC2 0E93 0062
+0EC3 0E93 0021
+0EC3 0E93 003F
+0EC3 0E93 0061
+0EC3 0E93 0041
+0EC3 0E93 0062
+0EC4 0E93 0021
+0EC4 0E93 003F
+0EC4 0E93 0061
+0EC4 0E93 0041
+0EC4 0E93 0062
0E94 0021
0E94 003F
0E94 0061
@@ -97643,6 +99882,36 @@ A8C4 0062
0EC4 0E97 0061
0EC4 0E97 0041
0EC4 0E97 0062
+0E98 0021
+0E98 003F
+0E98 0061
+0E98 0041
+0E98 0062
+0EC0 0E98 0021
+0EC0 0E98 003F
+0EC0 0E98 0061
+0EC0 0E98 0041
+0EC0 0E98 0062
+0EC1 0E98 0021
+0EC1 0E98 003F
+0EC1 0E98 0061
+0EC1 0E98 0041
+0EC1 0E98 0062
+0EC2 0E98 0021
+0EC2 0E98 003F
+0EC2 0E98 0061
+0EC2 0E98 0041
+0EC2 0E98 0062
+0EC3 0E98 0021
+0EC3 0E98 003F
+0EC3 0E98 0061
+0EC3 0E98 0041
+0EC3 0E98 0062
+0EC4 0E98 0021
+0EC4 0E98 003F
+0EC4 0E98 0061
+0EC4 0E98 0041
+0EC4 0E98 0062
0E99 0021
0E99 003F
0E99 0061
@@ -97853,6 +100122,36 @@ A8C4 0062
0EC4 0E9F 0061
0EC4 0E9F 0041
0EC4 0E9F 0062
+0EA0 0021
+0EA0 003F
+0EA0 0061
+0EA0 0041
+0EA0 0062
+0EC0 0EA0 0021
+0EC0 0EA0 003F
+0EC0 0EA0 0061
+0EC0 0EA0 0041
+0EC0 0EA0 0062
+0EC1 0EA0 0021
+0EC1 0EA0 003F
+0EC1 0EA0 0061
+0EC1 0EA0 0041
+0EC1 0EA0 0062
+0EC2 0EA0 0021
+0EC2 0EA0 003F
+0EC2 0EA0 0061
+0EC2 0EA0 0041
+0EC2 0EA0 0062
+0EC3 0EA0 0021
+0EC3 0EA0 003F
+0EC3 0EA0 0061
+0EC3 0EA0 0041
+0EC3 0EA0 0062
+0EC4 0EA0 0021
+0EC4 0EA0 003F
+0EC4 0EA0 0061
+0EC4 0EA0 0041
+0EC4 0EA0 0062
0EA1 0021
0EA1 003F
0EA1 0061
@@ -98003,6 +100302,66 @@ A8C4 0062
0EC4 0EA7 0061
0EC4 0EA7 0041
0EC4 0EA7 0062
+0EA8 0021
+0EA8 003F
+0EA8 0061
+0EA8 0041
+0EA8 0062
+0EC0 0EA8 0021
+0EC0 0EA8 003F
+0EC0 0EA8 0061
+0EC0 0EA8 0041
+0EC0 0EA8 0062
+0EC1 0EA8 0021
+0EC1 0EA8 003F
+0EC1 0EA8 0061
+0EC1 0EA8 0041
+0EC1 0EA8 0062
+0EC2 0EA8 0021
+0EC2 0EA8 003F
+0EC2 0EA8 0061
+0EC2 0EA8 0041
+0EC2 0EA8 0062
+0EC3 0EA8 0021
+0EC3 0EA8 003F
+0EC3 0EA8 0061
+0EC3 0EA8 0041
+0EC3 0EA8 0062
+0EC4 0EA8 0021
+0EC4 0EA8 003F
+0EC4 0EA8 0061
+0EC4 0EA8 0041
+0EC4 0EA8 0062
+0EA9 0021
+0EA9 003F
+0EA9 0061
+0EA9 0041
+0EA9 0062
+0EC0 0EA9 0021
+0EC0 0EA9 003F
+0EC0 0EA9 0061
+0EC0 0EA9 0041
+0EC0 0EA9 0062
+0EC1 0EA9 0021
+0EC1 0EA9 003F
+0EC1 0EA9 0061
+0EC1 0EA9 0041
+0EC1 0EA9 0062
+0EC2 0EA9 0021
+0EC2 0EA9 003F
+0EC2 0EA9 0061
+0EC2 0EA9 0041
+0EC2 0EA9 0062
+0EC3 0EA9 0021
+0EC3 0EA9 003F
+0EC3 0EA9 0061
+0EC3 0EA9 0041
+0EC3 0EA9 0062
+0EC4 0EA9 0021
+0EC4 0EA9 003F
+0EC4 0EA9 0061
+0EC4 0EA9 0041
+0EC4 0EA9 0062
0EAB 0021
0EAB 003F
0EAB 0061
@@ -98093,6 +100452,36 @@ A8C4 0062
0EC4 0EAB 0061
0EC4 0EAB 0041
0EC4 0EAB 0062
+0EAC 0021
+0EAC 003F
+0EAC 0061
+0EAC 0041
+0EAC 0062
+0EC0 0EAC 0021
+0EC0 0EAC 003F
+0EC0 0EAC 0061
+0EC0 0EAC 0041
+0EC0 0EAC 0062
+0EC1 0EAC 0021
+0EC1 0EAC 003F
+0EC1 0EAC 0061
+0EC1 0EAC 0041
+0EC1 0EAC 0062
+0EC2 0EAC 0021
+0EC2 0EAC 003F
+0EC2 0EAC 0061
+0EC2 0EAC 0041
+0EC2 0EAC 0062
+0EC3 0EAC 0021
+0EC3 0EAC 003F
+0EC3 0EAC 0061
+0EC3 0EAC 0041
+0EC3 0EAC 0062
+0EC4 0EAC 0021
+0EC4 0EAC 003F
+0EC4 0EAC 0061
+0EC4 0EAC 0041
+0EC4 0EAC 0062
0EAD 0021
0EAD 003F
0EAD 0061
@@ -98220,6 +100609,13 @@ A8C4 0062
0EB9 0061
0EB9 0041
0EB9 0062
+0334 0EBA
+0EBA 0334
+0EBA 0021
+0EBA 003F
+0EBA 0061
+0EBA 0041
+0EBA 0062
0EBB 0021
0EBB 003F
0EBB 0061
@@ -98252,24 +100648,51 @@ A8C4 0062
0EC0 0001 0E84 0061
0EC0 0591 0E84 0061
0EC0 1D165 0E84 0061
+0EC0 0001 0E86 0061
+0EC0 0591 0E86 0061
+0EC0 1D165 0E86 0061
0EC0 0001 0E87 0061
0EC0 0591 0E87 0061
0EC0 1D165 0E87 0061
0EC0 0001 0E88 0061
0EC0 0591 0E88 0061
0EC0 1D165 0E88 0061
+0EC0 0001 0E89 0061
+0EC0 0591 0E89 0061
+0EC0 1D165 0E89 0061
0EC0 0001 0EAA 0061
0EC0 0591 0EAA 0061
0EC0 1D165 0EAA 0061
0EC0 0001 0E8A 0061
0EC0 0591 0E8A 0061
0EC0 1D165 0E8A 0061
+0EC0 0001 0E8C 0061
+0EC0 0591 0E8C 0061
+0EC0 1D165 0E8C 0061
+0EC0 0001 0E8E 0061
+0EC0 0591 0E8E 0061
+0EC0 1D165 0E8E 0061
0EC0 0001 0EDF 0061
0EC0 0591 0EDF 0061
0EC0 1D165 0EDF 0061
0EC0 0001 0E8D 0061
0EC0 0591 0E8D 0061
0EC0 1D165 0E8D 0061
+0EC0 0001 0E8F 0061
+0EC0 0591 0E8F 0061
+0EC0 1D165 0E8F 0061
+0EC0 0001 0E90 0061
+0EC0 0591 0E90 0061
+0EC0 1D165 0E90 0061
+0EC0 0001 0E91 0061
+0EC0 0591 0E91 0061
+0EC0 1D165 0E91 0061
+0EC0 0001 0E92 0061
+0EC0 0591 0E92 0061
+0EC0 1D165 0E92 0061
+0EC0 0001 0E93 0061
+0EC0 0591 0E93 0061
+0EC0 1D165 0E93 0061
0EC0 0001 0E94 0061
0EC0 0591 0E94 0061
0EC0 1D165 0E94 0061
@@ -98282,6 +100705,9 @@ A8C4 0062
0EC0 0001 0E97 0061
0EC0 0591 0E97 0061
0EC0 1D165 0E97 0061
+0EC0 0001 0E98 0061
+0EC0 0591 0E98 0061
+0EC0 1D165 0E98 0061
0EC0 0001 0E99 0061
0EC0 0591 0E99 0061
0EC0 1D165 0E99 0061
@@ -98303,6 +100729,9 @@ A8C4 0062
0EC0 0001 0E9F 0061
0EC0 0591 0E9F 0061
0EC0 1D165 0E9F 0061
+0EC0 0001 0EA0 0061
+0EC0 0591 0EA0 0061
+0EC0 1D165 0EA0 0061
0EC0 0001 0EA1 0061
0EC0 0591 0EA1 0061
0EC0 1D165 0EA1 0061
@@ -98318,6 +100747,12 @@ A8C4 0062
0EC0 0001 0EA7 0061
0EC0 0591 0EA7 0061
0EC0 1D165 0EA7 0061
+0EC0 0001 0EA8 0061
+0EC0 0591 0EA8 0061
+0EC0 1D165 0EA8 0061
+0EC0 0001 0EA9 0061
+0EC0 0591 0EA9 0061
+0EC0 1D165 0EA9 0061
0EC0 0001 0EAB 0061
0EC0 0591 0EAB 0061
0EC0 1D165 0EAB 0061
@@ -98327,6 +100762,9 @@ A8C4 0062
0EC0 0001 0EDD 0061
0EC0 0591 0EDD 0061
0EC0 1D165 0EDD 0061
+0EC0 0001 0EAC 0061
+0EC0 0591 0EAC 0061
+0EC0 1D165 0EAC 0061
0EC0 0001 0EAD 0061
0EC0 0591 0EAD 0061
0EC0 1D165 0EAD 0061
@@ -98350,24 +100788,51 @@ A8C4 0062
0EC1 0001 0E84 0061
0EC1 0591 0E84 0061
0EC1 1D165 0E84 0061
+0EC1 0001 0E86 0061
+0EC1 0591 0E86 0061
+0EC1 1D165 0E86 0061
0EC1 0001 0E87 0061
0EC1 0591 0E87 0061
0EC1 1D165 0E87 0061
0EC1 0001 0E88 0061
0EC1 0591 0E88 0061
0EC1 1D165 0E88 0061
+0EC1 0001 0E89 0061
+0EC1 0591 0E89 0061
+0EC1 1D165 0E89 0061
0EC1 0001 0EAA 0061
0EC1 0591 0EAA 0061
0EC1 1D165 0EAA 0061
0EC1 0001 0E8A 0061
0EC1 0591 0E8A 0061
0EC1 1D165 0E8A 0061
+0EC1 0001 0E8C 0061
+0EC1 0591 0E8C 0061
+0EC1 1D165 0E8C 0061
+0EC1 0001 0E8E 0061
+0EC1 0591 0E8E 0061
+0EC1 1D165 0E8E 0061
0EC1 0001 0EDF 0061
0EC1 0591 0EDF 0061
0EC1 1D165 0EDF 0061
0EC1 0001 0E8D 0061
0EC1 0591 0E8D 0061
0EC1 1D165 0E8D 0061
+0EC1 0001 0E8F 0061
+0EC1 0591 0E8F 0061
+0EC1 1D165 0E8F 0061
+0EC1 0001 0E90 0061
+0EC1 0591 0E90 0061
+0EC1 1D165 0E90 0061
+0EC1 0001 0E91 0061
+0EC1 0591 0E91 0061
+0EC1 1D165 0E91 0061
+0EC1 0001 0E92 0061
+0EC1 0591 0E92 0061
+0EC1 1D165 0E92 0061
+0EC1 0001 0E93 0061
+0EC1 0591 0E93 0061
+0EC1 1D165 0E93 0061
0EC1 0001 0E94 0061
0EC1 0591 0E94 0061
0EC1 1D165 0E94 0061
@@ -98380,6 +100845,9 @@ A8C4 0062
0EC1 0001 0E97 0061
0EC1 0591 0E97 0061
0EC1 1D165 0E97 0061
+0EC1 0001 0E98 0061
+0EC1 0591 0E98 0061
+0EC1 1D165 0E98 0061
0EC1 0001 0E99 0061
0EC1 0591 0E99 0061
0EC1 1D165 0E99 0061
@@ -98401,6 +100869,9 @@ A8C4 0062
0EC1 0001 0E9F 0061
0EC1 0591 0E9F 0061
0EC1 1D165 0E9F 0061
+0EC1 0001 0EA0 0061
+0EC1 0591 0EA0 0061
+0EC1 1D165 0EA0 0061
0EC1 0001 0EA1 0061
0EC1 0591 0EA1 0061
0EC1 1D165 0EA1 0061
@@ -98416,6 +100887,12 @@ A8C4 0062
0EC1 0001 0EA7 0061
0EC1 0591 0EA7 0061
0EC1 1D165 0EA7 0061
+0EC1 0001 0EA8 0061
+0EC1 0591 0EA8 0061
+0EC1 1D165 0EA8 0061
+0EC1 0001 0EA9 0061
+0EC1 0591 0EA9 0061
+0EC1 1D165 0EA9 0061
0EC1 0001 0EAB 0061
0EC1 0591 0EAB 0061
0EC1 1D165 0EAB 0061
@@ -98425,6 +100902,9 @@ A8C4 0062
0EC1 0001 0EDD 0061
0EC1 0591 0EDD 0061
0EC1 1D165 0EDD 0061
+0EC1 0001 0EAC 0061
+0EC1 0591 0EAC 0061
+0EC1 1D165 0EAC 0061
0EC1 0001 0EAD 0061
0EC1 0591 0EAD 0061
0EC1 1D165 0EAD 0061
@@ -98448,24 +100928,51 @@ A8C4 0062
0EC2 0001 0E84 0061
0EC2 0591 0E84 0061
0EC2 1D165 0E84 0061
+0EC2 0001 0E86 0061
+0EC2 0591 0E86 0061
+0EC2 1D165 0E86 0061
0EC2 0001 0E87 0061
0EC2 0591 0E87 0061
0EC2 1D165 0E87 0061
0EC2 0001 0E88 0061
0EC2 0591 0E88 0061
0EC2 1D165 0E88 0061
+0EC2 0001 0E89 0061
+0EC2 0591 0E89 0061
+0EC2 1D165 0E89 0061
0EC2 0001 0EAA 0061
0EC2 0591 0EAA 0061
0EC2 1D165 0EAA 0061
0EC2 0001 0E8A 0061
0EC2 0591 0E8A 0061
0EC2 1D165 0E8A 0061
+0EC2 0001 0E8C 0061
+0EC2 0591 0E8C 0061
+0EC2 1D165 0E8C 0061
+0EC2 0001 0E8E 0061
+0EC2 0591 0E8E 0061
+0EC2 1D165 0E8E 0061
0EC2 0001 0EDF 0061
0EC2 0591 0EDF 0061
0EC2 1D165 0EDF 0061
0EC2 0001 0E8D 0061
0EC2 0591 0E8D 0061
0EC2 1D165 0E8D 0061
+0EC2 0001 0E8F 0061
+0EC2 0591 0E8F 0061
+0EC2 1D165 0E8F 0061
+0EC2 0001 0E90 0061
+0EC2 0591 0E90 0061
+0EC2 1D165 0E90 0061
+0EC2 0001 0E91 0061
+0EC2 0591 0E91 0061
+0EC2 1D165 0E91 0061
+0EC2 0001 0E92 0061
+0EC2 0591 0E92 0061
+0EC2 1D165 0E92 0061
+0EC2 0001 0E93 0061
+0EC2 0591 0E93 0061
+0EC2 1D165 0E93 0061
0EC2 0001 0E94 0061
0EC2 0591 0E94 0061
0EC2 1D165 0E94 0061
@@ -98478,6 +100985,9 @@ A8C4 0062
0EC2 0001 0E97 0061
0EC2 0591 0E97 0061
0EC2 1D165 0E97 0061
+0EC2 0001 0E98 0061
+0EC2 0591 0E98 0061
+0EC2 1D165 0E98 0061
0EC2 0001 0E99 0061
0EC2 0591 0E99 0061
0EC2 1D165 0E99 0061
@@ -98499,6 +101009,9 @@ A8C4 0062
0EC2 0001 0E9F 0061
0EC2 0591 0E9F 0061
0EC2 1D165 0E9F 0061
+0EC2 0001 0EA0 0061
+0EC2 0591 0EA0 0061
+0EC2 1D165 0EA0 0061
0EC2 0001 0EA1 0061
0EC2 0591 0EA1 0061
0EC2 1D165 0EA1 0061
@@ -98514,6 +101027,12 @@ A8C4 0062
0EC2 0001 0EA7 0061
0EC2 0591 0EA7 0061
0EC2 1D165 0EA7 0061
+0EC2 0001 0EA8 0061
+0EC2 0591 0EA8 0061
+0EC2 1D165 0EA8 0061
+0EC2 0001 0EA9 0061
+0EC2 0591 0EA9 0061
+0EC2 1D165 0EA9 0061
0EC2 0001 0EAB 0061
0EC2 0591 0EAB 0061
0EC2 1D165 0EAB 0061
@@ -98523,6 +101042,9 @@ A8C4 0062
0EC2 0001 0EDD 0061
0EC2 0591 0EDD 0061
0EC2 1D165 0EDD 0061
+0EC2 0001 0EAC 0061
+0EC2 0591 0EAC 0061
+0EC2 1D165 0EAC 0061
0EC2 0001 0EAD 0061
0EC2 0591 0EAD 0061
0EC2 1D165 0EAD 0061
@@ -98546,24 +101068,51 @@ A8C4 0062
0EC3 0001 0E84 0061
0EC3 0591 0E84 0061
0EC3 1D165 0E84 0061
+0EC3 0001 0E86 0061
+0EC3 0591 0E86 0061
+0EC3 1D165 0E86 0061
0EC3 0001 0E87 0061
0EC3 0591 0E87 0061
0EC3 1D165 0E87 0061
0EC3 0001 0E88 0061
0EC3 0591 0E88 0061
0EC3 1D165 0E88 0061
+0EC3 0001 0E89 0061
+0EC3 0591 0E89 0061
+0EC3 1D165 0E89 0061
0EC3 0001 0EAA 0061
0EC3 0591 0EAA 0061
0EC3 1D165 0EAA 0061
0EC3 0001 0E8A 0061
0EC3 0591 0E8A 0061
0EC3 1D165 0E8A 0061
+0EC3 0001 0E8C 0061
+0EC3 0591 0E8C 0061
+0EC3 1D165 0E8C 0061
+0EC3 0001 0E8E 0061
+0EC3 0591 0E8E 0061
+0EC3 1D165 0E8E 0061
0EC3 0001 0EDF 0061
0EC3 0591 0EDF 0061
0EC3 1D165 0EDF 0061
0EC3 0001 0E8D 0061
0EC3 0591 0E8D 0061
0EC3 1D165 0E8D 0061
+0EC3 0001 0E8F 0061
+0EC3 0591 0E8F 0061
+0EC3 1D165 0E8F 0061
+0EC3 0001 0E90 0061
+0EC3 0591 0E90 0061
+0EC3 1D165 0E90 0061
+0EC3 0001 0E91 0061
+0EC3 0591 0E91 0061
+0EC3 1D165 0E91 0061
+0EC3 0001 0E92 0061
+0EC3 0591 0E92 0061
+0EC3 1D165 0E92 0061
+0EC3 0001 0E93 0061
+0EC3 0591 0E93 0061
+0EC3 1D165 0E93 0061
0EC3 0001 0E94 0061
0EC3 0591 0E94 0061
0EC3 1D165 0E94 0061
@@ -98576,6 +101125,9 @@ A8C4 0062
0EC3 0001 0E97 0061
0EC3 0591 0E97 0061
0EC3 1D165 0E97 0061
+0EC3 0001 0E98 0061
+0EC3 0591 0E98 0061
+0EC3 1D165 0E98 0061
0EC3 0001 0E99 0061
0EC3 0591 0E99 0061
0EC3 1D165 0E99 0061
@@ -98597,6 +101149,9 @@ A8C4 0062
0EC3 0001 0E9F 0061
0EC3 0591 0E9F 0061
0EC3 1D165 0E9F 0061
+0EC3 0001 0EA0 0061
+0EC3 0591 0EA0 0061
+0EC3 1D165 0EA0 0061
0EC3 0001 0EA1 0061
0EC3 0591 0EA1 0061
0EC3 1D165 0EA1 0061
@@ -98612,6 +101167,12 @@ A8C4 0062
0EC3 0001 0EA7 0061
0EC3 0591 0EA7 0061
0EC3 1D165 0EA7 0061
+0EC3 0001 0EA8 0061
+0EC3 0591 0EA8 0061
+0EC3 1D165 0EA8 0061
+0EC3 0001 0EA9 0061
+0EC3 0591 0EA9 0061
+0EC3 1D165 0EA9 0061
0EC3 0001 0EAB 0061
0EC3 0591 0EAB 0061
0EC3 1D165 0EAB 0061
@@ -98621,6 +101182,9 @@ A8C4 0062
0EC3 0001 0EDD 0061
0EC3 0591 0EDD 0061
0EC3 1D165 0EDD 0061
+0EC3 0001 0EAC 0061
+0EC3 0591 0EAC 0061
+0EC3 1D165 0EAC 0061
0EC3 0001 0EAD 0061
0EC3 0591 0EAD 0061
0EC3 1D165 0EAD 0061
@@ -98644,24 +101208,51 @@ A8C4 0062
0EC4 0001 0E84 0061
0EC4 0591 0E84 0061
0EC4 1D165 0E84 0061
+0EC4 0001 0E86 0061
+0EC4 0591 0E86 0061
+0EC4 1D165 0E86 0061
0EC4 0001 0E87 0061
0EC4 0591 0E87 0061
0EC4 1D165 0E87 0061
0EC4 0001 0E88 0061
0EC4 0591 0E88 0061
0EC4 1D165 0E88 0061
+0EC4 0001 0E89 0061
+0EC4 0591 0E89 0061
+0EC4 1D165 0E89 0061
0EC4 0001 0EAA 0061
0EC4 0591 0EAA 0061
0EC4 1D165 0EAA 0061
0EC4 0001 0E8A 0061
0EC4 0591 0E8A 0061
0EC4 1D165 0E8A 0061
+0EC4 0001 0E8C 0061
+0EC4 0591 0E8C 0061
+0EC4 1D165 0E8C 0061
+0EC4 0001 0E8E 0061
+0EC4 0591 0E8E 0061
+0EC4 1D165 0E8E 0061
0EC4 0001 0EDF 0061
0EC4 0591 0EDF 0061
0EC4 1D165 0EDF 0061
0EC4 0001 0E8D 0061
0EC4 0591 0E8D 0061
0EC4 1D165 0E8D 0061
+0EC4 0001 0E8F 0061
+0EC4 0591 0E8F 0061
+0EC4 1D165 0E8F 0061
+0EC4 0001 0E90 0061
+0EC4 0591 0E90 0061
+0EC4 1D165 0E90 0061
+0EC4 0001 0E91 0061
+0EC4 0591 0E91 0061
+0EC4 1D165 0E91 0061
+0EC4 0001 0E92 0061
+0EC4 0591 0E92 0061
+0EC4 1D165 0E92 0061
+0EC4 0001 0E93 0061
+0EC4 0591 0E93 0061
+0EC4 1D165 0E93 0061
0EC4 0001 0E94 0061
0EC4 0591 0E94 0061
0EC4 1D165 0E94 0061
@@ -98674,6 +101265,9 @@ A8C4 0062
0EC4 0001 0E97 0061
0EC4 0591 0E97 0061
0EC4 1D165 0E97 0061
+0EC4 0001 0E98 0061
+0EC4 0591 0E98 0061
+0EC4 1D165 0E98 0061
0EC4 0001 0E99 0061
0EC4 0591 0E99 0061
0EC4 1D165 0E99 0061
@@ -98695,6 +101289,9 @@ A8C4 0062
0EC4 0001 0E9F 0061
0EC4 0591 0E9F 0061
0EC4 1D165 0E9F 0061
+0EC4 0001 0EA0 0061
+0EC4 0591 0EA0 0061
+0EC4 1D165 0EA0 0061
0EC4 0001 0EA1 0061
0EC4 0591 0EA1 0061
0EC4 1D165 0EA1 0061
@@ -98710,6 +101307,12 @@ A8C4 0062
0EC4 0001 0EA7 0061
0EC4 0591 0EA7 0061
0EC4 1D165 0EA7 0061
+0EC4 0001 0EA8 0061
+0EC4 0591 0EA8 0061
+0EC4 1D165 0EA8 0061
+0EC4 0001 0EA9 0061
+0EC4 0591 0EA9 0061
+0EC4 1D165 0EA9 0061
0EC4 0001 0EAB 0061
0EC4 0591 0EAB 0061
0EC4 1D165 0EAB 0061
@@ -98719,6 +101322,9 @@ A8C4 0062
0EC4 0001 0EDD 0061
0EC4 0591 0EDD 0061
0EC4 1D165 0EDD 0061
+0EC4 0001 0EAC 0061
+0EC4 0591 0EAC 0061
+0EC4 1D165 0EAC 0061
0EC4 0001 0EAD 0061
0EC4 0591 0EAD 0061
0EC4 1D165 0EAD 0061
@@ -102423,6 +105029,16 @@ AADC 0062
11A82 0061
11A82 0041
11A82 0062
+11A84 0021
+11A84 003F
+11A84 0061
+11A84 0041
+11A84 0062
+11A85 0021
+11A85 003F
+11A85 0061
+11A85 0041
+11A85 0062
0334 11A99
11A99 0334
11A99 0021
@@ -123499,6 +126115,11 @@ A6EF 0062
1E921 0041
1E943 0062
1E921 0062
+1E94B 0021
+1E94B 003F
+1E94B 0061
+1E94B 0041
+1E94B 0062
1100 0021
3131 0021
3260 0021
@@ -128330,64 +130951,92 @@ FF9C 0062
30F0 0334 3099
30F0 3099 0334
30F8 0334
+1B150 0021
3090 0021
+1B164 0021
30F0 0021
32FC 0021
30F8 0021
+1B150 003F
3090 003F
+1B164 003F
30F0 003F
32FC 003F
30F8 003F
+1B150 0061
+1B150 0041
3090 0061
3090 0041
+1B164 0061
+1B164 0041
30F0 0061
30F0 0041
32FC 0061
32FC 0041
30F8 0061
30F8 0041
+1B150 0062
3090 0062
+1B164 0062
30F0 0062
32FC 0062
30F8 0062
30F1 0334 3099
30F1 3099 0334
30F9 0334
+1B151 0021
3091 0021
+1B165 0021
30F1 0021
32FD 0021
30F9 0021
+1B151 003F
3091 003F
+1B165 003F
30F1 003F
32FD 003F
30F9 003F
+1B151 0061
+1B151 0041
3091 0061
3091 0041
+1B165 0061
+1B165 0041
30F1 0061
30F1 0041
32FD 0061
32FD 0041
30F9 0061
30F9 0041
+1B151 0062
3091 0062
+1B165 0062
30F1 0062
32FD 0062
30F9 0062
30F2 0334 3099
30F2 3099 0334
30FA 0334
+1B152 0021
3092 0021
+1B166 0021
30F2 0021
FF66 0021
32FE 0021
30FA 0021
+1B152 003F
3092 003F
+1B166 003F
30F2 003F
FF66 003F
32FE 003F
30FA 003F
+1B152 0061
+1B152 0041
3092 0061
3092 0041
+1B166 0061
+1B166 0041
30F2 0061
30F2 0041
FF66 0061
@@ -128396,24 +131045,31 @@ FF66 0041
32FE 0041
30FA 0061
30FA 0041
+1B152 0062
3092 0062
+1B166 0062
30F2 0062
FF66 0062
32FE 0062
30FA 0062
3093 0021
+1B167 0021
30F3 0021
FF9D 0021
3093 003F
+1B167 003F
30F3 003F
FF9D 003F
3093 0061
3093 0041
+1B167 0061
+1B167 0041
30F3 0061
30F3 0041
FF9D 0061
FF9D 0041
3093 0062
+1B167 0062
30F3 0062
FF9D 0062
1B002 0021
@@ -136271,6 +138927,11 @@ A4F7 0062
16F03 0061
16F03 0041
16F03 0062
+16F45 0021
+16F45 003F
+16F45 0061
+16F45 0041
+16F45 0062
16F04 0021
16F06 0021
16F04 003F
@@ -136321,6 +138982,11 @@ A4F7 0062
16F0D 0061
16F0D 0041
16F0D 0062
+16F48 0021
+16F48 003F
+16F48 0061
+16F48 0041
+16F48 0062
16F0E 0021
16F0E 003F
16F0E 0061
@@ -136331,6 +138997,11 @@ A4F7 0062
16F0F 0061
16F0F 0041
16F0F 0062
+16F4A 0021
+16F4A 003F
+16F4A 0061
+16F4A 0041
+16F4A 0062
16F10 0021
16F13 0021
16F10 003F
@@ -136506,11 +139177,21 @@ A4F7 0062
16F32 0061
16F32 0041
16F32 0062
+16F47 0021
+16F47 003F
+16F47 0061
+16F47 0041
+16F47 0062
16F33 0021
16F33 003F
16F33 0061
16F33 0041
16F33 0062
+16F46 0021
+16F46 003F
+16F46 0061
+16F46 0041
+16F46 0062
16F34 0021
16F34 003F
16F34 0061
@@ -136541,6 +139222,11 @@ A4F7 0062
16F39 0061
16F39 0041
16F39 0062
+16F49 0021
+16F49 003F
+16F49 0061
+16F49 0041
+16F49 0062
16F3A 0021
16F3A 003F
16F3A 0061
@@ -136616,6 +139302,11 @@ A4F7 0062
16F53 0061
16F53 0041
16F53 0062
+16F4F 0021
+16F4F 003F
+16F4F 0061
+16F4F 0041
+16F4F 0062
16F54 0021
16F54 003F
16F54 0061
@@ -136641,6 +139332,11 @@ A4F7 0062
16F58 0061
16F58 0041
16F58 0062
+16F81 0021
+16F81 003F
+16F81 0061
+16F81 0041
+16F81 0062
16F59 0021
16F59 003F
16F59 0061
@@ -136661,6 +139357,11 @@ A4F7 0062
16F5C 0061
16F5C 0041
16F5C 0062
+16F83 0021
+16F83 003F
+16F83 0061
+16F83 0041
+16F83 0062
16F5D 0021
16F5D 003F
16F5D 0061
@@ -136681,6 +139382,11 @@ A4F7 0062
16F60 0061
16F60 0041
16F60 0062
+16F84 0021
+16F84 003F
+16F84 0061
+16F84 0041
+16F84 0062
16F61 0021
16F61 003F
16F61 0061
@@ -136706,6 +139412,11 @@ A4F7 0062
16F65 0061
16F65 0041
16F65 0062
+16F86 0021
+16F86 003F
+16F86 0061
+16F86 0041
+16F86 0062
16F66 0021
16F66 003F
16F66 0061
@@ -136746,6 +139457,16 @@ A4F7 0062
16F6D 0061
16F6D 0041
16F6D 0062
+16F7F 0021
+16F7F 003F
+16F7F 0061
+16F7F 0041
+16F7F 0062
+16F87 0021
+16F87 003F
+16F87 0061
+16F87 0041
+16F87 0062
16F6E 0021
16F6E 003F
16F6E 0061
@@ -136771,6 +139492,11 @@ A4F7 0062
16F72 0061
16F72 0041
16F72 0062
+16F80 0021
+16F80 003F
+16F80 0061
+16F80 0041
+16F80 0062
16F73 0021
16F73 003F
16F73 0061
@@ -136781,6 +139507,16 @@ A4F7 0062
16F74 0061
16F74 0041
16F74 0062
+16F85 0021
+16F85 003F
+16F85 0061
+16F85 0041
+16F85 0062
+16F82 0021
+16F82 003F
+16F82 0061
+16F82 0041
+16F82 0062
16F75 0021
16F75 003F
16F75 0061
@@ -137976,6 +140712,481 @@ A4F7 0062
16B8F 0061
16B8F 0041
16B8F 0062
+1E100 0021
+1E100 003F
+1E100 0061
+1E100 0041
+1E100 0062
+1E101 0021
+1E101 003F
+1E101 0061
+1E101 0041
+1E101 0062
+1E102 0021
+1E102 003F
+1E102 0061
+1E102 0041
+1E102 0062
+1E103 0021
+1E103 003F
+1E103 0061
+1E103 0041
+1E103 0062
+1E104 0021
+1E104 003F
+1E104 0061
+1E104 0041
+1E104 0062
+1E105 0021
+1E105 003F
+1E105 0061
+1E105 0041
+1E105 0062
+1E106 0021
+1E106 003F
+1E106 0061
+1E106 0041
+1E106 0062
+1E107 0021
+1E107 003F
+1E107 0061
+1E107 0041
+1E107 0062
+1E108 0021
+1E108 003F
+1E108 0061
+1E108 0041
+1E108 0062
+1E109 0021
+1E109 003F
+1E109 0061
+1E109 0041
+1E109 0062
+1E10A 0021
+1E10A 003F
+1E10A 0061
+1E10A 0041
+1E10A 0062
+1E10B 0021
+1E10B 003F
+1E10B 0061
+1E10B 0041
+1E10B 0062
+1E10C 0021
+1E10C 003F
+1E10C 0061
+1E10C 0041
+1E10C 0062
+1E10D 0021
+1E10D 003F
+1E10D 0061
+1E10D 0041
+1E10D 0062
+1E10E 0021
+1E10E 003F
+1E10E 0061
+1E10E 0041
+1E10E 0062
+1E10F 0021
+1E10F 003F
+1E10F 0061
+1E10F 0041
+1E10F 0062
+1E110 0021
+1E110 003F
+1E110 0061
+1E110 0041
+1E110 0062
+1E111 0021
+1E111 003F
+1E111 0061
+1E111 0041
+1E111 0062
+1E112 0021
+1E112 003F
+1E112 0061
+1E112 0041
+1E112 0062
+1E113 0021
+1E113 003F
+1E113 0061
+1E113 0041
+1E113 0062
+1E114 0021
+1E114 003F
+1E114 0061
+1E114 0041
+1E114 0062
+1E115 0021
+1E115 003F
+1E115 0061
+1E115 0041
+1E115 0062
+1E116 0021
+1E116 003F
+1E116 0061
+1E116 0041
+1E116 0062
+1E117 0021
+1E117 003F
+1E117 0061
+1E117 0041
+1E117 0062
+1E118 0021
+1E118 003F
+1E118 0061
+1E118 0041
+1E118 0062
+1E119 0021
+1E119 003F
+1E119 0061
+1E119 0041
+1E119 0062
+1E11A 0021
+1E11A 003F
+1E11A 0061
+1E11A 0041
+1E11A 0062
+1E11B 0021
+1E11B 003F
+1E11B 0061
+1E11B 0041
+1E11B 0062
+1E11C 0021
+1E11C 003F
+1E11C 0061
+1E11C 0041
+1E11C 0062
+1E11D 0021
+1E11D 003F
+1E11D 0061
+1E11D 0041
+1E11D 0062
+1E11E 0021
+1E11E 003F
+1E11E 0061
+1E11E 0041
+1E11E 0062
+1E11F 0021
+1E11F 003F
+1E11F 0061
+1E11F 0041
+1E11F 0062
+1E120 0021
+1E120 003F
+1E120 0061
+1E120 0041
+1E120 0062
+1E121 0021
+1E121 003F
+1E121 0061
+1E121 0041
+1E121 0062
+1E122 0021
+1E122 003F
+1E122 0061
+1E122 0041
+1E122 0062
+1E123 0021
+1E123 003F
+1E123 0061
+1E123 0041
+1E123 0062
+1E124 0021
+1E124 003F
+1E124 0061
+1E124 0041
+1E124 0062
+1E125 0021
+1E125 003F
+1E125 0061
+1E125 0041
+1E125 0062
+1E126 0021
+1E126 003F
+1E126 0061
+1E126 0041
+1E126 0062
+1E127 0021
+1E127 003F
+1E127 0061
+1E127 0041
+1E127 0062
+1E128 0021
+1E128 003F
+1E128 0061
+1E128 0041
+1E128 0062
+1E129 0021
+1E129 003F
+1E129 0061
+1E129 0041
+1E129 0062
+1E12A 0021
+1E12A 003F
+1E12A 0061
+1E12A 0041
+1E12A 0062
+1E12B 0021
+1E12B 003F
+1E12B 0061
+1E12B 0041
+1E12B 0062
+1E12C 0021
+1E12C 003F
+1E12C 0061
+1E12C 0041
+1E12C 0062
+1E137 0021
+1E137 003F
+1E137 0061
+1E137 0041
+1E137 0062
+1E138 0021
+1E138 003F
+1E138 0061
+1E138 0041
+1E138 0062
+1E139 0021
+1E139 003F
+1E139 0061
+1E139 0041
+1E139 0062
+1E13A 0021
+1E13A 003F
+1E13A 0061
+1E13A 0041
+1E13A 0062
+1E13B 0021
+1E13B 003F
+1E13B 0061
+1E13B 0041
+1E13B 0062
+1E14E 0021
+1E14E 003F
+1E14E 0061
+1E14E 0041
+1E14E 0062
+1E2C0 0021
+1E2C0 003F
+1E2C0 0061
+1E2C0 0041
+1E2C0 0062
+1E2C1 0021
+1E2C1 003F
+1E2C1 0061
+1E2C1 0041
+1E2C1 0062
+1E2C2 0021
+1E2C2 003F
+1E2C2 0061
+1E2C2 0041
+1E2C2 0062
+1E2C3 0021
+1E2C3 003F
+1E2C3 0061
+1E2C3 0041
+1E2C3 0062
+1E2C4 0021
+1E2C4 003F
+1E2C4 0061
+1E2C4 0041
+1E2C4 0062
+1E2C5 0021
+1E2C5 003F
+1E2C5 0061
+1E2C5 0041
+1E2C5 0062
+1E2C6 0021
+1E2C6 003F
+1E2C6 0061
+1E2C6 0041
+1E2C6 0062
+1E2C7 0021
+1E2C7 003F
+1E2C7 0061
+1E2C7 0041
+1E2C7 0062
+1E2C8 0021
+1E2C8 003F
+1E2C8 0061
+1E2C8 0041
+1E2C8 0062
+1E2C9 0021
+1E2C9 003F
+1E2C9 0061
+1E2C9 0041
+1E2C9 0062
+1E2CA 0021
+1E2CA 003F
+1E2CA 0061
+1E2CA 0041
+1E2CA 0062
+1E2CB 0021
+1E2CB 003F
+1E2CB 0061
+1E2CB 0041
+1E2CB 0062
+1E2CC 0021
+1E2CC 003F
+1E2CC 0061
+1E2CC 0041
+1E2CC 0062
+1E2CD 0021
+1E2CD 003F
+1E2CD 0061
+1E2CD 0041
+1E2CD 0062
+1E2CE 0021
+1E2CE 003F
+1E2CE 0061
+1E2CE 0041
+1E2CE 0062
+1E2CF 0021
+1E2CF 003F
+1E2CF 0061
+1E2CF 0041
+1E2CF 0062
+1E2D0 0021
+1E2D0 003F
+1E2D0 0061
+1E2D0 0041
+1E2D0 0062
+1E2D1 0021
+1E2D1 003F
+1E2D1 0061
+1E2D1 0041
+1E2D1 0062
+1E2D2 0021
+1E2D2 003F
+1E2D2 0061
+1E2D2 0041
+1E2D2 0062
+1E2D3 0021
+1E2D3 003F
+1E2D3 0061
+1E2D3 0041
+1E2D3 0062
+1E2D4 0021
+1E2D4 003F
+1E2D4 0061
+1E2D4 0041
+1E2D4 0062
+1E2D5 0021
+1E2D5 003F
+1E2D5 0061
+1E2D5 0041
+1E2D5 0062
+1E2D6 0021
+1E2D6 003F
+1E2D6 0061
+1E2D6 0041
+1E2D6 0062
+1E2D7 0021
+1E2D7 003F
+1E2D7 0061
+1E2D7 0041
+1E2D7 0062
+1E2D8 0021
+1E2D8 003F
+1E2D8 0061
+1E2D8 0041
+1E2D8 0062
+1E2D9 0021
+1E2D9 003F
+1E2D9 0061
+1E2D9 0041
+1E2D9 0062
+1E2DA 0021
+1E2DA 003F
+1E2DA 0061
+1E2DA 0041
+1E2DA 0062
+1E2DB 0021
+1E2DB 003F
+1E2DB 0061
+1E2DB 0041
+1E2DB 0062
+1E2DC 0021
+1E2DC 003F
+1E2DC 0061
+1E2DC 0041
+1E2DC 0062
+1E2DD 0021
+1E2DD 003F
+1E2DD 0061
+1E2DD 0041
+1E2DD 0062
+1E2DE 0021
+1E2DE 003F
+1E2DE 0061
+1E2DE 0041
+1E2DE 0062
+1E2DF 0021
+1E2DF 003F
+1E2DF 0061
+1E2DF 0041
+1E2DF 0062
+1E2E0 0021
+1E2E0 003F
+1E2E0 0061
+1E2E0 0041
+1E2E0 0062
+1E2E1 0021
+1E2E1 003F
+1E2E1 0061
+1E2E1 0041
+1E2E1 0062
+1E2E2 0021
+1E2E2 003F
+1E2E2 0061
+1E2E2 0041
+1E2E2 0062
+1E2E3 0021
+1E2E3 003F
+1E2E3 0061
+1E2E3 0041
+1E2E3 0062
+1E2E4 0021
+1E2E4 003F
+1E2E4 0061
+1E2E4 0041
+1E2E4 0062
+1E2E5 0021
+1E2E5 003F
+1E2E5 0061
+1E2E5 0041
+1E2E5 0062
+1E2E6 0021
+1E2E6 003F
+1E2E6 0061
+1E2E6 0041
+1E2E6 0062
+1E2E7 0021
+1E2E7 003F
+1E2E7 0061
+1E2E7 0041
+1E2E7 0062
+1E2E8 0021
+1E2E8 003F
+1E2E8 0061
+1E2E8 0041
+1E2E8 0062
+1E2E9 0021
+1E2E9 003F
+1E2E9 0061
+1E2E9 0041
+1E2E9 0062
+1E2EA 0021
+1E2EA 003F
+1E2EA 0061
+1E2EA 0041
+1E2EA 0062
+1E2EB 0021
+1E2EB 003F
+1E2EB 0061
+1E2EB 0041
+1E2EB 0062
10280 0021
10280 003F
10280 0061
@@ -145406,6 +148617,121 @@ A4F7 0062
10B91 0061
10B91 0041
10B91 0062
+10FE0 0021
+10FE0 003F
+10FE0 0061
+10FE0 0041
+10FE0 0062
+10FE1 0021
+10FE1 003F
+10FE1 0061
+10FE1 0041
+10FE1 0062
+10FE2 0021
+10FE2 003F
+10FE2 0061
+10FE2 0041
+10FE2 0062
+10FE3 0021
+10FE3 003F
+10FE3 0061
+10FE3 0041
+10FE3 0062
+10FE4 0021
+10FE4 003F
+10FE4 0061
+10FE4 0041
+10FE4 0062
+10FE5 0021
+10FE5 003F
+10FE5 0061
+10FE5 0041
+10FE5 0062
+10FE6 0021
+10FE6 003F
+10FE6 0061
+10FE6 0041
+10FE6 0062
+10FF6 0021
+10FF6 003F
+10FF6 0061
+10FF6 0041
+10FF6 0062
+10FE7 0021
+10FE7 003F
+10FE7 0061
+10FE7 0041
+10FE7 0062
+10FE8 0021
+10FE8 003F
+10FE8 0061
+10FE8 0041
+10FE8 0062
+10FE9 0021
+10FE9 003F
+10FE9 0061
+10FE9 0041
+10FE9 0062
+10FEA 0021
+10FEA 003F
+10FEA 0061
+10FEA 0041
+10FEA 0062
+10FEB 0021
+10FEB 003F
+10FEB 0061
+10FEB 0041
+10FEB 0062
+10FEC 0021
+10FEC 003F
+10FEC 0061
+10FEC 0041
+10FEC 0062
+10FED 0021
+10FED 003F
+10FED 0061
+10FED 0041
+10FED 0062
+10FEE 0021
+10FEE 003F
+10FEE 0061
+10FEE 0041
+10FEE 0062
+10FEF 0021
+10FEF 003F
+10FEF 0061
+10FEF 0041
+10FEF 0062
+10FF0 0021
+10FF0 003F
+10FF0 0061
+10FF0 0041
+10FF0 0062
+10FF1 0021
+10FF1 003F
+10FF1 0061
+10FF1 0041
+10FF1 0062
+10FF2 0021
+10FF2 003F
+10FF2 0061
+10FF2 0041
+10FF2 0062
+10FF3 0021
+10FF3 003F
+10FF3 0061
+10FF3 0041
+10FF3 0062
+10FF4 0021
+10FF4 003F
+10FF4 0061
+10FF4 0041
+10FF4 0062
+10FF5 0021
+10FF5 003F
+10FF5 0061
+10FF5 0041
+10FF5 0062
10AC0 0021
10AC0 003F
10AC0 0061
@@ -160721,6 +164047,11 @@ F9A8 003F
F9A8 0061
F9A8 0041
F9A8 0062
+32FF 0021
+32FF 003F
+32FF 0061
+32FF 0041
+32FF 0062
32AD 0021
32AD 003F
32AD 0061
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_SHIFTED_SHORT.txt b/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_SHIFTED_SHORT.txt
index d634c5997..4a2088980 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_SHIFTED_SHORT.txt
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/data/CollationTest_SHIFTED_SHORT.txt
@@ -1,10 +1,10 @@
# CollationTest_CLDR_SHIFTED_SHORT.txt
-# Date: 2018-05-21, 23:52:53 GMT
-# © 2018 Unicode®, Inc.
+# Date: 2019-04-01, 20:17:36 GMT
+# © 2019 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
-# UCA Version: 11.0.0
-# UCD Version: 11.0.0
+# UCA Version: 12.1.0
+# UCD Version: 12.1.0
# For a description of the format and usage, see
# http://www.unicode.org/reports/tr35/tr35-collation.html#Root_Data_Files
@@ -158,6 +158,8 @@ FF0C 003F
2E4C 003F
2E4E 0021
2E4E 003F
+2E4F 0021
+2E4F 003F
055D 0021
055D 003F
060C 0021
@@ -195,6 +197,9 @@ FE45 0021
FE45 003F
FE46 0021
FE46 003F
+16FE2 0334
+16FE2 0021
+16FE2 003F
003B 0021
037E 0021
FE14 0021
@@ -621,6 +626,15 @@ FFFB 0021
11372 0021
11373 0021
11374 0021
+13430 0021
+13431 0021
+13432 0021
+13433 0021
+13434 0021
+13435 0021
+13436 0021
+13437 0021
+13438 0021
1BCA0 0021
1BCA1 0021
1BCA2 0021
@@ -1482,6 +1496,15 @@ FFFB 003F
11372 003F
11373 003F
11374 003F
+13430 003F
+13431 003F
+13432 003F
+13433 003F
+13434 003F
+13435 003F
+13436 003F
+13437 003F
+13438 003F
1BCA0 003F
1BCA1 003F
1BCA2 003F
@@ -3044,6 +3067,8 @@ A8FC 003F
0A76 003F
0AF0 0021
0AF0 003F
+0C77 0021
+0C77 003F
0C84 0021
0C84 003F
0DF4 0021
@@ -3196,8 +3221,6 @@ AADF 003F
1AAC 003F
1AAD 0021
1AAD 003F
-166D 0021
-166D 003F
1CC0 0021
1CC0 003F
1CC1 0021
@@ -3443,6 +3466,12 @@ AA5C 003F
1183B 0334
1183B 0021
1183B 003F
+119E2 0334
+119E2 0021
+119E2 003F
+11FFF 0334
+11FFF 0021
+11FFF 003F
16B37 0334
16B37 0021
16B37 003F
@@ -4339,6 +4368,15 @@ FE2F 0334
1CE8 0334
110BD 0334
110CD 0334
+13430 0334
+13431 0334
+13432 0334
+13433 0334
+13434 0334
+13435 0334
+13436 0334
+13437 0334
+13438 0334
1BCA0 0334
1BCA1 0334
1BCA2 0334
@@ -5549,18 +5587,40 @@ A92D 0334
193B 0334
0334 16B30
16B30 0334
+0334 1E131
+1E131 0334
0334 16B31
16B31 0334
+0334 1E136
+1E136 0334
0334 16B32
16B32 0334
+0334 1E132
+1E132 0334
0334 16B33
16B33 0334
+0334 1E133
+1E133 0334
0334 16B34
16B34 0334
+0334 1E130
+1E130 0334
0334 16B35
16B35 0334
+0334 1E134
+1E134 0334
0334 16B36
16B36 0334
+0334 1E135
+1E135 0334
+0334 1E2EC
+1E2EC 0334
+0334 1E2ED
+1E2ED 0334
+0334 1E2EE
+1E2EE 0334
+0334 1E2EF
+1E2EF 0334
0334 302A
302A 0334
0334 302B
@@ -6098,6 +6158,7 @@ A981 0021
1163D 0021
116AB 0021
11837 0021
+119DE 0021
11A38 0021
11A96 0021
11C3D 0021
@@ -6141,6 +6202,7 @@ A981 003F
1163D 003F
116AB 003F
11837 003F
+119DE 003F
11A38 003F
11A96 003F
11C3D 003F
@@ -6161,6 +6223,7 @@ A981 003F
1163D 0334
116AB 0334
11837 0334
+119DE 0334
11A38 0334
11A96 0334
11C3D 0334
@@ -6197,6 +6260,7 @@ A983 0021
1163E 0021
116AC 0021
11838 0021
+119DF 0021
11A39 0021
11A97 0021
11C3E 0021
@@ -6232,6 +6296,7 @@ A983 003F
1163E 003F
116AC 003F
11838 003F
+119DF 003F
11A39 003F
11A97 003F
11C3E 003F
@@ -6247,6 +6312,7 @@ A983 003F
1163E 0334
116AC 0334
11838 0334
+119DF 0334
11A39 0334
11A97 0334
11C3E 0334
@@ -6358,19 +6424,41 @@ A92D 003F
193B 0021
193B 003F
16B30 0021
+1E131 0021
16B30 003F
+1E131 003F
16B31 0021
+1E136 0021
16B31 003F
+1E136 003F
16B32 0021
+1E132 0021
16B32 003F
+1E132 003F
16B33 0021
+1E133 0021
16B33 003F
+1E133 003F
16B34 0021
+1E130 0021
16B34 003F
+1E130 003F
16B35 0021
+1E134 0021
16B35 003F
+1E134 003F
16B36 0021
+1E135 0021
16B36 003F
+1E135 003F
+1E2EC 0021
+1E2EC 003F
+1E2ED 0021
+1E2ED 003F
+1E2EE 0021
+1E2EE 003F
+1E2EF 0021
+1E2EF 003F
302A 0021
302A 003F
302B 0021
@@ -7328,6 +7416,156 @@ FBC1 0062
0BFA 0061
0BFA 0041
0BFA 0062
+11FD5 0021
+11FD5 003F
+11FD5 0334
+11FD5 0061
+11FD5 0041
+11FD5 0062
+11FD6 0021
+11FD6 003F
+11FD6 0334
+11FD6 0061
+11FD6 0041
+11FD6 0062
+11FD7 0021
+11FD7 003F
+11FD7 0334
+11FD7 0061
+11FD7 0041
+11FD7 0062
+11FD8 0021
+11FD8 003F
+11FD8 0334
+11FD8 0061
+11FD8 0041
+11FD8 0062
+11FD9 0021
+11FD9 003F
+11FD9 0334
+11FD9 0061
+11FD9 0041
+11FD9 0062
+11FDA 0021
+11FDA 003F
+11FDA 0334
+11FDA 0061
+11FDA 0041
+11FDA 0062
+11FDB 0021
+11FDB 003F
+11FDB 0334
+11FDB 0061
+11FDB 0041
+11FDB 0062
+11FDC 0021
+11FDC 003F
+11FDC 0334
+11FDC 0061
+11FDC 0041
+11FDC 0062
+11FE1 0021
+11FE1 003F
+11FE1 0334
+11FE1 0061
+11FE1 0041
+11FE1 0062
+11FE2 0021
+11FE2 003F
+11FE2 0334
+11FE2 0061
+11FE2 0041
+11FE2 0062
+11FE3 0021
+11FE3 003F
+11FE3 0334
+11FE3 0061
+11FE3 0041
+11FE3 0062
+11FE4 0021
+11FE4 003F
+11FE4 0334
+11FE4 0061
+11FE4 0041
+11FE4 0062
+11FE5 0021
+11FE5 003F
+11FE5 0334
+11FE5 0061
+11FE5 0041
+11FE5 0062
+11FE6 0021
+11FE6 003F
+11FE6 0334
+11FE6 0061
+11FE6 0041
+11FE6 0062
+11FE7 0021
+11FE7 003F
+11FE7 0334
+11FE7 0061
+11FE7 0041
+11FE7 0062
+11FE8 0021
+11FE8 003F
+11FE8 0334
+11FE8 0061
+11FE8 0041
+11FE8 0062
+11FE9 0021
+11FE9 003F
+11FE9 0334
+11FE9 0061
+11FE9 0041
+11FE9 0062
+11FEA 0021
+11FEA 003F
+11FEA 0334
+11FEA 0061
+11FEA 0041
+11FEA 0062
+11FEB 0021
+11FEB 003F
+11FEB 0334
+11FEB 0061
+11FEB 0041
+11FEB 0062
+11FEC 0021
+11FEC 003F
+11FEC 0334
+11FEC 0061
+11FEC 0041
+11FEC 0062
+11FED 0021
+11FED 003F
+11FED 0334
+11FED 0061
+11FED 0041
+11FED 0062
+11FEE 0021
+11FEE 003F
+11FEE 0334
+11FEE 0061
+11FEE 0041
+11FEE 0062
+11FEF 0021
+11FEF 003F
+11FEF 0334
+11FEF 0061
+11FEF 0041
+11FEF 0062
+11FF0 0021
+11FF0 003F
+11FF0 0334
+11FF0 0061
+11FF0 0041
+11FF0 0062
+11FF1 0021
+11FF1 003F
+11FF1 0334
+11FF1 0061
+11FF1 0041
+11FF1 0062
0C7F 0021
0C7F 003F
0C7F 0061
@@ -7558,6 +7796,11 @@ A839 0062
0FD8 0061
0FD8 0041
0FD8 0062
+166D 0021
+166D 003F
+166D 0061
+166D 0041
+166D 0062
1940 0021
1940 003F
1940 0061
@@ -18721,6 +18964,11 @@ FFEE 0062
2BC8 0061
2BC8 0041
2BC8 0062
+2BC9 0021
+2BC9 003F
+2BC9 0061
+2BC9 0041
+2BC9 0062
2BCA 0021
2BCA 003F
2BCA 0061
@@ -18986,6 +19234,11 @@ FFEE 0062
2BFE 0061
2BFE 0041
2BFE 0062
+2BFF 0021
+2BFF 003F
+2BFF 0061
+2BFF 0041
+2BFF 0062
2CE5 0021
2CE5 003F
2CE5 0061
@@ -22047,6 +22300,12 @@ A4C6 0062
16B45 0061
16B45 0041
16B45 0062
+1E14F 0021
+1E14F 003F
+1E14F 0334
+1E14F 0061
+1E14F 0041
+1E14F 0062
1D000 0021
1D000 003F
1D000 0334
@@ -25150,6 +25409,12 @@ A4C6 0062
1ECAC 0061
1ECAC 0041
1ECAC 0062
+1ED2E 0021
+1ED2E 003F
+1ED2E 0334
+1ED2E 0061
+1ED2E 0041
+1ED2E 0062
1F000 0021
1F000 003F
1F000 0334
@@ -26506,6 +26771,510 @@ A4C6 0062
1F0F5 0061
1F0F5 0041
1F0F5 0062
+1FA00 0021
+1FA00 003F
+1FA00 0334
+1FA00 0061
+1FA00 0041
+1FA00 0062
+1FA01 0021
+1FA01 003F
+1FA01 0334
+1FA01 0061
+1FA01 0041
+1FA01 0062
+1FA02 0021
+1FA02 003F
+1FA02 0334
+1FA02 0061
+1FA02 0041
+1FA02 0062
+1FA03 0021
+1FA03 003F
+1FA03 0334
+1FA03 0061
+1FA03 0041
+1FA03 0062
+1FA04 0021
+1FA04 003F
+1FA04 0334
+1FA04 0061
+1FA04 0041
+1FA04 0062
+1FA05 0021
+1FA05 003F
+1FA05 0334
+1FA05 0061
+1FA05 0041
+1FA05 0062
+1FA06 0021
+1FA06 003F
+1FA06 0334
+1FA06 0061
+1FA06 0041
+1FA06 0062
+1FA07 0021
+1FA07 003F
+1FA07 0334
+1FA07 0061
+1FA07 0041
+1FA07 0062
+1FA08 0021
+1FA08 003F
+1FA08 0334
+1FA08 0061
+1FA08 0041
+1FA08 0062
+1FA09 0021
+1FA09 003F
+1FA09 0334
+1FA09 0061
+1FA09 0041
+1FA09 0062
+1FA0A 0021
+1FA0A 003F
+1FA0A 0334
+1FA0A 0061
+1FA0A 0041
+1FA0A 0062
+1FA0B 0021
+1FA0B 003F
+1FA0B 0334
+1FA0B 0061
+1FA0B 0041
+1FA0B 0062
+1FA0C 0021
+1FA0C 003F
+1FA0C 0334
+1FA0C 0061
+1FA0C 0041
+1FA0C 0062
+1FA0D 0021
+1FA0D 003F
+1FA0D 0334
+1FA0D 0061
+1FA0D 0041
+1FA0D 0062
+1FA0E 0021
+1FA0E 003F
+1FA0E 0334
+1FA0E 0061
+1FA0E 0041
+1FA0E 0062
+1FA0F 0021
+1FA0F 003F
+1FA0F 0334
+1FA0F 0061
+1FA0F 0041
+1FA0F 0062
+1FA10 0021
+1FA10 003F
+1FA10 0334
+1FA10 0061
+1FA10 0041
+1FA10 0062
+1FA11 0021
+1FA11 003F
+1FA11 0334
+1FA11 0061
+1FA11 0041
+1FA11 0062
+1FA12 0021
+1FA12 003F
+1FA12 0334
+1FA12 0061
+1FA12 0041
+1FA12 0062
+1FA13 0021
+1FA13 003F
+1FA13 0334
+1FA13 0061
+1FA13 0041
+1FA13 0062
+1FA14 0021
+1FA14 003F
+1FA14 0334
+1FA14 0061
+1FA14 0041
+1FA14 0062
+1FA15 0021
+1FA15 003F
+1FA15 0334
+1FA15 0061
+1FA15 0041
+1FA15 0062
+1FA16 0021
+1FA16 003F
+1FA16 0334
+1FA16 0061
+1FA16 0041
+1FA16 0062
+1FA17 0021
+1FA17 003F
+1FA17 0334
+1FA17 0061
+1FA17 0041
+1FA17 0062
+1FA18 0021
+1FA18 003F
+1FA18 0334
+1FA18 0061
+1FA18 0041
+1FA18 0062
+1FA19 0021
+1FA19 003F
+1FA19 0334
+1FA19 0061
+1FA19 0041
+1FA19 0062
+1FA1A 0021
+1FA1A 003F
+1FA1A 0334
+1FA1A 0061
+1FA1A 0041
+1FA1A 0062
+1FA1B 0021
+1FA1B 003F
+1FA1B 0334
+1FA1B 0061
+1FA1B 0041
+1FA1B 0062
+1FA1C 0021
+1FA1C 003F
+1FA1C 0334
+1FA1C 0061
+1FA1C 0041
+1FA1C 0062
+1FA1D 0021
+1FA1D 003F
+1FA1D 0334
+1FA1D 0061
+1FA1D 0041
+1FA1D 0062
+1FA1E 0021
+1FA1E 003F
+1FA1E 0334
+1FA1E 0061
+1FA1E 0041
+1FA1E 0062
+1FA1F 0021
+1FA1F 003F
+1FA1F 0334
+1FA1F 0061
+1FA1F 0041
+1FA1F 0062
+1FA20 0021
+1FA20 003F
+1FA20 0334
+1FA20 0061
+1FA20 0041
+1FA20 0062
+1FA21 0021
+1FA21 003F
+1FA21 0334
+1FA21 0061
+1FA21 0041
+1FA21 0062
+1FA22 0021
+1FA22 003F
+1FA22 0334
+1FA22 0061
+1FA22 0041
+1FA22 0062
+1FA23 0021
+1FA23 003F
+1FA23 0334
+1FA23 0061
+1FA23 0041
+1FA23 0062
+1FA24 0021
+1FA24 003F
+1FA24 0334
+1FA24 0061
+1FA24 0041
+1FA24 0062
+1FA25 0021
+1FA25 003F
+1FA25 0334
+1FA25 0061
+1FA25 0041
+1FA25 0062
+1FA26 0021
+1FA26 003F
+1FA26 0334
+1FA26 0061
+1FA26 0041
+1FA26 0062
+1FA27 0021
+1FA27 003F
+1FA27 0334
+1FA27 0061
+1FA27 0041
+1FA27 0062
+1FA28 0021
+1FA28 003F
+1FA28 0334
+1FA28 0061
+1FA28 0041
+1FA28 0062
+1FA29 0021
+1FA29 003F
+1FA29 0334
+1FA29 0061
+1FA29 0041
+1FA29 0062
+1FA2A 0021
+1FA2A 003F
+1FA2A 0334
+1FA2A 0061
+1FA2A 0041
+1FA2A 0062
+1FA2B 0021
+1FA2B 003F
+1FA2B 0334
+1FA2B 0061
+1FA2B 0041
+1FA2B 0062
+1FA2C 0021
+1FA2C 003F
+1FA2C 0334
+1FA2C 0061
+1FA2C 0041
+1FA2C 0062
+1FA2D 0021
+1FA2D 003F
+1FA2D 0334
+1FA2D 0061
+1FA2D 0041
+1FA2D 0062
+1FA2E 0021
+1FA2E 003F
+1FA2E 0334
+1FA2E 0061
+1FA2E 0041
+1FA2E 0062
+1FA2F 0021
+1FA2F 003F
+1FA2F 0334
+1FA2F 0061
+1FA2F 0041
+1FA2F 0062
+1FA30 0021
+1FA30 003F
+1FA30 0334
+1FA30 0061
+1FA30 0041
+1FA30 0062
+1FA31 0021
+1FA31 003F
+1FA31 0334
+1FA31 0061
+1FA31 0041
+1FA31 0062
+1FA32 0021
+1FA32 003F
+1FA32 0334
+1FA32 0061
+1FA32 0041
+1FA32 0062
+1FA33 0021
+1FA33 003F
+1FA33 0334
+1FA33 0061
+1FA33 0041
+1FA33 0062
+1FA34 0021
+1FA34 003F
+1FA34 0334
+1FA34 0061
+1FA34 0041
+1FA34 0062
+1FA35 0021
+1FA35 003F
+1FA35 0334
+1FA35 0061
+1FA35 0041
+1FA35 0062
+1FA36 0021
+1FA36 003F
+1FA36 0334
+1FA36 0061
+1FA36 0041
+1FA36 0062
+1FA37 0021
+1FA37 003F
+1FA37 0334
+1FA37 0061
+1FA37 0041
+1FA37 0062
+1FA38 0021
+1FA38 003F
+1FA38 0334
+1FA38 0061
+1FA38 0041
+1FA38 0062
+1FA39 0021
+1FA39 003F
+1FA39 0334
+1FA39 0061
+1FA39 0041
+1FA39 0062
+1FA3A 0021
+1FA3A 003F
+1FA3A 0334
+1FA3A 0061
+1FA3A 0041
+1FA3A 0062
+1FA3B 0021
+1FA3B 003F
+1FA3B 0334
+1FA3B 0061
+1FA3B 0041
+1FA3B 0062
+1FA3C 0021
+1FA3C 003F
+1FA3C 0334
+1FA3C 0061
+1FA3C 0041
+1FA3C 0062
+1FA3D 0021
+1FA3D 003F
+1FA3D 0334
+1FA3D 0061
+1FA3D 0041
+1FA3D 0062
+1FA3E 0021
+1FA3E 003F
+1FA3E 0334
+1FA3E 0061
+1FA3E 0041
+1FA3E 0062
+1FA3F 0021
+1FA3F 003F
+1FA3F 0334
+1FA3F 0061
+1FA3F 0041
+1FA3F 0062
+1FA40 0021
+1FA40 003F
+1FA40 0334
+1FA40 0061
+1FA40 0041
+1FA40 0062
+1FA41 0021
+1FA41 003F
+1FA41 0334
+1FA41 0061
+1FA41 0041
+1FA41 0062
+1FA42 0021
+1FA42 003F
+1FA42 0334
+1FA42 0061
+1FA42 0041
+1FA42 0062
+1FA43 0021
+1FA43 003F
+1FA43 0334
+1FA43 0061
+1FA43 0041
+1FA43 0062
+1FA44 0021
+1FA44 003F
+1FA44 0334
+1FA44 0061
+1FA44 0041
+1FA44 0062
+1FA45 0021
+1FA45 003F
+1FA45 0334
+1FA45 0061
+1FA45 0041
+1FA45 0062
+1FA46 0021
+1FA46 003F
+1FA46 0334
+1FA46 0061
+1FA46 0041
+1FA46 0062
+1FA47 0021
+1FA47 003F
+1FA47 0334
+1FA47 0061
+1FA47 0041
+1FA47 0062
+1FA48 0021
+1FA48 003F
+1FA48 0334
+1FA48 0061
+1FA48 0041
+1FA48 0062
+1FA49 0021
+1FA49 003F
+1FA49 0334
+1FA49 0061
+1FA49 0041
+1FA49 0062
+1FA4A 0021
+1FA4A 003F
+1FA4A 0334
+1FA4A 0061
+1FA4A 0041
+1FA4A 0062
+1FA4B 0021
+1FA4B 003F
+1FA4B 0334
+1FA4B 0061
+1FA4B 0041
+1FA4B 0062
+1FA4C 0021
+1FA4C 003F
+1FA4C 0334
+1FA4C 0061
+1FA4C 0041
+1FA4C 0062
+1FA4D 0021
+1FA4D 003F
+1FA4D 0334
+1FA4D 0061
+1FA4D 0041
+1FA4D 0062
+1FA4E 0021
+1FA4E 003F
+1FA4E 0334
+1FA4E 0061
+1FA4E 0041
+1FA4E 0062
+1FA4F 0021
+1FA4F 003F
+1FA4F 0334
+1FA4F 0061
+1FA4F 0041
+1FA4F 0062
+1FA50 0021
+1FA50 003F
+1FA50 0334
+1FA50 0061
+1FA50 0041
+1FA50 0062
+1FA51 0021
+1FA51 003F
+1FA51 0334
+1FA51 0061
+1FA51 0041
+1FA51 0062
+1FA52 0021
+1FA52 003F
+1FA52 0334
+1FA52 0061
+1FA52 0041
+1FA52 0062
+1FA53 0021
+1FA53 003F
+1FA53 0334
+1FA53 0061
+1FA53 0041
+1FA53 0062
1FA60 0021
1FA60 003F
1FA60 0334
@@ -31306,6 +32075,24 @@ A4C6 0062
1F90B 0061
1F90B 0041
1F90B 0062
+1F90D 0021
+1F90D 003F
+1F90D 0334
+1F90D 0061
+1F90D 0041
+1F90D 0062
+1F90E 0021
+1F90E 003F
+1F90E 0334
+1F90E 0061
+1F90E 0041
+1F90E 0062
+1F90F 0021
+1F90F 003F
+1F90F 0334
+1F90F 0061
+1F90F 0041
+1F90F 0062
1F910 0021
1F910 003F
1F910 0334
@@ -31588,6 +32375,12 @@ A4C6 0062
1F93E 0061
1F93E 0041
1F93E 0062
+1F93F 0021
+1F93F 003F
+1F93F 0334
+1F93F 0061
+1F93F 0041
+1F93F 0062
1F940 0021
1F940 003F
1F940 0334
@@ -31882,6 +32675,12 @@ A4C6 0062
1F970 0061
1F970 0041
1F970 0062
+1F971 0021
+1F971 003F
+1F971 0334
+1F971 0061
+1F971 0041
+1F971 0062
1F973 0021
1F973 003F
1F973 0334
@@ -31912,6 +32711,12 @@ A4C6 0062
1F97A 0061
1F97A 0041
1F97A 0062
+1F97B 0021
+1F97B 003F
+1F97B 0334
+1F97B 0061
+1F97B 0041
+1F97B 0062
1F97C 0021
1F97C 003F
1F97C 0334
@@ -32146,6 +32951,54 @@ A4C6 0062
1F9A2 0061
1F9A2 0041
1F9A2 0062
+1F9A5 0021
+1F9A5 003F
+1F9A5 0334
+1F9A5 0061
+1F9A5 0041
+1F9A5 0062
+1F9A6 0021
+1F9A6 003F
+1F9A6 0334
+1F9A6 0061
+1F9A6 0041
+1F9A6 0062
+1F9A7 0021
+1F9A7 003F
+1F9A7 0334
+1F9A7 0061
+1F9A7 0041
+1F9A7 0062
+1F9A8 0021
+1F9A8 003F
+1F9A8 0334
+1F9A8 0061
+1F9A8 0041
+1F9A8 0062
+1F9A9 0021
+1F9A9 003F
+1F9A9 0334
+1F9A9 0061
+1F9A9 0041
+1F9A9 0062
+1F9AA 0021
+1F9AA 003F
+1F9AA 0334
+1F9AA 0061
+1F9AA 0041
+1F9AA 0062
+1F9AE 0021
+1F9AE 003F
+1F9AE 0334
+1F9AE 0061
+1F9AE 0041
+1F9AE 0062
+1F9AF 0021
+1F9AF 003F
+1F9AF 0334
+1F9AF 0061
+1F9AF 0041
+1F9AF 0062
1F9B0 0021
1F9B0 003F
1F9B0 0334
@@ -32206,6 +33059,42 @@ A4C6 0062
1F9B9 0061
1F9B9 0041
1F9B9 0062
+1F9BA 0021
+1F9BA 003F
+1F9BA 0334
+1F9BA 0061
+1F9BA 0041
+1F9BA 0062
+1F9BB 0021
+1F9BB 003F
+1F9BB 0334
+1F9BB 0061
+1F9BB 0041
+1F9BB 0062
+1F9BC 0021
+1F9BC 003F
+1F9BC 0334
+1F9BC 0061
+1F9BC 0041
+1F9BC 0062
+1F9BD 0021
+1F9BD 003F
+1F9BD 0334
+1F9BD 0061
+1F9BD 0041
+1F9BD 0062
+1F9BE 0021
+1F9BE 003F
+1F9BE 0334
+1F9BE 0061
+1F9BE 0041
+1F9BE 0062
+1F9BF 0021
+1F9BF 003F
+1F9BF 0334
+1F9BF 0061
+1F9BF 0041
+1F9BF 0062
1F9C0 0021
1F9C0 003F
1F9C0 0334
@@ -32224,6 +33113,72 @@ A4C6 0062
1F9C2 0061
1F9C2 0041
1F9C2 0062
+1F9C3 0021
+1F9C3 003F
+1F9C3 0334
+1F9C3 0061
+1F9C3 0041
+1F9C3 0062
+1F9C4 0021
+1F9C4 003F
+1F9C4 0334
+1F9C4 0061
+1F9C4 0041
+1F9C4 0062
+1F9C5 0021
+1F9C5 003F
+1F9C5 0334
+1F9C5 0061
+1F9C5 0041
+1F9C5 0062
+1F9C6 0021
+1F9C6 003F
+1F9C6 0334
+1F9C6 0061
+1F9C6 0041
+1F9C6 0062
+1F9C7 0021
+1F9C7 003F
+1F9C7 0334
+1F9C7 0061
+1F9C7 0041
+1F9C7 0062
+1F9C8 0021
+1F9C8 003F
+1F9C8 0334
+1F9C8 0061
+1F9C8 0041
+1F9C8 0062
+1F9C9 0021
+1F9C9 003F
+1F9C9 0334
+1F9C9 0061
+1F9C9 0041
+1F9C9 0062
+1F9CA 0021
+1F9CA 003F
+1F9CA 0334
+1F9CA 0061
+1F9CA 0041
+1F9CA 0062
+1F9CD 0021
+1F9CD 003F
+1F9CD 0334
+1F9CD 0061
+1F9CD 0041
+1F9CD 0062
+1F9CE 0021
+1F9CE 003F
+1F9CE 0334
+1F9CE 0061
+1F9CE 0041
+1F9CE 0062
+1F9CF 0021
+1F9CF 003F
+1F9CF 0334
+1F9CF 0061
+1F9CF 0041
+1F9CF 0062
1F9D0 0021
1F9D0 003F
1F9D0 0334
@@ -32512,6 +33467,102 @@ A4C6 0062
1F9FF 0061
1F9FF 0041
1F9FF 0062
+1FA70 0021
+1FA70 003F
+1FA70 0334
+1FA70 0061
+1FA70 0041
+1FA70 0062
+1FA71 0021
+1FA71 003F
+1FA71 0334
+1FA71 0061
+1FA71 0041
+1FA71 0062
+1FA72 0021
+1FA72 003F
+1FA72 0334
+1FA72 0061
+1FA72 0041
+1FA72 0062
+1FA73 0021
+1FA73 003F
+1FA73 0334
+1FA73 0061
+1FA73 0041
+1FA73 0062
+1FA78 0021
+1FA78 003F
+1FA78 0334
+1FA78 0061
+1FA78 0041
+1FA78 0062
+1FA79 0021
+1FA79 003F
+1FA79 0334
+1FA79 0061
+1FA79 0041
+1FA79 0062
+1FA7A 0021
+1FA7A 003F
+1FA7A 0334
+1FA7A 0061
+1FA7A 0041
+1FA7A 0062
+1FA80 0021
+1FA80 003F
+1FA80 0334
+1FA80 0061
+1FA80 0041
+1FA80 0062
+1FA81 0021
+1FA81 003F
+1FA81 0334
+1FA81 0061
+1FA81 0041
+1FA81 0062
+1FA82 0021
+1FA82 003F
+1FA82 0334
+1FA82 0061
+1FA82 0041
+1FA82 0062
+1FA90 0021
+1FA90 003F
+1FA90 0334
+1FA90 0061
+1FA90 0041
+1FA90 0062
+1FA91 0021
+1FA91 003F
+1FA91 0334
+1FA91 0061
+1FA91 0041
+1FA91 0062
+1FA92 0021
+1FA92 003F
+1FA92 0334
+1FA92 0061
+1FA92 0041
+1FA92 0062
+1FA93 0021
+1FA93 003F
+1FA93 0334
+1FA93 0061
+1FA93 0041
+1FA93 0062
+1FA94 0021
+1FA94 003F
+1FA94 0334
+1FA94 0061
+1FA94 0041
+1FA94 0062
+1FA95 0021
+1FA95 003F
+1FA95 0334
+1FA95 0061
+1FA95 0041
+1FA95 0062
1F600 0021
1F600 003F
1F600 0334
@@ -33790,6 +34841,12 @@ A4C6 0062
1F6D4 0061
1F6D4 0041
1F6D4 0062
+1F6D5 0021
+1F6D5 003F
+1F6D5 0334
+1F6D5 0061
+1F6D5 0041
+1F6D5 0062
1F6E0 0021
1F6E0 003F
1F6E0 0334
@@ -33928,6 +34985,12 @@ A4C6 0062
1F6F9 0061
1F6F9 0041
1F6F9 0062
+1F6FA 0021
+1F6FA 003F
+1F6FA 0334
+1F6FA 0061
+1F6FA 0041
+1F6FA 0062
1F700 0021
1F700 003F
1F700 0334
@@ -35158,6 +36221,78 @@ A4C6 0062
1F7D8 0061
1F7D8 0041
1F7D8 0062
+1F7E0 0021
+1F7E0 003F
+1F7E0 0334
+1F7E0 0061
+1F7E0 0041
+1F7E0 0062
+1F7E1 0021
+1F7E1 003F
+1F7E1 0334
+1F7E1 0061
+1F7E1 0041
+1F7E1 0062
+1F7E2 0021
+1F7E2 003F
+1F7E2 0334
+1F7E2 0061
+1F7E2 0041
+1F7E2 0062
+1F7E3 0021
+1F7E3 003F
+1F7E3 0334
+1F7E3 0061
+1F7E3 0041
+1F7E3 0062
+1F7E4 0021
+1F7E4 003F
+1F7E4 0334
+1F7E4 0061
+1F7E4 0041
+1F7E4 0062
+1F7E5 0021
+1F7E5 003F
+1F7E5 0334
+1F7E5 0061
+1F7E5 0041
+1F7E5 0062
+1F7E6 0021
+1F7E6 003F
+1F7E6 0334
+1F7E6 0061
+1F7E6 0041
+1F7E6 0062
+1F7E7 0021
+1F7E7 003F
+1F7E7 0334
+1F7E7 0061
+1F7E7 0041
+1F7E7 0062
+1F7E8 0021
+1F7E8 003F
+1F7E8 0334
+1F7E8 0061
+1F7E8 0041
+1F7E8 0062
+1F7E9 0021
+1F7E9 003F
+1F7E9 0334
+1F7E9 0061
+1F7E9 0041
+1F7E9 0062
+1F7EA 0021
+1F7EA 003F
+1F7EA 0334
+1F7EA 0061
+1F7EA 0041
+1F7EA 0062
+1F7EB 0021
+1F7EB 003F
+1F7EB 0334
+1F7EB 0061
+1F7EB 0041
+1F7EB 0062
1F800 0021
1F800 003F
1F800 0334
@@ -39663,6 +40798,18 @@ AAF4 0062
16B43 0061
16B43 0041
16B43 0062
+1E13C 0021
+1E13C 003F
+1E13C 0334
+1E13C 0061
+1E13C 0041
+1E13C 0062
+1E13D 0021
+1E13D 003F
+1E13D 0334
+1E13D 0061
+1E13D 0041
+1E13D 0062
3005 0021
3005 003F
3005 0061
@@ -39685,6 +40832,12 @@ AAF4 0062
16FE1 0061
16FE1 0041
16FE1 0062
+16FE3 0021
+16FE3 003F
+16FE3 0334
+16FE3 0061
+16FE3 0041
+16FE3 0062
3031 0021
3031 003F
3032 0021
@@ -39846,6 +40999,30 @@ A838 0062
0BF9 0061
0BF9 0041
0BF9 0062
+11FDD 0021
+11FDD 003F
+11FDD 0334
+11FDD 0061
+11FDD 0041
+11FDD 0062
+11FDE 0021
+11FDE 003F
+11FDE 0334
+11FDE 0061
+11FDE 0041
+11FDE 0062
+11FDF 0021
+11FDF 003F
+11FDF 0334
+11FDF 0061
+11FDF 0041
+11FDF 0062
+11FE0 0021
+11FE0 003F
+11FE0 0334
+11FE0 0061
+11FE0 0041
+11FE0 0062
0E3F 0021
0E3F 003F
0E3F 0061
@@ -39856,6 +41033,12 @@ A838 0062
17DB 0061
17DB 0041
17DB 0062
+1E2FF 0021
+1E2FF 003F
+1E2FF 0334
+1E2FF 0061
+1E2FF 0041
+1E2FF 0062
20A0 0021
20A0 003F
20A0 0061
@@ -40137,6 +41320,132 @@ A835 0062
0BF2 0061
0BF2 0041
0BF2 0062
+11FC0 0021
+11FC0 003F
+11FC0 0334
+11FC0 0061
+11FC0 0041
+11FC0 0062
+11FC1 0021
+11FC1 003F
+11FC1 0334
+11FC1 0061
+11FC1 0041
+11FC1 0062
+11FC2 0021
+11FC2 003F
+11FC2 0334
+11FC2 0061
+11FC2 0041
+11FC2 0062
+11FC3 0021
+11FC3 003F
+11FC3 0334
+11FC3 0061
+11FC3 0041
+11FC3 0062
+11FC4 0021
+11FC4 003F
+11FC4 0334
+11FC4 0061
+11FC4 0041
+11FC4 0062
+11FC5 0021
+11FC5 003F
+11FC5 0334
+11FC5 0061
+11FC5 0041
+11FC5 0062
+11FC6 0021
+11FC6 003F
+11FC6 0334
+11FC6 0061
+11FC6 0041
+11FC6 0062
+11FC7 0021
+11FC7 003F
+11FC7 0334
+11FC7 0061
+11FC7 0041
+11FC7 0062
+11FC8 0021
+11FC8 003F
+11FC8 0334
+11FC8 0061
+11FC8 0041
+11FC8 0062
+11FC9 0021
+11FC9 003F
+11FC9 0334
+11FC9 0061
+11FC9 0041
+11FC9 0062
+11FCA 0021
+11FCA 003F
+11FCA 0334
+11FCA 0061
+11FCA 0041
+11FCA 0062
+11FCB 0021
+11FCB 003F
+11FCB 0334
+11FCB 0061
+11FCB 0041
+11FCB 0062
+11FCC 0021
+11FCC 003F
+11FCC 0334
+11FCC 0061
+11FCC 0041
+11FCC 0062
+11FCD 0021
+11FCD 003F
+11FCD 0334
+11FCD 0061
+11FCD 0041
+11FCD 0062
+11FCE 0021
+11FCE 003F
+11FCE 0334
+11FCE 0061
+11FCE 0041
+11FCE 0062
+11FCF 0021
+11FCF 003F
+11FCF 0334
+11FCF 0061
+11FCF 0041
+11FCF 0062
+11FD0 0021
+11FD0 003F
+11FD0 0334
+11FD0 0061
+11FD0 0041
+11FD0 0062
+11FD1 0021
+11FD1 003F
+11FD1 0334
+11FD1 0061
+11FD1 0041
+11FD1 0062
+11FD2 0021
+11FD2 003F
+11FD2 0334
+11FD2 0061
+11FD2 0041
+11FD2 0062
+11FD3 0021
+11FD3 003F
+11FD3 0334
+11FD3 0061
+11FD3 0041
+11FD3 0062
+11FD4 0021
+11FD4 003F
+11FD4 0334
+11FD4 0061
+11FD4 0041
+11FD4 0062
0D58 0021
0D58 003F
0D58 0061
@@ -42059,6 +43368,264 @@ A835 0062
1ECB4 0061
1ECB4 0041
1ECB4 0062
+1ED0A 0021
+1ED0A 003F
+1ED0A 0334
+1ED0A 0061
+1ED0A 0041
+1ED0A 0062
+1ED0B 0021
+1ED0B 003F
+1ED0B 0334
+1ED0B 0061
+1ED0B 0041
+1ED0B 0062
+1ED0C 0021
+1ED0C 003F
+1ED0C 0334
+1ED0C 0061
+1ED0C 0041
+1ED0C 0062
+1ED0D 0021
+1ED0D 003F
+1ED0D 0334
+1ED0D 0061
+1ED0D 0041
+1ED0D 0062
+1ED0E 0021
+1ED0E 003F
+1ED0E 0334
+1ED0E 0061
+1ED0E 0041
+1ED0E 0062
+1ED0F 0021
+1ED0F 003F
+1ED0F 0334
+1ED0F 0061
+1ED0F 0041
+1ED0F 0062
+1ED10 0021
+1ED10 003F
+1ED10 0334
+1ED10 0061
+1ED10 0041
+1ED10 0062
+1ED11 0021
+1ED11 003F
+1ED11 0334
+1ED11 0061
+1ED11 0041
+1ED11 0062
+1ED12 0021
+1ED12 003F
+1ED12 0334
+1ED12 0061
+1ED12 0041
+1ED12 0062
+1ED13 0021
+1ED13 003F
+1ED13 0334
+1ED13 0061
+1ED13 0041
+1ED13 0062
+1ED14 0021
+1ED14 003F
+1ED14 0334
+1ED14 0061
+1ED14 0041
+1ED14 0062
+1ED15 0021
+1ED15 003F
+1ED15 0334
+1ED15 0061
+1ED15 0041
+1ED15 0062
+1ED16 0021
+1ED16 003F
+1ED16 0334
+1ED16 0061
+1ED16 0041
+1ED16 0062
+1ED17 0021
+1ED17 003F
+1ED17 0334
+1ED17 0061
+1ED17 0041
+1ED17 0062
+1ED18 0021
+1ED18 003F
+1ED18 0334
+1ED18 0061
+1ED18 0041
+1ED18 0062
+1ED19 0021
+1ED19 003F
+1ED19 0334
+1ED19 0061
+1ED19 0041
+1ED19 0062
+1ED1A 0021
+1ED1A 003F
+1ED1A 0334
+1ED1A 0061
+1ED1A 0041
+1ED1A 0062
+1ED1B 0021
+1ED1B 003F
+1ED1B 0334
+1ED1B 0061
+1ED1B 0041
+1ED1B 0062
+1ED1C 0021
+1ED1C 003F
+1ED1C 0334
+1ED1C 0061
+1ED1C 0041
+1ED1C 0062
+1ED1D 0021
+1ED1D 003F
+1ED1D 0334
+1ED1D 0061
+1ED1D 0041
+1ED1D 0062
+1ED1E 0021
+1ED1E 003F
+1ED1E 0334
+1ED1E 0061
+1ED1E 0041
+1ED1E 0062
+1ED1F 0021
+1ED1F 003F
+1ED1F 0334
+1ED1F 0061
+1ED1F 0041
+1ED1F 0062
+1ED20 0021
+1ED20 003F
+1ED20 0334
+1ED20 0061
+1ED20 0041
+1ED20 0062
+1ED21 0021
+1ED21 003F
+1ED21 0334
+1ED21 0061
+1ED21 0041
+1ED21 0062
+1ED22 0021
+1ED22 003F
+1ED22 0334
+1ED22 0061
+1ED22 0041
+1ED22 0062
+1ED23 0021
+1ED23 003F
+1ED23 0334
+1ED23 0061
+1ED23 0041
+1ED23 0062
+1ED24 0021
+1ED24 003F
+1ED24 0334
+1ED24 0061
+1ED24 0041
+1ED24 0062
+1ED25 0021
+1ED25 003F
+1ED25 0334
+1ED25 0061
+1ED25 0041
+1ED25 0062
+1ED26 0021
+1ED26 003F
+1ED26 0334
+1ED26 0061
+1ED26 0041
+1ED26 0062
+1ED27 0021
+1ED27 003F
+1ED27 0334
+1ED27 0061
+1ED27 0041
+1ED27 0062
+1ED28 0021
+1ED28 003F
+1ED28 0334
+1ED28 0061
+1ED28 0041
+1ED28 0062
+1ED29 0021
+1ED29 003F
+1ED29 0334
+1ED29 0061
+1ED29 0041
+1ED29 0062
+1ED2A 0021
+1ED2A 003F
+1ED2A 0334
+1ED2A 0061
+1ED2A 0041
+1ED2A 0062
+1ED2B 0021
+1ED2B 003F
+1ED2B 0334
+1ED2B 0061
+1ED2B 0041
+1ED2B 0062
+1ED2C 0021
+1ED2C 003F
+1ED2C 0334
+1ED2C 0061
+1ED2C 0041
+1ED2C 0062
+1ED2D 0021
+1ED2D 003F
+1ED2D 0334
+1ED2D 0061
+1ED2D 0041
+1ED2D 0062
+1ED37 0021
+1ED37 003F
+1ED37 0334
+1ED37 0061
+1ED37 0041
+1ED37 0062
+1ED38 0021
+1ED38 003F
+1ED38 0334
+1ED38 0061
+1ED38 0041
+1ED38 0062
+1ED39 0021
+1ED39 003F
+1ED39 0334
+1ED39 0061
+1ED39 0041
+1ED39 0062
+1ED3A 0021
+1ED3A 003F
+1ED3A 0334
+1ED3A 0061
+1ED3A 0041
+1ED3A 0062
+1ED3B 0021
+1ED3B 003F
+1ED3B 0334
+1ED3B 0061
+1ED3B 0041
+1ED3B 0062
+1ED3C 0021
+1ED3C 003F
+1ED3C 0334
+1ED3C 0061
+1ED3C 0041
+1ED3C 0062
+1ED3D 0021
+1ED3D 003F
+1ED3D 0334
+1ED3D 0061
+1ED3D 0041
+1ED3D 0062
109C9 0021
109C9 003F
109C9 0334
@@ -42605,6 +44172,8 @@ ABF0 0021
16B50 0021
16E80 0021
1D2E0 0021
+1E140 0021
+1E2F0 0021
1E950 0021
0030 003F
0660 003F
@@ -42666,6 +44235,8 @@ ABF0 003F
16B50 003F
16E80 003F
1D2E0 003F
+1E140 003F
+1E2F0 003F
1E950 003F
FF10 0021
FF10 003F
@@ -42720,6 +44291,8 @@ FF10 003F
16B50 0334
16E80 0334
1D2E0 0334
+1E140 0334
+1E2F0 0334
1E950 0334
1D7CE 0334
1D7D8 0334
@@ -42793,6 +44366,8 @@ ABF0 0061
16B50 0061
16E80 0061
1D2E0 0061
+1E140 0061
+1E2F0 0061
1E950 0061
0030 0041
0660 0041
@@ -42854,6 +44429,8 @@ ABF0 0041
16B50 0041
16E80 0041
1D2E0 0041
+1E140 0041
+1E2F0 0041
1E950 0041
FF10 0061
FF10 0041
@@ -42945,6 +44522,8 @@ ABF0 0062
16B50 0062
16E80 0062
1D2E0 0062
+1E140 0062
+1E2F0 0062
1E950 0062
FF10 0062
1F101 0062
@@ -43065,10 +44644,13 @@ ABF1 0021
1D360 0021
1D372 0021
1D377 0021
+1E141 0021
+1E2F1 0021
1E8C7 0021
1E951 0021
1EC71 0021
1ECA3 0021
+1ED01 0021
0031 003F
0661 003F
06F1 003F
@@ -43168,10 +44750,13 @@ ABF1 003F
1D360 003F
1D372 003F
1D377 003F
+1E141 003F
+1E2F1 003F
1E8C7 003F
1E951 003F
1EC71 003F
1ECA3 003F
+1ED01 003F
FF11 0021
FF11 003F
2474 0021
@@ -43264,10 +44849,13 @@ FF11 003F
1D360 0334
1D372 0334
1D377 0334
+1E141 0334
+1E2F1 0334
1E8C7 0334
1E951 0334
1EC71 0334
1ECA3 0334
+1ED01 0334
1D7CF 0334
1D7D9 0334
1D7E3 0334
@@ -43769,10 +45357,13 @@ ABF1 0061
1D360 0061
1D372 0061
1D377 0061
+1E141 0061
+1E2F1 0061
1E8C7 0061
1E951 0061
1EC71 0061
1ECA3 0061
+1ED01 0061
0031 0041
0661 0041
06F1 0041
@@ -43872,10 +45463,13 @@ ABF1 0041
1D360 0041
1D372 0041
1D377 0041
+1E141 0041
+1E2F1 0041
1E8C7 0041
1E951 0041
1EC71 0041
1ECA3 0041
+1ED01 0041
FF11 0061
FF11 0041
2474 0061
@@ -44013,10 +45607,13 @@ ABF1 0062
1D360 0062
1D372 0062
1D377 0062
+1E141 0062
+1E2F1 0062
1E8C7 0062
1E951 0062
1EC71 0062
1ECA3 0062
+1ED01 0062
FF11 0062
2474 0062
1F102 0062
@@ -44145,10 +45742,13 @@ ABF2 0021
1D2E2 0021
1D361 0021
1D373 0021
+1E142 0021
+1E2F2 0021
1E8C8 0021
1E952 0021
1EC72 0021
1ECA4 0021
+1ED02 0021
0032 003F
0662 003F
06F2 003F
@@ -44243,10 +45843,13 @@ ABF2 003F
1D2E2 003F
1D361 003F
1D373 003F
+1E142 003F
+1E2F2 003F
1E8C8 003F
1E952 003F
1EC72 003F
1ECA4 003F
+1ED02 003F
FF12 0021
FF12 003F
2475 0021
@@ -44335,10 +45938,13 @@ FF12 003F
1D2E2 0334
1D361 0334
1D373 0334
+1E142 0334
+1E2F2 0334
1E8C8 0334
1E952 0334
1EC72 0334
1ECA4 0334
+1ED02 0334
1D7D0 0334
1D7DA 0334
1D7E4 0334
@@ -44346,10 +45952,13 @@ FF12 003F
1D7F8 0334
16E95 0021
1ECB2 0021
+1ED2F 0021
16E95 003F
1ECB2 003F
+1ED2F 003F
16E95 0334
1ECB2 0334
+1ED2F 0334
2154 0021
2154 003F
2154 0061
@@ -44605,10 +46214,13 @@ ABF2 0061
1D2E2 0061
1D361 0061
1D373 0061
+1E142 0061
+1E2F2 0061
1E8C8 0061
1E952 0061
1EC72 0061
1ECA4 0061
+1ED02 0061
0032 0041
0662 0041
06F2 0041
@@ -44703,10 +46315,13 @@ ABF2 0041
1D2E2 0041
1D361 0041
1D373 0041
+1E142 0041
+1E2F2 0041
1E8C8 0041
1E952 0041
1EC72 0041
1ECA4 0041
+1ED02 0041
FF12 0061
FF12 0041
2475 0061
@@ -44743,8 +46358,10 @@ FF12 0041
2082 0041
16E95 0061
1ECB2 0061
+1ED2F 0061
16E95 0041
1ECB2 0041
+1ED2F 0041
0032 0062
0662 0062
06F2 0062
@@ -44839,10 +46456,13 @@ ABF2 0062
1D2E2 0062
1D361 0062
1D373 0062
+1E142 0062
+1E2F2 0062
1E8C8 0062
1E952 0062
1EC72 0062
1ECA4 0062
+1ED02 0062
FF12 0062
2475 0062
1F103 0062
@@ -44862,6 +46482,7 @@ FF12 0062
2082 0062
16E95 0062
1ECB2 0062
+1ED2F 0062
1F19D 0021
1F19D 003F
1F19D 0334
@@ -44983,10 +46604,13 @@ ABF3 0021
1D2E3 0021
1D362 0021
1D374 0021
+1E143 0021
+1E2F3 0021
1E8C9 0021
1E953 0021
1EC73 0021
1ECA5 0021
+1ED03 0021
0033 003F
0663 003F
06F3 003F
@@ -45081,10 +46705,13 @@ ABF3 003F
1D2E3 003F
1D362 003F
1D374 003F
+1E143 003F
+1E2F3 003F
1E8C9 003F
1E953 003F
1EC73 003F
1ECA5 003F
+1ED03 003F
FF13 0021
FF13 003F
2476 0021
@@ -45173,10 +46800,13 @@ FF13 003F
1D2E3 0334
1D362 0334
1D374 0334
+1E143 0334
+1E2F3 0334
1E8C9 0334
1E953 0334
1EC73 0334
1ECA5 0334
+1ED03 0334
1D7D1 0334
1D7DB 0334
1D7E5 0334
@@ -45184,7 +46814,10 @@ FF13 003F
1D7F9 0334
16E96 0021
16E96 003F
+1ED30 0021
+1ED30 003F
16E96 0334
+1ED30 0334
00BE 0021
00BE 003F
00BE 0061
@@ -45359,10 +46992,13 @@ ABF3 0061
1D2E3 0061
1D362 0061
1D374 0061
+1E143 0061
+1E2F3 0061
1E8C9 0061
1E953 0061
1EC73 0061
1ECA5 0061
+1ED03 0061
0033 0041
0663 0041
06F3 0041
@@ -45457,10 +47093,13 @@ ABF3 0041
1D2E3 0041
1D362 0041
1D374 0041
+1E143 0041
+1E2F3 0041
1E8C9 0041
1E953 0041
1EC73 0041
1ECA5 0041
+1ED03 0041
FF13 0061
FF13 0041
2476 0061
@@ -45497,6 +47136,8 @@ FF13 0041
2083 0041
16E96 0061
16E96 0041
+1ED30 0061
+1ED30 0041
0033 0062
0663 0062
06F3 0062
@@ -45591,10 +47232,13 @@ ABF3 0062
1D2E3 0062
1D362 0062
1D374 0062
+1E143 0062
+1E2F3 0062
1E8C9 0062
1E953 0062
1EC73 0062
1ECA5 0062
+1ED03 0062
FF13 0062
2476 0062
1F104 0062
@@ -45613,6 +47257,7 @@ FF13 0062
00B3 0062
2083 0062
16E96 0062
+1ED30 0062
1F19B 0021
1F19B 003F
1F19B 0334
@@ -45726,10 +47371,13 @@ ABF4 0021
1D2E4 0021
1D363 0021
1D375 0021
+1E144 0021
+1E2F4 0021
1E8CA 0021
1E954 0021
1EC74 0021
1ECA6 0021
+1ED04 0021
0034 003F
0664 003F
06F4 003F
@@ -45822,10 +47470,13 @@ ABF4 003F
1D2E4 003F
1D363 003F
1D375 003F
+1E144 003F
+1E2F4 003F
1E8CA 003F
1E954 003F
1EC74 003F
1ECA6 003F
+1ED04 003F
FF14 0021
FF14 003F
2477 0021
@@ -45914,15 +47565,21 @@ FF14 003F
1D2E4 0334
1D363 0334
1D375 0334
+1E144 0334
+1E2F4 0334
1E8CA 0334
1E954 0334
1EC74 0334
1ECA6 0334
+1ED04 0334
1D7D2 0334
1D7DC 0334
1D7E6 0334
1D7F0 0334
1D7FA 0334
+1ED31 0021
+1ED31 003F
+1ED31 0334
2158 0021
2158 003F
2158 0061
@@ -46075,10 +47732,13 @@ ABF4 0061
1D2E4 0061
1D363 0061
1D375 0061
+1E144 0061
+1E2F4 0061
1E8CA 0061
1E954 0061
1EC74 0061
1ECA6 0061
+1ED04 0061
0034 0041
0664 0041
06F4 0041
@@ -46171,10 +47831,13 @@ ABF4 0041
1D2E4 0041
1D363 0041
1D375 0041
+1E144 0041
+1E2F4 0041
1E8CA 0041
1E954 0041
1EC74 0041
1ECA6 0041
+1ED04 0041
FF14 0061
FF14 0041
2477 0061
@@ -46209,6 +47872,8 @@ FF14 0041
2074 0041
2084 0061
2084 0041
+1ED31 0061
+1ED31 0041
0034 0062
0664 0062
06F4 0062
@@ -46301,10 +47966,13 @@ ABF4 0062
1D2E4 0062
1D363 0062
1D375 0062
+1E144 0062
+1E2F4 0062
1E8CA 0062
1E954 0062
1EC74 0062
1ECA6 0062
+1ED04 0062
FF14 0062
2477 0062
1F105 0062
@@ -46322,6 +47990,7 @@ FF14 0062
278D 0062
2074 0062
2084 0062
+1ED31 0062
1F19E 0021
1F19E 003F
1F19E 0334
@@ -46436,10 +48105,13 @@ ABF5 0021
1D364 0021
1D376 0021
1D378 0021
+1E145 0021
+1E2F5 0021
1E8CB 0021
1E955 0021
1EC75 0021
1ECA7 0021
+1ED05 0021
0035 003F
0665 003F
06F5 003F
@@ -46533,10 +48205,13 @@ ABF5 003F
1D364 003F
1D376 003F
1D378 003F
+1E145 003F
+1E2F5 003F
1E8CB 003F
1E955 003F
1EC75 003F
1ECA7 003F
+1ED05 003F
FF15 0021
FF15 003F
2478 0021
@@ -46626,15 +48301,21 @@ FF15 003F
1D364 0334
1D376 0334
1D378 0334
+1E145 0334
+1E2F5 0334
1E8CB 0334
1E955 0334
1EC75 0334
1ECA7 0334
+1ED05 0334
1D7D3 0334
1D7DD 0334
1D7E7 0334
1D7F1 0334
1D7FB 0334
+1ED32 0021
+1ED32 003F
+1ED32 0334
215A 0021
215A 003F
215A 0061
@@ -46754,10 +48435,13 @@ ABF5 0061
1D364 0061
1D376 0061
1D378 0061
+1E145 0061
+1E2F5 0061
1E8CB 0061
1E955 0061
1EC75 0061
1ECA7 0061
+1ED05 0061
0035 0041
0665 0041
06F5 0041
@@ -46851,10 +48535,13 @@ ABF5 0041
1D364 0041
1D376 0041
1D378 0041
+1E145 0041
+1E2F5 0041
1E8CB 0041
1E955 0041
1EC75 0041
1ECA7 0041
+1ED05 0041
FF15 0061
FF15 0041
2478 0061
@@ -46889,6 +48576,8 @@ FF15 0041
2075 0041
2085 0061
2085 0041
+1ED32 0061
+1ED32 0041
0035 0062
0665 0062
06F5 0062
@@ -46982,10 +48671,13 @@ ABF5 0062
1D364 0062
1D376 0062
1D378 0062
+1E145 0062
+1E2F5 0062
1E8CB 0062
1E955 0062
1EC75 0062
1ECA7 0062
+1ED05 0062
FF15 0062
2478 0062
1F106 0062
@@ -47003,6 +48695,7 @@ FF15 0062
278E 0062
2075 0062
2085 0062
+1ED32 0062
33E4 0021
33E4 003F
33E4 0061
@@ -47094,10 +48787,13 @@ ABF6 0021
16E86 0021
1D2E6 0021
1D365 0021
+1E146 0021
+1E2F6 0021
1E8CC 0021
1E956 0021
1EC76 0021
1ECA8 0021
+1ED06 0021
0036 003F
0666 003F
06F6 003F
@@ -47174,10 +48870,13 @@ ABF6 003F
16E86 003F
1D2E6 003F
1D365 003F
+1E146 003F
+1E2F6 003F
1E8CC 003F
1E956 003F
1EC76 003F
1ECA8 003F
+1ED06 003F
FF16 0021
FF16 003F
2479 0021
@@ -47249,15 +48948,21 @@ FF16 003F
16E86 0334
1D2E6 0334
1D365 0334
+1E146 0334
+1E2F6 0334
1E8CC 0334
1E956 0334
1EC76 0334
1ECA8 0334
+1ED06 0334
1D7D4 0334
1D7DE 0334
1D7E8 0334
1D7F2 0334
1D7FC 0334
+1ED33 0021
+1ED33 003F
+1ED33 0334
324D 0021
324D 003F
324D 0061
@@ -47345,10 +49050,13 @@ ABF6 0061
16E86 0061
1D2E6 0061
1D365 0061
+1E146 0061
+1E2F6 0061
1E8CC 0061
1E956 0061
1EC76 0061
1ECA8 0061
+1ED06 0061
0036 0041
0666 0041
06F6 0041
@@ -47425,10 +49133,13 @@ ABF6 0041
16E86 0041
1D2E6 0041
1D365 0041
+1E146 0041
+1E2F6 0041
1E8CC 0041
1E956 0041
1EC76 0041
1ECA8 0041
+1ED06 0041
FF16 0061
FF16 0041
2479 0061
@@ -47463,6 +49174,8 @@ FF16 0041
2076 0041
2086 0061
2086 0041
+1ED33 0061
+1ED33 0041
0036 0062
0666 0062
06F6 0062
@@ -47539,10 +49252,13 @@ ABF6 0062
16E86 0062
1D2E6 0062
1D365 0062
+1E146 0062
+1E2F6 0062
1E8CC 0062
1E956 0062
1EC76 0062
1ECA8 0062
+1ED06 0062
FF16 0062
2479 0062
1F107 0062
@@ -47560,6 +49276,7 @@ FF16 0062
278F 0062
2076 0062
2086 0062
+1ED33 0062
33E5 0021
33E5 003F
33E5 0061
@@ -47651,10 +49368,13 @@ ABF7 0021
16E87 0021
1D2E7 0021
1D366 0021
+1E147 0021
+1E2F7 0021
1E8CD 0021
1E957 0021
1EC77 0021
1ECA9 0021
+1ED07 0021
0037 003F
0667 003F
06F7 003F
@@ -47731,10 +49451,13 @@ ABF7 003F
16E87 003F
1D2E7 003F
1D366 003F
+1E147 003F
+1E2F7 003F
1E8CD 003F
1E957 003F
1EC77 003F
1ECA9 003F
+1ED07 003F
FF17 0021
FF17 003F
247A 0021
@@ -47807,15 +49530,21 @@ FF17 003F
16E87 0334
1D2E7 0334
1D366 0334
+1E147 0334
+1E2F7 0334
1E8CD 0334
1E957 0334
1EC77 0334
1ECA9 0334
+1ED07 0334
1D7D5 0334
1D7DF 0334
1D7E9 0334
1D7F3 0334
1D7FD 0334
+1ED34 0021
+1ED34 003F
+1ED34 0334
215E 0021
215E 003F
215E 0061
@@ -47908,10 +49637,13 @@ ABF7 0061
16E87 0061
1D2E7 0061
1D366 0061
+1E147 0061
+1E2F7 0061
1E8CD 0061
1E957 0061
1EC77 0061
1ECA9 0061
+1ED07 0061
0037 0041
0667 0041
06F7 0041
@@ -47988,10 +49720,13 @@ ABF7 0041
16E87 0041
1D2E7 0041
1D366 0041
+1E147 0041
+1E2F7 0041
1E8CD 0041
1E957 0041
1EC77 0041
1ECA9 0041
+1ED07 0041
FF17 0061
FF17 0041
247A 0061
@@ -48026,6 +49761,8 @@ FF17 0041
2077 0041
2087 0061
2087 0041
+1ED34 0061
+1ED34 0041
0037 0062
0667 0062
06F7 0062
@@ -48102,10 +49839,13 @@ ABF7 0062
16E87 0062
1D2E7 0062
1D366 0062
+1E147 0062
+1E2F7 0062
1E8CD 0062
1E957 0062
1EC77 0062
1ECA9 0062
+1ED07 0062
FF17 0062
247A 0062
1F108 0062
@@ -48123,6 +49863,7 @@ FF17 0062
2790 0062
2077 0062
2087 0062
+1ED34 0062
33E6 0021
33E6 003F
33E6 0061
@@ -48213,10 +49954,13 @@ ABF8 0021
16E88 0021
1D2E8 0021
1D367 0021
+1E148 0021
+1E2F8 0021
1E8CE 0021
1E958 0021
1EC78 0021
1ECAA 0021
+1ED08 0021
0038 003F
0668 003F
06F8 003F
@@ -48292,10 +50036,13 @@ ABF8 003F
16E88 003F
1D2E8 003F
1D367 003F
+1E148 003F
+1E2F8 003F
1E8CE 003F
1E958 003F
1EC78 003F
1ECAA 003F
+1ED08 003F
FF18 0021
FF18 003F
247B 0021
@@ -48367,15 +50114,21 @@ FF18 003F
16E88 0334
1D2E8 0334
1D367 0334
+1E148 0334
+1E2F8 0334
1E8CE 0334
1E958 0334
1EC78 0334
1ECAA 0334
+1ED08 0334
1D7D6 0334
1D7E0 0334
1D7EA 0334
1D7F4 0334
1D7FE 0334
+1ED35 0021
+1ED35 003F
+1ED35 0334
324F 0021
324F 003F
324F 0061
@@ -48456,10 +50209,13 @@ ABF8 0061
16E88 0061
1D2E8 0061
1D367 0061
+1E148 0061
+1E2F8 0061
1E8CE 0061
1E958 0061
1EC78 0061
1ECAA 0061
+1ED08 0061
0038 0041
0668 0041
06F8 0041
@@ -48535,10 +50291,13 @@ ABF8 0041
16E88 0041
1D2E8 0041
1D367 0041
+1E148 0041
+1E2F8 0041
1E8CE 0041
1E958 0041
1EC78 0041
1ECAA 0041
+1ED08 0041
FF18 0061
FF18 0041
247B 0061
@@ -48573,6 +50332,8 @@ FF18 0041
2078 0041
2088 0061
2088 0041
+1ED35 0061
+1ED35 0041
0038 0062
0668 0062
06F8 0062
@@ -48648,10 +50409,13 @@ ABF8 0062
16E88 0062
1D2E8 0062
1D367 0062
+1E148 0062
+1E2F8 0062
1E8CE 0062
1E958 0062
1EC78 0062
1ECAA 0062
+1ED08 0062
FF18 0062
247B 0062
1F109 0062
@@ -48669,6 +50433,7 @@ FF18 0062
2791 0062
2078 0062
2088 0062
+1ED35 0062
1F19F 0021
1F19F 003F
1F19F 0334
@@ -48767,10 +50532,13 @@ ABF9 0021
16E89 0021
1D2E9 0021
1D368 0021
+1E149 0021
+1E2F9 0021
1E8CF 0021
1E959 0021
1EC79 0021
1ECAB 0021
+1ED09 0021
0039 003F
0669 003F
06F9 003F
@@ -48848,10 +50616,13 @@ ABF9 003F
16E89 003F
1D2E9 003F
1D368 003F
+1E149 003F
+1E2F9 003F
1E8CF 003F
1E959 003F
1EC79 003F
1ECAB 003F
+1ED09 003F
FF19 0021
FF19 003F
247C 0021
@@ -48925,15 +50696,21 @@ FF19 003F
16E89 0334
1D2E9 0334
1D368 0334
+1E149 0334
+1E2F9 0334
1E8CF 0334
1E959 0334
1EC79 0334
1ECAB 0334
+1ED09 0334
1D7D7 0334
1D7E1 0334
1D7EB 0334
1D7F5 0334
1D7FF 0334
+1ED36 0021
+1ED36 003F
+1ED36 0334
0039 0061
0669 0061
06F9 0061
@@ -49011,10 +50788,13 @@ ABF9 0061
16E89 0061
1D2E9 0061
1D368 0061
+1E149 0061
+1E2F9 0061
1E8CF 0061
1E959 0061
1EC79 0061
1ECAB 0061
+1ED09 0061
0039 0041
0669 0041
06F9 0041
@@ -49092,10 +50872,13 @@ ABF9 0041
16E89 0041
1D2E9 0041
1D368 0041
+1E149 0041
+1E2F9 0041
1E8CF 0041
1E959 0041
1EC79 0041
1ECAB 0041
+1ED09 0041
FF19 0061
FF19 0041
247C 0061
@@ -49130,6 +50913,8 @@ FF19 0041
2079 0041
2089 0061
2089 0041
+1ED36 0061
+1ED36 0041
0039 0062
0669 0062
06F9 0062
@@ -49207,10 +50992,13 @@ ABF9 0062
16E89 0062
1D2E9 0062
1D368 0062
+1E149 0062
+1E2F9 0062
1E8CF 0062
1E959 0062
1EC79 0062
1ECAB 0062
+1ED09 0062
FF19 0062
247C 0062
1F10A 0062
@@ -49228,6 +51016,7 @@ FF19 0062
2792 0062
2079 0062
2089 0062
+1ED36 0062
33E8 0021
33E8 003F
33E8 0061
@@ -49318,6 +51107,7 @@ FF0C 0061
2E41 0061
2E4C 0061
2E4E 0061
+2E4F 0061
055D 0061
060C 0061
060D 0061
@@ -49336,6 +51126,7 @@ FE51 0061
FF64 0061
FE45 0061
FE46 0061
+16FE2 0061
003B 0061
037E 0061
FE14 0061
@@ -49884,6 +51675,7 @@ A8FC 0061
09FD 0061
0A76 0061
0AF0 0061
+0C77 0061
0C84 0061
0DF4 0061
0E4F 0061
@@ -49951,7 +51743,6 @@ AADF 0061
1AA6 0061
1AAC 0061
1AAD 0061
-166D 0061
1CC0 0061
1CC1 0061
1CC2 0061
@@ -50040,6 +51831,8 @@ AA5C 0061
115D7 0061
11643 0061
1183B 0061
+119E2 0061
+11FFF 0061
16B37 0061
16B38 0061
16B39 0061
@@ -50376,6 +52169,15 @@ FFFB 0061
11372 0061
11373 0061
11374 0061
+13430 0061
+13431 0061
+13432 0061
+13433 0061
+13434 0061
+13435 0061
+13436 0061
+13437 0061
+13438 0061
1BCA0 0061
1BCA1 0061
1BCA2 0061
@@ -51003,6 +52805,7 @@ FF0C 0041
2E41 0041
2E4C 0041
2E4E 0041
+2E4F 0041
055D 0041
060C 0041
060D 0041
@@ -51021,6 +52824,7 @@ FE51 0041
FF64 0041
FE45 0041
FE46 0041
+16FE2 0041
003B 0041
037E 0041
FE14 0041
@@ -51569,6 +53373,7 @@ A8FC 0041
09FD 0041
0A76 0041
0AF0 0041
+0C77 0041
0C84 0041
0DF4 0041
0E4F 0041
@@ -51636,7 +53441,6 @@ AADF 0041
1AA6 0041
1AAC 0041
1AAD 0041
-166D 0041
1CC0 0041
1CC1 0041
1CC2 0041
@@ -51725,6 +53529,8 @@ AA5C 0041
115D7 0041
11643 0041
1183B 0041
+119E2 0041
+11FFF 0041
16B37 0041
16B38 0041
16B39 0041
@@ -52061,6 +53867,15 @@ FFFB 0041
11372 0041
11373 0041
11374 0041
+13430 0041
+13431 0041
+13432 0041
+13433 0041
+13434 0041
+13435 0041
+13436 0041
+13437 0041
+13438 0041
1BCA0 0041
1BCA1 0041
1BCA2 0041
@@ -53879,6 +55694,7 @@ A981 0061
1163D 0061
116AB 0061
11837 0061
+119DE 0061
11A38 0061
11A96 0061
11C3D 0061
@@ -53922,6 +55738,7 @@ A981 0041
1163D 0041
116AB 0041
11837 0041
+119DE 0041
11A38 0041
11A96 0041
11C3D 0041
@@ -53958,6 +55775,7 @@ A983 0061
1163E 0061
116AC 0061
11838 0061
+119DF 0061
11A39 0061
11A97 0061
11C3E 0061
@@ -53993,6 +55811,7 @@ A983 0041
1163E 0041
116AC 0041
11838 0041
+119DF 0041
11A39 0041
11A97 0041
11C3E 0041
@@ -54099,19 +55918,41 @@ A92D 0041
193B 0061
193B 0041
16B30 0061
+1E131 0061
16B30 0041
+1E131 0041
16B31 0061
+1E136 0061
16B31 0041
+1E136 0041
16B32 0061
+1E132 0061
16B32 0041
+1E132 0041
16B33 0061
+1E133 0061
16B33 0041
+1E133 0041
16B34 0061
+1E130 0061
16B34 0041
+1E130 0041
16B35 0061
+1E134 0061
16B35 0041
+1E134 0041
16B36 0061
+1E135 0061
16B36 0041
+1E135 0041
+1E2EC 0061
+1E2EC 0041
+1E2ED 0061
+1E2ED 0041
+1E2EE 0061
+1E2EE 0041
+1E2EF 0061
+1E2EF 0041
302A 0061
302A 0041
302B 0061
@@ -54662,6 +56503,16 @@ A73C 0062
1D8F 0061
1D8F 0041
1D8F 0062
+A7BB 0021
+A7BB 003F
+A7BA 0021
+A7BA 003F
+A7BB 0061
+A7BB 0041
+A7BA 0061
+A7BA 0041
+A7BB 0062
+A7BA 0062
1D01 0021
1D01 003F
1D01 0061
@@ -54824,6 +56675,7 @@ FF0C 0062
2E41 0062
2E4C 0062
2E4E 0062
+2E4F 0062
055D 0062
060C 0062
060D 0062
@@ -54842,6 +56694,7 @@ FE51 0062
FF64 0062
FE45 0062
FE46 0062
+16FE2 0062
003B 0062
037E 0062
FE14 0062
@@ -55390,6 +57243,7 @@ A8FC 0062
09FD 0062
0A76 0062
0AF0 0062
+0C77 0062
0C84 0062
0DF4 0062
0E4F 0062
@@ -55457,7 +57311,6 @@ AADF 0062
1AA6 0062
1AAC 0062
1AAD 0062
-166D 0062
1CC0 0062
1CC1 0062
1CC2 0062
@@ -55546,6 +57399,8 @@ AA5C 0062
115D7 0062
11643 0062
1183B 0062
+119E2 0062
+11FFF 0062
16B37 0062
16B38 0062
16B39 0062
@@ -55882,6 +57737,15 @@ FFFB 0062
11372 0062
11373 0062
11374 0062
+13430 0062
+13431 0062
+13432 0062
+13433 0062
+13434 0062
+13435 0062
+13436 0062
+13437 0062
+13438 0062
1BCA0 0062
1BCA1 0062
1BCA2 0062
@@ -57001,6 +58865,7 @@ A981 0062
1163D 0062
116AB 0062
11837 0062
+119DE 0062
11A38 0062
11A96 0062
11C3D 0062
@@ -57037,6 +58902,7 @@ A983 0062
1163E 0062
116AC 0062
11838 0062
+119DF 0062
11A39 0062
11A97 0062
11C3E 0062
@@ -57093,12 +58959,23 @@ A92D 0062
193A 0062
193B 0062
16B30 0062
+1E131 0062
16B31 0062
+1E136 0062
16B32 0062
+1E132 0062
16B33 0062
+1E133 0062
16B34 0062
+1E130 0062
16B35 0062
+1E134 0062
16B36 0062
+1E135 0062
+1E2EC 0062
+1E2ED 0062
+1E2EE 0062
+1E2EF 0062
302A 0062
302B 0062
302C 0062
@@ -57794,9 +59671,14 @@ A793 0062
A792 0062
A794 0021
A794 003F
+A7C4 0021
+A7C4 003F
A794 0061
A794 0041
+A7C4 0061
+A7C4 0041
A794 0062
+A7C4 0062
0188 0021
0188 003F
0187 0021
@@ -58316,6 +60198,11 @@ A779 0062
01C6 0062
01C5 0062
01C4 0062
+AB66 0021
+AB66 003F
+AB66 0061
+AB66 0041
+AB66 0062
02A5 0021
02A5 003F
02A5 0061
@@ -61252,6 +63139,16 @@ A7F7 0062
1D96 0061
1D96 0041
1D96 0062
+A7BD 0021
+A7BD 003F
+A7BC 0021
+A7BC 003F
+A7BD 0061
+A7BD 0041
+A7BC 0061
+A7BC 0041
+A7BD 0062
+A7BC 0062
0269 0021
0269 003F
0196 0021
@@ -63122,6 +65019,12 @@ FF2D 0062
33AB 0061
33AB 0041
33AB 0062
+1F16C 0021
+1F16C 003F
+1F16C 0334
+1F16C 0061
+1F16C 0041
+1F16C 0062
33B3 0021
33B3 003F
33B3 0061
@@ -66745,13 +68648,18 @@ A731 0062
1D8A 0062
0282 0021
0282 003F
+A7C5 0021
+A7C5 003F
1DB3 0021
1DB3 003F
0282 0061
0282 0041
+A7C5 0061
+A7C5 0041
1DB3 0061
1DB3 0041
0282 0062
+A7C5 0062
1DB3 0062
023F 0021
023F 003F
@@ -67227,6 +69135,11 @@ A786 0062
02A6 0041
01BE 0062
02A6 0062
+AB67 0021
+AB67 003F
+AB67 0061
+AB67 0041
+AB67 0062
02A7 0021
02A7 003F
02A7 0061
@@ -68196,6 +70109,16 @@ AB5F 0061
AB5F 0041
AB52 0062
AB5F 0062
+A7BF 0021
+A7BF 003F
+A7BE 0021
+A7BE 003F
+A7BF 0061
+A7BF 0041
+A7BE 0061
+A7BE 0041
+A7BF 0062
+A7BE 0062
0265 0021
0265 003F
A78D 0021
@@ -69050,6 +70973,16 @@ FF37 0062
1D21 0061
1D21 0041
1D21 0062
+A7C3 0021
+A7C3 003F
+A7C2 0021
+A7C2 003F
+A7C3 0061
+A7C3 0041
+A7C2 0061
+A7C2 0041
+A7C3 0062
+A7C2 0062
2C73 0021
2C73 003F
2C72 0021
@@ -70180,9 +72113,14 @@ FF3A 0062
1D76 0062
1D8E 0021
1D8E 003F
+A7C6 0021
+A7C6 003F
1D8E 0061
1D8E 0041
+A7C6 0061
+A7C6 0041
1D8E 0062
+A7C6 0062
0225 0021
0225 003F
0224 0021
@@ -90450,6 +92388,7 @@ A8FE 0062
1CEF 0021
1CF0 0021
1CF1 0021
+1CFA 0021
1CEA 003F
1CEB 003F
1CEC 003F
@@ -90457,6 +92396,7 @@ A8FE 0062
1CEF 003F
1CF0 003F
1CF1 003F
+1CFA 003F
1CE9 0061
1CE9 0041
1CEA 0061
@@ -90466,6 +92406,7 @@ A8FE 0062
1CEF 0061
1CF0 0061
1CF1 0061
+1CFA 0061
1CEA 0041
1CEB 0041
1CEC 0041
@@ -90473,6 +92414,7 @@ A8FE 0062
1CEF 0041
1CF0 0041
1CF1 0041
+1CFA 0041
1CE9 0062
1CEA 0062
1CEB 0062
@@ -90481,6 +92423,7 @@ A8FE 0062
1CEF 0062
1CF0 0062
1CF1 0062
+1CFA 0062
1CF5 0021
1CF5 003F
1CF5 0061
@@ -97542,6 +99485,12 @@ A8C4 0062
11448 0061
11448 0041
11448 0062
+1145F 0021
+1145F 003F
+1145F 0334
+1145F 0061
+1145F 0041
+1145F 0062
11435 0021
11435 003F
11435 0334
@@ -98935,6 +100884,12 @@ A8C4 0062
1168B 0061
1168B 0041
1168B 0062
+116B8 0021
+116B8 003F
+116B8 0334
+116B8 0061
+116B8 0041
+116B8 0062
1168C 0021
1168C 003F
1168C 0334
@@ -99164,6 +101119,379 @@ A8C4 0062
116B6 0061
116B6 0041
116B6 0062
+119A0 0021
+119A0 003F
+119A0 0334
+119A0 0061
+119A0 0041
+119A0 0062
+119A1 0021
+119A1 003F
+119A1 0334
+119A1 0061
+119A1 0041
+119A1 0062
+119A2 0021
+119A2 003F
+119A2 0334
+119A2 0061
+119A2 0041
+119A2 0062
+119A3 0021
+119A3 003F
+119A3 0334
+119A3 0061
+119A3 0041
+119A3 0062
+119A4 0021
+119A4 003F
+119A4 0334
+119A4 0061
+119A4 0041
+119A4 0062
+119A5 0021
+119A5 003F
+119A5 0334
+119A5 0061
+119A5 0041
+119A5 0062
+119A6 0021
+119A6 003F
+119A6 0334
+119A6 0061
+119A6 0041
+119A6 0062
+119A7 0021
+119A7 003F
+119A7 0334
+119A7 0061
+119A7 0041
+119A7 0062
+119AA 0021
+119AA 003F
+119AA 0334
+119AA 0061
+119AA 0041
+119AA 0062
+119AB 0021
+119AB 003F
+119AB 0334
+119AB 0061
+119AB 0041
+119AB 0062
+119AC 0021
+119AC 003F
+119AC 0334
+119AC 0061
+119AC 0041
+119AC 0062
+119AD 0021
+119AD 003F
+119AD 0334
+119AD 0061
+119AD 0041
+119AD 0062
+119AE 0021
+119AE 003F
+119AE 0334
+119AE 0061
+119AE 0041
+119AE 0062
+119AF 0021
+119AF 003F
+119AF 0334
+119AF 0061
+119AF 0041
+119AF 0062
+119B0 0021
+119B0 003F
+119B0 0334
+119B0 0061
+119B0 0041
+119B0 0062
+119B1 0021
+119B1 003F
+119B1 0334
+119B1 0061
+119B1 0041
+119B1 0062
+119B2 0021
+119B2 003F
+119B2 0334
+119B2 0061
+119B2 0041
+119B2 0062
+119B3 0021
+119B3 003F
+119B3 0334
+119B3 0061
+119B3 0041
+119B3 0062
+119B4 0021
+119B4 003F
+119B4 0334
+119B4 0061
+119B4 0041
+119B4 0062
+119B5 0021
+119B5 003F
+119B5 0334
+119B5 0061
+119B5 0041
+119B5 0062
+119B6 0021
+119B6 003F
+119B6 0334
+119B6 0061
+119B6 0041
+119B6 0062
+119B7 0021
+119B7 003F
+119B7 0334
+119B7 0061
+119B7 0041
+119B7 0062
+119B8 0021
+119B8 003F
+119B8 0334
+119B8 0061
+119B8 0041
+119B8 0062
+119B9 0021
+119B9 003F
+119B9 0334
+119B9 0061
+119B9 0041
+119B9 0062
+119BA 0021
+119BA 003F
+119BA 0334
+119BA 0061
+119BA 0041
+119BA 0062
+119BB 0021
+119BB 003F
+119BB 0334
+119BB 0061
+119BB 0041
+119BB 0062
+119BC 0021
+119BC 003F
+119BC 0334
+119BC 0061
+119BC 0041
+119BC 0062
+119BD 0021
+119BD 003F
+119BD 0334
+119BD 0061
+119BD 0041
+119BD 0062
+119BE 0021
+119BE 003F
+119BE 0334
+119BE 0061
+119BE 0041
+119BE 0062
+119BF 0021
+119BF 003F
+119BF 0334
+119BF 0061
+119BF 0041
+119BF 0062
+119C0 0021
+119C0 003F
+119C0 0334
+119C0 0061
+119C0 0041
+119C0 0062
+119C1 0021
+119C1 003F
+119C1 0334
+119C1 0061
+119C1 0041
+119C1 0062
+119C2 0021
+119C2 003F
+119C2 0334
+119C2 0061
+119C2 0041
+119C2 0062
+119C3 0021
+119C3 003F
+119C3 0334
+119C3 0061
+119C3 0041
+119C3 0062
+119C4 0021
+119C4 003F
+119C4 0334
+119C4 0061
+119C4 0041
+119C4 0062
+119C5 0021
+119C5 003F
+119C5 0334
+119C5 0061
+119C5 0041
+119C5 0062
+119C6 0021
+119C6 003F
+119C6 0334
+119C6 0061
+119C6 0041
+119C6 0062
+119C7 0021
+119C7 003F
+119C7 0334
+119C7 0061
+119C7 0041
+119C7 0062
+119C8 0021
+119C8 003F
+119C8 0334
+119C8 0061
+119C8 0041
+119C8 0062
+119C9 0021
+119C9 003F
+119C9 0334
+119C9 0061
+119C9 0041
+119C9 0062
+119CA 0021
+119CA 003F
+119CA 0334
+119CA 0061
+119CA 0041
+119CA 0062
+119CB 0021
+119CB 003F
+119CB 0334
+119CB 0061
+119CB 0041
+119CB 0062
+119CC 0021
+119CC 003F
+119CC 0334
+119CC 0061
+119CC 0041
+119CC 0062
+119CD 0021
+119CD 003F
+119CD 0334
+119CD 0061
+119CD 0041
+119CD 0062
+119CE 0021
+119CE 003F
+119CE 0334
+119CE 0061
+119CE 0041
+119CE 0062
+119CF 0021
+119CF 003F
+119CF 0334
+119CF 0061
+119CF 0041
+119CF 0062
+119D0 0021
+119D0 003F
+119D0 0334
+119D0 0061
+119D0 0041
+119D0 0062
+119E1 0021
+119E1 003F
+119E1 0334
+119E1 0061
+119E1 0041
+119E1 0062
+119E3 0021
+119E3 003F
+119E3 0334
+119E3 0061
+119E3 0041
+119E3 0062
+119D1 0021
+119D1 003F
+119D1 0334
+119D1 0061
+119D1 0041
+119D1 0062
+119D2 0021
+119D2 003F
+119D2 0334
+119D2 0061
+119D2 0041
+119D2 0062
+119D3 0021
+119D3 003F
+119D3 0334
+119D3 0061
+119D3 0041
+119D3 0062
+119D4 0021
+119D4 003F
+119D4 0334
+119D4 0061
+119D4 0041
+119D4 0062
+119D5 0021
+119D5 003F
+119D5 0334
+119D5 0061
+119D5 0041
+119D5 0062
+119D6 0021
+119D6 003F
+119D6 0334
+119D6 0061
+119D6 0041
+119D6 0062
+119D7 0021
+119D7 003F
+119D7 0334
+119D7 0061
+119D7 0041
+119D7 0062
+119DA 0021
+119DA 003F
+119DA 0334
+119DA 0061
+119DA 0041
+119DA 0062
+119E4 0021
+119E4 003F
+119E4 0334
+119E4 0061
+119E4 0041
+119E4 0062
+119DB 0021
+119DB 003F
+119DB 0334
+119DB 0061
+119DB 0041
+119DB 0062
+119DC 0021
+119DC 003F
+119DC 0334
+119DC 0061
+119DC 0041
+119DC 0062
+119DD 0021
+119DD 003F
+119DD 0334
+119DD 0061
+119DD 0041
+119DD 0062
+119E0 0021
+119E0 003F
+0334 119E0
+119E0 0334
+119E0 0061
+119E0 0041
+119E0 0062
11800 0021
11800 003F
11800 0334
@@ -104024,6 +106352,36 @@ A8C4 0062
0EC4 0E84 0061
0EC4 0E84 0041
0EC4 0E84 0062
+0E86 0021
+0E86 003F
+0E86 0061
+0E86 0041
+0E86 0062
+0EC0 0E86 0021
+0EC0 0E86 003F
+0EC0 0E86 0061
+0EC0 0E86 0041
+0EC0 0E86 0062
+0EC1 0E86 0021
+0EC1 0E86 003F
+0EC1 0E86 0061
+0EC1 0E86 0041
+0EC1 0E86 0062
+0EC2 0E86 0021
+0EC2 0E86 003F
+0EC2 0E86 0061
+0EC2 0E86 0041
+0EC2 0E86 0062
+0EC3 0E86 0021
+0EC3 0E86 003F
+0EC3 0E86 0061
+0EC3 0E86 0041
+0EC3 0E86 0062
+0EC4 0E86 0021
+0EC4 0E86 003F
+0EC4 0E86 0061
+0EC4 0E86 0041
+0EC4 0E86 0062
0E87 0021
0E87 003F
0E87 0061
@@ -104084,6 +106442,36 @@ A8C4 0062
0EC4 0E88 0061
0EC4 0E88 0041
0EC4 0E88 0062
+0E89 0021
+0E89 003F
+0E89 0061
+0E89 0041
+0E89 0062
+0EC0 0E89 0021
+0EC0 0E89 003F
+0EC0 0E89 0061
+0EC0 0E89 0041
+0EC0 0E89 0062
+0EC1 0E89 0021
+0EC1 0E89 003F
+0EC1 0E89 0061
+0EC1 0E89 0041
+0EC1 0E89 0062
+0EC2 0E89 0021
+0EC2 0E89 003F
+0EC2 0E89 0061
+0EC2 0E89 0041
+0EC2 0E89 0062
+0EC3 0E89 0021
+0EC3 0E89 003F
+0EC3 0E89 0061
+0EC3 0E89 0041
+0EC3 0E89 0062
+0EC4 0E89 0021
+0EC4 0E89 003F
+0EC4 0E89 0061
+0EC4 0E89 0041
+0EC4 0E89 0062
0EAA 0021
0EAA 003F
0EAA 0061
@@ -104144,6 +106532,66 @@ A8C4 0062
0EC4 0E8A 0061
0EC4 0E8A 0041
0EC4 0E8A 0062
+0E8C 0021
+0E8C 003F
+0E8C 0061
+0E8C 0041
+0E8C 0062
+0EC0 0E8C 0021
+0EC0 0E8C 003F
+0EC0 0E8C 0061
+0EC0 0E8C 0041
+0EC0 0E8C 0062
+0EC1 0E8C 0021
+0EC1 0E8C 003F
+0EC1 0E8C 0061
+0EC1 0E8C 0041
+0EC1 0E8C 0062
+0EC2 0E8C 0021
+0EC2 0E8C 003F
+0EC2 0E8C 0061
+0EC2 0E8C 0041
+0EC2 0E8C 0062
+0EC3 0E8C 0021
+0EC3 0E8C 003F
+0EC3 0E8C 0061
+0EC3 0E8C 0041
+0EC3 0E8C 0062
+0EC4 0E8C 0021
+0EC4 0E8C 003F
+0EC4 0E8C 0061
+0EC4 0E8C 0041
+0EC4 0E8C 0062
+0E8E 0021
+0E8E 003F
+0E8E 0061
+0E8E 0041
+0E8E 0062
+0EC0 0E8E 0021
+0EC0 0E8E 003F
+0EC0 0E8E 0061
+0EC0 0E8E 0041
+0EC0 0E8E 0062
+0EC1 0E8E 0021
+0EC1 0E8E 003F
+0EC1 0E8E 0061
+0EC1 0E8E 0041
+0EC1 0E8E 0062
+0EC2 0E8E 0021
+0EC2 0E8E 003F
+0EC2 0E8E 0061
+0EC2 0E8E 0041
+0EC2 0E8E 0062
+0EC3 0E8E 0021
+0EC3 0E8E 003F
+0EC3 0E8E 0061
+0EC3 0E8E 0041
+0EC3 0E8E 0062
+0EC4 0E8E 0021
+0EC4 0E8E 003F
+0EC4 0E8E 0061
+0EC4 0E8E 0041
+0EC4 0E8E 0062
0EDF 0021
0EDF 003F
0EDF 0061
@@ -104204,6 +106652,156 @@ A8C4 0062
0EC4 0E8D 0061
0EC4 0E8D 0041
0EC4 0E8D 0062
+0E8F 0021
+0E8F 003F
+0E8F 0061
+0E8F 0041
+0E8F 0062
+0EC0 0E8F 0021
+0EC0 0E8F 003F
+0EC0 0E8F 0061
+0EC0 0E8F 0041
+0EC0 0E8F 0062
+0EC1 0E8F 0021
+0EC1 0E8F 003F
+0EC1 0E8F 0061
+0EC1 0E8F 0041
+0EC1 0E8F 0062
+0EC2 0E8F 0021
+0EC2 0E8F 003F
+0EC2 0E8F 0061
+0EC2 0E8F 0041
+0EC2 0E8F 0062
+0EC3 0E8F 0021
+0EC3 0E8F 003F
+0EC3 0E8F 0061
+0EC3 0E8F 0041
+0EC3 0E8F 0062
+0EC4 0E8F 0021
+0EC4 0E8F 003F
+0EC4 0E8F 0061
+0EC4 0E8F 0041
+0EC4 0E8F 0062
+0E90 0021
+0E90 003F
+0E90 0061
+0E90 0041
+0E90 0062
+0EC0 0E90 0021
+0EC0 0E90 003F
+0EC0 0E90 0061
+0EC0 0E90 0041
+0EC0 0E90 0062
+0EC1 0E90 0021
+0EC1 0E90 003F
+0EC1 0E90 0061
+0EC1 0E90 0041
+0EC1 0E90 0062
+0EC2 0E90 0021
+0EC2 0E90 003F
+0EC2 0E90 0061
+0EC2 0E90 0041
+0EC2 0E90 0062
+0EC3 0E90 0021
+0EC3 0E90 003F
+0EC3 0E90 0061
+0EC3 0E90 0041
+0EC3 0E90 0062
+0EC4 0E90 0021
+0EC4 0E90 003F
+0EC4 0E90 0061
+0EC4 0E90 0041
+0EC4 0E90 0062
+0E91 0021
+0E91 003F
+0E91 0061
+0E91 0041
+0E91 0062
+0EC0 0E91 0021
+0EC0 0E91 003F
+0EC0 0E91 0061
+0EC0 0E91 0041
+0EC0 0E91 0062
+0EC1 0E91 0021
+0EC1 0E91 003F
+0EC1 0E91 0061
+0EC1 0E91 0041
+0EC1 0E91 0062
+0EC2 0E91 0021
+0EC2 0E91 003F
+0EC2 0E91 0061
+0EC2 0E91 0041
+0EC2 0E91 0062
+0EC3 0E91 0021
+0EC3 0E91 003F
+0EC3 0E91 0061
+0EC3 0E91 0041
+0EC3 0E91 0062
+0EC4 0E91 0021
+0EC4 0E91 003F
+0EC4 0E91 0061
+0EC4 0E91 0041
+0EC4 0E91 0062
+0E92 0021
+0E92 003F
+0E92 0061
+0E92 0041
+0E92 0062
+0EC0 0E92 0021
+0EC0 0E92 003F
+0EC0 0E92 0061
+0EC0 0E92 0041
+0EC0 0E92 0062
+0EC1 0E92 0021
+0EC1 0E92 003F
+0EC1 0E92 0061
+0EC1 0E92 0041
+0EC1 0E92 0062
+0EC2 0E92 0021
+0EC2 0E92 003F
+0EC2 0E92 0061
+0EC2 0E92 0041
+0EC2 0E92 0062
+0EC3 0E92 0021
+0EC3 0E92 003F
+0EC3 0E92 0061
+0EC3 0E92 0041
+0EC3 0E92 0062
+0EC4 0E92 0021
+0EC4 0E92 003F
+0EC4 0E92 0061
+0EC4 0E92 0041
+0EC4 0E92 0062
+0E93 0021
+0E93 003F
+0E93 0061
+0E93 0041
+0E93 0062
+0EC0 0E93 0021
+0EC0 0E93 003F
+0EC0 0E93 0061
+0EC0 0E93 0041
+0EC0 0E93 0062
+0EC1 0E93 0021
+0EC1 0E93 003F
+0EC1 0E93 0061
+0EC1 0E93 0041
+0EC1 0E93 0062
+0EC2 0E93 0021
+0EC2 0E93 003F
+0EC2 0E93 0061
+0EC2 0E93 0041
+0EC2 0E93 0062
+0EC3 0E93 0021
+0EC3 0E93 003F
+0EC3 0E93 0061
+0EC3 0E93 0041
+0EC3 0E93 0062
+0EC4 0E93 0021
+0EC4 0E93 003F
+0EC4 0E93 0061
+0EC4 0E93 0041
+0EC4 0E93 0062
0E94 0021
0E94 003F
0E94 0061
@@ -104324,6 +106922,36 @@ A8C4 0062
0EC4 0E97 0061
0EC4 0E97 0041
0EC4 0E97 0062
+0E98 0021
+0E98 003F
+0E98 0061
+0E98 0041
+0E98 0062
+0EC0 0E98 0021
+0EC0 0E98 003F
+0EC0 0E98 0061
+0EC0 0E98 0041
+0EC0 0E98 0062
+0EC1 0E98 0021
+0EC1 0E98 003F
+0EC1 0E98 0061
+0EC1 0E98 0041
+0EC1 0E98 0062
+0EC2 0E98 0021
+0EC2 0E98 003F
+0EC2 0E98 0061
+0EC2 0E98 0041
+0EC2 0E98 0062
+0EC3 0E98 0021
+0EC3 0E98 003F
+0EC3 0E98 0061
+0EC3 0E98 0041
+0EC3 0E98 0062
+0EC4 0E98 0021
+0EC4 0E98 003F
+0EC4 0E98 0061
+0EC4 0E98 0041
+0EC4 0E98 0062
0E99 0021
0E99 003F
0E99 0061
@@ -104534,6 +107162,36 @@ A8C4 0062
0EC4 0E9F 0061
0EC4 0E9F 0041
0EC4 0E9F 0062
+0EA0 0021
+0EA0 003F
+0EA0 0061
+0EA0 0041
+0EA0 0062
+0EC0 0EA0 0021
+0EC0 0EA0 003F
+0EC0 0EA0 0061
+0EC0 0EA0 0041
+0EC0 0EA0 0062
+0EC1 0EA0 0021
+0EC1 0EA0 003F
+0EC1 0EA0 0061
+0EC1 0EA0 0041
+0EC1 0EA0 0062
+0EC2 0EA0 0021
+0EC2 0EA0 003F
+0EC2 0EA0 0061
+0EC2 0EA0 0041
+0EC2 0EA0 0062
+0EC3 0EA0 0021
+0EC3 0EA0 003F
+0EC3 0EA0 0061
+0EC3 0EA0 0041
+0EC3 0EA0 0062
+0EC4 0EA0 0021
+0EC4 0EA0 003F
+0EC4 0EA0 0061
+0EC4 0EA0 0041
+0EC4 0EA0 0062
0EA1 0021
0EA1 003F
0EA1 0061
@@ -104684,6 +107342,66 @@ A8C4 0062
0EC4 0EA7 0061
0EC4 0EA7 0041
0EC4 0EA7 0062
+0EA8 0021
+0EA8 003F
+0EA8 0061
+0EA8 0041
+0EA8 0062
+0EC0 0EA8 0021
+0EC0 0EA8 003F
+0EC0 0EA8 0061
+0EC0 0EA8 0041
+0EC0 0EA8 0062
+0EC1 0EA8 0021
+0EC1 0EA8 003F
+0EC1 0EA8 0061
+0EC1 0EA8 0041
+0EC1 0EA8 0062
+0EC2 0EA8 0021
+0EC2 0EA8 003F
+0EC2 0EA8 0061
+0EC2 0EA8 0041
+0EC2 0EA8 0062
+0EC3 0EA8 0021
+0EC3 0EA8 003F
+0EC3 0EA8 0061
+0EC3 0EA8 0041
+0EC3 0EA8 0062
+0EC4 0EA8 0021
+0EC4 0EA8 003F
+0EC4 0EA8 0061
+0EC4 0EA8 0041
+0EC4 0EA8 0062
+0EA9 0021
+0EA9 003F
+0EA9 0061
+0EA9 0041
+0EA9 0062
+0EC0 0EA9 0021
+0EC0 0EA9 003F
+0EC0 0EA9 0061
+0EC0 0EA9 0041
+0EC0 0EA9 0062
+0EC1 0EA9 0021
+0EC1 0EA9 003F
+0EC1 0EA9 0061
+0EC1 0EA9 0041
+0EC1 0EA9 0062
+0EC2 0EA9 0021
+0EC2 0EA9 003F
+0EC2 0EA9 0061
+0EC2 0EA9 0041
+0EC2 0EA9 0062
+0EC3 0EA9 0021
+0EC3 0EA9 003F
+0EC3 0EA9 0061
+0EC3 0EA9 0041
+0EC3 0EA9 0062
+0EC4 0EA9 0021
+0EC4 0EA9 003F
+0EC4 0EA9 0061
+0EC4 0EA9 0041
+0EC4 0EA9 0062
0EAB 0021
0EAB 003F
0EAB 0061
@@ -104774,6 +107492,36 @@ A8C4 0062
0EC4 0EAB 0061
0EC4 0EAB 0041
0EC4 0EAB 0062
+0EAC 0021
+0EAC 003F
+0EAC 0061
+0EAC 0041
+0EAC 0062
+0EC0 0EAC 0021
+0EC0 0EAC 003F
+0EC0 0EAC 0061
+0EC0 0EAC 0041
+0EC0 0EAC 0062
+0EC1 0EAC 0021
+0EC1 0EAC 003F
+0EC1 0EAC 0061
+0EC1 0EAC 0041
+0EC1 0EAC 0062
+0EC2 0EAC 0021
+0EC2 0EAC 003F
+0EC2 0EAC 0061
+0EC2 0EAC 0041
+0EC2 0EAC 0062
+0EC3 0EAC 0021
+0EC3 0EAC 003F
+0EC3 0EAC 0061
+0EC3 0EAC 0041
+0EC3 0EAC 0062
+0EC4 0EAC 0021
+0EC4 0EAC 003F
+0EC4 0EAC 0061
+0EC4 0EAC 0041
+0EC4 0EAC 0062
0EAD 0021
0EAD 003F
0EAD 0061
@@ -104901,6 +107649,13 @@ A8C4 0062
0EB9 0061
0EB9 0041
0EB9 0062
+0EBA 0021
+0EBA 003F
+0334 0EBA
+0EBA 0334
+0EBA 0061
+0EBA 0041
+0EBA 0062
0EBB 0021
0EBB 003F
0EBB 0061
@@ -104933,24 +107688,51 @@ A8C4 0062
0EC0 0001 0E84 0061
0EC0 0591 0E84 0061
0EC0 1D165 0E84 0061
+0EC0 0001 0E86 0061
+0EC0 0591 0E86 0061
+0EC0 1D165 0E86 0061
0EC0 0001 0E87 0061
0EC0 0591 0E87 0061
0EC0 1D165 0E87 0061
0EC0 0001 0E88 0061
0EC0 0591 0E88 0061
0EC0 1D165 0E88 0061
+0EC0 0001 0E89 0061
+0EC0 0591 0E89 0061
+0EC0 1D165 0E89 0061
0EC0 0001 0EAA 0061
0EC0 0591 0EAA 0061
0EC0 1D165 0EAA 0061
0EC0 0001 0E8A 0061
0EC0 0591 0E8A 0061
0EC0 1D165 0E8A 0061
+0EC0 0001 0E8C 0061
+0EC0 0591 0E8C 0061
+0EC0 1D165 0E8C 0061
+0EC0 0001 0E8E 0061
+0EC0 0591 0E8E 0061
+0EC0 1D165 0E8E 0061
0EC0 0001 0EDF 0061
0EC0 0591 0EDF 0061
0EC0 1D165 0EDF 0061
0EC0 0001 0E8D 0061
0EC0 0591 0E8D 0061
0EC0 1D165 0E8D 0061
+0EC0 0001 0E8F 0061
+0EC0 0591 0E8F 0061
+0EC0 1D165 0E8F 0061
+0EC0 0001 0E90 0061
+0EC0 0591 0E90 0061
+0EC0 1D165 0E90 0061
+0EC0 0001 0E91 0061
+0EC0 0591 0E91 0061
+0EC0 1D165 0E91 0061
+0EC0 0001 0E92 0061
+0EC0 0591 0E92 0061
+0EC0 1D165 0E92 0061
+0EC0 0001 0E93 0061
+0EC0 0591 0E93 0061
+0EC0 1D165 0E93 0061
0EC0 0001 0E94 0061
0EC0 0591 0E94 0061
0EC0 1D165 0E94 0061
@@ -104963,6 +107745,9 @@ A8C4 0062
0EC0 0001 0E97 0061
0EC0 0591 0E97 0061
0EC0 1D165 0E97 0061
+0EC0 0001 0E98 0061
+0EC0 0591 0E98 0061
+0EC0 1D165 0E98 0061
0EC0 0001 0E99 0061
0EC0 0591 0E99 0061
0EC0 1D165 0E99 0061
@@ -104984,6 +107769,9 @@ A8C4 0062
0EC0 0001 0E9F 0061
0EC0 0591 0E9F 0061
0EC0 1D165 0E9F 0061
+0EC0 0001 0EA0 0061
+0EC0 0591 0EA0 0061
+0EC0 1D165 0EA0 0061
0EC0 0001 0EA1 0061
0EC0 0591 0EA1 0061
0EC0 1D165 0EA1 0061
@@ -104999,6 +107787,12 @@ A8C4 0062
0EC0 0001 0EA7 0061
0EC0 0591 0EA7 0061
0EC0 1D165 0EA7 0061
+0EC0 0001 0EA8 0061
+0EC0 0591 0EA8 0061
+0EC0 1D165 0EA8 0061
+0EC0 0001 0EA9 0061
+0EC0 0591 0EA9 0061
+0EC0 1D165 0EA9 0061
0EC0 0001 0EAB 0061
0EC0 0591 0EAB 0061
0EC0 1D165 0EAB 0061
@@ -105008,6 +107802,9 @@ A8C4 0062
0EC0 0001 0EDD 0061
0EC0 0591 0EDD 0061
0EC0 1D165 0EDD 0061
+0EC0 0001 0EAC 0061
+0EC0 0591 0EAC 0061
+0EC0 1D165 0EAC 0061
0EC0 0001 0EAD 0061
0EC0 0591 0EAD 0061
0EC0 1D165 0EAD 0061
@@ -105031,24 +107828,51 @@ A8C4 0062
0EC1 0001 0E84 0061
0EC1 0591 0E84 0061
0EC1 1D165 0E84 0061
+0EC1 0001 0E86 0061
+0EC1 0591 0E86 0061
+0EC1 1D165 0E86 0061
0EC1 0001 0E87 0061
0EC1 0591 0E87 0061
0EC1 1D165 0E87 0061
0EC1 0001 0E88 0061
0EC1 0591 0E88 0061
0EC1 1D165 0E88 0061
+0EC1 0001 0E89 0061
+0EC1 0591 0E89 0061
+0EC1 1D165 0E89 0061
0EC1 0001 0EAA 0061
0EC1 0591 0EAA 0061
0EC1 1D165 0EAA 0061
0EC1 0001 0E8A 0061
0EC1 0591 0E8A 0061
0EC1 1D165 0E8A 0061
+0EC1 0001 0E8C 0061
+0EC1 0591 0E8C 0061
+0EC1 1D165 0E8C 0061
+0EC1 0001 0E8E 0061
+0EC1 0591 0E8E 0061
+0EC1 1D165 0E8E 0061
0EC1 0001 0EDF 0061
0EC1 0591 0EDF 0061
0EC1 1D165 0EDF 0061
0EC1 0001 0E8D 0061
0EC1 0591 0E8D 0061
0EC1 1D165 0E8D 0061
+0EC1 0001 0E8F 0061
+0EC1 0591 0E8F 0061
+0EC1 1D165 0E8F 0061
+0EC1 0001 0E90 0061
+0EC1 0591 0E90 0061
+0EC1 1D165 0E90 0061
+0EC1 0001 0E91 0061
+0EC1 0591 0E91 0061
+0EC1 1D165 0E91 0061
+0EC1 0001 0E92 0061
+0EC1 0591 0E92 0061
+0EC1 1D165 0E92 0061
+0EC1 0001 0E93 0061
+0EC1 0591 0E93 0061
+0EC1 1D165 0E93 0061
0EC1 0001 0E94 0061
0EC1 0591 0E94 0061
0EC1 1D165 0E94 0061
@@ -105061,6 +107885,9 @@ A8C4 0062
0EC1 0001 0E97 0061
0EC1 0591 0E97 0061
0EC1 1D165 0E97 0061
+0EC1 0001 0E98 0061
+0EC1 0591 0E98 0061
+0EC1 1D165 0E98 0061
0EC1 0001 0E99 0061
0EC1 0591 0E99 0061
0EC1 1D165 0E99 0061
@@ -105082,6 +107909,9 @@ A8C4 0062
0EC1 0001 0E9F 0061
0EC1 0591 0E9F 0061
0EC1 1D165 0E9F 0061
+0EC1 0001 0EA0 0061
+0EC1 0591 0EA0 0061
+0EC1 1D165 0EA0 0061
0EC1 0001 0EA1 0061
0EC1 0591 0EA1 0061
0EC1 1D165 0EA1 0061
@@ -105097,6 +107927,12 @@ A8C4 0062
0EC1 0001 0EA7 0061
0EC1 0591 0EA7 0061
0EC1 1D165 0EA7 0061
+0EC1 0001 0EA8 0061
+0EC1 0591 0EA8 0061
+0EC1 1D165 0EA8 0061
+0EC1 0001 0EA9 0061
+0EC1 0591 0EA9 0061
+0EC1 1D165 0EA9 0061
0EC1 0001 0EAB 0061
0EC1 0591 0EAB 0061
0EC1 1D165 0EAB 0061
@@ -105106,6 +107942,9 @@ A8C4 0062
0EC1 0001 0EDD 0061
0EC1 0591 0EDD 0061
0EC1 1D165 0EDD 0061
+0EC1 0001 0EAC 0061
+0EC1 0591 0EAC 0061
+0EC1 1D165 0EAC 0061
0EC1 0001 0EAD 0061
0EC1 0591 0EAD 0061
0EC1 1D165 0EAD 0061
@@ -105129,24 +107968,51 @@ A8C4 0062
0EC2 0001 0E84 0061
0EC2 0591 0E84 0061
0EC2 1D165 0E84 0061
+0EC2 0001 0E86 0061
+0EC2 0591 0E86 0061
+0EC2 1D165 0E86 0061
0EC2 0001 0E87 0061
0EC2 0591 0E87 0061
0EC2 1D165 0E87 0061
0EC2 0001 0E88 0061
0EC2 0591 0E88 0061
0EC2 1D165 0E88 0061
+0EC2 0001 0E89 0061
+0EC2 0591 0E89 0061
+0EC2 1D165 0E89 0061
0EC2 0001 0EAA 0061
0EC2 0591 0EAA 0061
0EC2 1D165 0EAA 0061
0EC2 0001 0E8A 0061
0EC2 0591 0E8A 0061
0EC2 1D165 0E8A 0061
+0EC2 0001 0E8C 0061
+0EC2 0591 0E8C 0061
+0EC2 1D165 0E8C 0061
+0EC2 0001 0E8E 0061
+0EC2 0591 0E8E 0061
+0EC2 1D165 0E8E 0061
0EC2 0001 0EDF 0061
0EC2 0591 0EDF 0061
0EC2 1D165 0EDF 0061
0EC2 0001 0E8D 0061
0EC2 0591 0E8D 0061
0EC2 1D165 0E8D 0061
+0EC2 0001 0E8F 0061
+0EC2 0591 0E8F 0061
+0EC2 1D165 0E8F 0061
+0EC2 0001 0E90 0061
+0EC2 0591 0E90 0061
+0EC2 1D165 0E90 0061
+0EC2 0001 0E91 0061
+0EC2 0591 0E91 0061
+0EC2 1D165 0E91 0061
+0EC2 0001 0E92 0061
+0EC2 0591 0E92 0061
+0EC2 1D165 0E92 0061
+0EC2 0001 0E93 0061
+0EC2 0591 0E93 0061
+0EC2 1D165 0E93 0061
0EC2 0001 0E94 0061
0EC2 0591 0E94 0061
0EC2 1D165 0E94 0061
@@ -105159,6 +108025,9 @@ A8C4 0062
0EC2 0001 0E97 0061
0EC2 0591 0E97 0061
0EC2 1D165 0E97 0061
+0EC2 0001 0E98 0061
+0EC2 0591 0E98 0061
+0EC2 1D165 0E98 0061
0EC2 0001 0E99 0061
0EC2 0591 0E99 0061
0EC2 1D165 0E99 0061
@@ -105180,6 +108049,9 @@ A8C4 0062
0EC2 0001 0E9F 0061
0EC2 0591 0E9F 0061
0EC2 1D165 0E9F 0061
+0EC2 0001 0EA0 0061
+0EC2 0591 0EA0 0061
+0EC2 1D165 0EA0 0061
0EC2 0001 0EA1 0061
0EC2 0591 0EA1 0061
0EC2 1D165 0EA1 0061
@@ -105195,6 +108067,12 @@ A8C4 0062
0EC2 0001 0EA7 0061
0EC2 0591 0EA7 0061
0EC2 1D165 0EA7 0061
+0EC2 0001 0EA8 0061
+0EC2 0591 0EA8 0061
+0EC2 1D165 0EA8 0061
+0EC2 0001 0EA9 0061
+0EC2 0591 0EA9 0061
+0EC2 1D165 0EA9 0061
0EC2 0001 0EAB 0061
0EC2 0591 0EAB 0061
0EC2 1D165 0EAB 0061
@@ -105204,6 +108082,9 @@ A8C4 0062
0EC2 0001 0EDD 0061
0EC2 0591 0EDD 0061
0EC2 1D165 0EDD 0061
+0EC2 0001 0EAC 0061
+0EC2 0591 0EAC 0061
+0EC2 1D165 0EAC 0061
0EC2 0001 0EAD 0061
0EC2 0591 0EAD 0061
0EC2 1D165 0EAD 0061
@@ -105227,24 +108108,51 @@ A8C4 0062
0EC3 0001 0E84 0061
0EC3 0591 0E84 0061
0EC3 1D165 0E84 0061
+0EC3 0001 0E86 0061
+0EC3 0591 0E86 0061
+0EC3 1D165 0E86 0061
0EC3 0001 0E87 0061
0EC3 0591 0E87 0061
0EC3 1D165 0E87 0061
0EC3 0001 0E88 0061
0EC3 0591 0E88 0061
0EC3 1D165 0E88 0061
+0EC3 0001 0E89 0061
+0EC3 0591 0E89 0061
+0EC3 1D165 0E89 0061
0EC3 0001 0EAA 0061
0EC3 0591 0EAA 0061
0EC3 1D165 0EAA 0061
0EC3 0001 0E8A 0061
0EC3 0591 0E8A 0061
0EC3 1D165 0E8A 0061
+0EC3 0001 0E8C 0061
+0EC3 0591 0E8C 0061
+0EC3 1D165 0E8C 0061
+0EC3 0001 0E8E 0061
+0EC3 0591 0E8E 0061
+0EC3 1D165 0E8E 0061
0EC3 0001 0EDF 0061
0EC3 0591 0EDF 0061
0EC3 1D165 0EDF 0061
0EC3 0001 0E8D 0061
0EC3 0591 0E8D 0061
0EC3 1D165 0E8D 0061
+0EC3 0001 0E8F 0061
+0EC3 0591 0E8F 0061
+0EC3 1D165 0E8F 0061
+0EC3 0001 0E90 0061
+0EC3 0591 0E90 0061
+0EC3 1D165 0E90 0061
+0EC3 0001 0E91 0061
+0EC3 0591 0E91 0061
+0EC3 1D165 0E91 0061
+0EC3 0001 0E92 0061
+0EC3 0591 0E92 0061
+0EC3 1D165 0E92 0061
+0EC3 0001 0E93 0061
+0EC3 0591 0E93 0061
+0EC3 1D165 0E93 0061
0EC3 0001 0E94 0061
0EC3 0591 0E94 0061
0EC3 1D165 0E94 0061
@@ -105257,6 +108165,9 @@ A8C4 0062
0EC3 0001 0E97 0061
0EC3 0591 0E97 0061
0EC3 1D165 0E97 0061
+0EC3 0001 0E98 0061
+0EC3 0591 0E98 0061
+0EC3 1D165 0E98 0061
0EC3 0001 0E99 0061
0EC3 0591 0E99 0061
0EC3 1D165 0E99 0061
@@ -105278,6 +108189,9 @@ A8C4 0062
0EC3 0001 0E9F 0061
0EC3 0591 0E9F 0061
0EC3 1D165 0E9F 0061
+0EC3 0001 0EA0 0061
+0EC3 0591 0EA0 0061
+0EC3 1D165 0EA0 0061
0EC3 0001 0EA1 0061
0EC3 0591 0EA1 0061
0EC3 1D165 0EA1 0061
@@ -105293,6 +108207,12 @@ A8C4 0062
0EC3 0001 0EA7 0061
0EC3 0591 0EA7 0061
0EC3 1D165 0EA7 0061
+0EC3 0001 0EA8 0061
+0EC3 0591 0EA8 0061
+0EC3 1D165 0EA8 0061
+0EC3 0001 0EA9 0061
+0EC3 0591 0EA9 0061
+0EC3 1D165 0EA9 0061
0EC3 0001 0EAB 0061
0EC3 0591 0EAB 0061
0EC3 1D165 0EAB 0061
@@ -105302,6 +108222,9 @@ A8C4 0062
0EC3 0001 0EDD 0061
0EC3 0591 0EDD 0061
0EC3 1D165 0EDD 0061
+0EC3 0001 0EAC 0061
+0EC3 0591 0EAC 0061
+0EC3 1D165 0EAC 0061
0EC3 0001 0EAD 0061
0EC3 0591 0EAD 0061
0EC3 1D165 0EAD 0061
@@ -105325,24 +108248,51 @@ A8C4 0062
0EC4 0001 0E84 0061
0EC4 0591 0E84 0061
0EC4 1D165 0E84 0061
+0EC4 0001 0E86 0061
+0EC4 0591 0E86 0061
+0EC4 1D165 0E86 0061
0EC4 0001 0E87 0061
0EC4 0591 0E87 0061
0EC4 1D165 0E87 0061
0EC4 0001 0E88 0061
0EC4 0591 0E88 0061
0EC4 1D165 0E88 0061
+0EC4 0001 0E89 0061
+0EC4 0591 0E89 0061
+0EC4 1D165 0E89 0061
0EC4 0001 0EAA 0061
0EC4 0591 0EAA 0061
0EC4 1D165 0EAA 0061
0EC4 0001 0E8A 0061
0EC4 0591 0E8A 0061
0EC4 1D165 0E8A 0061
+0EC4 0001 0E8C 0061
+0EC4 0591 0E8C 0061
+0EC4 1D165 0E8C 0061
+0EC4 0001 0E8E 0061
+0EC4 0591 0E8E 0061
+0EC4 1D165 0E8E 0061
0EC4 0001 0EDF 0061
0EC4 0591 0EDF 0061
0EC4 1D165 0EDF 0061
0EC4 0001 0E8D 0061
0EC4 0591 0E8D 0061
0EC4 1D165 0E8D 0061
+0EC4 0001 0E8F 0061
+0EC4 0591 0E8F 0061
+0EC4 1D165 0E8F 0061
+0EC4 0001 0E90 0061
+0EC4 0591 0E90 0061
+0EC4 1D165 0E90 0061
+0EC4 0001 0E91 0061
+0EC4 0591 0E91 0061
+0EC4 1D165 0E91 0061
+0EC4 0001 0E92 0061
+0EC4 0591 0E92 0061
+0EC4 1D165 0E92 0061
+0EC4 0001 0E93 0061
+0EC4 0591 0E93 0061
+0EC4 1D165 0E93 0061
0EC4 0001 0E94 0061
0EC4 0591 0E94 0061
0EC4 1D165 0E94 0061
@@ -105355,6 +108305,9 @@ A8C4 0062
0EC4 0001 0E97 0061
0EC4 0591 0E97 0061
0EC4 1D165 0E97 0061
+0EC4 0001 0E98 0061
+0EC4 0591 0E98 0061
+0EC4 1D165 0E98 0061
0EC4 0001 0E99 0061
0EC4 0591 0E99 0061
0EC4 1D165 0E99 0061
@@ -105376,6 +108329,9 @@ A8C4 0062
0EC4 0001 0E9F 0061
0EC4 0591 0E9F 0061
0EC4 1D165 0E9F 0061
+0EC4 0001 0EA0 0061
+0EC4 0591 0EA0 0061
+0EC4 1D165 0EA0 0061
0EC4 0001 0EA1 0061
0EC4 0591 0EA1 0061
0EC4 1D165 0EA1 0061
@@ -105391,6 +108347,12 @@ A8C4 0062
0EC4 0001 0EA7 0061
0EC4 0591 0EA7 0061
0EC4 1D165 0EA7 0061
+0EC4 0001 0EA8 0061
+0EC4 0591 0EA8 0061
+0EC4 1D165 0EA8 0061
+0EC4 0001 0EA9 0061
+0EC4 0591 0EA9 0061
+0EC4 1D165 0EA9 0061
0EC4 0001 0EAB 0061
0EC4 0591 0EAB 0061
0EC4 1D165 0EAB 0061
@@ -105400,6 +108362,9 @@ A8C4 0062
0EC4 0001 0EDD 0061
0EC4 0591 0EDD 0061
0EC4 1D165 0EDD 0061
+0EC4 0001 0EAC 0061
+0EC4 0591 0EAC 0061
+0EC4 1D165 0EAC 0061
0EC4 0001 0EAD 0061
0EC4 0591 0EAD 0061
0EC4 1D165 0EAD 0061
@@ -109228,6 +112193,18 @@ AADC 0062
11A82 0061
11A82 0041
11A82 0062
+11A84 0021
+11A84 003F
+11A84 0334
+11A84 0061
+11A84 0041
+11A84 0062
+11A85 0021
+11A85 003F
+11A85 0334
+11A85 0061
+11A85 0041
+11A85 0062
11A99 0021
11A99 003F
0334 11A99
@@ -131656,6 +134633,12 @@ A6EF 0062
1E921 0041
1E943 0062
1E921 0062
+1E94B 0021
+1E94B 003F
+1E94B 0334
+1E94B 0061
+1E94B 0041
+1E94B 0062
1100 0021
1100 003F
3200 0021
@@ -136644,54 +139627,82 @@ FF9C 0062
3357 0061
3357 0041
3357 0062
+1B150 0021
+1B150 003F
3090 0021
3090 003F
+1B164 0021
+1B164 003F
30F0 0021
30F0 003F
32FC 0021
32FC 003F
30F8 0021
30F8 003F
+1B150 0334
+1B164 0334
30F0 0334 3099
30F0 3099 0334
30F8 0334
+1B150 0061
+1B150 0041
3090 0061
3090 0041
+1B164 0061
+1B164 0041
30F0 0061
30F0 0041
32FC 0061
32FC 0041
30F8 0061
30F8 0041
+1B150 0062
3090 0062
+1B164 0062
30F0 0062
32FC 0062
30F8 0062
+1B151 0021
+1B151 003F
3091 0021
3091 003F
+1B165 0021
+1B165 003F
30F1 0021
30F1 003F
32FD 0021
32FD 003F
30F9 0021
30F9 003F
+1B151 0334
+1B165 0334
30F1 0334 3099
30F1 3099 0334
30F9 0334
+1B151 0061
+1B151 0041
3091 0061
3091 0041
+1B165 0061
+1B165 0041
30F1 0061
30F1 0041
32FD 0061
32FD 0041
30F9 0061
30F9 0041
+1B151 0062
3091 0062
+1B165 0062
30F1 0062
32FD 0062
30F9 0062
+1B152 0021
+1B152 003F
3092 0021
3092 003F
+1B166 0021
+1B166 003F
30F2 0021
30F2 003F
FF66 0021
@@ -136700,11 +139711,17 @@ FF66 003F
32FE 003F
30FA 0021
30FA 003F
+1B152 0334
+1B166 0334
30F2 0334 3099
30F2 3099 0334
30FA 0334
+1B152 0061
+1B152 0041
3092 0061
3092 0041
+1B166 0061
+1B166 0041
30F2 0061
30F2 0041
FF66 0061
@@ -136713,24 +139730,32 @@ FF66 0041
32FE 0041
30FA 0061
30FA 0041
+1B152 0062
3092 0062
+1B166 0062
30F2 0062
FF66 0062
32FE 0062
30FA 0062
3093 0021
3093 003F
+1B167 0021
+1B167 003F
30F3 0021
30F3 003F
FF9D 0021
FF9D 003F
+1B167 0334
3093 0061
3093 0041
+1B167 0061
+1B167 0041
30F3 0061
30F3 0041
FF9D 0061
FF9D 0041
3093 0062
+1B167 0062
30F3 0062
FF9D 0062
1B002 0021
@@ -144878,6 +147903,12 @@ A4F7 0062
16F03 0061
16F03 0041
16F03 0062
+16F45 0021
+16F45 003F
+16F45 0334
+16F45 0061
+16F45 0041
+16F45 0062
16F04 0021
16F04 003F
16F06 0021
@@ -144938,6 +147969,12 @@ A4F7 0062
16F0D 0061
16F0D 0041
16F0D 0062
+16F48 0021
+16F48 003F
+16F48 0334
+16F48 0061
+16F48 0041
+16F48 0062
16F0E 0021
16F0E 003F
16F0E 0334
@@ -144950,6 +147987,12 @@ A4F7 0062
16F0F 0061
16F0F 0041
16F0F 0062
+16F4A 0021
+16F4A 003F
+16F4A 0334
+16F4A 0061
+16F4A 0041
+16F4A 0062
16F10 0021
16F10 003F
16F13 0021
@@ -145160,12 +148203,24 @@ A4F7 0062
16F32 0061
16F32 0041
16F32 0062
+16F47 0021
+16F47 003F
+16F47 0334
+16F47 0061
+16F47 0041
+16F47 0062
16F33 0021
16F33 003F
16F33 0334
16F33 0061
16F33 0041
16F33 0062
+16F46 0021
+16F46 003F
+16F46 0334
+16F46 0061
+16F46 0041
+16F46 0062
16F34 0021
16F34 003F
16F34 0334
@@ -145202,6 +148257,12 @@ A4F7 0062
16F39 0061
16F39 0041
16F39 0062
+16F49 0021
+16F49 003F
+16F49 0334
+16F49 0061
+16F49 0041
+16F49 0062
16F3A 0021
16F3A 003F
16F3A 0334
@@ -145292,6 +148353,12 @@ A4F7 0062
16F53 0061
16F53 0041
16F53 0062
+16F4F 0021
+16F4F 003F
+16F4F 0334
+16F4F 0061
+16F4F 0041
+16F4F 0062
16F54 0021
16F54 003F
16F54 0334
@@ -145322,6 +148389,12 @@ A4F7 0062
16F58 0061
16F58 0041
16F58 0062
+16F81 0021
+16F81 003F
+16F81 0334
+16F81 0061
+16F81 0041
+16F81 0062
16F59 0021
16F59 003F
16F59 0334
@@ -145346,6 +148419,12 @@ A4F7 0062
16F5C 0061
16F5C 0041
16F5C 0062
+16F83 0021
+16F83 003F
+16F83 0334
+16F83 0061
+16F83 0041
+16F83 0062
16F5D 0021
16F5D 003F
16F5D 0334
@@ -145370,6 +148449,12 @@ A4F7 0062
16F60 0061
16F60 0041
16F60 0062
+16F84 0021
+16F84 003F
+16F84 0334
+16F84 0061
+16F84 0041
+16F84 0062
16F61 0021
16F61 003F
16F61 0334
@@ -145400,6 +148485,12 @@ A4F7 0062
16F65 0061
16F65 0041
16F65 0062
+16F86 0021
+16F86 003F
+16F86 0334
+16F86 0061
+16F86 0041
+16F86 0062
16F66 0021
16F66 003F
16F66 0334
@@ -145448,6 +148539,18 @@ A4F7 0062
16F6D 0061
16F6D 0041
16F6D 0062
+16F7F 0021
+16F7F 003F
+16F7F 0334
+16F7F 0061
+16F7F 0041
+16F7F 0062
+16F87 0021
+16F87 003F
+16F87 0334
+16F87 0061
+16F87 0041
+16F87 0062
16F6E 0021
16F6E 003F
16F6E 0334
@@ -145478,6 +148581,12 @@ A4F7 0062
16F72 0061
16F72 0041
16F72 0062
+16F80 0021
+16F80 003F
+16F80 0334
+16F80 0061
+16F80 0041
+16F80 0062
16F73 0021
16F73 003F
16F73 0334
@@ -145490,6 +148599,18 @@ A4F7 0062
16F74 0061
16F74 0041
16F74 0062
+16F85 0021
+16F85 003F
+16F85 0334
+16F85 0061
+16F85 0041
+16F85 0062
+16F82 0021
+16F82 003F
+16F82 0334
+16F82 0061
+16F82 0041
+16F82 0062
16F75 0021
16F75 003F
16F75 0334
@@ -146924,6 +150045,576 @@ A4F7 0062
16B8F 0061
16B8F 0041
16B8F 0062
+1E100 0021
+1E100 003F
+1E100 0334
+1E100 0061
+1E100 0041
+1E100 0062
+1E101 0021
+1E101 003F
+1E101 0334
+1E101 0061
+1E101 0041
+1E101 0062
+1E102 0021
+1E102 003F
+1E102 0334
+1E102 0061
+1E102 0041
+1E102 0062
+1E103 0021
+1E103 003F
+1E103 0334
+1E103 0061
+1E103 0041
+1E103 0062
+1E104 0021
+1E104 003F
+1E104 0334
+1E104 0061
+1E104 0041
+1E104 0062
+1E105 0021
+1E105 003F
+1E105 0334
+1E105 0061
+1E105 0041
+1E105 0062
+1E106 0021
+1E106 003F
+1E106 0334
+1E106 0061
+1E106 0041
+1E106 0062
+1E107 0021
+1E107 003F
+1E107 0334
+1E107 0061
+1E107 0041
+1E107 0062
+1E108 0021
+1E108 003F
+1E108 0334
+1E108 0061
+1E108 0041
+1E108 0062
+1E109 0021
+1E109 003F
+1E109 0334
+1E109 0061
+1E109 0041
+1E109 0062
+1E10A 0021
+1E10A 003F
+1E10A 0334
+1E10A 0061
+1E10A 0041
+1E10A 0062
+1E10B 0021
+1E10B 003F
+1E10B 0334
+1E10B 0061
+1E10B 0041
+1E10B 0062
+1E10C 0021
+1E10C 003F
+1E10C 0334
+1E10C 0061
+1E10C 0041
+1E10C 0062
+1E10D 0021
+1E10D 003F
+1E10D 0334
+1E10D 0061
+1E10D 0041
+1E10D 0062
+1E10E 0021
+1E10E 003F
+1E10E 0334
+1E10E 0061
+1E10E 0041
+1E10E 0062
+1E10F 0021
+1E10F 003F
+1E10F 0334
+1E10F 0061
+1E10F 0041
+1E10F 0062
+1E110 0021
+1E110 003F
+1E110 0334
+1E110 0061
+1E110 0041
+1E110 0062
+1E111 0021
+1E111 003F
+1E111 0334
+1E111 0061
+1E111 0041
+1E111 0062
+1E112 0021
+1E112 003F
+1E112 0334
+1E112 0061
+1E112 0041
+1E112 0062
+1E113 0021
+1E113 003F
+1E113 0334
+1E113 0061
+1E113 0041
+1E113 0062
+1E114 0021
+1E114 003F
+1E114 0334
+1E114 0061
+1E114 0041
+1E114 0062
+1E115 0021
+1E115 003F
+1E115 0334
+1E115 0061
+1E115 0041
+1E115 0062
+1E116 0021
+1E116 003F
+1E116 0334
+1E116 0061
+1E116 0041
+1E116 0062
+1E117 0021
+1E117 003F
+1E117 0334
+1E117 0061
+1E117 0041
+1E117 0062
+1E118 0021
+1E118 003F
+1E118 0334
+1E118 0061
+1E118 0041
+1E118 0062
+1E119 0021
+1E119 003F
+1E119 0334
+1E119 0061
+1E119 0041
+1E119 0062
+1E11A 0021
+1E11A 003F
+1E11A 0334
+1E11A 0061
+1E11A 0041
+1E11A 0062
+1E11B 0021
+1E11B 003F
+1E11B 0334
+1E11B 0061
+1E11B 0041
+1E11B 0062
+1E11C 0021
+1E11C 003F
+1E11C 0334
+1E11C 0061
+1E11C 0041
+1E11C 0062
+1E11D 0021
+1E11D 003F
+1E11D 0334
+1E11D 0061
+1E11D 0041
+1E11D 0062
+1E11E 0021
+1E11E 003F
+1E11E 0334
+1E11E 0061
+1E11E 0041
+1E11E 0062
+1E11F 0021
+1E11F 003F
+1E11F 0334
+1E11F 0061
+1E11F 0041
+1E11F 0062
+1E120 0021
+1E120 003F
+1E120 0334
+1E120 0061
+1E120 0041
+1E120 0062
+1E121 0021
+1E121 003F
+1E121 0334
+1E121 0061
+1E121 0041
+1E121 0062
+1E122 0021
+1E122 003F
+1E122 0334
+1E122 0061
+1E122 0041
+1E122 0062
+1E123 0021
+1E123 003F
+1E123 0334
+1E123 0061
+1E123 0041
+1E123 0062
+1E124 0021
+1E124 003F
+1E124 0334
+1E124 0061
+1E124 0041
+1E124 0062
+1E125 0021
+1E125 003F
+1E125 0334
+1E125 0061
+1E125 0041
+1E125 0062
+1E126 0021
+1E126 003F
+1E126 0334
+1E126 0061
+1E126 0041
+1E126 0062
+1E127 0021
+1E127 003F
+1E127 0334
+1E127 0061
+1E127 0041
+1E127 0062
+1E128 0021
+1E128 003F
+1E128 0334
+1E128 0061
+1E128 0041
+1E128 0062
+1E129 0021
+1E129 003F
+1E129 0334
+1E129 0061
+1E129 0041
+1E129 0062
+1E12A 0021
+1E12A 003F
+1E12A 0334
+1E12A 0061
+1E12A 0041
+1E12A 0062
+1E12B 0021
+1E12B 003F
+1E12B 0334
+1E12B 0061
+1E12B 0041
+1E12B 0062
+1E12C 0021
+1E12C 003F
+1E12C 0334
+1E12C 0061
+1E12C 0041
+1E12C 0062
+1E137 0021
+1E137 003F
+1E137 0334
+1E137 0061
+1E137 0041
+1E137 0062
+1E138 0021
+1E138 003F
+1E138 0334
+1E138 0061
+1E138 0041
+1E138 0062
+1E139 0021
+1E139 003F
+1E139 0334
+1E139 0061
+1E139 0041
+1E139 0062
+1E13A 0021
+1E13A 003F
+1E13A 0334
+1E13A 0061
+1E13A 0041
+1E13A 0062
+1E13B 0021
+1E13B 003F
+1E13B 0334
+1E13B 0061
+1E13B 0041
+1E13B 0062
+1E14E 0021
+1E14E 003F
+1E14E 0334
+1E14E 0061
+1E14E 0041
+1E14E 0062
+1E2C0 0021
+1E2C0 003F
+1E2C0 0334
+1E2C0 0061
+1E2C0 0041
+1E2C0 0062
+1E2C1 0021
+1E2C1 003F
+1E2C1 0334
+1E2C1 0061
+1E2C1 0041
+1E2C1 0062
+1E2C2 0021
+1E2C2 003F
+1E2C2 0334
+1E2C2 0061
+1E2C2 0041
+1E2C2 0062
+1E2C3 0021
+1E2C3 003F
+1E2C3 0334
+1E2C3 0061
+1E2C3 0041
+1E2C3 0062
+1E2C4 0021
+1E2C4 003F
+1E2C4 0334
+1E2C4 0061
+1E2C4 0041
+1E2C4 0062
+1E2C5 0021
+1E2C5 003F
+1E2C5 0334
+1E2C5 0061
+1E2C5 0041
+1E2C5 0062
+1E2C6 0021
+1E2C6 003F
+1E2C6 0334
+1E2C6 0061
+1E2C6 0041
+1E2C6 0062
+1E2C7 0021
+1E2C7 003F
+1E2C7 0334
+1E2C7 0061
+1E2C7 0041
+1E2C7 0062
+1E2C8 0021
+1E2C8 003F
+1E2C8 0334
+1E2C8 0061
+1E2C8 0041
+1E2C8 0062
+1E2C9 0021
+1E2C9 003F
+1E2C9 0334
+1E2C9 0061
+1E2C9 0041
+1E2C9 0062
+1E2CA 0021
+1E2CA 003F
+1E2CA 0334
+1E2CA 0061
+1E2CA 0041
+1E2CA 0062
+1E2CB 0021
+1E2CB 003F
+1E2CB 0334
+1E2CB 0061
+1E2CB 0041
+1E2CB 0062
+1E2CC 0021
+1E2CC 003F
+1E2CC 0334
+1E2CC 0061
+1E2CC 0041
+1E2CC 0062
+1E2CD 0021
+1E2CD 003F
+1E2CD 0334
+1E2CD 0061
+1E2CD 0041
+1E2CD 0062
+1E2CE 0021
+1E2CE 003F
+1E2CE 0334
+1E2CE 0061
+1E2CE 0041
+1E2CE 0062
+1E2CF 0021
+1E2CF 003F
+1E2CF 0334
+1E2CF 0061
+1E2CF 0041
+1E2CF 0062
+1E2D0 0021
+1E2D0 003F
+1E2D0 0334
+1E2D0 0061
+1E2D0 0041
+1E2D0 0062
+1E2D1 0021
+1E2D1 003F
+1E2D1 0334
+1E2D1 0061
+1E2D1 0041
+1E2D1 0062
+1E2D2 0021
+1E2D2 003F
+1E2D2 0334
+1E2D2 0061
+1E2D2 0041
+1E2D2 0062
+1E2D3 0021
+1E2D3 003F
+1E2D3 0334
+1E2D3 0061
+1E2D3 0041
+1E2D3 0062
+1E2D4 0021
+1E2D4 003F
+1E2D4 0334
+1E2D4 0061
+1E2D4 0041
+1E2D4 0062
+1E2D5 0021
+1E2D5 003F
+1E2D5 0334
+1E2D5 0061
+1E2D5 0041
+1E2D5 0062
+1E2D6 0021
+1E2D6 003F
+1E2D6 0334
+1E2D6 0061
+1E2D6 0041
+1E2D6 0062
+1E2D7 0021
+1E2D7 003F
+1E2D7 0334
+1E2D7 0061
+1E2D7 0041
+1E2D7 0062
+1E2D8 0021
+1E2D8 003F
+1E2D8 0334
+1E2D8 0061
+1E2D8 0041
+1E2D8 0062
+1E2D9 0021
+1E2D9 003F
+1E2D9 0334
+1E2D9 0061
+1E2D9 0041
+1E2D9 0062
+1E2DA 0021
+1E2DA 003F
+1E2DA 0334
+1E2DA 0061
+1E2DA 0041
+1E2DA 0062
+1E2DB 0021
+1E2DB 003F
+1E2DB 0334
+1E2DB 0061
+1E2DB 0041
+1E2DB 0062
+1E2DC 0021
+1E2DC 003F
+1E2DC 0334
+1E2DC 0061
+1E2DC 0041
+1E2DC 0062
+1E2DD 0021
+1E2DD 003F
+1E2DD 0334
+1E2DD 0061
+1E2DD 0041
+1E2DD 0062
+1E2DE 0021
+1E2DE 003F
+1E2DE 0334
+1E2DE 0061
+1E2DE 0041
+1E2DE 0062
+1E2DF 0021
+1E2DF 003F
+1E2DF 0334
+1E2DF 0061
+1E2DF 0041
+1E2DF 0062
+1E2E0 0021
+1E2E0 003F
+1E2E0 0334
+1E2E0 0061
+1E2E0 0041
+1E2E0 0062
+1E2E1 0021
+1E2E1 003F
+1E2E1 0334
+1E2E1 0061
+1E2E1 0041
+1E2E1 0062
+1E2E2 0021
+1E2E2 003F
+1E2E2 0334
+1E2E2 0061
+1E2E2 0041
+1E2E2 0062
+1E2E3 0021
+1E2E3 003F
+1E2E3 0334
+1E2E3 0061
+1E2E3 0041
+1E2E3 0062
+1E2E4 0021
+1E2E4 003F
+1E2E4 0334
+1E2E4 0061
+1E2E4 0041
+1E2E4 0062
+1E2E5 0021
+1E2E5 003F
+1E2E5 0334
+1E2E5 0061
+1E2E5 0041
+1E2E5 0062
+1E2E6 0021
+1E2E6 003F
+1E2E6 0334
+1E2E6 0061
+1E2E6 0041
+1E2E6 0062
+1E2E7 0021
+1E2E7 003F
+1E2E7 0334
+1E2E7 0061
+1E2E7 0041
+1E2E7 0062
+1E2E8 0021
+1E2E8 003F
+1E2E8 0334
+1E2E8 0061
+1E2E8 0041
+1E2E8 0062
+1E2E9 0021
+1E2E9 003F
+1E2E9 0334
+1E2E9 0061
+1E2E9 0041
+1E2E9 0062
+1E2EA 0021
+1E2EA 003F
+1E2EA 0334
+1E2EA 0061
+1E2EA 0041
+1E2EA 0062
+1E2EB 0021
+1E2EB 003F
+1E2EB 0334
+1E2EB 0061
+1E2EB 0041
+1E2EB 0062
10280 0021
10280 003F
10280 0334
@@ -155840,6 +159531,144 @@ A4F7 0062
10B91 0061
10B91 0041
10B91 0062
+10FE0 0021
+10FE0 003F
+10FE0 0334
+10FE0 0061
+10FE0 0041
+10FE0 0062
+10FE1 0021
+10FE1 003F
+10FE1 0334
+10FE1 0061
+10FE1 0041
+10FE1 0062
+10FE2 0021
+10FE2 003F
+10FE2 0334
+10FE2 0061
+10FE2 0041
+10FE2 0062
+10FE3 0021
+10FE3 003F
+10FE3 0334
+10FE3 0061
+10FE3 0041
+10FE3 0062
+10FE4 0021
+10FE4 003F
+10FE4 0334
+10FE4 0061
+10FE4 0041
+10FE4 0062
+10FE5 0021
+10FE5 003F
+10FE5 0334
+10FE5 0061
+10FE5 0041
+10FE5 0062
+10FE6 0021
+10FE6 003F
+10FE6 0334
+10FE6 0061
+10FE6 0041
+10FE6 0062
+10FF6 0021
+10FF6 003F
+10FF6 0334
+10FF6 0061
+10FF6 0041
+10FF6 0062
+10FE7 0021
+10FE7 003F
+10FE7 0334
+10FE7 0061
+10FE7 0041
+10FE7 0062
+10FE8 0021
+10FE8 003F
+10FE8 0334
+10FE8 0061
+10FE8 0041
+10FE8 0062
+10FE9 0021
+10FE9 003F
+10FE9 0334
+10FE9 0061
+10FE9 0041
+10FE9 0062
+10FEA 0021
+10FEA 003F
+10FEA 0334
+10FEA 0061
+10FEA 0041
+10FEA 0062
+10FEB 0021
+10FEB 003F
+10FEB 0334
+10FEB 0061
+10FEB 0041
+10FEB 0062
+10FEC 0021
+10FEC 003F
+10FEC 0334
+10FEC 0061
+10FEC 0041
+10FEC 0062
+10FED 0021
+10FED 003F
+10FED 0334
+10FED 0061
+10FED 0041
+10FED 0062
+10FEE 0021
+10FEE 003F
+10FEE 0334
+10FEE 0061
+10FEE 0041
+10FEE 0062
+10FEF 0021
+10FEF 003F
+10FEF 0334
+10FEF 0061
+10FEF 0041
+10FEF 0062
+10FF0 0021
+10FF0 003F
+10FF0 0334
+10FF0 0061
+10FF0 0041
+10FF0 0062
+10FF1 0021
+10FF1 003F
+10FF1 0334
+10FF1 0061
+10FF1 0041
+10FF1 0062
+10FF2 0021
+10FF2 003F
+10FF2 0334
+10FF2 0061
+10FF2 0041
+10FF2 0062
+10FF3 0021
+10FF3 003F
+10FF3 0334
+10FF3 0061
+10FF3 0041
+10FF3 0062
+10FF4 0021
+10FF4 003F
+10FF4 0334
+10FF4 0061
+10FF4 0041
+10FF4 0062
+10FF5 0021
+10FF5 003F
+10FF5 0334
+10FF5 0061
+10FF5 0041
+10FF5 0062
10AC0 0021
10AC0 003F
10AC0 0334
@@ -174217,6 +178046,11 @@ F9A8 003F
F9A8 0061
F9A8 0041
F9A8 0062
+32FF 0021
+32FF 003F
+32FF 0061
+32FF 0041
+32FF 0062
323D 0021
323D 003F
32AD 0021
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationAPITest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationAPITest.java
index 3b595f9ab..84c3a201e 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationAPITest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationAPITest.java
@@ -496,10 +496,8 @@ public class CollationAPITest extends TestFmwk {
doAssert((col.getDecomposition() == Collator.NO_DECOMPOSITION), "Decomposition mode = Collator.NO_DECOMPOSITION");
- // Android patch: Add --omitCollationRules to genrb.
- // RuleBasedCollator rcol = (RuleBasedCollator)Collator.getInstance(new Locale("da", "DK"));
- // doAssert(rcol.getRules().length() != 0, "da_DK rules does not have length 0");
- // Android patch end.
+ RuleBasedCollator rcol = (RuleBasedCollator)Collator.getInstance(new Locale("da", "DK"));
+ doAssert(rcol.getRules().length() != 0, "da_DK rules does not have length 0");
try {
col = Collator.getInstance(Locale.FRENCH);
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationCreationMethodTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationCreationMethodTest.java
index 1c248de49..2797b1c26 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationCreationMethodTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationCreationMethodTest.java
@@ -120,9 +120,7 @@ public class CollationCreationMethodTest extends TestFmwk
msg.append(" failed to produce identical keys on both collators\n");
msg.append(" localeCollator key: ").append(CollationTest.prettify(k1)).append('\n');
msg.append(" ruleCollator key: ").append(CollationTest.prettify(k2)).append('\n');
- // Android patch: Add --omitCollationRules to genrb.
- logln(msg.toString());
- // Android patch end.
+ errln(msg.toString());
}
}
}
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java
index ac78e4912..f008297fd 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java
@@ -1986,9 +1986,7 @@ public class CollationMiscTest extends TestFmwk {
}
coll = new RuleBasedCollator(rule);
} catch (Exception e) {
- // Android patch: Add --omitCollationRules to genrb.
- logln(e.getMessage());
- // Android patch end.
+ warnln(e.getMessage());
}
}
@@ -3083,9 +3081,7 @@ public class CollationMiscTest extends TestFmwk {
}
}catch(Exception e){
- // Android patch: Add --omitCollationRules to genrb.
- logln("ERROR: in creation of rule based collator");
- // Android patch end.
+ warnln("ERROR: in creation of rule based collator");
}
}
@@ -3114,9 +3110,7 @@ public class CollationMiscTest extends TestFmwk {
}
}catch(Exception e){
- // Android patch: Add --omitCollationRules to genrb.
- logln("ERROR: in creation of rule based collator");
- // Android patch end.
+ warnln("ERROR: in creation of rule based collator");
}
}
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationServiceTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationServiceTest.java
index 76377fe41..4be8e1cd8 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationServiceTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationServiceTest.java
@@ -359,7 +359,7 @@ public class CollationServiceTest extends TestFmwk {
new ULocale("de"),
isAvailable);
if (assertTrue("getFunctionalEquivalent(de)!=null", equiv!=null)) {
- assertEquals("getFunctionalEquivalent(de)", "root", equiv.toString());
+ assertEquals("getFunctionalEquivalent(de)", "", equiv.toString());
}
assertTrue("getFunctionalEquivalent(de).isAvailable==true",
isAvailable[0] == true);
@@ -368,7 +368,7 @@ public class CollationServiceTest extends TestFmwk {
new ULocale("de_DE"),
isAvailable);
if (assertTrue("getFunctionalEquivalent(de_DE)!=null", equiv!=null)) {
- assertEquals("getFunctionalEquivalent(de_DE)", "root", equiv.toString());
+ assertEquals("getFunctionalEquivalent(de_DE)", "", equiv.toString());
}
assertTrue("getFunctionalEquivalent(de_DE).isAvailable==false",
isAvailable[0] == false);
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationTest.java
index 1a4b2fa9b..5b2212a6d 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationTest.java
@@ -1324,9 +1324,7 @@ public class CollationTest extends TestFmwk {
coll = new RuleBasedCollator(rules.toString());
} catch (Exception e) {
logln(rules.toString());
- // Android patch: Add --omitCollationRules to genrb.
- logln("RuleBasedCollator(rules) failed - " + e.getMessage());
- // Android patch end.
+ errln("RuleBasedCollator(rules) failed - " + e.getMessage());
coll = null;
}
}
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/G7CollationTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/G7CollationTest.java
index cd45c2d54..29770da58 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/G7CollationTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/collator/G7CollationTest.java
@@ -243,9 +243,7 @@ public class G7CollationTest extends TestFmwk{
if (ok1) {
logln(msg1 + source + msg2 + target + msg3 + sResult);
} else {
- // Android patch: Add --omitCollationRules to genrb.
- logln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
- // Android patch end.
+ errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
}
msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\"";
@@ -255,14 +253,10 @@ public class G7CollationTest extends TestFmwk{
if (ok2) {
logln(msg1 + source + msg2 + target + msg3 + sResult);
} else {
- // Android patch: Add --omitCollationRules to genrb.
- logln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
- // Android patch end.
+ errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
msg1 = " ";
msg2 = " vs. ";
- // Android patch: Add --omitCollationRules to genrb.
- logln(msg1 + CollationTest.prettify(sourceKey) + msg2 + CollationTest.prettify(targetKey));
- // Android patch end.
+ errln(msg1 + CollationTest.prettify(sourceKey) + msg2 + CollationTest.prettify(targetKey));
}
msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\"";
@@ -274,9 +268,7 @@ public class G7CollationTest extends TestFmwk{
if (ok3) {
logln(msg1 + source + msg2 + target + msg3 + sResult);
} else {
- // Android patch: Add --omitCollationRules to genrb.
- logln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
- // Android patch end.
+ errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
}
}
}
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/format/GlobalizationPreferencesTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/format/GlobalizationPreferencesTest.java
index 7bc21bc63..a3fcb4da0 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/format/GlobalizationPreferencesTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/format/GlobalizationPreferencesTest.java
@@ -868,8 +868,8 @@ public class GlobalizationPreferencesTest extends TestFmwk {
gp.setLocale(new ULocale("aar"));
BreakIterator brk = gp.getBreakIterator(GlobalizationPreferences.BI_LINE);
String locStr = brk.getLocale(ULocale.VALID_LOCALE).toString();
- if (!locStr.equals("root")) {
- errln("FAIL: Line break iterator locale is " + locStr + " Expected: root");
+ if (!locStr.isEmpty()) {
+ errln("FAIL: Line break iterator locale is " + locStr + " Expected: \"\"");
}
// Set locale - es
diff --git a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/util/ICUResourceBundleCollationTest.java b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/util/ICUResourceBundleCollationTest.java
index 93808e784..f6b3f9e37 100644
--- a/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/util/ICUResourceBundleCollationTest.java
+++ b/icu4j/main/tests/collate/src/com/ibm/icu/dev/test/util/ICUResourceBundleCollationTest.java
@@ -30,38 +30,38 @@ public final class ICUResourceBundleCollationTest extends TestFmwk {
@Test
public void TestFunctionalEquivalent(){
- // Android patch: Add exceptions for big5han and gb2312han in genrb.
String[] collCases = {
+ // note: in ICU 64, empty locales are shown as available for collation
// avail locale equiv
"f", "sv_US_CALIFORNIA", "sv",
"f", "zh_TW@collation=stroke", "zh@collation=stroke", /* alias of zh_Hant_TW */
- "f", "zh_Hant_TW@collation=stroke", "zh@collation=stroke",
+ "t", "zh_Hant_TW@collation=stroke", "zh@collation=stroke",
"f", "sv_CN@collation=pinyin", "sv",
"t", "zh@collation=pinyin", "zh",
"f", "zh_CN@collation=pinyin", "zh", /* alias of zh_Hans_CN */
- "f", "zh_Hans_CN@collation=pinyin", "zh",
+ "t", "zh_Hans_CN@collation=pinyin", "zh",
"f", "zh_HK@collation=pinyin", "zh", /* alias of zh_Hant_HK */
- "f", "zh_Hant_HK@collation=pinyin", "zh",
+ "t", "zh_Hant_HK@collation=pinyin", "zh",
"f", "zh_HK@collation=stroke", "zh@collation=stroke", /* alias of zh_Hant_HK */
- "f", "zh_Hant_HK@collation=stroke", "zh@collation=stroke",
+ "t", "zh_Hant_HK@collation=stroke", "zh@collation=stroke",
"f", "zh_HK", "zh@collation=stroke", /* alias of zh_Hant_HK */
- "f", "zh_Hant_HK", "zh@collation=stroke",
+ "t", "zh_Hant_HK", "zh@collation=stroke",
"f", "zh_MO", "zh@collation=stroke", /* alias of zh_Hant_MO */
- "f", "zh_Hant_MO", "zh@collation=stroke",
+ "t", "zh_Hant_MO", "zh@collation=stroke",
"f", "zh_TW_STROKE", "zh@collation=stroke",
- // "f", "zh_TW_STROKE@collation=big5han", "zh@collation=big5han",
+ "f", "zh_TW_STROKE@collation=big5han", "zh@collation=big5han",
"f", "sv_CN@calendar=japanese", "sv",
"t", "sv@calendar=japanese", "sv",
- // "f", "zh_TW@collation=big5han", "zh@collation=big5han", /* alias of zh_Hant_TW */
- // "f", "zh_Hant_TW@collation=big5han", "zh@collation=big5han",
- // "f", "zh_TW@collation=gb2312han", "zh@collation=gb2312han", /* alias of zh_Hant_TW */
- // "f", "zh_Hant_TW@collation=gb2312han", "zh@collation=gb2312han",
- // "f", "zh_CN@collation=big5han", "zh@collation=big5han", /* alias of zh_Hans_CN */
- // "f", "zh_Hans_CN@collation=big5han", "zh@collation=big5han",
- // "f", "zh_CN@collation=gb2312han", "zh@collation=gb2312han", /* alias of zh_Hans_CN */
- // "f", "zh_Hans_CN@collation=gb2312han", "zh@collation=gb2312han",
- // "t", "zh@collation=big5han", "zh@collation=big5han",
- // "t", "zh@collation=gb2312han", "zh@collation=gb2312han",
+ "f", "zh_TW@collation=big5han", "zh@collation=big5han", /* alias of zh_Hant_TW */
+ "t", "zh_Hant_TW@collation=big5han", "zh@collation=big5han",
+ "f", "zh_TW@collation=gb2312han", "zh@collation=gb2312han", /* alias of zh_Hant_TW */
+ "t", "zh_Hant_TW@collation=gb2312han", "zh@collation=gb2312han",
+ "f", "zh_CN@collation=big5han", "zh@collation=big5han", /* alias of zh_Hans_CN */
+ "t", "zh_Hans_CN@collation=big5han", "zh@collation=big5han",
+ "f", "zh_CN@collation=gb2312han", "zh@collation=gb2312han", /* alias of zh_Hans_CN */
+ "t", "zh_Hans_CN@collation=gb2312han", "zh@collation=gb2312han",
+ "t", "zh@collation=big5han", "zh@collation=big5han",
+ "t", "zh@collation=gb2312han", "zh@collation=gb2312han",
"t", "hi@collation=standard", "hi",
"f", "hi_AU@collation=standard;currency=CHF;calendar=buddhist", "hi",
"f", "sv_SE@collation=pinyin", "sv", /* bug 4582 tests */
@@ -73,7 +73,6 @@ public final class ICUResourceBundleCollationTest extends TestFmwk {
"f", "nl_NL@collation=stroke", "root",
"f", "nl_NL_EEXT@collation=stroke", "root",
};
- // Android patch end.
logln("Testing functional equivalents for collation...");
getFunctionalEquivalentTestCases(ICUData.ICU_COLLATION_BASE_NAME,
@@ -97,7 +96,9 @@ public final class ICUResourceBundleCollationTest extends TestFmwk {
ICUResourceBundle bundle = null;
String key = null;
try{
- bundle = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_COLLATION_BASE_NAME,ULocale.canonicalize("de__PHONEBOOK"));
+ bundle = (ICUResourceBundle) UResourceBundle.getBundleInstance(
+ ICUData.ICU_COLLATION_BASE_NAME,
+ ULocale.canonicalize("de@collation=phonebook"));
if(!bundle.getULocale().getName().equals("de")){
errln("did not get the expected bundle");
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt
index 6ff99a8f2..b48cc6c3e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt
@@ -204,6 +204,29 @@ pattern format output breaks
#E0 52413 5,2413E4 K
0E0 52413 5E4
+test scientific infinite precision
+// ICU-11511, ICU-7460, CLDR-10103
+set locale en
+begin
+pattern format output breaks
+// From the spec:
+// "0.##E0 means a max of 3 significant digits."
+0.##E0 98760 9.88E4
+// "#.##E0 also means a max of 3 significant digits."
+#.##E0 98760 9.88E4
+// "#.0#E0 means a max of 2 significant digits."
+#.0#E0 98760 9.9E4 K
+// "0E0 means a max of 1 significant digit."
+0E0 98760 1E5
+// "#E0 means infinite precision."
+#E0 98760 9.876E4 K
+// "###E0 means engineering notation with infinite precision."
+###E0 98760 98.76E3 K
+// Additional tests:
+##0.#E0 98760 99E3 K
+###.#E0 98760 99E3 K
+##0E0 98760 100E3 K
+
test percents
set locale fr
begin
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/BidiTest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/BidiTest.txt
index e7637c3de..49665bd19 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/BidiTest.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/BidiTest.txt
@@ -1,6 +1,6 @@
-# BidiTest-11.0.0.txt
-# Date: 2018-01-31, 08:20:07 GMT
-# © 2018 Unicode®, Inc.
+# BidiTest-12.1.0.txt
+# Date: 2019-03-08, 23:59:20 GMT
+# © 2019 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
#
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/CompositionExclusions.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/CompositionExclusions.txt
index ea63595bd..aa654974b 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/CompositionExclusions.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/CompositionExclusions.txt
@@ -1,6 +1,6 @@
-# CompositionExclusions-11.0.0.txt
-# Date: 2017-12-06, 00:00:00 GMT [KW, LI]
-# © 2017 Unicode®, Inc.
+# CompositionExclusions-12.1.0.txt
+# Date: 2019-03-08, 23:59:00 GMT [KW, LI]
+# © 2019 Unicode®, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/IdnaTestV2.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/IdnaTestV2.txt
index 8897be96b..731b78177 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/IdnaTestV2.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/IdnaTestV2.txt
@@ -1,10 +1,15 @@
# IdnaTestV2.txt
-# Date: 2018-05-22, 05:53:13 GMT
-# © 2018 Unicode®, Inc.
+# Date: 2019-04-01, 09:18:19 GMT
+# © 2019 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
-# Contains test cases for verifying UTS #46 conformance. For more information,
-# see http://www.unicode.org/reports/tr46/
+#
+# Unicode IDNA Compatible Preprocessing for UTS #46
+# Version: 12.1.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr46
+#
+# Test cases for verifying UTS #46 conformance.
#
# FORMAT:
#
@@ -1614,8 +1619,8 @@ xn--h8e470bl0d838o.xn----381i; ꡦᡑ‍⒈.𐋣-; [C2, V3, V6]; xn--h8e470bl0d8
xn--3kj.xn--yib19191t; ⴌ.􍼠ٹ; [B5, B6, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
xn--knd.xn--yib19191t; Ⴌ.􍼠ٹ; [B5, B6, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
ⴌ。􍼠ﭩ; ⴌ.􍼠ٹ; [B5, B6, P1, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
-𐮁𐭱.྄፞-ᳺ; ; [B1, P1, V5, V6]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-
-xn--r19c5a.xn----xjg270ag3m; 𐮁𐭱.྄፞-ᳺ; [B1, V5, V6]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-
+𐮁𐭱.྄፞-ᳺ; ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
+xn--r19c5a.xn----xjg270ag3m; 𐮁𐭱.྄፞-ᳺ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
⒈䰹‍-。웈; ⒈䰹‍-.웈; [C2, P1, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [P1, V3, V6] # ⒈䰹-.웈
⒈䰹‍-。웈; ⒈䰹‍-.웈; [C2, P1, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [P1, V3, V6] # ⒈䰹-.웈
1.䰹‍-。웈; 1.䰹‍-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; 1.xn----zw5a.xn--kp5b; [V3] # 1.䰹-.웈
@@ -1668,28 +1673,28 @@ xn--gdh.xn--lfb92e; ≮.ݩ؃; [B1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
𐶭舌。‌𑚶򟱃𞰘; 𐶭舌.‌𑚶򟱃𞰘; [B1, B2, B3, C1, P1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; xn--tc1ao37z.xn--6e2dw557azds2d; [B2, B3, B5, B6, P1, V5, V6] # 舌.𑚶
xn--tc1ao37z.xn--6e2dw557azds2d; 𐶭舌.𑚶򟱃𞰘; [B2, B3, B5, B6, V5, V6]; xn--tc1ao37z.xn--6e2dw557azds2d; ; ; # 舌.𑚶
xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; 𐶭舌.‌𑚶򟱃𞰘; [B1, B2, B3, C1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; ; # 舌.𑚶
-‌Ⴠ-.𝟷ς𞴺ς; ‌Ⴠ-.1ς𞴺ς; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ςς
-‌Ⴠ-.1ς𞴺ς; ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ςς
-‌ⴠ-.1ς𞴺ς; ; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1ςς
-‌Ⴠ-.1Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σσ
-‌ⴠ-.1σ𞴺σ; ; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1σσ
-‌Ⴠ-.1σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σσ
-xn----z1g.xn--1-0mba52321c; Ⴠ-.1σ𞴺σ; [B1, B6, V3, V6]; xn----z1g.xn--1-0mba52321c; ; ; # Ⴠ-.1σσ
-xn----z1g168i.xn--1-0mba52321c; ‌Ⴠ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; ; # Ⴠ-.1σσ
-xn----2ws.xn--1-0mba52321c; ⴠ-.1σ𞴺σ; [B1, B6, V3, V6]; xn----2ws.xn--1-0mba52321c; ; ; # ⴠ-.1σσ
-xn----rgn530d.xn--1-0mba52321c; ‌ⴠ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----rgn530d.xn--1-0mba52321c; ; ; # ⴠ-.1σσ
-‌Ⴠ-.1ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ςσ
-‌ⴠ-.1ς𞴺σ; ; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1ςσ
-xn----rgn530d.xn--1-ymbd52321c; ‌ⴠ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----rgn530d.xn--1-ymbd52321c; ; ; # ⴠ-.1ςσ
-xn----z1g168i.xn--1-ymbd52321c; ‌Ⴠ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; ; # Ⴠ-.1ςσ
-xn----rgn530d.xn--1-ymba92321c; ‌ⴠ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----rgn530d.xn--1-ymba92321c; ; ; # ⴠ-.1ςς
-xn----z1g168i.xn--1-ymba92321c; ‌Ⴠ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; ; # Ⴠ-.1ςς
-‌ⴠ-.𝟷ς𞴺ς; ‌ⴠ-.1ς𞴺ς; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1ςς
-‌Ⴠ-.𝟷Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σσ
-‌ⴠ-.𝟷σ𞴺σ; ‌ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1σσ
-‌Ⴠ-.𝟷σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σσ
-‌Ⴠ-.𝟷ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ςσ
-‌ⴠ-.𝟷ς𞴺σ; ‌ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # ⴠ-.1ςσ
+‌Ⴠ-.𝟷ς𞴺ς; ‌Ⴠ-.1ς𞴺ς; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺ς
+‌Ⴠ-.1ς𞴺ς; ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺ς
+‌ⴠ-.1ς𞴺ς; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+‌Ⴠ-.1Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌ⴠ-.1σ𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+‌Ⴠ-.1σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+xn----z1g.xn--1-0mba52321c; Ⴠ-.1σ𞴺σ; [B1, B6, V3, V6]; xn----z1g.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----z1g168i.xn--1-0mba52321c; ‌Ⴠ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----2ws.xn--1-0mba52321c; ⴠ-.1σ𞴺σ; [B1, B6, V3]; xn----2ws.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+xn----rgn530d.xn--1-0mba52321c; ‌ⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+‌Ⴠ-.1ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺σ
+‌ⴠ-.1ς𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymbd52321c; ‌ⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; ; # ⴠ-.1ς𞴺σ
+xn----z1g168i.xn--1-ymbd52321c; ‌Ⴠ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; ; # Ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymba92321c; ‌ⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; ; # ⴠ-.1ς𞴺ς
+xn----z1g168i.xn--1-ymba92321c; ‌Ⴠ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; ; # Ⴠ-.1ς𞴺ς
+‌ⴠ-.𝟷ς𞴺ς; ‌ⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+‌Ⴠ-.𝟷Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌ⴠ-.𝟷σ𞴺σ; ‌ⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+‌Ⴠ-.𝟷σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌Ⴠ-.𝟷ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺σ
+‌ⴠ-.𝟷ς𞴺σ; ‌ⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
𑲘󠄒𓑡。𝟪Ⴜ; 𑲘𓑡.8Ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
𑲘󠄒𓑡。8Ⴜ; 𑲘𓑡.8Ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
𑲘󠄒𓑡。8ⴜ; 𑲘𓑡.8ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
@@ -2111,11 +2116,10 @@ xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ڇ6Ⴔ辘.صيڇ‌; [B2, B3, C1, V6]; xn--6-
꡽≯.򻲀򒳄; ꡽≯.򻲀򒳄; [P1, V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
xn--hdh8193c.xn--5z40cp629b; ꡽≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
ςოٻ.ςܔ; ; [B5, B6]; xn--3xa80l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # ςოٻ.ςܔ
-ΣᲝٻ.Σܔ; σᲝٻ.σܔ; [B5, B6, P1, V6]; xn--4xa60lw94a.xn--4xa21o; ; ; # σᲝٻ.σܔ
+ΣᲝٻ.Σܔ; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
σოٻ.σܔ; ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
Σოٻ.σܔ; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
xn--4xa60l26n.xn--4xa21o; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
-xn--4xa60lw94a.xn--4xa21o; σᲝٻ.σܔ; [B5, B6, V6]; xn--4xa60lw94a.xn--4xa21o; ; ; # σᲝٻ.σܔ
Σოٻ.ςܔ; σოٻ.ςܔ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
σოٻ.ςܔ; ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
xn--4xa60l26n.xn--3xa41o; σოٻ.ςܔ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; ; # σოٻ.ςܔ
@@ -4038,8 +4042,8 @@ xn--1ss-ir6ln166b.xn--weg; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ;
xn--1-qfa2471kdb0d.xn--weg; 1꫶ß𑲥.ᷘ; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; ; # 1꫶ß𑲥.ᷘ
1꫶SS𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
1꫶ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
-1꫶Ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
1꫶Ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1꫶Ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
‍񫶩𞪯್。ݼ⒈; ‍񫶩𞪯್.ݼ⒈; [B1, C2, P1, V6]; xn--8tc969gzn94a4lm8a.xn--dqb689l; ; xn--8tc9875v5is1a.xn--dqb689l; [B5, B6, P1, V6] # ್.ݼ⒈
‍񫶩𞪯್。ݼ1.; ‍񫶩𞪯್.ݼ1.; [B1, C2, P1, V6]; xn--8tc969gzn94a4lm8a.xn--1-g6c.; ; xn--8tc9875v5is1a.xn--1-g6c.; [B5, B6, P1, V6] # ್.ݼ1.
xn--8tc9875v5is1a.xn--1-g6c.; 񫶩𞪯್.ݼ1.; [B5, B6, V6]; xn--8tc9875v5is1a.xn--1-g6c.; ; ; # ್.ݼ1.
@@ -5577,12 +5581,11 @@ xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ꡰ︒--.៌靈𐹢񘳮; [B1, B6, V2, V3,
ᅟႿႵრ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
ᅟႿႵრ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
ᅟⴟⴕრ。୍; ᅟⴟⴕრ.୍; [P1, V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
-ᅟႿႵᲠ。୍; ᅟႿႵᲠ.୍; [P1, V5, V6]; xn--tndt39bg47a.xn--9ic; ; ; # ႿႵᲠ.୍
-xn--tndt39bg47a.xn--9ic; ᅟႿႵᲠ.୍; [V5, V6]; xn--tndt39bg47a.xn--9ic; ; ; # ႿႵᲠ.୍
-xn--1od7wz74eeb.xn--9ic; ᅟⴟⴕრ.୍; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+ᅟႿႵᲠ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
xn--tndt4hvw.xn--9ic; ᅟႿႵრ.୍; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+xn--1od7wz74eeb.xn--9ic; ᅟⴟⴕრ.୍; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
ᅟⴟⴕრ。୍; ᅟⴟⴕრ.୍; [P1, V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
-ᅟႿႵᲠ。୍; ᅟႿႵᲠ.୍; [P1, V5, V6]; xn--tndt39bg47a.xn--9ic; ; ; # ႿႵᲠ.୍
+ᅟႿႵᲠ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
ᅟႿⴕრ。୍; ᅟႿⴕრ.୍; [P1, V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
xn--3nd0etsm92g.xn--9ic; ᅟႿⴕრ.୍; [V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
ᅟႿⴕრ。୍; ᅟႿⴕრ.୍; [P1, V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationCorrections.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationCorrections.txt
index 8b3cd2b13..360f49cc9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationCorrections.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationCorrections.txt
@@ -1,6 +1,6 @@
-# NormalizationCorrections-11.0.0.txt
-# Date: 2017-12-06, 01:00:00 GMT [KW, LI]
-# © 2017 Unicode®, Inc.
+# NormalizationCorrections-12.1.0.txt
+# Date: 2019-03-08, 23:59:00 GMT [KW, LI]
+# © 2019 Unicode®, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationTest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationTest.txt
index 15270455e..cf4c3a9ba 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationTest.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/NormalizationTest.txt
@@ -1,6 +1,6 @@
-# NormalizationTest-11.0.0.txt
-# Date: 2018-02-19, 18:33:08 GMT
-# © 2018 Unicode®, Inc.
+# NormalizationTest-12.1.0.txt
+# Date: 2019-04-01, 09:10:28 GMT
+# © 2019 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
#
@@ -2149,6 +2149,7 @@
32FC;32FC;32FC;30F0;30F0;
32FD;32FD;32FD;30F1;30F1;
32FE;32FE;32FE;30F2;30F2;
+32FF;32FF;32FF;4EE4 548C;4EE4 548C;
3300;3300;3300;30A2 30D1 30FC 30C8;30A2 30CF 309A 30FC 30C8;
3301;3301;3301;30A2 30EB 30D5 30A1;30A2 30EB 30D5 30A1;
3302;3302;3302;30A2 30F3 30DA 30A2;30A2 30F3 30D8 309A 30A2;
@@ -16363,6 +16364,7 @@ FFEE;FFEE;FFEE;25CB;25CB;
1F14F;1F14F;1F14F;0057 0043;0057 0043;
1F16A;1F16A;1F16A;004D 0043;004D 0043;
1F16B;1F16B;1F16B;004D 0044;004D 0044;
+1F16C;1F16C;1F16C;004D 0052;004D 0052;
1F190;1F190;1F190;0044 004A;0044 004A;
1F200;1F200;1F200;307B 304B;307B 304B;
1F201;1F201;1F201;30B3 30B3;30B3 30B3;
@@ -17685,6 +17687,8 @@ FFEE;FFEE;FFEE;25CB;25CB;
0061 0EB8 0EC8 0EB8 0E48 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;
0061 0EC8 0EB8 0E48 0EB9 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;
0061 0EB9 0EC8 0EB8 0E48 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;
+0061 05B0 094D 3099 0EBA 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062;
+0061 0EBA 05B0 094D 3099 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062;
0061 0F71 0EC8 0EB8 0EC8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;
0061 0EC8 0F71 0EC8 0EB8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;
0061 0F71 0EC8 0EB8 0EC9 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;
@@ -18453,6 +18457,8 @@ FFEE;FFEE;FFEE;25CB;25CB;
0061 11839 05B0 094D 3099 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;
0061 3099 093C 0334 1183A 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;
0061 1183A 3099 093C 0334 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;
+0061 05B0 094D 3099 119E0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062;
+0061 119E0 05B0 094D 3099 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062;
0061 05B0 094D 3099 11A34 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;
0061 11A34 05B0 094D 3099 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;
0061 05B0 094D 3099 11A47 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;
@@ -18637,6 +18643,28 @@ FFEE;FFEE;FFEE;25CB;25CB;
0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;
0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;
0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;
+0061 0315 0300 05AE 1E130 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062;
+0061 1E130 0315 0300 05AE 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;
+0061 0315 0300 05AE 1E131 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062;
+0061 1E131 0315 0300 05AE 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062;
+0061 0315 0300 05AE 1E132 0062;00E0 05AE 1E132 0315 0062;0061 05AE 0300 1E132 0315 0062;00E0 05AE 1E132 0315 0062;0061 05AE 0300 1E132 0315 0062;
+0061 1E132 0315 0300 05AE 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062;
+0061 0315 0300 05AE 1E133 0062;00E0 05AE 1E133 0315 0062;0061 05AE 0300 1E133 0315 0062;00E0 05AE 1E133 0315 0062;0061 05AE 0300 1E133 0315 0062;
+0061 1E133 0315 0300 05AE 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062;
+0061 0315 0300 05AE 1E134 0062;00E0 05AE 1E134 0315 0062;0061 05AE 0300 1E134 0315 0062;00E0 05AE 1E134 0315 0062;0061 05AE 0300 1E134 0315 0062;
+0061 1E134 0315 0300 05AE 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062;
+0061 0315 0300 05AE 1E135 0062;00E0 05AE 1E135 0315 0062;0061 05AE 0300 1E135 0315 0062;00E0 05AE 1E135 0315 0062;0061 05AE 0300 1E135 0315 0062;
+0061 1E135 0315 0300 05AE 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;
+0061 0315 0300 05AE 1E136 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 0315 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 0315 0062;
+0061 1E136 0315 0300 05AE 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;
+0061 0315 0300 05AE 1E2EC 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 0315 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 0315 0062;
+0061 1E2EC 0315 0300 05AE 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;
+0061 0315 0300 05AE 1E2ED 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 0315 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 0315 0062;
+0061 1E2ED 0315 0300 05AE 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062;
+0061 0315 0300 05AE 1E2EE 0062;00E0 05AE 1E2EE 0315 0062;0061 05AE 0300 1E2EE 0315 0062;00E0 05AE 1E2EE 0315 0062;0061 05AE 0300 1E2EE 0315 0062;
+0061 1E2EE 0315 0300 05AE 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;
+0061 0315 0300 05AE 1E2EF 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062;
+0061 1E2EF 0315 0300 05AE 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;
0061 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;
0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;
0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/SpecialCasing.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/SpecialCasing.txt
index c90d09acb..1c04aacf9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/SpecialCasing.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/SpecialCasing.txt
@@ -1,6 +1,6 @@
-# SpecialCasing-11.0.0.txt
-# Date: 2018-02-22, 06:16:47 GMT
-# © 2018 Unicode®, Inc.
+# SpecialCasing-12.1.0.txt
+# Date: 2019-03-10, 10:53:28 GMT
+# © 2019 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
#
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/UnicodeData.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/UnicodeData.txt
index ec32fafbc..e65aec52f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/UnicodeData.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/UnicodeData.txt
@@ -640,7 +640,7 @@
027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;
0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6
0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;
-0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;;
+0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;A7C5;;A7C5
0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9
0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
@@ -2809,6 +2809,7 @@
0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+0C77;TELUGU SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;;
0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
@@ -3203,14 +3204,24 @@
0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;
0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;
0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;
+0E86;LAO LETTER PALI GHA;Lo;0;L;;;;;N;;;;;
0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;
0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;
+0E89;LAO LETTER PALI CHA;Lo;0;L;;;;;N;;;;;
0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;
+0E8C;LAO LETTER PALI JHA;Lo;0;L;;;;;N;;;;;
0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;
+0E8E;LAO LETTER PALI NYA;Lo;0;L;;;;;N;;;;;
+0E8F;LAO LETTER PALI TTA;Lo;0;L;;;;;N;;;;;
+0E90;LAO LETTER PALI TTHA;Lo;0;L;;;;;N;;;;;
+0E91;LAO LETTER PALI DDA;Lo;0;L;;;;;N;;;;;
+0E92;LAO LETTER PALI DDHA;Lo;0;L;;;;;N;;;;;
+0E93;LAO LETTER PALI NNA;Lo;0;L;;;;;N;;;;;
0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;
0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;
0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;
0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;
+0E98;LAO LETTER PALI DHA;Lo;0;L;;;;;N;;;;;
0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;
0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;
0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;
@@ -3218,13 +3229,17 @@
0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;
0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;
0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;
+0EA0;LAO LETTER PALI BHA;Lo;0;L;;;;;N;;;;;
0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;
0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;
0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;
0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;
0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;
+0EA8;LAO LETTER SANSKRIT SHA;Lo;0;L;;;;;N;;;;;
+0EA9;LAO LETTER SANSKRIT SSA;Lo;0;L;;;;;N;;;;;
0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;
0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;
+0EAC;LAO LETTER PALI LLA;Lo;0;L;;;;;N;;;;;
0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;
0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;
0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;
@@ -3238,6 +3253,7 @@
0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;
0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;
+0EBA;LAO SIGN PALI VIRAMA;Mn;9;NSM;;;;;N;;;;;
0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;
0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;
0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;
@@ -5079,7 +5095,7 @@
166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;
166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;
166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;
-166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;;
+166D;CANADIAN SYLLABICS CHI SIGN;So;0;L;;;;;N;;;;;
166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;
166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;
1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;
@@ -6488,14 +6504,15 @@
1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;;
1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;;
-1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
-1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Mc;0;L;;;;;N;;;;;
+1CF2;VEDIC SIGN ARDHAVISARGA;Lo;0;L;;;;;N;;;;;
+1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Lo;0;L;;;;;N;;;;;
1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;;
1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;;
1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;;
+1CFA;VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;;
1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;
1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;
@@ -6638,7 +6655,7 @@
1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
-1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C6;;A7C6
1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;;
@@ -10165,6 +10182,7 @@
2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;
+2BC9;NEPTUNE FORM TWO;So;0;ON;;;;;N;;;;;
2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;
@@ -10218,6 +10236,7 @@
2BFC;DOUBLED SYMBOL;So;0;ON;;;;;N;;;;;
2BFD;PASSED SYMBOL;So;0;ON;;;;;N;;;;;
2BFE;REVERSED RIGHT ANGLE;So;0;ON;;;;;Y;;;;;
+2BFF;HELLSCHREIBER PAUSE SYMBOL;So;0;ON;;;;;N;;;;;
2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;
2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;
2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;
@@ -10756,6 +10775,7 @@
2E4C;MEDIEVAL COMMA;Po;0;ON;;;;;N;;;;;
2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;;
2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;;
+2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;;
2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
@@ -11836,6 +11856,7 @@
32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;
32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;
32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;
+32FF;SQUARE ERA NAME REIWA;So;0;L;<square> 4EE4 548C;;;;N;;;;;
3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;
3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;
3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;
@@ -14060,7 +14081,7 @@ A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791;
A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790
A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793;
A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792
-A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
+A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C4;;A7C4
A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797;
A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796
@@ -14098,6 +14119,17 @@ A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7;
A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6
A7B8;LATIN CAPITAL LETTER U WITH STROKE;Lu;0;L;;;;;N;;;;A7B9;
A7B9;LATIN SMALL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;A7B8;;A7B8
+A7BA;LATIN CAPITAL LETTER GLOTTAL A;Lu;0;L;;;;;N;;;;A7BB;
+A7BB;LATIN SMALL LETTER GLOTTAL A;Ll;0;L;;;;;N;;;A7BA;;A7BA
+A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD;
+A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC
+A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF;
+A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE
+A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3;
+A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2
+A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794;
+A7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282;
+A7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E;
A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;
A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L;<super> 0126;;;;N;;;;;
A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L;<super> 0153;;;;N;;;;;
@@ -14506,7 +14538,7 @@ A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;;
A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;
A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;;
A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;
-A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;;
+A9BD;JAVANESE CONSONANT SIGN KERET;Mn;0;NSM;;;;;N;;;;;
A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;;
A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;;
A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;;
@@ -14863,6 +14895,8 @@ AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;;
AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;;
AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;;
AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;;
+AB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
+AB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0
AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1
AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2
@@ -19105,6 +19139,29 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;;
10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;
+10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;
+10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;
+10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;
+10FE3;ELYMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;;
+10FE4;ELYMAIC LETTER HE;Lo;0;R;;;;;N;;;;;
+10FE5;ELYMAIC LETTER WAW;Lo;0;R;;;;;N;;;;;
+10FE6;ELYMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
+10FE7;ELYMAIC LETTER HETH;Lo;0;R;;;;;N;;;;;
+10FE8;ELYMAIC LETTER TETH;Lo;0;R;;;;;N;;;;;
+10FE9;ELYMAIC LETTER YODH;Lo;0;R;;;;;N;;;;;
+10FEA;ELYMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;;
+10FEB;ELYMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;;
+10FEC;ELYMAIC LETTER MEM;Lo;0;R;;;;;N;;;;;
+10FED;ELYMAIC LETTER NUN;Lo;0;R;;;;;N;;;;;
+10FEE;ELYMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
+10FEF;ELYMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;;
+10FF0;ELYMAIC LETTER PE;Lo;0;R;;;;;N;;;;;
+10FF1;ELYMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;;
+10FF2;ELYMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;;
+10FF3;ELYMAIC LETTER RESH;Lo;0;R;;;;;N;;;;;
+10FF4;ELYMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;;
+10FF5;ELYMAIC LETTER TAW;Lo;0;R;;;;;N;;;;;
+10FF6;ELYMAIC LIGATURE ZAYIN-YODH;Lo;0;R;;;;;N;;;;;
11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
@@ -19887,6 +19944,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;;
1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;;
1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;;
+1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;
11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;;
11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;;
11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;;
@@ -20209,6 +20267,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;
116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
+116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;;
116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -20421,6 +20480,71 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;
118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;
+119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;;
+119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
+119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;;
+119A3;NANDINAGARI LETTER II;Lo;0;L;;;;;N;;;;;
+119A4;NANDINAGARI LETTER U;Lo;0;L;;;;;N;;;;;
+119A5;NANDINAGARI LETTER UU;Lo;0;L;;;;;N;;;;;
+119A6;NANDINAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+119A7;NANDINAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+119AA;NANDINAGARI LETTER E;Lo;0;L;;;;;N;;;;;
+119AB;NANDINAGARI LETTER AI;Lo;0;L;;;;;N;;;;;
+119AC;NANDINAGARI LETTER O;Lo;0;L;;;;;N;;;;;
+119AD;NANDINAGARI LETTER AU;Lo;0;L;;;;;N;;;;;
+119AE;NANDINAGARI LETTER KA;Lo;0;L;;;;;N;;;;;
+119AF;NANDINAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;
+119B0;NANDINAGARI LETTER GA;Lo;0;L;;;;;N;;;;;
+119B1;NANDINAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;
+119B2;NANDINAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;
+119B3;NANDINAGARI LETTER CA;Lo;0;L;;;;;N;;;;;
+119B4;NANDINAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;
+119B5;NANDINAGARI LETTER JA;Lo;0;L;;;;;N;;;;;
+119B6;NANDINAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;
+119B7;NANDINAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;
+119B8;NANDINAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;
+119B9;NANDINAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+119BA;NANDINAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;
+119BB;NANDINAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+119BC;NANDINAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;
+119BD;NANDINAGARI LETTER TA;Lo;0;L;;;;;N;;;;;
+119BE;NANDINAGARI LETTER THA;Lo;0;L;;;;;N;;;;;
+119BF;NANDINAGARI LETTER DA;Lo;0;L;;;;;N;;;;;
+119C0;NANDINAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;
+119C1;NANDINAGARI LETTER NA;Lo;0;L;;;;;N;;;;;
+119C2;NANDINAGARI LETTER PA;Lo;0;L;;;;;N;;;;;
+119C3;NANDINAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;
+119C4;NANDINAGARI LETTER BA;Lo;0;L;;;;;N;;;;;
+119C5;NANDINAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;
+119C6;NANDINAGARI LETTER MA;Lo;0;L;;;;;N;;;;;
+119C7;NANDINAGARI LETTER YA;Lo;0;L;;;;;N;;;;;
+119C8;NANDINAGARI LETTER RA;Lo;0;L;;;;;N;;;;;
+119C9;NANDINAGARI LETTER LA;Lo;0;L;;;;;N;;;;;
+119CA;NANDINAGARI LETTER VA;Lo;0;L;;;;;N;;;;;
+119CB;NANDINAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;
+119CC;NANDINAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
+119CD;NANDINAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
+119CE;NANDINAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
+119CF;NANDINAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;
+119D0;NANDINAGARI LETTER RRA;Lo;0;L;;;;;N;;;;;
+119D1;NANDINAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+119D2;NANDINAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
+119D3;NANDINAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
+119D4;NANDINAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+119D5;NANDINAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+119D6;NANDINAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+119D7;NANDINAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
+119DA;NANDINAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
+119DB;NANDINAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
+119DC;NANDINAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
+119DD;NANDINAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
+119DE;NANDINAGARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
+119DF;NANDINAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+119E0;NANDINAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
+119E1;NANDINAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
+119E2;NANDINAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;;
+119E3;NANDINAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;
+119E4;NANDINAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;
11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;;
11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
@@ -20545,6 +20669,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;;
11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;;
11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;;
+11A84;SOYOMBO SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
+11A85;SOYOMBO SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;
11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;;
11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;;
@@ -20959,6 +21085,57 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;
11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;;
+11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;;
+11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
+11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;;
+11FC3;TAMIL FRACTION ONE SIXTY-FOURTH;No;0;L;;;;1/64;N;;;;;
+11FC4;TAMIL FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;;
+11FC5;TAMIL FRACTION ONE THIRTY-SECOND;No;0;L;;;;1/32;N;;;;;
+11FC6;TAMIL FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;;
+11FC7;TAMIL FRACTION THREE SIXTY-FOURTHS;No;0;L;;;;3/64;N;;;;;
+11FC8;TAMIL FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;;
+11FC9;TAMIL FRACTION ONE SIXTEENTH-1;No;0;L;;;;1/16;N;;;;;
+11FCA;TAMIL FRACTION ONE SIXTEENTH-2;No;0;L;;;;1/16;N;;;;;
+11FCB;TAMIL FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;;
+11FCC;TAMIL FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;
+11FCD;TAMIL FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;;
+11FCE;TAMIL FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;
+11FCF;TAMIL FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;;
+11FD0;TAMIL FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
+11FD1;TAMIL FRACTION ONE HALF-1;No;0;L;;;;1/2;N;;;;;
+11FD2;TAMIL FRACTION ONE HALF-2;No;0;L;;;;1/2;N;;;;;
+11FD3;TAMIL FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
+11FD4;TAMIL FRACTION DOWNSCALING FACTOR KIIZH;No;0;L;;;;1/320;N;;;;;
+11FD5;TAMIL SIGN NEL;So;0;ON;;;;;N;;;;;
+11FD6;TAMIL SIGN CEVITU;So;0;ON;;;;;N;;;;;
+11FD7;TAMIL SIGN AAZHAAKKU;So;0;ON;;;;;N;;;;;
+11FD8;TAMIL SIGN UZHAKKU;So;0;ON;;;;;N;;;;;
+11FD9;TAMIL SIGN MUUVUZHAKKU;So;0;ON;;;;;N;;;;;
+11FDA;TAMIL SIGN KURUNI;So;0;ON;;;;;N;;;;;
+11FDB;TAMIL SIGN PATHAKKU;So;0;ON;;;;;N;;;;;
+11FDC;TAMIL SIGN MUKKURUNI;So;0;ON;;;;;N;;;;;
+11FDD;TAMIL SIGN KAACU;Sc;0;ET;;;;;N;;;;;
+11FDE;TAMIL SIGN PANAM;Sc;0;ET;;;;;N;;;;;
+11FDF;TAMIL SIGN PON;Sc;0;ET;;;;;N;;;;;
+11FE0;TAMIL SIGN VARAAKAN;Sc;0;ET;;;;;N;;;;;
+11FE1;TAMIL SIGN PAARAM;So;0;ON;;;;;N;;;;;
+11FE2;TAMIL SIGN KUZHI;So;0;ON;;;;;N;;;;;
+11FE3;TAMIL SIGN VELI;So;0;ON;;;;;N;;;;;
+11FE4;TAMIL WET CULTIVATION SIGN;So;0;ON;;;;;N;;;;;
+11FE5;TAMIL DRY CULTIVATION SIGN;So;0;ON;;;;;N;;;;;
+11FE6;TAMIL LAND SIGN;So;0;ON;;;;;N;;;;;
+11FE7;TAMIL SALT PAN SIGN;So;0;ON;;;;;N;;;;;
+11FE8;TAMIL TRADITIONAL CREDIT SIGN;So;0;ON;;;;;N;;;;;
+11FE9;TAMIL TRADITIONAL NUMBER SIGN;So;0;ON;;;;;N;;;;;
+11FEA;TAMIL CURRENT SIGN;So;0;ON;;;;;N;;;;;
+11FEB;TAMIL AND ODD SIGN;So;0;ON;;;;;N;;;;;
+11FEC;TAMIL SPENT SIGN;So;0;ON;;;;;N;;;;;
+11FED;TAMIL TOTAL SIGN;So;0;ON;;;;;N;;;;;
+11FEE;TAMIL IN POSSESSION SIGN;So;0;ON;;;;;N;;;;;
+11FEF;TAMIL STARTING FROM SIGN;So;0;ON;;;;;N;;;;;
+11FF0;TAMIL SIGN MUTHALIYA;So;0;ON;;;;;N;;;;;
+11FF1;TAMIL SIGN VAKAIYARAA;So;0;ON;;;;;N;;;;;
+11FFF;TAMIL PUNCTUATION END OF TEXT;Po;0;L;;;;;N;;;;;
12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
@@ -23264,6 +23441,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
+13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;;
+13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;;
+13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;;
+13433;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM START;Cf;0;L;;;;;N;;;;;
+13434;EGYPTIAN HIEROGLYPH INSERT AT TOP END;Cf;0;L;;;;;N;;;;;
+13435;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM END;Cf;0;L;;;;;N;;;;;
+13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;;
+13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;;
+13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;;
14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@@ -24782,6 +24968,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;;
16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;;
16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;;
+16F45;MIAO LETTER BRI;Lo;0;L;;;;;N;;;;;
+16F46;MIAO LETTER SYI;Lo;0;L;;;;;N;;;;;
+16F47;MIAO LETTER DZYI;Lo;0;L;;;;;N;;;;;
+16F48;MIAO LETTER TE;Lo;0;L;;;;;N;;;;;
+16F49;MIAO LETTER TSE;Lo;0;L;;;;;N;;;;;
+16F4A;MIAO LETTER RTE;Lo;0;L;;;;;N;;;;;
+16F4F;MIAO SIGN CONSONANT MODIFIER BAR;Mn;0;NSM;;;;;N;;;;;
16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;;
16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;;
16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;;
@@ -24829,6 +25022,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;;
16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;;
16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;;
+16F7F;MIAO VOWEL SIGN UOG;Mc;0;L;;;;;N;;;;;
+16F80;MIAO VOWEL SIGN YUI;Mc;0;L;;;;;N;;;;;
+16F81;MIAO VOWEL SIGN OG;Mc;0;L;;;;;N;;;;;
+16F82;MIAO VOWEL SIGN OER;Mc;0;L;;;;;N;;;;;
+16F83;MIAO VOWEL SIGN VW;Mc;0;L;;;;;N;;;;;
+16F84;MIAO VOWEL SIGN IG;Mc;0;L;;;;;N;;;;;
+16F85;MIAO VOWEL SIGN EA;Mc;0;L;;;;;N;;;;;
+16F86;MIAO VOWEL SIGN IONG;Mc;0;L;;;;;N;;;;;
+16F87;MIAO VOWEL SIGN UI;Mc;0;L;;;;;N;;;;;
16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;;
16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;;
16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;;
@@ -24848,8 +25050,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;;
16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;;
16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;;
+16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;;
+16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;;
17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;;
-187F1;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;
+187F7;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;
18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;
18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;;
18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;;
@@ -25892,6 +26096,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;
1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;
1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;
+1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
+1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
+1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
+1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
+1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
+1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
+1B167;KATAKANA LETTER SMALL N;Lo;0;L;;;;;N;;;;;
1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;;
1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;;
1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;;
@@ -28820,6 +29031,136 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;;
+1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;;
+1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;;
+1E103;NYIAKENG PUACHUE HMONG LETTER TA;Lo;0;L;;;;;N;;;;;
+1E104;NYIAKENG PUACHUE HMONG LETTER HA;Lo;0;L;;;;;N;;;;;
+1E105;NYIAKENG PUACHUE HMONG LETTER NA;Lo;0;L;;;;;N;;;;;
+1E106;NYIAKENG PUACHUE HMONG LETTER XA;Lo;0;L;;;;;N;;;;;
+1E107;NYIAKENG PUACHUE HMONG LETTER NKA;Lo;0;L;;;;;N;;;;;
+1E108;NYIAKENG PUACHUE HMONG LETTER CA;Lo;0;L;;;;;N;;;;;
+1E109;NYIAKENG PUACHUE HMONG LETTER LA;Lo;0;L;;;;;N;;;;;
+1E10A;NYIAKENG PUACHUE HMONG LETTER SA;Lo;0;L;;;;;N;;;;;
+1E10B;NYIAKENG PUACHUE HMONG LETTER ZA;Lo;0;L;;;;;N;;;;;
+1E10C;NYIAKENG PUACHUE HMONG LETTER NCA;Lo;0;L;;;;;N;;;;;
+1E10D;NYIAKENG PUACHUE HMONG LETTER NTSA;Lo;0;L;;;;;N;;;;;
+1E10E;NYIAKENG PUACHUE HMONG LETTER KA;Lo;0;L;;;;;N;;;;;
+1E10F;NYIAKENG PUACHUE HMONG LETTER DA;Lo;0;L;;;;;N;;;;;
+1E110;NYIAKENG PUACHUE HMONG LETTER NYA;Lo;0;L;;;;;N;;;;;
+1E111;NYIAKENG PUACHUE HMONG LETTER NRA;Lo;0;L;;;;;N;;;;;
+1E112;NYIAKENG PUACHUE HMONG LETTER VA;Lo;0;L;;;;;N;;;;;
+1E113;NYIAKENG PUACHUE HMONG LETTER NTXA;Lo;0;L;;;;;N;;;;;
+1E114;NYIAKENG PUACHUE HMONG LETTER TXA;Lo;0;L;;;;;N;;;;;
+1E115;NYIAKENG PUACHUE HMONG LETTER FA;Lo;0;L;;;;;N;;;;;
+1E116;NYIAKENG PUACHUE HMONG LETTER RA;Lo;0;L;;;;;N;;;;;
+1E117;NYIAKENG PUACHUE HMONG LETTER QA;Lo;0;L;;;;;N;;;;;
+1E118;NYIAKENG PUACHUE HMONG LETTER YA;Lo;0;L;;;;;N;;;;;
+1E119;NYIAKENG PUACHUE HMONG LETTER NQA;Lo;0;L;;;;;N;;;;;
+1E11A;NYIAKENG PUACHUE HMONG LETTER PA;Lo;0;L;;;;;N;;;;;
+1E11B;NYIAKENG PUACHUE HMONG LETTER XYA;Lo;0;L;;;;;N;;;;;
+1E11C;NYIAKENG PUACHUE HMONG LETTER NPA;Lo;0;L;;;;;N;;;;;
+1E11D;NYIAKENG PUACHUE HMONG LETTER DLA;Lo;0;L;;;;;N;;;;;
+1E11E;NYIAKENG PUACHUE HMONG LETTER NPLA;Lo;0;L;;;;;N;;;;;
+1E11F;NYIAKENG PUACHUE HMONG LETTER HAH;Lo;0;L;;;;;N;;;;;
+1E120;NYIAKENG PUACHUE HMONG LETTER MLA;Lo;0;L;;;;;N;;;;;
+1E121;NYIAKENG PUACHUE HMONG LETTER PLA;Lo;0;L;;;;;N;;;;;
+1E122;NYIAKENG PUACHUE HMONG LETTER GA;Lo;0;L;;;;;N;;;;;
+1E123;NYIAKENG PUACHUE HMONG LETTER RRA;Lo;0;L;;;;;N;;;;;
+1E124;NYIAKENG PUACHUE HMONG LETTER A;Lo;0;L;;;;;N;;;;;
+1E125;NYIAKENG PUACHUE HMONG LETTER AA;Lo;0;L;;;;;N;;;;;
+1E126;NYIAKENG PUACHUE HMONG LETTER I;Lo;0;L;;;;;N;;;;;
+1E127;NYIAKENG PUACHUE HMONG LETTER U;Lo;0;L;;;;;N;;;;;
+1E128;NYIAKENG PUACHUE HMONG LETTER O;Lo;0;L;;;;;N;;;;;
+1E129;NYIAKENG PUACHUE HMONG LETTER OO;Lo;0;L;;;;;N;;;;;
+1E12A;NYIAKENG PUACHUE HMONG LETTER E;Lo;0;L;;;;;N;;;;;
+1E12B;NYIAKENG PUACHUE HMONG LETTER EE;Lo;0;L;;;;;N;;;;;
+1E12C;NYIAKENG PUACHUE HMONG LETTER W;Lo;0;L;;;;;N;;;;;
+1E130;NYIAKENG PUACHUE HMONG TONE-B;Mn;230;NSM;;;;;N;;;;;
+1E131;NYIAKENG PUACHUE HMONG TONE-M;Mn;230;NSM;;;;;N;;;;;
+1E132;NYIAKENG PUACHUE HMONG TONE-J;Mn;230;NSM;;;;;N;;;;;
+1E133;NYIAKENG PUACHUE HMONG TONE-V;Mn;230;NSM;;;;;N;;;;;
+1E134;NYIAKENG PUACHUE HMONG TONE-S;Mn;230;NSM;;;;;N;;;;;
+1E135;NYIAKENG PUACHUE HMONG TONE-G;Mn;230;NSM;;;;;N;;;;;
+1E136;NYIAKENG PUACHUE HMONG TONE-D;Mn;230;NSM;;;;;N;;;;;
+1E137;NYIAKENG PUACHUE HMONG SIGN FOR PERSON;Lm;0;L;;;;;N;;;;;
+1E138;NYIAKENG PUACHUE HMONG SIGN FOR THING;Lm;0;L;;;;;N;;;;;
+1E139;NYIAKENG PUACHUE HMONG SIGN FOR LOCATION;Lm;0;L;;;;;N;;;;;
+1E13A;NYIAKENG PUACHUE HMONG SIGN FOR ANIMAL;Lm;0;L;;;;;N;;;;;
+1E13B;NYIAKENG PUACHUE HMONG SIGN FOR INVERTEBRATE;Lm;0;L;;;;;N;;;;;
+1E13C;NYIAKENG PUACHUE HMONG SIGN XW XW;Lm;0;L;;;;;N;;;;;
+1E13D;NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;
+1E140;NYIAKENG PUACHUE HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1E141;NYIAKENG PUACHUE HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1E142;NYIAKENG PUACHUE HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1E143;NYIAKENG PUACHUE HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1E144;NYIAKENG PUACHUE HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1E145;NYIAKENG PUACHUE HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1E146;NYIAKENG PUACHUE HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1E147;NYIAKENG PUACHUE HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1E148;NYIAKENG PUACHUE HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;;
+1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;;
+1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;;
+1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;;
+1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;;
+1E2C3;WANCHO LETTER CA;Lo;0;L;;;;;N;;;;;
+1E2C4;WANCHO LETTER DA;Lo;0;L;;;;;N;;;;;
+1E2C5;WANCHO LETTER GA;Lo;0;L;;;;;N;;;;;
+1E2C6;WANCHO LETTER YA;Lo;0;L;;;;;N;;;;;
+1E2C7;WANCHO LETTER PHA;Lo;0;L;;;;;N;;;;;
+1E2C8;WANCHO LETTER LA;Lo;0;L;;;;;N;;;;;
+1E2C9;WANCHO LETTER NA;Lo;0;L;;;;;N;;;;;
+1E2CA;WANCHO LETTER PA;Lo;0;L;;;;;N;;;;;
+1E2CB;WANCHO LETTER TA;Lo;0;L;;;;;N;;;;;
+1E2CC;WANCHO LETTER THA;Lo;0;L;;;;;N;;;;;
+1E2CD;WANCHO LETTER FA;Lo;0;L;;;;;N;;;;;
+1E2CE;WANCHO LETTER SA;Lo;0;L;;;;;N;;;;;
+1E2CF;WANCHO LETTER SHA;Lo;0;L;;;;;N;;;;;
+1E2D0;WANCHO LETTER JA;Lo;0;L;;;;;N;;;;;
+1E2D1;WANCHO LETTER ZA;Lo;0;L;;;;;N;;;;;
+1E2D2;WANCHO LETTER WA;Lo;0;L;;;;;N;;;;;
+1E2D3;WANCHO LETTER VA;Lo;0;L;;;;;N;;;;;
+1E2D4;WANCHO LETTER KA;Lo;0;L;;;;;N;;;;;
+1E2D5;WANCHO LETTER O;Lo;0;L;;;;;N;;;;;
+1E2D6;WANCHO LETTER AU;Lo;0;L;;;;;N;;;;;
+1E2D7;WANCHO LETTER RA;Lo;0;L;;;;;N;;;;;
+1E2D8;WANCHO LETTER MA;Lo;0;L;;;;;N;;;;;
+1E2D9;WANCHO LETTER KHA;Lo;0;L;;;;;N;;;;;
+1E2DA;WANCHO LETTER HA;Lo;0;L;;;;;N;;;;;
+1E2DB;WANCHO LETTER E;Lo;0;L;;;;;N;;;;;
+1E2DC;WANCHO LETTER I;Lo;0;L;;;;;N;;;;;
+1E2DD;WANCHO LETTER NGA;Lo;0;L;;;;;N;;;;;
+1E2DE;WANCHO LETTER U;Lo;0;L;;;;;N;;;;;
+1E2DF;WANCHO LETTER LLHA;Lo;0;L;;;;;N;;;;;
+1E2E0;WANCHO LETTER TSA;Lo;0;L;;;;;N;;;;;
+1E2E1;WANCHO LETTER TRA;Lo;0;L;;;;;N;;;;;
+1E2E2;WANCHO LETTER ONG;Lo;0;L;;;;;N;;;;;
+1E2E3;WANCHO LETTER AANG;Lo;0;L;;;;;N;;;;;
+1E2E4;WANCHO LETTER ANG;Lo;0;L;;;;;N;;;;;
+1E2E5;WANCHO LETTER ING;Lo;0;L;;;;;N;;;;;
+1E2E6;WANCHO LETTER ON;Lo;0;L;;;;;N;;;;;
+1E2E7;WANCHO LETTER EN;Lo;0;L;;;;;N;;;;;
+1E2E8;WANCHO LETTER AAN;Lo;0;L;;;;;N;;;;;
+1E2E9;WANCHO LETTER NYA;Lo;0;L;;;;;N;;;;;
+1E2EA;WANCHO LETTER UEN;Lo;0;L;;;;;N;;;;;
+1E2EB;WANCHO LETTER YIH;Lo;0;L;;;;;N;;;;;
+1E2EC;WANCHO TONE TUP;Mn;230;NSM;;;;;N;;;;;
+1E2ED;WANCHO TONE TUPNI;Mn;230;NSM;;;;;N;;;;;
+1E2EE;WANCHO TONE KOI;Mn;230;NSM;;;;;N;;;;;
+1E2EF;WANCHO TONE KOINI;Mn;230;NSM;;;;;N;;;;;
+1E2F0;WANCHO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1E2F1;WANCHO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1E2F2;WANCHO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1E2F3;WANCHO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1E2F4;WANCHO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1E2F5;WANCHO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1E2F6;WANCHO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1E2F7;WANCHO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
+1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;;
1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;
1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;
1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;
@@ -29108,6 +29449,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;
1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;;
+1E94B;ADLAM NASALIZATION MARK;Lm;0;R;;;;;N;;;;;
1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
@@ -29188,6 +29530,67 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1ECB2;INDIC SIYAQ NUMBER ALTERNATE TWO;No;0;AL;;;;2;N;;;;;
1ECB3;INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND;No;0;AL;;;;10000;N;;;;;
1ECB4;INDIC SIYAQ ALTERNATE LAKH MARK;No;0;AL;;;;100000;N;;;;;
+1ED01;OTTOMAN SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;;
+1ED02;OTTOMAN SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;;
+1ED03;OTTOMAN SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;;
+1ED04;OTTOMAN SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;;
+1ED05;OTTOMAN SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;;
+1ED06;OTTOMAN SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;;
+1ED07;OTTOMAN SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;;
+1ED08;OTTOMAN SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;;
+1ED09;OTTOMAN SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;;
+1ED0A;OTTOMAN SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;;
+1ED0B;OTTOMAN SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;;
+1ED0C;OTTOMAN SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;;
+1ED0D;OTTOMAN SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;;
+1ED0E;OTTOMAN SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;;
+1ED0F;OTTOMAN SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;;
+1ED10;OTTOMAN SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;;
+1ED11;OTTOMAN SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;;
+1ED12;OTTOMAN SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;;
+1ED13;OTTOMAN SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;;
+1ED14;OTTOMAN SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;;
+1ED15;OTTOMAN SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;;
+1ED16;OTTOMAN SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;;
+1ED17;OTTOMAN SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;;
+1ED18;OTTOMAN SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;;
+1ED19;OTTOMAN SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;;
+1ED1A;OTTOMAN SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;;
+1ED1B;OTTOMAN SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;;
+1ED1C;OTTOMAN SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;;
+1ED1D;OTTOMAN SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;;
+1ED1E;OTTOMAN SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;;
+1ED1F;OTTOMAN SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;;
+1ED20;OTTOMAN SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;;
+1ED21;OTTOMAN SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;;
+1ED22;OTTOMAN SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;;
+1ED23;OTTOMAN SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;;
+1ED24;OTTOMAN SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;;
+1ED25;OTTOMAN SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;;
+1ED26;OTTOMAN SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;;
+1ED27;OTTOMAN SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;;
+1ED28;OTTOMAN SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;;
+1ED29;OTTOMAN SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;;
+1ED2A;OTTOMAN SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;;
+1ED2B;OTTOMAN SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;;
+1ED2C;OTTOMAN SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;;
+1ED2D;OTTOMAN SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;;
+1ED2E;OTTOMAN SIYAQ MARRATAN;So;0;AL;;;;;N;;;;;
+1ED2F;OTTOMAN SIYAQ ALTERNATE NUMBER TWO;No;0;AL;;;;2;N;;;;;
+1ED30;OTTOMAN SIYAQ ALTERNATE NUMBER THREE;No;0;AL;;;;3;N;;;;;
+1ED31;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR;No;0;AL;;;;4;N;;;;;
+1ED32;OTTOMAN SIYAQ ALTERNATE NUMBER FIVE;No;0;AL;;;;5;N;;;;;
+1ED33;OTTOMAN SIYAQ ALTERNATE NUMBER SIX;No;0;AL;;;;6;N;;;;;
+1ED34;OTTOMAN SIYAQ ALTERNATE NUMBER SEVEN;No;0;AL;;;;7;N;;;;;
+1ED35;OTTOMAN SIYAQ ALTERNATE NUMBER EIGHT;No;0;AL;;;;8;N;;;;;
+1ED36;OTTOMAN SIYAQ ALTERNATE NUMBER NINE;No;0;AL;;;;9;N;;;;;
+1ED37;OTTOMAN SIYAQ ALTERNATE NUMBER TEN;No;0;AL;;;;10;N;;;;;
+1ED38;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;;
+1ED39;OTTOMAN SIYAQ ALTERNATE NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;;
+1ED3A;OTTOMAN SIYAQ ALTERNATE NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;;
+1ED3B;OTTOMAN SIYAQ ALTERNATE NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;;
+1ED3C;OTTOMAN SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;;
+1ED3D;OTTOMAN SIYAQ FRACTION ONE SIXTH;No;0;AL;;;;1/6;N;;;;;
1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;
1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;
1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;
@@ -29662,6 +30065,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;
1F16A;RAISED MC SIGN;So;0;ON;<super> 004D 0043;;;;N;;;;;
1F16B;RAISED MD SIGN;So;0;ON;<super> 004D 0044;;;;N;;;;;
+1F16C;RAISED MR SIGN;So;0;ON;<super> 004D 0052;;;;N;;;;;
1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;
1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;
1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;
@@ -30794,6 +31198,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;;
1F6D3;STUPA;So;0;ON;;;;;N;;;;;
1F6D4;PAGODA;So;0;ON;;;;;N;;;;;
+1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;
1F6E1;SHIELD;So;0;ON;;;;;N;;;;;
1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;
@@ -30817,6 +31222,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F6F7;SLED;So;0;ON;;;;;N;;;;;
1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;;
1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;;
+1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;;
1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;
1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;
1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;
@@ -31022,6 +31428,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;
1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
+1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;;
+1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;;
+1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;;
+1F7E3;LARGE PURPLE CIRCLE;So;0;ON;;;;;N;;;;;
+1F7E4;LARGE BROWN CIRCLE;So;0;ON;;;;;N;;;;;
+1F7E5;LARGE RED SQUARE;So;0;ON;;;;;N;;;;;
+1F7E6;LARGE BLUE SQUARE;So;0;ON;;;;;N;;;;;
+1F7E7;LARGE ORANGE SQUARE;So;0;ON;;;;;N;;;;;
+1F7E8;LARGE YELLOW SQUARE;So;0;ON;;;;;N;;;;;
+1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;;
+1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;;
+1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;;
1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;
@@ -31182,6 +31600,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;;
1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;;
1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;;
+1F90D;WHITE HEART;So;0;ON;;;;;N;;;;;
+1F90E;BROWN HEART;So;0;ON;;;;;N;;;;;
+1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;;
1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;;
1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;;
1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;;
@@ -31229,6 +31650,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F93C;WRESTLERS;So;0;ON;;;;;N;;;;;
1F93D;WATER POLO;So;0;ON;;;;;N;;;;;
1F93E;HANDBALL;So;0;ON;;;;;N;;;;;
+1F93F;DIVING MASK;So;0;ON;;;;;N;;;;;
1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;;
1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;;
1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;;
@@ -31278,11 +31700,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F96E;MOON CAKE;So;0;ON;;;;;N;;;;;
1F96F;BAGEL;So;0;ON;;;;;N;;;;;
1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;;
+1F971;YAWNING FACE;So;0;ON;;;;;N;;;;;
1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;;
1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;;
1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;;
1F976;FREEZING FACE;So;0;ON;;;;;N;;;;;
1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;;
+1F97B;SARI;So;0;ON;;;;;N;;;;;
1F97C;LAB COAT;So;0;ON;;;;;N;;;;;
1F97D;GOGGLES;So;0;ON;;;;;N;;;;;
1F97E;HIKING BOOT;So;0;ON;;;;;N;;;;;
@@ -31322,6 +31746,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F9A0;MICROBE;So;0;ON;;;;;N;;;;;
1F9A1;BADGER;So;0;ON;;;;;N;;;;;
1F9A2;SWAN;So;0;ON;;;;;N;;;;;
+1F9A5;SLOTH;So;0;ON;;;;;N;;;;;
+1F9A6;OTTER;So;0;ON;;;;;N;;;;;
+1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;;
+1F9A8;SKUNK;So;0;ON;;;;;N;;;;;
+1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;;
+1F9AA;OYSTER;So;0;ON;;;;;N;;;;;
+1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;;
+1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;;
1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;;
1F9B1;EMOJI COMPONENT CURLY HAIR;So;0;ON;;;;;N;;;;;
1F9B2;EMOJI COMPONENT BALD;So;0;ON;;;;;N;;;;;
@@ -31332,9 +31764,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F9B7;TOOTH;So;0;ON;;;;;N;;;;;
1F9B8;SUPERHERO;So;0;ON;;;;;N;;;;;
1F9B9;SUPERVILLAIN;So;0;ON;;;;;N;;;;;
+1F9BA;SAFETY VEST;So;0;ON;;;;;N;;;;;
+1F9BB;EAR WITH HEARING AID;So;0;ON;;;;;N;;;;;
+1F9BC;MOTORIZED WHEELCHAIR;So;0;ON;;;;;N;;;;;
+1F9BD;MANUAL WHEELCHAIR;So;0;ON;;;;;N;;;;;
+1F9BE;MECHANICAL ARM;So;0;ON;;;;;N;;;;;
+1F9BF;MECHANICAL LEG;So;0;ON;;;;;N;;;;;
1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;;
1F9C1;CUPCAKE;So;0;ON;;;;;N;;;;;
1F9C2;SALT SHAKER;So;0;ON;;;;;N;;;;;
+1F9C3;BEVERAGE BOX;So;0;ON;;;;;N;;;;;
+1F9C4;GARLIC;So;0;ON;;;;;N;;;;;
+1F9C5;ONION;So;0;ON;;;;;N;;;;;
+1F9C6;FALAFEL;So;0;ON;;;;;N;;;;;
+1F9C7;WAFFLE;So;0;ON;;;;;N;;;;;
+1F9C8;BUTTER;So;0;ON;;;;;N;;;;;
+1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;;
+1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;;
+1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;;
+1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;;
+1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;;
1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;;
1F9D1;ADULT;So;0;ON;;;;;N;;;;;
1F9D2;CHILD;So;0;ON;;;;;N;;;;;
@@ -31383,6 +31832,90 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F9FD;SPONGE;So;0;ON;;;;;N;;;;;
1F9FE;RECEIPT;So;0;ON;;;;;N;;;;;
1F9FF;NAZAR AMULET;So;0;ON;;;;;N;;;;;
+1FA00;NEUTRAL CHESS KING;So;0;ON;;;;;N;;;;;
+1FA01;NEUTRAL CHESS QUEEN;So;0;ON;;;;;N;;;;;
+1FA02;NEUTRAL CHESS ROOK;So;0;ON;;;;;N;;;;;
+1FA03;NEUTRAL CHESS BISHOP;So;0;ON;;;;;N;;;;;
+1FA04;NEUTRAL CHESS KNIGHT;So;0;ON;;;;;N;;;;;
+1FA05;NEUTRAL CHESS PAWN;So;0;ON;;;;;N;;;;;
+1FA06;WHITE CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA07;BLACK CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA08;NEUTRAL CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA09;WHITE CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0A;WHITE CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0B;WHITE CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0C;WHITE CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0D;WHITE CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0E;WHITE CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA0F;BLACK CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA10;BLACK CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA11;BLACK CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA12;BLACK CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA13;BLACK CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA14;BLACK CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA15;NEUTRAL CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA16;NEUTRAL CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA17;NEUTRAL CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA18;NEUTRAL CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA19;NEUTRAL CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA1A;NEUTRAL CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA1B;WHITE CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA1C;BLACK CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA1D;NEUTRAL CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA1E;WHITE CHESS TURNED KING;So;0;ON;;;;;N;;;;;
+1FA1F;WHITE CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;
+1FA20;WHITE CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;
+1FA21;WHITE CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;
+1FA22;WHITE CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;
+1FA23;WHITE CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;
+1FA24;BLACK CHESS TURNED KING;So;0;ON;;;;;N;;;;;
+1FA25;BLACK CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;
+1FA26;BLACK CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;
+1FA27;BLACK CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;
+1FA28;BLACK CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;
+1FA29;BLACK CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;
+1FA2A;NEUTRAL CHESS TURNED KING;So;0;ON;;;;;N;;;;;
+1FA2B;NEUTRAL CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;
+1FA2C;NEUTRAL CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;
+1FA2D;NEUTRAL CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;
+1FA2E;NEUTRAL CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;
+1FA2F;NEUTRAL CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;
+1FA30;WHITE CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA31;BLACK CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA32;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;
+1FA33;WHITE CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA34;WHITE CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA35;WHITE CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA36;WHITE CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA37;WHITE CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA38;WHITE CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA39;BLACK CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3A;BLACK CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3B;BLACK CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3C;BLACK CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3D;BLACK CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3E;BLACK CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA3F;NEUTRAL CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA40;NEUTRAL CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA41;NEUTRAL CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA42;NEUTRAL CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA43;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA44;NEUTRAL CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;
+1FA45;WHITE CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;
+1FA46;BLACK CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;
+1FA47;NEUTRAL CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;
+1FA48;WHITE CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;
+1FA49;BLACK CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;
+1FA4A;NEUTRAL CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;
+1FA4B;WHITE CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA4C;BLACK CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA4D;NEUTRAL CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;
+1FA4E;WHITE CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;;
+1FA4F;WHITE CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;;
+1FA50;WHITE CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;;
+1FA51;BLACK CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;;
+1FA52;BLACK CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;;
+1FA53;BLACK CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;;
1FA60;XIANGQI RED GENERAL;So;0;ON;;;;;N;;;;;
1FA61;XIANGQI RED MANDARIN;So;0;ON;;;;;N;;;;;
1FA62;XIANGQI RED ELEPHANT;So;0;ON;;;;;N;;;;;
@@ -31397,6 +31930,22 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FA6B;XIANGQI BLACK CHARIOT;So;0;ON;;;;;N;;;;;
1FA6C;XIANGQI BLACK CANNON;So;0;ON;;;;;N;;;;;
1FA6D;XIANGQI BLACK SOLDIER;So;0;ON;;;;;N;;;;;
+1FA70;BALLET SHOES;So;0;ON;;;;;N;;;;;
+1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;;
+1FA72;BRIEFS;So;0;ON;;;;;N;;;;;
+1FA73;SHORTS;So;0;ON;;;;;N;;;;;
+1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
+1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
+1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;
+1FA80;YO-YO;So;0;ON;;;;;N;;;;;
+1FA81;KITE;So;0;ON;;;;;N;;;;;
+1FA82;PARACHUTE;So;0;ON;;;;;N;;;;;
+1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;
+1FA91;CHAIR;So;0;ON;;;;;N;;;;;
+1FA92;RAZOR;So;0;ON;;;;;N;;;;;
+1FA93;AXE;So;0;ON;;;;;N;;;;;
+1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;;
+1FA95;BANJO;So;0;ON;;;;;N;;;;;
20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/confusables.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/confusables.txt
index 0b8c1c5ff..ee85eeeef 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/confusables.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/unicode/confusables.txt
@@ -1,11 +1,11 @@
# confusables.txt
-# Date: 2018-03-13, 10:46:37 GMT
-# © 2018 Unicode®, Inc.
+# Date: 2019-04-01, 21:59:19 GMT
+# © 2019 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
#
# Unicode Security Mechanisms for UTS #39
-# Version: 11.0.0
+# Version: 12.1.0
#
# For documentation and usage, see http://www.unicode.org/reports/tr39
#
@@ -2353,7 +2353,7 @@ A6B1 ; 2C75 ; MA # ( ꚱ → Ⱶ ) BAMUM LETTER NDAA → LATIN CAPITAL LETTER HA
A795 ; A727 ; MA # ( ꞕ → ꜧ ) LATIN SMALL LETTER H WITH PALATAL HOOK → LATIN SMALL LETTER HENG #
02DB ; 0069 ; MA #* ( ˛ → i ) OGONEK → LATIN SMALL LETTER I # →ͺ→→ι→→ι→
-2373 ; 0069 ; MA #* ( ⍳ → i ) APL FUNCTIONAL SYMBOL IOTA → LATIN SMALL LETTER I # →ɩ→
+2373 ; 0069 ; MA #* ( ⍳ → i ) APL FUNCTIONAL SYMBOL IOTA → LATIN SMALL LETTER I # →ι→
FF49 ; 0069 ; MA # ( i → i ) FULLWIDTH LATIN SMALL LETTER I → LATIN SMALL LETTER I # →і→
2170 ; 0069 ; MA # ( ⅰ → i ) SMALL ROMAN NUMERAL ONE → LATIN SMALL LETTER I #
2139 ; 0069 ; MA # ( ℹ → i ) INFORMATION SOURCE → LATIN SMALL LETTER I #
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_64BitBCD.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_64BitBCD.java
index 54f5cec9a..ea84162a9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_64BitBCD.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_64BitBCD.java
@@ -82,6 +82,12 @@ public final class DecimalQuantity_64BitBCD extends DecimalQuantity_AbstractBCD
}
@Override
+ protected void popFromLeft(int numDigits) {
+ bcd &= (1L << ((precision - numDigits) * 4)) - 1;
+ precision -= numDigits;
+ }
+
+ @Override
protected void setBcdToZero() {
bcd = 0L;
scale = 0;
@@ -173,11 +179,9 @@ public final class DecimalQuantity_64BitBCD extends DecimalQuantity_AbstractBCD
@Override
public String toString() {
return String.format(
- "<DecimalQuantity2 %s:%d:%d:%s %016XE%d>",
- (lOptPos > 1000 ? "max" : String.valueOf(lOptPos)),
+ "<DecimalQuantity2 %d:%d %016XE%d>",
lReqPos,
rReqPos,
- (rOptPos < -1000 ? "min" : String.valueOf(rOptPos)),
bcd,
scale);
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_ByteArrayBCD.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_ByteArrayBCD.java
index 7012e8452..de87080b7 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_ByteArrayBCD.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_ByteArrayBCD.java
@@ -94,6 +94,15 @@ public final class DecimalQuantity_ByteArrayBCD extends DecimalQuantity_Abstract
}
@Override
+ protected void popFromLeft(int numDigits) {
+ int i = precision - 1;
+ for (; i >= precision - numDigits; i--) {
+ bcd[i] = 0;
+ }
+ precision -= numDigits;
+ }
+
+ @Override
protected void setBcdToZero() {
for (int i = 0; i < precision; i++) {
bcd[i] = (byte) 0;
@@ -221,11 +230,9 @@ public final class DecimalQuantity_ByteArrayBCD extends DecimalQuantity_Abstract
sb.append(bcd[i]);
}
return String.format(
- "<DecimalQuantity3 %s:%d:%d:%s %s%s%d>",
- (lOptPos > 1000 ? "max" : String.valueOf(lOptPos)),
+ "<DecimalQuantity3 %d:%d %s%s%d>",
lReqPos,
rReqPos,
- (rOptPos < -1000 ? "min" : String.valueOf(rOptPos)),
sb,
"E",
scale);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
index 64cb95552..994ca998e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/impl/number/DecimalQuantity_SimpleStorage.java
@@ -319,37 +319,39 @@ public class DecimalQuantity_SimpleStorage implements DecimalQuantity {
}
@Override
- public void setIntegerLength(int minInt, int maxInt) {
+ public void setMinInteger(int minInt) {
// Graceful failures for bogus input
minInt = Math.max(0, minInt);
- maxInt = Math.max(0, maxInt);
-
- // The minima must be less than or equal to the maxima
- if (maxInt < minInt) {
- minInt = maxInt;
- }
// Save values into internal state
// Negation is safe for minFrac/maxFrac because -Integer.MAX_VALUE > Integer.MIN_VALUE
- lOptPos = maxInt;
lReqPos = minInt;
}
@Override
- public void setFractionLength(int minFrac, int maxFrac) {
+ public void setMinFraction(int minFrac) {
// Graceful failures for bogus input
minFrac = Math.max(0, minFrac);
- maxFrac = Math.max(0, maxFrac);
-
- // The minima must be less than or equal to the maxima
- if (maxFrac < minFrac) {
- minFrac = maxFrac;
- }
// Save values into internal state
// Negation is safe for minFrac/maxFrac because -Integer.MAX_VALUE > Integer.MIN_VALUE
rReqPos = -minFrac;
- rOptPos = -maxFrac;
+ }
+
+ @Override
+ public void applyMaxInteger(int maxInt) {
+ BigDecimal d;
+ if (primary != -1) {
+ d = BigDecimal.valueOf(primary).scaleByPowerOfTen(primaryScale);
+ } else {
+ d = fallback;
+ }
+ d = d.scaleByPowerOfTen(-maxInt).remainder(BigDecimal.ONE).scaleByPowerOfTen(maxInt);
+ if (primary != -1) {
+ primary = d.scaleByPowerOfTen(-primaryScale).longValueExact();
+ } else {
+ fallback = d;
+ }
}
@Override
@@ -364,6 +366,12 @@ public class DecimalQuantity_SimpleStorage implements DecimalQuantity {
}
@Override
+ public void roundToNickel(int roundingMagnitude, MathContext mathContext) {
+ BigDecimal nickel = BigDecimal.valueOf(5).scaleByPowerOfTen(roundingMagnitude);
+ roundToIncrement(nickel, mathContext);
+ }
+
+ @Override
public void roundToMagnitude(int roundingMagnitude, MathContext mathContext) {
if (roundingMagnitude < -1000) {
roundToInfinity();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegressionTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegressionTest.java
index 134d170c1..8f73d1621 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegressionTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegressionTest.java
@@ -2150,36 +2150,32 @@ public class CalendarRegressionTest extends com.ibm.icu.dev.test.TestFmwk {
Locale loc = new Locale("en", "TH");
Calendar cal = Calendar.getInstance(loc);
String calType = cal.getType();
- // Android patch: Force default Gregorian calendar.
- if ( !calType.equals("gregorian")) {
- errln("FAIL: Calendar type for en_TH should still be gregorian");
+ if ( !calType.equals("buddhist")) {
+ errln("FAIL: Calendar type for en_TH should still be buddhist");
}
- // Android patch end.
}
@Test
public void TestGetKeywordValuesForLocale(){
- // Android patch: Force default Gregorian calendar.
final String[][] PREFERRED = {
{"root", "gregorian"},
{"und", "gregorian"},
{"en_US", "gregorian"},
{"en_029", "gregorian"},
- {"th_TH", "gregorian", "buddhist"},
- {"und_TH", "gregorian", "buddhist"},
- {"en_TH", "gregorian", "buddhist"},
+ {"th_TH", "buddhist", "gregorian"},
+ {"und_TH", "buddhist", "gregorian"},
+ {"en_TH", "buddhist", "gregorian"},
{"he_IL", "gregorian", "hebrew", "islamic", "islamic-civil", "islamic-tbla"},
{"ar_EG", "gregorian", "coptic", "islamic", "islamic-civil", "islamic-tbla"},
{"ja", "gregorian", "japanese"},
{"ps_Guru_IN", "gregorian", "indian"},
- {"th@calendar=gregorian", "gregorian", "buddhist"},
+ {"th@calendar=gregorian", "buddhist", "gregorian"},
{"en@calendar=islamic", "gregorian"},
{"zh_TW", "gregorian", "roc", "chinese"},
- {"ar_IR", "gregorian", "persian", "islamic", "islamic-civil", "islamic-tbla"},
- {"th@rg=SAZZZZ", "gregorian", "islamic-umalqura", "islamic", "islamic-rgsa"},
+ {"ar_IR", "persian", "gregorian", "islamic", "islamic-civil", "islamic-tbla"},
+ {"th@rg=SAZZZZ", "islamic-umalqura", "gregorian", "islamic", "islamic-rgsa"},
};
- // Android patch end.
String[] ALL = Calendar.getKeywordValuesForLocale("calendar", ULocale.getDefault(), false);
HashSet ALLSET = new HashSet();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java
index 7a1e6fcf8..c2cf6e11d 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java
@@ -12,7 +12,6 @@ import com.ibm.icu.impl.EraRules;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.JapaneseCalendar;
import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.TimeZone;
/**
* Tests for EraRules class
@@ -45,8 +44,7 @@ public class EraRulesTest extends TestFmwk {
+ calId);
}
- // Android-changed: EraRules.getCurrentEraIndex() uses UTC time. http://b/131766004
- Calendar cal = Calendar.getInstance(TimeZone.GMT_ZONE, new ULocale("en"));
+ Calendar cal = Calendar.getInstance(new ULocale("en"));
int currentIdx = rules1.getCurrentEraIndex();
int currentYear = cal.get(Calendar.YEAR);
int idx = rules1.getEraIndex(currentYear, cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE));
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java
index bec3b0e16..03e6a0c74 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java
@@ -332,11 +332,9 @@ public class IBMCalendarTest extends CalendarTestFmwk {
// Thai locale
Calendar cal = Calendar.getInstance(new ULocale("th_TH"));
String type = cal.getType();
- // Android patch: Force default Gregorian calendar.
- if (!type.equals("gregorian")) {
- errln("FAIL: Gregorian calendar is not returned for locale " + cal.toString());
+ if (!type.equals("buddhist")) {
+ errln("FAIL: Buddhist calendar is not returned for locale " + cal.toString());
}
- // Android patch end.
}
/**
@@ -1088,7 +1086,6 @@ public class IBMCalendarTest extends CalendarTestFmwk {
"ja_JP@calendar=japanese",
"th_TH@calendar=buddhist",
"th-TH-u-ca-gregory",
- "ja_JP_TRADITIONAL",
"th_TH_TRADITIONAL",
"th_TH_TRADITIONAL@calendar=gregorian",
"en_US",
@@ -1104,7 +1101,6 @@ public class IBMCalendarTest extends CalendarTestFmwk {
"th@rg=SA", // ignore malformed rg tag, use buddhist
};
- // Android patch: Force default Gregorian calendar.
String[] types = {
"gregorian",
"japanese",
@@ -1112,22 +1108,20 @@ public class IBMCalendarTest extends CalendarTestFmwk {
"japanese",
"buddhist",
"gregorian",
- "japanese",
"buddhist",
"gregorian",
"gregorian",
- "gregorian",
- "gregorian",
- "gregorian",
+ "buddhist",
+ "buddhist",
+ "buddhist",
"gregorian", // iso8601 is a gregorian sub type
"gregorian",
- "gregorian",
- "gregorian",
+ "islamic-umalqura",
+ "islamic-umalqura",
"japanese",
- "gregorian",
- "gregorian",
+ "buddhist",
+ "buddhist",
};
- // Android patch end.
for (int i = 0; i < locs.length; i++) {
Calendar cal = Calendar.getInstance(new ULocale(locs[i]));
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/JapaneseTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/JapaneseTest.java
index 1c90f3ac2..26d204dcc 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/JapaneseTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/JapaneseTest.java
@@ -19,6 +19,7 @@ import org.junit.runners.JUnit4;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.DateTimePatternGenerator;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.JapaneseCalendar;
@@ -150,13 +151,17 @@ public class JapaneseTest extends CalendarTestFmwk {
@Test
public void Test3860()
{
+ final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here.
+ final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei era (Heisei year 1 Jan 8)
+ // or the new era in Gregorian 2019 (new era year 1 May 1). If before the accession date,
+ // the year will be in the previous era.
ULocale loc = new ULocale("ja_JP@calendar=japanese");
Calendar cal = new JapaneseCalendar(loc);
- DateFormat enjformat = cal.getDateTimeFormat(0,0,new ULocale("en_JP@calendar=japanese"));
- DateFormat format = cal.getDateTimeFormat(0,0,loc);
- ((SimpleDateFormat)format).applyPattern("y/M/d"); // Note: just 'y' doesn't work here.
+ DateFormat enjformat = cal.getDateTimeFormat(DateFormat.FULL,DateFormat.FULL,new ULocale("en_JP@calendar=japanese"));
+ DateFormat format = cal.getDateTimeFormat(DateFormat.SHORT,DateFormat.SHORT,loc); // SHORT => no jpanyear since we will apply a short pattern
+ ((SimpleDateFormat)format).applyPattern(jCalShortPattern);
ParsePosition pos = new ParsePosition(0);
- Date aDate = format.parse("1/5/9", pos); // after the start of Reiwa accession. Jan 1, R1 wouldn't work because it is actually Heisei 31
+ Date aDate = format.parse(jCalGannenDate, pos);
String inEn = enjformat.format(aDate);
cal.clear();
@@ -165,7 +170,7 @@ public class JapaneseTest extends CalendarTestFmwk {
int gotEra = cal.get(Calendar.ERA);
int expectYear = 1;
- int expectEra = JapaneseCalendar.CURRENT_ERA; // Reiwa
+ int expectEra = JapaneseCalendar.CURRENT_ERA;
if((gotYear != expectYear) || (gotEra != expectEra)) {
errln("Expected year " + expectYear + ", era " + expectEra +", but got year " + gotYear + " and era " + gotEra + ", == " + inEn);
@@ -173,7 +178,7 @@ public class JapaneseTest extends CalendarTestFmwk {
logln("Got year " + gotYear + " and era " + gotEra + ", == " + inEn);
}
- // Test parse with missing era (should default to current era)
+ // Test parse with missing era (should default to current era, heisei)
// Test parse with incomplete information
logln("Testing parse w/ just year...");
Calendar cal2 = new JapaneseCalendar(loc);
@@ -197,13 +202,79 @@ public class JapaneseTest extends CalendarTestFmwk {
gotYear = cal2.get(Calendar.YEAR);
gotEra = cal2.get(Calendar.ERA);
expectYear = 1;
- expectEra = JapaneseCalendar.CURRENT_ERA; // Reiwa
+ expectEra = JapaneseCalendar.CURRENT_ERA;
if((gotYear != 1) || (gotEra != expectEra)) {
errln("parse "+ samplestr + " of 'y' as Japanese Calendar, expected year " + expectYear +
" and era " + expectEra + ", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
} else {
logln(" year: " + gotYear + ", era: " + gotEra);
}
+
+ // Tests for formats with gannen numbering Gy年
+ pos.setIndex(0);
+ aDate = format.parse(jCalGannenDate, pos); // reset
+ DateFormat fmtWithGannen = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, loc);
+ String aString = fmtWithGannen.format(aDate);
+ if (aString.charAt(2) != '\u5143') { // 元
+ errln("Formatting year 1 as Gannen, got " + aString + " but expected 3rd char to be \u5143");
+ } else {
+ // Replace 元 with 1 and parse the result
+ String bString = aString.replace('\u5143', '1');
+ try {
+ Date bDate = fmtWithGannen.parse(bString);
+ bString = fmtWithGannen.format(bDate);
+ if (!bString.equals(aString)) {
+ errln("Parsing 1 when expecting \u5143, formatting the result produced " + bString + " but expected " + aString);
+ }
+ } catch (ParseException pe) {
+ errln("Exception parsing 1 when expecting \u5143 in string " + bString);
+ }
+ }
+ }
+
+ @Test
+ public void TestForceGannenNumbering() {
+ final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here.
+ final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei [1989-] era (Heisei year 1 Jan 8)
+ // or Reiwa [2019-] era (Reiwa year 1 May 1). If before the accession date,
+ // the year will be in the previous era.
+ ULocale loc = new ULocale("ja_JP@calendar=japanese");
+ Date refDate = new Date(600336000000L); // 1989 Jan 9 Monday = Heisei 1
+ final String patText = "Gy年M月d日";
+ final String patNumr = "GGGGGy/MM/dd";
+ final String skelText = "yMMMM";
+
+ // Test Gannen year forcing
+ SimpleDateFormat testFmt1 = new SimpleDateFormat(patText, loc);
+ SimpleDateFormat testFmt2 = new SimpleDateFormat(patNumr, loc);
+ String testString1 = testFmt1.format(refDate);
+ if (testString1.length() < 3 || testString1.charAt(2) != '\u5143') { // 元
+ errln("Formatting year 1 in created text style, got " + testString1 + " but expected 3rd char to be \u5143");
+ }
+ String testString2 = testFmt2.format(refDate);
+ if (testString2.length() < 2 || testString2.charAt(1) != '1') {
+ errln("Formatting year 1 in created numeric style, got " + testString2 + " but expected 2nd char to be 1");
+ }
+ // Now switch the patterns and verify that Gannen use follows the pattern
+ testFmt1.applyPattern(patNumr);
+ testString1 = testFmt1.format(refDate);
+ if (testString1.length() < 2 || testString1.charAt(1) != '1') { //
+ errln("Formatting year 1 in applied numeric style, got " + testString1 + " but expected 2nd char to be 1");
+ }
+ testFmt2.applyPattern(patText);
+ testString2 = testFmt2.format(refDate);
+ if (testString2.length() < 3 || testString2.charAt(2) != '\u5143') { // 元
+ errln("Formatting year 1 in applied text style, got " + testString2 + " but expected 3rd char to be \u5143");
+ }
+
+ // Test disabling of Gannen year forcing
+ DateTimePatternGenerator dtpgen = DateTimePatternGenerator.getInstance(loc);
+ String pattern = dtpgen.getBestPattern(skelText);
+ SimpleDateFormat testFmt3 = new SimpleDateFormat(pattern, "", loc); // empty override string to disable Gannen year numbering
+ String testString3 = testFmt3.format(refDate);
+ if (testString3.length() < 3 || testString3.charAt(2) != '1') {
+ errln("Formatting year 1 with Gannen disabled, got " + testString3 + " but expected 3rd char to be 1");
+ }
}
@Test
@@ -379,29 +450,32 @@ public class JapaneseTest extends CalendarTestFmwk {
doLimitsTest(jcal, null, cal.getTime());
doTheoreticalLimitsTest(jcal, true);
}
-
- public void TestHeiseiToReiwa() {
- Calendar cal = Calendar.getInstance();
- cal.set(2019, Calendar.APRIL, 29);
-
- DateFormat jfmt = DateFormat.getDateInstance(DateFormat.LONG, new ULocale("ja@calendar=japanese"));
- final String[] EXPECTED_FORMAT = {
- "\u5E73\u621031\u5E744\u670829\u65E5", // Heisei 31 April 29
- "\u5E73\u621031\u5E744\u670830\u65E5", // Heisei 31 April 30
- "\u4EE4\u548C1\u5E745\u67081\u65E5", // Reiwa 1 May 1
- "\u4EE4\u548C1\u5E745\u67082\u65E5", // Reiwa 1 May 2
- };
-
- for (int i = 0; i < EXPECTED_FORMAT.length; i++) {
- Date d = cal.getTime();
- String dateStr = jfmt.format(d);
- if (!EXPECTED_FORMAT[i].equals(dateStr)) {
- errln("Formatting year:" + cal.get(Calendar.YEAR) + " month:" + (cal.get(Calendar.MONTH) + 1)
- + " day:" + cal.get(Calendar.DATE) + " - expected: " + EXPECTED_FORMAT[i]
- + " / actual: " + dateStr);
+ // The following currently assumes that Reiwa is the last known/valid era.
+ // Filed ICU-20551 to generalize this when we have more time...
+ @Test
+ public void TestJpnCalAddSetNextEra() {
+ final JapaneseCalendar jCal = new JapaneseCalendar();
+ jCal.clear(); // This sets to 1970 in Showa
+
+ final int sEra = jCal.get(Calendar.ERA); // Don't assume era number for Showa
+ final int[] startYears = { 1926, 1989, 2019, 0 }; // start years for Show, Heisei, Reiwa; 0 marks invalid era beyond
+
+ for (int iEra = 1; iEra < 3; iEra++) {
+ jCal.clear();
+ jCal.set(Calendar.ERA, sEra + iEra);
+ int eYear = jCal.get(Calendar.EXTENDED_YEAR);
+ if (eYear != startYears[iEra]) {
+ errln("ERROR: set " + iEra + ", expected start year " + startYears[iEra] + " but get " + eYear);
+ } else {
+ jCal.add(Calendar.ERA, 1);
+ eYear = jCal.get(Calendar.EXTENDED_YEAR);
+ int nextEraStart = (startYears[iEra + 1] == 0) ? startYears[iEra] : startYears[iEra + 1];
+ if (eYear != nextEraStart) {
+ errln("ERROR: set " + iEra + " then add ERA 1, expected start year " + nextEraStart
+ + " but get " + eYear);
+ }
}
- cal.add(Calendar.DATE, 1);
}
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java
index 350a9f4f2..83826ec41 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatRegressionTest.java
@@ -1239,6 +1239,38 @@ public class DateFormatRegressionTest extends TestFmwk {
}
@Test
+ public void Test12902_yWithGregoCalInThaiLoc() {
+ final Date testDate = new Date(43200000); // 1970-Jan-01 12:00 GMT
+ final String skeleton = "y";
+ // Note that in locale "th", the availableFormats for skeleton "y" differ by calendar:
+ // for buddhist (default calendar): y{"G y"}
+ // for gregorian: y{"y"}
+ final String expectFormat = "1970"; // format for skeleton y in Thai locale with Gregorian calendar
+
+ GregorianCalendar pureGregorianCalendar = new GregorianCalendar(TimeZone.GMT_ZONE, ULocale.ENGLISH);
+ pureGregorianCalendar.setGregorianChange(new Date(Long.MIN_VALUE)); // Per original bug, but not relevant
+ DateFormat df1 = DateFormat.getPatternInstance(pureGregorianCalendar, skeleton, ULocale.forLanguageTag("th"));
+ try {
+ String getFormat = df1.format(testDate);
+ if (!getFormat.equals(expectFormat)) {
+ errln("Error in DateFormat.format for th with Grego cal, expect: " + expectFormat + ", get: " + getFormat);
+ }
+ } catch (Exception e) {
+ errln("Fail in DateFormat.format for th with Grego cal: " + e);
+ }
+
+ DateFormat df2 = DateFormat.getPatternInstance(skeleton, new ULocale("th-u-ca-gregory"));
+ try {
+ String getFormat = df2.format(testDate);
+ if (!getFormat.equals(expectFormat)) {
+ errln("Error in DateFormat.format for th-u-ca-gregory, expect: " + expectFormat + ", get: " + getFormat);
+ }
+ } catch (Exception e) {
+ errln("Fail in DateFormat.format for th-u-ca-gregory: " + e);
+ }
+ }
+
+ @Test
public void TestT10110() {
try {
SimpleDateFormat formatter = new SimpleDateFormat("Gy年M月d日E", new Locale("zh_Hans"));
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
index 8797c5009..461552c21 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java
@@ -3029,10 +3029,10 @@ public class DateFormatTest extends TestFmwk {
String CA_DATA[] = {
"yyyy MM dd HH:mm:ss",
- "h:mm a", "2015 01 01 10:00:00", "10:00 a. m.",
- "h:mm a", "2015 01 01 22:00:00", "10:00 p. m.",
- "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a. m.",
- "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p. m.",
+ "h:mm a", "2015 01 01 10:00:00", "10:00 a.\u00A0m.",
+ "h:mm a", "2015 01 01 22:00:00", "10:00 p.\u00A0m.",
+ "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a.\u00A0m.",
+ "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p.\u00A0m.",
};
expectFormat(EN_DATA, new Locale("en", "", ""));
@@ -5214,7 +5214,7 @@ public class DateFormatTest extends TestFmwk {
sdf.setTimeZone(TimeZone.GMT_ZONE);
sdf.applyPattern("hh:mm:ss BBBB");
- assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", "01:00:00 de la mañana", sdf.format(k010000));
+ assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", "01:00:00 a.\u00A0m.", sdf.format(k010000));
sdf = new SimpleDateFormat("", new ULocale("es"));
sdf.setTimeZone(TimeZone.GMT_ZONE);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
index dafe99a78..bbf442306 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateIntervalFormatTest.java
@@ -32,11 +32,13 @@ import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateIntervalFormat;
+import com.ibm.icu.text.DateIntervalFormat.FormattedDateInterval;
import com.ibm.icu.text.DateIntervalInfo;
import com.ibm.icu.text.DateIntervalInfo.PatternInfo;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.DateInterval;
+import com.ibm.icu.util.JapaneseCalendar;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
@@ -60,657 +62,688 @@ public class DateIntervalFormatTest extends TestFmwk {
public void TestFormat() {
// first item is date pattern
// followed by a group of locale/from_data/to_data/skeleton/interval_data
+ // Note that from_data/to_data are specified using era names from root, for the calendar specified by locale.
String[] DATA = {
- "yyyy MM dd HH:mm:ss",
+ "GGGGG y MM dd HH:mm:ss", // pattern for from_data/to_data
// test root
- "root", "2007 11 10 10:10:10", "2007 12 10 10:10:10", "yM", "2007-11 \\u2013 2007-12",
+ "root", "CE 2007 11 10 10:10:10", "CE 2007 12 10 10:10:10", "yM", "2007-11 \\u2013 2007-12",
// test 'H' and 'h', using availableFormat in fallback
- "en", "2007 11 10 10:10:10", "2007 11 10 15:10:10", "Hms", "10:10:10 \\u2013 15:10:10",
- "en", "2007 11 10 10:10:10", "2007 11 10 15:10:10", "hms", "10:10:10 AM \\u2013 3:10:10 PM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "Hms", "10:10:10 \\u2013 15:10:10",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "hms", "10:10:10 AM \\u2013 3:10:10 PM",
// test skeleton with both date and time
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 AM \\u2013 Nov 20, 2007, 10:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 AM \\u2013 Nov 20, 2007, 10:10 AM",
- "en", "2007 11 10 10:10:10", "2007 11 10 11:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 \\u2013 11:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 \\u2013 11:10 AM",
- "en", "2007 11 10 10:10:10", "2007 11 10 11:10:10", "hms", "10:10:10 AM \\u2013 11:10:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "hms", "10:10:10 AM \\u2013 11:10:10 AM",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMMy", "October 10, 2007 \\u2013 October 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMy", "October 10, 2007 \\u2013 October 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMM", "October 10, 2007 \\u2013 October 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMM", "October 10, 2007 \\u2013 October 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMMy", "October 2007 \\u2013 October 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMMy", "October 2007 \\u2013 October 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMMMy", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMMy", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMy", "Oct 10, 2007 \\u2013 Oct 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMy", "Oct 10, 2007 \\u2013 Oct 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMM", "Oct 10, 2007 \\u2013 Oct 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "Oct 10, 2007 \\u2013 Oct 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMy", "Oct 2007 \\u2013 Oct 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Oct 2007 \\u2013 Oct 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMMM", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMM", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMy", "10/10/2007 \\u2013 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10/10/2007 \\u2013 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dM", "10/10/2007 \\u2013 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dM", "10/10/2007 \\u2013 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "My", "10/2007 \\u2013 10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10/2007 \\u2013 10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdM", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "d", "10/10/2007 \\u2013 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "d", "10/10/2007 \\u2013 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Ed", "10 Wed \\u2013 10 Fri",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Ed", "10 Wed \\u2013 10 Fri",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "y", "2007 \\u2013 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007 \\u2013 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "M", "10/2007 \\u2013 10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10/2007 \\u2013 10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMM", "Oct 2007 \\u2013 Oct 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMM", "Oct 2007 \\u2013 Oct 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMM", "October 2007 \\u2013 October 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMM", "October 2007 \\u2013 October 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 10/10/2008, 10:10 AM PT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 10/10/2008, 10:10 AM PT",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 10/10/2008, 10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 10/10/2008, 10 AM",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 10/10/2008, 10 AM PT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 10/10/2008, 10 AM PT",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 10/10/2008, 10 AM PDT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 10/10/2008, 10 AM PDT",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 10/10/2008, 10:10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 10/10/2008, 10:10:10 AM",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMMMy", "O 10, 2007 \\u2013 O 10, 2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMMy", "O 10, 2007 \\u2013 O 10, 2008",
- "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEEdM", "W, 10/10/2007 \\u2013 F, 10/10/2008",
+ "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEEdM", "W, 10/10/2007 \\u2013 F, 10/10/2008",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10 \\u2013 Saturday, November 10, 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10 \\u2013 Saturday, November 10, 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMy", "October 10 \\u2013 November 10, 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "October 10 \\u2013 November 10, 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMM", "October 10 \\u2013 November 10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMM", "October 10 \\u2013 November 10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMMy", "October \\u2013 November 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "October \\u2013 November 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10 \\u2013 Saturday, November 10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10 \\u2013 Saturday, November 10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMMMy", "Wed, Oct 10 \\u2013 Sat, Nov 10, 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMMy", "Wed, Oct 10 \\u2013 Sat, Nov 10, 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMy", "Oct 10 \\u2013 Nov 10, 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMy", "Oct 10 \\u2013 Nov 10, 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMM", "Oct 10 \\u2013 Nov 10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "Oct 10 \\u2013 Nov 10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMy", "Oct \\u2013 Nov 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Oct \\u2013 Nov 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMMM", "Wed, Oct 10 \\u2013 Sat, Nov 10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMM", "Wed, Oct 10 \\u2013 Sat, Nov 10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMy", "10/10/2007 \\u2013 11/10/2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMy", "10/10/2007 \\u2013 11/10/2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dM", "10/10 \\u2013 11/10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dM", "10/10 \\u2013 11/10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "My", "10/2007 \\u2013 11/2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10/2007 \\u2013 11/2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdM", "Wed, 10/10 \\u2013 Sat, 11/10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdM", "Wed, 10/10 \\u2013 Sat, 11/10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "d", "10/10 \\u2013 11/10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10/10 \\u2013 11/10",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "Ed", "10 Wed \\u2013 10 Sat",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Ed", "10 Wed \\u2013 10 Sat",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "y", "2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "y", "2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "M", "10 \\u2013 11",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "M", "10 \\u2013 11",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMM", "Oct \\u2013 Nov",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Oct \\u2013 Nov",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMM", "October \\u2013 November",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMM", "October \\u2013 November",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 11/10/2007, 10:10 AM PT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 11/10/2007, 10:10 AM PT",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 11/10/2007, 10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 11/10/2007, 10 AM",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 11/10/2007, 10 AM PT",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 11/10/2007, 10 AM PT",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 11/10/2007, 10 AM PST",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 11/10/2007, 10 AM PST",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 11/10/2007, 10:10:10 AM",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 11/10/2007, 10:10:10 AM",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMMy", "O 10 \\u2013 N 10, 2007",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMMy", "O 10 \\u2013 N 10, 2007",
- "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEEdM", "W, 10/10 \\u2013 S, 11/10",
+ "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEEdM", "W, 10/10 \\u2013 S, 11/10",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMMy", "Saturday, November 10 \\u2013 Tuesday, November 20, 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMMy", "Saturday, November 10 \\u2013 Tuesday, November 20, 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMMy", "November 10 \\u2013 20, 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMy", "November 10 \\u2013 20, 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMM", "November 10 \\u2013 20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "November 10 \\u2013 20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMMy", "November 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMMy", "November 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMM", "Saturday, November 10 \\u2013 Tuesday, November 20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMM", "Saturday, November 10 \\u2013 Tuesday, November 20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMMMy", "Sat, Nov 10 \\u2013 Tue, Nov 20, 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMMy", "Sat, Nov 10 \\u2013 Tue, Nov 20, 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMM", "Nov 10 \\u2013 20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMM", "Nov 10 \\u2013 20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMy", "Nov 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMMM", "Sat, Nov 10 \\u2013 Tue, Nov 20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMM", "Sat, Nov 10 \\u2013 Tue, Nov 20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMy", "11/10/2007 \\u2013 11/20/2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMy", "11/10/2007 \\u2013 11/20/2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "11/2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdM", "Sat, 11/10 \\u2013 Tue, 11/20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11/2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "Sat, 11/10 \\u2013 Tue, 11/20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "d", "10 \\u2013 20",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Ed", "10 Sat \\u2013 20 Tue",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10 \\u2013 20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Ed", "10 Sat \\u2013 20 Tue",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "M", "11",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMM", "Nov",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMM", "Nov",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmv", "11/10/2007, 10:10 AM PT \\u2013 11/20/2007, 10:10 AM PT",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "11/10/2007, 10:10 AM PT \\u2013 11/20/2007, 10:10 AM PT",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hz", "11/10/2007, 10 AM PST \\u2013 11/20/2007, 10 AM PST",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hz", "11/10/2007, 10 AM PST \\u2013 11/20/2007, 10 AM PST",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEddMMyyyy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEddMMyyyy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hms", "11/10/2007, 10:10:10 AM \\u2013 11/20/2007, 10:10:10 AM",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hms", "11/10/2007, 10:10:10 AM \\u2013 11/20/2007, 10:10:10 AM",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMMMy", "N 10 \\u2013 20, 2007",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMMy", "N 10 \\u2013 20, 2007",
- "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEEdM", "S, 11/10 \\u2013 T, 11/20",
+ "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEEdM", "S, 11/10 \\u2013 T, 11/20",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMMy", "January 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMy", "January 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMM", "January 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMM", "January 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMMy", "January 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMMy", "January 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMM", "Wednesday, January 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMM", "Wednesday, January 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMy", "Jan 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMy", "Jan 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMM", "Jan 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "Jan 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMy", "Jan 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdMMM", "Wed, Jan 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMMM", "Wed, Jan 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdMy", "Wed, 1/10/2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMy", "Wed, 1/10/2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMy", "1/10/2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMy", "1/10/2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dM", "1/10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dM", "1/10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdM", "Wed, 1/10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdM", "Wed, 1/10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "d", "10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "d", "10",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Ed", "10 Wed",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Ed", "10 Wed",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "y", "2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "y", "2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMM", "Jan",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMM", "Jan",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMM", "January",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMM", "January",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hm", "10:00 AM \\u2013 2:10 PM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "10:00 AM \\u2013 2:10 PM",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM PST",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM PST",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "10 AM \\u2013 2 PM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10 AM \\u2013 2 PM",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hv", "10 AM \\u2013 2 PM PT",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hv", "10 AM \\u2013 2 PM PT",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hz", "10 AM \\u2013 2 PM PST",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hz", "10 AM \\u2013 2 PM PST",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEddMMyyyy", "Wed, 01/10/2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEddMMyyyy", "Wed, 01/10/2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hhmm", "10:00 AM \\u2013 2:10 PM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmm", "10:00 AM \\u2013 2:10 PM",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hhmmzz", "10:00 AM \\u2013 2:10 PM PST",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmmzz", "10:00 AM \\u2013 2:10 PM PST",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMMMy", "J 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMMy", "J 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEEdM", "W, 1/10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEEdM", "W, 1/10",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMMy", "January 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMMy", "January 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "MMMMy", "January 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "MMMMy", "January 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMMMy", "Wed, Jan 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMMy", "Wed, Jan 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMy", "Jan 10, 2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMy", "Jan 10, 2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMM", "Jan 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMM", "Jan 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMMM", "Wed, Jan 10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMM", "Wed, Jan 10",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMy", "Wed, 1/10/2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMy", "Wed, 1/10/2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dM", "1/10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dM", "1/10",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdM", "Wed, 1/10",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdM", "Wed, 1/10",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "y", "2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "y", "2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "MMM", "Jan",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "MMM", "Jan",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hm", "10:00 \\u2013 10:20 AM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "10:00 \\u2013 10:20 AM",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmv", "10:00 \\u2013 10:20 AM PT",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "10:00 \\u2013 10:20 AM PT",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "h", "10 AM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "h", "10 AM",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hz", "10 AM PST",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "10 AM PST",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EddMMy", "Wed, 01/10/2007",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EddMMy", "Wed, 01/10/2007",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hhmm", "10:00 \\u2013 10:20 AM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmm", "10:00 \\u2013 10:20 AM",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hhmmzz", "10:00 \\u2013 10:20 AM PST",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmmzz", "10:00 \\u2013 10:20 AM PST",
- "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hms", "10:00:10 AM \\u2013 10:20:10 AM",
+ "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hms", "10:00:10 AM \\u2013 10:20:10 AM",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMMM", "January 10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMM", "January 10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMM", "Wednesday, January 10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMM", "Wednesday, January 10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdMMMy", "Wed, Jan 10, 2007",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMMMy", "Wed, Jan 10, 2007",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMM", "Jan 10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMM", "Jan 10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdMMM", "Wed, Jan 10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dM", "1/10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMMM", "Wed, Jan 10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dM", "1/10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "My", "1/2007",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "My", "1/2007",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdM", "Wed, 1/10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "d", "10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdM", "Wed, 1/10",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "d", "10",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "Ed", "10 Wed",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "Ed", "10 Wed",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "y", "2007",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "y", "2007",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "M", "1",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "M", "1",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "MMM", "Jan",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMM", "Jan",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "MMMM", "January",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMMM", "January",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hm", "10:10 AM",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "10:10 AM",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmv", "10:10 AM PT",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmv", "10:10 AM PT",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmz", "10:10 AM PST",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10 AM PST",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "h", "10 AM",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "10 AM",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hz", "10 AM PST",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hz", "10 AM PST",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hhmmzz", "10:10 AM PST",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmmzz", "10:10 AM PST",
- "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hms", "10:10:10 AM \u2013 10:10:20 AM",
+ "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hms", "10:10:10 AM \u2013 10:10:20 AM",
- "en", "2007 01 01 22:00:00", "2007 01 01 23:00:00", "yMMMMdHm", "January 1, 2007, 22:00 \u2013 23:00",
+ "en", "CE 2007 01 01 22:00:00", "CE 2007 01 01 23:00:00", "yMMMMdHm", "January 1, 2007, 22:00 \u2013 23:00",
- "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f32008\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e94",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f32008\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e94",
- "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hm", "2007/10/10 \\u4e0a\\u534810:10 \\u2013 2008/10/10 \\u4e0a\\u534810:10",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "2007/10/10 \\u4e0a\\u534810:10 \\u2013 2008/10/10 \\u4e0a\\u534810:10",
- "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
- "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMM", "10\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMM", "10\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
- "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMMy", "2007\\u5e7410\\u6708\\u81f311\\u6708",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "2007\\u5e7410\\u6708\\u81f311\\u6708",
- "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMM", "10\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f311\\u670810\\u65e5\\u661f\\u671f\\u516d",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMM", "10\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f311\\u670810\\u65e5\\u661f\\u671f\\u516d",
- "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmv", "2007/10/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10 \\u2013 2007/11/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10",
+ "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmv", "2007/10/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10 \\u2013 2007/11/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u81f320\\u65e5",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u81f320\\u65e5",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMM", "11\\u670810\\u65e5\\u81f320\\u65e5",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "11\\u670810\\u65e5\\u81f320\\u65e5",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMMy", "2007\\u5E7411\\u6708", // (fixed expected result per ticket 6872<-6626)
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMMy", "2007\\u5E7411\\u6708", // (fixed expected result per ticket 6872<-6626)
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMM", "11\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMM", "11\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMMM", "11\\u670810\\u65e5\\u5468\\u516d\\u81f320\\u65e5\\u5468\\u4e8c",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMM", "11\\u670810\\u65e5\\u5468\\u516d\\u81f320\\u65e5\\u5468\\u4e8c",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "2007/11/10\\u5468\\u516d\\u81f32007/11/20\\u5468\\u4e8c",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "2007/11/10\\u5468\\u516d\\u81f32007/11/20\\u5468\\u4e8c",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMy", "2007/11/10 \\u2013 2007/11/20",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMy", "2007/11/10 \\u2013 2007/11/20",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "2007\u5E7411\u6708",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdM", "11/10\\u5468\\u516d\\u81f311/20\\u5468\\u4e8c",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "2007\u5E7411\u6708",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "11/10\\u5468\\u516d\\u81f311/20\\u5468\\u4e8c",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "d", "10\\u201320\\u65e5",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10\\u201320\\u65e5",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "y", "2007\\u5E74", // (fixed expected result per ticket:6626:)
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007\\u5E74", // (fixed expected result per ticket:6626:)
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "M", "11\\u6708",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11\\u6708",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMM", "11\\u6708", // (fixed expected result per ticket 6872<-6626 and others)
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMM", "11\\u6708", // (fixed expected result per ticket 6872<-6626 and others)
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMM", "\\u5341\\u4E00\\u6708", // (fixed expected result per ticket 6872<-6626 and others)
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMM", "\\u5341\\u4E00\\u6708", // (fixed expected result per ticket 6872<-6626 and others)
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmz", "2007/11/10 GMT-8 \\u4e0a\\u534810:10 \\u2013 2007/11/20 GMT-8 \\u4e0a\\u534810:10",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmz", "2007/11/10 GMT-8 \\u4e0a\\u534810:10 \\u2013 2007/11/20 GMT-8 \\u4e0a\\u534810:10",
- "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "h", "2007/11/10 \\u4e0a\\u534810\\u65f6 \\u2013 2007/11/20 \\u4e0a\\u534810\\u65f6",
+ "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "h", "2007/11/10 \\u4e0a\\u534810\\u65f6 \\u2013 2007/11/20 \\u4e0a\\u534810\\u65f6",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket 6872<-6626)
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket 6872<-6626)
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hm", "\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F3\\u4E0B\\u53482:10",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F3\\u4E0B\\u53482:10",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmz", "GMT-8\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "GMT-8\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810\\u65F6\\u81F3\\u4E0B\\u53482\\u65F6",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810\\u65F6\\u81F3\\u4E0B\\u53482\\u65F6",
- "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hz", "GMT-8\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hz", "GMT-8\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
- "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMM", "1\\u670810\\u65e5", // (fixed expected result per ticket 6872<-6626)
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMM", "1\\u670810\\u65e5", // (fixed expected result per ticket 6872<-6626)
- "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hm", "\\u4e0a\\u534810:00\\u81f310:20",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "\\u4e0a\\u534810:00\\u81f310:20",
- "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F310:20",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F310:20",
- "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "h", "\\u4e0a\\u534810\\u65f6",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "h", "\\u4e0a\\u534810\\u65f6",
- "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hz", "GMT-8\\u4e0a\\u534810\\u65f6",
+ "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "GMT-8\\u4e0a\\u534810\\u65f6",
- "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket 6872<-6626)
+ "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket 6872<-6626)
- "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hm", "\\u4e0a\\u534810:10",
+ "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "\\u4e0a\\u534810:10",
- "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "h", "\\u4e0a\\u534810\\u65f6",
+ "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "\\u4e0a\\u534810\\u65f6",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. 2007 \\u2013 Freitag, 10. Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. 2007 \\u2013 Freitag, 10. Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMy", "10. Okt. 2007 \\u2013 10. Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMy", "10. Okt. 2007 \\u2013 10. Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMM", "10. Okt. 2007 \\u2013 10. Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "10. Okt. 2007 \\u2013 10. Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMy", "Okt. 2007 \\u2013 Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Okt. 2007 \\u2013 Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEdMMM", "Mi., 10. Okt. 2007 \\u2013 Fr., 10. Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEdMMM", "Mi., 10. Okt. 2007 \\u2013 Fr., 10. Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMy", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMy", "10.10.2007 \\u2013 10.10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10.10.2007 \\u2013 10.10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dM", "10.10.2007 \\u2013 10.10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dM", "10.10.2007 \\u2013 10.10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "My", "10.2007 \\u2013 10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10.2007 \\u2013 10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdM", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "d", "10.10.2007 \\u2013 10.10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "d", "10.10.2007 \\u2013 10.10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "y", "2007\\u20132008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007\\u20132008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "M", "10.2007 \\u2013 10.2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10.2007 \\u2013 10.2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMM", "Okt. 2007 \\u2013 Okt. 2008",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMM", "Okt. 2007 \\u2013 Okt. 2008",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hm", "10.10.2007, 10:10 AM \\u2013 10.10.2008, 10:10 AM",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10.10.2007, 10:10 AM \\u2013 10.10.2008, 10:10 AM",
- "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "jm", "10.10.2007, 10:10 \\u2013 10.10.2008, 10:10",
+ "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "jm", "10.10.2007, 10:10 \\u2013 10.10.2008, 10:10",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov. 2007",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov. 2007",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMy", "10. Okt. \\u2013 10. Nov. 2007",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMy", "10. Okt. \\u2013 10. Nov. 2007",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMM", "10. Okt. \\u2013 10. Nov.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "10. Okt. \\u2013 10. Nov.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMy", "Okt.\\u2013Nov. 2007",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Okt.\\u2013Nov. 2007",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMM", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMM", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMy", "Mi., 10.10. \\u2013 Sa., 10.11.2007",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMy", "Mi., 10.10. \\u2013 Sa., 10.11.2007",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dM", "10.10. \\u2013 10.11.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dM", "10.10. \\u2013 10.11.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "My", "10.2007 \\u2013 11.2007",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10.2007 \\u2013 11.2007",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdM", "Mi., 10.10. \\u2013 Sa., 10.11.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdM", "Mi., 10.10. \\u2013 Sa., 10.11.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "d", "10.10. \\u2013 10.11.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10.10. \\u2013 10.11.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "M", "10.\\u201311.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "M", "10.\\u201311.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMM", "Okt.\\u2013Nov.",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Okt.\\u2013Nov.",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmv", "10.10.2007, 10:10 AM Los Angeles Zeit \\u2013 10.11.2007, 10:10 AM Los Angeles Zeit",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmv", "10.10.2007, 10:10 AM Los Angeles Zeit \\u2013 10.11.2007, 10:10 AM Los Angeles Zeit",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "jmv", "10.10.2007, 10:10 Los Angeles Zeit \\u2013 10.11.2007, 10:10 Los Angeles Zeit",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "jmv", "10.10.2007, 10:10 Los Angeles Zeit \\u2013 10.11.2007, 10:10 Los Angeles Zeit",
- "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hms", "10.10.2007, 10:10:10 AM \\u2013 10.11.2007, 10:10:10 AM",
+ "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10.10.2007, 10:10:10 AM \\u2013 10.11.2007, 10:10:10 AM",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMy", "Samstag, 10. \\u2013 Dienstag, 20. Nov. 2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMy", "Samstag, 10. \\u2013 Dienstag, 20. Nov. 2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMy", "10.\\u201320. Nov. 2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMy", "10.\\u201320. Nov. 2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMM", "10.\\u201320. Nov.",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMM", "10.\\u201320. Nov.",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMy", "Nov. 2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov. 2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMM", "Samstag, 10. \\u2013 Dienstag, 20. Nov.",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMM", "Samstag, 10. \\u2013 Dienstag, 20. Nov.",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "Sa., 10. \\u2013 Di., 20.11.2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sa., 10. \\u2013 Di., 20.11.2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMy", "10.\\u201320.11.2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMy", "10.\\u201320.11.2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "10.\\u201320.11.",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "10.\\u201320.11.",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "11.2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11.2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdM", "Sa., 10. \\u2013 Di., 20.11.",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "Sa., 10. \\u2013 Di., 20.11.",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "d", "10.\\u201320.",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10.\\u201320.",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "y", "2007",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "M", "11",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmv", "10.11.2007, 10:10 AM Los Angeles Zeit \\u2013 20.11.2007, 10:10 AM Los Angeles Zeit",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "10.11.2007, 10:10 AM Los Angeles Zeit \\u2013 20.11.2007, 10:10 AM Los Angeles Zeit",
- "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "jmv", "10.11.2007, 10:10 Los Angeles Zeit \\u2013 20.11.2007, 10:10 Los Angeles Zeit",
+ "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "jmv", "10.11.2007, 10:10 Los Angeles Zeit \\u2013 20.11.2007, 10:10 Los Angeles Zeit",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMy", "10. Jan. 2007",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMy", "10. Jan. 2007",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMM", "10. Jan.",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "10. Jan.",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMy", "Jan. 2007",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan. 2007",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM GMT-8",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM GMT-8",
- "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "10 Uhr AM \\u2013 2 Uhr PM",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10 Uhr AM \\u2013 2 Uhr PM",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hm", "10:00\\u201310:20 AM",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "10:00\\u201310:20 AM",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmv", "10:00\\u201310:20 AM Los Angeles Zeit",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "10:00\\u201310:20 AM Los Angeles Zeit",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmz", "10:00\\u201310:20 AM GMT-8",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmz", "10:00\\u201310:20 AM GMT-8",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "h", "10 Uhr AM",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "h", "10 Uhr AM",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hv", "10 Uhr AM Los Angeles Zeit",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hv", "10 Uhr AM Los Angeles Zeit",
- "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hz", "10 Uhr AM GMT-8",
+ "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "10 Uhr AM GMT-8",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hm", "10:10 AM",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "10:10 AM",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "jm", "10:10",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "jm", "10:10",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmv", "10:10 AM Los Angeles Zeit",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmv", "10:10 AM Los Angeles Zeit",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "jmv", "10:10 Los Angeles Zeit",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "jmv", "10:10 Los Angeles Zeit",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmz", "10:10 AM GMT-8",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10 AM GMT-8",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "jmz", "10:10 GMT-8",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "jmz", "10:10 GMT-8",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "h", "10 Uhr AM",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "10 Uhr AM",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hv", "10 Uhr AM Los Angeles Zeit",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hv", "10 Uhr AM Los Angeles Zeit",
- "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hz", "10 Uhr AM GMT-8",
+ "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hz", "10 Uhr AM GMT-8",
// Thai (default calendar buddhist)
- // Android patch: Force default Gregorian calendar.
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E1E\\u0E38\\u0E18\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2550 \\u2013 \\u0E27\\u0E31\\u0E19\\u0E28\\u0E38\\u0E01\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2551",
+
+
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. 2550 \\u2013 10 \\u0E15.\\u0E04. 2551",
+
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "MMMy", "\\u0E15.\\u0E04. 2550 \\u2013 \\u0E15.\\u0E04. 2551",
+
+
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "EdMy", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
+
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "dMy", "10/10/2550 \\u2013 10/10/2551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2550 \\u2013 \\u0E27\\u0E31\\u0E19\\u0E2D\\u0E32\\u0E17\\u0E34\\u0E15\\u0E22\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "My", "10/2550 \\u2013 10/2551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. 2550 \\u2013 10 \\u0E15.\\u0E04. 2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "EdM", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "MMMy", "\\u0E15.\\u0E04. 2550 \\u2013 \\u0E15.\\u0E04. 2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "y", "2550\\u20132551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EdMy", "\\u0E2A. 10/10/2550 \\u2013 \\u0E2D\\u0E32. 10/10/2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "M", "10/2550 \\u2013 10/2551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "dMy", "10/10/2550 \\u2013 10/10/2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E1E\\u0E38\\u0E18\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. \\u2013 \\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E1E.\\u0E22. 2550",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "My", "10/2550 \\u2013 10/2551",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EdM", "\\u0E2A. 10/10/2550 \\u2013 \\u0E2D\\u0E32. 10/10/2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. \\u2013 10 \\u0E1E.\\u0E22.",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMMy", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22. 2550",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "y", "2550\\u20132551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "dM", "10/10 \\u2013 10/11",
- "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "M", "10/2550 \\u2013 10/2551",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "My", "10/2550 \\u2013 11/2550",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. \\u2013 \\u0E27\\u0E31\\u0E19\\u0E2D\\u0E31\\u0E07\\u0E04\\u0E32\\u0E23\\u0E17\\u0E35\\u0E48 10 \\u0E1E.\\u0E22. 2550",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "d", "10/10 \\u2013 10/11",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "y", "\u0E1E.\u0E28. 2550",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. \\u2013 10 \\u0E1E.\\u0E22.",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "MMMy", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22. 2550",
+ "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMM", "\u0E15.\u0E04.\u2013\u0E1E.\u0E22.",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dM", "10/10 \\u2013 10/11",
+ // Tests for Japanese calendar with eras, including new era in 2019 (Heisei 31 through April 30, then new era)
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "My", "10/2550 \\u2013 11/2550",
+ "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GyMMMd", "Mar 15 \u2013 Apr 15, 31 Heisei",
+ "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GGGGGyMd", "3/15/31 \u2013 4/15/31 H",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "d", "10/10 \\u2013 10/11",
+ "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GyMMMd", "Jan 5, 64 Sh\u014Dwa \u2013 Jan 15, 1 Heisei",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "y", "2550",
+ "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GGGGGyMd", "1/5/64 S \u2013 1/15/1 H",
+
+ "en-u-ca-japanese", "H 31 04 15 09:00:00", DateFormat.JP_ERA_2019_NARROW+" 1 05 15 09:00:00", "GyMMMd", "Apr 15, 31 Heisei \u2013 May 15, 1 "+DateFormat.JP_ERA_2019_ROOT,
+ "en-u-ca-japanese", "H 31 04 15 09:00:00", DateFormat.JP_ERA_2019_NARROW+" 1 05 15 09:00:00", "GGGGGyMd", "4/15/31 H \u2013 5/15/1 "+DateFormat.JP_ERA_2019_NARROW,
+
+
+ "ja-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GyMMMd", "\u5E73\u621031\u5E743\u670815\u65E5\uFF5E4\u670815\u65E5",
- "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "MMM", "\\u0E15.\\u0E04. \\u2013 \\u0E1E.\\u0E22.",
+ "ja-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GGGGGyMd", "H31/03/15\uFF5E31/04/15",
+
+ "ja-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GyMMMd", "\u662D\u548C64\u5E741\u67085\u65E5\uFF5E\u5E73\u6210\u5143\u5E741\u670815\u65E5",
+
+ "ja-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GGGGGyMd", "S64/01/05\uFF5EH1/01/15",
+
+ "ja-u-ca-japanese", "H 31 04 15 09:00:00", DateFormat.JP_ERA_2019_NARROW+" 1 05 15 09:00:00", "GGGGGyMd", "H31/04/15\uFF5E"+DateFormat.JP_ERA_2019_NARROW+"1/05/15",
- // Android patch end.
};
expect(DATA, DATA.length);
}
private void expect(String[] data, int data_length) {
- int i = 1;
+ int i = 0;
+ String pattern = data[i++];
+
while (i<data_length) {
String locName = data[i++];
- ULocale loc = new ULocale(locName);
- SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
- // 'f'
String datestr = data[i++];
String datestr_2 = data[i++];
+
+ ULocale loc = new ULocale(locName);
+ Calendar defCal = Calendar.getInstance(loc);
+ String calType = defCal.getType();
+
+ ULocale refLoc = ULocale.ROOT.setKeywordValue("calendar", calType);
+ SimpleDateFormat ref = new SimpleDateFormat(pattern, refLoc);
+ // 'f'
Date date, date_2;
try {
date = ref.parse(datestr);
date_2 = ref.parse(datestr_2);
} catch ( ParseException e ) {
errln("parse exception" + e);
+ i += 2; // skip the rest of the strings for this item
continue;
}
DateInterval dtitv = new DateInterval(date.getTime(),
@@ -1426,7 +1459,7 @@ public class DateIntervalFormatTest extends TestFmwk {
} catch (Exception e) { /* No op */ }
// Check getPatterns()
- Output<String> secondPart = new Output<String>();
+ Output<String> secondPart = new Output<>();
Calendar fromCalendar = Calendar.getInstance(Locale.ENGLISH);
fromCalendar.set(2016, 5, 22);
Calendar toCalendar= Calendar.getInstance(Locale.ENGLISH);
@@ -1830,8 +1863,8 @@ public class DateIntervalFormatTest extends TestFmwk {
public void TestTicket11669 () {
// These final variables are accessed directly by the concurrent threads.
final DateIntervalFormat formatter = DateIntervalFormat.getInstance(DateFormat.YEAR_MONTH_DAY, ULocale.US);
- final ArrayList<DateInterval> testIntervals = new ArrayList<DateInterval>();
- final ArrayList<String>expectedResults = new ArrayList<String>();
+ final ArrayList<DateInterval> testIntervals = new ArrayList<>();
+ final ArrayList<String>expectedResults = new ArrayList<>();
// Create and save the input test data.
TimeZone tz = TimeZone.getTimeZone("Americal/Los_Angeles");
@@ -1874,7 +1907,7 @@ public class DateIntervalFormatTest extends TestFmwk {
}
}
- List<TestThread> threads = new ArrayList<TestThread>();
+ List<TestThread> threads = new ArrayList<>();
for (int i=0; i<4; ++i) {
threads.add(new TestThread());
}
@@ -1892,4 +1925,87 @@ public class DateIntervalFormatTest extends TestFmwk {
}
}
}
+
+ @Test
+ public void testFormattedDateInterval() {
+ DateIntervalFormat fmt = DateIntervalFormat.getInstance("dMMMMy", ULocale.US);
+
+ {
+ String message = "FormattedDateInterval test 1";
+ String expectedString = "July 20 \u2013 25, 2018";
+ Calendar input1 = Calendar.getInstance(ULocale.UK);
+ Calendar input2 = Calendar.getInstance(ULocale.UK);
+ input1.set(2018, 6, 20);
+ input2.set(2018, 6, 25);
+ FormattedDateInterval result = fmt.formatToValue(input1, input2);
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {DateFormat.Field.MONTH, 0, 4},
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 5, 7, 0},
+ {DateFormat.Field.DAY_OF_MONTH, 5, 7},
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 10, 12, 1},
+ {DateFormat.Field.DAY_OF_MONTH, 10, 12},
+ {DateFormat.Field.YEAR, 14, 18}};
+ FormattedValueTest.checkFormattedValue(
+ message,
+ result,
+ expectedString,
+ expectedFieldPositions);
+ }
+
+ fmt = DateIntervalFormat.getInstance("dMMMha", ULocale.US);
+
+ {
+ String message = "FormattedDateInterval test 2";
+ String expectedString = "Feb 15, 11 AM \u2013 3 PM";
+ Calendar input1 = Calendar.getInstance(ULocale.US);
+ Calendar input2 = Calendar.getInstance(ULocale.US);
+ input1.set(2019, 1, 15, 11, 0, 0);
+ input2.set(2019, 1, 15, 15, 0, 0);
+ FormattedDateInterval result = fmt.formatToValue(input1, input2);
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {DateFormat.Field.MONTH, 0, 3},
+ {DateFormat.Field.DAY_OF_MONTH, 4, 6},
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 8, 13, 0},
+ {DateFormat.Field.HOUR1, 8, 10},
+ {DateFormat.Field.AM_PM, 11, 13},
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 16, 20, 1},
+ {DateFormat.Field.HOUR1, 16, 17},
+ {DateFormat.Field.AM_PM, 18, 20}};
+ FormattedValueTest.checkFormattedValue(
+ message,
+ result,
+ expectedString,
+ expectedFieldPositions);
+ }
+
+ // To test the fallback pattern behavior, make a custom DateIntervalInfo.
+ DateIntervalInfo dtitvinf = new DateIntervalInfo();
+ dtitvinf.setFallbackIntervalPattern("<< {1} --- {0} >>");
+ fmt = DateIntervalFormat.getInstance("dMMMMy", ULocale.US, dtitvinf);
+
+ {
+ String message = "FormattedDateInterval with fallback format test 1";
+ String expectedString = "<< July 25, 2018 --- July 20, 2018 >>";
+ Date input1 = new Date(2018 - 1900, 6, 20);
+ Date input2 = new Date(2018 - 1900, 6, 25);
+ DateInterval dtiv = new DateInterval(input1.getTime(), input2.getTime());
+ FormattedDateInterval result = fmt.formatToValue(dtiv);
+ Object[][] expectedFieldPositions = new Object[][] {
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 3, 16, 1},
+ {DateFormat.Field.MONTH, 3, 7},
+ {DateFormat.Field.DAY_OF_MONTH, 8, 10},
+ {DateFormat.Field.YEAR, 12, 16},
+ {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 21, 34, 0},
+ {DateFormat.Field.MONTH, 21, 25},
+ {DateFormat.Field.DAY_OF_MONTH, 26, 28},
+ {DateFormat.Field.YEAR, 30, 34}};
+ FormattedValueTest.checkFormattedValue(
+ message,
+ result,
+ expectedString,
+ expectedFieldPositions);
+ }
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java
index ed1be796c..e96df6882 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java
@@ -77,7 +77,7 @@ public class DateTimeGeneratorTest extends TestFmwk {
{"en", "CCCCCCm", "hh:mm aaaaa"},
{"en-BN", "Cm", "h:mm b"},
{"gu-IN", "Cm", "h:mm B"},
- {"und-IN", "Cm", "h:mm a"},
+ {"und-IN", "Cm", "h:mm B"},
};
for (String[] test : tests) {
DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(ULocale.forLanguageTag(test[0]));
@@ -453,7 +453,7 @@ public class DateTimeGeneratorTest extends TestFmwk {
new String[] {"MMMd", "13 ene."},
new String[] {"MMMMd", "13 de enero"},
new String[] {"yQQQ", "T1 1999"},
- new String[] {"hhmm", "11:58 p. m."},
+ new String[] {"hhmm", "11:58 p.\u00A0m."},
new String[] {"HHmm", "23:58"},
new String[] {"jjmm", "23:58"},
new String[] {"mmss", "58:59"},
@@ -483,9 +483,9 @@ public class DateTimeGeneratorTest extends TestFmwk {
new String[] {"JJmm", "23:58"},
new ULocale("ja@calendar=japanese"), // (new locale for testing ticket 6872<-5702)
- new String[] {"yM", "\u5E73\u621011/1"},
+ new String[] {"yM", "H11/1"},
new String[] {"yMMM", "\u5E73\u621011\u5E741\u6708"},
- new String[] {"yMd", "\u5E73\u621011/1/13"},
+ new String[] {"yMd", "H11/1/13"},
new String[] {"yMMMd", "\u5E73\u621011\u5E741\u670813\u65E5"},
new String[] {"Md", "1/13"},
new String[] {"MMMd", "1\u670813\u65E5"},
@@ -1668,4 +1668,43 @@ public class DateTimeGeneratorTest extends TestFmwk {
}
}
}
+
+ @Test
+ public void testJjMapping() {
+ final String jSkeleton = "j";
+ final char[] timeCycleChars = { 'H', 'h', 'K', 'k' };
+ // First test that j maps correctly by region in a locale for which we do not have data.
+ {
+ String testLocaleID = "de_US"; // short patterns from fallback locale "de" have "HH"
+ ULocale testLocale = new ULocale(testLocaleID);
+ DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(testLocale);
+ String jPattern = dtpg.getBestPattern(jSkeleton);
+ String jPatSkeleton = dtpg.getSkeleton(jPattern);
+ if (jPatSkeleton.indexOf('h') < 0) { // expect US preferred cycle 'h', not H or other cycle
+ errln("DateTimePatternGeneratorgetBestpattern locale " + testLocaleID + ", pattern j did not use 'h'");
+ }
+ }
+
+ // Next test that in all available Locales, the actual short time pattern uses the same cycle as produced by 'j'
+ ULocale[] locales = DateFormat.getAvailableULocales();
+ for (ULocale locale: locales) {
+ String localeID = locale.getName();
+ DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale);
+ DateFormat dfmt = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
+ String shortPattern = ((SimpleDateFormat)dfmt).toPattern();
+ String jPattern = dtpg.getBestPattern(jSkeleton);
+ // Now check that shortPattern and jPattern use the same hour cycle
+ String jPatSkeleton = dtpg.getSkeleton(jPattern);
+ String shortPatSkeleton = dtpg.getSkeleton(shortPattern);
+ for (char timeCycleChar: timeCycleChars) {
+ if (jPatSkeleton.indexOf(timeCycleChar) >= 0) {
+ if (shortPatSkeleton.indexOf(timeCycleChar) < 0) {
+ String dfmtCalType = dfmt.getCalendar().getType();
+ errln("locale " + localeID + ", expected j resolved char " + timeCycleChar +
+ " to occur in short time pattern " + shortPattern + " for " + dfmtCalType);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/FormattedValueTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/FormattedValueTest.java
new file mode 100644
index 000000000..57ed86dd9
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/FormattedValueTest.java
@@ -0,0 +1,287 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.dev.test.format;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+import java.text.AttributedCharacterIterator;
+import java.text.Format;
+import java.text.Format.Field;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.ibm.icu.text.ConstrainedFieldPosition;
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.FormattedValue;
+import com.ibm.icu.text.NumberFormat;
+
+/**
+ * @author sffc
+ */
+public class FormattedValueTest {
+ @Test
+ public void testBasic() {
+ ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
+ assertAllPartsEqual(
+ "basic",
+ cfpos,
+ 15,
+ null,
+ null,
+ 0,
+ 0,
+ 0L);
+ }
+
+ @Test
+ public void testSetters() {
+ ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
+
+ cfpos.constrainField(NumberFormat.Field.COMPACT);
+ assertAllPartsEqual(
+ "setters 1",
+ cfpos,
+ 10,
+ NumberFormat.Field.COMPACT,
+ null,
+ 0,
+ 0,
+ 0L);
+
+ cfpos.constrainFieldAndValue(NumberFormat.Field.COMPACT, 42);
+ assertAllPartsEqual(
+ "setters 1.2",
+ cfpos,
+ 8,
+ NumberFormat.Field.COMPACT,
+ 42,
+ 0,
+ 0,
+ 0L);
+
+ cfpos.constrainClass(NumberFormat.Field.class);
+ assertAllPartsEqual(
+ "setters 1.5",
+ cfpos,
+ 11,
+ null,
+ null,
+ 0,
+ 0,
+ 0L);
+
+ cfpos.setInt64IterationContext(42424242424242L);
+ assertAllPartsEqual(
+ "setters 2",
+ cfpos,
+ 11,
+ null,
+ null,
+ 0,
+ 0,
+ 42424242424242L);
+
+ cfpos.setState(NumberFormat.Field.COMPACT, BigDecimal.ONE, 5, 10);
+ assertAllPartsEqual(
+ "setters 3",
+ cfpos,
+ 11,
+ NumberFormat.Field.COMPACT,
+ BigDecimal.ONE,
+ 5,
+ 10,
+ 42424242424242L);
+
+ cfpos.reset();
+ assertAllPartsEqual(
+ "setters 4",
+ cfpos,
+ 15,
+ null,
+ null,
+ 0,
+ 0,
+ 0L);
+ }
+
+ @Test
+ public void testIllegalArgumentException() {
+ ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
+ try {
+ cfpos.matchesField(null, null);
+ fail("Expected an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // pass
+ }
+ }
+
+ private void assertAllPartsEqual(
+ String messagePrefix,
+ ConstrainedFieldPosition cfpos,
+ int matching,
+ Field field,
+ Object value,
+ int start,
+ int limit,
+ long context) {
+ assertEquals(messagePrefix + ": field", field, cfpos.getField());
+ assertEquals(messagePrefix + ": field value", value, cfpos.getFieldValue());
+ assertEquals(messagePrefix + ": start", start, cfpos.getStart());
+ assertEquals(messagePrefix + ": limit", limit, cfpos.getLimit());
+ assertEquals(messagePrefix + ": context", context, cfpos.getInt64IterationContext());
+
+ assertEquals(messagePrefix + ": integer field",
+ ((matching & 1) != 0), cfpos.matchesField(NumberFormat.Field.INTEGER, null));
+ assertEquals(messagePrefix + ": compact field",
+ ((matching & 2) != 0), cfpos.matchesField(NumberFormat.Field.COMPACT, null));
+ assertEquals(messagePrefix + ": date field",
+ ((matching & 4) != 0), cfpos.matchesField(DateFormat.Field.AM_PM, null));
+ assertEquals(messagePrefix + ": compact field with value",
+ ((matching & 8) != 0), cfpos.matchesField(NumberFormat.Field.COMPACT, 42));
+ }
+
+ public static void checkFormattedValue(String message, FormattedValue fv, String expectedString,
+ Object[][] expectedFieldPositions) {
+ // Calculate some initial expected values
+ int stringLength = fv.toString().length();
+ HashSet<Format.Field> uniqueFields = new HashSet<>();
+ Set<Class<?>> uniqueFieldClasses = new HashSet<>();
+ for (int i=0; i<expectedFieldPositions.length; i++) {
+ uniqueFields.add((Format.Field) expectedFieldPositions[i][0]);
+ uniqueFieldClasses.add(expectedFieldPositions[i][0].getClass());
+ }
+ String baseMessage = message + ": " + fv.toString() + ": ";
+
+ // Check the String and CharSequence
+ assertEquals(baseMessage + " string", expectedString, fv.toString());
+ assertCharSequenceEquals(expectedString, fv);
+
+ // Check the AttributedCharacterIterator
+ AttributedCharacterIterator fpi = fv.toCharacterIterator();
+ Set<AttributedCharacterIterator.Attribute> allAttributes = fpi.getAllAttributeKeys();
+ assertEquals(baseMessage + "All known fields should be in the iterator", uniqueFields.size(), allAttributes.size());
+ assertEquals(baseMessage + "Iterator should have length of string output", stringLength, fpi.getEndIndex());
+ int i = 0;
+ for (char c = fpi.first(); c != AttributedCharacterIterator.DONE; c = fpi.next(), i++) {
+ Set<AttributedCharacterIterator.Attribute> currentAttributes = fpi.getAttributes().keySet();
+ int attributesRemaining = currentAttributes.size();
+ for (Object[] cas : expectedFieldPositions) {
+ Format.Field expectedField = (Format.Field) cas[0];
+ int expectedBeginIndex = (Integer) cas[1];
+ int expectedEndIndex = (Integer) cas[2];
+ Object expectedValue = cas.length == 4 ? cas[3] : expectedField;
+ if (expectedBeginIndex > i || expectedEndIndex <= i) {
+ // Field position does not overlap with the current character
+ continue;
+ }
+
+ assertTrue(baseMessage + "Character at " + i + " should have field " + expectedField,
+ currentAttributes.contains(expectedField));
+ assertTrue(baseMessage + "Field " + expectedField + " should be a known attribute",
+ allAttributes.contains(expectedField));
+ int actualBeginIndex = fpi.getRunStart(expectedField);
+ int actualEndIndex = fpi.getRunLimit(expectedField);
+ Object actualValue = fpi.getAttribute(expectedField);
+ assertEquals(baseMessage + expectedField + " begin @" + i, expectedBeginIndex, actualBeginIndex);
+ assertEquals(baseMessage + expectedField + " end @" + i, expectedEndIndex, actualEndIndex);
+ assertEquals(baseMessage + expectedField + " value @" + i, expectedValue, actualValue);
+ attributesRemaining--;
+ }
+ assertEquals(baseMessage + "Should have looked at every field: " + i + ": " + currentAttributes,
+ 0, attributesRemaining);
+ }
+ assertEquals(baseMessage + "Should have looked at every character", stringLength, i);
+
+ // Check nextPosition over all fields
+ ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
+ i = 0;
+ for (Object[] cas : expectedFieldPositions) {
+ assertTrue(baseMessage + i, fv.nextPosition(cfpos));
+ Format.Field expectedField = (Format.Field) cas[0];
+ int expectedStart = (Integer) cas[1];
+ int expectedLimit = (Integer) cas[2];
+ Object expectedValue = cas.length == 4 ? cas[3] : null;
+ assertEquals(baseMessage + "field " + i, expectedField, cfpos.getField());
+ assertEquals(baseMessage + "start " + i, expectedStart, cfpos.getStart());
+ assertEquals(baseMessage + "limit " + i, expectedLimit, cfpos.getLimit());
+ assertEquals(baseMessage + "value " + i, expectedValue, cfpos.getFieldValue());
+ i++;
+ }
+ boolean afterLoopResult = fv.nextPosition(cfpos);
+ assertFalse(baseMessage + "after loop: " + cfpos, afterLoopResult);
+
+ // Check nextPosition constrained over each class one at a time
+ for (Class<?> classConstraint : uniqueFieldClasses) {
+ cfpos.reset();
+ cfpos.constrainClass(classConstraint);
+ i = 0;
+ for (Object[] cas : expectedFieldPositions) {
+ if (cas[0].getClass() != classConstraint) {
+ continue;
+ }
+ assertTrue(baseMessage + i, fv.nextPosition(cfpos));
+ Format.Field expectedField = (Format.Field) cas[0];
+ int expectedStart = (Integer) cas[1];
+ int expectedLimit = (Integer) cas[2];
+ Object expectedValue = cas.length == 4 ? cas[3] : null;
+ assertEquals(baseMessage + "field " + i, expectedField, cfpos.getField());
+ assertEquals(baseMessage + "start " + i, expectedStart, cfpos.getStart());
+ assertEquals(baseMessage + "limit " + i, expectedLimit, cfpos.getLimit());
+ assertEquals(baseMessage + "value " + i, expectedValue, cfpos.getFieldValue());
+ i++;
+ }
+ afterLoopResult = fv.nextPosition(cfpos);
+ assertFalse(baseMessage + "after loop: " + cfpos, afterLoopResult);
+ }
+
+ // Check nextPosition constrained over an unrelated class
+ cfpos.reset();
+ cfpos.constrainClass(HashSet.class);
+ assertFalse(baseMessage + "unrelated class", fv.nextPosition(cfpos));
+
+ // Check nextPosition constrained over each field one at a time
+ for (Format.Field field : uniqueFields) {
+ cfpos.reset();
+ cfpos.constrainField(field);
+ i = 0;
+ for (Object[] cas : expectedFieldPositions) {
+ if (cas[0] != field) {
+ continue;
+ }
+ assertTrue(baseMessage + i, fv.nextPosition(cfpos));
+ Format.Field expectedField = (Format.Field) cas[0];
+ int expectedStart = (Integer) cas[1];
+ int expectedLimit = (Integer) cas[2];
+ Object expectedValue = cas.length == 4 ? cas[3] : null;
+ assertEquals(baseMessage + "field " + i, expectedField, cfpos.getField());
+ assertEquals(baseMessage + "start " + i, expectedStart, cfpos.getStart());
+ assertEquals(baseMessage + "limit " + i, expectedLimit, cfpos.getLimit());
+ assertEquals(baseMessage + "value " + i, expectedValue, cfpos.getFieldValue());
+ i++;
+ }
+ afterLoopResult = fv.nextPosition(cfpos);
+ assertFalse(baseMessage + "after loop: " + cfpos, afterLoopResult);
+ }
+ }
+
+ public static void assertCharSequenceEquals(CharSequence a, CharSequence b) {
+ assertEquals(a.toString(), b.toString());
+
+ assertEquals(a.length(), b.length());
+ for (int i = 0; i < a.length(); i++) {
+ assertEquals(a.charAt(i), b.charAt(i));
+ }
+
+ int start = Math.min(2, a.length());
+ int end = Math.min(8, a.length());
+ if (start != end) {
+ assertCharSequenceEquals(a.subSequence(start, end), b.subSequence(start, end));
+ }
+ }
+}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/IntlTestDateFormatSymbols.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/IntlTestDateFormatSymbols.java
index 4a3a67213..bce4c8d38 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/IntlTestDateFormatSymbols.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/IntlTestDateFormatSymbols.java
@@ -142,18 +142,33 @@ public class IntlTestDateFormatSymbols extends TestFmwk
// just do some VERY basic tests to make sure that get/set work
long count;
- final String[] eras = en.getEras();
- fr.setEras(eras);
- final String[] eras1 = fr.getEras();
- count = eras.length;
- if( count != eras1.length) {
+ final String[] erasEn = en.getEras();
+ final String[] eraNamesEn = en.getEraNames();
+ final String[] erasNarrowEn = en.getNarrowEras();
+ fr.setEras(erasEn);
+ fr.setNarrowEras(erasNarrowEn);
+ final String[] erasFr = fr.getEras();
+ final String[] erasNarrowFr = fr.getNarrowEras();
+ count = erasEn.length;
+ if( count != erasFr.length || count != erasNarrowFr.length) {
errln("ERROR: setEras() failed (different size array)");
}
- else {
+ else { // like the C++ tests
for(int i = 0; i < count; i++) {
- if(! eras[i].equals(eras1[i])) {
+ if(! erasEn[i].equals(erasFr[i])) {
errln("ERROR: setEras() failed (different string values)");
}
+ if(! erasNarrowEn[i].equals(erasNarrowFr[i])) {
+ errln("ERROR: setNarrowEras() failed (different string values)");
+ }
+ if( eraNamesEn[i].length() <= erasEn[i].length() ) {
+ // At least for English we know a wide eraName should be longer than an abbrev era
+ errln("ERROR: english eraNames[i] not longer than eras[i]");
+ }
+ if( erasNarrowEn[i].length() >= erasEn[i].length() ) {
+ // At least for English we know a narrowEra should be shorter than an abbrev era
+ errln("ERROR: english erasNarrow[i] not shorter than eras[i]");
+ }
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ListFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ListFormatterTest.java
index 667525c2b..2d0367f3f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ListFormatterTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ListFormatterTest.java
@@ -148,7 +148,7 @@ public class ListFormatterTest extends TestFmwk {
@Test
public void TestFromList() {
ListFormatter listFormatter = ListFormatter.getInstance(ULocale.ENGLISH);
- ArrayList<String> list = new ArrayList<String>();
+ ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
@@ -187,6 +187,24 @@ public class ListFormatterTest extends TestFmwk {
assertEquals("bug 9946", "{0}, {1}, and {2}", listFormatter.format("{0}", "{1}", "{2}"));
}
+
+ void DoTheRealListStyleTesting(ULocale locale, String items[], ListFormatter.Style style, String expected) {
+ ListFormatter listFormatter = ListFormatter.getInstance(locale, style);
+ assertEquals("Style \"" + style + "\"", expected, listFormatter.format((Object[])items));
+ }
+
+ @Test
+ public void TestDifferentStyles() {
+ ULocale locale = ULocale.FRENCH;
+ String[] input = { "rouge", "jaune", "bleu", "vert" };
+
+ DoTheRealListStyleTesting(locale, input, ListFormatter.Style.STANDARD, "rouge, jaune, bleu et vert");
+ DoTheRealListStyleTesting(locale, input, ListFormatter.Style.OR, "rouge, jaune, bleu ou vert");
+ DoTheRealListStyleTesting(locale, input, ListFormatter.Style.UNIT, "rouge, jaune, bleu et vert");
+ DoTheRealListStyleTesting(locale, input, ListFormatter.Style.UNIT_NARROW, "rouge jaune bleu vert");
+ DoTheRealListStyleTesting(locale, input, ListFormatter.Style.UNIT_SHORT, "rouge, jaune, bleu et vert");
+ }
+
private boolean isDefaultLocaleEnglishLike() {
ULocale defaultLocale = ULocale.getDefault(ULocale.Category.FORMAT);
return defaultLocale.equals(ULocale.ENGLISH) || defaultLocale.equals(ULocale.US);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
index 4efc18ab1..3691a3477 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java
@@ -70,7 +70,7 @@ public class MeasureUnitTest extends TestFmwk {
if (first == null || second == null) {
throw new IllegalArgumentException("OrderedPair.of requires non null values.");
}
- return new OrderedPair<F, S>(first, second);
+ return new OrderedPair<>(first, second);
}
@Override
@@ -83,11 +83,11 @@ public class MeasureUnitTest extends TestFmwk {
}
}
- private static final String[] DRAFT_VERSIONS = {"61", "62", "63"};
+ private static final String[] DRAFT_VERSIONS = {"62", "63", "64"};
- private static final HashSet<String> DRAFT_VERSION_SET = new HashSet<String>();
+ private static final HashSet<String> DRAFT_VERSION_SET = new HashSet<>();
- private static final HashSet<String> TIME_CODES = new HashSet<String>();
+ private static final HashSet<String> TIME_CODES = new HashSet<>();
private static final String[][] JAVA_VERSIONS = {
{"G_FORCE", "53"},
@@ -229,9 +229,31 @@ public class MeasureUnitTest extends TestFmwk {
{"PERMILLE", "63"},
{"PETABYTE", "63"},
{"ATMOSPHERE", "63"},
+ {"DUNAM", "64"},
+ {"MOLE", "64"},
+ {"PERMYRIAD", "64"},
+ {"DAY_PERSON", "64"},
+ {"MONTH_PERSON", "64"},
+ {"WEEK_PERSON", "64"},
+ {"YEAR_PERSON", "64"},
+ {"BRITISH_THERMAL_UNIT", "64"},
+ {"ELECTRONVOLT", "64"},
+ {"NEWTON", "64"},
+ {"POUND_FORCE", "64"},
+ {"SOLAR_RADIUS", "64"},
+ {"SOLAR_LUMINOSITY", "64"},
+ {"DALTON", "64"},
+ {"EARTH_MASS", "64"},
+ {"SOLAR_MASS", "64"},
+ {"KILOPASCAL", "64"},
+ {"MEGAPASCAL", "64"},
+ {"NEWTON_METER", "64"},
+ {"POUND_FOOT", "64"},
+ {"BARREL", "64"},
+ {"FLUID_OUNCE_IMPERIAL", "64"},
};
- private static final HashMap<String, String> JAVA_VERSION_MAP = new HashMap<String, String>();
+ private static final HashMap<String, String> JAVA_VERSION_MAP = new HashMap<>();
static {
TIME_CODES.add("year");
@@ -254,12 +276,12 @@ public class MeasureUnitTest extends TestFmwk {
// various generateXXX calls go here, see
// http://site.icu-project.org/design/formatting/measureformat/updating-measure-unit
// use this test to run each of the ollowing in succession
- //generateConstants("63"); // for MeasureUnit.java, update generated MeasureUnit constants
- //generateBackwardCompatibilityTest("63"); // for MeasureUnitTest.java, create TestCompatible63
- //generateCXXHConstants("63"); // for measunit.h, update generated createXXX methods
+ //generateConstants("64"); // for MeasureUnit.java, update generated MeasureUnit constants
+ //generateBackwardCompatibilityTest("64"); // for MeasureUnitTest.java, create TestCompatible63
+ //generateCXXHConstants("64"); // for measunit.h, update generated createXXX methods
//generateCXXConstants(); // for measunit.cpp, update generated code
- //generateCXXBackwardCompatibilityTest("63"); // for measfmttest.cpp, create TestCompatible63
- //updateJAVAVersions("63"); // for MeasureUnitTest.java, JAVA_VERSIONS
+ //generateCXXBackwardCompatibilityTest("64"); // for measfmttest.cpp, create TestCompatible63
+ //updateJAVAVersions("64"); // for MeasureUnitTest.java, JAVA_VERSIONS
}
@Test
@@ -1286,6 +1308,174 @@ public class MeasureUnitTest extends TestFmwk {
}
@Test
+ public void TestCompatible64() {
+ MeasureUnit[] units = {
+ MeasureUnit.G_FORCE,
+ MeasureUnit.METER_PER_SECOND_SQUARED,
+ MeasureUnit.ARC_MINUTE,
+ MeasureUnit.ARC_SECOND,
+ MeasureUnit.DEGREE,
+ MeasureUnit.RADIAN,
+ MeasureUnit.REVOLUTION_ANGLE,
+ MeasureUnit.ACRE,
+ MeasureUnit.DUNAM,
+ MeasureUnit.HECTARE,
+ MeasureUnit.SQUARE_CENTIMETER,
+ MeasureUnit.SQUARE_FOOT,
+ MeasureUnit.SQUARE_INCH,
+ MeasureUnit.SQUARE_KILOMETER,
+ MeasureUnit.SQUARE_METER,
+ MeasureUnit.SQUARE_MILE,
+ MeasureUnit.SQUARE_YARD,
+ MeasureUnit.KARAT,
+ MeasureUnit.MILLIGRAM_PER_DECILITER,
+ MeasureUnit.MILLIMOLE_PER_LITER,
+ MeasureUnit.MOLE,
+ MeasureUnit.PART_PER_MILLION,
+ MeasureUnit.PERCENT,
+ MeasureUnit.PERMILLE,
+ MeasureUnit.PERMYRIAD,
+ MeasureUnit.LITER_PER_100KILOMETERS,
+ MeasureUnit.LITER_PER_KILOMETER,
+ MeasureUnit.MILE_PER_GALLON,
+ MeasureUnit.MILE_PER_GALLON_IMPERIAL,
+ MeasureUnit.BIT,
+ MeasureUnit.BYTE,
+ MeasureUnit.GIGABIT,
+ MeasureUnit.GIGABYTE,
+ MeasureUnit.KILOBIT,
+ MeasureUnit.KILOBYTE,
+ MeasureUnit.MEGABIT,
+ MeasureUnit.MEGABYTE,
+ MeasureUnit.PETABYTE,
+ MeasureUnit.TERABIT,
+ MeasureUnit.TERABYTE,
+ MeasureUnit.CENTURY,
+ MeasureUnit.DAY,
+ MeasureUnit.DAY_PERSON,
+ MeasureUnit.HOUR,
+ MeasureUnit.MICROSECOND,
+ MeasureUnit.MILLISECOND,
+ MeasureUnit.MINUTE,
+ MeasureUnit.MONTH,
+ MeasureUnit.MONTH_PERSON,
+ MeasureUnit.NANOSECOND,
+ MeasureUnit.SECOND,
+ MeasureUnit.WEEK,
+ MeasureUnit.WEEK_PERSON,
+ MeasureUnit.YEAR,
+ MeasureUnit.YEAR_PERSON,
+ MeasureUnit.AMPERE,
+ MeasureUnit.MILLIAMPERE,
+ MeasureUnit.OHM,
+ MeasureUnit.VOLT,
+ MeasureUnit.BRITISH_THERMAL_UNIT,
+ MeasureUnit.CALORIE,
+ MeasureUnit.ELECTRONVOLT,
+ MeasureUnit.FOODCALORIE,
+ MeasureUnit.JOULE,
+ MeasureUnit.KILOCALORIE,
+ MeasureUnit.KILOJOULE,
+ MeasureUnit.KILOWATT_HOUR,
+ MeasureUnit.NEWTON,
+ MeasureUnit.POUND_FORCE,
+ MeasureUnit.GIGAHERTZ,
+ MeasureUnit.HERTZ,
+ MeasureUnit.KILOHERTZ,
+ MeasureUnit.MEGAHERTZ,
+ MeasureUnit.ASTRONOMICAL_UNIT,
+ MeasureUnit.CENTIMETER,
+ MeasureUnit.DECIMETER,
+ MeasureUnit.FATHOM,
+ MeasureUnit.FOOT,
+ MeasureUnit.FURLONG,
+ MeasureUnit.INCH,
+ MeasureUnit.KILOMETER,
+ MeasureUnit.LIGHT_YEAR,
+ MeasureUnit.METER,
+ MeasureUnit.MICROMETER,
+ MeasureUnit.MILE,
+ MeasureUnit.MILE_SCANDINAVIAN,
+ MeasureUnit.MILLIMETER,
+ MeasureUnit.NANOMETER,
+ MeasureUnit.NAUTICAL_MILE,
+ MeasureUnit.PARSEC,
+ MeasureUnit.PICOMETER,
+ MeasureUnit.POINT,
+ MeasureUnit.SOLAR_RADIUS,
+ MeasureUnit.YARD,
+ MeasureUnit.LUX,
+ MeasureUnit.SOLAR_LUMINOSITY,
+ MeasureUnit.CARAT,
+ MeasureUnit.DALTON,
+ MeasureUnit.EARTH_MASS,
+ MeasureUnit.GRAM,
+ MeasureUnit.KILOGRAM,
+ MeasureUnit.METRIC_TON,
+ MeasureUnit.MICROGRAM,
+ MeasureUnit.MILLIGRAM,
+ MeasureUnit.OUNCE,
+ MeasureUnit.OUNCE_TROY,
+ MeasureUnit.POUND,
+ MeasureUnit.SOLAR_MASS,
+ MeasureUnit.STONE,
+ MeasureUnit.TON,
+ MeasureUnit.GIGAWATT,
+ MeasureUnit.HORSEPOWER,
+ MeasureUnit.KILOWATT,
+ MeasureUnit.MEGAWATT,
+ MeasureUnit.MILLIWATT,
+ MeasureUnit.WATT,
+ MeasureUnit.ATMOSPHERE,
+ MeasureUnit.HECTOPASCAL,
+ MeasureUnit.INCH_HG,
+ MeasureUnit.KILOPASCAL,
+ MeasureUnit.MEGAPASCAL,
+ MeasureUnit.MILLIBAR,
+ MeasureUnit.MILLIMETER_OF_MERCURY,
+ MeasureUnit.POUND_PER_SQUARE_INCH,
+ MeasureUnit.KILOMETER_PER_HOUR,
+ MeasureUnit.KNOT,
+ MeasureUnit.METER_PER_SECOND,
+ MeasureUnit.MILE_PER_HOUR,
+ MeasureUnit.CELSIUS,
+ MeasureUnit.FAHRENHEIT,
+ MeasureUnit.GENERIC_TEMPERATURE,
+ MeasureUnit.KELVIN,
+ MeasureUnit.NEWTON_METER,
+ MeasureUnit.POUND_FOOT,
+ MeasureUnit.ACRE_FOOT,
+ MeasureUnit.BARREL,
+ MeasureUnit.BUSHEL,
+ MeasureUnit.CENTILITER,
+ MeasureUnit.CUBIC_CENTIMETER,
+ MeasureUnit.CUBIC_FOOT,
+ MeasureUnit.CUBIC_INCH,
+ MeasureUnit.CUBIC_KILOMETER,
+ MeasureUnit.CUBIC_METER,
+ MeasureUnit.CUBIC_MILE,
+ MeasureUnit.CUBIC_YARD,
+ MeasureUnit.CUP,
+ MeasureUnit.CUP_METRIC,
+ MeasureUnit.DECILITER,
+ MeasureUnit.FLUID_OUNCE,
+ MeasureUnit.FLUID_OUNCE_IMPERIAL,
+ MeasureUnit.GALLON,
+ MeasureUnit.GALLON_IMPERIAL,
+ MeasureUnit.HECTOLITER,
+ MeasureUnit.LITER,
+ MeasureUnit.MEGALITER,
+ MeasureUnit.MILLILITER,
+ MeasureUnit.PINT,
+ MeasureUnit.PINT_METRIC,
+ MeasureUnit.QUART,
+ MeasureUnit.TABLESPOON,
+ MeasureUnit.TEASPOON,
+ };
+ assertEquals("", 161, units.length);
+ }
+
+ @Test
public void TestExamplesInDocs() {
MeasureFormat fmtFr = MeasureFormat.getInstance(
ULocale.FRENCH, FormatWidth.SHORT);
@@ -1616,7 +1806,7 @@ public class MeasureUnitTest extends TestFmwk {
}
static void assertUnique(Collection<?> coll) {
- int expectedSize = new HashSet<Object>(coll).size();
+ int expectedSize = new HashSet<>(coll).size();
int actualSize = coll.size();
assertEquals("Collection should contain only unique elements", expectedSize, actualSize);
}
@@ -1688,7 +1878,7 @@ public class MeasureUnitTest extends TestFmwk {
{ ulocSpanish, FormatWidth.NUMERIC, "5:37" },
{ ulocFinnish, FormatWidth.NARROW, "5t 37min" },
{ ulocFinnish, FormatWidth.NUMERIC, "5.37" },
- { ULocale.FRENCH, FormatWidth.NARROW, "5h 37\u202Fmin" },
+ { ULocale.FRENCH, FormatWidth.NARROW, "5h 37min" },
{ ULocale.FRENCH, FormatWidth.NUMERIC, "5:37" },
{ ulocIcelandic, FormatWidth.NARROW, "5 klst. og 37 m\u00EDn." },
{ ulocIcelandic, FormatWidth.NUMERIC, "5:37" },
@@ -1966,14 +2156,14 @@ public class MeasureUnitTest extends TestFmwk {
@Test
public void testOldFormatWithList() {
- List<Measure> measures = new ArrayList<Measure>(2);
+ List<Measure> measures = new ArrayList<>(2);
measures.add(new Measure(5, MeasureUnit.ACRE));
measures.add(new Measure(3000, MeasureUnit.SQUARE_FOOT));
MeasureFormat fmt = MeasureFormat.getInstance(
ULocale.ENGLISH, FormatWidth.WIDE);
assertEquals("", "5 acres, 3,000 square feet", fmt.format(measures));
assertEquals("", "5 acres", fmt.format(measures.subList(0, 1)));
- List<String> badList = new ArrayList<String>();
+ List<String> badList = new ArrayList<>();
badList.add("be");
badList.add("you");
try {
@@ -2148,7 +2338,7 @@ public class MeasureUnitTest extends TestFmwk {
@Test
public void testCLDRUnitAvailability() {
- Set<MeasureUnit> knownUnits = new HashSet<MeasureUnit>();
+ Set<MeasureUnit> knownUnits = new HashSet<>();
Class cMeasureUnit, cTimeUnit;
try {
cMeasureUnit = Class.forName("com.ibm.icu.util.MeasureUnit");
@@ -2193,13 +2383,41 @@ public class MeasureUnitTest extends TestFmwk {
// Should not throw an exception.
}
+ @Test
+ public void test20332_PersonUnits() {
+ Object[][] cases = new Object[][] {
+ {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.NARROW, "25y"},
+ {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.SHORT, "25 yrs"},
+ {ULocale.US, MeasureUnit.YEAR_PERSON, MeasureFormat.FormatWidth.WIDE, "25 years"},
+ {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.NARROW, "25m"},
+ {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.SHORT, "25 mths"},
+ {ULocale.US, MeasureUnit.MONTH_PERSON, MeasureFormat.FormatWidth.WIDE, "25 months"},
+ {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.NARROW, "25w"},
+ {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.SHORT, "25 wks"},
+ {ULocale.US, MeasureUnit.WEEK_PERSON, MeasureFormat.FormatWidth.WIDE, "25 weeks"},
+ {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.NARROW, "25d"},
+ {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.SHORT, "25 days"},
+ {ULocale.US, MeasureUnit.DAY_PERSON, MeasureFormat.FormatWidth.WIDE, "25 days"}
+ };
+ for (Object[] cas : cases) {
+ ULocale locale = (ULocale) cas[0];
+ MeasureUnit unit = (MeasureUnit) cas[1];
+ MeasureFormat.FormatWidth width = (MeasureFormat.FormatWidth) cas[2];
+ String expected = (String) cas[3];
+
+ MeasureFormat fmt = MeasureFormat.getInstance(locale, width);
+ String result = fmt.formatMeasures(new Measure(25, unit));
+ assertEquals("" + locale + " " + unit + " " + width, expected, result);
+ }
+ }
+
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> getUnitsToPerParts() {
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
Map<MeasureUnit, Pair<String, String>> unitsToPerStrings =
- new HashMap<MeasureUnit, Pair<String, String>>();
- Map<String, MeasureUnit> namesToUnits = new HashMap<String, MeasureUnit>();
+ new HashMap<>();
+ Map<String, MeasureUnit> namesToUnits = new HashMap<>();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
// Currency types are always atomic units, so we can skip these
@@ -2217,7 +2435,7 @@ public class MeasureUnitTest extends TestFmwk {
}
}
Map<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> unitsToPerUnits =
- new HashMap<MeasureUnit, Pair<MeasureUnit, MeasureUnit>>();
+ new HashMap<>();
for (Map.Entry<MeasureUnit, Pair<String, String>> entry : unitsToPerStrings.entrySet()) {
Pair<String, String> perStrings = entry.getValue();
MeasureUnit unit = namesToUnits.get(perStrings.first);
@@ -2232,7 +2450,7 @@ public class MeasureUnitTest extends TestFmwk {
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateCXXHConstants(String thisVersion) {
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
System.out.println();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
@@ -2249,8 +2467,9 @@ public class MeasureUnitTest extends TestFmwk {
System.out.println("#ifndef U_HIDE_DRAFT_API");
}
System.out.println(" /**");
- System.out.println(" * Returns unit of " + type + ": " + code + ".");
+ System.out.println(" * Returns by pointer, unit of " + type + ": " + code + ".");
System.out.println(" * Caller owns returned value and must free it.");
+ System.out.printf(" * Also see {@link #get%s()}.\n", name);
System.out.println(" * @param status ICU error code.");
if (isDraft(javaName)) {
System.out.println(" * @draft ICU " + getVersion(javaName, thisVersion));
@@ -2259,6 +2478,19 @@ public class MeasureUnitTest extends TestFmwk {
}
System.out.println(" */");
System.out.printf(" static MeasureUnit *create%s(UErrorCode &status);\n", name);
+ System.out.println();
+ System.out.println(" /**");
+ System.out.println(" * Returns by value, unit of " + type + ": " + code + ".");
+ System.out.printf(" * Also see {@link #create%s()}.\n", name);
+ // TODO: When the get* methods become stable in ICU 66, update their
+ // @draft code to be more like that for the create* methods above.
+ String getterVersion = getVersion(javaName, thisVersion);
+ if (Integer.valueOf(getterVersion) < 64) {
+ getterVersion = "64";
+ }
+ System.out.println(" * @draft ICU " + getterVersion);
+ System.out.println(" */");
+ System.out.printf(" static MeasureUnit get%s();\n", name);
if (isDraft(javaName)) {
System.out.println("#endif /* U_HIDE_DRAFT_API */");
}
@@ -2280,7 +2512,7 @@ public class MeasureUnitTest extends TestFmwk {
// for MeasureFormat during the release process.
static void updateJAVAVersions(String thisVersion) {
System.out.println();
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
@@ -2298,9 +2530,9 @@ public class MeasureUnitTest extends TestFmwk {
}
static TreeMap<String, List<MeasureUnit>> getAllUnits() {
- TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>();
+ TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<>();
for (String type : MeasureUnit.getAvailableTypes()) {
- ArrayList<MeasureUnit> units = new ArrayList<MeasureUnit>(MeasureUnit.getAvailable(type));
+ ArrayList<MeasureUnit> units = new ArrayList<>(MeasureUnit.getAvailable(type));
Collections.sort(
units,
new Comparator<MeasureUnit>() {
@@ -2366,9 +2598,9 @@ public class MeasureUnitTest extends TestFmwk {
first = true;
int offset = 0;
int typeIdx = 0;
- Map<MeasureUnit, Integer> measureUnitToOffset = new HashMap<MeasureUnit, Integer>();
+ Map<MeasureUnit, Integer> measureUnitToOffset = new HashMap<>();
Map<MeasureUnit, Pair<Integer, Integer>> measureUnitToTypeSubType =
- new HashMap<MeasureUnit, Pair<Integer, Integer>>();
+ new HashMap<>();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
int subTypeIdx = 0;
for (MeasureUnit unit : entry.getValue()) {
@@ -2395,7 +2627,7 @@ public class MeasureUnitTest extends TestFmwk {
// Build unit per unit offsets to corresponding type sub types sorted by
// unit first and then per unit.
TreeMap<OrderedPair<Integer, Integer>, Pair<Integer, Integer>> unitPerUnitOffsetsToTypeSubType
- = new TreeMap<OrderedPair<Integer, Integer>, Pair<Integer, Integer>>();
+ = new TreeMap<>();
for (Map.Entry<MeasureUnit, Pair<MeasureUnit, MeasureUnit>> entry
: getUnitsToPerParts().entrySet()) {
Pair<MeasureUnit, MeasureUnit> unitPerUnit = entry.getValue();
@@ -2433,7 +2665,7 @@ public class MeasureUnitTest extends TestFmwk {
System.out.println("static const int32_t kBaseSubTypeIdx = " + baseSubTypeIdx + ";");
System.out.println();
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
@@ -2452,6 +2684,11 @@ public class MeasureUnitTest extends TestFmwk {
typeSubType.first, typeSubType.second);
System.out.println("}");
System.out.println();
+ System.out.printf("MeasureUnit MeasureUnit::get%s() {\n", name);
+ System.out.printf(" return MeasureUnit(%d, %d);\n",
+ typeSubType.first, typeSubType.second);
+ System.out.println("}");
+ System.out.println();
}
}
}
@@ -2491,7 +2728,7 @@ public class MeasureUnitTest extends TestFmwk {
// DO NOT DELETE THIS FUNCTION! It may appear as dead code, but we use this to generate code
// for MeasureFormat during the release process.
static void generateBackwardCompatibilityTest(String version) {
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
System.out.println();
System.out.printf(" public void TestCompatible%s() {\n", version.replace(".", "_"));
System.out.println(" MeasureUnit[] units = {");
@@ -2517,10 +2754,11 @@ public class MeasureUnitTest extends TestFmwk {
// for MeasureFormat during the release process.
static void generateCXXBackwardCompatibilityTest(String version) {
System.out.println();
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
System.out.printf("void MeasureFormatTest::TestCompatible%s() {\n", version.replace(".", "_"));
System.out.println(" UErrorCode status = U_ZERO_ERROR;");
System.out.println(" LocalPointer<MeasureUnit> measureUnit;");
+ System.out.println(" MeasureUnit measureUnitValue;");
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
if (isTypeHidden(entry.getKey())) {
@@ -2530,6 +2768,7 @@ public class MeasureUnitTest extends TestFmwk {
String camelCase = toCamelCase(unit);
checkForDup(seen, camelCase, unit);
System.out.printf(" measureUnit.adoptInstead(MeasureUnit::create%s(status));\n", camelCase);
+ System.out.printf(" measureUnitValue = MeasureUnit::get%s();\n", camelCase);
}
}
System.out.println(" assertSuccess(\"\", status);");
@@ -2560,7 +2799,7 @@ public class MeasureUnitTest extends TestFmwk {
// for MeasureFormat during the release process.
static void generateConstants(String thisVersion) {
System.out.println();
- Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
+ Map<String, MeasureUnit> seen = new HashMap<>();
TreeMap<String, List<MeasureUnit>> allUnits = getAllUnits();
for (Map.Entry<String, List<MeasureUnit>> entry : allUnits.entrySet()) {
String type = entry.getKey();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java
index 90b5721cc..f3cab4f33 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatDataDrivenTest.java
@@ -9,6 +9,7 @@ import java.text.ParsePosition;
import org.junit.Test;
import com.ibm.icu.dev.test.TestUtil;
+import com.ibm.icu.dev.text.DecimalFormat_ICU58;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.impl.number.DecimalFormatProperties.ParseMode;
import com.ibm.icu.impl.number.Padder.PadPosition;
@@ -292,13 +293,6 @@ public class NumberFormatDataDrivenTest {
/**
* Backwards-compatibility test: snapshot of DecimalFormat from ICU 58.
*/
- // Android patch: Android can't access DecimalFormat_ICU58 for testing (b/33448125).
- // That class lived in a package under test and relied on package access, but
- // 1.) Android Compatibility Test Suite (CTS) run tests with a different ClassLoader,
- // preventing package access, and
- // 2.) By default, the OpenJDK 9 toolchain won't compile non-libcore code that in
- // libcore packages (see http://b/68224249).
- /*
private DataDrivenNumberFormatTestUtility.CodeUnderTest ICU58 = new DataDrivenNumberFormatTestUtility.CodeUnderTest() {
@Override
public Character Id() {
@@ -356,7 +350,7 @@ public class NumberFormatDataDrivenTest {
/**
* @param tuple
* @return
- *
+ */
private DecimalFormat_ICU58 createDecimalFormat(DataDrivenNumberFormatTestData tuple) {
DecimalFormat_ICU58 fmt = new DecimalFormat_ICU58(
@@ -369,7 +363,7 @@ public class NumberFormatDataDrivenTest {
/**
* @param tuple
* @param fmt
- *
+ */
private void adjustDecimalFormat(DataDrivenNumberFormatTestData tuple, DecimalFormat_ICU58 fmt) {
if (tuple.minIntegerDigits != null) {
fmt.setMinimumIntegerDigits(tuple.minIntegerDigits);
@@ -474,8 +468,6 @@ public class NumberFormatDataDrivenTest {
}
}
};
- */
- // Android patch end.
/**
* Test of available JDK APIs.
@@ -901,8 +893,6 @@ public class NumberFormatDataDrivenTest {
.runFormatSuiteIncludingKnownFailures("numberformattestspecification.txt", ICU4J);
}
- // Android patch: Android can't access DecimalFormat_ICU58 for testing (b/33448125).
- /*
@Test
public void TestDataDrivenICU58() {
// Android can't access DecimalFormat_ICU58 for testing (ticket #13283).
@@ -912,8 +902,6 @@ public class NumberFormatDataDrivenTest {
DataDrivenNumberFormatTestUtility
.runFormatSuiteIncludingKnownFailures("numberformattestspecification.txt", ICU58);
}
- */
- // Android patch end.
@Test
public void TestDataDrivenJDK() {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatSpecificationTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatSpecificationTest.java
index 2f8914a07..ca88831f9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatSpecificationTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatSpecificationTest.java
@@ -88,9 +88,7 @@ public class NumberFormatSpecificationTest extends TestFmwk {
assertEquals("", "12,300E3", formatFrWithPattern(12300.1, "##0.0000E0"));
assertEquals("", "12,30E3", formatFrWithPattern(12300.1, "##0.000#E0"));
assertEquals("", "12,301E3", formatFrWithPattern(12301.0, "##0.000#E0"));
- if (!logKnownIssue("11020", "Rounding does not work with scientific notation.")) {
- assertEquals("", "170,0E-3", formatFrWithPattern(0.17, "##0.000#E0"));
- }
+ assertEquals("", "170,0E-3", formatFrWithPattern(0.17, "##0.000#E0"));
}
@Test
@@ -126,10 +124,8 @@ public class NumberFormatSpecificationTest extends TestFmwk {
assertEquals("", "ne1 234nx", formatFrWithPattern(-1234, "####,##0$*x;ne#n"));
assertEquals("", "n1 234*xx", formatFrWithPattern(-1234, "####,##0$*x;n#'*'"));
assertEquals("", "yyyy%432,6", formatFrWithPattern(4.33, "*y%4.2######"));
- if (!logKnownIssue("11025", "Padding broken when used with currencies")) {
- assertEquals("", "EUR *433,00", formatFrWithPattern(433.0, "¤¤ **####0.00"));
- assertEquals("", "EUR *433,00", formatFrWithPattern(433.0, "¤¤ **#######0"));
- }
+ assertEquals("", "EUR *433,00", formatFrWithPattern(433.0, "¤¤ **####0.00"));
+ assertEquals("", "EUR *433,00", formatFrWithPattern(433.0, "¤¤ **#######0"));
{
DecimalFormatSymbols sym = new DecimalFormatSymbols(ULocale.FRANCE);
DecimalFormat fmt = new DecimalFormat("¤¤ **#######0", sym);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
index 63e956c01..f6b575231 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
@@ -43,10 +43,12 @@ import org.junit.runners.JUnit4;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.dev.test.format.IntlTestDecimalFormatAPIC.FieldContainer;
+import com.ibm.icu.dev.text.DecimalFormat_ICU58;
import com.ibm.icu.impl.ICUConfig;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.impl.data.ResourceReader;
import com.ibm.icu.impl.data.TokenIterator;
+import com.ibm.icu.impl.number.PatternStringUtils;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.math.MathContext;
import com.ibm.icu.text.CompactDecimalFormat;
@@ -256,6 +258,25 @@ public class NumberFormatTest extends TestFmwk {
}
}
+ @Test
+ public void Test20186_SpacesAroundSemicolon() {
+ DecimalFormat df = new DecimalFormat("0.00 ; -0.00");
+ expect2(df, 1, "1.00 ");
+ expect2(df, -1, " -1.00");
+
+ df = new DecimalFormat("0.00;");
+ expect2(df, 1, "1.00");
+ expect2(df, -1, "-1.00");
+
+ df = new DecimalFormat("0.00;0.00");
+ expect2(df, 1, "1.00");
+ expect(df, -1, "1.00"); // parses as 1, not -1
+
+ df = new DecimalFormat(" 0.00 ; -0.00 ");
+ expect2(df, 1, " 1.00 ");
+ expect2(df, -1, " -1.00 ");
+ }
+
// Test exponential pattern
@Test
public void TestExponential() {
@@ -658,28 +679,28 @@ public class NumberFormatTest extends TestFmwk {
@Test
public void TestCurrency() {
String[] DATA = {
- "fr", "CA", "", "1,50\u00a0$",
- "de", "DE", "", "1,50\u00a0\u20AC",
- "de", "DE", "PREEURO", "1,50\u00a0DM",
- "fr", "FR", "", "1,50\u00a0\u20AC",
- "fr", "FR", "PREEURO", "1,50\u00a0F",
+ "fr_CA", "1,50\u00a0$",
+ "de_DE", "1,50\u00a0\u20AC",
+ "de_DE@currency=DEM", "1,50\u00a0DM",
+ "fr_FR", "1,50\u00a0\u20AC",
+ "fr_FR@currency=FRF", "1,50\u00a0F",
};
- for (int i=0; i<DATA.length; i+=4) {
- Locale locale = new Locale(DATA[i], DATA[i+1], DATA[i+2]);
+ for (int i=0; i<DATA.length; i+=2) {
+ Locale locale = new Locale(DATA[i]);
NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
String s = fmt.format(1.50);
- if (s.equals(DATA[i+3])) {
+ if (s.equals(DATA[i+1])) {
logln("Ok: 1.50 x " + locale + " => " + s);
} else {
logln("FAIL: 1.50 x " + locale + " => " + s +
- ", expected " + DATA[i+3]);
+ ", expected " + DATA[i+1]);
}
}
// format currency with CurrencyAmount
- for (int i=0; i<DATA.length; i+=4) {
- Locale locale = new Locale(DATA[i], DATA[i+1], DATA[i+2]);
+ for (int i=0; i<DATA.length; i+=2) {
+ Locale locale = new Locale(DATA[i]);
Currency curr = Currency.getInstance(locale);
logln("\nName of the currency is: " + curr.getName(locale, Currency.LONG_NAME, new boolean[] {false}));
@@ -688,11 +709,11 @@ public class NumberFormatTest extends TestFmwk {
NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
String sCurr = fmt.format(cAmt);
- if (sCurr.equals(DATA[i+3])) {
+ if (sCurr.equals(DATA[i+1])) {
logln("Ok: 1.50 x " + locale + " => " + sCurr);
} else {
errln("FAIL: 1.50 x " + locale + " => " + sCurr +
- ", expected " + DATA[i+3]);
+ ", expected " + DATA[i+1]);
}
}
@@ -1397,6 +1418,29 @@ public class NumberFormatTest extends TestFmwk {
expect2(new DecimalFormat("*'😃'####.00", US), 1.1, "😃😃😃1.10");
}
+ @Test
+ public void TestIgnorePadding() {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ DecimalFormat fmt = new DecimalFormat("", dfs);
+ fmt.setGroupingUsed(false);
+ fmt.setFormatWidth(0);
+ fmt.setPadCharacter('*');
+ fmt.setPadPosition(0);
+ fmt.setMinimumIntegerDigits(0);
+ fmt.setMaximumIntegerDigits(8);
+ fmt.setMinimumFractionDigits(0);
+ fmt.setMaximumFractionDigits(0);
+ String pattern = fmt.toPattern();
+ if (pattern.startsWith("*")) {
+ errln("ERROR toPattern result should ignore padding but get \"" + pattern + "\"");
+ }
+ fmt.applyPattern(pattern);
+ String format = fmt.format(24);
+ if (!format.equals("24")) {
+ errln("ERROR format result expect 24 but get \"" + format + "\"");
+ }
+ }
+
/**
* Upgrade to alphaWorks
*/
@@ -1693,7 +1737,8 @@ public class NumberFormatTest extends TestFmwk {
localizedPattern, df1.toLocalizedPattern());
// Android can't access DecimalFormat_ICU58 for testing (ticket #13283).
- /*
+ if (TestUtil.getJavaVendor() == TestUtil.JavaVendor.Android) continue;
+
// Note: ICU 58 does not support plus signs in patterns
// Note: ICU 58 always prints the negative part of scientific notation patterns,
// even when the negative part is not necessary
@@ -1706,12 +1751,28 @@ public class NumberFormatTest extends TestFmwk {
standardPattern58, df4.toPattern());
assertEquals("toLocalizedPattern should match on ICU58 standardPattern instance",
localizedPattern58, df3.toLocalizedPattern());
- */
- // Android patch end.
}
}
@Test
+ public void TestParseEmpty(){
+ String parsetxt = "";
+ NumberFormat numfmt = NumberFormat.getInstance(new ULocale("en_US"), NumberFormat.NUMBERSTYLE);
+ ParsePosition ppos = new ParsePosition(0);
+ Number value = null;
+ try {
+ value = numfmt.parse(parsetxt, ppos);
+ if (value==null) {
+ logln("NumberFormat.parse empty string succeeds (no exception) with null return as expected, ppos " + ppos.getIndex());
+ } else {
+ errln("NumberFormat.parse empty string succeeds (no exception) but returns non-null value " + value + ", ppos " + ppos.getIndex());
+ }
+ } catch (IllegalArgumentException e){
+ errln("NumberFormat.parse empty string throws IllegalArgumentException");
+ }
+ }
+
+ @Test
public void TestParseNull() throws ParseException {
DecimalFormat df = new DecimalFormat();
try {
@@ -1874,8 +1935,16 @@ public class NumberFormatTest extends TestFmwk {
if (availableNames == null || availableNames.length <= 0) {
errln("ERROR: NumberingSystem.getAvailableNames() returned a null or empty array.");
} else {
+ // Check for alphabetical order
+ for (int i=0; i<availableNames.length-1; i++) {
+ assertTrue("Names should be in alphabetical order",
+ availableNames[i].compareTo(availableNames[i+1]) < 0);
+ }
+
boolean latnFound = false;
for (String name : availableNames){
+ assertNotEquals("should not throw and should not be null",
+ null, NumberingSystem.getInstanceByName(name));
if ("latn".equals(name)) {
latnFound = true;
break;
@@ -1887,6 +1956,9 @@ public class NumberFormatTest extends TestFmwk {
}
}
+ assertEquals("Non-existing numbering system should return null",
+ null, NumberingSystem.getInstanceByName("dummy"));
+
// Test NumberingSystem.getInstance()
NumberingSystem ns1 = NumberingSystem.getInstance();
if (ns1 == null || ns1.isAlgorithmic()) {
@@ -4007,6 +4079,115 @@ public class NumberFormatTest extends TestFmwk {
}
@Test
+ public void TestSetMaxFracAndRoundIncr() {
+ class SetMxFrAndRndIncrItem {
+ String descrip;
+ String localeID;
+ int style;
+ int minInt;
+ int minFrac;
+ int maxFrac;
+ double roundIncr;
+ String expPattern;
+ double valueToFmt;
+ String expFormat;
+ // Simple constructor
+ public SetMxFrAndRndIncrItem(String desc, String loc, int stl, int mnI, int mnF, int mxF,
+ double rdIn, String ePat, double val, String eFmt) {
+ descrip = desc;
+ localeID = loc;
+ style = stl;
+ minInt = mnI;
+ minFrac = mnF;
+ maxFrac = mxF;
+ roundIncr = rdIn;
+ expPattern = ePat;
+ valueToFmt = val;
+ expFormat = eFmt ;
+ }
+ };
+
+ final SetMxFrAndRndIncrItem[] items = {
+ // descrip locale style mnI mnF mxF rdInc expPat value expFmt
+ new SetMxFrAndRndIncrItem( "01 en_US DEC 1/0/3/0.0", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 3, 0.0, "#,##0.###", 0.128, "0.128" ),
+ new SetMxFrAndRndIncrItem( "02 en_US DEC 1/0/1/0.0", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 1, 0.0, "#,##0.#", 0.128, "0.1" ),
+ new SetMxFrAndRndIncrItem( "03 en_US DEC 1/0/1/0.01", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 1, 0.01, "#,##0.#", 0.128, "0.1" ),
+ new SetMxFrAndRndIncrItem( "04 en_US DEC 1/1/1/0.01", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 1, 0.01, "#,##0.0", 0.128, "0.1" ),
+ new SetMxFrAndRndIncrItem( "05 en_US DEC 1/0/1/0.1", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 1, 0.1, "#,##0.1", 0.128, "0.1" ), // use incr
+ new SetMxFrAndRndIncrItem( "06 en_US DEC 1/1/1/0.1", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 1, 0.1, "#,##0.1", 0.128, "0.1" ), // use incr
+
+ new SetMxFrAndRndIncrItem( "10 en_US DEC 1/0/1/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 1, 0.02, "#,##0.#", 0.128, "0.1" ),
+ new SetMxFrAndRndIncrItem( "11 en_US DEC 1/0/2/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 2, 0.02, "#,##0.02", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "12 en_US DEC 1/0/3/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 0, 3, 0.02, "#,##0.02#", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "13 en_US DEC 1/1/1/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 1, 0.02, "#,##0.0", 0.128, "0.1" ),
+ new SetMxFrAndRndIncrItem( "14 en_US DEC 1/1/2/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 2, 0.02, "#,##0.02", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "15 en_US DEC 1/1/3/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 3, 0.02, "#,##0.02#", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "16 en_US DEC 1/2/2/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 2, 0.02, "#,##0.02", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "17 en_US DEC 1/2/3/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 3, 0.02, "#,##0.02#", 0.128, "0.12" ), // use incr
+ new SetMxFrAndRndIncrItem( "18 en_US DEC 1/3/3/0.02", "en_US", NumberFormat.NUMBERSTYLE, 1, 3, 3, 0.02, "#,##0.020", 0.128, "0.12" ), // use incr; expFmt != ICU4C
+
+ new SetMxFrAndRndIncrItem( "20 en_US DEC 1/1/1/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 1, 0.0075, "#,##0.0", 0.019, "0.0" ),
+ new SetMxFrAndRndIncrItem( "21 en_US DEC 1/1/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 2, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
+ new SetMxFrAndRndIncrItem( "22 en_US DEC 1/1/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 2, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
+ new SetMxFrAndRndIncrItem( "23 en_US DEC 1/1/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
+ new SetMxFrAndRndIncrItem( "24 en_US DEC 1/1/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 1, 3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
+ new SetMxFrAndRndIncrItem( "25 en_US DEC 1/2/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 2, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
+ new SetMxFrAndRndIncrItem( "26 en_US DEC 1/2/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 2, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
+ new SetMxFrAndRndIncrItem( "27 en_US DEC 1/2/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
+ new SetMxFrAndRndIncrItem( "28 en_US DEC 1/2/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 2, 3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
+ new SetMxFrAndRndIncrItem( "29 en_US DEC 1/3/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 3, 3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
+ new SetMxFrAndRndIncrItem( "2A en_US DEC 1/3/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE, 1, 3, 3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
+ };
+
+ for (SetMxFrAndRndIncrItem item: items) {
+ ULocale locale = new ULocale(item.localeID);
+ DecimalFormat df = (DecimalFormat)NumberFormat.getInstance(locale, item.style);
+ df.setMinimumIntegerDigits(item.minInt);
+ df.setMinimumFractionDigits(item.minFrac);
+ df.setMaximumFractionDigits(item.maxFrac);
+ df.setRoundingIncrement(item.roundIncr);
+
+ boolean roundIncrUsed = (item.roundIncr != 0 &&
+ !PatternStringUtils.ignoreRoundingIncrement(java.math.BigDecimal.valueOf(item.roundIncr),item.maxFrac));
+ int fracForRoundIncr = 0;
+ if (roundIncrUsed) {
+ double testIncr = item.roundIncr;
+ for (; testIncr > ((int)testIncr); testIncr *= 10.0, fracForRoundIncr++);
+ }
+
+ int minInt = df.getMinimumIntegerDigits();
+ if (minInt != item.minInt) {
+ errln("test " + item.descrip + ": getMinimumIntegerDigits, expected " + item.minInt + ", got " + minInt);
+ }
+ int minFrac = df.getMinimumFractionDigits();
+ int expMinFrac = (roundIncrUsed)? fracForRoundIncr: item.minFrac;
+ if (minFrac != expMinFrac) {
+ errln("test " + item.descrip + ": getMinimumFractionDigits, expected " + expMinFrac + ", got " + minFrac);
+ }
+ int maxFrac = df.getMaximumFractionDigits();
+ int expMaxFrac = (roundIncrUsed)? fracForRoundIncr: item.maxFrac;
+ if (maxFrac != expMaxFrac) {
+ errln("test " + item.descrip + ": getMaximumFractionDigits, expected " + expMaxFrac + ", got " + maxFrac);
+ }
+ java.math.BigDecimal bigdec = df.getRoundingIncrement(); // why doesn't this return com.ibm.icu.math.BigDecimal?
+ double roundIncr = (bigdec != null)? bigdec.doubleValue(): 0.0;
+ double expRoundIncr = (roundIncrUsed)? item.roundIncr: 0.0;
+ if (roundIncr != expRoundIncr) {
+ errln("test " + item.descrip + ": getRoundingIncrement, expected " + expRoundIncr + ", got " + roundIncr);
+ }
+
+ String getPattern = df.toPattern();
+ if (!getPattern.equals(item.expPattern)) {
+ errln("test " + item.descrip + ": toPattern, expected " + item.expPattern + ", got " + getPattern);
+ }
+ String getFormat = df.format(item.valueToFmt);
+ if (!getFormat.equals(item.expFormat)) {
+ errln("test " + item.descrip + ": format, expected " + item.expFormat + ", got " + getFormat);
+ }
+ }
+ }
+
+ @Test
public void TestBug9936() {
DecimalFormat numberFormat =
(DecimalFormat) NumberFormat.getInstance(ULocale.US);
@@ -5849,10 +6030,10 @@ public class NumberFormatTest extends TestFmwk {
@Test
public void testParseNoExponent() throws ParseException {
DecimalFormat df = new DecimalFormat();
- assertEquals("Parse no exponent has wrong default", false, df.getParseNoExponent());
+ assertEquals("Parse no exponent has wrong default", false, df.isParseNoExponent());
Number result1 = df.parse("123E4");
df.setParseNoExponent(true);
- assertEquals("Parse no exponent getter is broken", true, df.getParseNoExponent());
+ assertEquals("Parse no exponent getter is broken", true, df.isParseNoExponent());
Number result2 = df.parse("123E4");
assertEquals("Exponent did not parse before setParseNoExponent", result1, new Long(1230000));
assertEquals("Exponent parsed after setParseNoExponent", result2, new Long(123));
@@ -5896,17 +6077,17 @@ public class NumberFormatTest extends TestFmwk {
for (int p = 0; p < patterns.length; p++) {
String pat = patterns[p];
DecimalFormat df = new DecimalFormat(pat);
- assertEquals("parseCaseSensitive default is wrong", false, df.getParseCaseSensitive());
+ assertEquals("parseCaseSensitive default is wrong", false, df.isParseCaseSensitive());
for (int i = 0; i < inputs.length; i++) {
String inp = inputs[i];
df.setParseCaseSensitive(false);
- assertEquals("parseCaseSensitive getter is broken", false, df.getParseCaseSensitive());
+ assertEquals("parseCaseSensitive getter is broken", false, df.isParseCaseSensitive());
ParsePosition actualInsensitive = new ParsePosition(0);
df.parse(inp, actualInsensitive);
assertEquals("Insensitive, pattern "+p+", input "+i,
expectedParsePositions[p*2][i], actualInsensitive.getIndex());
df.setParseCaseSensitive(true);
- assertEquals("parseCaseSensitive getter is broken", true, df.getParseCaseSensitive());
+ assertEquals("parseCaseSensitive getter is broken", true, df.isParseCaseSensitive());
ParsePosition actualSensitive = new ParsePosition(0);
df.parse(inp, actualSensitive);
assertEquals("Sensitive, pattern "+p+", input "+i,
@@ -5958,13 +6139,13 @@ public class NumberFormatTest extends TestFmwk {
for (int i=0; i<locs.length; i++) {
ULocale loc = locs[i];
DecimalFormat df1 = (DecimalFormat) NumberFormat.getNumberInstance(loc);
- assertFalse("Default should be false", df1.getSignAlwaysShown());
+ assertFalse("Default should be false", df1.isSignAlwaysShown());
df1.setSignAlwaysShown(true);
- assertTrue("Getter should now return true", df1.getSignAlwaysShown());
+ assertTrue("Getter should now return true", df1.isSignAlwaysShown());
DecimalFormat df2 = (DecimalFormat) NumberFormat.getCurrencyInstance(loc);
- assertFalse("Default should be false", df2.getSignAlwaysShown());
+ assertFalse("Default should be false", df2.isSignAlwaysShown());
df2.setSignAlwaysShown(true);
- assertTrue("Getter should now return true", df2.getSignAlwaysShown());
+ assertTrue("Getter should now return true", df2.isSignAlwaysShown());
for (int j=0; j<2; j++) {
DecimalFormat df = (j == 0) ? df1 : df2;
for (int k=0; k<numbers.length; k++) {
@@ -6330,6 +6511,32 @@ public class NumberFormatTest extends TestFmwk {
result = nf.parse(".0003e-2147483644");
assertEquals("Should not overflow",
"0", result.toString());
+
+ // Test largest parseable exponent
+ // This is limited by ICU's BigDecimal implementation
+ result = nf.parse("1e999999999");
+ assertEquals("Should not overflow",
+ "1E+999999999", result.toString());
+
+ // Test max value as well
+ String[] infinityInputs = {
+ "9876e1000000000",
+ "9876e2147483640",
+ "9876e2147483641",
+ "9876e2147483642",
+ "9876e2147483643",
+ "9876e2147483644",
+ "9876e2147483645",
+ "9876e2147483646",
+ "9876e2147483647",
+ "9876e2147483648",
+ "9876e2147483649",
+ };
+ for (String input : infinityInputs) {
+ result = nf.parse(input);
+ assertEquals("Should become Infinity: " + input,
+ "Infinity", result.toString());
+ }
}
@Test
@@ -6354,4 +6561,94 @@ public class NumberFormatTest extends TestFmwk {
assertEquals("Should round-trip without crashing", expectedUString, actualUString);
}
+
+ @Test
+ public void test20348_CurrencyPrefixOverride() {
+ DecimalFormat fmt = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.ENGLISH);
+ assertEquals("Initial pattern",
+ "¤#,##0.00", fmt.toPattern());
+ assertEquals("Initial prefix",
+ "¤", fmt.getPositivePrefix());
+ assertEquals("Initial suffix",
+ "-¤", fmt.getNegativePrefix());
+ assertEquals("Initial format",
+ "\u00A4100.00", fmt.format(100));
+
+ fmt.setPositivePrefix("$");
+ assertEquals("Set positive prefix pattern",
+ "$#,##0.00;-\u00A4#,##0.00", fmt.toPattern());
+ assertEquals("Set positive prefix prefix",
+ "$", fmt.getPositivePrefix());
+ assertEquals("Set positive prefix suffix",
+ "-¤", fmt.getNegativePrefix());
+ assertEquals("Set positive prefix format",
+ "$100.00", fmt.format(100));
+
+ fmt.setNegativePrefix("-$");
+ assertEquals("Set negative prefix pattern",
+ "$#,##0.00;'-'$#,##0.00", fmt.toPattern());
+ assertEquals("Set negative prefix prefix",
+ "$", fmt.getPositivePrefix());
+ assertEquals("Set negative prefix suffix",
+ "-$", fmt.getNegativePrefix());
+ assertEquals("Set negative prefix format",
+ "$100.00", fmt.format(100));
+ }
+
+ @Test
+ public void test20358_GroupingInPattern() {
+ DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
+ assertEquals("Initial pattern",
+ "#,##0.###", fmt.toPattern());
+ assertTrue("Initial grouping",
+ fmt.isGroupingUsed());
+ assertEquals("Initial format",
+ "54,321", fmt.format(54321));
+
+ fmt.setGroupingUsed(false);
+ assertEquals("Set grouping false",
+ "0.###", fmt.toPattern());
+ assertFalse("Set grouping false grouping",
+ fmt.isGroupingUsed());
+ assertEquals("Set grouping false format",
+ "54321", fmt.format(54321));
+
+ fmt.setGroupingUsed(true);
+ assertEquals("Set grouping true",
+ "#,##0.###", fmt.toPattern());
+ assertTrue("Set grouping true grouping",
+ fmt.isGroupingUsed());
+ assertEquals("Set grouping true format",
+ "54,321", fmt.format(54321));
+ }
+
+ @Test
+ public void test13731_DefaultCurrency() {
+ {
+ NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.CURRENCYSTYLE);
+ assertEquals("symbol", "¤1.10", nf.format(1.1));
+ assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
+ }
+ {
+ NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.ISOCURRENCYSTYLE);
+ assertEquals("iso_code", "XXX 1.10", nf.format(1.1));
+ assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
+ }
+ {
+ NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.PLURALCURRENCYSTYLE);
+ assertEquals("plural", "1.10 (unknown currency)", nf.format(1.1));
+ assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
+ }
+ }
+
+ @Test
+ public void test20499_CurrencyVisibleDigitsPlural() {
+ ULocale locale = new ULocale("ro-RO");
+ NumberFormat nf = NumberFormat.getInstance(locale, NumberFormat.PLURALCURRENCYSTYLE);
+ String expected = "24,00 lei românești";
+ for (int i=0; i<5; i++) {
+ String actual = nf.format(24);
+ assertEquals("iteration " + i, expected, actual);
+ }
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
index 31f78ea5b..5c9c6609f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralFormatTest.java
@@ -82,7 +82,7 @@ public class PluralFormatTest extends TestFmwk {
@Test
public void TestSingular1Locales() {
- String localeIDs = "bem,da,de,el,en,eo,es,et,fi,fo,he,it,nb,nl,nn,no,pt_PT,sv,af,bg,ca,eu,fur,fy,ha,ku,lb,ml," +
+ String localeIDs = "bem,da,de,el,en,eo,es,et,fi,fo,he,it,mr,nb,nl,nn,no,pt_PT,sv,af,bg,ca,eu,fur,fy,ha,ku,lb,ml," +
"nah,ne,om,or,pap,ps,so,sq,sw,ta,te,tk,ur,mn,gsw,rm";
String testPattern = "one{one} other{other}";
Map changes = new HashMap();
@@ -94,7 +94,7 @@ public class PluralFormatTest extends TestFmwk {
@Test
public void TestSingular01Locales() {
- String localeIDs = "ff,fr,kab,gu,mr,pa,pt,zu,bn";
+ String localeIDs = "ff,fr,kab,gu,pa,pt,zu,bn";
String testPattern = "one{one} other{other}";
Map changes = new HashMap();
changes.put(new Integer(0), "one");
@@ -148,7 +148,8 @@ public class PluralFormatTest extends TestFmwk {
changes.put(new Integer(1), "one");
changes.put(new Integer(2), "few");
changes.put(new Integer(20), "other");
- changes.put(new Integer(101), "few");
+ changes.put(new Integer(101), "other");
+ changes.put(new Integer(102), "few");
changes.put(new Integer(120), "other");
helperTestRules(localeIDs, testPattern, changes);
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
index 64d913825..5976761de 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/PluralRulesTest.java
@@ -41,6 +41,10 @@ import com.ibm.icu.dev.test.serializable.SerializableTestUtility;
import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Utility;
+import com.ibm.icu.number.FormattedNumber;
+import com.ibm.icu.number.NumberFormatter;
+import com.ibm.icu.number.Precision;
+import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.FixedDecimal;
@@ -323,8 +327,8 @@ public class PluralRulesTest extends TestFmwk {
public void testUniqueRules() {
main: for (ULocale locale : factory.getAvailableULocales()) {
PluralRules rules = factory.forLocale(locale);
- Map<String, PluralRules> keywordToRule = new HashMap<String, PluralRules>();
- Collection<FixedDecimalSamples> samples = new LinkedHashSet<FixedDecimalSamples>();
+ Map<String, PluralRules> keywordToRule = new HashMap<>();
+ Collection<FixedDecimalSamples> samples = new LinkedHashSet<>();
for (String keyword : rules.getKeywords()) {
for (SampleType sampleType : SampleType.values()) {
@@ -467,21 +471,66 @@ public class PluralRulesTest extends TestFmwk {
@Test
public void testBuiltInRules() {
- // spot check
- PluralRules rules = factory.forLocale(ULocale.US);
- assertEquals("us 0", PluralRules.KEYWORD_OTHER, rules.select(0));
- assertEquals("us 1", PluralRules.KEYWORD_ONE, rules.select(1));
- assertEquals("us 2", PluralRules.KEYWORD_OTHER, rules.select(2));
-
- rules = factory.forLocale(ULocale.JAPAN);
- assertEquals("ja 0", PluralRules.KEYWORD_OTHER, rules.select(0));
- assertEquals("ja 1", PluralRules.KEYWORD_OTHER, rules.select(1));
- assertEquals("ja 2", PluralRules.KEYWORD_OTHER, rules.select(2));
-
- rules = factory.forLocale(ULocale.createCanonical("ru"));
- assertEquals("ru 0", PluralRules.KEYWORD_MANY, rules.select(0));
- assertEquals("ru 1", PluralRules.KEYWORD_ONE, rules.select(1));
- assertEquals("ru 2", PluralRules.KEYWORD_FEW, rules.select(2));
+ Object[][] cases = {
+ {"en-US", PluralRules.KEYWORD_OTHER, 0},
+ {"en-US", PluralRules.KEYWORD_ONE, 1},
+ {"en-US", PluralRules.KEYWORD_OTHER, 2},
+ {"ja-JP", PluralRules.KEYWORD_OTHER, 0},
+ {"ja-JP", PluralRules.KEYWORD_OTHER, 1},
+ {"ja-JP", PluralRules.KEYWORD_OTHER, 2},
+ {"ru", PluralRules.KEYWORD_MANY, 0},
+ {"ru", PluralRules.KEYWORD_ONE, 1},
+ {"ru", PluralRules.KEYWORD_FEW, 2}
+ };
+ for (Object[] cas : cases) {
+ ULocale locale = new ULocale((String) cas[0]);
+ PluralRules rules = factory.forLocale(locale);
+ String expectedKeyword = (String) cas[1];
+ double number = (Integer) cas[2];
+ String message = locale + " " + number;
+ // Check both as double and as FormattedNumber.
+ assertEquals(message, expectedKeyword, rules.select(number));
+ FormattedNumber fn = NumberFormatter.withLocale(locale).format(number);
+ assertEquals(message, expectedKeyword, rules.select(fn));
+ }
+ }
+
+ @Test
+ public void testSelectTrailingZeros() {
+ UnlocalizedNumberFormatter unf = NumberFormatter.with()
+ .precision(Precision.fixedFraction(2));
+ Object[][] cases = {
+ // 1) locale
+ // 2) double expected keyword
+ // 3) formatted number expected keyword (2 fraction digits)
+ // 4) input number
+ {"bs", PluralRules.KEYWORD_FEW, PluralRules.KEYWORD_OTHER, 5.2}, // 5.2 => two, but 5.20 => other
+ {"si", PluralRules.KEYWORD_ONE, PluralRules.KEYWORD_ONE, 0.0},
+ {"si", PluralRules.KEYWORD_ONE, PluralRules.KEYWORD_ONE, 1.0},
+ {"si", PluralRules.KEYWORD_ONE, PluralRules.KEYWORD_OTHER, 0.1}, // 0.1 => one, but 0.10 => other
+ {"si", PluralRules.KEYWORD_ONE, PluralRules.KEYWORD_ONE, 0.01}, // 0.01 => one
+ {"hsb", PluralRules.KEYWORD_FEW, PluralRules.KEYWORD_FEW, 1.03}, // (f % 100 == 3) => few
+ {"hsb", PluralRules.KEYWORD_FEW, PluralRules.KEYWORD_OTHER, 1.3}, // 1.3 => few, but 1.30 => other
+ };
+ for (Object[] cas : cases) {
+ ULocale locale = new ULocale((String) cas[0]);
+ PluralRules rules = factory.forLocale(locale);
+ String expectedDoubleKeyword = (String) cas[1];
+ String expectedFormattedKeyword = (String) cas[2];
+ double number = (Double) cas[3];
+ String message = locale + " " + number;
+ // Check both as double and as FormattedNumber.
+ assertEquals(message, expectedDoubleKeyword, rules.select(number));
+ FormattedNumber fn = unf.locale(locale).format(number);
+ assertEquals(message, expectedFormattedKeyword, rules.select(fn));
+ }
+ }
+
+ @Test
+ public void testLocaleExtension() {
+ PluralRules rules = PluralRules.forLocale(new ULocale("pt@calendar=gregorian"));
+ String key = rules.select(1);
+ assertEquals("pt@calendar=gregorian select(1)", "one", key);
}
@Test
@@ -605,7 +654,7 @@ public class PluralRulesTest extends TestFmwk {
*/
@Test
public void TestGetSamples() {
- Set<ULocale> uniqueRuleSet = new HashSet<ULocale>();
+ Set<ULocale> uniqueRuleSet = new HashSet<>();
for (ULocale locale : factory.getAvailableULocales()) {
uniqueRuleSet.add(PluralRules.getFunctionalEquivalent(locale, null));
}
@@ -719,7 +768,7 @@ public class PluralRulesTest extends TestFmwk {
} else if ("null".equals(valueList)) {
values = null;
} else {
- values = new TreeSet<Double>();
+ values = new TreeSet<>();
for (String value : valueList.split(",")) {
values.add(Double.parseDouble(value));
}
@@ -825,9 +874,9 @@ public class PluralRulesTest extends TestFmwk {
// suppressed in
// INTEGER but not
// DECIMAL
- }, { { "en", new HashSet<Double>(Arrays.asList(1.0d)) }, // check that 1 is suppressed
+ }, { { "en", new HashSet<>(Arrays.asList(1.0d)) }, // check that 1 is suppressed
{ "one", KeywordStatus.SUPPRESSED, null }, { "other", KeywordStatus.UNBOUNDED, null } }, };
- Output<Double> uniqueValue = new Output<Double>();
+ Output<Double> uniqueValue = new Output<>();
for (Object[][] test : tests) {
ULocale locale = new ULocale((String) test[0][0]);
// NumberType numberType = (NumberType) test[1];
@@ -938,7 +987,7 @@ public class PluralRulesTest extends TestFmwk {
};
private void generateLOCALE_SNAPSHOT() {
- Comparator c = new CollectionUtilities.CollectionComparator<Comparable>();
+ Comparator c = new CollectionUtilities.CollectionComparator<>();
Relation<Set<StandardPluralCategories>, PluralRules> setsToRules = Relation.of(
new TreeMap<Set<StandardPluralCategories>, Set<PluralRules>>(c), TreeSet.class, PLURAL_RULE_COMPARATOR);
Relation<PluralRules, ULocale> data = Relation.of(
@@ -1003,11 +1052,11 @@ public class PluralRulesTest extends TestFmwk {
"ksh; zero: @integer 0; one: @integer 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
// [one, two, other]
- "iu,kw,naq,se,sma,smi,smj,smn,sms; one: @integer 1; two: @integer 2; other: @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, …",
+ "iu,naq,se,sma,smi,smj,smn,sms; one: @integer 1; two: @integer 2; other: @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, …",
// [one, few, other]
"shi; one: @integer 0, 1; few: @integer 2~10; other: @integer 11~26, 100, 1000, 10000, 100000, 1000000, …",
- "mo,ro; one: @integer 1; few: @integer 0, 2~16, 101, 1001, …; other: @integer 20~35, 100, 1000, 10000, 100000, 1000000, …",
+ "mo,ro; one: @integer 1; few: @integer 0, 2~16, 102, 1002, …; other: @integer 20~35, 100, 1000, 10000, 100000, 1000000, …",
"bs,hr,sh,sr; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; few: @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …; other: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",
// [one, two, few, other]
@@ -1032,7 +1081,8 @@ public class PluralRulesTest extends TestFmwk {
// [zero, one, two, few, many, other]
"ar; zero: @integer 0; one: @integer 1; two: @integer 2; few: @integer 3~10, 103~110, 1003, …; many: @integer 11~26, 111, 1011, …; other: @integer 100~102, 200~202, 300~302, 400~402, 500~502, 600, 1000, 10000, 100000, 1000000, …",
- "cy; zero: @integer 0; one: @integer 1; two: @integer 2; few: @integer 3; many: @integer 6; other: @integer 4, 5, 7~20, 100, 1000, 10000, 100000, 1000000, …", };
+ "cy; zero: @integer 0; one: @integer 1; two: @integer 2; few: @integer 3; many: @integer 6; other: @integer 4, 5, 7~20, 100, 1000, 10000, 100000, 1000000, …",
+ "kw; zero: @integer 0; one: @integer 1; two: @integer 2, 22, 42, 62, 82, 102, 122, 142, 1002, …; few: @integer 3, 23, 43, 63, 83, 103, 123, 143, 1003, …; many: @integer 21, 41, 61, 81, 101, 121, 141, 161, 1001, …; other: @integer 4~19, 100, 1000000, …", };
private <T extends Serializable> T serializeAndDeserialize(T original, Output<Integer> size) {
try {
@@ -1054,7 +1104,7 @@ public class PluralRulesTest extends TestFmwk {
@Test
public void TestSerialization() {
- Output<Integer> size = new Output<Integer>();
+ Output<Integer> size = new Output<>();
int max = 0;
for (ULocale locale : PluralRules.getAvailableULocales()) {
PluralRules item = PluralRules.forLocale(locale);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfRoundTripTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfRoundTripTest.java
index a8574c21c..5ba07e07b 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfRoundTripTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfRoundTripTest.java
@@ -140,6 +140,19 @@ public class RbnfRoundTripTest extends TestFmwk {
}
/**
+ * Perform an exhaustive round-trip test on the jpanyear spellout rules
+ */
+ @Test
+ public void TestJapaneseYearSpelloutRT() {
+ RuleBasedNumberFormat formatter
+ = new RuleBasedNumberFormat(Locale.JAPAN,
+ RuleBasedNumberFormat.SPELLOUT);
+ formatter.setDefaultRuleSet("%spellout-numbering-year-latn");
+
+ doTest(formatter, 0, 50);
+ }
+
+ /**
* Perform an exhaustive round-trip test on the Russian spellout rules
*/
@Test
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java
index fbfaa6b96..0dbe81e0f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RbnfTest.java
@@ -851,6 +851,26 @@ public class RbnfTest extends TestFmwk {
}
@Test
+ public void TestJpanyear()
+ {
+ Locale locale = new Locale("ja");
+ RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale,
+ RuleBasedNumberFormat.SPELLOUT);
+
+ String[][] testDataYear = {
+ { "0", "0" },
+ { "1", "\u5143" }, // 元
+ { "2", "2" },
+ { "10", "10" },
+ { "31", "31" },
+ };
+
+ formatter.setDefaultRuleSet("%spellout-numbering-year-latn");
+ logln("testing year rules");
+ doTest(formatter, testDataYear, true);
+ }
+
+ @Test
public void TestBigNumbers() {
BigInteger bigI = new BigInteger("1234567890", 10);
StringBuffer buf = new StringBuffer();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java
index 5e1866721..4c6d92c6a 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java
@@ -21,9 +21,11 @@ import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.RelativeDateTimeFormatter;
import com.ibm.icu.text.RelativeDateTimeFormatter.AbsoluteUnit;
import com.ibm.icu.text.RelativeDateTimeFormatter.Direction;
+import com.ibm.icu.text.RelativeDateTimeFormatter.FormattedRelativeDateTime;
import com.ibm.icu.text.RelativeDateTimeFormatter.RelativeDateTimeUnit;
import com.ibm.icu.text.RelativeDateTimeFormatter.RelativeUnit;
import com.ibm.icu.text.RelativeDateTimeFormatter.Style;
+import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.util.ULocale;
@RunWith(JUnit4.class)
@@ -366,6 +368,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.NEXT, AbsoluteUnit.DAY, "tomorrow"},
{Direction.NEXT, AbsoluteUnit.WEEK, "next week"},
{Direction.NEXT, AbsoluteUnit.MONTH, "next month"},
+ {Direction.NEXT, AbsoluteUnit.QUARTER, "next quarter"},
{Direction.NEXT, AbsoluteUnit.YEAR, "next year"},
{Direction.NEXT, AbsoluteUnit.MONDAY, "next Monday"},
{Direction.NEXT, AbsoluteUnit.TUESDAY, "next Tuesday"},
@@ -380,6 +383,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.LAST, AbsoluteUnit.DAY, "yesterday"},
{Direction.LAST, AbsoluteUnit.WEEK, "last week"},
{Direction.LAST, AbsoluteUnit.MONTH, "last month"},
+ {Direction.LAST, AbsoluteUnit.QUARTER, "last quarter"},
{Direction.LAST, AbsoluteUnit.YEAR, "last year"},
{Direction.LAST, AbsoluteUnit.MONDAY, "last Monday"},
{Direction.LAST, AbsoluteUnit.TUESDAY, "last Tuesday"},
@@ -392,6 +396,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.THIS, AbsoluteUnit.DAY, "today"},
{Direction.THIS, AbsoluteUnit.WEEK, "this week"},
{Direction.THIS, AbsoluteUnit.MONTH, "this month"},
+ {Direction.THIS, AbsoluteUnit.QUARTER, "this quarter"},
{Direction.THIS, AbsoluteUnit.YEAR, "this year"},
{Direction.THIS, AbsoluteUnit.MONDAY, "this Monday"},
{Direction.THIS, AbsoluteUnit.TUESDAY, "this Tuesday"},
@@ -404,6 +409,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.PLAIN, AbsoluteUnit.DAY, "day"},
{Direction.PLAIN, AbsoluteUnit.WEEK, "week"},
{Direction.PLAIN, AbsoluteUnit.MONTH, "month"},
+ {Direction.PLAIN, AbsoluteUnit.QUARTER, "quarter"},
{Direction.PLAIN, AbsoluteUnit.YEAR, "year"},
{Direction.PLAIN, AbsoluteUnit.MONDAY, "Monday"},
{Direction.PLAIN, AbsoluteUnit.TUESDAY, "Tuesday"},
@@ -430,6 +436,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.NEXT, AbsoluteUnit.DAY, "Tomorrow"},
{Direction.NEXT, AbsoluteUnit.WEEK, "Next week"},
{Direction.NEXT, AbsoluteUnit.MONTH, "Next month"},
+ {Direction.NEXT, AbsoluteUnit.QUARTER, "Next quarter"},
{Direction.NEXT, AbsoluteUnit.YEAR, "Next year"},
{Direction.NEXT, AbsoluteUnit.MONDAY, "Next Monday"},
@@ -445,6 +452,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.LAST, AbsoluteUnit.DAY, "Yesterday"},
{Direction.LAST, AbsoluteUnit.WEEK, "Last week"},
{Direction.LAST, AbsoluteUnit.MONTH, "Last month"},
+ {Direction.LAST, AbsoluteUnit.QUARTER, "Last quarter"},
{Direction.LAST, AbsoluteUnit.YEAR, "Last year"},
{Direction.LAST, AbsoluteUnit.MONDAY, "Last Monday"},
{Direction.LAST, AbsoluteUnit.TUESDAY, "Last Tuesday"},
@@ -457,6 +465,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.THIS, AbsoluteUnit.DAY, "Today"},
{Direction.THIS, AbsoluteUnit.WEEK, "This week"},
{Direction.THIS, AbsoluteUnit.MONTH, "This month"},
+ {Direction.THIS, AbsoluteUnit.QUARTER, "This quarter"},
{Direction.THIS, AbsoluteUnit.YEAR, "This year"},
{Direction.THIS, AbsoluteUnit.MONDAY, "This Monday"},
{Direction.THIS, AbsoluteUnit.TUESDAY, "This Tuesday"},
@@ -469,6 +478,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.PLAIN, AbsoluteUnit.DAY, "Day"},
{Direction.PLAIN, AbsoluteUnit.WEEK, "Week"},
{Direction.PLAIN, AbsoluteUnit.MONTH, "Month"},
+ {Direction.PLAIN, AbsoluteUnit.QUARTER, "Quarter"},
{Direction.PLAIN, AbsoluteUnit.YEAR, "Year"},
{Direction.PLAIN, AbsoluteUnit.MONDAY, "Monday"},
{Direction.PLAIN, AbsoluteUnit.TUESDAY, "Tuesday"},
@@ -501,6 +511,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.NEXT, AbsoluteUnit.WEEK, "next wk."},
{Direction.NEXT, AbsoluteUnit.MONTH, "next mo."},
+ {Direction.NEXT, AbsoluteUnit.QUARTER, "next qtr."},
{Direction.NEXT, AbsoluteUnit.YEAR, "next yr."},
{Direction.NEXT, AbsoluteUnit.MONDAY, "next Mon."},
@@ -517,6 +528,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.LAST, AbsoluteUnit.DAY, "yesterday"},
{Direction.LAST, AbsoluteUnit.WEEK, "last wk."},
{Direction.LAST, AbsoluteUnit.MONTH, "last mo."},
+ {Direction.LAST, AbsoluteUnit.QUARTER, "last qtr."},
{Direction.LAST, AbsoluteUnit.YEAR, "last yr."},
{Direction.LAST, AbsoluteUnit.MONDAY, "last Mon."},
{Direction.LAST, AbsoluteUnit.TUESDAY, "last Tue."},
@@ -531,6 +543,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.THIS, AbsoluteUnit.DAY, "today"},
{Direction.THIS, AbsoluteUnit.WEEK, "this wk."},
{Direction.THIS, AbsoluteUnit.MONTH, "this mo."},
+ {Direction.THIS, AbsoluteUnit.QUARTER, "this qtr."},
{Direction.THIS, AbsoluteUnit.YEAR, "this yr."},
{Direction.THIS, AbsoluteUnit.MONDAY, "this Mon."},
{Direction.THIS, AbsoluteUnit.TUESDAY, "this Tue."},
@@ -543,6 +556,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.PLAIN, AbsoluteUnit.DAY, "day"},
{Direction.PLAIN, AbsoluteUnit.WEEK, "wk."},
{Direction.PLAIN, AbsoluteUnit.MONTH, "mo."},
+ {Direction.PLAIN, AbsoluteUnit.QUARTER, "qtr."},
{Direction.PLAIN, AbsoluteUnit.YEAR, "yr."},
{Direction.PLAIN, AbsoluteUnit.MONDAY, "Mo"},
{Direction.PLAIN, AbsoluteUnit.TUESDAY, "Tu"},
@@ -575,6 +589,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.NEXT, AbsoluteUnit.WEEK, "next wk."},
{Direction.NEXT, AbsoluteUnit.MONTH, "next mo."},
+ {Direction.NEXT, AbsoluteUnit.QUARTER, "next qtr."},
{Direction.NEXT, AbsoluteUnit.YEAR, "next yr."},
{Direction.NEXT, AbsoluteUnit.MONDAY, "next M"},
@@ -591,6 +606,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.LAST, AbsoluteUnit.DAY, "yesterday"},
{Direction.LAST, AbsoluteUnit.WEEK, "last wk."},
{Direction.LAST, AbsoluteUnit.MONTH, "last mo."},
+ {Direction.LAST, AbsoluteUnit.QUARTER, "last qtr."},
{Direction.LAST, AbsoluteUnit.YEAR, "last yr."},
{Direction.LAST, AbsoluteUnit.MONDAY, "last M"},
{Direction.LAST, AbsoluteUnit.TUESDAY, "last Tu"},
@@ -603,6 +619,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.THIS, AbsoluteUnit.DAY, "today"},
{Direction.THIS, AbsoluteUnit.WEEK, "this wk."},
{Direction.THIS, AbsoluteUnit.MONTH, "this mo."},
+ {Direction.THIS, AbsoluteUnit.QUARTER, "this qtr."},
{Direction.THIS, AbsoluteUnit.YEAR, "this yr."},
{Direction.THIS, AbsoluteUnit.MONDAY, "this M"},
{Direction.THIS, AbsoluteUnit.TUESDAY, "this Tu"},
@@ -617,6 +634,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
{Direction.PLAIN, AbsoluteUnit.DAY, "day"},
{Direction.PLAIN, AbsoluteUnit.WEEK, "wk."},
{Direction.PLAIN, AbsoluteUnit.MONTH, "mo."},
+ {Direction.PLAIN, AbsoluteUnit.QUARTER, "qtr."},
{Direction.PLAIN, AbsoluteUnit.YEAR, "yr."},
{Direction.PLAIN, AbsoluteUnit.MONDAY, "M"},
{Direction.PLAIN, AbsoluteUnit.TUESDAY, "T"},
@@ -749,6 +767,37 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
"dans 5 jours", "dans 5 jours" /* 5 */
};
+ String[] ak_decDef_long_stdAlon_sec = { // falls back to root
+ /* text numeric */
+ "-5 s", "-5 s", /* -5 */
+ "-2.2 s", "-2.2 s", /* -2.2 */
+ "-2 s", "-2 s", /* -2 */
+ "-1 s", "-1 s", /* -1 */
+ "-0.7 s", "-0.7 s", /* -0.7 */
+ "now", "-0 s", /* -0 */
+ "now", "+0 s", /* 0 */
+ "+0.7 s", "+0.7 s", /* 0.7 */
+ "+1 s", "+1 s", /* 1 */
+ "+2 s", "+2 s", /* 2 */
+ "+5 s", "+5 s", /* 5 */
+ };
+
+ @SuppressWarnings("unused")
+ String[] enIN_decDef_short_midSent_weds = {
+ /* text numeric */
+ "5 Wed. ago", "5 Wed. ago", /* -5 */
+ "2.2 Wed. ago", "2.2 Wed. ago", /* -2.2 */
+ "2 Wed. ago", "2 Wed. ago", /* -2 */
+ "last Wed", "1 Wed. ago", /* -1 */
+ "0.7 Wed. ago", "0.7 Wed. ago", /* -0.7 */
+ "this Wed", "0 Wed. ago", /* -0 */
+ "this Wed", "in 0 Wed.", /* 0 */
+ "in 0.7 Wed.", "in 0.7 Wed.", /* 0.7 */
+ "next Wed", "in 1 Wed", /* 1 */ // in 1 Wed. missing in logical group
+ "in 2 Wed.", "in 2 Wed.", /* 2 */
+ "in 5 Wed.", "in 5 Wed." /* 5 */
+ };
+
class TestRelativeDateTimeUnitItem {
public String localeID;
public int decPlaces; /* fixed decimal places; -1 to use default num formatter */
@@ -781,6 +830,11 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
RelativeDateTimeUnit.TUESDAY, en_dec0_long_midSent_tues),
new TestRelativeDateTimeUnitItem("fr", -1, Style.LONG, DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
RelativeDateTimeUnit.DAY, fr_decDef_long_midSent_day),
+ new TestRelativeDateTimeUnitItem("ak", -1, Style.LONG, DisplayContext.CAPITALIZATION_FOR_STANDALONE,
+ RelativeDateTimeUnit.SECOND, ak_decDef_long_stdAlon_sec),
+ // ICU4J RelativeDateTimeFormatter does not currently support RelativeDateTimeUnit.WEDNESDAY
+ //new TestRelativeDateTimeUnitItem("en_IN", -1, Style.SHORT, DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,
+ // RelativeDateTimeUnit.WEDNESDAY, enIN_decDef_short_midSent_weds),
};
for (TestRelativeDateTimeUnitItem item: items) {
ULocale uloc = new ULocale(item.localeID);
@@ -974,12 +1028,101 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
assertEquals("narrow: in 6 qtr", "in 6 qtr", w);
}
-@Test
-public void TestLocales() {
- ULocale[] availableLocales = ULocale.getAvailableLocales();
- for (ULocale loc: availableLocales) {
- RelativeDateTimeFormatter.getInstance(loc);
+ @Test
+ public void TestLocales() {
+ ULocale[] availableLocales = ULocale.getAvailableLocales();
+ for (ULocale loc: availableLocales) {
+ RelativeDateTimeFormatter.getInstance(loc);
+ }
+ }
+
+ @Test
+ public void TestFields() {
+ RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(ULocale.US);
+
+ {
+ String message = "automatic absolute unit";
+ FormattedRelativeDateTime fv = fmt.formatToValue(1, RelativeDateTimeUnit.DAY);
+ String expectedString = "tomorrow";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.LITERAL, 0, 8}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+ {
+ String message = "automatic numeric unit";
+ FormattedRelativeDateTime fv = fmt.formatToValue(3, RelativeDateTimeUnit.DAY);
+ String expectedString = "in 3 days";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.LITERAL, 0, 2},
+ {NumberFormat.Field.INTEGER, 3, 4},
+ {RelativeDateTimeFormatter.Field.NUMERIC, 3, 4},
+ {RelativeDateTimeFormatter.Field.LITERAL, 5, 9}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+ {
+ String message = "manual absolute unit";
+ FormattedRelativeDateTime fv = fmt.formatToValue(Direction.NEXT, AbsoluteUnit.MONDAY);
+ String expectedString = "next Monday";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.LITERAL, 0, 11}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+ {
+ String message = "manual numeric unit";
+ FormattedRelativeDateTime fv = fmt.formatNumericToValue(1.5, RelativeDateTimeUnit.WEEK);
+ String expectedString = "in 1.5 weeks";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.LITERAL, 0, 2},
+ {NumberFormat.Field.INTEGER, 3, 4},
+ {NumberFormat.Field.DECIMAL_SEPARATOR, 4, 5},
+ {NumberFormat.Field.FRACTION, 5, 6},
+ {RelativeDateTimeFormatter.Field.NUMERIC, 3, 6},
+ {RelativeDateTimeFormatter.Field.LITERAL, 7, 12}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+ {
+ String message = "manual numeric resolved unit";
+ FormattedRelativeDateTime fv = fmt.formatToValue(12, Direction.LAST, RelativeUnit.HOURS);
+ String expectedString = "12 hours ago";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {RelativeDateTimeFormatter.Field.NUMERIC, 0, 2},
+ {RelativeDateTimeFormatter.Field.LITERAL, 3, 12}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+
+ // Test when the number field is at the end
+ fmt = RelativeDateTimeFormatter.getInstance(new ULocale("sw"));
+ {
+ String message = "numeric field at end";
+ FormattedRelativeDateTime fv = fmt.formatToValue(12, RelativeDateTimeUnit.HOUR);
+ String expectedString = "baada ya saa 12";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.LITERAL, 0, 12},
+ {NumberFormat.Field.INTEGER, 13, 15},
+ {RelativeDateTimeFormatter.Field.NUMERIC, 13, 15}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
+ }
+
+ @Test
+ public void TestRBNF() {
+ RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ULocale.US, RuleBasedNumberFormat.SPELLOUT);
+ RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(ULocale.US, rbnf);
+ assertEquals("format (direction)", "in five seconds", fmt.format(5, Direction.NEXT, RelativeUnit.SECONDS));
+ assertEquals("formatNumeric", "one week ago", fmt.formatNumeric(-1, RelativeDateTimeUnit.WEEK));
+ assertEquals("format (absolute)", "yesterday", fmt.format(Direction.LAST, AbsoluteUnit.DAY));
+ assertEquals("format (relative)", "in forty-two months", fmt.format(42, RelativeDateTimeUnit.MONTH));
+
+ {
+ String message = "formatToValue (relative)";
+ FormattedRelativeDateTime fv = fmt.formatToValue(-100, RelativeDateTimeUnit.YEAR);
+ String expectedString = "one hundred years ago";
+ Object[][] expectedFieldPositions = new Object[][]{
+ {RelativeDateTimeFormatter.Field.NUMERIC, 0, 11},
+ {RelativeDateTimeFormatter.Field.LITERAL, 12, 21}};
+ FormattedValueTest.checkFormattedValue(message, fv, expectedString, expectedFieldPositions);
+ }
}
-}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TestMessageFormat.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TestMessageFormat.java
index 39235e96b..10d65002e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TestMessageFormat.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TestMessageFormat.java
@@ -40,6 +40,8 @@ import com.ibm.icu.text.MessagePattern;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.text.UFormat;
+import com.ibm.icu.util.Calendar;
+import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
@@ -111,7 +113,7 @@ public class TestMessageFormat extends TestFmwk {
errln("Number format creation failed for " + locale[i].getDisplayName());
continue;
}
- FieldPosition pos = new FieldPosition(0);
+ FieldPosition pos = new FieldPosition(FieldPosition_DONT_CARE);
buffer.setLength(0);
form.format(myNumber, buffer, pos);
parsePos.setIndex(0);
@@ -215,7 +217,7 @@ public class TestMessageFormat extends TestFmwk {
//it_out << "Pat out: " << form.toPattern(buffer));
StringBuffer result = new StringBuffer();
- FieldPosition fieldpos = new FieldPosition(0);
+ FieldPosition fieldpos = new FieldPosition(FieldPosition_DONT_CARE);
form.format(testArgs, result, fieldpos);
assertEquals("format", testResultStrings[i], result.toString());
@@ -260,7 +262,7 @@ public class TestMessageFormat extends TestFmwk {
return;
}
Object testArgs1[] = { "abc", "def" };
- FieldPosition fieldpos = new FieldPosition(0);
+ FieldPosition fieldpos = new FieldPosition(FieldPosition_DONT_CARE);
assertEquals("format",
"There are abc files on def",
form.format(testArgs1, buffer2, fieldpos).toString());
@@ -458,7 +460,7 @@ public class TestMessageFormat extends TestFmwk {
MessageFormat msg = new MessageFormat(formatStr, Locale.ENGLISH);
result.setLength(0);
- FieldPosition pos = new FieldPosition(0);
+ FieldPosition pos = new FieldPosition(FieldPosition_DONT_CARE);
result = msg.format(
arguments,
result,
@@ -512,7 +514,7 @@ public class TestMessageFormat extends TestFmwk {
String compareStr = "On Aug 8, 1997, it began.";
MessageFormat msg = new MessageFormat(formatStr);
- FieldPosition fp = new FieldPosition(0);
+ FieldPosition fp = new FieldPosition(FieldPosition_DONT_CARE);
try {
msg.format(new Date(871068000000L),
@@ -923,7 +925,7 @@ public class TestMessageFormat extends TestFmwk {
MessageFormat msg = new MessageFormat(formatStr, ULocale.US);
result.setLength(0);
- FieldPosition pos = new FieldPosition(0);
+ FieldPosition pos = new FieldPosition(FieldPosition_DONT_CARE);
result = msg.format(
arguments,
result,
@@ -940,7 +942,7 @@ public class TestMessageFormat extends TestFmwk {
msg.setFormatsByArgumentIndex(fmts);
result.setLength(0);
- pos = new FieldPosition(0);
+ pos = new FieldPosition(FieldPosition_DONT_CARE);
result = msg.format(
arguments,
result,
@@ -952,7 +954,7 @@ public class TestMessageFormat extends TestFmwk {
Format newFmt = NumberFormat.getCurrencyInstance(ULocale.GERMAN);
msg.setFormatByArgumentIndex(0, newFmt);
result.setLength(0);
- pos = new FieldPosition(0);
+ pos = new FieldPosition(FieldPosition_DONT_CARE);
result = msg.format(
arguments,
result,
@@ -1008,7 +1010,7 @@ public class TestMessageFormat extends TestFmwk {
String compareStr = "On Aug 8, 1997, it began.";
MessageFormat msg = new MessageFormat(formatStr);
- FieldPosition fp = new FieldPosition(0);
+ FieldPosition fp = new FieldPosition(FieldPosition_DONT_CARE);
try {
msg.format(arguments.get("startDate"), result, fp);
@@ -1118,7 +1120,7 @@ public class TestMessageFormat extends TestFmwk {
gotException = false;
try {
Object args[] = {new Long(42)};
- msg.format(args, new StringBuffer(), new FieldPosition(0));
+ msg.format(args, new StringBuffer(), new FieldPosition(FieldPosition_DONT_CARE));
} catch (IllegalArgumentException e) {
gotException = true;
}
@@ -1131,7 +1133,7 @@ public class TestMessageFormat extends TestFmwk {
gotException = false;
try {
Object args[] = {new Long(42)};
- msg.format((Object) args, new StringBuffer(), new FieldPosition(0));
+ msg.format((Object) args, new StringBuffer(), new FieldPosition(FieldPosition_DONT_CARE));
} catch (IllegalArgumentException e) {
gotException = true;
}
@@ -1878,7 +1880,7 @@ public class TestMessageFormat extends TestFmwk {
map.put("_oOo_", new Integer(3));
StringBuffer result = new StringBuffer();
assertEquals("trim-named-arg format() failed", "x 3 y",
- m.format(map, result, new FieldPosition(0)).toString());
+ m.format(map, result, new FieldPosition(FieldPosition_DONT_CARE)).toString());
}
@Test
@@ -2116,10 +2118,44 @@ public class TestMessageFormat extends TestFmwk {
MessageFormat msgf = new MessageFormat(messagePattern, locale);
StringBuffer sb = new StringBuffer();
- FieldPosition fpos = new FieldPosition(0);
+ FieldPosition fpos = new FieldPosition(FieldPosition_DONT_CARE);
msgf.format(new Object[] { arg }, sb, fpos);
assertEquals(messagePattern, expected, sb.toString());
}
}
+
+ private static void doTheRealDateTimeSkeletonTesting(Date date, String messagePattern, ULocale locale, String expected) {
+
+ MessageFormat msgf = new MessageFormat(messagePattern, locale);
+ StringBuffer sb = new StringBuffer();
+ FieldPosition fpos = new FieldPosition(FieldPosition_DONT_CARE);
+ msgf.format(new Object[] { date }, sb, fpos);
+
+ assertEquals(messagePattern, expected, sb.toString());
+ }
+
+ @Test
+ public void TestMessageFormatDateSkeleton() {
+ Date date = new GregorianCalendar(2021, Calendar.NOVEMBER, 23, 16, 42, 55).getTime();
+
+ doTheRealDateTimeSkeletonTesting(date, "{0,date,::MMMMd}", ULocale.ENGLISH, "November 23");
+ doTheRealDateTimeSkeletonTesting(date, "{0,date,::yMMMMdjm}", ULocale.ENGLISH, "November 23, 2021, 4:42 PM");
+ doTheRealDateTimeSkeletonTesting(date, "{0,date, :: yMMMMd }", ULocale.ENGLISH, "November 23, 2021");
+ doTheRealDateTimeSkeletonTesting(date, "{0,date,::yMMMMd}", ULocale.FRENCH, "23 novembre 2021");
+ doTheRealDateTimeSkeletonTesting(date, "Expiration: {0,date,::yMMM}!", ULocale.ENGLISH, "Expiration: Nov 2021!");
+ doTheRealDateTimeSkeletonTesting(date, "{0,date,'::'yMMMMd}", ULocale.ENGLISH, "::2021November23"); // pattern literal
+ }
+
+ @Test
+ public void TestMessageFormatTimeSkeleton() {
+ Date date = new GregorianCalendar(2021, Calendar.NOVEMBER, 23, 16, 42, 55).getTime();
+
+ doTheRealDateTimeSkeletonTesting(date, "{0,time,::MMMMd}", ULocale.ENGLISH, "November 23");
+ doTheRealDateTimeSkeletonTesting(date, "{0,time,::yMMMMdjm}", ULocale.ENGLISH, "November 23, 2021, 4:42 PM");
+ doTheRealDateTimeSkeletonTesting(date, "{0,time, :: yMMMMd }", ULocale.ENGLISH, "November 23, 2021");
+ doTheRealDateTimeSkeletonTesting(date, "{0,time,::yMMMMd}", ULocale.FRENCH, "23 novembre 2021");
+ doTheRealDateTimeSkeletonTesting(date, "Expiration: {0,time,::yMMM}!", ULocale.ENGLISH, "Expiration: Nov 2021!");
+ doTheRealDateTimeSkeletonTesting(date, "{0,time,'::'yMMMMd}", ULocale.ENGLISH, "::2021November23"); // pattern literal
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/TestUScript.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/TestUScript.java
index 2935a437c..96583b19a 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/TestUScript.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/TestUScript.java
@@ -329,6 +329,8 @@ public class TestUScript extends TestFmwk {
// new in ICU 61
"Dogra", "Gunjala_Gondi", "Makasar", "Medefaidrin",
"Hanifi_Rohingya", "Sogdian", "Old_Sogdian",
+ // new in ICU 64
+ "Elymaic", "Nyiakeng_Puachue_Hmong", "Nandinagari", "Wancho",
};
String[] expectedShort = new String[]{
"Bali", "Batk", "Blis", "Brah", "Cham", "Cirt", "Cyrs", "Egyd", "Egyh", "Egyp",
@@ -361,6 +363,8 @@ public class TestUScript extends TestFmwk {
"Gonm", "Soyo", "Zanb",
// new in ICU 61
"Dogr", "Gong", "Maka", "Medf", "Rohg", "Sogd", "Sogo",
+ // new in ICU 64
+ "Elym", "Hmnp", "Nand", "Wcho",
};
if(expectedLong.length!=(UScript.CODE_LIMIT-UScript.BALINESE)) {
errln("need to add new script codes in lang.TestUScript.java!");
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java
index 1649a718d..7d2948dfa 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java
@@ -960,8 +960,8 @@ public final class UCharacterCaseTest extends TestFmwk
// Iterate once forward, once backward, to cover more runtime conditions.
int srcLength = expSrcIndex;
int destLength = expDestIndex;
- List<Integer> srcIndexes = new ArrayList<Integer>();
- List<Integer> destIndexes = new ArrayList<Integer>();
+ List<Integer> srcIndexes = new ArrayList<>();
+ List<Integer> destIndexes = new ArrayList<>();
srcIndexes.add(-1);
destIndexes.add(-1);
int srcIndex = 0;
@@ -1503,6 +1503,18 @@ public final class UCharacterCaseTest extends TestFmwk
assertEquals("title", "\u1F88\u1F80\u1FF3", result);
}
+ @Test
+ public void TestFoldBug20316() {
+ String s = "廬ᾒ뻪ᣃइ垚Ⴡₓ렞체ꖲ갹ݖ䕷꾬쯎㊅ᦘᰄ㸜䡏遁럢豑黾奯㸀⊻줮끎蒹衤劔뽳趧熶撒쫃窩겨ཇ脌쵐嫑⟑겭㋋濜隣ᳰ봢ℼ櫩靛㉃炔鋳" +
+ "оे⳨ᦧྃ깢粣ᑤꇪ찃̹鵄ዤꛛᰙ⡝捣쯋톐蕩栭쥀뎊ᄯ৻恳〬昴껤룩列潱ᑮ煃鶖안꽊鹭宪帐❖ा쥈잔";
+ String result = CaseMap.fold().apply(s);
+ assertTrue("廬ᾒ...->廬ἢι...", result.startsWith("廬ἢι"));
+ s = "儊ẖ깸ᝓ恷ᇁ䜄쌼ꇸჃ䗑䘬䒥㈴槁蛚紆洔㖣믏亝醣黹Ά嶨䖕篕舀ꖧ₭ଯᒗ✧ԗ墖쁳㽎苊澎긁⾆⒞蠻왃囨ᡠ邏꾭⪐턣搤穳≠톲絋砖ሷ⠆" +
+ "瞏惢鵶剕듘ᅤ♟Ԡⴠ⊡鹔ጙ갑⣚堟ᣗ✸㕇絮䠎瘗⟡놥擢ꉭ佱ྪ飹痵⿑⨴츿璿僖㯷넴鋰膄釚겼ナ黪差";
+ result = CaseMap.fold().apply(s);
+ assertTrue("儊ẖ...->儊h\u0331...", result.startsWith("儊h\u0331"));
+ }
+
// private data members - test data --------------------------------------
private static final Locale TURKISH_LOCALE_ = new Locale("tr", "TR");
@@ -1747,7 +1759,7 @@ public final class UCharacterCaseTest extends TestFmwk
*/
private String[] getUnicodeStrings(String str)
{
- List<String> v = new ArrayList<String>(10);
+ List<String> v = new ArrayList<>(10);
int start = 0;
for (int casecount = 4; casecount > 0; casecount --) {
int end = str.indexOf("; ", start);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterTest.java
index fc8e89dd3..dd8357ab9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterTest.java
@@ -56,7 +56,7 @@ public final class UCharacterTest extends TestFmwk
/**
* Expected Unicode version.
*/
- private final VersionInfo VERSION_ = VersionInfo.getInstance(11);
+ private final VersionInfo VERSION_ = VersionInfo.getInstance(12, 1);
// constructor ===================================================
@@ -1232,28 +1232,54 @@ public final class UCharacterTest extends TestFmwk
@Test
public void TestUCharFromNameUnderflow() {
// Ticket #10889: Underflow crash when there is no dash.
- int c = UCharacter.getCharFromExtendedName("<NO BREAK SPACE>");
+ String name = "<NO BREAK SPACE>";
+ int c = UCharacter.getCharFromExtendedName(name);
if(c >= 0) {
- errln("UCharacter.getCharFromExtendedName(<NO BREAK SPACE>) = U+" + hex(c) +
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
" but should fail (-1)");
}
// Test related edge cases.
- c = UCharacter.getCharFromExtendedName("<-00a0>");
+ name = "<-00a0>";
+ c = UCharacter.getCharFromExtendedName(name);
if(c >= 0) {
- errln("UCharacter.getCharFromExtendedName(<-00a0>) = U+" + hex(c) +
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
" but should fail (-1)");
}
- c = UCharacter.getCharFromExtendedName("<control->");
+ name = "<control->";
+ c = UCharacter.getCharFromExtendedName(name);
if(c >= 0) {
- errln("UCharacter.getCharFromExtendedName(<control->) = U+" + hex(c) +
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
" but should fail (-1)");
}
- c = UCharacter.getCharFromExtendedName("<control-111111>");
+ name = "<control-111111>";
+ c = UCharacter.getCharFromExtendedName(name);
if(c >= 0) {
- errln("UCharacter.getCharFromExtendedName(<control-111111>) = U+" + hex(c) +
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
+ " but should fail (-1)");
+ }
+
+ // ICU-20292: integer overflow
+ name = "<noncharacter-10010FFFF>";
+ c = UCharacter.getCharFromExtendedName(name);
+ if(c >= 0) {
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
+ " but should fail (-1)");
+ }
+
+ name = "<noncharacter-00010FFFF>"; // too many digits even if only leading 0s
+ c = UCharacter.getCharFromExtendedName(name);
+ if(c >= 0) {
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
+ " but should fail (-1)");
+ }
+
+ name = "<noncharacter-fFFf>>";
+ c = UCharacter.getCharFromExtendedName(name);
+ if(c >= 0) {
+ errln("UCharacter.getCharFromExtendedName(" + name + ") = U+" + hex(c) +
" but should fail (-1)");
}
}
@@ -1569,6 +1595,8 @@ public final class UCharacterTest extends TestFmwk
{ 0x1E800, UCharacterDirection.LEFT_TO_RIGHT }, /* new default-R range in Unicode 5.2: U+1E800 - U+1EFFF */
{ 0x1EC70, UCharacterDirection.RIGHT_TO_LEFT }, // Unicode 11 changes U+1EC70..U+1ECBF from R to AL.
{ 0x1ECC0, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
+ { 0x1ED00, UCharacterDirection.RIGHT_TO_LEFT }, // Unicode 12 changes U+1ED00..U+1ED4F from R to AL.
+ { 0x1ED50, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
{ 0x1EE00, UCharacterDirection.RIGHT_TO_LEFT },
{ 0x1EF00, UCharacterDirection.RIGHT_TO_LEFT_ARABIC }, /* Unicode 6.1 changes U+1EE00..U+1EEFF from R to AL */
{ 0x1F000, UCharacterDirection.RIGHT_TO_LEFT },
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java
index 6696daa2b..5c528c620 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java
@@ -204,14 +204,14 @@ public class AffixUtilsTest {
String input = cas[0];
String expected = cas[1];
sb.clear();
- AffixUtils.unescape(input, sb, 0, provider);
+ AffixUtils.unescape(input, sb, 0, provider, null);
assertEquals("With symbol provider on <" + input + ">", expected, sb.toString());
}
// Test insertion position
sb.clear();
sb.append("abcdefg", null);
- AffixUtils.unescape("-+%", sb, 4, provider);
+ AffixUtils.unescape("-+%", sb, 4, provider, null);
assertEquals("Symbol provider into middle", "abcd123efg", sb.toString());
}
@@ -237,7 +237,7 @@ public class AffixUtilsTest {
private static String unescapeWithDefaults(String input) {
NumberStringBuilder nsb = new NumberStringBuilder();
- int length = AffixUtils.unescape(input, nsb, 0, DEFAULT_SYMBOL_PROVIDER);
+ int length = AffixUtils.unescape(input, nsb, 0, DEFAULT_SYMBOL_PROVIDER, null);
assertEquals("Return value of unescape", nsb.length(), length);
return nsb.toString();
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java
index 18a5dc32a..9271d94b4 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/DecimalQuantityTest.java
@@ -22,6 +22,8 @@ import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.impl.number.DecimalQuantity;
import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
+import com.ibm.icu.impl.number.NumberStringBuilder;
+import com.ibm.icu.impl.number.RoundingUtils;
import com.ibm.icu.number.LocalizedNumberFormatter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
@@ -36,7 +38,7 @@ public class DecimalQuantityTest extends TestFmwk {
public void testBehavior() throws ParseException {
// Make a list of several formatters to test the behavior of DecimalQuantity.
- List<LocalizedNumberFormatter> formats = new ArrayList<LocalizedNumberFormatter>();
+ List<LocalizedNumberFormatter> formats = new ArrayList<>();
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
@@ -120,7 +122,7 @@ public class DecimalQuantityTest extends TestFmwk {
assertEquals("Double is not valid", Double.toString(Double.parseDouble(str)), str);
}
- List<DecimalQuantity> qs = new ArrayList<DecimalQuantity>();
+ List<DecimalQuantity> qs = new ArrayList<>();
BigDecimal d = new BigDecimal(str);
qs.add(new DecimalQuantity_SimpleStorage(d));
if (mode == 0)
@@ -167,8 +169,8 @@ public class DecimalQuantityTest extends TestFmwk {
DecimalQuantity q0 = rq.createCopy();
// Force an accurate double
q0.roundToInfinity();
- q0.setIntegerLength(1, Integer.MAX_VALUE);
- q0.setFractionLength(1, Integer.MAX_VALUE);
+ q0.setMinInteger(1);
+ q0.setMinFraction(1);
String actual = q0.toPlainString();
assertEquals("Unexpected output from simple string conversion (" + q0 + ")", expected, actual);
}
@@ -234,8 +236,12 @@ public class DecimalQuantityTest extends TestFmwk {
for (LocalizedNumberFormatter format : formats) {
DecimalQuantity q0 = rq0.createCopy();
DecimalQuantity q1 = rq1.createCopy();
- String s1 = format.format(q0).toString();
- String s2 = format.format(q1).toString();
+ NumberStringBuilder nsb1 = new NumberStringBuilder();
+ NumberStringBuilder nsb2 = new NumberStringBuilder();
+ format.formatImpl(q0, nsb1);
+ format.formatImpl(q1, nsb2);
+ String s1 = nsb1.toString();
+ String s2 = nsb2.toString();
assertEquals("Different output from formatter (" + q0 + ", " + q1 + ")", s1, s2);
}
}
@@ -304,6 +310,15 @@ public class DecimalQuantityTest extends TestFmwk {
assertFalse("Should not be using byte array", fq.isUsingBytes());
assertEquals("Failed on round", "1.23412341234E+16", fq.toScientificString());
assertNull("Failed health check", fq.checkHealth());
+ // Bytes with popFromLeft
+ fq.setToBigDecimal(new BigDecimal("999999999999999999"));
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 bytes 999999999999999999E0>");
+ fq.applyMaxInteger(17);
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 bytes 99999999999999999E0>");
+ fq.applyMaxInteger(16);
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 9999999999999999E0>");
+ fq.applyMaxInteger(15);
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 999999999999999E0>");
}
@Test
@@ -388,25 +403,26 @@ public class DecimalQuantityTest extends TestFmwk {
@Test
public void testDecimalQuantityBehaviorStandalone() {
DecimalQuantity_DualStorageBCD fq = new DecimalQuantity_DualStorageBCD();
- assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 0E0>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 0E0>");
fq.setToInt(51423);
- assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 51423E0>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 51423E0>");
fq.adjustMagnitude(-3);
- assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 51423E-3>");
- fq.setToLong(999999999999000L);
- assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 999999999999E3>");
- fq.setIntegerLength(2, 5);
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:0:-999 long 999999999999E3>");
- fq.setFractionLength(3, 6);
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 999999999999E3>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 51423E-3>");
+ fq.setToLong(90909090909000L);
+ assertToStringAndHealth(fq, "<DecimalQuantity 0:0 long 90909090909E3>");
+ fq.setMinInteger(2);
+ fq.applyMaxInteger(5);
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:0 long 9E3>");
+ fq.setMinFraction(3);
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:-3 long 9E3>");
fq.setToDouble(987.654321);
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:-3 long 987654321E-6>");
fq.roundToInfinity();
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:-3 long 987654321E-6>");
fq.roundToIncrement(new BigDecimal("0.005"), MATH_CONTEXT_HALF_EVEN);
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987655E-3>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:-3 long 987655E-3>");
fq.roundToMagnitude(-2, MATH_CONTEXT_HALF_EVEN);
- assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 98766E-2>");
+ assertToStringAndHealth(fq, "<DecimalQuantity 2:-3 long 98766E-2>");
}
@Test
@@ -481,8 +497,7 @@ public class DecimalQuantityTest extends TestFmwk {
Object[][] cases = new Object[][] {
{ "0", 0.0 },
{ "514.23", 514.23 },
- // NOTE: This does not currently pass in Java. See DecimalFormat_AbstractBCD#toDecimal.
- // { "-3.142E-271", -3.142e-271 }
+ { "-3.142E-271", -3.142e-271 }
};
for (Object[] cas : cases) {
@@ -500,15 +515,91 @@ public class DecimalQuantityTest extends TestFmwk {
public void testMaxDigits() {
DecimalQuantity_DualStorageBCD dq = new DecimalQuantity_DualStorageBCD(876.543);
dq.roundToInfinity();
- dq.setIntegerLength(0, 2);
- dq.setFractionLength(0, 2);
+ dq.setMinInteger(0);
+ dq.applyMaxInteger(2);
+ dq.setMinFraction(0);
+ dq.roundToMagnitude(-2, RoundingUtils.mathContextUnlimited(RoundingMode.FLOOR));
assertEquals("Should trim, toPlainString", "76.54", dq.toPlainString());
assertEquals("Should trim, toScientificString", "7.654E+1", dq.toScientificString());
assertEquals("Should trim, toLong", 76, dq.toLong(true));
assertEquals("Should trim, toFractionLong", 54, dq.toFractionLong(false));
- if (!logKnownIssue("13701", "consider cleaning up")) {
- assertEquals("Should trim, toDouble", 76.54, dq.toDouble());
- assertEquals("Should trim, toBigDecimal", new BigDecimal("76.54"), dq.toBigDecimal());
+ assertEquals("Should trim, toDouble", 76.54, dq.toDouble());
+ assertEquals("Should trim, toBigDecimal", new BigDecimal("76.54"), dq.toBigDecimal());
+ }
+
+ @Test
+ public void testNickelRounding() {
+ Object[][] cases = new Object[][] {
+ {1.000, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.001, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.010, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.020, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.024, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.025, -2, RoundingMode.HALF_EVEN, "1."},
+ {1.025, -2, RoundingMode.HALF_DOWN, "1."},
+ {1.025, -2, RoundingMode.HALF_UP, "1.05"},
+ {1.026, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.030, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.040, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.050, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.060, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.070, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.074, -2, RoundingMode.HALF_EVEN, "1.05"},
+ {1.075, -2, RoundingMode.HALF_DOWN, "1.05"},
+ {1.075, -2, RoundingMode.HALF_UP, "1.1"},
+ {1.075, -2, RoundingMode.HALF_EVEN, "1.1"},
+ {1.076, -2, RoundingMode.HALF_EVEN, "1.1"},
+ {1.080, -2, RoundingMode.HALF_EVEN, "1.1"},
+ {1.090, -2, RoundingMode.HALF_EVEN, "1.1"},
+ {1.099, -2, RoundingMode.HALF_EVEN, "1.1"},
+ {1.999, -2, RoundingMode.HALF_EVEN, "2."},
+ {2.25, -1, RoundingMode.HALF_EVEN, "2."},
+ {2.25, -1, RoundingMode.HALF_UP, "2.5"},
+ {2.75, -1, RoundingMode.HALF_DOWN, "2.5"},
+ {2.75, -1, RoundingMode.HALF_EVEN, "3."},
+ {3.00, -1, RoundingMode.CEILING, "3."},
+ {3.25, -1, RoundingMode.CEILING, "3.5"},
+ {3.50, -1, RoundingMode.CEILING, "3.5"},
+ {3.75, -1, RoundingMode.CEILING, "4."},
+ {4.00, -1, RoundingMode.FLOOR, "4."},
+ {4.25, -1, RoundingMode.FLOOR, "4."},
+ {4.50, -1, RoundingMode.FLOOR, "4.5"},
+ {4.75, -1, RoundingMode.FLOOR, "4.5"},
+ {5.00, -1, RoundingMode.UP, "5."},
+ {5.25, -1, RoundingMode.UP, "5.5"},
+ {5.50, -1, RoundingMode.UP, "5.5"},
+ {5.75, -1, RoundingMode.UP, "6."},
+ {6.00, -1, RoundingMode.DOWN, "6."},
+ {6.25, -1, RoundingMode.DOWN, "6."},
+ {6.50, -1, RoundingMode.DOWN, "6.5"},
+ {6.75, -1, RoundingMode.DOWN, "6.5"},
+ {7.00, -1, RoundingMode.UNNECESSARY, "7."},
+ {7.50, -1, RoundingMode.UNNECESSARY, "7.5"},
+ };
+ for (Object[] cas : cases) {
+ double input = (Double) cas[0];
+ int magnitude = (Integer) cas[1];
+ RoundingMode roundingMode = (RoundingMode) cas[2];
+ String expected = (String) cas[3];
+ String message = input + " @ " + magnitude + " / " + roundingMode;
+ for (int i=0; i<2; i++) {
+ DecimalQuantity dq;
+ if (i == 0) {
+ dq = new DecimalQuantity_DualStorageBCD(input);
+ } else {
+ dq = new DecimalQuantity_SimpleStorage(input);
+ }
+ dq.roundToNickel(magnitude, RoundingUtils.mathContextUnlimited(roundingMode));
+ String actual = dq.toPlainString();
+ assertEquals(message, expected, actual);
+ }
+ }
+ try {
+ DecimalQuantity_DualStorageBCD dq = new DecimalQuantity_DualStorageBCD(7.1);
+ dq.roundToNickel(-1, RoundingUtils.mathContextUnlimited(RoundingMode.UNNECESSARY));
+ fail("Expected ArithmeticException");
+ } catch (ArithmeticException expected) {
+ // pass
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java
index 5bfec66f2..69947cd82 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/ExhaustiveNumberTest.java
@@ -16,8 +16,11 @@ import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.number.Precision;
+import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.UnicodeSet;
+import com.ibm.icu.util.MeasureUnit;
+import com.ibm.icu.util.NoUnit;
import com.ibm.icu.util.ULocale;
/**
@@ -50,7 +53,7 @@ public class ExhaustiveNumberTest extends TestFmwk {
UnicodeSet minusSign = get(Key.MINUS_SIGN);
UnicodeSet percent = get(Key.PERCENT_SIGN);
UnicodeSet permille = get(Key.PERMILLE_SIGN);
- UnicodeSet infinity = get(Key.INFINITY);
+ UnicodeSet infinity = get(Key.INFINITY_SIGN);
for (ULocale locale : ULocale.getAvailableLocales()) {
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
@@ -88,11 +91,29 @@ public class ExhaustiveNumberTest extends TestFmwk {
}
@Test
+ public void test20417_PercentParity() {
+ UnlocalizedNumberFormatter uNoUnitPercent = NumberFormatter.with().unit(NoUnit.PERCENT);
+ UnlocalizedNumberFormatter uNoUnitPermille = NumberFormatter.with().unit(NoUnit.PERMILLE);
+ UnlocalizedNumberFormatter uMeasurePercent = NumberFormatter.with().unit(MeasureUnit.PERCENT);
+ UnlocalizedNumberFormatter uMeasurePermille = NumberFormatter.with().unit(MeasureUnit.PERMILLE);
+
+ for (ULocale locale : ULocale.getAvailableLocales()) {
+ String sNoUnitPercent = uNoUnitPercent.locale(locale).format(50).toString();
+ String sNoUnitPermille = uNoUnitPermille.locale(locale).format(50).toString();
+ String sMeasurePercent = uMeasurePercent.locale(locale).format(50).toString();
+ String sMeasurePermille = uMeasurePermille.locale(locale).format(50).toString();
+
+ assertEquals("Percent, locale " + locale, sNoUnitPercent, sMeasurePercent);
+ assertEquals("Permille, locale " + locale, sNoUnitPermille, sMeasurePermille);
+ }
+ }
+
+ @Test
public void unlimitedRoundingBigDecimal() {
BigDecimal ten10000 = BigDecimal.valueOf(10).pow(10000);
BigDecimal longFraction = ten10000.subtract(BigDecimal.ONE).divide(ten10000);
String expected = longFraction.toPlainString();
- String actual = NumberFormatter.withLocale(ULocale.ENGLISH).rounding(Precision.unlimited())
+ String actual = NumberFormatter.withLocale(ULocale.ENGLISH).precision(Precision.unlimited())
.format(longFraction).toString();
assertEquals("All digits should be displayed", expected, actual);
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
index 7f70a5541..5f2c13c6e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/MutablePatternModifierTest.java
@@ -25,7 +25,7 @@ public class MutablePatternModifierTest {
@Test
public void basic() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH),
Currency.getInstance("USD"),
@@ -51,7 +51,7 @@ public class MutablePatternModifierTest {
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setNumberProperties(1, null);
assertEquals("a", getPrefix(mod));
@@ -76,7 +76,7 @@ public class MutablePatternModifierTest {
@Test
public void mutableEqualsImmutable() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH), null, UnitWidth.SHORT, null);
DecimalQuantity fq = new DecimalQuantity_DualStorageBCD(1);
@@ -106,7 +106,7 @@ public class MutablePatternModifierTest {
@Test
public void patternWithNoPlaceholder() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("abc"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("abc"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH),
Currency.getInstance("USD"),
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
index 1074f0128..e0ad131b3 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
@@ -12,7 +12,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
-import java.text.AttributedCharacterIterator;
import java.text.FieldPosition;
import java.text.Format;
import java.util.HashMap;
@@ -24,6 +23,7 @@ import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
+import com.ibm.icu.dev.test.format.FormattedValueTest;
import com.ibm.icu.dev.test.serializable.SerializableTestUtility;
import com.ibm.icu.impl.number.Grouper;
import com.ibm.icu.impl.number.LocalizedNumberFormatterAsFormat;
@@ -65,6 +65,7 @@ public class NumberFormatterApiTest {
private static final Currency CAD = Currency.getInstance("CAD");
private static final Currency ESP = Currency.getInstance("ESP");
private static final Currency PTE = Currency.getInstance("PTE");
+ private static final Currency RON = Currency.getInstance("RON");
@Test
public void notationSimple() {
@@ -385,8 +386,8 @@ public class NumberFormatterApiTest {
1e7,
"1000\u842C");
- Map<String, Map<String, String>> compactCustomData = new HashMap<String, Map<String, String>>();
- Map<String, String> entry = new HashMap<String, String>();
+ Map<String, Map<String, String>> compactCustomData = new HashMap<>();
+ Map<String, String> entry = new HashMap<>();
entry.put("one", "Kun");
entry.put("other", "0KK");
compactCustomData.put("1000", entry);
@@ -499,6 +500,15 @@ public class NumberFormatterApiTest {
5.43,
"5.43 m²");
+ // Try accessing a narrow unit directly from root.
+ assertFormatSingle(
+ "Interesting Data Fallback 4",
+ "measure-unit/area-square-meter unit-width-narrow",
+ NumberFormatter.with().unit(MeasureUnit.SQUARE_METER).unitWidth(UnitWidth.NARROW),
+ ULocale.forLanguageTag("root"),
+ 5.43,
+ "5.43 m²");
+
// es_US has "{0}°" for unitsNarrow/temperature/FAHRENHEIT.
// NOTE: This example is in the documentation.
assertFormatSingle(
@@ -719,7 +729,7 @@ public class NumberFormatterApiTest {
// NOTE: This is a bit of a hack on CLDR's part. They set the currency symbol to U+200B (zero-
// width space), and they set the decimal separator to the $ symbol.
assertFormatSingle(
- "Currency-dependent symbols (Test)",
+ "Currency-dependent symbols (Test Short)",
"currency/PTE unit-width-short",
NumberFormatter.with().unit(PTE).unitWidth(UnitWidth.SHORT),
ULocale.forLanguageTag("pt-PT"),
@@ -727,20 +737,28 @@ public class NumberFormatterApiTest {
"444,444$55 \u200B");
assertFormatSingle(
- "Currency-dependent symbols (Test)",
+ "Currency-dependent symbols (Test Narrow)",
"currency/PTE unit-width-narrow",
NumberFormatter.with().unit(PTE).unitWidth(UnitWidth.NARROW),
ULocale.forLanguageTag("pt-PT"),
444444.55,
- "444,444$55 PTE");
+ "444,444$55 \u200B");
assertFormatSingle(
- "Currency-dependent symbols (Test)",
+ "Currency-dependent symbols (Test ISO Code)",
"currency/PTE unit-width-iso-code",
NumberFormatter.with().unit(PTE).unitWidth(UnitWidth.ISO_CODE),
ULocale.forLanguageTag("pt-PT"),
444444.55,
"444,444$55 PTE");
+
+ assertFormatSingle(
+ "Plural form depending on visible digits (ICU-20499)",
+ "currency/RON unit-width-full-name",
+ NumberFormatter.with().unit(RON).unitWidth(UnitWidth.FULL_NAME),
+ ULocale.forLanguageTag("ro-RO"),
+ 24,
+ "24,00 lei românești");
}
@Test
@@ -1079,6 +1097,36 @@ public class NumberFormatterApiTest {
"0.00");
assertFormatDescending(
+ "Strange Increment",
+ "precision-increment/3.140",
+ NumberFormatter.with().precision(Precision.increment(new BigDecimal("3.140"))),
+ ULocale.ENGLISH,
+ "87,649.960",
+ "8,763.740",
+ "876.060",
+ "87.920",
+ "9.420",
+ "0.000",
+ "0.000",
+ "0.000",
+ "0.000");
+
+ assertFormatDescending(
+ "Increment Resolving to Power of 10",
+ "precision-increment/0.010",
+ NumberFormatter.with().precision(Precision.increment(new BigDecimal("0.010"))),
+ ULocale.ENGLISH,
+ "87,650.000",
+ "8,765.000",
+ "876.500",
+ "87.650",
+ "8.760",
+ "0.880",
+ "0.090",
+ "0.010",
+ "0.000");
+
+ assertFormatDescending(
"Currency Standard",
"currency/CZK precision-currency-standard",
NumberFormatter.with().precision(Precision.currency(CurrencyUsage.STANDARD)).unit(CZK),
@@ -1543,6 +1591,31 @@ public class NumberFormatterApiTest {
"00.08765",
"00.008765",
"00");
+
+ assertFormatSingle(
+ "Integer Width Remove All A",
+ "integer-width/00",
+ NumberFormatter.with().integerWidth(IntegerWidth.zeroFillTo(2).truncateAt(2)),
+ ULocale.ENGLISH,
+ 2500,
+ "00");
+
+ assertFormatSingle(
+ "Integer Width Remove All B",
+ "integer-width/00",
+ NumberFormatter.with().integerWidth(IntegerWidth.zeroFillTo(2).truncateAt(2)),
+ ULocale.ENGLISH,
+ 25000,
+ "00");
+
+ assertFormatSingle(
+ "Integer Width Remove All B, Bytes Mode",
+ "integer-width/00",
+ NumberFormatter.with().integerWidth(IntegerWidth.zeroFillTo(2).truncateAt(2)),
+ ULocale.ENGLISH,
+ // Note: this double produces all 17 significant digits
+ 10000000000000002000.0,
+ "00");
}
@Test
@@ -1887,6 +1960,40 @@ public class NumberFormatterApiTest {
ULocale.ENGLISH,
-444444,
"(444,444.00)");
+
+ assertFormatSingle(
+ "Sign Accounting Negative Narrow",
+ "currency/USD unit-width-narrow sign-accounting",
+ NumberFormatter.with().sign(SignDisplay.ACCOUNTING).unit(USD).unitWidth(UnitWidth.NARROW),
+ ULocale.CANADA,
+ -444444,
+ "($444,444.00)");
+
+ assertFormatSingle(
+ "Sign Accounting Negative Short",
+ "currency/USD sign-accounting",
+ NumberFormatter.with().sign(SignDisplay.ACCOUNTING).unit(USD).unitWidth(UnitWidth.SHORT),
+ ULocale.CANADA,
+ -444444,
+ "(US$444,444.00)");
+
+ assertFormatSingle(
+ "Sign Accounting Negative Iso Code",
+ "currency/USD unit-width-iso-code sign-accounting",
+ NumberFormatter.with().sign(SignDisplay.ACCOUNTING).unit(USD).unitWidth(UnitWidth.ISO_CODE),
+ ULocale.CANADA,
+ -444444,
+ "(USD 444,444.00)");
+
+ // Note: CLDR does not provide an accounting pattern for long name currency.
+ // We fall back to normal currency format. This may change in the future.
+ assertFormatSingle(
+ "Sign Accounting Negative Full Name",
+ "currency/USD unit-width-full-name sign-accounting",
+ NumberFormatter.with().sign(SignDisplay.ACCOUNTING).unit(USD).unitWidth(UnitWidth.FULL_NAME),
+ ULocale.CANADA,
+ -444444,
+ "-444,444.00 US dollars");
}
@Test
@@ -2080,9 +2187,16 @@ public class NumberFormatterApiTest {
}
@Test
- public void fieldPosition() {
- FormattedNumber fmtd = NumberFormatter.withLocale(ULocale.ENGLISH).format(-9876543210.12);
- assertEquals("Should have expected format output", "-9,876,543,210.12", fmtd.toString());
+ public void fieldPositionLogic() {
+ String message = "Field position logic test";
+
+ FormattedNumber fmtd = assertFormatSingle(
+ message,
+ "",
+ NumberFormatter.with(),
+ ULocale.ENGLISH,
+ -9876543210.12,
+ "-9,876,543,210.12");
Object[][] expectedFieldPositions = new Object[][]{
{NumberFormat.Field.SIGN, 0, 1},
@@ -2093,38 +2207,11 @@ public class NumberFormatterApiTest {
{NumberFormat.Field.DECIMAL_SEPARATOR, 14, 15},
{NumberFormat.Field.FRACTION, 15, 17}};
- AttributedCharacterIterator fpi = fmtd.getFieldIterator();
- Set<AttributedCharacterIterator.Attribute> allAttributes = fpi.getAllAttributeKeys();
- assertEquals("All known fields should be in the iterator", 5, allAttributes.size());
- assertEquals("Iterator should have length of string output", 17, fpi.getEndIndex());
- int i = 0;
- for (char c = fpi.first(); c != AttributedCharacterIterator.DONE; c = fpi.next(), i++) {
- Set<AttributedCharacterIterator.Attribute> currentAttributes = fpi.getAttributes().keySet();
- int attributesRemaining = currentAttributes.size();
- for (Object[] cas : expectedFieldPositions) {
- NumberFormat.Field expectedField = (NumberFormat.Field) cas[0];
- int expectedBeginIndex = (Integer) cas[1];
- int expectedEndIndex = (Integer) cas[2];
- if (expectedBeginIndex > i || expectedEndIndex <= i) {
- // Field position does not overlap with the current character
- continue;
- }
-
- assertTrue("Current character should have expected field", currentAttributes.contains(expectedField));
- assertTrue("Field should be a known attribute", allAttributes.contains(expectedField));
- int actualBeginIndex = fpi.getRunStart(expectedField);
- int actualEndIndex = fpi.getRunLimit(expectedField);
- assertEquals(expectedField + " begin index @" + i, expectedBeginIndex, actualBeginIndex);
- assertEquals(expectedField + " end index @" + i, expectedEndIndex, actualEndIndex);
- attributesRemaining--;
- }
- assertEquals("Should have looked at every field", 0, attributesRemaining);
- }
- assertEquals("Should have looked at every character", 17, i);
+ assertNumberFieldPositions(message, fmtd, expectedFieldPositions);
// Test the iteration functionality of nextFieldPosition
FieldPosition actual = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
- i = 1;
+ int i = 1;
while (fmtd.nextFieldPosition(actual)) {
Object[] cas = expectedFieldPositions[i++];
NumberFormat.Field expectedField = (NumberFormat.Field) cas[0];
@@ -2152,6 +2239,270 @@ public class NumberFormatterApiTest {
assertFalse("No fraction part in an integer", fmtd.nextFieldPosition(actual));
}
+ @Test
+ public void fieldPositionCoverage() {
+ {
+ String message = "Measure unit field position basic";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/temperature-fahrenheit",
+ NumberFormatter.with().unit(MeasureUnit.FAHRENHEIT),
+ ULocale.ENGLISH,
+ 68,
+ "68°F");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.MEASURE_UNIT, 2, 4}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Measure unit field position with compound unit";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/temperature-fahrenheit per-measure-unit/duration-day",
+ NumberFormatter.with().unit(MeasureUnit.FAHRENHEIT).perUnit(MeasureUnit.DAY),
+ ULocale.ENGLISH,
+ 68,
+ "68°F/d");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.MEASURE_UNIT, 2, 6}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Measure unit field position with spaces";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/length-meter unit-width-full-name",
+ NumberFormatter.with().unit(MeasureUnit.METER).unitWidth(UnitWidth.FULL_NAME),
+ ULocale.ENGLISH,
+ 68,
+ "68 meters");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ // note: field starts after the space
+ {NumberFormat.Field.MEASURE_UNIT, 3, 9}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Measure unit field position with prefix and suffix";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/length-meter per-measure-unit/duration-second unit-width-full-name",
+ NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND).unitWidth(UnitWidth.FULL_NAME),
+ new ULocale("ky"), // locale with the interesting data
+ 68,
+ "секундасына 68 метр");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.MEASURE_UNIT, 0, 11},
+ {NumberFormat.Field.INTEGER, 12, 14},
+ {NumberFormat.Field.MEASURE_UNIT, 15, 19}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Measure unit field position with inner spaces";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/temperature-fahrenheit unit-width-full-name",
+ NumberFormatter.with().unit(MeasureUnit.FAHRENHEIT).unitWidth(UnitWidth.FULL_NAME),
+ new ULocale("vi"), // locale with the interesting data
+ 68,
+ "68 độ F");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ // Should trim leading/trailing spaces, but not inner spaces:
+ {NumberFormat.Field.MEASURE_UNIT, 3, 7}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ // Data: other{"‎{0} K"} == "\u200E{0} K"
+ // If that data changes, try to find another example of a non-empty unit prefix/suffix
+ // that is also all ignorables (whitespace and bidi control marks).
+ String message = "Measure unit field position with fully ignorable prefix";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "measure-unit/temperature-kelvin",
+ NumberFormatter.with().unit(MeasureUnit.KELVIN),
+ new ULocale("fa"), // locale with the interesting data
+ 68,
+ "‎۶۸ K");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 1, 3},
+ {NumberFormat.Field.MEASURE_UNIT, 4, 5}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field basic";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-short",
+ NumberFormatter.with().notation(Notation.compactShort()),
+ ULocale.US,
+ 65000,
+ "65K");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 2, 3}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with spaces";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ ULocale.US,
+ 65000,
+ "65 thousand");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 11}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with inner space";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ new ULocale("fil"), // locale with interesting data
+ 6000,
+ "6 na libo");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 1},
+ {NumberFormat.Field.COMPACT, 2, 9}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with bidi mark";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ new ULocale("he"), // locale with interesting data
+ 6000,
+ "\u200F6 אלף");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 1, 2},
+ {NumberFormat.Field.COMPACT, 3, 6}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact with currency fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-short currency/USD",
+ NumberFormatter.with().notation(Notation.compactShort()).unit(USD),
+ new ULocale("sr_Latn"), // locale with interesting data
+ 65000,
+ "65 hilj. US$");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 8},
+ {NumberFormat.Field.CURRENCY, 9, 12}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Currency long name fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "currency/USD unit-width-full-name",
+ NumberFormatter.with().unit(USD)
+ .unitWidth(UnitWidth.FULL_NAME),
+ ULocale.ENGLISH,
+ 12345,
+ "12,345.00 US dollars");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.GROUPING_SEPARATOR, 2, 3},
+ {NumberFormat.Field.INTEGER, 0, 6},
+ {NumberFormat.Field.DECIMAL_SEPARATOR, 6, 7},
+ {NumberFormat.Field.FRACTION, 7, 9},
+ {NumberFormat.Field.CURRENCY, 10, 20}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact with measure unit fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long measure-unit/length-meter unit-width-full-name",
+ NumberFormatter.with().notation(Notation.compactLong())
+ .unit(MeasureUnit.METER)
+ .unitWidth(UnitWidth.FULL_NAME),
+ ULocale.US,
+ 65000,
+ "65 thousand meters");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 11},
+ {NumberFormat.Field.MEASURE_UNIT, 12, 18}};
+ assertNumberFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+ }
+
/** Handler for serialization compatibility test suite. */
public static class FormatHandler implements SerializableTestUtility.Handler {
@Override
@@ -2219,9 +2570,9 @@ public class NumberFormatterApiTest {
Method[] methodsWithOneArgument = new Method[] { Precision.class.getDeclaredMethod("fixedFraction", Integer.TYPE),
Precision.class.getDeclaredMethod("minFraction", Integer.TYPE),
Precision.class.getDeclaredMethod("maxFraction", Integer.TYPE),
- Precision.class.getDeclaredMethod("fixedDigits", Integer.TYPE),
- Precision.class.getDeclaredMethod("minDigits", Integer.TYPE),
- Precision.class.getDeclaredMethod("maxDigits", Integer.TYPE),
+ Precision.class.getDeclaredMethod("fixedSignificantDigits", Integer.TYPE),
+ Precision.class.getDeclaredMethod("minSignificantDigits", Integer.TYPE),
+ Precision.class.getDeclaredMethod("maxSignificantDigits", Integer.TYPE),
FractionPrecision.class.getDeclaredMethod("withMinDigits", Integer.TYPE),
FractionPrecision.class.getDeclaredMethod("withMaxDigits", Integer.TYPE),
ScientificNotation.class.getDeclaredMethod("withMinExponentDigits", Integer.TYPE),
@@ -2229,7 +2580,7 @@ public class NumberFormatterApiTest {
IntegerWidth.class.getDeclaredMethod("truncateAt", Integer.TYPE), };
Method[] methodsWithTwoArguments = new Method[] {
Precision.class.getDeclaredMethod("minMaxFraction", Integer.TYPE, Integer.TYPE),
- Precision.class.getDeclaredMethod("minMaxDigits", Integer.TYPE, Integer.TYPE), };
+ Precision.class.getDeclaredMethod("minMaxSignificantDigits", Integer.TYPE, Integer.TYPE), };
final int EXPECTED_MAX_INT_FRAC_SIG = 999;
final String expectedSubstring0 = "between 0 and 999 (inclusive)";
@@ -2239,10 +2590,10 @@ public class NumberFormatterApiTest {
// We require that the upper bounds all be 999 inclusive.
// The lower bound may be either -1, 0, or 1.
Set<String> methodsWithLowerBound1 = new HashSet();
- methodsWithLowerBound1.add("fixedDigits");
- methodsWithLowerBound1.add("minDigits");
- methodsWithLowerBound1.add("maxDigits");
- methodsWithLowerBound1.add("minMaxDigits");
+ methodsWithLowerBound1.add("fixedSignificantDigits");
+ methodsWithLowerBound1.add("minSignificantDigits");
+ methodsWithLowerBound1.add("maxSignificantDigits");
+ methodsWithLowerBound1.add("minMaxSignificantDigits");
methodsWithLowerBound1.add("withMinDigits");
methodsWithLowerBound1.add("withMaxDigits");
methodsWithLowerBound1.add("withMinExponentDigits");
@@ -2256,7 +2607,7 @@ public class NumberFormatterApiTest {
methodsWithLowerBoundN1.add("truncateAt");
// Some of the methods require an object to be called upon.
- Map<String, Object> targets = new HashMap<String, Object>();
+ Map<String, Object> targets = new HashMap<>();
targets.put("withMinDigits", Precision.integer());
targets.put("withMaxDigits", Precision.integer());
targets.put("withMinExponentDigits", Notation.scientific());
@@ -2277,7 +2628,8 @@ public class NumberFormatterApiTest {
assertTrue(message, argument < lowerBound || argument > EXPECTED_MAX_INT_FRAC_SIG);
// Ensure the exception message contains the expected substring
String actualMessage = e.getCause().getMessage();
- assertNotEquals(message + ": " + actualMessage, -1, actualMessage.indexOf(expectedSubstring));
+ assertNotEquals(message + ": " + actualMessage + "; " + expectedSubstring
+ , -1, actualMessage.indexOf(expectedSubstring));
}
}
for (Method method : methodsWithTwoArguments) {
@@ -2380,7 +2732,7 @@ public class NumberFormatterApiTest {
}
}
- static void assertFormatSingle(
+ static FormattedNumber assertFormatSingle(
String message,
String skeleton,
UnlocalizedNumberFormatter f,
@@ -2389,7 +2741,8 @@ public class NumberFormatterApiTest {
String expected) {
LocalizedNumberFormatter l1 = f.threshold(0L).locale(locale); // no self-regulation
LocalizedNumberFormatter l2 = f.threshold(1L).locale(locale); // all self-regulation
- String actual1 = l1.format(input).toString();
+ FormattedNumber result1 = l1.format(input);
+ String actual1 = result1.toString();
assertEquals(message + ": Unsafe Path: " + input, expected, actual1);
String actual2 = l2.format(input).toString();
assertEquals(message + ": Safe Path: " + input, expected, actual2);
@@ -2404,6 +2757,7 @@ public class NumberFormatterApiTest {
} else {
assertUndefinedSkeleton(f);
}
+ return result1;
}
static void assertFormatSingleMeasure(
@@ -2438,4 +2792,8 @@ public class NumberFormatterApiTest {
fail("Expected toSkeleton to fail, but it passed, producing: " + skeleton);
} catch (UnsupportedOperationException expected) {}
}
+
+ private void assertNumberFieldPositions(String message, FormattedNumber result, Object[][] expectedFieldPositions) {
+ FormattedValueTest.checkFormattedValue(message, result, result.toString(), expectedFieldPositions);
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java
index f2f9c6a1c..35f0a551c 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java
@@ -389,4 +389,52 @@ public class NumberParserTest {
result.charEnd);
}
}
+
+ @Test
+ public void test20360_BidiOverflow() {
+ StringBuilder inputString = new StringBuilder();
+ inputString.append('-');
+ for (int i=0; i<100000; i++) {
+ inputString.append('\u061C');
+ }
+ inputString.append('5');
+
+ NumberParserImpl parser = NumberParserImpl.createSimpleParser(ULocale.ENGLISH, "0", 0);
+
+ ParsedNumber resultObject = new ParsedNumber();
+ parser.parse(inputString.toString(), true, resultObject);
+ assertTrue("Greedy Parse, success", resultObject.success());
+ assertEquals("Greedy Parse, chars consumed", 100002, resultObject.charEnd);
+ assertEquals("Greedy Parse, expected double", -5, resultObject.getNumber().intValue());
+
+ resultObject.clear();
+ parser.parse(inputString.toString(), false, resultObject);
+ assertFalse("Non-Greedy Parse, success", resultObject.success());
+ assertEquals("Non-Greedy Parse, chars consumed", 1, resultObject.charEnd);
+ }
+
+ @Test
+ public void testInfiniteRecursion() {
+ StringBuilder inputString = new StringBuilder();
+ inputString.append('-');
+ for (int i=0; i<200; i++) {
+ inputString.append('\u061C');
+ }
+ inputString.append('5');
+
+ NumberParserImpl parser = NumberParserImpl.createSimpleParser(ULocale.ENGLISH, "0", 0);
+
+ ParsedNumber resultObject = new ParsedNumber();
+ parser.parse(inputString.toString(), false, resultObject);
+ assertFalse("Default recursion limit, success", resultObject.success());
+ assertEquals("Default recursion limit, chars consumed", 1, resultObject.charEnd);
+
+ parser = NumberParserImpl.createSimpleParser(
+ ULocale.ENGLISH, "0", ParsingUtils.PARSE_FLAG_ALLOW_INFINITE_RECURSION);
+ resultObject.clear();
+ parser.parse(inputString.toString(), false, resultObject);
+ assertTrue("Unlimited recursion, success", resultObject.success());
+ assertEquals("Unlimited recursion, chars consumed", 202, resultObject.charEnd);
+ assertEquals("Unlimited recursion, expected double", -5, resultObject.getNumber().intValue());
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
index 367d8df40..e9a55faf3 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
@@ -4,10 +4,20 @@ package com.ibm.icu.dev.test.number;
import static org.junit.Assert.assertEquals;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import org.junit.Test;
+import com.ibm.icu.dev.test.format.FormattedValueTest;
+import com.ibm.icu.impl.ICUData;
+import com.ibm.icu.impl.ICUResourceBundle;
+import com.ibm.icu.impl.UResource;
+import com.ibm.icu.number.FormattedNumberRange;
import com.ibm.icu.number.LocalizedNumberFormatter;
import com.ibm.icu.number.LocalizedNumberRangeFormatter;
import com.ibm.icu.number.Notation;
@@ -19,9 +29,12 @@ import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityFallback;
import com.ibm.icu.number.Precision;
import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.number.UnlocalizedNumberRangeFormatter;
+import com.ibm.icu.text.NumberFormat;
+import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.ULocale;
+import com.ibm.icu.util.UResourceBundle;
/**
* @author sffc
@@ -636,7 +649,7 @@ public class NumberRangeFormatterTest {
"Different rounding rules",
NumberRangeFormatter.with()
.numberFormatterFirst(NumberFormatter.with().precision(Precision.integer()))
- .numberFormatterSecond(NumberFormatter.with().precision(Precision.fixedDigits(2))),
+ .numberFormatterSecond(NumberFormatter.with().precision(Precision.fixedSignificantDigits(2))),
new ULocale("en-us"),
"1–5.0",
"5–5.0",
@@ -706,6 +719,117 @@ public class NumberRangeFormatterTest {
}
}
+ @Test
+ public void testFieldPositions() {
+ {
+ String message = "Field position test 1";
+ String expectedString = "3K – 5K m";
+ FormattedNumberRange fmtd = assertFormattedRangeEquals(
+ message,
+ NumberRangeFormatter.with()
+ .numberFormatterBoth(NumberFormatter.with()
+ .unit(MeasureUnit.METER)
+ .notation(Notation.compactShort()))
+ .locale(ULocale.US),
+ 3000,
+ 5000,
+ expectedString);
+ Object[][] expectedFieldPositions = new Object[][]{
+ {NumberFormat.Field.INTEGER, 0, 1},
+ {NumberFormat.Field.COMPACT, 1, 2},
+ {NumberFormat.Field.INTEGER, 5, 6},
+ {NumberFormat.Field.COMPACT, 6, 7},
+ {NumberFormat.Field.MEASURE_UNIT, 8, 9}};
+ FormattedValueTest.checkFormattedValue(message, fmtd, expectedString, expectedFieldPositions);
+ }
+
+ {
+ String message = "Field position test 2";
+ String expectedString = "87,654,321–98,765,432";
+ FormattedNumberRange fmtd = assertFormattedRangeEquals(
+ message,
+ NumberRangeFormatter.withLocale(ULocale.US),
+ 87654321,
+ 98765432,
+ expectedString);
+ Object[][] expectedFieldPositions = new Object[][]{
+ {NumberFormat.Field.GROUPING_SEPARATOR, 2, 3},
+ {NumberFormat.Field.GROUPING_SEPARATOR, 6, 7},
+ {NumberFormat.Field.INTEGER, 0, 10},
+ {NumberFormat.Field.GROUPING_SEPARATOR, 13, 14},
+ {NumberFormat.Field.GROUPING_SEPARATOR, 17, 18},
+ {NumberFormat.Field.INTEGER, 11, 21}};
+ FormattedValueTest.checkFormattedValue(message, fmtd, expectedString, expectedFieldPositions);
+ }
+ }
+
+ static final String[] allNSNames = NumberingSystem.getAvailableNames();
+
+ private class RangePatternSink extends UResource.Sink {
+ Map<String,String> rangePatterns = new HashMap<>();
+ Map<String,String> approxPatterns = new HashMap<>();
+
+ // NumberElements{ latn{ miscPatterns{ range{"{0}-{1}"} } } }
+ @Override
+ public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
+ UResource.Table numberElementsTable = value.getTable();
+ for (int i = 0; numberElementsTable.getKeyAndValue(i, key, value); ++i) {
+ String nsName = key.toString();
+ if (Arrays.binarySearch(allNSNames, nsName) < 0) {
+ continue;
+ }
+ UResource.Table nsTable = value.getTable();
+ for (int j = 0; nsTable.getKeyAndValue(j, key, value); ++j) {
+ if (!key.contentEquals("miscPatterns")) {
+ continue;
+ }
+ UResource.Table miscTable = value.getTable();
+ for (int k = 0; miscTable.getKeyAndValue(k, key, value); ++k) {
+ if (key.contentEquals("range") && !rangePatterns.containsKey(nsName)) {
+ rangePatterns.put(nsName, value.getString());
+ }
+ if (key.contentEquals("approximately") && !approxPatterns.containsKey(nsName)) {
+ approxPatterns.put(nsName, value.getString());
+ }
+ }
+ }
+ }
+ }
+
+ public void checkAndReset(ULocale locale) {
+ // NOTE: If this test ever starts failing, there might not need to
+ // be any changes made to NumberRangeFormatter. Please add a new
+ // test demonstrating how different numbering systems in the same
+ // locale produce different results in NumberRangeFormatter, and
+ // then you can disable or delete this test.
+ // Additional context: ICU-20144
+
+ Set<String> allRangePatterns = new HashSet<>();
+ allRangePatterns.addAll(rangePatterns.values());
+ assertEquals("Should have only one unique range pattern: " + locale + ": " + rangePatterns,
+ 1, allRangePatterns.size());
+
+ Set<String> allApproxPatterns = new HashSet<>();
+ allApproxPatterns.addAll(approxPatterns.values());
+ assertEquals("Should have only one unique approximately pattern: " + locale + ": " + approxPatterns,
+ 1, allApproxPatterns.size());
+
+ rangePatterns.clear();
+ approxPatterns.clear();
+ }
+ }
+
+ @Test
+ public void testNumberingSystemRangeData() {
+ RangePatternSink sink = new RangePatternSink();
+ for (ULocale locale : ULocale.getAvailableLocales()) {
+ ICUResourceBundle resource = (ICUResourceBundle)
+ UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale);
+ resource.getAllItemsWithFallback("NumberElements", sink);
+ sink.checkAndReset(locale);
+ }
+ }
+
static void assertFormatRange(
String message,
UnlocalizedNumberRangeFormatter f,
@@ -733,10 +857,12 @@ public class NumberRangeFormatterTest {
assertFormattedRangeEquals(message, l, 5e3, 5e6, expected_50K_50M);
}
- private static void assertFormattedRangeEquals(String message, LocalizedNumberRangeFormatter l, Number first,
+ private static FormattedNumberRange assertFormattedRangeEquals(String message, LocalizedNumberRangeFormatter l, Number first,
Number second, String expected) {
- String actual = l.formatRange(first, second).toString();
+ FormattedNumberRange fnr = l.formatRange(first, second);
+ String actual = fnr.toString();
assertEquals(message + ": " + first + ", " + second, expected, actual);
+ return fnr;
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
index 90470deba..bcd413cab 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberSkeletonTest.java
@@ -213,7 +213,7 @@ public class NumberSkeletonTest {
String[] stems = {
"precision-increment",
"measure-unit",
- "per-unit",
+ "per-measure-unit",
"currency",
"integer-width",
"numbering-system",
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberStringBuilderTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberStringBuilderTest.java
index e838d30b5..c85bbfe51 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberStringBuilderTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberStringBuilderTest.java
@@ -262,6 +262,10 @@ public class NumberStringBuilderTest {
int end = Math.min(12, a.length());
if (start != end) {
assertCharSequenceEquals(a.subSequence(start, end), b.subSequence(start, end));
+ if (b instanceof NumberStringBuilder) {
+ NumberStringBuilder bnsb = (NumberStringBuilder) b;
+ assertCharSequenceEquals(a.subSequence(start, end), bnsb.subString(start, end));
+ }
}
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PatternStringTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PatternStringTest.java
index e5823804f..aaf2d8f49 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PatternStringTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PatternStringTest.java
@@ -72,19 +72,19 @@ public class PatternStringTest {
@Test
public void testToPatternWithProperties() {
Object[][] cases = {
- { new DecimalFormatProperties().setPositivePrefix("abc"), "abc#" },
- { new DecimalFormatProperties().setPositiveSuffix("abc"), "#abc" },
+ { new DecimalFormatProperties().setPositivePrefix("abc"), "abc#;-#" },
+ { new DecimalFormatProperties().setPositiveSuffix("abc"), "#abc;-#" },
{ new DecimalFormatProperties().setPositivePrefixPattern("abc"), "abc#" },
{ new DecimalFormatProperties().setPositiveSuffixPattern("abc"), "#abc" },
{ new DecimalFormatProperties().setNegativePrefix("abc"), "#;abc#" },
- { new DecimalFormatProperties().setNegativeSuffix("abc"), "#;#abc" },
+ { new DecimalFormatProperties().setNegativeSuffix("abc"), "#;-#abc" },
{ new DecimalFormatProperties().setNegativePrefixPattern("abc"), "#;abc#" },
- { new DecimalFormatProperties().setNegativeSuffixPattern("abc"), "#;#abc" },
- { new DecimalFormatProperties().setPositivePrefix("+"), "'+'#" },
+ { new DecimalFormatProperties().setNegativeSuffixPattern("abc"), "#;-#abc" },
+ { new DecimalFormatProperties().setPositivePrefix("+"), "'+'#;-#" },
{ new DecimalFormatProperties().setPositivePrefixPattern("+"), "+#" },
- { new DecimalFormatProperties().setPositivePrefix("+'"), "'+'''#" },
- { new DecimalFormatProperties().setPositivePrefix("'+"), "'''+'#" },
- { new DecimalFormatProperties().setPositivePrefix("'"), "''#" },
+ { new DecimalFormatProperties().setPositivePrefix("+'"), "'+'''#;-#" },
+ { new DecimalFormatProperties().setPositivePrefix("'+"), "'''+'#;-#" },
+ { new DecimalFormatProperties().setPositivePrefix("'"), "''#;-#" },
{ new DecimalFormatProperties().setPositivePrefixPattern("+''"), "+''#" }, };
for (Object[] cas : cases) {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java
index a18ad8682..754982357 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java
@@ -1005,7 +1005,7 @@ public class RBBIMonkeyTest extends TestFmwk {
//
@Test
public void TestMonkey() {
- String tests[] = {"grapheme.txt", "word.txt", "line.txt", "sentence.txt", "line_normal.txt",
+ String tests[] = {"grapheme.txt", "word.txt", "line.txt", "line_cj.txt", "sentence.txt", "line_normal.txt",
"line_normal_cj.txt", "line_loose.txt", "line_loose_cj.txt", "word_POSIX.txt"
};
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITestMonkey.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITestMonkey.java
index 7b5803264..ba33b0ae4 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITestMonkey.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITestMonkey.java
@@ -330,7 +330,7 @@ public class RBBITestMonkey extends TestFmwk {
fMidNumLetSet = new UnicodeSet("[\\p{Word_Break = MidNumLet}]");
fMidLetterSet = new UnicodeSet("[\\p{Word_Break = MidLetter}]");
fMidNumSet = new UnicodeSet("[\\p{Word_Break = MidNum}]");
- fNumericSet = new UnicodeSet("[\\p{Word_Break = Numeric}]");
+ fNumericSet = new UnicodeSet("[[\\p{Word_Break = Numeric}][\\uFF10-\\uff19]]");
fFormatSet = new UnicodeSet("[\\p{Word_Break = Format}]");
fExtendNumLetSet = new UnicodeSet("[\\p{Word_Break = ExtendNumLet}]");
fExtendSet = new UnicodeSet("[\\p{Word_Break = Extend}]");
@@ -981,17 +981,12 @@ public class RBBITestMonkey extends TestFmwk {
continue;
}
-
-
// LB 13 Don't break before closings.
- // NU x CL, NU x CP and NU x IS are not matched here so that they will
- // fall into LB 17 and the more general number regular expression.
//
- if (!fNU.contains(prevChar) && fCL.contains(thisChar) ||
- !fNU.contains(prevChar) && fCP.contains(thisChar) ||
+ if (fCL.contains(thisChar) ||
+ fCP.contains(thisChar) ||
fEX.contains(thisChar) ||
- !fNU.contains(prevChar) && fIS.contains(thisChar) ||
- !fNU.contains(prevChar) && fSY.contains(thisChar)) {
+ fSY.contains(thisChar)) {
continue;
}
@@ -1012,6 +1007,19 @@ public class RBBITestMonkey extends TestFmwk {
continue;
}
+ // LB 14a Break before an IS that begins a number and follows a space
+ if (nextPos < fText.length()) {
+ int nextChar = fText.codePointAt(nextPos);
+ if (fSP.contains(prevChar) && fIS.contains(thisChar) && fNU.contains(nextChar)) {
+ break;
+ }
+ }
+
+ // LB14b Do not break before numeric separators, even after spaces.
+ if (fIS.contains(thisChar)) {
+ continue;
+ }
+
// LB 15 Do not break within "[
// QU CM* SP* x OP
if (fOP.contains(thisChar)) {
@@ -1230,8 +1238,8 @@ public class RBBITestMonkey extends TestFmwk {
// Match the following regular expression in the input text.
- // ((PR | PO) CM*)? ((OP | HY) CM*)? NU CM* ((NU | IS | SY) CM*) * ((CL | CP) CM*)? (PR | PO) CM*)?
- // 0 0 1 3 3 4 7 7 7 7 9 9 9 11 11 (match states)
+ // ((PR | PO) CM*)? ((OP | HY) CM*)? (IS CM*)? NU CM* ((NU | IS | SY) CM*) * ((CL | CP) CM*)? (PR | PO) CM*)?
+ // 0 0 1 4 4 4 5 5 7 7 7 7 9 9 9 11 11 (match states)
// retVals array [0] index of the start of the match, or -1 if no match
// [1] index of first char following the match.
// Can not use Java regex because need supplementary character support,
@@ -1263,6 +1271,10 @@ public class RBBITestMonkey extends TestFmwk {
matchState = 4;
break;
}
+ if (cLBType == UCharacter.LineBreak.INFIX_NUMERIC) {
+ matchState = 5;
+ break;
+ }
if (cLBType == UCharacter.LineBreak.NUMERIC) {
matchState = 7;
break;
@@ -1282,25 +1294,42 @@ public class RBBITestMonkey extends TestFmwk {
matchState = 4;
break;
}
+ if (cLBType == UCharacter.LineBreak.INFIX_NUMERIC) {
+ matchState = 5;
+ break;
+ }
if (cLBType == UCharacter.LineBreak.NUMERIC) {
matchState = 7;
break;
}
break matchLoop; /* No Match */
-
case 4:
if (cLBType == UCharacter.LineBreak.COMBINING_MARK || cLBType == UCharacter.LineBreak.ZWJ) {
matchState = 4;
break;
}
+ if (cLBType == UCharacter.LineBreak.INFIX_NUMERIC) {
+ matchState = 5;
+ break;
+ }
+ if (cLBType == UCharacter.LineBreak.NUMERIC) {
+ matchState = 7;
+ break;
+ }
+ break matchLoop; /* No Match */
+
+ case 5:
+ if (cLBType == UCharacter.LineBreak.COMBINING_MARK || cLBType == UCharacter.LineBreak.ZWJ) {
+ matchState = 5;
+ break;
+ }
if (cLBType == UCharacter.LineBreak.NUMERIC) {
matchState = 7;
break;
}
break matchLoop; /* No Match */
- // ((PR | PO) CM*)? ((OP | HY) CM*)? NU CM* ((NU | IS | SY) CM*) * (CL CM*)? (PR | PO) CM*)?
- // 0 0 1 3 3 4 7 7 7 7 9 9 11 11 (match states)
+
case 7:
if (cLBType == UCharacter.LineBreak.COMBINING_MARK || cLBType == UCharacter.LineBreak.ZWJ) {
@@ -1359,7 +1388,7 @@ public class RBBITestMonkey extends TestFmwk {
break matchLoop; // Match Complete.
}
}
- if (matchState > 4) {
+ if (matchState >= 7) {
retVals[0] = startIdx;
retVals[1] = idx;
}
@@ -1371,9 +1400,6 @@ public class RBBITestMonkey extends TestFmwk {
List charClasses() {
return fSets;
}
-
-
-
}
@@ -1889,7 +1915,13 @@ public class RBBITestMonkey extends TestFmwk {
if (c < 0) { // TODO: deal with sets containing strings.
errln("c < 0");
}
- UTF16.appendCodePoint(testText, c);
+ // Do not assemble a supplementary character from randomly generated separate surrogates.
+ // (It could be a dictionary character)
+ if (c < 0x10000 && Character.isLowSurrogate((char)c) && testText.length() > 0 &&
+ Character.isHighSurrogate(testText.charAt(testText.length()-1))) {
+ continue;
+ }
+ testText.appendCodePoint(c);
if (printTestData) {
System.out.print(Integer.toHexString(c) + " ");
}
@@ -2096,15 +2128,15 @@ public class RBBITestMonkey extends TestFmwk {
}
}
+ // Test parameters are passed on the command line, or
+ // via the Eclipse Run Configuration settings, arguments tab, VM parameters.
+ // For example,
+ // -ea -Dseed=554654 -Dloop=1
+
@Test
public void TestCharMonkey() {
-
- int loopCount = 500;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 10000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 500 : 10000);
+ int seed = getIntProperty("seed", 1);
RBBICharMonkey m = new RBBICharMonkey();
BreakIterator bi = BreakIterator.getCharacterInstance(Locale.US);
@@ -2113,13 +2145,8 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestWordMonkey() {
-
- int loopCount = 500;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 10000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 500 : 10000);
+ int seed = getIntProperty("seed", 1);
logln("Word Break Monkey Test");
RBBIWordMonkey m = new RBBIWordMonkey();
@@ -2129,12 +2156,8 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestLineMonkey() {
- int loopCount = 500;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 10000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 500 : 10000);
+ int seed = getIntProperty("seed", 1);
logln("Line Break Monkey Test");
RBBILineMonkey m = new RBBILineMonkey();
@@ -2144,13 +2167,8 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestSentMonkey() {
-
- int loopCount = 500;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 3000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 500 : 3000);
+ int seed = getIntProperty("seed", 1);
logln("Sentence Break Monkey Test");
RBBISentenceMonkey m = new RBBISentenceMonkey();
@@ -2169,13 +2187,8 @@ public class RBBITestMonkey extends TestFmwk {
//
@Test
public void TestRTCharMonkey() {
-
- int loopCount = 200;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 2000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 200 : 2000);
+ int seed = getIntProperty("seed", 1);
RBBICharMonkey m = new RBBICharMonkey();
BreakIterator bi = BreakIterator.getCharacterInstance(Locale.US);
@@ -2186,13 +2199,9 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestRTWordMonkey() {
+ int loopCount = getIntProperty("loop", isQuick() ? 200 : 2000);
+ int seed = getIntProperty("seed", 1);
- int loopCount = 200;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 2000;
- }
logln("Word Break Monkey Test");
RBBIWordMonkey m = new RBBIWordMonkey();
BreakIterator bi = BreakIterator.getWordInstance(Locale.US);
@@ -2203,12 +2212,8 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestRTLineMonkey() {
- int loopCount = 200;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 2000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 200 : 2000);
+ int seed = getIntProperty("seed", 1);
logln("Line Break Monkey Test");
RBBILineMonkey m = new RBBILineMonkey();
@@ -2220,13 +2225,8 @@ public class RBBITestMonkey extends TestFmwk {
@Test
public void TestRTSentMonkey() {
-
- int loopCount = 200;
- int seed = 1;
-
- if (TestFmwk.getExhaustiveness() >= 9) {
- loopCount = 1000;
- }
+ int loopCount = getIntProperty("loop", isQuick() ? 200 : 1000);
+ int seed = getIntProperty("seed", 1);
logln("Sentence Break Monkey Test");
RBBISentenceMonkey m = new RBBISentenceMonkey();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line.txt
index 3e0324bf9..425f0109b 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line.txt
@@ -78,19 +78,33 @@ LB5.3: NL ÷;
LB6: . (BK | CR | LF | NL);
LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
+
# Rules LB14 - LB17.
-# Moved before LB7, because they can match a longer sequence that would also match LB7,
-# for example, the sequence "OP CM SP AL" matches LB14 while the prefix of it,
-# "while only the prefix "OP CM SP" matches LB7.1
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
LB15: QU CM* SP* OP;
LB16: (CL | CP)CM* SP* NS;
LB17: B2 CM* SP* B2;
-# LB8, break after ZW SP*, precedes LB7 because they will both match the sequences like ZW SP,
-# and LB8 should take precedence.
-
-LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
# LB7 Do not break before spaces or zero width space.
@@ -118,15 +132,9 @@ LB12: GL CM* [^CM];
LB12a: [^SP BA HY] CM* GL;
-# LB 13 ICU Tailoring, matches tailoring example 8 from UAX 14.
-#
-# LB13.1 [^SP] CM* [CL CP EX IS SY] # original UAX 14 rule.
-# LB13.2 SP CM* [CL CP EX IS SY]
-
-LB13.1: [^NU SP] CM* [CL CP IS SY];
-LB13.2: [^SP] CM* EX;
-LB13.2: SP [CL CP EX IS SY];
-
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
# LB 14-17 are moved above LB 7.
@@ -172,8 +180,6 @@ LB23a.2: (ID | EB | EM) CM* PO;
LB24.2: (PR | PO) CM* (AL | HL);
LB24.3: (AL | HL | CM) CM* (PR | PO);
-# Numbers. Equivalent to Tailoring example 8 from UAX 14.
-LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
LB26.1: JL CM* (JL | JV | H2 | H3);
LB26.2: (JV | H2) CM* (JV | JT);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_cj.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_cj.txt
new file mode 100644
index 000000000..765953bb0
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_cj.txt
@@ -0,0 +1,213 @@
+#
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
+# Copyright (c) 2016, International Business Machines Corporation and others. All Rights Reserved.
+
+# file: line.txt
+#
+# Reference Line Break rules for intltest rbbi/RBBIMonkeyTest.
+# Rules derived from Unicode Standard Annex #14 Revision 40 for Unicode 11.0
+#
+# Note: Rule syntax and the monkey test itself are still a work in progress.
+# They are expected to change with review and the addition of support for rule tailoring.
+
+
+type = line;
+locale = zh;
+
+
+AI = [:LineBreak = Ambiguous:];
+AL = [:LineBreak = Alphabetic:];
+BA = [:LineBreak = Break_After:];
+HH = [\u2010]; # \u2010 is HYPHEN, default line break is BA.
+BB = [:LineBreak = Break_Before:];
+BK = [:LineBreak = Mandatory_Break:];
+B2 = [:LineBreak = Break_Both:];
+CB = [:LineBreak = Contingent_Break:];
+CJ = [:LineBreak = Conditional_Japanese_Starter:];
+CL = [[:LineBreak = Close_Punctuation:] \u201d];
+CMS = [:LineBreak = Combining_Mark:];
+CP = [:LineBreak = Close_Parenthesis:];
+CR = [:LineBreak = Carriage_Return:];
+EB = [:LineBreak = EB:];
+EM = [:LineBreak = EM:];
+EX = [:LineBreak = Exclamation:];
+GL = [:LineBreak = Glue:];
+HL = [:LineBreak = Hebrew_Letter:];
+HY = [:LineBreak = Hyphen:];
+H2 = [:LineBreak = H2:];
+H3 = [:LineBreak = H3:];
+ID = [:LineBreak = Ideographic:];
+IN = [:LineBreak = Inseperable:];
+IS = [:LineBreak = Infix_Numeric:];
+JL = [:LineBreak = JL:];
+JV = [:LineBreak = JV:];
+JT = [:LineBreak = JT:];
+LF = [:LineBreak = Line_Feed:];
+NL = [:LineBreak = Next_Line:];
+NS = [[:LineBreak = Nonstarter:] CJ]; # CSS Strict tailoring: CJ resolves to NS.
+NU = [:LineBreak = Numeric:];
+OP = [[:LineBreak = Open_Punctuation:] \u201c];
+PO = [:LineBreak = Postfix_Numeric:];
+PR = [:LineBreak = Prefix_Numeric:];
+QU = [[:LineBreak = Quotation:] - [\u201c\u201d]];
+RI = [:LineBreak = Regional_Indicator:];
+SA = [:LineBreak = Complex_Context:];
+SG = [:LineBreak = Surrogate:];
+SP = [:LineBreak = Space:];
+SY = [:LineBreak = Break_Symbols:];
+WJ = [:LineBreak = Word_Joiner:];
+XX = [:LineBreak = Unknown:];
+ZW = [:LineBreak = ZWSpace:];
+ZWJ = [:LineBreak = ZWJ:];
+
+# LB1 - Resolve AI, CB, CJ, SA, SG, and XX into other line breaking classes
+AL = [AL AI SG XX ];
+dictionary = SA;
+
+# By LB9, a ZWJ also behaves as a CM. Including it in the definition of CM avoids having to explicitly
+# list it in the numerous rules that use CM.
+CM = [CMS ZWJ];
+
+LB4: BK ÷;
+LB5: CR LF;
+LB5.1: CR ÷;
+LB5.2: LF ÷;
+LB5.3: NL ÷;
+
+LB6: . (BK | CR | LF | NL);
+LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
+
+# Rules LB14 - LB17.
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
+LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
+LB15: QU CM* SP* OP;
+LB16: (CL | CP)CM* SP* NS;
+LB17: B2 CM* SP* B2;
+
+
+# LB7 Do not break before spaces or zero width space.
+
+LB7.1: [^ZW SP] CM* [SP ZW];
+LB7.2: [ZW SP] [SP ZW];
+
+# LB8a
+# ZWJ x
+# Don't match a CM on the right - let other rules pick up CM sequences, where
+# the ZWJ behaves as just another generic CM.
+LB8a: ZWJ [^CM];
+
+
+# LB9: X CM -> X
+# LB10: Unattached CM -> AL
+
+#LB11: × WJ;
+# WJ ×
+
+LB11.1: [^SP] CM* WJ;
+LB11.2: SP WJ;
+LB11.3: WJ CM* [^CM];
+
+LB12: GL CM* [^CM];
+
+LB12a: [^SP BA HY] CM* GL;
+
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
+
+# LB 14-17 are moved above LB 7.
+
+LB18: SP ÷;
+
+LB19: . CM* QU;
+LB19.1: QU CM* [^CM];
+
+# LB 20 Break before and after CB.
+# Interaction with LB8a: ZWJ x . is tricky because CM includes ZWJ.
+# ZWJ acts like a CM to the left, combining with CB.
+# ZWJ acts independently to the right, no break after by LB8a.
+LB20.1: . CM* ZWJ CB;
+LB20.2: . CM* ÷ CB;
+
+LB20.3: CB CM* ZWJ [^CM];
+LB20.4: CB CM* ÷;
+
+# LB 20.09 Don't break between Hyphens and Letters when there is a break preceding the hyphen.
+LB20.09: ^(HY | HH) CM* AL;
+
+# Note: Rule 21a must come before 21 to prevent 21.1 from matching HL BA, then
+# not picking up the continuing match after the BA from 21a.
+LB21a: HL CM* (HY | BA) CM* [^CM CB];
+
+LB21.1: . CM* [BA HY NS];
+LB21.2: BB CM* [^CM CB];
+
+LB21b: SY CM* HL;
+
+LB22.1: (AL | HL | CM) CM* IN; # The CM is from LB10, treat an unattached CM as AL.
+LB22.2: EX CM* IN;
+LB22.3: (ID | EB | EM) CM* IN;
+LB22.4: IN CM* IN;
+LB22.5: NU CM* IN;
+
+LB23.1: (AL | HL | CM) CM* NU;
+LB23.2: NU CM* (AL | HL);
+
+LB23a.1: PR CM* (ID | EB | EM);
+LB23a.2: (ID | EB | EM) CM* PO;
+
+LB24.2: (PR | PO) CM* (AL | HL);
+LB24.3: (AL | HL | CM) CM* (PR | PO);
+
+
+LB26.1: JL CM* (JL | JV | H2 | H3);
+LB26.2: (JV | H2) CM* (JV | JT);
+LB26.3: (JT | H3) CM* JT;
+
+LB27.1: (JL | JV | JT | H2 | H3) CM* IN;
+LB27.2: (JL | JV | JT | H2 | H3) CM* PO;
+LB27.3: PR CM* (JL | JV | JT | H2 | H3);
+
+# LB28 Do not break between Alphabetics.
+# Unattached (leading) CM treated as AL.
+LB28: (AL | HL | CM)CM* (AL | HL);
+
+LB29: IS CM* (AL | HL);
+
+# LB30 is adjusted for unattached leading CM being treated as AL.
+LB30.1: (AL | CM | HL | NU) CM* OP;
+LB30.2: CP CM* (AL | HL | NU);
+
+# LB30a keep pairs of RI together.
+LB30a.1: RI CM* RI ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA HY NS CM];
+LB30a.2: RI CM* RI CM* CMS ÷ [^BK CR LF NL SP ZW WJ CL CP EX IS SY GL QU BA HY NS CM];
+LB30a.3: RI CM* RI CM* [BK CR LF NL SP ZW WJ GL CL CP EX IS SY QU BA HY NS ZWJ]?;
+
+# LB30b Do not break between Emoji Base and Emoji Modifier
+LB30b: EB CM* EM;
+
+# LB31 Break Everywhere Else.
+# Include combining marks
+LB31.1: . CM* ZWJ [^CM];
+LB31.2: . CM* ÷;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose.txt
index 839519236..86eb170c4 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose.txt
@@ -86,19 +86,33 @@ LB5.3: NL ÷;
LB6: . (BK | CR | LF | NL);
LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
+
# Rules LB14 - LB17.
-# Moved before LB7, because they can match a longer sequence that would also match LB7,
-# for example, the sequence "OP CM SP AL" matches LB14 while the prefix of it,
-# "while only the prefix "OP CM SP" matches LB7.1
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
LB15: QU CM* SP* OP;
LB16: (CL | CP)CM* SP* NS;
LB17: B2 CM* SP* B2;
-# LB8, break after ZW SP*, precedes LB7 because they will both match the sequences like ZW SP,
-# and LB8 should take precedence.
-
-LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
# LB7 Do not break before spaces or zero width space.
@@ -126,15 +140,9 @@ LB12: GL CM* [^CM];
LB12a: [^SP BA HY] CM* GL;
-# LB 13 ICU Tailoring, matches tailoring example 8 from UAX 14.
-#
-# LB13.1 [^SP] CM* [CL CP EX IS SY] # original UAX 14 rule.
-# LB13.2 SP CM* [CL CP EX IS SY]
-
-LB13.1: [^NU SP] CM* [CL CP IS SY];
-LB13.2: [^SP] CM* EX;
-LB13.2: SP [CL CP EX IS SY];
-
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
# LB 14-17 are moved above LB 7.
@@ -180,8 +188,6 @@ LB23a.2: (ID | EB | EM) CM* PO;
LB24.2: (PR | PO) CM* (AL | HL);
LB24.3: (AL | HL | CM) CM* (PR | PO);
-# Numbers. Equivalent to Tailoring example 8 from UAX 14.
-LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
LB26.1: JL CM* (JL | JV | H2 | H3);
LB26.2: (JV | H2) CM* (JV | JT);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose_cj.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose_cj.txt
index d67432710..049ecd017 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose_cj.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_loose_cj.txt
@@ -30,6 +30,7 @@
# this includes: 00B0 2030 2032 2033 2035 2103 2109 FE6A FF05 FFE0
# * after prefix characters with LineBreak class PR and EastAsianWidth A,F,W;
# this includes: 00A4 00B1 20AC 2116 FE69 FF04 FFE1 FFE5 FFE6
+# It allows breaking before 201C and after 201D, for zh_Hans, zh_Hant, and ja.
type = line;
@@ -46,7 +47,7 @@ BK = [:LineBreak = Mandatory_Break:];
B2 = [:LineBreak = Break_Both:];
CB = [:LineBreak = Contingent_Break:];
CJ = [:LineBreak = Conditional_Japanese_Starter:];
-CL = [:LineBreak = Close_Punctuation:];
+CL = [[:LineBreak = Close_Punctuation:] \u201d];
CMS = [:LineBreak = Combining_Mark:];
CP = [:LineBreak = Close_Parenthesis:];
CR = [:LineBreak = Carriage_Return:];
@@ -70,12 +71,12 @@ NL = [:LineBreak = Next_Line:];
NSX = [\u301C \u30A0 \u3005 \u303B \u309D \u309E \u30FD \u30FE \u203C \u2047 \u2048 \u2049 \u30FB \uFF1A \uFF1B \uFF65];
NS = [[:LineBreak = Nonstarter:] - NSX];
NU = [:LineBreak = Numeric:];
-OP = [:LineBreak = Open_Punctuation:];
+OP = [[:LineBreak = Open_Punctuation:] \u201c];
POX = [\u00B0 \u2030 \u2032 \u2033 \u2035 \u2103 \u2109 \uFE6A \uFF05 \uFFE0];
PO = [[:LineBreak = Postfix_Numeric:] - POX];
PRX = [\u00A4 \u00B1 \u20AC \u2116 \uFE69 \uFF04 \uFFE1 \uFFE5 \uFFE6];
PR = [[:LineBreak = Prefix_Numeric:] - PRX];
-QU = [:LineBreak = Quotation:];
+QU = [[:LineBreak = Quotation:] - [\u201c\u201d]];
RI = [:LineBreak = Regional_Indicator:];
SA = [:LineBreak = Complex_Context:];
SG = [:LineBreak = Surrogate:];
@@ -103,19 +104,34 @@ LB5.3: NL ÷;
LB6: . (BK | CR | LF | NL);
LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+# Loose_cj tailoring: do not include $PRX at the beginning or $POX at the end.
+LB25: ((PR | PO | POX)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PRX | PO))?;
+
# Rules LB14 - LB17.
-# Moved before LB7, because they can match a longer sequence that would also match LB7,
-# for example, the sequence "OP CM SP AL" matches LB14 while the prefix of it,
-# "while only the prefix "OP CM SP" matches LB7.1
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
LB15: QU CM* SP* OP;
LB16: (CL | CP)CM* SP* NS;
LB17: B2 CM* SP* B2;
-# LB8, break after ZW SP*, precedes LB7 because they will both match the sequences like ZW SP,
-# and LB8 should take precedence.
-
-LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
# LB7 Do not break before spaces or zero width space.
@@ -143,14 +159,9 @@ LB12: GL CM* [^CM];
LB12a: [^SP BA BAX HY] CM* GL;
-# LB 13 ICU Tailoring, matches tailoring exmaple 8 from UAX 14.
-#
-# LB13.1 [^SP] CM* [CL CP EX IS SY] # original UAX 14 rule.
-# LB13.2 SP CM* [CL CP EX IS SY]
-
-LB13.1: [^NU SP] CM* [CL CP IS SY];
-LB13.2: [^SP] CM* EX;
-LB13.2: SP [CL CP EX IS SY];
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
# LB 14-17 are moved above LB 7.
@@ -200,9 +211,6 @@ LB23a.2: (ID | EB | EM) CM* PO;
LB24.2: (PR | PO | POX) CM* (AL | HL);
LB24.3: (AL | HL | CM) CM* (PR | PO | POX);
-# Numbers. Equivalent to Tailoring example 8 from UAx 14.
-# Loose_cj tailoring: do not include $PRX at the beginning or $POX at the end.
-LB25: ((PR | PO | POX)CM*)? ((OP | HY)CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PRX | PO))?;
LB26.1: JL CM* (JL | JV | H2 | H3);
LB26.2: (JV | H2) CM* (JV | JT);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal.txt
index 7f5b91c42..2cf6e7c11 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal.txt
@@ -92,19 +92,33 @@ LB5.3: NL ÷;
LB6: . (BK | CR | LF | NL);
LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
+
# Rules LB14 - LB17.
-# Moved before LB7, because they can match a longer sequence that would also match LB7,
-# for example, the sequence "OP CM SP AL" matches LB14 while the prefix of it,
-# "while only the prefix "OP CM SP" matches LB7.1
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
LB15: QU CM* SP* OP;
LB16: (CL | CP)CM* SP* NS;
LB17: B2 CM* SP* B2;
-# LB8, break after ZW SP*, precedes LB7 because they will both match the sequences like ZW SP,
-# and LB8 should take precedence.
-
-LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
# LB7 Do not break before spaces or zero width space.
@@ -132,15 +146,9 @@ LB12: GL CM* [^CM];
LB12a: [^SP BA HY] CM* GL;
-# LB 13 ICU Tailoring, matches tailoring exmaple 8 from UAX 14.
-#
-# LB13.1 [^SP] CM* [CL CP EX IS SY] # original UAX 14 rule.
-# LB13.2 SP CM* [CL CP EX IS SY]
-
-LB13.1: [^NU SP] CM* [CL CP IS SY];
-LB13.2: [^SP] CM* EX;
-LB13.2: SP [CL CP EX IS SY];
-
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
# LB 14-17 are moved above LB 7.
@@ -186,8 +194,6 @@ LB23a.2: (ID | EB | EM) CM* PO;
LB24.2: (PR | PO) CM* (AL | HL);
LB24.3: (AL | HL | CM) CM* (PR | PO);
-# Numbers. Equivalent to Tailoring example 8 from UAx 14.
-LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
LB26.1: JL CM* (JL | JV | H2 | H3);
LB26.2: (JV | H2) CM* (JV | JT);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal_cj.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal_cj.txt
index cf9075171..57139f4b2 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal_cj.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/line_normal_cj.txt
@@ -26,6 +26,7 @@
# It sets characters of class CJ to behave like ID.
# In addition, it allows breaks:
# * before hyphens 2010 & 2013 (both BA) and 301C, 30A0 (both NS)
+# It allows breaking before 201C and after 201D, for zh_Hans, zh_Hant, and ja.
type = line;
locale = ja@lb=normal;
@@ -40,7 +41,7 @@ BK = [:LineBreak = Mandatory_Break:];
B2 = [:LineBreak = Break_Both:];
CB = [:LineBreak = Contingent_Break:];
CJ = [:LineBreak = Conditional_Japanese_Starter:];
-CL = [:LineBreak = Close_Punctuation:];
+CL = [[:LineBreak = Close_Punctuation:] \u201d];
CMS = [:LineBreak = Combining_Mark:];
CP = [:LineBreak = Close_Parenthesis:];
CR = [:LineBreak = Carriage_Return:];
@@ -63,10 +64,10 @@ NL = [:LineBreak = Next_Line:];
NSX = [\u301C \u30A0];
NS = [[:LineBreak = Nonstarter:] - NSX];
NU = [:LineBreak = Numeric:];
-OP = [:LineBreak = Open_Punctuation:];
+OP = [[:LineBreak = Open_Punctuation:] \u201c];
PO = [:LineBreak = Postfix_Numeric:];
PR = [:LineBreak = Prefix_Numeric:];
-QU = [:LineBreak = Quotation:];
+QU = [[:LineBreak = Quotation:] - [\u201c\u201d]];
RI = [:LineBreak = Regional_Indicator:];
SA = [:LineBreak = Complex_Context:];
SG = [:LineBreak = Surrogate:];
@@ -94,11 +95,29 @@ LB5.3: NL ÷;
LB6: . (BK | CR | LF | NL);
LB6.1: [^BK CR LF NL SP ZW] CM* (BK | CR | LF | NL);
+# LB8 break after ZW SP*.
+# Precedes LB7 because both rules will match the sequences like ZW SP,
+# and LB8 must take precedence.
+
+LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
+
+# Numbers. Equivalent to Tailoring example 8 from UAX 14.
+# Moved up, before LB14, because it can match longer sequences which must take precedence.
+LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? (IS CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
+
# Rules LB14 - LB17.
-# Moved before LB7, because they can match a longer sequence that would also match LB7,
-# for example, the sequence "OP CM SP AL" matches LB14 while the prefix of it,
-# "while only the prefix "OP CM SP" matches LB7.1
+# Moved up, before LB7, because they can match a longer sequence that would also match LB7.
+# For example, the sequence "OP CM SP AL" matches LB14
+# while the prefix of it, "OP CM SP" matches LB7.1
LB14: OP CM* SP* .;
+
+# LB 14a Break before an IS that begins a number and follows a space.
+LB14a: SP ÷ IS CM* NU;
+
+# LB14b × IS
+LB14b.1: [^SP] CM* IS;
+LB14b.2: SP IS;
+
LB15: QU CM* SP* OP;
# Do not break between closing punctuation and $NS, even with intervening spaces
@@ -106,11 +125,6 @@ LB15: QU CM* SP* OP;
LB16: (CL | CP)CM* SP* NS;
LB17: B2 CM* SP* B2;
-# LB8, break after ZW SP*, precedes LB7 because they will both match the sequences like ZW SP,
-# and LB8 should take precedence.
-
-LB8: ZW SP* ÷ [^ZW SP BK CR LF NL];
-
# LB7 Do not break before spaces or zero width space.
LB7.1: [^ZW SP] CM* [SP ZW];
@@ -137,15 +151,9 @@ LB12: GL CM* [^CM];
LB12a: [^SP BA BAX HY] CM* GL;
-# LB 13 ICU Tailoring, matches tailoring exmaple 8 from UAX 14.
-#
-# LB13.1 [^SP] CM* [CL CP EX IS SY] # original UAX 14 rule.
-# LB13.2 SP CM* [CL CP EX IS SY]
-
-LB13.1: [^NU SP] CM* [CL CP IS SY];
-LB13.2: [^SP] CM* EX;
-LB13.2: SP [CL CP EX IS SY];
-
+# LB 13 Do not break before ‘]’ or ‘!’ or ‘/’, even after spaces.
+LB13.1: [^SP] CM* [CL CP EX SY];
+LB13.2: SP [CL CP EX SY];
# LB 14-17 are moved above LB 7.
@@ -195,9 +203,6 @@ LB23a.2: (ID | EB | EM) CM* PO;
LB24.2: (PR | PO) CM* (AL | HL);
LB24.3: (AL | HL | CM) CM* (PR | PO);
-# Numbers. Equivalent to Tailoring example 8 from UAx 14.
-LB25: ((PR | PO)CM*)? ((OP | HY)CM*)? NU (CM*(NU | SY | IS))* (CM*(CL | CP))? (CM*(PR | PO))?;
-
LB26.1: JL CM* (JL | JV | H2 | H3);
LB26.2: (JV | H2) CM* (JV | JT);
LB26.3: (JT | H3) CM* JT;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word.txt
index fc7bc9b18..9b3e527ee 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word.txt
@@ -30,7 +30,7 @@ Double_Quote = [\p{Word_Break = Double_Quote}];
MidNumLet = [\p{Word_Break = MidNumLet}];
MidLetter = [\p{Word_Break = MidLetter}];
MidNum = [\p{Word_Break = MidNum}];
-Numeric = [\p{Word_Break = Numeric}];
+Numeric = [[\p{Word_Break = Numeric}] [\uFF10-\uff19]]; # Patch for ICU-12079;
ExtendNumLet = [\p{Word_Break = ExtendNumLet}];
WSegSpace = [\p{Word_Break = WSegSpace}];
Extended_Pict = [:ExtPict:];
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word_POSIX.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word_POSIX.txt
index 10efc32d2..04bcb321a 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word_POSIX.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/break_rules/word_POSIX.txt
@@ -29,7 +29,7 @@ Double_Quote = [\p{Word_Break = Double_Quote}];
MidNumLet = [\p{Word_Break = MidNumLet} - [.]];
MidLetter = [\p{Word_Break = MidLetter} - [\:]];
MidNum = [\p{Word_Break = MidNum} [.]];
-Numeric = [\p{Word_Break = Numeric}];
+Numeric = [[\p{Word_Break = Numeric}] [\uFF10-\uff19]]; # Patch for ICU-12079;
ExtendNumLet = [\p{Word_Break = ExtendNumLet}];
WSegSpace = [\p{Word_Break = WSegSpace}];
Extended_Pict = [:ExtPict:];
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt
index 63ba17223..a19419cd8 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt
@@ -240,8 +240,7 @@
<data>•aa\N{COMBINING GRAVE ACCENT}a<200> •</data>
# fullwidth numeric, midletter characters etc should be treated like their halfwidth counterparts
-# <data>•ISN'T<200> •19<100>日<400></data>
-# why was this added with the dbbi stuff?
+<data>•ISN'T<200> •19<100>日<400></data>
# to test for bug #4098467
# What follows is a string of Korean characters (I found it in the Yellow Pages
@@ -629,9 +628,9 @@ Calls to xxx will return an implementor of this interface. \u2029•</data>
<data>• •\u2014\u2028<100>\u2014•</data>
<data>• •\uFFFC\u2028<100>\uFFFC•</data>
<data>• \u0029\u2028<100>\u0029•</data>
-#<data>• \u0301\u2028<100>\u0301•</data> # TODO: fix.
+<data>• •\u0301\u2028<100>\u0301•</data>
<data>• \u0021\u2028<100>\u0021•</data>
-#<data>• \u00A0\u2028<100>\u00A0•</data> # TODO: fix
+<data>• •\u00A0\u2028<100>\u00A0•</data>
<data>• •\u002D\u2028<100>\u002D•</data>
<data>• •\u4E00\u2028<100>\u4E00•</data>
<data>• •\u2024\u2028<100>\u2024•</data>
@@ -650,7 +649,7 @@ Calls to xxx will return an implementor of this interface. \u2029•</data>
<data>• •\uF8FF\u2028<100>\uF8FF•</data>
<data>• \u200B\u2028<100>\u200B•</data>
-# Regional Indicator sequences. They group in pairs. The reverse rules are tricky.
+# Regional Indicator sequences. They group in pairs.
# Sequences are long enough that the non-exaustive monkey test won't reliably pick up problems.
<data>•\U0001F1E6\U0001F1E6•\U0001F1E6\U0001F1E6•\U0001F1E6\U0001F1E6•\U0001F1E6\U0001F1E6•</data>
@@ -778,6 +777,20 @@ between •Mae •Hong •Son •and •the •Salween •River, •the •Thano
the •Khun •Tan •Range •(ดอย•ขุน•ตาน), •the •Phi •Pan •Nam •Range •(ทิว•เขา•ผี•ปัน•น้ำ), •as •well •as •the •western •\
part •of •the •Luang •Prabang •Range •(ทิว•เขา•หลวง•พระ•บาง).•</data>
+# Breaking around numbers that begin with a decimal point.
+# Bug ICU-12017
+
+<line>
+<data>•start •.789 •end•</data>
+<data>•start .abc •end•</data>
+<data>•start •( .789 •end)•</data>
+<data>•start •.\u0301789 •end•</data> # \u0301 is a CM (COMBINING ACUTE ACCENT)
+<data>•start •.\u200D789 •end•</data> # \u200D is ZWJ
+<data>•start •.\u200D\u0301789 •end•</data>
+<data>•start •.\u0301\u200D789 •end•</data>
+<data>•start .\u0301\u200D•</data>
+<data>•start .\u0301\u200D •</data>
+<data>•start ; •end •</data>
########################################################################################
#
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/FormatHandler.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/FormatHandler.java
index 7bb5e98fc..8d5eeb46d 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/FormatHandler.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/FormatHandler.java
@@ -34,6 +34,7 @@ import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralFormat;
import com.ibm.icu.text.PluralRules;
+import com.ibm.icu.text.RelativeDateTimeFormatter;
import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.text.SelectFormat;
import com.ibm.icu.text.SimpleDateFormat;
@@ -1800,6 +1801,36 @@ public class FormatHandler
}
}
+ public static class RelativeDateTimeFormatterFieldHandler implements SerializableTestUtility.Handler
+ {
+ @Override
+ public Object[] getTestObjects()
+ {
+ return new Object[] {RelativeDateTimeFormatter.Field.LITERAL};
+ }
+
+ @Override
+ public boolean hasSameBehavior(Object a, Object b)
+ {
+ return (a == b);
+ }
+ }
+
+ public static class DateIntervalSpanFieldHandler implements SerializableTestUtility.Handler
+ {
+ @Override
+ public Object[] getTestObjects()
+ {
+ return new Object[] {DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN};
+ }
+
+ @Override
+ public boolean hasSameBehavior(Object a, Object b)
+ {
+ return (a == b);
+ }
+ }
+
public static class DateFormatHandler implements SerializableTestUtility.Handler
{
static HashMap cannedPatterns = new HashMap();
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java
index c1e97c771..7dba946f0 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java
@@ -818,6 +818,8 @@ public class SerializableTestUtility {
map.put("com.ibm.icu.text.DateFormat$Field", new FormatHandler.DateFormatFieldHandler());
map.put("com.ibm.icu.text.ChineseDateFormat$Field", new FormatHandler.ChineseDateFormatFieldHandler());
map.put("com.ibm.icu.text.MessageFormat$Field", new FormatHandler.MessageFormatFieldHandler());
+ map.put("com.ibm.icu.text.RelativeDateTimeFormatter$Field", new FormatHandler.RelativeDateTimeFormatterFieldHandler());
+ map.put("com.ibm.icu.text.DateIntervalFormat$SpanField", new FormatHandler.DateIntervalSpanFieldHandler());
map.put("com.ibm.icu.impl.duration.BasicDurationFormat", new FormatHandler.BasicDurationFormatHandler());
map.put("com.ibm.icu.impl.RelativeDateFormat", new FormatHandler.RelativeDateFormatHandler());
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat
deleted file mode 100644
index 59c12a9bb..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.InvalidFormatException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.InvalidFormatException.dat
deleted file mode 100644
index 6f521a4d0..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.InvalidFormatException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat
deleted file mode 100644
index 0132142eb..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.number.Properties.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.number.Properties.dat
deleted file mode 100644
index 9f33fd92e..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.number.Properties.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ArabicShapingException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ArabicShapingException.dat
deleted file mode 100644
index fc54cfcb2..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ArabicShapingException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat.dat
deleted file mode 100644
index 277fcdeac..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat
deleted file mode 100644
index 71f802782..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat.dat
deleted file mode 100644
index b35088114..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormatSymbols.dat
deleted file mode 100644
index d0b66d9aa..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormatSymbols.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormat.dat
deleted file mode 100644
index be4fa92ce..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormatSymbols.dat
deleted file mode 100644
index aedf1093c..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DecimalFormatSymbols.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MeasureFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MeasureFormat.dat
deleted file mode 100644
index f870a1f9d..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MeasureFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat.dat
deleted file mode 100644
index 7d9ed7aef..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralFormat.dat
deleted file mode 100644
index 788221fd4..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SimpleDateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SimpleDateFormat.dat
deleted file mode 100644
index 6ab1c4fcd..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SimpleDateFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.StringPrepParseException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.StringPrepParseException.dat
deleted file mode 100644
index 5b2b5c8c1..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.StringPrepParseException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeUnitFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeUnitFormat.dat
deleted file mode 100644
index 6802e5649..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeUnitFormat.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.BuddhistCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.BuddhistCalendar.dat
deleted file mode 100644
index e2cbddfd1..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.BuddhistCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ChineseCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ChineseCalendar.dat
deleted file mode 100644
index 8d0a912d8..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ChineseCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.EthiopicCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.EthiopicCalendar.dat
deleted file mode 100644
index 598b2087b..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.EthiopicCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat
deleted file mode 100644
index 33d7a9ec1..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUException.dat
deleted file mode 100644
index 6f53dded6..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUUncheckedIOException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUUncheckedIOException.dat
deleted file mode 100644
index 87f504aa7..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ICUUncheckedIOException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IllformedLocaleException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IllformedLocaleException.dat
deleted file mode 100644
index 9c4573e32..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IllformedLocaleException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IndianCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IndianCalendar.dat
deleted file mode 100644
index 4c69836b1..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IndianCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.JapaneseCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.JapaneseCalendar.dat
deleted file mode 100644
index 22c5321c3..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.JapaneseCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.PersianCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.PersianCalendar.dat
deleted file mode 100644
index e487e5b53..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.PersianCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TaiwanCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TaiwanCalendar.dat
deleted file mode 100644
index 3480e5929..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TaiwanCalendar.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.UResourceTypeMismatchException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.UResourceTypeMismatchException.dat
deleted file mode 100644
index 640fae3e7..000000000
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.UResourceTypeMismatchException.dat
+++ /dev/null
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.DateNumberFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.DateNumberFormat.dat
index 571713e21..571713e21 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.DateNumberFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.DateNumberFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat
new file mode 100644
index 000000000..384b149e1
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.InvalidFormatException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.InvalidFormatException.dat
new file mode 100644
index 000000000..bc8ea6453
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.InvalidFormatException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.JavaTimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.JavaTimeZone.dat
index f3e44f0ab..254b50db7 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.JavaTimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.JavaTimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.OlsonTimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.OlsonTimeZone.dat
index 6cc62cbae..564396483 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.OlsonTimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.OlsonTimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.RelativeDateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.RelativeDateFormat.dat
index 889d56cac..e8ea7432a 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.RelativeDateFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.RelativeDateFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat
index b3f344e2e..b3f344e2e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TZDBTimeZoneNames.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneAdapter.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneAdapter.dat
index 53aef916b..b8a2801a4 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneAdapter.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneAdapter.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneGenericNames.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneGenericNames.dat
index 056868dda..056868dda 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneGenericNames.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneGenericNames.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat
index 9548e9a06..9548e9a06 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.TimeZoneNamesImpl.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat
index 883e9aed7..883e9aed7 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat
new file mode 100644
index 000000000..4568ae05c
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Currency.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.CustomSymbolCurrency.dat
index 24627cc12..24627cc12 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Currency.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.CustomSymbolCurrency.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.DecimalFormatProperties.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.DecimalFormatProperties.dat
new file mode 100644
index 000000000..72bb5f0ff
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.DecimalFormatProperties.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.LocalizedNumberFormatterAsFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.LocalizedNumberFormatterAsFormat.dat
new file mode 100644
index 000000000..44475d607
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.LocalizedNumberFormatterAsFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.Properties.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.Properties.dat
new file mode 100644
index 000000000..b5775ace3
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.impl.number.Properties.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.BigDecimal.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.BigDecimal.dat
index b27bcaf1c..b27bcaf1c 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.BigDecimal.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.BigDecimal.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.MathContext.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.MathContext.dat
index da7bc6076..da7bc6076 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.math.MathContext.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.math.MathContext.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.number.SkeletonSyntaxException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.number.SkeletonSyntaxException.dat
new file mode 100644
index 000000000..8d1cb6ec2
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.number.SkeletonSyntaxException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ArabicShapingException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ArabicShapingException.dat
new file mode 100644
index 000000000..69e239137
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ArabicShapingException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat$Field.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat$Field.dat
index 2eb95fa67..2eb95fa67 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.ChineseDateFormat$Field.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat$Field.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat.dat
new file mode 100644
index 000000000..8f6791d88
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat
new file mode 100644
index 000000000..96ef88cf1
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CompactDecimalFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CompactDecimalFormat.dat
index 9252bf202..9252bf202 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CompactDecimalFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CompactDecimalFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CurrencyPluralInfo.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CurrencyPluralInfo.dat
index c18aa5c44..e35372cbe 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.CurrencyPluralInfo.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.CurrencyPluralInfo.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat$Field.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat$Field.dat
index a7cf73693..a7cf73693 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateFormat$Field.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat$Field.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat.dat
new file mode 100644
index 000000000..a578dcc0d
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormatSymbols.dat
new file mode 100644
index 000000000..df9e25009
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateFormatSymbols.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat$SpanField.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat$SpanField.dat
new file mode 100644
index 000000000..14859f733
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat$SpanField.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat.dat
index 7a6cfaab1..9d4d1ac49 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat
index 6bc48a952..6bc48a952 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo.dat
index b75cfcbca..4d99cc699 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.DateIntervalInfo.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DateIntervalInfo.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormat.dat
new file mode 100644
index 000000000..40aebfb94
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormatSymbols.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormatSymbols.dat
new file mode 100644
index 000000000..e90f8e132
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.DecimalFormatSymbols.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MeasureFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MeasureFormat.dat
new file mode 100644
index 000000000..05702101a
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MeasureFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat$Field.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat$Field.dat
index f30df97bf..f30df97bf 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat$Field.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat$Field.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat.dat
index 5f0b1bb7c..5f0b1bb7c 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.MessageFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.MessageFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat$Field.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat$Field.dat
index cab3e3df0..cab3e3df0 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.NumberFormat$Field.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat$Field.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat.dat
new file mode 100644
index 000000000..2bf1de719
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.NumberFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralFormat.dat
new file mode 100644
index 000000000..6fbc975af
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralRules.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralRules.dat
index 6982646be..6982646be 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.PluralRules.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.PluralRules.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RelativeDateTimeFormatter$Field.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RelativeDateTimeFormatter$Field.dat
new file mode 100644
index 000000000..1977b04e2
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RelativeDateTimeFormatter$Field.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.RuleBasedNumberFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RuleBasedNumberFormat.dat
index 64c471ee7..64c471ee7 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.RuleBasedNumberFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.RuleBasedNumberFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SelectFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SelectFormat.dat
index 3fd758f7e..3fd758f7e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.SelectFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SelectFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SimpleDateFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SimpleDateFormat.dat
new file mode 100644
index 000000000..5a8c1db6f
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.SimpleDateFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.StringPrepParseException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.StringPrepParseException.dat
new file mode 100644
index 000000000..3ef707a37
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.StringPrepParseException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeUnitFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeUnitFormat.dat
new file mode 100644
index 000000000..4a944833c
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeUnitFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeZoneFormat.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeZoneFormat.dat
index 6a8bffd3e..6a8bffd3e 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.text.TimeZoneFormat.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.text.TimeZoneFormat.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.AnnualTimeZoneRule.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.AnnualTimeZoneRule.dat
index 095de16c5..095de16c5 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.AnnualTimeZoneRule.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.AnnualTimeZoneRule.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.BuddhistCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.BuddhistCalendar.dat
new file mode 100644
index 000000000..ac1b3b0a0
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.BuddhistCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Calendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Calendar.dat
index 7052d76d7..c5b1c0bbf 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.Calendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Calendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ChineseCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ChineseCalendar.dat
new file mode 100644
index 000000000..15e2fde36
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ChineseCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.CopticCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.CopticCalendar.dat
index 9bb21c1d7..01ba80211 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.CopticCalendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.CopticCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Currency.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Currency.dat
new file mode 100644
index 000000000..24627cc12
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.Currency.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DangiCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DangiCalendar.dat
index b8b38ba6b..1dfad3c06 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DangiCalendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DangiCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateInterval.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateInterval.dat
index 71d722236..71d722236 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateInterval.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateInterval.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateTimeRule.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateTimeRule.dat
index ed1338849..ed1338849 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.DateTimeRule.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.DateTimeRule.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.EthiopicCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.EthiopicCalendar.dat
new file mode 100644
index 000000000..6a37fcc4a
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.EthiopicCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.GregorianCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.GregorianCalendar.dat
index 6ca49dcd0..d88df8ee6 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.GregorianCalendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.GregorianCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.HebrewCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.HebrewCalendar.dat
index 3ba8bf5c1..ead2f93c9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.HebrewCalendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.HebrewCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat
new file mode 100644
index 000000000..3e0c6940e
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUCloneNotSupportedException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUException.dat
new file mode 100644
index 000000000..094580bce
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUUncheckedIOException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUUncheckedIOException.dat
new file mode 100644
index 000000000..d84b7f77f
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ICUUncheckedIOException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IllformedLocaleException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IllformedLocaleException.dat
new file mode 100644
index 000000000..30199b7e5
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IllformedLocaleException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IndianCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IndianCalendar.dat
new file mode 100644
index 000000000..18e3914f8
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IndianCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.InitialTimeZoneRule.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.InitialTimeZoneRule.dat
index 7da9b4d81..7da9b4d81 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.InitialTimeZoneRule.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.InitialTimeZoneRule.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IslamicCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IslamicCalendar.dat
index 4af76ac31..51845a770 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.IslamicCalendar.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.IslamicCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.JapaneseCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.JapaneseCalendar.dat
new file mode 100644
index 000000000..d4e2b2cea
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.JapaneseCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.MeasureUnit.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.MeasureUnit.dat
index 9f018342f..9f018342f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.MeasureUnit.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.MeasureUnit.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeUnit.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.NoUnit.dat
index 9f018342f..9f018342f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeUnit.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.NoUnit.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.PersianCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.PersianCalendar.dat
new file mode 100644
index 000000000..1c0b45522
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.PersianCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.RuleBasedTimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.RuleBasedTimeZone.dat
index 285f40521..698b470d4 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.RuleBasedTimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.RuleBasedTimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.SimpleTimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.SimpleTimeZone.dat
index 216f9a5aa..216f9a5aa 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.SimpleTimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.SimpleTimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TaiwanCalendar.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TaiwanCalendar.dat
new file mode 100644
index 000000000..d8e96ced9
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TaiwanCalendar.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat
index b2224bdd6..b2224bdd6 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeUnit.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeUnit.dat
new file mode 100644
index 000000000..9f018342f
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeUnit.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeZone.dat
index 5d69e249d..b944d5957 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.TimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.TimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ULocale.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ULocale.dat
index ef2083217..ef2083217 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.ULocale.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.ULocale.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.UResourceTypeMismatchException.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.UResourceTypeMismatchException.dat
new file mode 100644
index 000000000..5d9435638
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.UResourceTypeMismatchException.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.VTimeZone.dat b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.VTimeZone.dat
index 77e2c5b0f..77e2c5b0f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_59.1/com.ibm.icu.util.VTimeZone.dat
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_64.1/com.ibm.icu.util.VTimeZone.dat
Binary files differ
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/BytesTrieTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/BytesTrieTest.java
index d3f88494f..6cca357f7 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/BytesTrieTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/BytesTrieTest.java
@@ -510,6 +510,27 @@ public class BytesTrieTest extends TestFmwk {
data);
}
+ @Test
+ public void TestClone() throws CloneNotSupportedException {
+ final StringAndValue[] data={
+ new StringAndValue("a", 1),
+ new StringAndValue("ab", 100),
+ new StringAndValue("abc", 300),
+ new StringAndValue("az", 999)
+ };
+ BytesTrie trie = buildTrie(data, data.length, StringTrieBuilder.Option.SMALL);
+ assertEquals("a result", BytesTrie.Result.INTERMEDIATE_VALUE, trie.next('a'));
+ assertEquals("a value", 1, trie.getValue());
+ BytesTrie clone = trie.clone();
+ trie = null;
+ assertEquals("ab result", BytesTrie.Result.INTERMEDIATE_VALUE, clone.next('b'));
+ assertEquals("ab value", 100, clone.getValue());
+ BytesTrie copy = new BytesTrie(clone);
+ clone = null;
+ assertEquals("abc result", BytesTrie.Result.FINAL_VALUE, copy.next('c'));
+ assertEquals("abc value", 300, copy.getValue());
+ }
+
private void checkData(StringAndValue data[]) {
checkData(data, data.length);
}
@@ -526,6 +547,7 @@ public class BytesTrieTest extends TestFmwk {
checkFirst(trie, data, dataLength);
checkNext(trie, data, dataLength);
checkNextWithState(trie, data, dataLength);
+ checkNextWithState64(trie, data, dataLength);
checkNextString(trie, data, dataLength);
checkIterator(trie, data, dataLength);
}
@@ -718,6 +740,54 @@ public class BytesTrieTest extends TestFmwk {
}
}
+ private void checkNextWithState64(BytesTrie trie, StringAndValue data[], int dataLength) {
+ assertNotEquals("trie(initial state).getState64()!=0", 0, trie.getState64());
+ for(int i=0; i<dataLength; ++i) {
+ byte[] expectedString=data[i].bytes;
+ int stringLength=data[i].s.length();
+ int partialLength=stringLength/3;
+ for(int j=0; j<partialLength; ++j) {
+ if(!trie.next(expectedString[j]).matches()) {
+ errln("trie.next()=BytesTrie.Result.NO_MATCH for a prefix of "+data[i].s);
+ return;
+ }
+ }
+ long state = trie.getState64();
+ assertNotEquals("trie.getState64()!=0", 0, state);
+ BytesTrie.Result resultAtState=trie.current();
+ BytesTrie.Result result;
+ int valueAtState=-99;
+ if(resultAtState.hasValue()) {
+ valueAtState=trie.getValue();
+ }
+ result=trie.next(0); // mismatch
+ if(result!=BytesTrie.Result.NO_MATCH || result!=trie.current()) {
+ errln("trie.next(0) matched after part of "+data[i].s);
+ }
+ if( resultAtState!=trie.resetToState64(state).current() ||
+ (resultAtState.hasValue() && valueAtState!=trie.getValue())
+ ) {
+ errln("trie.next(part of "+data[i].s+") changes current()/getValue() after "+
+ "saveState/next(0)/resetToState");
+ } else if(!(result=trie.next(expectedString, partialLength, stringLength)).hasValue() ||
+ result!=trie.current()) {
+ errln("trie.next(rest of "+data[i].s+") does not seem to contain "+data[i].s+" after "+
+ "saveState/next(0)/resetToState");
+ } else if(!(result=trie.resetToState64(state).
+ next(expectedString, partialLength, stringLength)).hasValue() ||
+ result!=trie.current()) {
+ errln("trie does not seem to contain "+data[i].s+
+ " after saveState/next(rest)/resetToState");
+ } else if(trie.getValue()!=data[i].value) {
+ errln(String.format("trie value for %s is %d=0x%x instead of expected %d=0x%x",
+ data[i].s,
+ trie.getValue(), trie.getValue(),
+ data[i].value, data[i].value));
+ }
+ trie.reset();
+ }
+ }
+
// next(string) is also tested in other functions,
// but here we try to go partway through the string, and then beyond it.
private void checkNextString(BytesTrie trie, StringAndValue data[], int dataLength) {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CharsTrieTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CharsTrieTest.java
index 6654e7ebb..149e7bfdd 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CharsTrieTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CharsTrieTest.java
@@ -637,6 +637,27 @@ public class CharsTrieTest extends TestFmwk {
checkIterator(CharsTrie.iterator(trieChars, 0, 0), data);
}
+ @Test
+ public void TestClone() throws CloneNotSupportedException {
+ final StringAndValue[] data={
+ new StringAndValue("a", 1),
+ new StringAndValue("ab", 100),
+ new StringAndValue("abc", 300),
+ new StringAndValue("az", 999)
+ };
+ CharsTrie trie = buildTrie(data, data.length, StringTrieBuilder.Option.SMALL);
+ assertEquals("a result", BytesTrie.Result.INTERMEDIATE_VALUE, trie.next('a'));
+ assertEquals("a value", 1, trie.getValue());
+ CharsTrie clone = trie.clone();
+ trie = null;
+ assertEquals("ab result", BytesTrie.Result.INTERMEDIATE_VALUE, clone.next('b'));
+ assertEquals("ab value", 100, clone.getValue());
+ CharsTrie copy = new CharsTrie(clone);
+ clone = null;
+ assertEquals("abc result", BytesTrie.Result.FINAL_VALUE, copy.next('c'));
+ assertEquals("abc value", 300, copy.getValue());
+ }
+
private void checkData(StringAndValue data[]) {
checkData(data, data.length);
}
@@ -653,6 +674,7 @@ public class CharsTrieTest extends TestFmwk {
checkFirst(trie, data, dataLength);
checkNext(trie, data, dataLength);
checkNextWithState(trie, data, dataLength);
+ checkNextWithState64(trie, data, dataLength);
checkNextString(trie, data, dataLength);
checkIterator(trie, data, dataLength);
}
@@ -864,6 +886,54 @@ public class CharsTrieTest extends TestFmwk {
}
}
+ private void checkNextWithState64(CharsTrie trie, StringAndValue[] data, int dataLength) {
+ assertNotEquals("trie(initial state).getState64()!=0", 0, trie.getState64());
+ for(int i=0; i<dataLength; ++i) {
+ String expectedString=data[i].s;
+ int stringLength=expectedString.length();
+ int partialLength=stringLength/3;
+ for(int j=0; j<partialLength; ++j) {
+ if(!trie.next(expectedString.charAt(j)).matches()) {
+ errln("trie.next()=BytesTrie.Result.NO_MATCH for a prefix of "+data[i].s);
+ return;
+ }
+ }
+ long state = trie.getState64();
+ assertNotEquals("trie.getState64()!=0", 0, state);
+ BytesTrie.Result resultAtState=trie.current();
+ BytesTrie.Result result;
+ int valueAtState=-99;
+ if(resultAtState.hasValue()) {
+ valueAtState=trie.getValue();
+ }
+ result=trie.next(0); // mismatch
+ if(result!=BytesTrie.Result.NO_MATCH || result!=trie.current()) {
+ errln("trie.next(0) matched after part of "+data[i].s);
+ }
+ if( resultAtState!=trie.resetToState64(state).current() ||
+ (resultAtState.hasValue() && valueAtState!=trie.getValue())
+ ) {
+ errln("trie.next(part of "+data[i].s+") changes current()/getValue() after "+
+ "saveState/next(0)/resetToState");
+ } else if(!(result=trie.next(expectedString, partialLength, stringLength)).hasValue() ||
+ result!=trie.current()) {
+ errln("trie.next(rest of "+data[i].s+") does not seem to contain "+data[i].s+" after "+
+ "saveState/next(0)/resetToState");
+ } else if(!(result=trie.resetToState64(state).
+ next(expectedString, partialLength, stringLength)).hasValue() ||
+ result!=trie.current()) {
+ errln("trie does not seem to contain "+data[i].s+
+ " after saveState/next(rest)/resetToState");
+ } else if(trie.getValue()!=data[i].value) {
+ errln(String.format("trie value for %s is %d=0x%x instead of expected %d=0x%x",
+ data[i].s,
+ trie.getValue(), trie.getValue(),
+ data[i].value, data[i].value));
+ }
+ trie.reset();
+ }
+ }
+
// next(string) is also tested in other functions,
// but here we try to go partway through the string, and then beyond it.
private void checkNextString(CharsTrie trie, StringAndValue[] data, int dataLength) {
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
index 508e8faa5..7c8a3cced 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
@@ -239,6 +239,30 @@ public class CurrencyTest extends TestFmwk {
}
@Test
+ public void test20484_NarrowSymbolFallback() {
+ Object[][] cases = new Object[][] {
+ {"en-US", "CAD", "CA$", "$"},
+ {"en-US", "CDF", "CDF", "CDF"},
+ {"sw-CD", "CDF", "FC", "FC"},
+ {"en-US", "GEL", "GEL", "₾"},
+ {"ka-GE", "GEL", "₾", "₾"},
+ {"ka", "GEL", "₾", "₾"},
+ };
+ for (Object[] cas : cases) {
+ ULocale locale = new ULocale((String) cas[0]);
+ String isoCode = (String) cas[1];
+ String expectedShort = (String) cas[2];
+ String expectedNarrow = (String) cas[3];
+
+ CurrencyDisplayNames cdn = CurrencyDisplayNames.getInstance(locale);
+ assertEquals("Short symbol: " + locale + ": " + isoCode,
+ expectedShort, cdn.getSymbol(isoCode));
+ assertEquals("Narrow symbol: " + locale + ": " + isoCode,
+ expectedNarrow, cdn.getNarrowSymbol(isoCode));
+ }
+ }
+
+ @Test
public void testGetName_Locale_Int_String_BooleanArray() {
Currency currency = Currency.getInstance(ULocale.CHINA);
boolean[] isChoiceFormat = new boolean[1];
@@ -626,7 +650,6 @@ public class CurrencyTest extends TestFmwk {
{ "eo_DE@currency=DEM", "2000-12-23", "EUR", "DEM" },
{ "eo-DE-u-cu-dem", "2000-12-23", "EUR", "DEM" },
{ "en_US", null, "USD", "USN" },
- { "en_US_PREEURO", null, "USD", "USN" },
{ "en_US_Q", null, "USD", "USN" },
};
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java
index 17105ecd7..b91206933 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/DebugUtilitiesData.java
@@ -10,7 +10,7 @@
package com.ibm.icu.dev.test.util;
public class DebugUtilitiesData extends Object {
- public static final String ICU4C_VERSION="63.2";
+ public static final String ICU4C_VERSION="64.2";
public static final int UDebugEnumType = 0;
public static final int UCalendarDateFields = 1;
public static final int UCalendarMonths = 2;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java
index 6294f0ec2..28f77b7dc 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ICUResourceBundleTest.java
@@ -754,7 +754,6 @@ public final class ICUResourceBundleTest extends TestFmwk {
@Test
public void TestFunctionalEquivalent(){
- // Android patch: Force default Gregorian calendar.
String[] calCases = {
// avail locale equiv
"t", "en_US_POSIX", "en@calendar=gregorian",
@@ -762,11 +761,10 @@ public final class ICUResourceBundleTest extends TestFmwk {
"f", "ja_JP_TOKYO@calendar=japanese", "ja@calendar=japanese",
"t", "sr@calendar=gregorian", "sr@calendar=gregorian",
"t", "en", "en@calendar=gregorian",
- "t", "th_TH", "th@calendar=gregorian",
+ "t", "th_TH", "th@calendar=buddhist",
"t", "th_TH@calendar=gregorian", "th@calendar=gregorian",
- "f", "th_TH_Bangkok", "th@calendar=gregorian",
+ "f", "th_TH_Bangkok", "th@calendar=buddhist",
};
- // Android patch end.
logln("Testing functional equivalents for calendar...");
getFunctionalEquivalentTestCases(ICUData.ICU_BASE_NAME,
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleBuilderTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleBuilderTest.java
index 772d0eab2..71002bac2 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleBuilderTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleBuilderTest.java
@@ -82,12 +82,12 @@ public class LocaleBuilderTest extends TestFmwk {
{"E", "z", "ExtZ", "L", "en", "E", "z", null, "T", "en", "en"},
{"E", "a", "x", "X"},
{"E", "a", "abc_def", "T", "und-a-abc-def", "@a=abc-def"},
- // Design limitation - typeless u extension keyword 00 below is interpreted as a boolean value true/yes.
+ // Design limitation - typeless u extension keyword 0a below is interpreted as a boolean value true/yes.
// With the legacy keyword syntax, "yes" is used for such boolean value instead of "true".
- // However, once the legacy keyword is translated back to BCP 47 u extension, key "00" is unknown,
+ // However, once the legacy keyword is translated back to BCP 47 u extension, key "0a" is unknown,
// so "yes" is preserved - not mapped to "true". We could change the code to automatically transform
- // "yes" to "true", but it will break roundtrip conversion if BCP 47 u extension has "00-yes".
- {"L", "en", "E", "u", "bbb-aaa-00", "T", "en-u-aaa-bbb-00-yes", "en@00=yes;attribute=aaa-bbb"},
+ // "yes" to "true", but it will break roundtrip conversion if BCP 47 u extension has "0a-yes".
+ {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a-yes", "en@0a=yes;attribute=aaa-bbb"},
{"L", "fr", "R", "FR", "P", "Yoshito-ICU", "T", "fr-FR-x-yoshito-icu", "fr_FR@x=yoshito-icu"},
{"L", "ja", "R", "jp", "K", "ca", "japanese", "T", "ja-JP-u-ca-japanese", "ja_JP@calendar=japanese"},
{"K", "co", "PHONEBK", "K", "ca", "gregory", "L", "De", "T", "de-u-ca-gregory-co-phonebk", "de@calendar=gregorian;collation=phonebook"},
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
index 6071e5dca..0b1f7cda5 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
@@ -193,7 +193,7 @@ public class LocaleMatcherTest extends TestFmwk {
final LocaleMatcher matcher = newLocaleMatcher("en, fil, ro, nn");
assertEquals(new ULocale("fil"), matcher.getBestMatch("tl"));
assertEquals(new ULocale("ro"), matcher.getBestMatch("mo"));
- assertEquals(new ULocale("nn"), matcher.getBestMatch("no")); // Google patch
+ assertEquals(new ULocale("nn"), matcher.getBestMatch("nb"));
// make sure default works
assertEquals(new ULocale("en"), matcher.getBestMatch("ja"));
}
@@ -377,7 +377,7 @@ public class LocaleMatcherTest extends TestFmwk {
// When it *does* occur in the list, BestMatch returns it, as expected.
matcher = newLocaleMatcher("it,und");
- assertEquals("und", matcher.getBestMatch("und").toString());
+ assertEquals("", matcher.getBestMatch("und").toString());
// The unusual part:
// max("und") = "en_Latn_US", and since matching is based on maximized
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TestLocaleValidity.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TestLocaleValidity.java
index 7a411b864..553cbd802 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TestLocaleValidity.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TestLocaleValidity.java
@@ -105,8 +105,8 @@ public class TestLocaleValidity extends TestFmwk {
{"OK", "en-u-ca-buddhist-ca-islamic-umalqura-cf-account-co-big5han-cu-adp-fw-fri-hc-h11-ka-noignore-kb-false-kc-false-kf-false-kk-false-kn-false-kr-latn-digit-symbol-ks-identic-kv-currency-nu-ahom-sd-usny-tz-adalv-va-posix"},
- // bad case (for language tag)
- {"{language, root}", "root"},
+ // root is canonicalized to the root locale (ICU-20273)
+ {"OK", "root"},
// deprecated, but turned into valid by ULocale.Builder()
{"OK", "en-u-ca-islamicc"}, // deprecated
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java
index babf4cdbc..56dd2a2d9 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/ULocaleTest.java
@@ -25,6 +25,7 @@ import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -677,9 +678,6 @@ public class ULocaleTest extends TestFmwk {
{"no", "", "", "NY", "no@ny", "no@ny", "no__NY"},
{"el", "Latn", "", "", "el-latn", "el_Latn", null},
{"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", null},
- {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
- {"zh", "Hant", "CN", "STROKE", "zh-hant_CN_STROKE", "zh_Hant_CN_STROKE", "zh_Hant_CN@collation=stroke"},
- {"zh", "Hant", "TW", "PINYIN", "zh-hant_TW_PINYIN", "zh_Hant_TW_PINYIN", "zh_Hant_TW@collation=pinyin"},
{"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", null},
{"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", null},
{"ab", "Cdef", "GH", "IJ", "ab_cdef_gh_ij", "ab_Cdef_GH_IJ", null}, /* total garbage */
@@ -689,6 +687,13 @@ public class ULocaleTest extends TestFmwk {
{"", "", "", "", "_@FOO=bar", "@foo=bar", null},
{"", "", "", "", "__@FOO=bar", "@foo=bar", null},
{"", "", "", "FOO", "__foo@FOO=bar", "__FOO@foo=bar", null}, // we have some of these prefixes
+
+ // Before ICU 64, ICU locale canonicalization had some additional mappings.
+ // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
+ // The following now use standard canonicalization.
+ {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW_STROKE"},
+ {"zh", "Hant", "CN", "STROKE", "zh-hant_CN_STROKE", "zh_Hant_CN_STROKE", "zh_Hant_CN_STROKE"},
+ {"zh", "Hant", "TW", "PINYIN", "zh-hant_TW_PINYIN", "zh_Hant_TW_PINYIN", "zh_Hant_TW_PINYIN"},
};
String loc, buf,buf1;
@@ -886,35 +891,6 @@ public class ULocaleTest extends TestFmwk {
@Test
public void TestCanonicalization(){
final String[][]testCases = new String[][]{
- { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
- { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
- { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
- { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=EUR" },
- { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
- { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
- { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
- { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
- { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
- { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
- { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
- { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
- { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
- { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
- { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
- { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
- { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
- { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
- { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
- { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
- { "de_PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
- { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
- { "en_GB@EURO", null, "en_GB@currency=EUR" }, /* POSIX ID */
- { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
- { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
- { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
- { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
- { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
- { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
{ "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
{ "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
{ "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
@@ -923,17 +899,9 @@ public class ULocaleTest extends TestFmwk {
{ "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
{ "no@ny", null, "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
{ "no-no.utf32@B", null, "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
- { "qz-qz@Euro", null, "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
{ "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
{ "de-1901", "de__1901", "de__1901" }, /* registered name */
{ "de-1906", "de__1906", "de__1906" }, /* registered name */
- { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
- { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
- { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
- { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
- { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
- { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
- { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
/* posix behavior that used to be performed by getName */
{ "mr.utf8", null, "mr" },
@@ -948,6 +916,56 @@ public class ULocaleTest extends TestFmwk {
{ "en_Hant_IL_VALLEY_GIRL@currency=EUR;calendar=Japanese;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
/* already-canonical ids are not changed */
{ "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
+ /* norwegian is just too weird, if we handle things in their full generality */
+ /* this is a negative test to show that we DO NOT handle 'lang=no,var=NY' specially. */
+ { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
+
+ /* test cases reflecting internal resource bundle usage */
+ /* root is just a language */
+ { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
+ /* level 2 canonicalization should not touch basename when there are keywords and it is null */
+ { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
+
+ // Before ICU 64, ICU locale canonicalization had some additional mappings.
+ // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
+ // The following now use standard canonicalization.
+ { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES_PREEURO" },
+ { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT_PREEURO" },
+ { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE_PREEURO" },
+ { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU_PREEURO" },
+ { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR_PREEURO" },
+ { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE_PREEURO" },
+ { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE_PREEURO" },
+ { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES_PREEURO" },
+ { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES_PREEURO" },
+ { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI_PREEURO" },
+ { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE_PREEURO" },
+ { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR_PREEURO" },
+ { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU_PREEURO" },
+ { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE_PREEURO" },
+ { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES_PREEURO" },
+ { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT_PREEURO" },
+ { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE_PREEURO" },
+ { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL_PREEURO" },
+ { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT_PREEURO" },
+ { "de__PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
+ { "de_PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
+ { "en_GB_EURO", "en_GB_EURO", "en_GB_EURO" },
+ { "en_GB@EURO", null, "en_GB_EURO" }, /* POSIX ID */
+ { "es__TRADITIONAL", "es__TRADITIONAL", "es__TRADITIONAL" },
+ { "hi__DIRECT", "hi__DIRECT", "hi__DIRECT" },
+ { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL" },
+ { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH_TRADITIONAL" },
+ { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW_STROKE" },
+ { "zh__PINYIN", "zh__PINYIN", "zh__PINYIN" },
+ { "qz-qz@Euro", null, "qz_QZ_EURO" }, /* qz-qz uses private use iso codes */
+ { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_SP_CYRL" }, /* .NET name */
+ { "sr-SP-Latn", "sr_SP_LATN", "sr_SP_LATN" }, /* .NET name */
+ { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_YU_CYRILLIC" }, /* Linux name */
+ { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_UZ_CYRL" }, /* .NET name */
+ { "uz-UZ-Latn", "uz_UZ_LATN", "uz_UZ_LATN" }, /* .NET name */
+ { "zh-CHS", "zh_CHS", "zh_CHS" }, /* .NET name */
+ { "zh-CHT", "zh_CHT", "zh_CHT" }, /* .NET name This may change back to zh_Hant */
/* PRE_EURO and EURO conversions don't affect other keywords */
/* not in spec
{ "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
@@ -958,15 +976,6 @@ public class ULocaleTest extends TestFmwk {
{ "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
{ "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
*/
- /* norwegian is just too weird, if we handle things in their full generality */
- /* this is a negative test to show that we DO NOT handle 'lang=no,var=NY' specially. */
- { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
-
- /* test cases reflecting internal resource bundle usage */
- /* root is just a language */
- { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
- /* level 2 canonicalization should not touch basename when there are keywords and it is null */
- { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
};
for(int i = 0; i< testCases.length;i++){
@@ -1481,6 +1490,14 @@ public class ULocaleTest extends TestFmwk {
assertEquals("foobar", target, name);
}
+ @Test
+ public void TestBug20407iVariantPreferredValue() {
+ ULocale uloc = ULocale.createCanonical("hy-arevela");
+ assertEquals("getName()", "hy", uloc.getName());
+ uloc = ULocale.createCanonical("hy-arevmda");
+ assertEquals("getName()", "hyw", uloc.getName());
+ }
+
private void initHashtable() {
h[0] = new HashMap<String, String>();
h[1] = new HashMap<String, String>();
@@ -3044,8 +3061,8 @@ public class ULocaleTest extends TestFmwk {
"nl"
}, {
"und_NO",
- "no_Latn_NO", // Android patch: Replace nb with no.
- "no"
+ "nb_Latn_NO",
+ "nb"
}, {
"und_NP",
"ne_Deva_NP",
@@ -3156,8 +3173,8 @@ public class ULocaleTest extends TestFmwk {
"sl"
}, {
"und_SJ",
- "no_Latn_SJ", // Android patch: Replace nb with no.
- "no_SJ"
+ "nb_Latn_SJ",
+ "nb_SJ"
}, {
"und_SK",
"sk_Latn_SK",
@@ -3408,8 +3425,8 @@ public class ULocaleTest extends TestFmwk {
"zh_HK"
}, {
"und_AQ",
- "und_Latn_AQ",
- "und_AQ"
+ "_Latn_AQ",
+ "_AQ"
}, {
"und_Zzzz",
"en_Latn_US",
@@ -3432,8 +3449,8 @@ public class ULocaleTest extends TestFmwk {
"zh_HK"
}, {
"und_Zzzz_AQ",
- "und_Latn_AQ",
- "und_AQ"
+ "_Latn_AQ",
+ "_AQ"
}, {
"und_Latn",
"en_Latn_US",
@@ -3456,8 +3473,8 @@ public class ULocaleTest extends TestFmwk {
"zh_Latn_HK"
}, {
"und_Latn_AQ",
- "und_Latn_AQ",
- "und_AQ"
+ "_Latn_AQ",
+ "_AQ"
}, {
"und_Hans",
"zh_Hans_CN",
@@ -3528,8 +3545,8 @@ public class ULocaleTest extends TestFmwk {
"zh_Moon_HK"
}, {
"und_Moon_AQ",
- "und_Moon_AQ",
- "und_Moon_AQ"
+ "_Moon_AQ",
+ "_Moon_AQ"
}, {
"es",
"es_Latn_ES",
@@ -4068,6 +4085,8 @@ public class ULocaleTest extends TestFmwk {
{"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil"},
{"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo"},
{"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
+ /* ICU-20320*/
+ {"en@9=efg;a=baz", "en-9-efg-a-baz"},
};
for (int i = 0; i < locale_to_langtag.length; i++) {
@@ -4094,6 +4113,13 @@ public class ULocaleTest extends TestFmwk {
}
@Test
+ public void TestDigitSingletonExtensionBug20320() {
+ ULocale uloc = ULocale.forLanguageTag("en-0-abc-a-xyz");
+ assertEquals("getExtension(\'a\')", "xyz", uloc.getExtension('a'));
+ assertEquals("getExtension(\'0\')", "abc", uloc.getExtension('0'));
+ }
+
+ @Test
public void TestForLanguageTag() {
final Integer NOERROR = Integer.valueOf(-1);
@@ -4162,6 +4188,9 @@ public class ULocaleTest extends TestFmwk {
{"zh-u-ca-gregory-co-pinyin-ca-chinese", "zh@calendar=gregorian;collation=pinyin", NOERROR},
{"de-latn-DE-1901-u-co-phonebk-co-pinyin-ca-gregory", "de_Latn_DE_1901@calendar=gregorian;collation=phonebook", NOERROR},
{"th-u-kf-nu-thai-kf-false", "th@colcasefirst=yes;numbers=thai", NOERROR},
+ /* #20410 */
+ {"art-lojban-x-0", "jbo@x=0", NOERROR},
+ {"zh-xiang-u-nu-thai-x-0", "hsn@numbers=thai;x=0", NOERROR},
};
for (int i = 0; i < langtag_to_locale.length; i++) {
@@ -4244,7 +4273,7 @@ public class ULocaleTest extends TestFmwk {
{new ULocale("en__POSIX"), new ULocale("en"), ULocale.ROOT, null},
{new ULocale("de_DE@collation=phonebook"), new ULocale("de@collation=phonebook"), new ULocale("@collation=phonebook"), null},
{new ULocale("_US_POSIX"), new ULocale("_US"), ULocale.ROOT, null},
- {new ULocale("root"), ULocale.ROOT, null},
+ {new ULocale("root"), null},
};
for(ULocale[] chain : TESTLOCALES) {
@@ -4316,7 +4345,7 @@ public class ULocaleTest extends TestFmwk {
for (String[] testcase : TESTCASES) {
ULocale loc = ULocale.forLanguageTag(testcase[0]);
- Set<String> expectedAttributes = new HashSet<String>();
+ Set<String> expectedAttributes = new HashSet<>();
if (testcase[1] != null) {
String[] attrs = testcase[1].split(",");
for (String s : attrs) {
@@ -4324,7 +4353,7 @@ public class ULocaleTest extends TestFmwk {
}
}
- Map<String, String> expectedKeywords = new HashMap<String, String>();
+ Map<String, String> expectedKeywords = new HashMap<>();
if (testcase[2] != null) {
String[] ukeys = testcase[2].split(",");
for (int i = 0; i < ukeys.length; i++) {
@@ -4648,7 +4677,6 @@ public class ULocaleTest extends TestFmwk {
"th_TH@calendar=gergorian",
"th_TH@numbers=latn",
"this is a bogus locale id",
- "und",
"zh_CN",
"zh_TW",
"zh_Hans",
@@ -4656,7 +4684,7 @@ public class ULocaleTest extends TestFmwk {
"zh_Hant_TW",
};
- TreeSet<ULocale> sortedLocales = new TreeSet<ULocale>();
+ TreeSet<ULocale> sortedLocales = new TreeSet<>();
for (ULocale locale : locales) {
sortedLocales.add(locale);
}
@@ -4697,6 +4725,36 @@ public class ULocaleTest extends TestFmwk {
}
@Test
+ public void TestBug20321UnicodeLocaleKey() {
+ // key = alphanum alpha ;
+ String[] INVALID = {
+ "a0",
+ "00",
+ "a@",
+ "0@",
+ "@a",
+ "@a",
+ "abc",
+ "0bc",
+ };
+
+ for (String invalid : INVALID) {
+ String bcpKey = ULocale.toUnicodeLocaleKey(invalid);
+ assertNull("keyword=" + invalid, bcpKey);
+ }
+
+ String[] VALID = {
+ "aa",
+ "0a",
+ };
+
+ for (String valid : VALID) {
+ String bcpKey = ULocale.toUnicodeLocaleKey(valid);
+ assertEquals("keyword=" + valid, valid, bcpKey);
+ };
+ }
+
+ @Test
public void TestToLegacyKey() {
String[][] DATA = {
{"kb", "colbackwards"},
@@ -4832,4 +4890,148 @@ public class ULocaleTest extends TestFmwk {
}
}
}
+
+ @Test
+ public void TestUnd() {
+ final String empty = "";
+ final String root = "root";
+ final String und = "und";
+
+ ULocale empty_new = new ULocale(empty);
+ ULocale empty_tag = ULocale.forLanguageTag(empty);
+
+ ULocale root_new = new ULocale(root);
+ ULocale root_tag = ULocale.forLanguageTag(root);
+ ULocale root_build = new Builder().setLanguageTag(root).build();
+
+ ULocale und_new = new ULocale(und);
+ ULocale und_tag = ULocale.forLanguageTag(und);
+ ULocale und_build = new Builder().setLanguageTag(und).build();
+
+ Assert.assertEquals(empty, empty_new.getName());
+ Assert.assertEquals(empty, root_new.getName());
+ Assert.assertEquals(empty, und_new.getName());
+
+ Assert.assertEquals(empty, empty_tag.getName());
+ Assert.assertEquals(empty, root_tag.getName());
+ Assert.assertEquals(empty, und_tag.getName());
+
+ Assert.assertEquals(empty, root_build.getName());
+ Assert.assertEquals(empty, und_build.getName());
+
+ Assert.assertEquals(und, empty_new.toLanguageTag());
+ Assert.assertEquals(und, root_new.toLanguageTag());
+ Assert.assertEquals(und, und_new.toLanguageTag());
+
+ Assert.assertEquals(und, empty_tag.toLanguageTag());
+ Assert.assertEquals(und, root_tag.toLanguageTag());
+ Assert.assertEquals(und, und_tag.toLanguageTag());
+
+ Assert.assertEquals(und, root_build.toLanguageTag());
+ Assert.assertEquals(und, und_build.toLanguageTag());
+
+ Assert.assertEquals(empty_new, empty_tag);
+
+ Assert.assertEquals(root_new, root_tag);
+ Assert.assertEquals(root_new, root_build);
+ Assert.assertEquals(root_tag, root_build);
+
+ Assert.assertEquals(und_new, und_tag);
+ Assert.assertEquals(und_new, und_build);
+ Assert.assertEquals(und_tag, und_build);
+
+ Assert.assertEquals(empty_new, root_new);
+ Assert.assertEquals(empty_new, und_new);
+ Assert.assertEquals(root_new, und_new);
+
+ Assert.assertEquals(empty_tag, root_tag);
+ Assert.assertEquals(empty_tag, und_tag);
+ Assert.assertEquals(root_tag, und_tag);
+
+ Assert.assertEquals(root_build, und_build);
+
+ final ULocale displayLocale = ULocale.ENGLISH;
+ final String displayName = "Unknown language";
+
+ Assert.assertEquals(displayName, empty_new.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, root_new.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, und_new.getDisplayName(displayLocale));
+
+ Assert.assertEquals(displayName, empty_tag.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, root_tag.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, und_tag.getDisplayName(displayLocale));
+
+ Assert.assertEquals(displayName, root_build.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, und_build.getDisplayName(displayLocale));
+ }
+
+ @Test
+ public void TestUndScript() {
+ final String id = "_Cyrl";
+ final String tag = "und-Cyrl";
+ final String script = "Cyrl";
+
+ ULocale locale_new = new ULocale(id);
+ ULocale locale_legacy = new ULocale(tag);
+ ULocale locale_tag = ULocale.forLanguageTag(tag);
+ ULocale locale_build = new Builder().setScript(script).build();
+
+ Assert.assertEquals(id, locale_new.getName());
+ Assert.assertEquals(id, locale_legacy.getName());
+ Assert.assertEquals(id, locale_tag.getName());
+ Assert.assertEquals(id, locale_build.getName());
+
+ Assert.assertEquals(tag, locale_new.toLanguageTag());
+ Assert.assertEquals(tag, locale_legacy.toLanguageTag());
+ Assert.assertEquals(tag, locale_tag.toLanguageTag());
+ Assert.assertEquals(tag, locale_build.toLanguageTag());
+
+ Assert.assertEquals(locale_new, locale_legacy);
+ Assert.assertEquals(locale_new, locale_tag);
+ Assert.assertEquals(locale_new, locale_build);
+ Assert.assertEquals(locale_tag, locale_build);
+
+ final ULocale displayLocale = ULocale.ENGLISH;
+ final String displayName = "Unknown language (Cyrillic)";
+
+ Assert.assertEquals(displayName, locale_new.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_legacy.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_tag.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_build.getDisplayName(displayLocale));
+ }
+
+ @Test
+ public void TestUndRegion() {
+ final String id = "_AQ";
+ final String tag = "und-AQ";
+ final String region = "AQ";
+
+ ULocale locale_new = new ULocale(id);
+ ULocale locale_legacy = new ULocale(tag);
+ ULocale locale_tag = ULocale.forLanguageTag(tag);
+ ULocale locale_build = new Builder().setRegion(region).build();
+
+ Assert.assertEquals(id, locale_new.getName());
+ Assert.assertEquals(id, locale_legacy.getName());
+ Assert.assertEquals(id, locale_tag.getName());
+ Assert.assertEquals(id, locale_build.getName());
+
+ Assert.assertEquals(tag, locale_new.toLanguageTag());
+ Assert.assertEquals(tag, locale_legacy.toLanguageTag());
+ Assert.assertEquals(tag, locale_tag.toLanguageTag());
+ Assert.assertEquals(tag, locale_build.toLanguageTag());
+
+ Assert.assertEquals(locale_new, locale_legacy);
+ Assert.assertEquals(locale_new, locale_tag);
+ Assert.assertEquals(locale_new, locale_build);
+ Assert.assertEquals(locale_tag, locale_build);
+
+ final ULocale displayLocale = ULocale.ENGLISH;
+ final String displayName = "Unknown language (Antarctica)";
+
+ Assert.assertEquals(displayName, locale_new.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_legacy.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_tag.getDisplayName(displayLocale));
+ Assert.assertEquals(displayName, locale_build.getDisplayName(displayLocale));
+ }
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleDistanceTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleDistanceTest.java
index 2ea96a7fb..c5d57ca05 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleDistanceTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleDistanceTest.java
@@ -4,9 +4,8 @@ package com.ibm.icu.dev.test.util;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import org.junit.Ignore;
@@ -15,17 +14,15 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.impl.locale.XLikelySubtags.LSR;
-import com.ibm.icu.impl.locale.XLocaleDistance;
-import com.ibm.icu.impl.locale.XLocaleDistance.DistanceNode;
-import com.ibm.icu.impl.locale.XLocaleDistance.DistanceOption;
-import com.ibm.icu.impl.locale.XLocaleDistance.DistanceTable;
+import com.ibm.icu.impl.locale.LocaleDistance;
+import com.ibm.icu.impl.locale.LocaleDistance.DistanceOption;
import com.ibm.icu.util.LocaleMatcher;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.ULocale;
/**
- * Test the XLocaleDistance.
+ * Test the LocaleDistance.
+ * TODO: Rename to LocaleDistanceTest.
*
* @author markdavis
*/
@@ -33,9 +30,7 @@ import com.ibm.icu.util.ULocale;
public class XLocaleDistanceTest extends TestFmwk {
private static final boolean REFORMAT = false; // set to true to get a reformatted data file listed
- public static final int FAIL = XLocaleDistance.ABOVE_THRESHOLD;
-
- private XLocaleDistance localeMatcher = XLocaleDistance.getDefault();
+ private LocaleDistance localeDistance = LocaleDistance.INSTANCE;
DataDrivenTestHelper tfh = new MyTestFileHandler()
.setFramework(this)
.load(XLocaleDistanceTest.class, "data/localeDistanceTest.txt");
@@ -58,7 +53,7 @@ public class XLocaleDistanceTest extends TestFmwk {
@Ignore("Disabled because of Linux; need to investigate.")
@Test
public void testTiming() {
- List<Arguments> testArgs = new ArrayList<Arguments>();
+ List<Arguments> testArgs = new ArrayList<>();
for (List<String> line : tfh.getLines()) {
if (tfh.isTestLine(line)) {
testArgs.add(new Arguments(line));
@@ -94,13 +89,13 @@ public class XLocaleDistanceTest extends TestFmwk {
oldTimeMinusLikely += System.nanoTime()-temp;
temp = System.nanoTime();
- final LSR desiredLSR = LSR.fromMaximalized(desired);
- final LSR supportedLSR = LSR.fromMaximalized(supported);
+// final LSR desiredLSR = LSR.maximizedFrom(desired);
+// final LSR supportedLSR = LSR.maximizedFrom(supported);
newLikelyTime += System.nanoTime()-temp;
temp = System.nanoTime();
- int dist1 = localeMatcher.distanceRaw(desiredLSR, supportedLSR, 1000, DistanceOption.REGION_FIRST);
- int dist2 = localeMatcher.distanceRaw(supportedLSR, desiredLSR, 1000, DistanceOption.REGION_FIRST);
+ int dist1 = localeDistance.testOnlyDistance(desired, supported, 1000, DistanceOption.REGION_FIRST);
+ int dist2 = localeDistance.testOnlyDistance(supported, desired, 1000, DistanceOption.REGION_FIRST);
newTimeMinusLikely += System.nanoTime()-temp;
}
}
@@ -118,52 +113,53 @@ public class XLocaleDistanceTest extends TestFmwk {
}
@Test
- @SuppressWarnings("deprecation")
public void testInternalTable() {
- checkTables(localeMatcher.internalGetDistanceTable(), "", 1);
- }
-
- @SuppressWarnings("deprecation")
- private void checkTables(DistanceTable internalGetDistanceTable, String title, int depth) {
- // Check that ANY, ANY is always present, and that the table has a depth of exactly 3 everyplace.
- Map<String, Set<String>> matches = internalGetDistanceTable.getInternalMatches();
-
- // must have ANY,ANY
- boolean haveANYANY = false;
- for (Entry<String, Set<String>> entry : matches.entrySet()) {
- String first = entry.getKey();
- boolean haveANYfirst = first.equals(XLocaleDistance.ANY);
- for (String second : entry.getValue()) {
- haveANYANY |= haveANYfirst && second.equals(XLocaleDistance.ANY);
- DistanceNode distanceNode = internalGetDistanceTable.getInternalNode(first, second);
- DistanceTable subDistanceTable = distanceNode.getDistanceTable();
- if (subDistanceTable == null || subDistanceTable.isEmpty()) {
- if (depth != 3) {
- logln("depth should be 3");
- }
- if (distanceNode.getClass() != DistanceNode.class) {
- logln("should be plain DistanceNode");
- }
- } else {
- if (depth >= 3) {
- logln("depth should be ≤ 3");
- }
- if (distanceNode.getClass() == DistanceNode.class) {
- logln("should NOT be plain DistanceNode");
- }
- checkTables(subDistanceTable, first + "," + second + ",", depth+1);
+ Set<String> strings = localeDistance.testOnlyGetDistanceTable(false).keySet();
+ // Check that the table has a depth of exactly 3 (desired, supported) pairs everyplace
+ // by removing every prefix of a 6-subtag string from a copy of the set of strings.
+ // Any remaining string is not a prefix of a full-depth string.
+ Set<String> remaining = new HashSet<>(strings);
+ // Check that ANY, ANY is always present.
+ assertTrue("*-*", strings.contains("*-*"));
+ for (String s : strings) {
+ int num = countSubtags(s);
+ assertTrue(s, 1 <= num && num <= 6);
+ if (num > 1) {
+ String oneShorter = removeLastSubtag(s);
+ assertTrue(oneShorter, strings.contains(oneShorter));
+ }
+ if (num == 2 || num == 4) {
+ String sPlusAnyAny = s + "-*-*";
+ assertTrue(sPlusAnyAny, strings.contains(sPlusAnyAny));
+ } else if (num == 6) {
+ for (;; --num) {
+ remaining.remove(s);
+ if (num == 1) { break; }
+ s = removeLastSubtag(s);
}
}
}
- if (!haveANYANY) {
- logln("ANY-ANY not in" + matches);
+ assertTrue("strings that do not lead to 6-subtag matches", remaining.isEmpty());
+ }
+
+ private static final int countSubtags(String s) {
+ if (s.isEmpty()) { return 0; }
+ int num = 1;
+ for (int pos = 0; (pos = s.indexOf('-', pos)) >= 0; ++pos) {
+ ++num;
}
+ return num;
+ }
+
+ private static final String removeLastSubtag(String s) {
+ int last = s.lastIndexOf('-');
+ return s.substring(0, last);
}
@Test
public void testShowDistanceTable() {
if (isVerbose()) {
- System.out.println(XLocaleDistance.getDefault().toString(false));
+ localeDistance.testOnlyPrintDistanceTable();
}
}
@@ -176,10 +172,9 @@ public class XLocaleDistanceTest extends TestFmwk {
}
class MyTestFileHandler extends DataDrivenTestHelper {
- final XLocaleDistance distance = XLocaleDistance.getDefault();
- Output<ULocale> bestDesired = new Output<ULocale>();
+ Output<ULocale> bestDesired = new Output<>();
private DistanceOption distanceOption = DistanceOption.REGION_FIRST;
- private Integer threshold = distance.getDefaultScriptDistance();
+ private Integer threshold = localeDistance.getDefaultScriptDistance();
@Override
public void handle(int lineNumber, boolean breakpoint, String commentBase, List<String> arguments) {
@@ -187,8 +182,8 @@ public class XLocaleDistanceTest extends TestFmwk {
breakpoint = false; // put debugger breakpoint here to break at @debug in test file
}
Arguments args = new Arguments(arguments);
- int supportedToDesiredActual = distance.distance(args.supported, args.desired, threshold, distanceOption);
- int desiredToSupportedActual = distance.distance(args.desired, args.supported, threshold, distanceOption);
+ int supportedToDesiredActual = localeDistance.testOnlyDistance(args.supported, args.desired, threshold, distanceOption);
+ int desiredToSupportedActual = localeDistance.testOnlyDistance(args.desired, args.supported, threshold, distanceOption);
String desiredTag = args.desired.toLanguageTag();
String supportedTag = args.supported.toLanguageTag();
final String comment = commentBase.isEmpty() ? "" : "\t# " + commentBase;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java
index d5e83fb68..7a4df3b30 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java
@@ -2,43 +2,41 @@
// License & terms of use: http://www.unicode.org/copyright.html#License
package com.ibm.icu.dev.test.util;
-
-import java.io.IOException;
+import java.io.BufferedReader;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
-import java.util.regex.Pattern;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
import com.ibm.icu.dev.test.TestFmwk;
-import com.ibm.icu.impl.locale.XCldrStub.Joiner;
-import com.ibm.icu.impl.locale.XCldrStub.Splitter;
-import com.ibm.icu.impl.locale.XLocaleDistance;
-import com.ibm.icu.impl.locale.XLocaleDistance.DistanceOption;
+import com.ibm.icu.impl.locale.LocaleDistance;
+import com.ibm.icu.impl.locale.LocaleDistance.DistanceOption;
+import com.ibm.icu.impl.locale.XCldrStub.FileUtilities;
import com.ibm.icu.impl.locale.XLocaleMatcher;
-import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.LocaleMatcher;
import com.ibm.icu.util.LocalePriorityList;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.ULocale;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
/**
* Test the XLocaleMatcher.
*
* @author markdavis
*/
-@RunWith(JUnit4.class)
+@RunWith(JUnitParamsRunner.class)
public class XLocaleMatcherTest extends TestFmwk {
- private static final boolean REFORMAT = false; // set to true to get a reformatted data file listed
-
private static final int REGION_DISTANCE = 4;
- private static final XLocaleDistance LANGUAGE_MATCHER_DATA = XLocaleDistance.getDefault();
+ private static final LocaleDistance LANGUAGE_MATCHER_DATA = LocaleDistance.INSTANCE;
private XLocaleMatcher newXLocaleMatcher() {
return new XLocaleMatcher("");
@@ -57,15 +55,6 @@ public class XLocaleMatcherTest extends TestFmwk {
return XLocaleMatcher.builder().setSupportedLocales(string).setThresholdDistance(d).build();
}
- private XLocaleMatcher newXLocaleMatcher(LocalePriorityList string, int d, DistanceOption distanceOption) {
- return XLocaleMatcher
- .builder()
- .setSupportedLocales(string)
- .setThresholdDistance(d)
- .setDistanceOption(distanceOption)
- .build();
- }
-
// public void testParentLocales() {
// // find all the regions that have a closer relation because of an explicit parent
// Set<String> explicitParents = new HashSet<>(INFO.getExplicitParents());
@@ -126,7 +115,7 @@ public class XLocaleMatcherTest extends TestFmwk {
@Test
public void testExactMatches() {
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)) {
@@ -186,17 +175,102 @@ public class XLocaleMatcherTest extends TestFmwk {
}
}
- @Ignore("b/118891283")
+ private static final class PerfCase {
+ ULocale desired;
+ ULocale expectedShort;
+ ULocale expectedLong;
+ ULocale expectedVeryLong;
+
+ PerfCase(String des, String expShort, String expLong, String expVeryLong) {
+ desired = new ULocale(des);
+ expectedShort = new ULocale(expShort);
+ expectedLong = new ULocale(expLong);
+ expectedVeryLong = new ULocale(expVeryLong);
+ }
+ }
+
+ private static final int WARM_UP_ITERATIONS = 1000;
+ private static final int BENCHMARK_ITERATIONS = 20000;
+ private static final int AVG_PCT_MEDIUM_NEW_OLD = 33;
+ private static final int AVG_PCT_LONG_NEW_OLD = 80;
+
@Test
public void testPerf() {
if (LANGUAGE_MATCHER_DATA == null) {
return; // skip except when testing data
}
- final ULocale desired = new ULocale("sv");
final String shortList = "en, sv";
- final String longList = "af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-TW, zu";
- final String veryLongList = "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, as, as_IN, asa, asa_TZ, ast, ast_ES, 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, ca, ca_AD, ca_ES, ca_ES_VALENCIA, ca_FR, ca_IT, ce, ce_RU, cgg, cgg_UG, chr, chr_US, ckb, ckb_IQ, ckb_IR, cs, cs_CZ, cu, cu_RU, cy, cy_GB, da, da_DK, da_GL, dav, dav_KE, de, de_AT, de_BE, de_CH, de_DE, 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_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, eo_001, es, es_419, es_AR, es_BO, 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, id, id_ID, ig, ig_NG, ii, ii_CN, is, is_IS, it, it_CH, it_IT, it_SM, ja, ja_JP, jgo, jgo_CM, jmc, jmc_TZ, 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, 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, mk, mk_MK, ml, ml_IN, mn, mn_MN, 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, 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, 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, pl, pl_PL, prg, prg_001, ps, ps_AF, pt, pt_AO, pt_BR, pt_CV, pt_GW, 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, se, se_FI, se_NO, se_SE, seh, seh_MZ, ses, ses_ML, sg, sg_CF, shi, shi_Latn, shi_Latn_MA, shi_Tfng, shi_Tfng_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_XK, sr_Latn, sr_Latn_BA, sr_Latn_ME, sr_Latn_RS, sr_Latn_XK, 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, th, th_TH, ti, ti_ER, ti_ET, tk, tk_TM, to, to_TO, tr, tr_CY, tr_TR, twq, twq_NE, tzm, tzm_MA, ug, ug_CN, uk, uk_UA, ur, ur_IN, ur_PK, uz, uz_Arab, uz_Arab_AF, uz_Cyrl, uz_Cyrl_UZ, uz_Latn, uz_Latn_UZ, vai, vai_Latn, vai_Latn_LR, vai_Vaii, vai_Vaii_LR, vi, vi_VN, vo, vo_001, vun, vun_TZ, wae, wae_CH, xog, xog_UG, yav, yav_CM, yi, yi_001, yo, yo_BJ, yo_NG, 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, zu, zu_ZA";
+ final String longList = "af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, " +
+ "el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, " +
+ "hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, " +
+ "mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, " +
+ "si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, " +
+ "zh-CN, zh-TW, zu";
+ final String veryLongList = "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, as, as_IN, asa, asa_TZ, " +
+ "ast, ast_ES, 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, ca, ca_AD, ca_ES, ca_ES_VALENCIA, " +
+ "ca_FR, ca_IT, ce, ce_RU, cgg, cgg_UG, chr, chr_US, ckb, ckb_IQ, ckb_IR, cs, cs_CZ, " +
+ "cu, cu_RU, cy, cy_GB, da, da_DK, da_GL, dav, dav_KE, de, de_AT, de_BE, de_CH, " +
+ "de_DE, de_LI, de_LU, dje, dje_NE, dsb, dsb_DE, dua, dua_CM, dyo, dyo_SN, dz, dz_BT, " +
+ // removed en_001 to avoid exact match
+ "ebu, ebu_KE, ee, ee_GH, ee_TG, el, el_CY, el_GR, en, 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_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, eo_001, es, es_419, es_AR, es_BO, 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, " +
+ "id, id_ID, ig, ig_NG, ii, ii_CN, is, is_IS, it, it_CH, it_IT, it_SM, ja, ja_JP, " +
+ "jgo, jgo_CM, jmc, jmc_TZ, 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, 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, mk, mk_MK, ml, ml_IN, mn, mn_MN, 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, 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, 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, pl, pl_PL, prg, prg_001, ps, ps_AF, pt, pt_AO, pt_BR, " +
+ "pt_CV, pt_GW, 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, se, se_FI, se_NO, se_SE, seh, seh_MZ, ses, ses_ML, sg, sg_CF, shi, " +
+ "shi_Latn, shi_Latn_MA, shi_Tfng, shi_Tfng_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_XK, sr_Latn, " +
+ "sr_Latn_BA, sr_Latn_ME, sr_Latn_RS, sr_Latn_XK, 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, th, th_TH, ti, ti_ER, ti_ET, tk, tk_TM, to, to_TO, tr, tr_CY, " +
+ "tr_TR, twq, twq_NE, tzm, tzm_MA, ug, ug_CN, uk, uk_UA, ur, ur_IN, ur_PK, uz, " +
+ "uz_Arab, uz_Arab_AF, uz_Cyrl, uz_Cyrl_UZ, uz_Latn, uz_Latn_UZ, vai, vai_Latn, " +
+ "vai_Latn_LR, vai_Vaii, vai_Vaii_LR, vi, vi_VN, vo, vo_001, vun, vun_TZ, wae, " +
+ "wae_CH, xog, xog_UG, yav, yav_CM, yi, yi_001, yo, yo_BJ, yo_NG, 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, zu, zu_ZA";
final XLocaleMatcher matcherShort = newXLocaleMatcher(shortList);
final XLocaleMatcher matcherLong = newXLocaleMatcher(longList);
@@ -206,134 +280,304 @@ public class XLocaleMatcherTest extends TestFmwk {
final LocaleMatcher matcherLongOld = new LocaleMatcher(longList);
final LocaleMatcher matcherVeryLongOld = new LocaleMatcher(veryLongList);
- //XLocaleMatcher.DEBUG = true;
- ULocale expected = new ULocale("sv");
- assertEquals(expected, matcherShort.getBestMatch(desired));
- assertEquals(expected, matcherLong.getBestMatch(desired));
- assertEquals(expected, matcherVeryLong.getBestMatch(desired));
- //XLocaleMatcher.DEBUG = false;
-
long timeShortNew=0;
long timeMediumNew=0;
long timeLongNew=0;
- for (int i = 0; i < 2; ++i) {
- int iterations = i == 0 ? 1000 : 1000000;
- boolean showMessage = i != 0;
- timeShortNew = timeXLocaleMatcher("Duration (few supported):\t", desired, matcherShort, showMessage, iterations);
- timeMediumNew = timeXLocaleMatcher("Duration (med. supported):\t", desired, matcherLong, showMessage, iterations);
- timeLongNew = timeXLocaleMatcher("Duration (many supported):\t", desired, matcherVeryLong, showMessage, iterations);
- }
-
long timeShortOld=0;
long timeMediumOld=0;
long timeLongOld=0;
- for (int i = 0; i < 2; ++i) {
- int iterations = i == 0 ? 1000 : 100000;
- boolean showMessage = i != 0;
- timeShortOld = timeLocaleMatcher("Old Duration (few supported):\t", desired, matcherShortOld, showMessage, iterations);
- timeMediumOld = timeLocaleMatcher("Old Duration (med. supported):\t", desired, matcherLongOld, showMessage, iterations);
- timeLongOld = timeLocaleMatcher("Old Duration (many supported):\t", desired, matcherVeryLongOld, showMessage, iterations);
+ PerfCase[] pcs = new PerfCase[] {
+ // Exact match in all matchers.
+ new PerfCase("sv", "sv", "sv", "sv"),
+ // Common locale, exact match only in very long list.
+ new PerfCase("fr_CA", "en", "fr", "fr_CA"),
+ // Unusual locale, no exact match.
+ new PerfCase("de_CA", "en", "de", "de"),
+ // World English maps to several region partitions.
+ new PerfCase("en_001", "en", "en", "en"),
+ // Ancient language with interesting subtags.
+ new PerfCase("egy_Copt_CY", "en", "af", "af")
+ };
+
+ for (PerfCase pc : pcs) {
+ final ULocale desired = pc.desired;
+
+ assertEquals(pc.expectedShort, matcherShort.getBestMatch(desired));
+ assertEquals(pc.expectedLong, matcherLong.getBestMatch(desired));
+ assertEquals(pc.expectedVeryLong, matcherVeryLong.getBestMatch(desired));
+
+ timeXLocaleMatcher(desired, matcherShort, WARM_UP_ITERATIONS);
+ timeXLocaleMatcher(desired, matcherLong, WARM_UP_ITERATIONS);
+ timeXLocaleMatcher(desired, matcherVeryLong, WARM_UP_ITERATIONS);
+ long tns = timeXLocaleMatcher(desired, matcherShort, BENCHMARK_ITERATIONS);
+ System.out.format("New Duration (few supported):\t%s\t%d\tnanos\n", desired, tns);
+ timeShortNew += tns;
+ long tnl = timeXLocaleMatcher(desired, matcherLong, BENCHMARK_ITERATIONS);
+ System.out.format("New Duration (med. supported):\t%s\t%d\tnanos\n", desired, tnl);
+ timeMediumNew += tnl;
+ long tnv = timeXLocaleMatcher(desired, matcherVeryLong, BENCHMARK_ITERATIONS);
+ System.out.format("New Duration (many supported):\t%s\t%d\tnanos\n", desired, tnv);
+ timeLongNew += tnv;
+
+ timeLocaleMatcher(desired, matcherShortOld, WARM_UP_ITERATIONS);
+ timeLocaleMatcher(desired, matcherLongOld, WARM_UP_ITERATIONS);
+ timeLocaleMatcher(desired, matcherVeryLongOld, WARM_UP_ITERATIONS);
+ long tos = timeLocaleMatcher(desired, matcherShortOld, BENCHMARK_ITERATIONS);
+ System.out.format("Old Duration (few supported):\t%s\t%d\tnanos new/old=%d%%\n",
+ desired, tos, (100 * tns) / tos);
+ timeShortOld += tos;
+ long tol = timeLocaleMatcher(desired, matcherLongOld, BENCHMARK_ITERATIONS);
+ System.out.format("Old Duration (med. supported):\t%s\t%d\tnanos new/old=%d%%\n",
+ desired, tol, (100 * tnl) / tol);
+ timeMediumOld += tol;
+ long tov = timeLocaleMatcher(desired, matcherVeryLongOld, BENCHMARK_ITERATIONS);
+ System.out.format("Old Duration (many supported):\t%s\t%d\tnanos new/old=%d%%\n",
+ desired, tov, (100 * tnv) / tov);
+ timeLongOld += tov;
}
- assertTrue("timeShortNew (=" + timeShortNew + ") < 25% of timeShortOld (=" + timeShortOld + ")", timeShortNew * 4 < timeShortOld);
- assertTrue("timeMediumNew (=" + timeMediumNew + ") < 25% of timeMediumOld (=" + timeMediumOld + ")", timeMediumNew * 4 < timeMediumOld);
- assertTrue("timeLongNew (=" + timeLongNew + ") < 25% of timeLongOld (=" + timeLongOld + ")", timeLongNew * 4 < timeLongOld);
-
+ assertTrue(
+ String.format("timeShortNew=%d < %d%% of timeShortOld=%d",
+ timeShortNew, AVG_PCT_MEDIUM_NEW_OLD, timeShortOld),
+ timeShortNew * 100 < timeShortOld * AVG_PCT_MEDIUM_NEW_OLD);
+ assertTrue(
+ String.format("timeMediumNew=%d < %d%% of timeMediumOld=%d",
+ timeMediumNew, AVG_PCT_MEDIUM_NEW_OLD, timeMediumOld),
+ timeMediumNew * 100 < timeMediumOld * AVG_PCT_MEDIUM_NEW_OLD);
+ assertTrue(
+ String.format("timeLongNew=%d < %d%% of timeLongOld=%d",
+ timeLongNew, AVG_PCT_LONG_NEW_OLD, timeLongOld),
+ timeLongNew * 100 < timeLongOld * AVG_PCT_LONG_NEW_OLD);
}
- private long timeXLocaleMatcher(String title, ULocale desired, XLocaleMatcher matcher,
- boolean showmessage, int iterations) {
+ private long timeXLocaleMatcher(ULocale desired, XLocaleMatcher matcher, int iterations) {
long start = System.nanoTime();
for (int i = iterations; i > 0; --i) {
matcher.getBestMatch(desired);
}
long delta = System.nanoTime() - start;
- if (showmessage) logln(title + (delta / iterations) + " nanos");
return (delta / iterations);
}
- private long timeLocaleMatcher(String title, ULocale desired, LocaleMatcher matcher,
- boolean showmessage, int iterations) {
+ private long timeLocaleMatcher(ULocale desired, LocaleMatcher matcher, int iterations) {
long start = System.nanoTime();
for (int i = iterations; i > 0; --i) {
matcher.getBestMatch(desired);
}
long delta = System.nanoTime() - start;
- if (showmessage) logln(title + (delta / iterations) + " nanos");
return (delta / iterations);
}
- @Test
- public void testDataDriven() throws IOException {
- DataDrivenTestHelper tfh = new MyTestFileHandler()
- .setFramework(this)
- .run(XLocaleMatcherTest.class, "data/localeMatcherTest.txt");
- if (REFORMAT) {
- System.out.println(tfh.appendLines(new StringBuilder()));
+ private static final class TestCase implements Cloneable {
+ private static final String ENDL = System.getProperties().getProperty("line.separator");
+
+ int lineNr = 0;
+
+ String nameLine = "";
+ String supportedLine = "";
+ String defaultLine = "";
+ String distanceLine = "";
+ String thresholdLine = "";
+ String matchLine = "";
+
+ String supported = "";
+ String def = "";
+ String distance = "";
+ String threshold = "";
+ String desired = "";
+ String expMatch = "";
+ String expDesired = "";
+ String expCombined = "";
+
+ @Override
+ public TestCase clone() throws CloneNotSupportedException {
+ return (TestCase) super.clone();
}
- }
- private static final Splitter COMMA_SPACE = Splitter.on(Pattern.compile(",\\s*|\\s+")).trimResults();
- private static final Joiner JOIN_COMMA_SPACE = Joiner.on(", ");
- @SuppressWarnings("unused")
- private static final UnicodeSet DIGITS = new UnicodeSet("[0-9]").freeze();
+ void reset(String newNameLine) {
+ nameLine = newNameLine;
+ supportedLine = "";
+ defaultLine = "";
+ distanceLine = "";
+ thresholdLine = "";
+
+ supported = "";
+ def = "";
+ distance = "";
+ threshold = "";
+ }
- class MyTestFileHandler extends DataDrivenTestHelper {
+ String toInputsKey() {
+ return supported + '+' + def + '+' + distance + '+' + threshold + '+' + desired;
+ }
- Output<ULocale> bestDesired = new Output<ULocale>();
- DistanceOption distanceOption = DistanceOption.REGION_FIRST;
- int threshold = -1;
+ private static void appendLine(StringBuilder sb, String line) {
+ if (!line.isEmpty()) {
+ sb.append(ENDL).append(line);
+ }
+ }
@Override
- public void handle(int lineNumber, boolean breakpoint, String commentBase, List<String> arguments) {
- List<String> supported = COMMA_SPACE.splitToList(arguments.get(0));
- final String supportedReformatted = JOIN_COMMA_SPACE.join(supported);
- LocalePriorityList supportedList = LocalePriorityList.add(supportedReformatted).build();
+ public String toString() {
+ StringBuilder sb = new StringBuilder(nameLine);
+ appendLine(sb, supportedLine);
+ appendLine(sb, defaultLine);
+ appendLine(sb, distanceLine);
+ appendLine(sb, thresholdLine);
+ sb.append(ENDL).append("line ").append(lineNr).append(':');
+ appendLine(sb, matchLine);
+ return sb.toString();
+ }
+ }
- Iterable<String> desired = COMMA_SPACE.split(arguments.get(1));
- final String desiredReformatted = JOIN_COMMA_SPACE.join(desired);
- LocalePriorityList desiredList = LocalePriorityList.add(desiredReformatted).build();
+ private static String getSuffixAfterPrefix(String s, int limit, String prefix) {
+ if (prefix.length() <= limit && s.startsWith(prefix)) {
+ return s.substring(prefix.length(), limit);
+ } else {
+ return null;
+ }
+ }
- String expected = arguments.get(2);
- String expectedLanguageTag = expected.equals("null") ? null : new ULocale(expected).toLanguageTag();
+ // UsedReflectively, not private to avoid unused-warning
+ static List<TestCase> readTestCases() throws Exception {
+ List<TestCase> tests = new ArrayList<>();
+ Map<String, Integer> uniqueTests = new HashMap<>();
+ TestCase test = new TestCase();
+ String filename = "data/localeMatcherTest.txt";
+ try (BufferedReader in = FileUtilities.openFile(XLocaleMatcherTest.class, filename)) {
+ String line;
+ while ((line = in.readLine()) != null) {
+ ++test.lineNr;
+ // Start of comment, or end of line, minus trailing spaces.
+ int limit = line.indexOf('#');
+ if (limit < 0) {
+ limit = line.length();
+ }
+ char c;
+ while (limit > 0 && ((c = line.charAt(limit - 1)) == ' ' || c == '\t')) {
+ --limit;
+ }
+ if (limit == 0) { // empty line
+ continue;
+ }
+ String suffix;
+ if (line.startsWith("** test: ")) {
+ test.reset(line);
+ } else if ((suffix = getSuffixAfterPrefix(line, limit, "@supported=")) != null) {
+ test.supportedLine = line;
+ test.supported = suffix;
+ } else if ((suffix = getSuffixAfterPrefix(line, limit, "@default=")) != null) {
+ test.defaultLine = line;
+ test.def = suffix;
+ } else if ((suffix = getSuffixAfterPrefix(line, limit, "@distance=")) != null) {
+ test.distanceLine = line;
+ test.distance = suffix;
+ } else if ((suffix = getSuffixAfterPrefix(line, limit, "@threshold=")) != null) {
+ test.thresholdLine = line;
+ test.threshold = suffix;
+ } else {
+ int matchSep = line.indexOf(">>");
+ // >> before an inline comment, and followed by more than white space.
+ if (0 <= matchSep && (matchSep + 2) < limit) {
+ test.matchLine = line;
+ test.desired = line.substring(0, matchSep).trim();
+ test.expDesired = test.expCombined = "";
+ int start = matchSep + 2;
+ int expLimit = line.indexOf('|', start);
+ if (expLimit < 0) {
+ test.expMatch = line.substring(start, limit).trim();
+ } else {
+ test.expMatch = line.substring(start, expLimit).trim();
+ start = expLimit + 1;
+ expLimit = line.indexOf('|', start);
+ if (expLimit < 0) {
+ test.expDesired = line.substring(start, limit).trim();
+ } else {
+ test.expDesired = line.substring(start, expLimit).trim();
+ test.expCombined = line.substring(expLimit + 1, limit).trim();
+ }
+ }
+ String inputs = test.toInputsKey();
+ Integer prevIndex = uniqueTests.get(inputs);
+ if (prevIndex == null) {
+ uniqueTests.put(inputs, tests.size());
+ } else {
+ System.out.println("Locale matcher test case on line " + test.lineNr
+ + " is a duplicate of line " + tests.get(prevIndex).lineNr);
+ }
+ tests.add(test.clone());
+ } else {
+ throw new IllegalArgumentException("test data syntax error on line "
+ + test.lineNr + "\n" + line);
+ }
+ }
+ }
+ }
+ System.out.println("Number of duplicate locale matcher test cases: " + (tests.size() - uniqueTests.size()));
+ return tests;
+ }
- String expectedUi = arguments.size() < 4 ? null : arguments.get(3);
- String expectedUiLanguageTag = expectedUi == null || expectedUi.equals("null") ? null
- : new ULocale(expectedUi).toLanguageTag();
+ private static ULocale getULocaleOrNull(String s) {
+ if (s.equals("null")) {
+ return null;
+ } else {
+ return new ULocale(s);
+ }
+ }
- if (breakpoint) {
- breakpoint = false; // put debugger breakpoint here to break at @debug in test file
+ @Test
+ @Parameters(method = "readTestCases")
+ public void dataDriven(TestCase test) {
+ XLocaleMatcher matcher;
+ if (test.def.isEmpty() && test.distance.isEmpty() && test.threshold.isEmpty()) {
+ matcher = new XLocaleMatcher(test.supported);
+ } else {
+ XLocaleMatcher.Builder builder = XLocaleMatcher.builder();
+ builder.setSupportedLocales(test.supported);
+ if (!test.def.isEmpty()) {
+ builder.setDefaultLanguage(new ULocale(test.def));
}
- XLocaleMatcher matcher = threshold < 0 && distanceOption == DistanceOption.REGION_FIRST
- ? newXLocaleMatcher(supportedList)
- : newXLocaleMatcher(supportedList, threshold, distanceOption);
- commentBase = "(" + lineNumber + ") " + commentBase;
-
- ULocale bestSupported;
- if (expectedUi != null) {
- bestSupported = matcher.getBestMatch(desiredList, bestDesired);
- ULocale bestUI = XLocaleMatcher.combine(bestSupported, bestDesired.value);
- assertEquals(commentBase + " (UI)", expectedUiLanguageTag, bestUI == null ? null : bestUI.toLanguageTag());
- } else {
- bestSupported = matcher.getBestMatch(desiredList);
+ if (!test.distance.isEmpty()) {
+ DistanceOption distance;
+ switch (test.distance) {
+ case "normal":
+ distance = DistanceOption.REGION_FIRST;
+ break;
+ case "script":
+ distance = DistanceOption.SCRIPT_FIRST;
+ break;
+ default:
+ throw new IllegalArgumentException("unsupported distance value " + test.distance);
+ }
+ builder.setDistanceOption(distance);
}
- String bestMatchLanguageTag = bestSupported == null ? null : bestSupported.toLanguageTag();
- assertEquals(commentBase, expectedLanguageTag, bestMatchLanguageTag);
+ if (!test.threshold.isEmpty()) {
+ int threshold = Integer.valueOf(test.threshold);
+ builder.setThresholdDistance(threshold);
+ }
+ matcher = builder.build();
}
- @Override
- public void handleParams(String comment, List<String> arguments) {
- String switchItem = arguments.get(0);
- if (switchItem.equals("@DistanceOption")) {
- distanceOption = DistanceOption.valueOf(arguments.get(1));
- } else if (switchItem.equals("@Threshold")) {
- threshold = Integer.valueOf(arguments.get(1));
- } else {
- super.handleParams(comment, arguments);
+ ULocale expMatch = getULocaleOrNull(test.expMatch);
+ if (test.expDesired.isEmpty() && test.expCombined.isEmpty()) {
+ ULocale bestSupported = matcher.getBestMatch(test.desired);
+ assertEquals("bestSupported", expMatch, bestSupported);
+ } else {
+ LocalePriorityList desired = LocalePriorityList.add(test.desired).build();
+ Output<ULocale> bestDesired = new Output<>();
+ ULocale bestSupported = matcher.getBestMatch(desired, bestDesired);
+ assertEquals("bestSupported", expMatch, bestSupported);
+ if (!test.expDesired.isEmpty()) {
+ ULocale expDesired = getULocaleOrNull(test.expDesired);
+ assertEquals("bestDesired", expDesired, bestDesired.value);
+ }
+ if (!test.expCombined.isEmpty()) {
+ ULocale expCombined = getULocaleOrNull(test.expCombined);
+ ULocale combined = XLocaleMatcher.combine(bestSupported, bestDesired.value);
+ assertEquals("combined", expCombined, combined);
}
- return;
}
}
}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
index 55c0f3f5a..bd653a7a5 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
@@ -1,194 +1,340 @@
# © 2017 and later: Unicode, Inc. and others.
# License & terms of use: http://www.unicode.org/copyright.html#License
#
-# Data-driven test for the XLocaleMatcher.
-# Format
-# • Everything after "#" is a comment
-# • Arguments are separated by ";". They are:
-
-# supported ; desired ; expected
+# Data-driven test for the language/locale matcher.
+# Format:
+#
+# Everything after "#" is a comment.
+# ** test: This line starts a group of test cases.
+#
+# Lines starting with an '@' sign provide matcher parameters.
+# @supported=<comma-separated supported languages>
+# @default=<default language> # no value = no explicit default
+# @distance=[normal|script] # no value = no explicit setting
+# @threshold=<number 0..100> # no value = no explicit setting
+#
+# A line with ">>" is a getBestMatch() test case:
+# <comma-separated desired languages> >> match | desired | combined
+# - match is the expected best supported language
+# - desired is the expected best desired language
+# - combined is the expected result of combine(match, desired)
+# An expected language can be "null" to check for the matcher returning null.
+# An empty or omitted value is not tested. (Omitted = not even the '|' separator.)
+#
+# ** test: A new test group resets all matcher parameters.
-# • The supported may have the threshold distance reset as a first item, eg 50, en, fr
-# A line starting with @debug will reach a statement in the test code where you can put a breakpoint for debugging
-# The test code also supports reformatting this file, by setting the REFORMAT flag.
+## X
-##################################################
-# testParentLocales
+** test: testParentLocales
# es-419, es-AR, and es-MX are in a cluster; es is in a different one
-@debug
-es-419, es-ES ; es-AR ; es-419
-es-ES, es-419 ; es-AR ; es-419
+@supported=es-419, es-ES
+es-AR >> es-419
+@supported=es-ES, es-419
+es-AR >> es-419
-es-419, es ; es-AR ; es-419
-es, es-419 ; es-AR ; es-419
+@supported=es-419, es
+es-AR >> es-419
+@supported=es, es-419
+es-AR >> es-419
-es-MX, es ; es-AR ; es-MX
-es, es-MX ; es-AR ; es-MX
+@supported=es-MX, es
+es-AR >> es-MX
+@supported=es, es-MX
+es-AR >> es-MX
# en-GB, en-AU, and en-NZ are in a cluster; en in a different one
-en-GB, en-US ; en-AU ; en-GB
-en-US, en-GB ; en-AU ; en-GB
+@supported=en-GB, en-US
+en-AU >> en-GB
+@supported=en-US, en-GB
+en-AU >> en-GB
-en-GB, en ; en-AU ; en-GB
-en, en-GB ; en-AU ; en-GB
+@supported=en-GB, en
+en-AU >> en-GB
+@supported=en, en-GB
+en-AU >> en-GB
-en-NZ, en-US ; en-AU ; en-NZ
-en-US, en-NZ ; en-AU ; en-NZ
+@supported=en-NZ, en-US
+en-AU >> en-NZ
+@supported=en-US, en-NZ
+en-AU >> en-NZ
-en-NZ, en ; en-AU ; en-NZ
-en, en-NZ ; en-AU ; en-NZ
+@supported=en-NZ, en
+en-AU >> en-NZ
+@supported=en, en-NZ
+en-AU >> en-NZ
# pt-AU and pt-PT in one cluster; pt-BR in another
-pt-PT, pt-BR ; pt-AO ; pt-PT
-pt-BR, pt-PT ; pt-AO ; pt-PT
-
-pt-PT, pt ; pt-AO ; pt-PT
-pt, pt-PT ; pt-AO ; pt-PT
-
-zh-MO, zh-TW ; zh-HK ; zh-MO
-zh-TW, zh-MO ; zh-HK ; zh-MO
-
-zh-MO, zh-TW ; zh-HK ; zh-MO
-zh-TW, zh-MO ; zh-HK ; zh-MO
-
-zh-MO, zh-CN ; zh-HK ; zh-MO
-zh-CN, zh-MO ; zh-HK ; zh-MO
-
-zh-MO, zh ; zh-HK ; zh-MO
-zh, zh-MO ; zh-HK ; zh-MO
-
-##################################################
-# testChinese
-
-zh-CN, zh-TW, iw ; zh-Hant-TW ; zh-TW
-zh-CN, zh-TW, iw ; zh-Hant ; zh-TW
-zh-CN, zh-TW, iw ; zh-TW ; zh-TW
-zh-CN, zh-TW, iw ; zh-Hans-CN ; zh-CN
-zh-CN, zh-TW, iw ; zh-CN ; zh-CN
-zh-CN, zh-TW, iw ; zh ; zh-CN
-
-##################################################
-# testenGB
-
-fr, en, en-GB, es-419, es-MX, es ; en-NZ ; en-GB
-fr, en, en-GB, es-419, es-MX, es ; es-ES ; es
-fr, en, en-GB, es-419, es-MX, es ; es-AR ; es-419
-fr, en, en-GB, es-419, es-MX, es ; es-MX ; es-MX
-
-##################################################
-# testFallbacks
-
-91, en, hi ; sa ; hi
-
-##################################################
-# testBasics
-
-fr, en-GB, en ; en-GB ; en-GB
-fr, en-GB, en ; en ; en
-fr, en-GB, en ; fr ; fr
-fr, en-GB, en ; ja ; fr # return first if no match
-
-##################################################
-# testFallback
+@supported=pt-PT, pt-BR
+pt-AO >> pt-PT
+@supported=pt-BR, pt-PT
+pt-AO >> pt-PT
+
+@supported=pt-PT, pt
+pt-AO >> pt-PT
+@supported=pt, pt-PT
+pt-AO >> pt-PT
+
+@supported=zh-MO, zh-TW
+zh-HK >> zh-MO
+@supported=zh-TW, zh-MO
+zh-HK >> zh-MO
+
+@supported=zh-MO, zh-CN
+zh-HK >> zh-MO
+@supported=zh-CN, zh-MO
+zh-HK >> zh-MO
+
+@supported=zh-MO, zh
+zh-HK >> zh-MO
+@supported=zh, zh-MO
+zh-HK >> zh-MO
+
+@distance=script
+@supported=es-419, es-ES
+es-AR >> es-419
+@supported=es-ES, es-419
+es-AR >> es-419
+@supported=es-419, es
+es-AR >> es-419
+@supported=es, es-419
+es-AR >> es-419
+@supported=es-MX, es
+es-AR >> es-MX
+@supported=es, es-MX
+es-AR >> es-MX
+@supported=en-GB, en-US
+en-AU >> en-GB
+@supported=en-US, en-GB
+en-AU >> en-GB
+@supported=en-GB, en
+en-AU >> en-GB
+@supported=en, en-GB
+en-AU >> en-GB
+@supported=en-NZ, en-US
+en-AU >> en-NZ
+@supported=en-US, en-NZ
+en-AU >> en-NZ
+@supported=en-NZ, en
+en-AU >> en-NZ
+@supported=en, en-NZ
+en-AU >> en-NZ
+@supported=pt-PT, pt-BR
+pt-AO >> pt-PT
+@supported=pt-BR, pt-PT
+pt-AO >> pt-PT
+@supported=pt-PT, pt
+pt-AO >> pt-PT
+@supported=pt, pt-PT
+pt-AO >> pt-PT
+@supported=zh-MO, zh-TW
+zh-HK >> zh-MO
+@supported=zh-TW, zh-MO
+zh-HK >> zh-MO
+@supported=zh-MO, zh-CN
+zh-HK >> zh-MO
+@supported=zh-CN, zh-MO
+zh-HK >> zh-MO
+@supported=zh-MO, zh
+zh-HK >> zh-MO
+@supported=zh, zh-MO
+zh-HK >> zh-MO
+
+** test: testChinese
+
+@supported=zh-CN, zh-TW, iw
+zh-Hant-TW >> zh-TW
+zh-Hant >> zh-TW
+zh-TW >> zh-TW
+zh-Hans-CN >> zh-CN
+zh-CN >> zh-CN
+zh >> zh-CN
+
+@distance=script
+zh-Hant-TW >> zh-TW
+zh-Hant >> zh-TW
+zh-TW >> zh-TW
+zh-Hans-CN >> zh-CN
+zh-CN >> zh-CN
+zh >> zh-CN
+
+** test: testenGB
+
+@supported=fr, en, en-GB, es-419, es-MX, es
+en-NZ >> en-GB
+es-ES >> es
+es-AR >> es-419
+es-MX >> es-MX
+
+@distance=script
+en-NZ >> en-GB
+es-ES >> es
+es-AR >> es-419
+es-MX >> es-MX
+
+** test: testFallbacks
+
+@supported=91, en, hi
+sa >> hi
+
+@distance=script
+sa >> hi
+
+** test: testBasics
+
+@supported=fr, en-GB, en
+en-GB >> en-GB
+en >> en
+fr >> fr
+ja >> fr # return first if no match
+
+@distance=script
+en-GB >> en-GB
+en >> en
+fr >> fr
+ja >> fr
+
+** test: testFallback
# check that script fallbacks are handled right
-zh-CN, zh-TW, iw ; zh-Hant ; zh-TW
-zh-CN, zh-TW, iw ; zh ; zh-CN
-zh-CN, zh-TW, iw ; zh-Hans-CN ; zh-CN
-zh-CN, zh-TW, iw ; zh-Hant-HK ; zh-TW
-zh-CN, zh-TW, iw ; he-IT ; iw
+@supported=zh-CN, zh-TW, iw
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+he-IT >> iw
+
+@distance=script
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+he-IT >> iw
-##################################################
-# testSpecials
+** test: testSpecials
# check that nearby languages are handled
-en, fil, ro, nn ; tl ; fil
-en, fil, ro, nn ; mo ; ro
-en, fil, ro, nn ; nb ; nn
+@supported=en, fil, ro, nn
+tl >> fil
+mo >> ro
+nb >> nn
# make sure default works
-en, fil, ro, nn ; ja ; en
+ja >> en
+
+@distance=script
+tl >> fil
+mo >> ro
+nb >> nn
+ja >> en
-##################################################
-# testRegionalSpecials
+** test: testRegionalSpecials
# verify that en-AU is closer to en-GB than to en (which is en-US)
-en, en-GB, es, es-419 ; es-MX ; es-419
-en, en-GB, es, es-419 ; en-AU ; en-GB
-en, en-GB, es, es-419 ; es-ES ; es
+@supported=en, en-GB, es, es-419
+es-MX >> es-419
+en-AU >> en-GB
+es-ES >> es
-##################################################
-# testHK
+@distance=script
+es-MX >> es-419
+en-AU >> en-GB
+es-ES >> es
+
+** test: testHK
# HK and MO are closer to each other for Hant than to TW
-zh, zh-TW, zh-MO ; zh-HK ; zh-MO
-zh, zh-TW, zh-HK ; zh-MO ; zh-HK
+@supported=zh, zh-TW, zh-MO
+zh-HK >> zh-MO
+@supported=zh, zh-TW, zh-HK
+zh-MO >> zh-HK
+
+@distance=script
+@supported=zh, zh-TW, zh-MO
+zh-HK >> zh-MO
+@supported=zh, zh-TW, zh-HK
+zh-MO >> zh-HK
-##################################################
-# testMatch-exact
+** test: testMatch-matchOnMazimized
-# see localeDistance.txt
+@supported=zh, zh-Hant
+und-TW >> zh-Hant # und-TW should be closer to zh-Hant than to zh
-##################################################
-# testMatch-none
+@supported=en-Hant-TW, und-TW
+zh-Hant >> und-TW # zh-Hant should be closer to und-TW than to en-Hant-TW
+zh >> und-TW # zh should be closer to und-TW than to en-Hant-TW
-# see localeDistance.txt
+@distance=script
+@supported=zh, zh-Hant
+und-TW >> zh-Hant
+@supported=en-Hant-TW, und-TW
+zh-Hant >> und-TW
+zh >> und-TW
-##################################################
-# testMatch-matchOnMazimized
+** test: testMatchGrandfatheredCode
-zh, zh-Hant ; und-TW ; zh-Hant # und-TW should be closer to zh-Hant than to zh
-en-Hant-TW, und-TW ; zh-Hant ; und-TW # zh-Hant should be closer to und-TW than to en-Hant-TW
-en-Hant-TW, und-TW ; zh ; und-TW # zh should be closer to und-TW than to en-Hant-TW
+@supported=fr, i-klingon, en-Latn-US
+en-GB-oed >> en-Latn-US
-##################################################
-# testMatchGrandfatheredCode
+@distance=script
+en-GB-oed >> en-Latn-US
-fr, i-klingon, en-Latn-US ; en-GB-oed ; en-Latn-US
+** test: testGetBestMatchForList-exactMatch
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja, de >> ja
-##################################################
-# testGetBestMatchForList-exactMatch
-fr, en-GB, ja, es-ES, es-MX ; ja, de ; ja
+@distance=script
+ja, de >> ja
-##################################################
-# testGetBestMatchForList-simpleVariantMatch
-fr, en-GB, ja, es-ES, es-MX ; de, en-US ; en-GB # Intentionally avoiding a perfect-match or two candidates for variant matches.
+** test: testGetBestMatchForList-simpleVariantMatch
+@supported=fr, en-GB, ja, es-ES, es-MX
+de, en-US >> en-GB # Intentionally avoiding a perfect-match or two candidates for variant matches.
# Fallback.
-fr, en-GB, ja, es-ES, es-MX ; de, zh ; fr
+de, zh >> fr
+
+@distance=script
+de, en-US >> en-GB
+de, zh >> fr
-##################################################
-# testGetBestMatchForList-matchOnMaximized
+** test: testGetBestMatchForList-matchOnMaximized
# Check that if the preference is maximized already, it works as well.
-en, ja ; ja-Jpan-JP, en-AU ; ja # Match for ja-Jpan-JP (maximized already)
+@supported=en, ja
+ja-Jpan-JP, en-AU >> ja # Match for ja-Jpan-JP (maximized already)
# ja-JP matches ja on likely subtags, and it's listed first, thus it wins over the second preference en-GB.
-en, ja ; ja-JP, en-US ; ja # Match for ja-Jpan-JP (maximized already)
+ja-JP, en-US >> ja # Match for ja-Jpan-JP (maximized already)
# Check that if the preference is maximized already, it works as well.
-en, ja ; ja-Jpan-JP, en-US ; ja # Match for ja-Jpan-JP (maximized already)
+ja-Jpan-JP, en-US >> ja # Match for ja-Jpan-JP (maximized already)
-##################################################
-# testGetBestMatchForList-noMatchOnMaximized
+@distance=script
+ja-Jpan-JP, en-AU >> ja
+ja-JP, en-US >> ja
+ja-Jpan-JP, en-US >> ja
+
+** test: testGetBestMatchForList-noMatchOnMaximized
# Regression test for http://b/5714572 .
# de maximizes to de-DE. Pick the exact match for the secondary language instead.
-en, de, fr, ja ; de-CH, fr ; de
+@supported=en, de, fr, ja
+de-CH, fr >> de
+
+@distance=script
+de-CH, fr >> de
-##################################################
-# testBestMatchForTraditionalChinese
+** test: testBestMatchForTraditionalChinese
# Scenario: An application that only supports Simplified Chinese (and some other languages),
# but does not support Traditional Chinese. zh-Hans-CN could be replaced with zh-CN, zh, or
@@ -197,28 +343,37 @@ en, de, fr, ja ; de-CH, fr ; de
# The script distance (simplified vs. traditional Han) is considered small enough
# to be an acceptable match. The regional difference is considered almost insignificant.
-fr, zh-Hans-CN, en-US ; zh-TW ; zh-Hans-CN
-fr, zh-Hans-CN, en-US ; zh-Hant ; zh-Hans-CN
+@supported=fr, zh-Hans-CN, en-US
+zh-TW >> zh-Hans-CN
+zh-Hant >> zh-Hans-CN
-# For geo-political reasons, you might want to avoid a zh-Hant -> zh-Hans match.
+# For geopolitical reasons, you might want to avoid a zh-Hant -> zh-Hans match.
# In this case, if zh-TW, zh-HK or a tag starting with zh-Hant is requested, you can
# change your call to getBestMatch to include a 2nd language preference.
# "en" is a better match since its distance to "en-US" is closer than the distance
# from "zh-TW" to "zh-CN" (script distance).
-fr, zh-Hans-CN, en-US ; zh-TW, en ; en-US
-fr, zh-Hans-CN, en-US ; zh-Hant-CN, en, en ; en-US
-fr, zh-Hans-CN, en-US ; zh-Hans, en ; zh-Hans-CN
+zh-TW, en >> en-US
+zh-Hant-CN, en >> en-US
+zh-Hans, en >> zh-Hans-CN
+
+@distance=script
+zh-TW >> zh-Hans-CN
+zh-Hant >> zh-Hans-CN
+zh-TW, en >> en-US
+zh-Hant-CN, en >> en-US
+zh-Hans, en >> zh-Hans-CN
-##################################################
-# testUndefined
+** test: testUndefined
# When the undefined language doesn't match anything in the list,
# getBestMatch returns the default, as usual.
-it, fr ; und ; it
+@supported=it, fr
+und >> it
# When it *does* occur in the list, bestMatch returns it, as expected.
-it, und ; und ; und
+@supported=it, und
+und >> und
# The unusual part: max("und") = "en-Latn-US", and since matching is based on maximized
# tags, the undefined language would normally match English. But that would produce the
@@ -229,159 +384,1570 @@ it, und ; und ; und
# so that max("und")="und". That produces the following, more desirable
# results:
-it, en ; und ; it
-it, und ; en ; it
-
-##################################################
-# testGetBestMatch-regionDistance
-
-es-AR, es ; es-MX ; es-AR
-fr, en, en-GB ; en-CA ; en-GB
-de-AT, de-DE, de-CH ; de ; de-DE
-
-##################################################
-# testAsymmetry
-
-mul, nl ; af ; nl # af => nl
-mul, af ; nl ; mul # but nl !=> af
-
-##################################################
-# testGetBestMatchForList-matchOnMaximized2
+@supported=it, en
+und >> it
+@supported=it, und
+en >> it
+
+@distance=script
+@supported=it, fr
+und >> it
+@supported=it, und
+und >> und
+@supported=it, en
+und >> it
+@supported=it, und
+en >> it
+
+** test: testGetBestMatch-regionDistance
+
+@supported=es-AR, es
+es-MX >> es-AR
+@supported=fr, en, en-GB
+en-CA >> en-GB
+@supported=de-AT, de-DE, de-CH
+de >> de-DE
+
+@distance=script
+@supported=es-AR, es
+es-MX >> es-AR
+@supported=fr, en, en-GB
+en-CA >> en-GB
+@supported=de-AT, de-DE, de-CH
+de >> de-DE
+
+** test: testAsymmetry
+
+@supported=mul, nl
+af >> nl # af => nl
+@supported=mul, af
+nl >> mul # but nl !=> af
+
+@distance=script
+@supported=mul, nl
+af >> nl
+@supported=mul, af
+nl >> mul
+
+** test: testGetBestMatchForList-matchOnMaximized2
# ja-JP matches ja on likely subtags, and it's listed first, thus it wins over the second preference en-GB.
-fr, en-GB, ja, es-ES, es-MX ; ja-JP, en-GB ; ja # Match for ja-JP, with likely region subtag
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja-JP, en-GB >> ja # Match for ja-JP, with likely region subtag
# Check that if the preference is maximized already, it works as well.
-fr, en-GB, ja, es-ES, es-MX ; ja-Jpan-JP, en-GB ; ja # Match for ja-Jpan-JP (maximized already)
+ja-Jpan-JP, en-GB >> ja # Match for ja-Jpan-JP (maximized already)
+
+@distance=script
+ja-JP, en-GB >> ja
+ja-Jpan-JP, en-GB >> ja
+
+** test: testGetBestMatchForList-closeEnoughMatchOnMaximized
-##################################################
-# testGetBestMatchForList-closeEnoughMatchOnMaximized
+@supported=en-GB, en, de, fr, ja
+de-CH, fr >> de
+en-US, ar, nl, de, ja >> en
-en-GB, en, de, fr, ja ; de-CH, fr ; de
-en-GB, en, de, fr, ja ; en-US, ar, nl, de, ja ; en
+@distance=script
+de-CH, fr >> de
+en-US, ar, nl, de, ja >> en
-##################################################
-# testGetBestMatchForPortuguese
+** test: testGetBestMatchForPortuguese
# pt might be supported and not pt-PT
-# European user who prefers Spanish over Brazillian Portuguese as a fallback.
+# European user who prefers Spanish over Brazilian Portuguese as a fallback.
-pt-PT, pt-BR, es, es-419 ; pt-PT, es, pt ; pt-PT
-pt-PT, pt, es, es-419 ; pt-PT, es, pt ; pt-PT # pt implicit
+@supported=pt-PT, pt-BR, es, es-419
+pt-PT, es, pt >> pt-PT
+@supported=pt-PT, pt, es, es-419
+pt-PT, es, pt >> pt-PT # pt implicit
-# Brazillian user who prefers South American Spanish over European Portuguese as a fallback.
+# Brazilian user who prefers South American Spanish over European Portuguese as a fallback.
# The asymmetry between this case and above is because it's "pt-PT" that's missing between the
# matchers as "pt-BR" is a much more common language.
-pt-PT, pt-BR, es, es-419 ; pt, es-419, pt-PT ; pt-BR
-pt-PT, pt-BR, es, es-419 ; pt-PT, es, pt ; pt-PT
-pt-PT, pt, es, es-419 ; pt-PT, es, pt ; pt-PT
-pt-PT, pt, es, es-419 ; pt, es-419, pt-PT ; pt
+@supported=pt-PT, pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
+pt-PT, es, pt >> pt-PT
+@supported=pt-PT, pt, es, es-419
+pt-PT, es, pt >> pt-PT
+pt, es-419, pt-PT >> pt
-pt-BR, es, es-419 ; pt, es-419, pt-PT ; pt-BR
+@supported=pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
# Code that adds the user's country can get "pt-US" for a user's language.
# That should fall back to "pt-BR".
-pt-PT, pt-BR, es, es-419 ; pt-US, pt-PT ; pt-BR
-pt-PT, pt, es, es-419 ; pt-US, pt-PT, pt ; pt # pt-BR implicit
+@supported=pt-PT, pt-BR, es, es-419
+pt-US, pt-PT >> pt-BR
+@supported=pt-PT, pt, es, es-419
+pt-US, pt-PT, pt >> pt # pt-BR implicit
+
+@distance=script
+@supported=pt-PT, pt-BR, es, es-419
+pt-PT, es, pt >> pt-PT
+@supported=pt-PT, pt, es, es-419
+pt-PT, es, pt >> pt-PT
+
+@supported=pt-PT, pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
+pt-PT, es, pt >> pt-PT
+@supported=pt-PT, pt, es, es-419
+pt-PT, es, pt >> pt-PT
+pt, es-419, pt-PT >> pt
+
+@supported=pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
+
+@supported=pt-PT, pt-BR, es, es-419
+pt-US, pt-PT >> pt-BR
+@supported=pt-PT, pt, es, es-419
+pt-US, pt-PT, pt >> pt
+
+** test: testVariantWithScriptMatch 1 and 2
+
+@supported=fr, en, sv
+en-GB >> en
+@supported=en, sv
+en-GB, sv >> en
-##################################################
-# testVariantWithScriptMatch 1 and 2
+@distance=script
+@supported=fr, en, sv
+en-GB >> en
+@supported=en, sv
+en-GB, sv >> en
-fr, en, sv ; en-GB ; en
-fr, en, sv ; en-GB ; en
-en, sv ; en-GB, sv ; en
+** test: testLongLists
-##################################################
-# testLongLists
+@supported=en, sv
+sv >> sv
-en, sv ; sv ; sv
-af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-TW, zu ; sv ; sv
-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, as, as-IN, asa, asa-TZ, ast, ast-ES, 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, ca, ca-AD, ca-ES, ca-ES-VALENCIA, ca-FR, ca-IT, ce, ce-RU, cgg, cgg-UG, chr, chr-US, ckb, ckb-IQ, ckb-IR, cs, cs-CZ, cu, cu-RU, cy, cy-GB, da, da-DK, da-GL, dav, dav-KE, de, de-AT, de-BE, de-CH, de-DE, 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-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, eo-001, es, es-419, es-AR, es-BO, 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, id, id-ID, ig, ig-NG, ii, ii-CN, is, is-IS, it, it-CH, it-IT, it-SM, ja, ja-JP, jgo, jgo-CM, jmc, jmc-TZ, 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, 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, mk, mk-MK, ml, ml-IN, mn, mn-MN, 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, 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, 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, pl, pl-PL, prg, prg-001, ps, ps-AF, pt, pt-AO, pt-BR, pt-CV, pt-GW, 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, se, se-FI, se-NO, se-SE, seh, seh-MZ, ses, ses-ML, sg, sg-CF, shi, shi-Latn, shi-Latn-MA, shi-Tfng, shi-Tfng-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-XK, sr-Latn, sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-Latn-XK, 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, th, th-TH, ti, ti-ER, ti-ET, tk, tk-TM, to, to-TO, tr, tr-CY, tr-TR, twq, twq-NE, tzm, tzm-MA, ug, ug-CN, uk, uk-UA, ur, ur-IN, ur-PK, uz, uz-Arab, uz-Arab-AF, uz-Cyrl, uz-Cyrl-UZ, uz-Latn, uz-Latn-UZ, vai, vai-Latn, vai-Latn-LR, vai-Vaii, vai-Vaii-LR, vi, vi-VN, vo, vo-001, vun, vun-TZ, wae, wae-CH, xog, xog-UG, yav, yav-CM, yi, yi-001, yo, yo-BJ, yo-NG, 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, zu, zu-ZA ; sv ; sv
+@supported=af, am, ar, az, be, bg, bn, bs, ca, cs, cy, da, de, el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-TW, zu
+sv >> sv
-##################################################
-# test8288
+@supported=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, as, as-IN, asa, asa-TZ, ast, ast-ES, 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, ca, ca-AD, ca-ES, ca-ES-VALENCIA, ca-FR, ca-IT, ce, ce-RU, cgg, cgg-UG, chr, chr-US, ckb, ckb-IQ, ckb-IR, cs, cs-CZ, cu, cu-RU, cy, cy-GB, da, da-DK, da-GL, dav, dav-KE, de, de-AT, de-BE, de-CH, de-DE, 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-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, eo-001, es, es-419, es-AR, es-BO, 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, id, id-ID, ig, ig-NG, ii, ii-CN, is, is-IS, it, it-CH, it-IT, it-SM, ja, ja-JP, jgo, jgo-CM, jmc, jmc-TZ, 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, 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, mk, mk-MK, ml, ml-IN, mn, mn-MN, 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, 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, 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, pl, pl-PL, prg, prg-001, ps, ps-AF, pt, pt-AO, pt-BR, pt-CV, pt-GW, 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, se, se-FI, se-NO, se-SE, seh, seh-MZ, ses, ses-ML, sg, sg-CF, shi, shi-Latn, shi-Latn-MA, shi-Tfng, shi-Tfng-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-XK, sr-Latn, sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-Latn-XK, 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, th, th-TH, ti, ti-ER, ti-ET, tk, tk-TM, to, to-TO, tr, tr-CY, tr-TR, twq, twq-NE, tzm, tzm-MA, ug, ug-CN, uk, uk-UA, ur, ur-IN, ur-PK, uz, uz-Arab, uz-Arab-AF, uz-Cyrl, uz-Cyrl-UZ, uz-Latn, uz-Latn-UZ, vai, vai-Latn, vai-Latn-LR, vai-Vaii, vai-Vaii-LR, vi, vi-VN, vo, vo-001, vun, vun-TZ, wae, wae-CH, xog, xog-UG, yav, yav-CM, yi, yi-001, yo, yo-BJ, yo-NG, 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, zu, zu-ZA
+sv >> sv
-it, en ; und ; it
-it, en ; und, en ; en
+@distance=script
+@supported=en, sv
+sv >> sv
+
+@supported=af, am, ar, az, be, bg, bn, bs, ca, cs, cy, da, de, el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-TW, zu
+sv >> sv
+
+@supported=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, as, as-IN, asa, asa-TZ, ast, ast-ES, 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, ca, ca-AD, ca-ES, ca-ES-VALENCIA, ca-FR, ca-IT, ce, ce-RU, cgg, cgg-UG, chr, chr-US, ckb, ckb-IQ, ckb-IR, cs, cs-CZ, cu, cu-RU, cy, cy-GB, da, da-DK, da-GL, dav, dav-KE, de, de-AT, de-BE, de-CH, de-DE, 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-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, eo-001, es, es-419, es-AR, es-BO, 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, id, id-ID, ig, ig-NG, ii, ii-CN, is, is-IS, it, it-CH, it-IT, it-SM, ja, ja-JP, jgo, jgo-CM, jmc, jmc-TZ, 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, 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, mk, mk-MK, ml, ml-IN, mn, mn-MN, 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, 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, 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, pl, pl-PL, prg, prg-001, ps, ps-AF, pt, pt-AO, pt-BR, pt-CV, pt-GW, 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, se, se-FI, se-NO, se-SE, seh, seh-MZ, ses, ses-ML, sg, sg-CF, shi, shi-Latn, shi-Latn-MA, shi-Tfng, shi-Tfng-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-XK, sr-Latn, sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-Latn-XK, 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, th, th-TH, ti, ti-ER, ti-ET, tk, tk-TM, to, to-TO, tr, tr-CY, tr-TR, twq, twq-NE, tzm, tzm-MA, ug, ug-CN, uk, uk-UA, ur, ur-IN, ur-PK, uz, uz-Arab, uz-Arab-AF, uz-Cyrl, uz-Cyrl-UZ, uz-Latn, uz-Latn-UZ, vai, vai-Latn, vai-Latn-LR, vai-Vaii, vai-Vaii-LR, vi, vi-VN, vo, vo-001, vun, vun-TZ, wae, wae-CH, xog, xog-UG, yav, yav-CM, yi, yi-001, yo, yo-BJ, yo-NG, 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, zu, zu-ZA
+sv >> sv
+
+** test: test8288
+
+@supported=it, en
+und >> it
+und, en >> en
# examples from
# http://unicode.org/repos/cldr/tags/latest/common/bcp47/
# http://unicode.org/repos/cldr/tags/latest/common/validity/variant.xml
-##################################################
-# testUnHack
+@distance=script
+und >> it
+und, en >> en
-en-NZ, en-IT ; en-US ; en-NZ
+** test: testUnHack
-##################################################
-# testEmptySupported => null
- ; en ; null
+@supported=en-NZ, en-IT
+en-US >> en-NZ
-##################################################
-# testVariantsAndExtensions
-##################################################
-# tests the .combine() method
+@distance=script
+en-US >> en-NZ
-und, fr ; fr-BE-fonipa ; fr ; fr-BE-fonipa
-und, fr-CA ; fr-BE-fonipa ; fr-CA ; fr-BE-fonipa
-und, fr-fonupa ; fr-BE-fonipa ; fr-fonupa ; fr-BE-fonipa
-und, no ; nn-BE-fonipa ; no ; no-BE-fonipa
-und, en-GB-u-sd-gbsct ; en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin ; en-GB-u-sd-gbsct ; en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin
+** test: testEmptySupported => null
+en >> null
-en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; fr-PSCRACK ; fr-PSCRACK
-en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; fr ; en-PSCRACK # was: fr-PSCRACK
-en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; de-CH ; en-PSCRACK # was: de-PSCRACK
+# testVariantsAndExtensions
-##################################################
-# testClusters
+** test: tests the .combine() method
+
+@supported=und, fr
+fr-BE-fonipa >> fr | | fr-BE-fonipa
+@supported=und, fr-CA
+fr-BE-fonipa >> fr-CA | | fr-BE-fonipa
+@supported=und, fr-fonupa
+fr-BE-fonipa >> fr-fonupa | | fr-BE-fonipa
+@supported=und, no
+nn-BE-fonipa >> no | | no-BE-fonipa
+@supported=und, en-GB-u-sd-gbsct
+en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin >> en-GB-u-sd-gbsct | | en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin
+
+@supported=en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK
+fr-PSCRACK >> fr-PSCRACK
+fr >> en-PSCRACK
+de-CH >> en-PSCRACK
+
+@distance=script
+@supported=und, fr
+fr-BE-fonipa >> fr
+@supported=und, fr-CA
+fr-BE-fonipa >> fr-CA
+@supported=und, fr-fonupa
+fr-BE-fonipa >> fr-fonupa
+@supported=und, no
+nn-BE-fonipa >> no | | no-BE-fonipa
+@supported=und, en-GB-u-sd-gbsct
+en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin >> en-GB-u-sd-gbsct | | en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin
+
+@supported=en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK
+fr-PSCRACK >> fr-PSCRACK
+fr >> en-PSCRACK
+de-CH >> en-PSCRACK
+
+** test: testClusters
# we favor es-419 over others in cluster. Clusters: es- {ES, MA, EA} {419, AR, MX}
-und, es, es-MA, es-MX, es-419 ; es-AR ; es-419
-und, es-MA, es, es-419, es-MX ; es-AR ; es-419
-und, es, es-MA, es-MX, es-419 ; es-EA ; es
-und, es-MA, es, es-419, es-MX ; es-EA ; es
+@supported=und, es, es-MA, es-MX, es-419
+es-AR >> es-419
+@supported=und, es-MA, es, es-419, es-MX
+es-AR >> es-419
+@supported=und, es, es-MA, es-MX, es-419
+es-EA >> es
+@supported=und, es-MA, es, es-419, es-MX
+es-EA >> es
# of course, fall back to within cluster
-und, es, es-MA, es-MX ; es-AR ; es-MX
-und, es-MA, es, es-MX ; es-AR ; es-MX
-und, es-MA, es-MX, es-419 ; es-EA ; es-MA
-und, es-MA, es-419, es-MX ; es-EA ; es-MA
+@supported=und, es, es-MA, es-MX
+es-AR >> es-MX
+@supported=und, es-MA, es, es-MX
+es-AR >> es-MX
+@supported=und, es-MA, es-MX, es-419
+es-EA >> es-MA
+@supported=und, es-MA, es-419, es-MX
+es-EA >> es-MA
# we favor es-GB over others in cluster. Clusters: en- {US, GU, VI} {GB, IN, ZA}
-und, en, en-GU, en-IN, en-GB ; en-ZA ; en-GB
-und, en-GU, en, en-GB, en-IN ; en-ZA ; en-GB
-und, en, en-GU, en-IN, en-GB ; en-VI ; en
-und, en-GU, en, en-GB, en-IN ; en-VI ; en
+@supported=und, en, en-GU, en-IN, en-GB
+en-ZA >> en-GB
+@supported=und, en-GU, en, en-GB, en-IN
+en-ZA >> en-GB
+@supported=und, en, en-GU, en-IN, en-GB
+en-VI >> en
+@supported=und, en-GU, en, en-GB, en-IN
+en-VI >> en
# of course, fall back to within cluster
-und, en, en-GU, en-IN ; en-ZA ; en-IN
-und, en-GU, en, en-IN ; en-ZA ; en-IN
-und, en-GU, en-IN, en-GB ; en-VI ; en-GU
-und, en-GU, en-GB, en-IN ; en-VI ; en-GU
-
-##################################################
-# testThreshold
-@Threshold=60
-
-50, und, fr-CA-fonupa ; fr-BE-fonipa ; fr-CA-fonupa ; fr-BE-fonipa
-50, und, fr-Cyrl-CA-fonupa ; fr-BE-fonipa ; fr-Cyrl-CA-fonupa ; fr-Cyrl-BE-fonipa
-
-@Threshold=-1 # restore
-
-##################################################
-# testScriptFirst
-@DistanceOption=SCRIPT_FIRST
-@debug
+@supported=und, en, en-GU, en-IN
+en-ZA >> en-IN
+@supported=und, en-GU, en, en-IN
+en-ZA >> en-IN
+@supported=und, en-GU, en-IN, en-GB
+en-VI >> en-GU
+@supported=und, en-GU, en-GB, en-IN
+en-VI >> en-GU
+
+@distance=script
+@supported=und, es, es-MA, es-MX, es-419
+es-AR >> es-419
+@supported=und, es-MA, es, es-419, es-MX
+es-AR >> es-419
+@supported=und, es, es-MA, es-MX, es-419
+es-EA >> es
+@supported=und, es-MA, es, es-419, es-MX
+es-EA >> es
+
+@supported=und, es, es-MA, es-MX
+es-AR >> es-MX
+@supported=und, es-MA, es, es-MX
+es-AR >> es-MX
+@supported=und, es-MA, es-MX, es-419
+es-EA >> es-MA
+@supported=und, es-MA, es-419, es-MX
+es-EA >> es-MA
+
+@supported=und, en, en-GU, en-IN, en-GB
+en-ZA >> en-GB
+@supported=und, en-GU, en, en-GB, en-IN
+en-ZA >> en-GB
+@supported=und, en, en-GU, en-IN, en-GB
+en-VI >> en
+@supported=und, en-GU, en, en-GB, en-IN
+en-VI >> en
+
+@supported=und, en, en-GU, en-IN
+en-ZA >> en-IN
+@supported=und, en-GU, en, en-IN
+en-ZA >> en-IN
+@supported=und, en-GU, en-IN, en-GB
+en-VI >> en-GU
+@supported=und, en-GU, en-GB, en-IN
+en-VI >> en-GU
+
+** test: testThreshold
+@supported=50, und, fr-CA-fonupa
+@threshold=60
+fr-BE-fonipa >> fr-CA-fonupa | | fr-BE-fonipa
+@supported=und, fr-Cyrl-CA-fonupa
+fr-BE-fonipa >> fr-Cyrl-CA-fonupa | | fr-Cyrl-BE-fonipa
+@threshold=50
+fr-BE-fonipa >> und
+
+@distance=script
+@supported=50, und, fr-CA-fonupa
+@threshold=
+fr-BE-fonipa >> fr-CA-fonupa | | fr-BE-fonipa
+@supported=und, fr-Cyrl-CA-fonupa
+fr-BE-fonipa >> fr-Cyrl-CA-fonupa | fr-BE-fonipa
+
+** test: testScriptFirst
+@supported=ru, fr
+zh, pl >> ru
+zh-Cyrl, pl >> ru
+@supported=hr, en-Cyrl
+sr >> hr
+@supported=da, ru, hr
+sr >> da
+
+@distance=script
+@supported=ru, fr
+zh, pl >> fr
+zh-Cyrl, pl >> ru
+@supported=hr, en-Cyrl
+sr >> en-Cyrl
+@supported=da, ru, hr
+sr >> ru
+
+## III
+
+** test: testBasicsWithDefault
+@supported=en-GB, en
+@default=fr
+en-GB >> en-GB
+en-US >> en
+fr >> fr
+ja >> fr
+
+@distance=script
+en-GB >> en-GB
+en-US >> en
+fr >> en-GB
+ja >> en-GB
+
+** test: testEmptyWithDefault
+@default=en
+fr >> en
+
+** test: testGetBestMatchForList_exactMatch
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja, de >> ja
+
+** test: testGetBestMatchForList_simpleVariantMatch
+# Intentionally avoiding a perfect-match or two candidates for variant matches.
+@supported=fr, en-GB, ja, es-ES, es-MX
+de, en-US >> en-GB
+# Fall back.
+de, zh >> fr
+
+** test: TestEuHack
+@supported=en-NZ, en-IT
+en-US >> en-NZ
+
+** test: TestBasics
+@supported=fr, en-GB, en
+en-GB >> en-GB
+en-US >> en
+fr-FR >> fr
+ja-JP >> fr
+# For a language that doesn't match anything, return the default.
+zu >> en-GB
+zxx >> fr
+
+@distance=script
+en-GB >> en-GB
+en-US >> en
+fr-FR >> fr
+ja-JP >> fr
+zu >> en-GB
+zxx >> en
+
+** test: TestExactMatch
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja, de >> ja
+
+** test: TestSimpleVariantMatch
+@supported=fr, en-GB, ja, es-ES, es-MX
+de, en-US >> en-GB
+de, zh >> fr
+
+** test: TestMatchOnMaximized
+# ja-JP matches ja on likely subtags, and it's listed first, thus it wins
+# over the secondary preference en-GB.
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja-JP, en-GB >> ja
+# Check that if the preference is maximized already, it works as well.
+ja-Jpan-JP, en-GB >> ja
+@supported=fr, zh-Hant, en
+zh, en >> en
+
+@distance=script
+zh, en >> en
+
+** test: TestCloseEnoughMatchOnMaximized
+@supported=en-GB, en, de, fr, ja
+de-CH, fr >> de
+en-US, ar, nl, de, ja >> en
+
+** test: TestGetBestMatchForPortuguese
+# 1. a supported set containing an explicit pt: {pt-PT, pt-BR, es, es-419}
+# 2. a supported set containing an implicit pt: {pt-PT, pt, es, es-419}
+# 3. a supported set containing no pt: {pt-BR, es, es-419}
+# European user who prefers Spanish over Brazilian Portuguese as a fallback.
+@supported=pt-PT, pt-BR, es, es-419
+pt-PT, es, pt >> pt-PT
+@supported=pt-PT, pt, es, es-419
+pt-PT, es, pt >> pt-PT
+@supported=pt-BR, es, es-419
+pt-PT, es, pt >> pt-BR
+
+# Brazilian user who prefers South American Spanish over European Portuguese
+# as a fallback. The asymmetry between this case and above is because it's
+# "pt-PT" that's missing between the matchers.
+@supported=pt-PT, pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
+@supported=pt-PT, pt, es, es-419
+pt, es-419, pt-PT >> pt
+@supported=pt-BR, es, es-419
+pt, es-419, pt-PT >> pt-BR
+
+# Sometimes we get "pt-US" for a user's language (which CLDR doesn't
+# recognize) but we deal with that as a synonym for "pt-BR".
+@supported=pt-PT, pt-BR, es, es-419
+pt-US, pt-PT >> pt-BR
+@supported=pt-PT, pt, es, es-419
+pt-US, pt-PT >> pt
+
+@distance=script
+@supported=pt-BR, es, es-419
+pt-PT, es, pt >> pt-BR
+@supported=pt-PT, pt, es, es-419
+pt-US, pt-PT >> pt
+
+** test: TestScriptAndRegion
+@supported=en-GB, en
+en-CA >> en-GB
+# fr-CA is a "close enough" match to "fr" to be returned in favor of "en-GB"
+@supported=fr, en-GB, en
+fr-CA, en-CA >> fr
+@supported=zh-Hant, zh-TW
+zh-HK >> zh-Hant
+
+@distance=script
+@supported=en-GB, en
+en-CA >> en-GB
+@supported=fr, en-GB, en
+fr-CA, en-CA >> fr
+@supported=zh-Hant, zh-TW
+zh-HK >> zh-Hant
+
+** test: TestFallback
+@supported=zh-CN, zh-TW, iw
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+he-IT >> iw
+
+** test: TestFallbackWithDefault
+# Check that script fallbacks are handled right and that we don't have to
+# fall back to the default.
+@supported=zh-CN, zh-TW, iw
+@default=fr
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+he-IT >> iw
+
+@distance=script
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+he-IT >> iw
+
+** test: TestSpecials
+# Check that nearby languages are handled.
+@supported=en, fil, ro, nn
+tl >> fil
+mo >> ro
+nb >> nn
+ja >> en # Make sure default works.
+
+** test: TestRegionalSpecials
+# Verify that en-AU is closer to en-GB than to en (which is en-US).
+@supported=en, en-GB, es-ES, es-419
+en-AU >> en-GB
+# Following 2 cases test closer/smaller region difference.
+es-MX >> es-419
+es-PT >> es-ES
+
+@distance=script
+en-AU >> en-GB
+es-MX >> es-419
+es-PT >> es-ES
+
+** test: TestEmpty
+fr >> null
+
+** test: TestUndefined
+# When the undefined language doesn't match anything in the list,
+# return the default.
+@supported=it, fr
+und >> it
+# When it *does* occur in the list, return it.
+@supported=it, und
+und >> und
+# The unusual part:
+# max("und") = "en-Latn-US", and since matching is based on
+# maximized tags, the undefined language would normally match
+# English. But that would produce the counterintuitive results
+# that BestMatchFor("und", LanguageMatcher("it,en")) would be "en",
+# and BestMatchFor("en", LanguageMatcher("it,und")) would be "und".
-ru, fr ; zh, pl ; fr
-ru, fr ; zh-Cyrl, pl ; ru
-#hr, en-Cyrl; sr ; en-Cyrl
-da, ru, hr; sr ; ru
+# To avoid that, we change the matcher's definitions of max
+# (AddLikelySubtagsWithDefaults) so that max("und")="und". That
+# produces the following, more desirable results:
+@supported=it, en
+und >> it
+@supported=it, und
+en >> it
+
+** test: TestVariantWithScriptMatch
+@supported=fr, en, sv
+en-GB >> en
+en-GB, sv >> en
+
+@distance=script
+en-GB, sv >> en
+
+** test: Serbian
+@supported=und, sr
+sr-ME >> sr
+@supported=und, sr-ME
+sr >> sr-ME
+@supported=und, sr-Latn
+bs >> und
+@supported=und, bs
+sr-Latn >> und
+@supported=und, sr
+bs >> und
+@supported=und, bs
+sr >> und
+@supported=und, sr-Latn
+sr >> sr-Latn
+@supported=und, sr
+sr-Latn >> sr
+
+@distance=script
+sr-ME >> sr
+@supported=und, sr-ME
+sr >> sr-ME
+@supported=und, sr-Latn
+bs >> sr-Latn
+@supported=und, bs
+sr-Latn >> bs
+@supported=und, sr
+bs >> und
+@supported=und, bs
+sr >> und
+@supported=und, sr-Latn
+sr >> sr-Latn
+@supported=und, sr
+sr-Latn >> sr
+
+** test: MatchGooglePrivateUseSubtag
+@supported=fr, x-bork, en-Latn-US
+x-piglatin >> fr
+x-bork >> x-bork
+@supported=fr, en-GB, x-bork, es-ES, es-419
+x-piglatin >> fr
+x-bork >> x-bork
+
+@distance=script
+@supported=fr, x-bork, en-Latn-US
+x-piglatin >> x-bork
+x-bork >> x-bork
+@supported=fr, en-GB, x-bork, es-ES, es-419
+x-piglatin >> x-bork
+x-bork >> x-bork
+
+** test: MatchGrandfatheredCode
+@supported=fr, i-klingon, en-Latn-US
+en-GB-oed >> en-Latn-US
+i-klingon >> tlh
+
+@distance=script
+en-GB-oed >> en-Latn-US
+i-klingon >> tlh
+
+** test: MatchGooglePseudoLocale
+# Google pseudo locales using variant subtags.
+# (See below for the region code based pseudo locales.)
+@supported=fr, en-PSACCENT, ar-PSBIDI, en-PSCRACK, zh-Hans-PSCRACK, pt-PT-PSCRACK, pt
+de >> fr
+en-US >> fr
+en >> fr
+ar-PSBIDI >> ar-PSBIDI
+en-PSACCENT >> en-PSACCENT
+en-PSCRACK >> en-PSCRACK
+pt-BR >> pt
+pt-PT-PSCRACK >> pt-PT-PSCRACK
+zh-Hans-PSCRACK >> zh-Hans-PSCRACK
+
+@distance=script
+de >> fr
+en-US >> fr
+en >> fr
+ar-PSBIDI >> ar-PSBIDI
+en-PSACCENT >> en-PSACCENT
+en-PSCRACK >> en-PSCRACK
+pt-BR >> pt
+pt-PT-PSCRACK >> pt-PT-PSCRACK
+zh-Hans-PSCRACK >> zh-Hans-PSCRACK
+
+** test: MatchGooglePseudoLocaleWithFallbacks
+# Pseudo locales based on the fall back option (XA..XC region codes).
+@supported=fr, en-XA, ar-XB, en-XC, zh-Hans-XC, pt
+de >> fr
+en-US >> fr
+en >> fr
+ar-XB >> ar-XB
+en-XA >> en-XA
+en-XC >> en-XC
+pt-BR >> pt
+zh-Hans-XC >> zh-Hans-XC
+
+@distance=script
+de >> fr
+en-US >> fr
+en >> fr
+ar-XB >> ar-XB
+en-XA >> en-XA
+en-XC >> en-XC
+pt-BR >> pt
+zh-Hans-XC >> zh-Hans-XC
+
+** test: DoNotMatchGooglePseudoLocale
+@supported=fr, en-XA, ar-XB, en-PSACCENT, ar-PSBIDI, en-DE, pt, ar-SY, ar-PSCRACK
+de >> fr
+# We wouldn't want to return pseudo locales when there's a good match for an
+# ordinary locale.
+# Note: If LanguageMatcher was not aware of PSACCENT, it would consider the
+# distance from "en" to "en-PSACCENT" smaller than to "en-DE" (the standard
+# variant distance is smaller than a region distance).
+en >> en-DE
+ar-EG >> ar-SY
+pt-BR >> pt
+ar-XB >> ar-XB
+ar-PSBIDI >> ar-PSBIDI
+en-XA >> en-XA
+en-PSACCENT >> en-PSACCENT
+ar-PSCRACK >> ar-PSCRACK
+
+@distance=script
+de >> en-DE
+en >> en-DE
+ar-EG >> ar-SY
+pt-BR >> pt
+ar-XB >> ar-XB
+ar-PSBIDI >> ar-PSBIDI
+en-XA >> en-XA
+en-PSACCENT >> en-PSACCENT
+ar-PSCRACK >> ar-PSCRACK
+
+** test: BestMatchForTraditionalChinese
+# Scenario: An application that only supports Simplified Chinese (and some
+# other languages), but does not support Traditional Chinese. zh-Hans-CN
+# could be replaced with zh-CN, zh, or zh-Hans, it wouldn't make much of a
+# difference.
+# The script distance (simplified vs. traditional Han) is considered small
+# enough to be an acceptable match. The regional difference is considered
+# almost insignificant.
+@supported=fr, zh-Hans-CN, en-US
+zh-TW >> zh-Hans-CN
+zh-Hant >> zh-Hans-CN
+
+# For geopolitical reasons, you might want to avoid a zh-Hant -> zh-Hans
+# match. In this case, if zh-TW, zh-HK or a tag starting with zh-Hant is
+# requested, you can change your call to getBestMatch to include a 2nd
+# language preference. "en" is a better match since its distance to "en-US"
+# is closer than the distance from "zh-TW" to "zh-CN" (script distance).
+zh-TW, en >> en-US
+zh-Hant-CN, en >> en-US
+zh-Hans, en >> zh-Hans-CN
+
+** test: MaxBeforeEquals
+# Compare maximized forms of earlier items before testing equality
+# of later items.
+@supported=en, fr-CA
+en-US, fr-CA >> en
+
+@distance=script
+en-US, fr-CA >> en
+
+** test: SiblingDefaultRegion
+@supported=de-AT, de-DE, de-CH
+de >> de-DE
+
+** test: ReturnDefaultInsteadOfNullForEmptyPriorityList
+@default=und
+de >> und
+
+** test: ReturnSpecifiedDefaultForNoMatch
+@supported=de, en, fr
+@default=und
+hi >> und
+
+@distance=script
+hi >> de
+
+** test: MatchedLanguageIgnoresDefault
+@supported=de, en, fr
+@default=und
+fr >> fr
+
+@distance=script
+fr >> fr
+
+## GenX
+
+** test: TwoSpanishes
+@supported=es, es-MX
+@default=und
+es-001 >> es
+und >> und
+ca >> und
+gl-ES >> es
+es >> es
+es-MX >> es-MX
+es-002 >> es
+es-003 >> es-MX
+es-005 >> es-MX
+es-019 >> es-MX
+es-029 >> es-MX
+es-419 >> es-MX
+es-142 >> es
+es-150 >> es
+es-AD >> es
+es-AR >> es-MX
+es-BO >> es-MX
+es-BZ >> es-MX
+es-CA >> es-MX
+es-CL >> es-MX
+es-CO >> es-MX
+es-CR >> es-MX
+es-CU >> es-MX
+es-DO >> es-MX
+es-EC >> es-MX
+es-ES >> es
+es-GI >> es
+es-GQ >> es
+es-GT >> es-MX
+es-HN >> es-MX
+es-NI >> es-MX
+es-PA >> es-MX
+es-PE >> es-MX
+es-PH >> es
+es-PR >> es-MX
+es-PY >> es-MX
+es-SV >> es-MX
+es-US >> es-MX
+es-UY >> es-MX
+es-VE >> es-MX
+
+@distance=script
+es-001 >> es
+und >> es
+ca >> es
+gl-ES >> es
+es >> es
+es-MX >> es-MX
+es-002 >> es
+es-003 >> es-MX
+es-005 >> es-MX
+es-019 >> es-MX
+es-029 >> es-MX
+es-419 >> es-MX
+es-142 >> es
+es-150 >> es
+es-AD >> es
+es-AR >> es-MX
+es-BO >> es-MX
+es-BZ >> es-MX
+es-CA >> es-MX
+es-CL >> es-MX
+es-CO >> es-MX
+es-CR >> es-MX
+es-CU >> es-MX
+es-DO >> es-MX
+es-EC >> es-MX
+es-ES >> es
+es-GI >> es
+es-GQ >> es
+es-GT >> es-MX
+es-HN >> es-MX
+es-NI >> es-MX
+es-PA >> es-MX
+es-PE >> es-MX
+es-PH >> es
+es-PR >> es-MX
+es-PY >> es-MX
+es-SV >> es-MX
+es-US >> es-MX
+es-UY >> es-MX
+es-VE >> es-MX
+
+** test: Three Spanishes
+@supported=es, es-419, es-MX
+@default=und
+es-001 >> es
+und >> und
+ca >> und
+gl-ES >> es
+es >> es
+es-419 >> es-419
+es-002 >> es
+es-003 >> es-419
+es-005 >> es-419
+es-019 >> es-419
+es-029 >> es-419
+es-142 >> es
+es-150 >> es
+es-AD >> es
+es-AR >> es-419
+es-BO >> es-419
+es-BZ >> es-419
+es-CA >> es-419
+es-CL >> es-419
+es-CO >> es-419
+es-CR >> es-419
+es-CU >> es-419
+es-DO >> es-419
+es-EC >> es-419
+es-ES >> es
+es-GI >> es
+es-GQ >> es
+es-GT >> es-419
+es-HN >> es-419
+es-MX >> es-MX
+es-NI >> es-419
+es-PA >> es-419
+es-PE >> es-419
+es-PH >> es
+es-PR >> es-419
+es-PY >> es-419
+es-SV >> es-419
+es-US >> es-419
+es-UY >> es-419
+es-VE >> es-419
+
+@distance=script
+es-001 >> es
+und >> es
+ca >> es
+gl-ES >> es
+es >> es
+es-419 >> es-419
+es-002 >> es
+es-003 >> es-419
+es-005 >> es-419
+es-019 >> es-419
+es-029 >> es-419
+es-142 >> es
+es-150 >> es
+es-AD >> es
+es-AR >> es-419
+es-BO >> es-419
+es-BZ >> es-419
+es-CA >> es-419
+es-CL >> es-419
+es-CO >> es-419
+es-CR >> es-419
+es-CU >> es-419
+es-DO >> es-419
+es-EC >> es-419
+es-ES >> es
+es-GI >> es
+es-GQ >> es
+es-GT >> es-419
+es-HN >> es-419
+es-MX >> es-MX
+es-NI >> es-419
+es-PA >> es-419
+es-PE >> es-419
+es-PH >> es
+es-PR >> es-419
+es-PY >> es-419
+es-SV >> es-419
+es-US >> es-419
+es-UY >> es-419
+es-VE >> es-419
+
+** test: Englishes
+@supported=en-GB, en-US
+@default=und
+und >> und
+ja >> und
+fr-CA >> und
+
+# Great Britain fallback
+en-AU >> en-GB
+en-BZ >> en-GB
+en-CA >> en-GB
+en-IN >> en-GB
+en-IE >> en-GB
+en-JM >> en-GB
+en-NZ >> en-GB
+en-PK >> en-GB
+en-TT >> en-GB
+en-ZA >> en-GB
+
+# United States fallback
+en-US >> en-US
+en >> en-US
+
+@distance=script
+und >> en-GB
+ja >> en-GB
+fr-CA >> en-GB
+en-AU >> en-GB
+en-BZ >> en-GB
+en-CA >> en-GB
+en-IN >> en-GB
+en-IE >> en-GB
+en-JM >> en-GB
+en-NZ >> en-GB
+en-PK >> en-GB
+en-TT >> en-GB
+en-ZA >> en-GB
+en-US >> en-US
+en >> en-US
+
+** test: TestFallback
+# manyEnMatcher
+@supported=en-GB, en-US, en, en-AU
+@default=und
+und >> und
+ja >> und
+fr-CA >> und
+
+# nonUsMatcher
+fr >> und
+
+# onlyAuMatcher
+@supported=en-AU, ja, ca
+fr >> und
+
+# noEnMatcher
+@supported=pl, ja, ca
+fr >> und
+
+@distance=script
+@supported=en-GB, en-US, en, en-AU
+und >> en-GB
+ja >> en-GB
+fr-CA >> en-GB
+fr >> en-GB
+@supported=en-AU, ja, ca
+fr >> en-AU
+@supported=pl, ja, ca
+fr >> pl
+
+## Go
+
+** test: basics
+@supported=fr, en-GB, en
+en-GB >> en-GB
+en-US >> en
+fr-FR >> fr
+ja-JP >> fr
+
+** test: script fallbacks
+@supported=zh-CN, zh-TW, iw
+zh-Hant >> zh-TW
+zh >> zh-CN
+zh-Hans-CN >> zh-CN
+zh-Hant-HK >> zh-TW
+@default=iw
+he-IT >> iw
+
+@distance=script
+he-IT >> iw
+
+** test: language-specific script fallbacks 1
+@supported=en, sr, nl
+sr-Latn >> sr
+sh >> en
+hr >> en
+bs >> en
+nl-Cyrl >> en # Mark: Expected value should be en not sr. Script difference exceeds threshold, so can't be nl
+
+@distance=script
+sr-Latn >> sr
+hr >> en
+bs >> en
+nl-Cyrl >> sr
+
+** test: language-specific script fallbacks 2
+@supported=en, sr-Latn
+sr >> sr-Latn
+sr-Cyrl >> sr-Latn
+@default=und
+hr >> und
+
+@distance=script
+@default=
+sr >> sr-Latn
+sr-Cyrl >> sr-Latn
+@default=und
+hr >> en
+
+** test: don't match hr to sr-Latn
+@supported=en, sr-Latn
+hr >> en
+
+@distance=script
+hr >> en
+
+** test: both deprecated and not
+@supported=fil, tl, iw, he
+he-IT >> iw
+he >> he
+iw >> iw
+fil-IT >> fil
+fil >> fil
+tl >> tl
+
+@distance=script
+he-IT >> iw
+he >> he
+iw >> iw
+fil-IT >> fil
+fil >> fil
+tl >> tl
+
+** test: nearby languages: Nynorsk to Bokmål
+@supported=en, nb
+nn >> nb
+
+@distance=script
+nn >> nb
+
+** test: nearby languages: Danish does not match nn
+@supported=en, nn
+da >> en
+
+@distance=script
+da >> en
+
+** test: nearby languages: Danish matches no
+@supported=en, no
+da >> no
+
+@distance=script
+da >> no
+
+** test: nearby languages: Danish matches nb
+@supported=en, nb
+da >> nb
+
+** test: prefer matching languages over language variants.
+@supported=nn, en-GB
+no, en-US >> nn
+nb, en-US >> nn
+
+@distance=script
+no, en-US >> nn
+nb, en-US >> nn
+
+** test: deprecated version is closer than same language with other differences
+@supported=nl, he, en-GB
+iw, en-US >> he
+
+@distance=script
+iw, en-US >> he
+
+** test: macro equivalent is closer than same language with other differences
+@supported=nl, zh, en-GB, no
+cmn, en-US >> zh
+nb, en-US >> no
+
+@distance=script
+cmn, en-US >> zh
+nb, en-US >> no
+
+** test: legacy equivalent is closer than same language with other differences
+@supported=nl, fil, en-GB
+tl, en-US >> fil
+
+@distance=script
+tl, en-US >> fil
+
+** test: distinguish near equivalents
+@supported=en, ro, mo, ro-MD
+ro >> ro
+mo >> mo
+ro-MD >> ro-MD
+
+@distance=script
+ro >> ro
+mo >> mo
+ro-MD >> ro-MD
+
+** test: maximization of legacy
+@supported=sr-Cyrl, sr-Latn, ro, ro-MD
+sh >> sr-Latn
+mo >> ro
+
+@distance=script
+sh >> sr-Latn
+mo >> ro
+
+** test: empty
+fr >> null
+en >> null
+
+** test: private use subtags
+@supported=fr, en-GB, x-bork, es-ES, es-419
+x-piglatin >> fr
+x-bork >> x-bork
+
+** test: grandfathered codes
+@supported=fr, i-klingon, en-Latn-US
+en-GB-oed >> en-Latn-US
+i-klingon >> tlh
+
+
+** test: simple variant match
+@supported=fr, en-GB, ja, es-ES, es-MX
+de, en-US >> en-GB
+de, zh >> fr
+
+** test: best match for traditional Chinese
+@supported=fr, zh-Hans-CN, en-US
+zh-TW >> zh-Hans-CN
+zh-Hant >> zh-Hans-CN
+zh-TW, en >> en-US
+zh-Hant-CN, en >> en-US
+zh-Hans, en >> zh-Hans-CN
+
+** test: more specific script should win in case regions are identical
+@supported=af, af-Latn, af-Arab
+af >> af
+af-ZA >> af
+af-Latn-ZA >> af
+af-Latn >> af-Latn
+
+@distance=script
+af >> af
+af-ZA >> af
+af-Latn-ZA >> af
+af-Latn >> af-Latn
+
+** test: more specific region should win
+@supported=nl, nl-NL, nl-BE
+nl >> nl
+nl-Latn >> nl
+nl-Latn-NL >> nl
+nl-NL >> nl-NL
+
+@distance=script
+nl >> nl
+nl-Latn >> nl
+nl-Latn-NL >> nl
+nl-NL >> nl-NL
+
+** test: region may replace matched if matched is enclosing
+@supported=es-419, es
+@default=es-MX
+es-MX >> es-419
+@default=
+es-SG >> es
+
+@distance=script
+@default=es-MX
+es-MX >> es-419
+@default=
+es-SG >> es
+
+** test: more specific region wins over more specific script
+@supported=nl, nl-Latn, nl-NL, nl-BE
+nl >> nl
+nl-Latn >> nl-Latn
+nl-NL >> nl-NL
+nl-Latn-NL >> nl
+
+@distance=script
+nl >> nl
+nl-Latn >> nl-Latn
+nl-NL >> nl-NL
+nl-Latn-NL >> nl
+
+** test: region distance Portuguese
+@supported=pt, pt-PT
+pt-ES >> pt-PT
+
+@distance=script
+pt-ES >> pt-PT
+
+** test: if no preferred locale specified, pick top language, not regional
+@supported=en, fr, fr-CA, fr-CH
+fr-US >> fr
+
+@distance=script
+fr-US >> fr
+
+** test: region distance German
+@supported=de-AT, de-DE, de-CH
+de >> de-DE
+
+** test: en-AU is closer to en-GB than to en (which is en-US)
+@supported=en, en-GB, es-ES, es-419
+en-AU >> en-GB
+@default=es-MX
+es-MX >> es-419
+@default=
+es-PT >> es-ES
+
+@distance=script
+en-AU >> en-GB
+es-MX >> es-419
+@default=
+es-PT >> es-ES
+
+** test: undefined
+@supported=it, fr
+und >> it
+
+** test: und does not match en
+@supported=it, en
+und >> it
+
+** test: undefined in priority list
+@supported=it, und
+und >> und
+en >> it
+
+** test: undefined
+@supported=it, fr, zh
+und-FR >> fr
+und-CN >> zh
+und-Hans >> zh
+und-Hant >> zh
+und-Latn >> it
+
+@distance=script
+und-FR >> fr
+und-CN >> zh
+und-Hans >> zh
+und-Hant >> zh
+und-Latn >> it
+
+** test: match on maximized tag
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja-JP, en-GB >> ja
+ja-Jpan-JP, en-GB >> ja
+
+** test: pick best maximized tag
+@supported=ja, ja-Jpan-US, ja-JP, en, ru
+ja-Jpan, ru >> ja
+ja-JP, ru >> ja-JP
+ja-US, ru >> ja-Jpan-US
+
+@distance=script
+ja-Jpan, ru >> ja
+ja-JP, ru >> ja-JP
+ja-US, ru >> ja-Jpan-US
+
+** test: termination: pick best maximized match
+@supported=ja, ja-Jpan, ja-JP, en, ru
+ja-Jpan-JP, ru >> ja
+ja-Jpan, ru >> ja-Jpan
+
+@distance=script
+ja-Jpan-JP, ru >> ja
+ja-Jpan, ru >> ja-Jpan
+
+** test: same language over exact, but distinguish when user is explicit
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja, de >> ja
+@supported=en, de, fr, ja
+de-CH, fr >> de
+@supported=en-GB, nl
+en, nl >> en-GB
+en, nl, en-GB >> en-GB
+
+@distance=script
+@supported=fr, en-GB, ja, es-ES, es-MX
+ja, de >> ja
+@supported=en, de, fr, ja
+de-CH, fr >> de
+@supported=en-GB, nl
+en, nl >> en-GB
+en, nl, en-GB >> en-GB
+
+** test: parent relation preserved
+@supported=en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh, zh-Hant, zh-Hant-HK
+en-150 >> en-GB
+en-AU >> en-GB
+en-BE >> en-GB
+en-GG >> en-GB
+en-GI >> en-GB
+en-HK >> en-GB
+en-IE >> en-GB
+en-IM >> en-GB
+en-IN >> en-GB
+en-JE >> en-GB
+en-MT >> en-GB
+en-NZ >> en-GB
+en-PK >> en-GB
+en-SG >> en-GB
+en-DE >> en-GB
+@default=es-AR
+es-AR >> es-419
+@default=es-BO
+es-BO >> es-419
+@default=es-CL
+es-CL >> es-419
+@default=es-CO
+es-CO >> es-419
+@default=es-CR
+es-CR >> es-419
+@default=es-CU
+es-CU >> es-419
+@default=es-DO
+es-DO >> es-419
+@default=es-EC
+es-EC >> es-419
+@default=es-GT
+es-GT >> es-419
+@default=es-HN
+es-HN >> es-419
+@default=es-MX
+es-MX >> es-419
+@default=es-NI
+es-NI >> es-419
+@default=es-PA
+es-PA >> es-419
+@default=es-PE
+es-PE >> es-419
+@default=es-PR
+es-PR >> es-419
+@default=
+es-PT >> es
+@default=es-PY
+es-PY >> es-419
+@default=es-SV
+es-SV >> es-419
+@default=
+es-US >> es-419
+@default=es-UY
+es-UY >> es-419
+@default=es-VE
+es-VE >> es-419
+@default=
+pt-AO >> pt-PT
+pt-CV >> pt-PT
+pt-GW >> pt-PT
+pt-MO >> pt-PT
+pt-MZ >> pt-PT
+pt-ST >> pt-PT
+pt-TL >> pt-PT
+
+@distance=script
+en-150 >> en-GB
+en-AU >> en-GB
+en-BE >> en-GB
+en-GG >> en-GB
+en-GI >> en-GB
+en-HK >> en-GB
+en-IE >> en-GB
+en-IM >> en-GB
+en-IN >> en-GB
+en-JE >> en-GB
+en-MT >> en-GB
+en-NZ >> en-GB
+en-PK >> en-GB
+en-SG >> en-GB
+en-DE >> en-GB
+@default=es-AR
+es-AR >> es-419
+@default=es-BO
+es-BO >> es-419
+@default=es-CL
+es-CL >> es-419
+@default=es-CO
+es-CO >> es-419
+@default=es-CR
+es-CR >> es-419
+@default=es-CU
+es-CU >> es-419
+@default=es-DO
+es-DO >> es-419
+@default=es-EC
+es-EC >> es-419
+@default=es-GT
+es-GT >> es-419
+@default=es-HN
+es-HN >> es-419
+@default=es-MX
+es-MX >> es-419
+@default=es-NI
+es-NI >> es-419
+@default=es-PA
+es-PA >> es-419
+@default=es-PE
+es-PE >> es-419
+@default=es-PR
+es-PR >> es-419
+@default=
+es-PT >> es
+@default=es-PY
+es-PY >> es-419
+@default=es-SV
+es-SV >> es-419
+@default=
+es-US >> es-419
+@default=es-UY
+es-UY >> es-419
+@default=es-VE
+es-VE >> es-419
+@default=
+pt-AO >> pt-PT
+pt-CV >> pt-PT
+pt-GW >> pt-PT
+pt-MO >> pt-PT
+pt-MZ >> pt-PT
+pt-ST >> pt-PT
+pt-TL >> pt-PT
+
+** test: preserve extensions
+@supported=en, de, sl-NEDIS
+@default=de-u-co-phonebk
+de-FR-u-co-phonebk >> de
+@default=sl-NEDIS-u-cu-eur
+sl-NEDIS-u-cu-eur >> sl-NEDIS
+sl-u-cu-eur >> sl-NEDIS
+sl-HR-NEDIS-u-cu-eur >> sl-NEDIS
+@default=de-t-m0-iso-i0-pinyin
+de-t-m0-iso-i0-pinyin >> de
+
+@distance=script
+@default=de-u-co-phonebk
+de-FR-u-co-phonebk >> de
+@default=sl-NEDIS-u-cu-eur
+sl-NEDIS-u-cu-eur >> sl-NEDIS
+sl-u-cu-eur >> sl-NEDIS
+sl-HR-NEDIS-u-cu-eur >> sl-NEDIS
+@default=de-t-m0-iso-i0-pinyin
+de-t-m0-iso-i0-pinyin >> de
+
+## ULS
+
+** test: testEmptyUserLanguagesGetsEmpty_getBestMatches
+@supported=de
+ >> de
+
+** test: testNoStrongMatchGetsEmpty_getBestMatches
+@supported=de
+fr >> de
+
+@distance=script
+fr >> de
+
+** test: testLooseMatchForGeneral_getBestMatches
+@supported=es-419
+es-MX >> es-419
+
+@distance=script
+es-MX >> es-419
+
+** test: testLooseMatchForEnglish_getBestMatches
+@supported=en, en-GB
+en-CA >> en-GB
+
+@distance=script
+en-CA >> en-GB
+
+** test: testLooseMatchForChinese_getBestMatches
+@supported=zh
+zh-TW >> zh
+
+@distance=script
+zh-TW >> zh
+
+## Geo
+
+** test: testGetBestMatchWithMinMatchScore
+@supported=fr-FR, fr, fr-CA, en
+@default=und
+fr >> fr # Exact match is chosen.
+@supported=en, fr, fr-CA
+fr-FR >> fr # Parent match is chosen.
+@supported=en, fr-CA
+fr-FR >> fr-CA # Sibling match is chosen.
+@supported=fr-CA, fr-FR
+fr >> fr-FR # Inferred region match is chosen.
+fr-SN >> fr-CA
+@supported=en, fr-FR
+fr >> fr-FR # Child match is chosen.
+@supported=de, en, it
+fr >> und
+@supported=iw, en
+iw-Latn >> und
+@supported=iw, no
+ru >> und
+@supported=iw-Latn, iw-Cyrl, iw
+ru >> und
+@supported=iw, iw-Latn
+ru >> und
+en >> und
+@supported=en, uk
+ru >> und
+@supported=zh-TW, en
+zh-CN >> zh-TW
+@supported=ja
+ru >> und
+
+@distance=script
+@supported=fr-FR, fr, fr-CA, en
+fr >> fr
+@supported=en, fr, fr-CA
+fr-FR >> fr
+@supported=en, fr-CA
+fr-FR >> fr-CA
+@supported=fr-CA, fr-FR
+fr >> fr-FR
+fr-SN >> fr-CA
+@supported=en, fr-FR
+fr >> fr-FR
+@supported=de, en, it
+fr >> de
+@supported=iw, en
+iw-Latn >> en
+@supported=iw, no
+ru >> iw
+@supported=iw-Latn, iw-Cyrl, iw
+ru >> iw-Cyrl
+@supported=iw, iw-Latn
+ru >> iw
+en >> iw-Latn
+@supported=en, uk
+ru >> uk
+@supported=zh-TW, en
+zh-CN >> zh-TW
+@supported=ja
+ru >> ja
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DecimalFormat_ICU58.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DecimalFormat_ICU58.java
new file mode 100644
index 000000000..4d81883d8
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DecimalFormat_ICU58.java
@@ -0,0 +1,6286 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+/*
+ *******************************************************************************
+ * Copyright (C) 1996-2016, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ *******************************************************************************
+ */
+package com.ibm.icu.dev.text;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.ChoiceFormat;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Set;
+
+import com.ibm.icu.impl.ICUConfig;
+import com.ibm.icu.impl.PatternProps;
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.math.BigDecimal;
+import com.ibm.icu.math.MathContext;
+import com.ibm.icu.text.CurrencyPluralInfo;
+import com.ibm.icu.text.DecimalFormatSymbols;
+import com.ibm.icu.text.NumberFormat;
+import com.ibm.icu.text.PluralRules.FixedDecimal;
+import com.ibm.icu.text.UFieldPosition;
+import com.ibm.icu.text.UTF16;
+import com.ibm.icu.text.UnicodeSet;
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.Currency.CurrencyUsage;
+import com.ibm.icu.util.CurrencyAmount;
+import com.ibm.icu.util.ULocale;
+import com.ibm.icu.util.ULocale.Category;
+
+/**
+ * {@icuenhanced java.text.DecimalFormat}.{@icu _usage_}
+ *
+ * <code>DecimalFormat</code> is a concrete subclass of {@link NumberFormat} that formats
+ * decimal numbers. It has a variety of features designed to make it possible to parse and
+ * format numbers in any locale, including support for Western, Arabic, or Indic digits.
+ * It also supports different flavors of numbers, including integers ("123"), fixed-point
+ * numbers ("123.4"), scientific notation ("1.23E4"), percentages ("12%"), and currency
+ * amounts ("$123.00", "USD123.00", "123.00 US dollars"). All of these flavors can be
+ * easily localized.
+ *
+ * <p>To obtain a {@link NumberFormat} for a specific locale (including the default
+ * locale) call one of <code>NumberFormat</code>'s factory methods such as {@link
+ * NumberFormat#getInstance}. Do not call the <code>DecimalFormat</code> constructors
+ * directly, unless you know what you are doing, since the {@link NumberFormat} factory
+ * methods may return subclasses other than <code>DecimalFormat</code>. If you need to
+ * customize the format object, do something like this:
+ *
+ * <blockquote><pre>
+ * NumberFormat f = NumberFormat.getInstance(loc);
+ * if (f instanceof DecimalFormat) {
+ * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
+ * }</pre></blockquote>
+ *
+ * <p><strong>Example Usage</strong>
+ *
+ * Print out a number using the localized number, currency, and percent
+ * format for each locale.
+ *
+ * <blockquote><pre>
+ * Locale[] locales = NumberFormat.getAvailableLocales();
+ * double myNumber = -1234.56;
+ * NumberFormat format;
+ * for (int j=0; j&lt;3; ++j) {
+ * System.out.println("FORMAT");
+ * for (int i = 0; i &lt; locales.length; ++i) {
+ * if (locales[i].getCountry().length() == 0) {
+ * // Skip language-only locales
+ * continue;
+ * }
+ * System.out.print(locales[i].getDisplayName());
+ * switch (j) {
+ * case 0:
+ * format = NumberFormat.getInstance(locales[i]); break;
+ * case 1:
+ * format = NumberFormat.getCurrencyInstance(locales[i]); break;
+ * default:
+ * format = NumberFormat.getPercentInstance(locales[i]); break;
+ * }
+ * try {
+ * // Assume format is a DecimalFormat
+ * System.out.print(": " + ((DecimalFormat) format).toPattern()
+ * + " -&gt; " + form.format(myNumber));
+ * } catch (Exception e) {}
+ * try {
+ * System.out.println(" -&gt; " + format.parse(form.format(myNumber)));
+ * } catch (ParseException e) {}
+ * }
+ * }</pre></blockquote>
+ *
+ * <p>Another example use getInstance(style).<br>
+ * Print out a number using the localized number, currency, percent,
+ * scientific, integer, iso currency, and plural currency format for each locale.
+ *
+ * <blockquote><pre>
+ * ULocale locale = new ULocale("en_US");
+ * double myNumber = 1234.56;
+ * for (int j=NumberFormat.NUMBERSTYLE; j&lt;=NumberFormat.PLURALCURRENCYSTYLE; ++j) {
+ * NumberFormat format = NumberFormat.getInstance(locale, j);
+ * try {
+ * // Assume format is a DecimalFormat
+ * System.out.print(": " + ((DecimalFormat) format).toPattern()
+ * + " -&gt; " + form.format(myNumber));
+ * } catch (Exception e) {}
+ * try {
+ * System.out.println(" -&gt; " + format.parse(form.format(myNumber)));
+ * } catch (ParseException e) {}
+ * }</pre></blockquote>
+ *
+ * <h3>Patterns</h3>
+ *
+ * <p>A <code>DecimalFormat</code> consists of a <em>pattern</em> and a set of
+ * <em>symbols</em>. The pattern may be set directly using {@link #applyPattern}, or
+ * indirectly using other API methods which manipulate aspects of the pattern, such as the
+ * minimum number of integer digits. The symbols are stored in a {@link
+ * DecimalFormatSymbols} object. When using the {@link NumberFormat} factory methods, the
+ * pattern and symbols are read from ICU's locale data.
+ *
+ * <h4>Special Pattern Characters</h4>
+ *
+ * <p>Many characters in a pattern are taken literally; they are matched during parsing
+ * and output unchanged during formatting. Special characters, on the other hand, stand
+ * for other characters, strings, or classes of characters. For example, the '#'
+ * character is replaced by a localized digit. Often the replacement character is the
+ * same as the pattern character; in the U.S. locale, the ',' grouping character is
+ * replaced by ','. However, the replacement is still happening, and if the symbols are
+ * modified, the grouping character changes. Some special characters affect the behavior
+ * of the formatter by their presence; for example, if the percent character is seen, then
+ * the value is multiplied by 100 before being displayed.
+ *
+ * <p>To insert a special character in a pattern as a literal, that is, without any
+ * special meaning, the character must be quoted. There are some exceptions to this which
+ * are noted below.
+ *
+ * <p>The characters listed here are used in non-localized patterns. Localized patterns
+ * use the corresponding characters taken from this formatter's {@link
+ * DecimalFormatSymbols} object instead, and these characters lose their special status.
+ * Two exceptions are the currency sign and quote, which are not localized.
+ *
+ * <blockquote>
+ * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
+ * location, localized, and meaning.">
+ * <tr style="background-color: #ccccff">
+ * <th align=left>Symbol
+ * <th align=left>Location
+ * <th align=left>Localized?
+ * <th align=left>Meaning
+ * <tr style="vertical-align: top;">
+ * <td><code>0</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Digit
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>1-9</code>
+ * <td>Number
+ * <td>Yes
+ * <td>'1' through '9' indicate rounding.
+ * <tr style="vertical-align: top;">
+ * <td><code>@</code>
+ * <td>Number
+ * <td>No
+ * <td>Significant digit
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>#</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Digit, zero shows as absent
+ * <tr style="vertical-align: top;">
+ * <td><code>.</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Decimal separator or monetary decimal separator
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>-</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Minus sign
+ * <tr style="vertical-align: top;">
+ * <td><code>,</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Grouping separator
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>E</code>
+ * <td>Number
+ * <td>Yes
+ * <td>Separates mantissa and exponent in scientific notation.
+ * <em>Need not be quoted in prefix or suffix.</em>
+ * <tr style="vertical-align: top;">
+ * <td><code>+</code>
+ * <td>Exponent
+ * <td>Yes
+ * <td>Prefix positive exponents with localized plus sign.
+ * <em>Need not be quoted in prefix or suffix.</em>
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>;</code>
+ * <td>Subpattern boundary
+ * <td>Yes
+ * <td>Separates positive and negative subpatterns
+ * <tr style="vertical-align: top;">
+ * <td><code>%</code>
+ * <td>Prefix or suffix
+ * <td>Yes
+ * <td>Multiply by 100 and show as percentage
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>&#92;u2030</code>
+ * <td>Prefix or suffix
+ * <td>Yes
+ * <td>Multiply by 1000 and show as per mille
+ * <tr style="vertical-align: top;">
+ * <td><code>&#164;</code> (<code>&#92;u00A4</code>)
+ * <td>Prefix or suffix
+ * <td>No
+ * <td>Currency sign, replaced by currency symbol. If
+ * doubled, replaced by international currency symbol.
+ * If tripled, replaced by currency plural names, for example,
+ * "US dollar" or "US dollars" for America.
+ * If present in a pattern, the monetary decimal separator
+ * is used instead of the decimal separator.
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>'</code>
+ * <td>Prefix or suffix
+ * <td>No
+ * <td>Used to quote special characters in a prefix or suffix,
+ * for example, <code>"'#'#"</code> formats 123 to
+ * <code>"#123"</code>. To create a single quote
+ * itself, use two in a row: <code>"# o''clock"</code>.
+ * <tr style="vertical-align: top;">
+ * <td><code>*</code>
+ * <td>Prefix or suffix boundary
+ * <td>Yes
+ * <td>Pad escape, precedes pad character
+ * </table>
+ * </blockquote>
+ *
+ * <p>A <code>DecimalFormat</code> pattern contains a postive and negative subpattern, for
+ * example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric part, and a
+ * suffix. If there is no explicit negative subpattern, the negative subpattern is the
+ * localized minus sign prefixed to the positive subpattern. That is, "0.00" alone is
+ * equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves
+ * only to specify the negative prefix and suffix; the number of digits, minimal digits,
+ * and other characteristics are ignored in the negative subpattern. That means that
+ * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".
+ *
+ * <p>The prefixes, suffixes, and various symbols used for infinity, digits, thousands
+ * separators, decimal separators, etc. may be set to arbitrary values, and they will
+ * appear properly during formatting. However, care must be taken that the symbols and
+ * strings do not conflict, or parsing will be unreliable. For example, either the
+ * positive and negative prefixes or the suffixes must be distinct for {@link #parse} to
+ * be able to distinguish positive from negative values. Another example is that the
+ * decimal separator and thousands separator should be distinct characters, or parsing
+ * will be impossible.
+ *
+ * <p>The <em>grouping separator</em> is a character that separates clusters of integer
+ * digits to make large numbers more legible. It commonly used for thousands, but in some
+ * locales it separates ten-thousands. The <em>grouping size</em> is the number of digits
+ * between the grouping separators, such as 3 for "100,000,000" or 4 for "1 0000
+ * 0000". There are actually two different grouping sizes: One used for the least
+ * significant integer digits, the <em>primary grouping size</em>, and one used for all
+ * others, the <em>secondary grouping size</em>. In most locales these are the same, but
+ * sometimes they are different. For example, if the primary grouping interval is 3, and
+ * the secondary is 2, then this corresponds to the pattern "#,##,##0", and the number
+ * 123456789 is formatted as "12,34,56,789". If a pattern contains multiple grouping
+ * separators, the interval between the last one and the end of the integer defines the
+ * primary grouping size, and the interval between the last two defines the secondary
+ * grouping size. All others are ignored, so "#,##,###,####" == "###,###,####" ==
+ * "##,#,###,####".
+ *
+ * <p>Illegal patterns, such as "#.#.#" or "#.###,###", will cause
+ * <code>DecimalFormat</code> to throw an {@link IllegalArgumentException} with a message
+ * that describes the problem.
+ *
+ * <h4>Pattern BNF</h4>
+ *
+ * <pre>
+ * pattern := subpattern (';' subpattern)?
+ * subpattern := prefix? number exponent? suffix?
+ * number := (integer ('.' fraction)?) | sigDigits
+ * prefix := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
+ * suffix := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
+ * integer := '#'* '0'* '0'
+ * fraction := '0'* '#'*
+ * sigDigits := '#'* '@' '@'* '#'*
+ * exponent := 'E' '+'? '0'* '0'
+ * padSpec := '*' padChar
+ * padChar := '&#92;u0000'..'&#92;uFFFD' - quote
+ * &#32;
+ * Notation:
+ * X* 0 or more instances of X
+ * X? 0 or 1 instances of X
+ * X|Y either X or Y
+ * C..D any character from C up to D, inclusive
+ * S-T characters in S, except those in T
+ * </pre>
+ * The first subpattern is for positive numbers. The second (optional)
+ * subpattern is for negative numbers.
+ *
+ * <p>Not indicated in the BNF syntax above:
+ *
+ * <ul>
+ *
+ * <li>The grouping separator ',' can occur inside the integer and sigDigits
+ * elements, between any two pattern characters of that element, as long as the integer or
+ * sigDigits element is not followed by the exponent element.
+ *
+ * <li>Two grouping intervals are recognized: That between the decimal point and the first
+ * grouping symbol, and that between the first and second grouping symbols. These
+ * intervals are identical in most locales, but in some locales they differ. For example,
+ * the pattern &quot;#,##,###&quot; formats the number 123456789 as
+ * &quot;12,34,56,789&quot;.
+ *
+ * <li>The pad specifier <code>padSpec</code> may appear before the prefix, after the
+ * prefix, before the suffix, after the suffix, or not at all.
+ *
+ * <li>In place of '0', the digits '1' through '9' may be used to indicate a rounding
+ * increment.
+ *
+ * </ul>
+ *
+ * <h4>Parsing</h4>
+ *
+ * <p><code>DecimalFormat</code> parses all Unicode characters that represent decimal
+ * digits, as defined by {@link UCharacter#digit}. In addition,
+ * <code>DecimalFormat</code> also recognizes as digits the ten consecutive characters
+ * starting with the localized zero digit defined in the {@link DecimalFormatSymbols}
+ * object. During formatting, the {@link DecimalFormatSymbols}-based digits are output.
+ *
+ * <p>During parsing, grouping separators are ignored.
+ *
+ * <p>For currency parsing, the formatter is able to parse every currency style formats no
+ * matter which style the formatter is constructed with. For example, a formatter
+ * instance gotten from NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can
+ * parse formats such as "USD1.00" and "3.00 US dollars".
+ *
+ * <p>If {@link #parse(String, ParsePosition)} fails to parse a string, it returns
+ * <code>null</code> and leaves the parse position unchanged. The convenience method
+ * {@link #parse(String)} indicates parse failure by throwing a {@link
+ * java.text.ParseException}.
+ *
+ * <p>Parsing an extremely large or small absolute value (such as 1.0E10000 or 1.0E-10000)
+ * requires huge memory allocation for representing the parsed number. Such input may expose
+ * a risk of DoS attacks. To prevent huge memory allocation triggered by such inputs,
+ * <code>DecimalFormat</code> internally limits of maximum decimal digits to be 1000. Thus,
+ * an input string resulting more than 1000 digits in plain decimal representation (non-exponent)
+ * will be treated as either overflow (positive/negative infinite) or underflow (+0.0/-0.0).
+ *
+ * <h4>Formatting</h4>
+ *
+ * <p>Formatting is guided by several parameters, all of which can be specified either
+ * using a pattern or using the API. The following description applies to formats that do
+ * not use <a href="#sci">scientific notation</a> or <a href="#sigdig">significant
+ * digits</a>.
+ *
+ * <ul><li>If the number of actual integer digits exceeds the <em>maximum integer
+ * digits</em>, then only the least significant digits are shown. For example, 1997 is
+ * formatted as "97" if the maximum integer digits is set to 2.
+ *
+ * <li>If the number of actual integer digits is less than the <em>minimum integer
+ * digits</em>, then leading zeros are added. For example, 1997 is formatted as "01997"
+ * if the minimum integer digits is set to 5.
+ *
+ * <li>If the number of actual fraction digits exceeds the <em>maximum fraction
+ * digits</em>, then half-even rounding it performed to the maximum fraction digits. For
+ * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2. This
+ * behavior can be changed by specifying a rounding increment and a rounding mode.
+ *
+ * <li>If the number of actual fraction digits is less than the <em>minimum fraction
+ * digits</em>, then trailing zeros are added. For example, 0.125 is formatted as
+ * "0.1250" if the mimimum fraction digits is set to 4.
+ *
+ * <li>Trailing fractional zeros are not displayed if they occur <em>j</em> positions
+ * after the decimal, where <em>j</em> is less than the maximum fraction digits. For
+ * example, 0.10004 is formatted as "0.1" if the maximum fraction digits is four or less.
+ * </ul>
+ *
+ * <p><strong>Special Values</strong>
+ *
+ * <p><code>NaN</code> is represented as a single character, typically
+ * <code>&#92;uFFFD</code>. This character is determined by the {@link
+ * DecimalFormatSymbols} object. This is the only value for which the prefixes and
+ * suffixes are not used.
+ *
+ * <p>Infinity is represented as a single character, typically <code>&#92;u221E</code>,
+ * with the positive or negative prefixes and suffixes applied. The infinity character is
+ * determined by the {@link DecimalFormatSymbols} object.
+ *
+ * <h4><a name="sci">Scientific Notation</a></h4>
+ *
+ * <p>Numbers in scientific notation are expressed as the product of a mantissa and a
+ * power of ten, for example, 1234 can be expressed as 1.234 x 10<sup>3</sup>. The
+ * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0),
+ * but it need not be. <code>DecimalFormat</code> supports arbitrary mantissas.
+ * <code>DecimalFormat</code> can be instructed to use scientific notation through the API
+ * or through the pattern. In a pattern, the exponent character immediately followed by
+ * one or more digit characters indicates scientific notation. Example: "0.###E0" formats
+ * the number 1234 as "1.234E3".
+ *
+ * <ul>
+ *
+ * <li>The number of digit characters after the exponent character gives the minimum
+ * exponent digit count. There is no maximum. Negative exponents are formatted using the
+ * localized minus sign, <em>not</em> the prefix and suffix from the pattern. This allows
+ * patterns such as "0.###E0 m/s". To prefix positive exponents with a localized plus
+ * sign, specify '+' between the exponent and the digits: "0.###E+0" will produce formats
+ * "1E+1", "1E+0", "1E-1", etc. (In localized patterns, use the localized plus sign
+ * rather than '+'.)
+ *
+ * <li>The minimum number of integer digits is achieved by adjusting the exponent.
+ * Example: 0.00123 formatted with "00.###E0" yields "12.3E-4". This only happens if
+ * there is no maximum number of integer digits. If there is a maximum, then the minimum
+ * number of integer digits is fixed at one.
+ *
+ * <li>The maximum number of integer digits, if present, specifies the exponent grouping.
+ * The most common use of this is to generate <em>engineering notation</em>, in which the
+ * exponent is a multiple of three, e.g., "##0.###E0". The number 12345 is formatted
+ * using "##0.####E0" as "12.345E3".
+ *
+ * <li>When using scientific notation, the formatter controls the digit counts using
+ * significant digits logic. The maximum number of significant digits limits the total
+ * number of integer and fraction digits that will be shown in the mantissa; it does not
+ * affect parsing. For example, 12345 formatted with "##0.##E0" is "12.3E3". See the
+ * section on significant digits for more details.
+ *
+ * <li>The number of significant digits shown is determined as follows: If
+ * areSignificantDigitsUsed() returns false, then the minimum number of significant digits
+ * shown is one, and the maximum number of significant digits shown is the sum of the
+ * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is unaffected by the
+ * maximum integer digits. If this sum is zero, then all significant digits are shown.
+ * If areSignificantDigitsUsed() returns true, then the significant digit counts are
+ * specified by getMinimumSignificantDigits() and getMaximumSignificantDigits(). In this
+ * case, the number of integer digits is fixed at one, and there is no exponent grouping.
+ *
+ * <li>Exponential patterns may not contain grouping separators.
+ *
+ * </ul>
+ *
+ * <h4><a name="sigdig">Significant Digits</a></h4>
+ *
+ * <code>DecimalFormat</code> has two ways of controlling how many digits are shows: (a)
+ * significant digits counts, or (b) integer and fraction digit counts. Integer and
+ * fraction digit counts are described above. When a formatter is using significant
+ * digits counts, the number of integer and fraction digits is not specified directly, and
+ * the formatter settings for these counts are ignored. Instead, the formatter uses
+ * however many integer and fraction digits are required to display the specified number
+ * of significant digits. Examples:
+ *
+ * <blockquote>
+ * <table border=0 cellspacing=3 cellpadding=0>
+ * <tr style="background-color: #ccccff">
+ * <th align=left>Pattern
+ * <th align=left>Minimum significant digits
+ * <th align=left>Maximum significant digits
+ * <th align=left>Number
+ * <th align=left>Output of format()
+ * <tr style="vertical-align: top;">
+ * <td><code>@@@</code>
+ * <td>3
+ * <td>3
+ * <td>12345
+ * <td><code>12300</code>
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>@@@</code>
+ * <td>3
+ * <td>3
+ * <td>0.12345
+ * <td><code>0.123</code>
+ * <tr style="vertical-align: top;">
+ * <td><code>@@##</code>
+ * <td>2
+ * <td>4
+ * <td>3.14159
+ * <td><code>3.142</code>
+ * <tr style="vertical-align: top; background-color: #eeeeff;">
+ * <td><code>@@##</code>
+ * <td>2
+ * <td>4
+ * <td>1.23004
+ * <td><code>1.23</code>
+ * </table>
+ * </blockquote>
+ *
+ * <ul>
+ *
+ * <li>Significant digit counts may be expressed using patterns that specify a minimum and
+ * maximum number of significant digits. These are indicated by the <code>'@'</code> and
+ * <code>'#'</code> characters. The minimum number of significant digits is the number of
+ * <code>'@'</code> characters. The maximum number of significant digits is the number of
+ * <code>'@'</code> characters plus the number of <code>'#'</code> characters following on
+ * the right. For example, the pattern <code>"@@@"</code> indicates exactly 3 significant
+ * digits. The pattern <code>"@##"</code> indicates from 1 to 3 significant digits.
+ * Trailing zero digits to the right of the decimal separator are suppressed after the
+ * minimum number of significant digits have been shown. For example, the pattern
+ * <code>"@##"</code> formats the number 0.1203 as <code>"0.12"</code>.
+ *
+ * <li>If a pattern uses significant digits, it may not contain a decimal separator, nor
+ * the <code>'0'</code> pattern character. Patterns such as <code>"@00"</code> or
+ * <code>"@.###"</code> are disallowed.
+ *
+ * <li>Any number of <code>'#'</code> characters may be prepended to the left of the
+ * leftmost <code>'@'</code> character. These have no effect on the minimum and maximum
+ * significant digits counts, but may be used to position grouping separators. For
+ * example, <code>"#,#@#"</code> indicates a minimum of one significant digits, a maximum
+ * of two significant digits, and a grouping size of three.
+ *
+ * <li>In order to enable significant digits formatting, use a pattern containing the
+ * <code>'@'</code> pattern character. Alternatively, call {@link
+ * #setSignificantDigitsUsed setSignificantDigitsUsed(true)}.
+ *
+ * <li>In order to disable significant digits formatting, use a pattern that does not
+ * contain the <code>'@'</code> pattern character. Alternatively, call {@link
+ * #setSignificantDigitsUsed setSignificantDigitsUsed(false)}.
+ *
+ * <li>The number of significant digits has no effect on parsing.
+ *
+ * <li>Significant digits may be used together with exponential notation. Such patterns
+ * are equivalent to a normal exponential pattern with a minimum and maximum integer digit
+ * count of one, a minimum fraction digit count of <code>getMinimumSignificantDigits() -
+ * 1</code>, and a maximum fraction digit count of <code>getMaximumSignificantDigits() -
+ * 1</code>. For example, the pattern <code>"@@###E0"</code> is equivalent to
+ * <code>"0.0###E0"</code>.
+ *
+ * <li>If signficant digits are in use, then the integer and fraction digit counts, as set
+ * via the API, are ignored. If significant digits are not in use, then the signficant
+ * digit counts, as set via the API, are ignored.
+ *
+ * </ul>
+ *
+ * <h4>Padding</h4>
+ *
+ * <p><code>DecimalFormat</code> supports padding the result of {@link #format} to a
+ * specific width. Padding may be specified either through the API or through the pattern
+ * syntax. In a pattern the pad escape character, followed by a single pad character,
+ * causes padding to be parsed and formatted. The pad escape character is '*' in
+ * unlocalized patterns, and can be localized using {@link
+ * DecimalFormatSymbols#setPadEscape}. For example, <code>"$*x#,##0.00"</code> formats
+ * 123 to <code>"$xx123.00"</code>, and 1234 to <code>"$1,234.00"</code>.
+ *
+ * <ul>
+ *
+ * <li>When padding is in effect, the width of the positive subpattern, including prefix
+ * and suffix, determines the format width. For example, in the pattern <code>"* #0
+ * o''clock"</code>, the format width is 10.
+ *
+ * <li>The width is counted in 16-bit code units (Java <code>char</code>s).
+ *
+ * <li>Some parameters which usually do not matter have meaning when padding is used,
+ * because the pattern width is significant with padding. In the pattern "*
+ * ##,##,#,##0.##", the format width is 14. The initial characters "##,##," do not affect
+ * the grouping size or maximum integer digits, but they do affect the format width.
+ *
+ * <li>Padding may be inserted at one of four locations: before the prefix, after the
+ * prefix, before the suffix, or after the suffix. If padding is specified in any other
+ * location, {@link #applyPattern} throws an {@link IllegalArgumentException}. If there
+ * is no prefix, before the prefix and after the prefix are equivalent, likewise for the
+ * suffix.
+ *
+ * <li>When specified in a pattern, the 16-bit <code>char</code> immediately following the
+ * pad escape is the pad character. This may be any character, including a special pattern
+ * character. That is, the pad escape <em>escapes</em> the following character. If there
+ * is no character after the pad escape, then the pattern is illegal.
+ *
+ * </ul>
+ *
+ * <p>
+ * <strong>Rounding</strong>
+ *
+ * <p><code>DecimalFormat</code> supports rounding to a specific increment. For example,
+ * 1230 rounded to the nearest 50 is 1250. 1.234 rounded to the nearest 0.65 is 1.3. The
+ * rounding increment may be specified through the API or in a pattern. To specify a
+ * rounding increment in a pattern, include the increment in the pattern itself. "#,#50"
+ * specifies a rounding increment of 50. "#,##0.05" specifies a rounding increment of
+ * 0.05.
+ *
+ * <ul>
+ *
+ * <li>Rounding only affects the string produced by formatting. It does not affect
+ * parsing or change any numerical values.
+ *
+ * <li>A <em>rounding mode</em> determines how values are rounded; see the {@link
+ * com.ibm.icu.math.BigDecimal} documentation for a description of the modes. Rounding
+ * increments specified in patterns use the default mode, {@link
+ * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}.
+ *
+ * <li>Some locales use rounding in their currency formats to reflect the smallest
+ * currency denomination.
+ *
+ * <li>In a pattern, digits '1' through '9' specify rounding, but otherwise behave
+ * identically to digit '0'.
+ *
+ * </ul>
+ *
+ * <h4>Synchronization</h4>
+ *
+ * <p><code>DecimalFormat</code> objects are not synchronized. Multiple threads should
+ * not access one formatter concurrently.
+ *
+ * @see java.text.Format
+ * @see NumberFormat
+ * @author Mark Davis
+ * @author Alan Liu
+ * @deprecated DecimalFormat was overhauled in ICU 59. This is the old implementation, provided
+ * temporarily to ease the transition. This class will be removed from ICU 60.
+ */
+@Deprecated
+public class DecimalFormat_ICU58 extends NumberFormat {
+
+ /**
+ * Creates a DecimalFormat using the default pattern and symbols for the default
+ * <code>FORMAT</code> locale. This is a convenient way to obtain a DecimalFormat when
+ * internationalization is not the main concern.
+ *
+ * <p>To obtain standard formats for a given locale, use the factory methods on
+ * NumberFormat such as getNumberInstance. These factories will return the most
+ * appropriate sub-class of NumberFormat for a given locale.
+ *
+ * @see NumberFormat#getInstance
+ * @see NumberFormat#getNumberInstance
+ * @see NumberFormat#getCurrencyInstance
+ * @see NumberFormat#getPercentInstance
+ * @see Category#FORMAT
+ * @stable ICU 2.0
+ */
+ public DecimalFormat_ICU58() {
+ ULocale def = ULocale.getDefault(Category.FORMAT);
+ String pattern = getPattern(def, 0);
+ // Always applyPattern after the symbols are set
+ this.symbols = new DecimalFormatSymbols(def);
+ setCurrency(Currency.getInstance(def));
+ applyPatternWithoutExpandAffix(pattern, false);
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ currencyPluralInfo = new CurrencyPluralInfo(def);
+ // the exact pattern is not known until the plural count is known.
+ // so, no need to expand affix now.
+ } else {
+ expandAffixAdjustWidth(null);
+ }
+ }
+
+ /**
+ * Creates a DecimalFormat from the given pattern and the symbols for the default
+ * <code>FORMAT</code> locale. This is a convenient way to obtain a DecimalFormat when
+ * internationalization is not the main concern.
+ *
+ * <p>To obtain standard formats for a given locale, use the factory methods on
+ * NumberFormat such as getNumberInstance. These factories will return the most
+ * appropriate sub-class of NumberFormat for a given locale.
+ *
+ * @param pattern A non-localized pattern string.
+ * @throws IllegalArgumentException if the given pattern is invalid.
+ * @see NumberFormat#getInstance
+ * @see NumberFormat#getNumberInstance
+ * @see NumberFormat#getCurrencyInstance
+ * @see NumberFormat#getPercentInstance
+ * @see Category#FORMAT
+ * @stable ICU 2.0
+ */
+ public DecimalFormat_ICU58(String pattern) {
+ // Always applyPattern after the symbols are set
+ ULocale def = ULocale.getDefault(Category.FORMAT);
+ this.symbols = new DecimalFormatSymbols(def);
+ setCurrency(Currency.getInstance(def));
+ applyPatternWithoutExpandAffix(pattern, false);
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ currencyPluralInfo = new CurrencyPluralInfo(def);
+ } else {
+ expandAffixAdjustWidth(null);
+ }
+ }
+
+ /**
+ * Creates a DecimalFormat from the given pattern and symbols. Use this constructor
+ * when you need to completely customize the behavior of the format.
+ *
+ * <p>To obtain standard formats for a given locale, use the factory methods on
+ * NumberFormat such as getInstance or getCurrencyInstance. If you need only minor
+ * adjustments to a standard format, you can modify the format returned by a
+ * NumberFormat factory method.
+ *
+ * @param pattern a non-localized pattern string
+ * @param symbols the set of symbols to be used
+ * @exception IllegalArgumentException if the given pattern is invalid
+ * @see NumberFormat#getInstance
+ * @see NumberFormat#getNumberInstance
+ * @see NumberFormat#getCurrencyInstance
+ * @see NumberFormat#getPercentInstance
+ * @see DecimalFormatSymbols
+ * @stable ICU 2.0
+ */
+ public DecimalFormat_ICU58(String pattern, DecimalFormatSymbols symbols) {
+ createFromPatternAndSymbols(pattern, symbols);
+ }
+
+ private void createFromPatternAndSymbols(String pattern, DecimalFormatSymbols inputSymbols) {
+ // Always applyPattern after the symbols are set
+ symbols = (DecimalFormatSymbols) inputSymbols.clone();
+ if (pattern.indexOf(CURRENCY_SIGN) >= 0) {
+ // Only spend time with currency symbols when we're going to display it.
+ // Also set some defaults before the apply pattern.
+ setCurrencyForSymbols();
+ }
+ applyPatternWithoutExpandAffix(pattern, false);
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ currencyPluralInfo = new CurrencyPluralInfo(symbols.getULocale());
+ } else {
+ expandAffixAdjustWidth(null);
+ }
+ }
+
+ /**
+ * Creates a DecimalFormat from the given pattern, symbols, information used for
+ * currency plural format, and format style. Use this constructor when you need to
+ * completely customize the behavior of the format.
+ *
+ * <p>To obtain standard formats for a given locale, use the factory methods on
+ * NumberFormat such as getInstance or getCurrencyInstance.
+ *
+ * <p>If you need only minor adjustments to a standard format, you can modify the
+ * format returned by a NumberFormat factory method using the setters.
+ *
+ * <p>If you want to completely customize a decimal format, using your own
+ * DecimalFormatSymbols (such as group separators) and your own information for
+ * currency plural formatting (such as plural rule and currency plural patterns), you
+ * can use this constructor.
+ *
+ * @param pattern a non-localized pattern string
+ * @param symbols the set of symbols to be used
+ * @param infoInput the information used for currency plural format, including
+ * currency plural patterns and plural rules.
+ * @param style the decimal formatting style, it is one of the following values:
+ * NumberFormat.NUMBERSTYLE; NumberFormat.CURRENCYSTYLE; NumberFormat.PERCENTSTYLE;
+ * NumberFormat.SCIENTIFICSTYLE; NumberFormat.INTEGERSTYLE;
+ * NumberFormat.ISOCURRENCYSTYLE; NumberFormat.PLURALCURRENCYSTYLE;
+ * @stable ICU 4.2
+ */
+ public DecimalFormat_ICU58(String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput,
+ int style) {
+ CurrencyPluralInfo info = infoInput;
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ info = (CurrencyPluralInfo) infoInput.clone();
+ }
+ create(pattern, symbols, info, style);
+ }
+
+ private void create(String pattern, DecimalFormatSymbols inputSymbols, CurrencyPluralInfo info,
+ int inputStyle) {
+ if (inputStyle != NumberFormat.PLURALCURRENCYSTYLE) {
+ createFromPatternAndSymbols(pattern, inputSymbols);
+ } else {
+ // Always applyPattern after the symbols are set
+ symbols = (DecimalFormatSymbols) inputSymbols.clone();
+ currencyPluralInfo = info;
+ // the pattern used in format is not fixed until formatting, in which, the
+ // number is known and will be used to pick the right pattern based on plural
+ // count. Here, set the pattern as the pattern of plural count == "other".
+ // For most locale, the patterns are probably the same for all plural
+ // count. If not, the right pattern need to be re-applied during format.
+ String currencyPluralPatternForOther =
+ currencyPluralInfo.getCurrencyPluralPattern("other");
+ applyPatternWithoutExpandAffix(currencyPluralPatternForOther, false);
+ setCurrencyForSymbols();
+ }
+ style = inputStyle;
+ }
+
+ /**
+ * Creates a DecimalFormat for currency plural format from the given pattern, symbols,
+ * and style.
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ public DecimalFormat_ICU58(String pattern, DecimalFormatSymbols inputSymbols, int style) {
+ CurrencyPluralInfo info = null;
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ info = new CurrencyPluralInfo(inputSymbols.getULocale());
+ }
+ create(pattern, inputSymbols, info, style);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @stable ICU 2.0
+ */
+ @Override
+ public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
+ return format(number, result, fieldPosition, false);
+ }
+
+ // See if number is negative.
+ // usage: isNegative(multiply(numberToBeFormatted));
+ private boolean isNegative(double number) {
+ // Detecting whether a double is negative is easy with the exception of the value
+ // -0.0. This is a double which has a zero mantissa (and exponent), but a negative
+ // sign bit. It is semantically distinct from a zero with a positive sign bit, and
+ // this distinction is important to certain kinds of computations. However, it's a
+ // little tricky to detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you
+ // may ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
+ // -Infinity. Proper detection of -0.0 is needed to deal with the issues raised by
+ // bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
+ return (number < 0.0) || (number == 0.0 && 1 / number < 0.0);
+ }
+
+ // Rounds the number and strips of the negative sign.
+ // usage: round(multiply(numberToBeFormatted))
+ private double round(double number) {
+ boolean isNegative = isNegative(number);
+ if (isNegative)
+ number = -number;
+
+ // Apply rounding after multiplier
+ if (roundingDouble > 0.0) {
+ // number = roundingDouble
+ // * round(number / roundingDouble, roundingMode, isNegative);
+ return round(
+ number, roundingDouble, roundingDoubleReciprocal, roundingMode,
+ isNegative);
+ }
+ return number;
+ }
+
+ // Multiplies given number by multipler (if there is one) returning the new
+ // number. If there is no multiplier, returns the number passed in unchanged.
+ private double multiply(double number) {
+ if (multiplier != 1) {
+ return number * multiplier;
+ }
+ return number;
+ }
+
+ // [Spark/CDL] The actual method to format number. If boolean value
+ // parseAttr == true, then attribute information will be recorded.
+ private StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition,
+ boolean parseAttr) {
+ fieldPosition.setBeginIndex(0);
+ fieldPosition.setEndIndex(0);
+
+ if (Double.isNaN(number)) {
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setBeginIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+
+ result.append(symbols.getNaN());
+ // TODO: Combine setting a single FieldPosition or adding to an AttributedCharacterIterator
+ // into a function like recordAttribute(FieldAttribute, begin, end).
+
+ // [Spark/CDL] Add attribute for NaN here.
+ // result.append(symbols.getNaN());
+ if (parseAttr) {
+ addAttribute(Field.INTEGER, result.length() - symbols.getNaN().length(),
+ result.length());
+ }
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setEndIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setEndIndex(result.length());
+ }
+
+ addPadding(result, fieldPosition, 0, 0);
+ return result;
+ }
+
+ // Do this BEFORE checking to see if value is negative or infinite and
+ // before rounding.
+ number = multiply(number);
+ boolean isNegative = isNegative(number);
+ number = round(number);
+
+ if (Double.isInfinite(number)) {
+ int prefixLen = appendAffix(result, isNegative, true, fieldPosition, parseAttr);
+
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setBeginIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+
+ // [Spark/CDL] Add attribute for infinity here.
+ result.append(symbols.getInfinity());
+ if (parseAttr) {
+ addAttribute(Field.INTEGER, result.length() - symbols.getInfinity().length(),
+ result.length());
+ }
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setEndIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setEndIndex(result.length());
+ }
+
+ int suffixLen = appendAffix(result, isNegative, false, fieldPosition, parseAttr);
+
+ addPadding(result, fieldPosition, prefixLen, suffixLen);
+ return result;
+ }
+
+ int precision = precision(false);
+
+ // This is to fix rounding for scientific notation. See ticket:10542.
+ // This code should go away when a permanent fix is done for ticket:9931.
+ //
+ // This block of code only executes for scientific notation so it will not interfere with the
+ // previous fix in {@link #resetActualRounding} for fixed decimal numbers.
+ // Moreover this code only runs when there is rounding to be done (precision > 0) and when the
+ // rounding mode is something other than ROUND_HALF_EVEN.
+ // This block of code does the correct rounding of number in advance so that it will fit into
+ // the number of digits indicated by precision. In this way, we avoid using the default
+ // ROUND_HALF_EVEN behavior of DigitList. For example, if number = 0.003016 and roundingMode =
+ // ROUND_DOWN and precision = 3 then after this code executes, number = 0.00301 (3 significant digits)
+ if (useExponentialNotation && precision > 0 && number != 0.0 && roundingMode != BigDecimal.ROUND_HALF_EVEN) {
+ int log10RoundingIncr = 1 - precision + (int) Math.floor(Math.log10(Math.abs(number)));
+ double roundingIncReciprocal = 0.0;
+ double roundingInc = 0.0;
+ if (log10RoundingIncr < 0) {
+ roundingIncReciprocal =
+ BigDecimal.ONE.movePointRight(-log10RoundingIncr).doubleValue();
+ } else {
+ roundingInc =
+ BigDecimal.ONE.movePointRight(log10RoundingIncr).doubleValue();
+ }
+ number = DecimalFormat_ICU58.round(number, roundingInc, roundingIncReciprocal, roundingMode, isNegative);
+ }
+ // End fix for ticket:10542
+
+ // At this point we are guaranteed a nonnegative finite
+ // number.
+ synchronized (digitList) {
+ digitList.set(number, precision, !useExponentialNotation &&
+ !areSignificantDigitsUsed());
+ return subformat(number, result, fieldPosition, isNegative, false, parseAttr);
+ }
+ }
+
+ /**
+ * This is a special function used by the CompactDecimalFormat subclass.
+ * It completes only the rounding portion of the formatting and returns
+ * the resulting double. CompactDecimalFormat uses the result to compute
+ * the plural form to use.
+ *
+ * @param number The number to format.
+ * @return The number rounded to the correct number of significant digits
+ * with negative sign stripped off.
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ double adjustNumberAsInFormatting(double number) {
+ if (Double.isNaN(number)) {
+ return number;
+ }
+ number = round(multiply(number));
+ if (Double.isInfinite(number)) {
+ return number;
+ }
+ return toDigitList(number).getDouble();
+ }
+
+ @Deprecated
+ DigitList toDigitList(double number) {
+ DigitList result = new DigitList();
+ result.set(number, precision(false), false);
+ return result;
+ }
+
+ /**
+ * This is a special function used by the CompactDecimalFormat subclass
+ * to determine if the number to be formatted is negative.
+ *
+ * @param number The number to format.
+ * @return True if number is negative.
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ boolean isNumberNegative(double number) {
+ if (Double.isNaN(number)) {
+ return false;
+ }
+ return isNegative(multiply(number));
+ }
+
+ /**
+ * Round a double value to the nearest multiple of the given rounding increment,
+ * according to the given mode. This is equivalent to rounding value/roundingInc to
+ * the nearest integer, according to the given mode, and returning that integer *
+ * roundingInc. Note this is changed from the version in 2.4, since division of
+ * doubles have inaccuracies. jitterbug 1871.
+ *
+ * @param number
+ * the absolute value of the number to be rounded
+ * @param roundingInc
+ * the rounding increment
+ * @param roundingIncReciprocal
+ * if non-zero, is the reciprocal of rounding inc.
+ * @param mode
+ * a BigDecimal rounding mode
+ * @param isNegative
+ * true if the number to be rounded is negative
+ * @return the absolute value of the rounded result
+ */
+ private static double round(double number, double roundingInc, double roundingIncReciprocal,
+ int mode, boolean isNegative) {
+
+ double div = roundingIncReciprocal == 0.0 ? number / roundingInc : number *
+ roundingIncReciprocal;
+
+ // do the absolute cases first
+
+ switch (mode) {
+ case BigDecimal.ROUND_CEILING:
+ div = (isNegative ? Math.floor(div + epsilon) : Math.ceil(div - epsilon));
+ break;
+ case BigDecimal.ROUND_FLOOR:
+ div = (isNegative ? Math.ceil(div - epsilon) : Math.floor(div + epsilon));
+ break;
+ case BigDecimal.ROUND_DOWN:
+ div = (Math.floor(div + epsilon));
+ break;
+ case BigDecimal.ROUND_UP:
+ div = (Math.ceil(div - epsilon));
+ break;
+ case BigDecimal.ROUND_UNNECESSARY:
+ if (div != Math.floor(div)) {
+ throw new ArithmeticException("Rounding necessary");
+ }
+ return number;
+ default:
+
+ // Handle complex cases, where the choice depends on the closer value.
+
+ // We figure out the distances to the two possible values, ceiling and floor.
+ // We then go for the diff that is smaller. Only if they are equal does the
+ // mode matter.
+
+ double ceil = Math.ceil(div);
+ double ceildiff = ceil - div; // (ceil * roundingInc) - number;
+ double floor = Math.floor(div);
+ double floordiff = div - floor; // number - (floor * roundingInc);
+
+ // Note that the diff values were those mapped back to the "normal" space by
+ // using the roundingInc. I don't have access to the original author of the
+ // code but suspect that that was to produce better result in edge cases
+ // because of machine precision, rather than simply using the difference
+ // between, say, ceil and div. However, it didn't work in all cases. Am
+ // trying instead using an epsilon value.
+
+ switch (mode) {
+ case BigDecimal.ROUND_HALF_EVEN:
+ // We should be able to just return Math.rint(a), but this
+ // doesn't work in some VMs.
+ // if one is smaller than the other, take the corresponding side
+ if (floordiff + epsilon < ceildiff) {
+ div = floor;
+ } else if (ceildiff + epsilon < floordiff) {
+ div = ceil;
+ } else { // they are equal, so we want to round to whichever is even
+ double testFloor = floor / 2;
+ div = (testFloor == Math.floor(testFloor)) ? floor : ceil;
+ }
+ break;
+ case BigDecimal.ROUND_HALF_DOWN:
+ div = ((floordiff <= ceildiff + epsilon) ? floor : ceil);
+ break;
+ case BigDecimal.ROUND_HALF_UP:
+ div = ((ceildiff <= floordiff + epsilon) ? ceil : floor);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid rounding mode: " + mode);
+ }
+ }
+ number = roundingIncReciprocal == 0.0 ? div * roundingInc : div / roundingIncReciprocal;
+ return number;
+ }
+
+ private static double epsilon = 0.00000000001;
+
+ /**
+ * @stable ICU 2.0
+ */
+ // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean
+ @Override
+ public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
+ return format(number, result, fieldPosition, false);
+ }
+
+ private StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition,
+ boolean parseAttr) {
+ fieldPosition.setBeginIndex(0);
+ fieldPosition.setEndIndex(0);
+
+ // If we are to do rounding, we need to move into the BigDecimal
+ // domain in order to do divide/multiply correctly.
+ if (actualRoundingIncrementICU != null) {
+ return format(BigDecimal.valueOf(number), result, fieldPosition);
+ }
+
+ boolean isNegative = (number < 0);
+ if (isNegative)
+ number = -number;
+
+ // In general, long values always represent real finite numbers, so we don't have
+ // to check for +/- Infinity or NaN. However, there is one case we have to be
+ // careful of: The multiplier can push a number near MIN_VALUE or MAX_VALUE
+ // outside the legal range. We check for this before multiplying, and if it
+ // happens we use BigInteger instead.
+ if (multiplier != 1) {
+ boolean tooBig = false;
+ if (number < 0) { // This can only happen if number == Long.MIN_VALUE
+ long cutoff = Long.MIN_VALUE / multiplier;
+ tooBig = (number <= cutoff); // number == cutoff can only happen if multiplier == -1
+ } else {
+ long cutoff = Long.MAX_VALUE / multiplier;
+ tooBig = (number > cutoff);
+ }
+ if (tooBig) {
+ // [Spark/CDL] Use
+ // format_BigInteger_StringBuffer_FieldPosition_boolean instead
+ // parseAttr is used to judge whether to synthesize attributes.
+ return format(BigInteger.valueOf(isNegative ? -number : number), result,
+ fieldPosition, parseAttr);
+ }
+ }
+
+ number *= multiplier;
+ synchronized (digitList) {
+ digitList.set(number, precision(true));
+ // Issue 11808
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
+ return subformat(number, result, fieldPosition, isNegative, true, parseAttr);
+ }
+ }
+
+ /**
+ * Formats a BigInteger number.
+ *
+ * @stable ICU 2.0
+ */
+ @Override
+ public StringBuffer format(BigInteger number, StringBuffer result,
+ FieldPosition fieldPosition) {
+ return format(number, result, fieldPosition, false);
+ }
+
+ private StringBuffer format(BigInteger number, StringBuffer result, FieldPosition fieldPosition,
+ boolean parseAttr) {
+ // If we are to do rounding, we need to move into the BigDecimal
+ // domain in order to do divide/multiply correctly.
+ if (actualRoundingIncrementICU != null) {
+ return format(new BigDecimal(number), result, fieldPosition);
+ }
+
+ if (multiplier != 1) {
+ number = number.multiply(BigInteger.valueOf(multiplier));
+ }
+
+ // At this point we are guaranteed a nonnegative finite
+ // number.
+ synchronized (digitList) {
+ digitList.set(number, precision(true));
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
+ return subformat(number.intValue(), result, fieldPosition, number.signum() < 0, true,
+ parseAttr);
+ }
+ }
+
+ /**
+ * Formats a BigDecimal number.
+ *
+ * @stable ICU 2.0
+ */
+ @Override
+ public StringBuffer format(java.math.BigDecimal number, StringBuffer result,
+ FieldPosition fieldPosition) {
+ return format(number, result, fieldPosition, false);
+ }
+
+ private StringBuffer format(java.math.BigDecimal number, StringBuffer result,
+ FieldPosition fieldPosition,
+ boolean parseAttr) {
+ if (multiplier != 1) {
+ number = number.multiply(java.math.BigDecimal.valueOf(multiplier));
+ }
+
+ if (actualRoundingIncrement != null) {
+ number = number.divide(actualRoundingIncrement, 0, roundingMode).multiply(actualRoundingIncrement);
+ }
+
+ synchronized (digitList) {
+ digitList.set(number, precision(false), !useExponentialNotation &&
+ !areSignificantDigitsUsed());
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
+ return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0,
+ false, parseAttr);
+ }
+ }
+
+ /**
+ * Formats a BigDecimal number.
+ *
+ * @stable ICU 2.0
+ */
+ @Override
+ public StringBuffer format(BigDecimal number, StringBuffer result,
+ FieldPosition fieldPosition) {
+ // This method is just a copy of the corresponding java.math.BigDecimal method
+ // for now. It isn't very efficient since it must create a conversion object to
+ // do math on the rounding increment. In the future we may try to clean this up,
+ // or even better, limit our support to just one flavor of BigDecimal.
+ if (multiplier != 1) {
+ number = number.multiply(BigDecimal.valueOf(multiplier), mathContext);
+ }
+
+ if (actualRoundingIncrementICU != null) {
+ number = number.divide(actualRoundingIncrementICU, 0, roundingMode)
+ .multiply(actualRoundingIncrementICU, mathContext);
+ }
+
+ synchronized (digitList) {
+ digitList.set(number, precision(false), !useExponentialNotation &&
+ !areSignificantDigitsUsed());
+ // For issue 11808.
+ if (digitList.wasRounded() && roundingMode == BigDecimal.ROUND_UNNECESSARY) {
+ throw new ArithmeticException("Rounding necessary");
+ }
+ return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0,
+ false, false);
+ }
+ }
+
+ /**
+ * Returns true if a grouping separator belongs at the given position, based on whether
+ * grouping is in use and the values of the primary and secondary grouping interval.
+ *
+ * @param pos the number of integer digits to the right of the current position. Zero
+ * indicates the position after the rightmost integer digit.
+ * @return true if a grouping character belongs at the current position.
+ */
+ private boolean isGroupingPosition(int pos) {
+ boolean result = false;
+ if (isGroupingUsed() && (pos > 0) && (groupingSize > 0)) {
+ if ((groupingSize2 > 0) && (pos > groupingSize)) {
+ result = ((pos - groupingSize) % groupingSize2) == 0;
+ } else {
+ result = pos % groupingSize == 0;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the number of fraction digits to display, or the total
+ * number of digits for significant digit formats and exponential
+ * formats.
+ */
+ private int precision(boolean isIntegral) {
+ if (areSignificantDigitsUsed()) {
+ return getMaximumSignificantDigits();
+ } else if (useExponentialNotation) {
+ return getMinimumIntegerDigits() + getMaximumFractionDigits();
+ } else {
+ return isIntegral ? 0 : getMaximumFractionDigits();
+ }
+ }
+
+ private StringBuffer subformat(int number, StringBuffer result, FieldPosition fieldPosition,
+ boolean isNegative, boolean isInteger, boolean parseAttr) {
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ // compute the plural category from the digitList plus other settings
+ return subformat(currencyPluralInfo.select(getFixedDecimal(number)),
+ result, fieldPosition, isNegative,
+ isInteger, parseAttr);
+ } else {
+ return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+ }
+ }
+
+ /**
+ * This is ugly, but don't see a better way to do it without major restructuring of the code.
+ */
+ /*package*/ FixedDecimal getFixedDecimal(double number) {
+ // get the visible fractions and the number of fraction digits.
+ return getFixedDecimal(number, digitList);
+ }
+
+ FixedDecimal getFixedDecimal(double number, DigitList dl) {
+ int fractionalDigitsInDigitList = dl.count - dl.decimalAt;
+ int v;
+ long f;
+ int maxFractionalDigits;
+ int minFractionalDigits;
+ if (useSignificantDigits) {
+ maxFractionalDigits = maxSignificantDigits - dl.decimalAt;
+ minFractionalDigits = minSignificantDigits - dl.decimalAt;
+ if (minFractionalDigits < 0) {
+ minFractionalDigits = 0;
+ }
+ if (maxFractionalDigits < 0) {
+ maxFractionalDigits = 0;
+ }
+ } else {
+ maxFractionalDigits = getMaximumFractionDigits();
+ minFractionalDigits = getMinimumFractionDigits();
+ }
+ v = fractionalDigitsInDigitList;
+ if (v < minFractionalDigits) {
+ v = minFractionalDigits;
+ } else if (v > maxFractionalDigits) {
+ v = maxFractionalDigits;
+ }
+ f = 0;
+ if (v > 0) {
+ for (int i = Math.max(0, dl.decimalAt); i < dl.count; ++i) {
+ f *= 10;
+ f += (dl.digits[i] - '0');
+ }
+ for (int i = v; i < fractionalDigitsInDigitList; ++i) {
+ f *= 10;
+ }
+ }
+ return new FixedDecimal(number, v, f);
+ }
+
+ private StringBuffer subformat(double number, StringBuffer result, FieldPosition fieldPosition,
+ boolean isNegative,
+ boolean isInteger, boolean parseAttr) {
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ // compute the plural category from the digitList plus other settings
+ return subformat(currencyPluralInfo.select(getFixedDecimal(number)),
+ result, fieldPosition, isNegative,
+ isInteger, parseAttr);
+ } else {
+ return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+ }
+ }
+
+ private StringBuffer subformat(String pluralCount, StringBuffer result, FieldPosition fieldPosition,
+ boolean isNegative, boolean isInteger, boolean parseAttr) {
+ // There are 2 ways to activate currency plural format: by applying a pattern with
+ // 3 currency sign directly, or by instantiate a decimal formatter using
+ // PLURALCURRENCYSTYLE. For both cases, the number of currency sign in the
+ // pattern is 3. Even if the number of currency sign in the pattern is 3, it does
+ // not mean we need to reset the pattern. For 1st case, we do not need to reset
+ // pattern. For 2nd case, we might need to reset pattern, if the default pattern
+ // (corresponding to plural count 'other') we use is different from the pattern
+ // based on 'pluralCount'.
+ //
+ // style is only valid when decimal formatter is constructed through
+ // DecimalFormat(pattern, symbol, style)
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ // May need to reset pattern if the style is PLURALCURRENCYSTYLE.
+ String currencyPluralPattern = currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
+ if (formatPattern.equals(currencyPluralPattern) == false) {
+ applyPatternWithoutExpandAffix(currencyPluralPattern, false);
+ }
+ }
+ // Expand the affix to the right name according to the plural rule. This is only
+ // used for currency plural formatting. Currency plural name is not a fixed
+ // static one, it is a dynamic name based on the currency plural count. So, the
+ // affixes need to be expanded here. For other cases, the affix is a static one
+ // based on pattern alone, and it is already expanded during applying pattern, or
+ // setDecimalFormatSymbols, or setCurrency.
+ expandAffixAdjustWidth(pluralCount);
+ return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+ }
+
+ /**
+ * Complete the formatting of a finite number. On entry, the
+ * digitList must be filled in with the correct digits.
+ */
+ private StringBuffer subformat(StringBuffer result, FieldPosition fieldPosition,
+ boolean isNegative, boolean isInteger, boolean parseAttr) {
+ // NOTE: This isn't required anymore because DigitList takes care of this.
+ //
+ // // The negative of the exponent represents the number of leading // zeros
+ // between the decimal and the first non-zero digit, for // a value < 0.1 (e.g.,
+ // for 0.00123, -fExponent == 2). If this // is more than the maximum fraction
+ // digits, then we have an underflow // for the printed representation. We
+ // recognize this here and set // the DigitList representation to zero in this
+ // situation.
+ //
+ // if (-digitList.decimalAt >= getMaximumFractionDigits())
+ // {
+ // digitList.count = 0;
+ // }
+
+
+
+ // Per bug 4147706, DecimalFormat must respect the sign of numbers which format as
+ // zero. This allows sensible computations and preserves relations such as
+ // signum(1/x) = signum(x), where x is +Infinity or -Infinity. Prior to this fix,
+ // we always formatted zero values as if they were positive. Liu 7/6/98.
+ if (digitList.isZero()) {
+ digitList.decimalAt = 0; // Normalize
+ }
+
+ int prefixLen = appendAffix(result, isNegative, true, fieldPosition, parseAttr);
+
+ if (useExponentialNotation) {
+ subformatExponential(result, fieldPosition, parseAttr);
+ } else {
+ subformatFixed(result, fieldPosition, isInteger, parseAttr);
+ }
+
+ int suffixLen = appendAffix(result, isNegative, false, fieldPosition, parseAttr);
+ addPadding(result, fieldPosition, prefixLen, suffixLen);
+ return result;
+ }
+
+ private void subformatFixed(StringBuffer result,
+ FieldPosition fieldPosition,
+ boolean isInteger,
+ boolean parseAttr) {
+ String[] digits = symbols.getDigitStrings();
+
+ String grouping = currencySignCount == CURRENCY_SIGN_COUNT_ZERO ?
+ symbols.getGroupingSeparatorString(): symbols.getMonetaryGroupingSeparatorString();
+ String decimal = currencySignCount == CURRENCY_SIGN_COUNT_ZERO ?
+ symbols.getDecimalSeparatorString() : symbols.getMonetaryDecimalSeparatorString();
+ boolean useSigDig = areSignificantDigitsUsed();
+ int maxIntDig = getMaximumIntegerDigits();
+ int minIntDig = getMinimumIntegerDigits();
+ int i;
+ // [Spark/CDL] Record the integer start index.
+ int intBegin = result.length();
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD ||
+ fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setBeginIndex(intBegin);
+ }
+ long fractionalDigits = 0;
+ int fractionalDigitsCount = 0;
+ boolean recordFractionDigits = false;
+
+ int sigCount = 0;
+ int minSigDig = getMinimumSignificantDigits();
+ int maxSigDig = getMaximumSignificantDigits();
+ if (!useSigDig) {
+ minSigDig = 0;
+ maxSigDig = Integer.MAX_VALUE;
+ }
+
+ // Output the integer portion. Here 'count' is the total number of integer
+ // digits we will display, including both leading zeros required to satisfy
+ // getMinimumIntegerDigits, and actual digits present in the number.
+ int count = useSigDig ? Math.max(1, digitList.decimalAt) : minIntDig;
+ if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
+ count = digitList.decimalAt;
+ }
+
+ // Handle the case where getMaximumIntegerDigits() is smaller than the real
+ // number of integer digits. If this is so, we output the least significant
+ // max integer digits. For example, the value 1997 printed with 2 max integer
+ // digits is just "97".
+
+ int digitIndex = 0; // Index into digitList.fDigits[]
+ if (count > maxIntDig && maxIntDig >= 0) {
+ count = maxIntDig;
+ digitIndex = digitList.decimalAt - count;
+ }
+
+ int sizeBeforeIntegerPart = result.length();
+ for (i = count - 1; i >= 0; --i) {
+ if (i < digitList.decimalAt && digitIndex < digitList.count
+ && sigCount < maxSigDig) {
+ // Output a real digit
+ result.append(digits[digitList.getDigitValue(digitIndex++)]);
+ ++sigCount;
+ } else {
+ // Output a zero (leading or trailing)
+ result.append(digits[0]);
+ if (sigCount > 0) {
+ ++sigCount;
+ }
+ }
+
+ // Output grouping separator if necessary.
+ if (isGroupingPosition(i)) {
+ result.append(grouping);
+ // [Spark/CDL] Add grouping separator attribute here.
+ // Set only for the first instance.
+ // Length of grouping separator is 1.
+ if (fieldPosition.getFieldAttribute() == Field.GROUPING_SEPARATOR &&
+ fieldPosition.getBeginIndex() == 0 && fieldPosition.getEndIndex() == 0) {
+ fieldPosition.setBeginIndex(result.length()-1);
+ fieldPosition.setEndIndex(result.length());
+ }
+ if (parseAttr) {
+ addAttribute(Field.GROUPING_SEPARATOR, result.length() - 1, result.length());
+ }
+ }
+ }
+
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD ||
+ fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setEndIndex(result.length());
+ }
+
+ // This handles the special case of formatting 0. For zero only, we count the
+ // zero to the left of the decimal point as one signficant digit. Ordinarily we
+ // do not count any leading 0's as significant. If the number we are formatting
+ // is not zero, then either sigCount or digits.getCount() will be non-zero.
+ if (sigCount == 0 && digitList.count == 0) {
+ sigCount = 1;
+ }
+
+ // Determine whether or not there are any printable fractional digits. If
+ // we've used up the digits we know there aren't.
+ boolean fractionPresent = (!isInteger && digitIndex < digitList.count)
+ || (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
+
+ // If there is no fraction present, and we haven't printed any integer digits,
+ // then print a zero. Otherwise we won't print _any_ digits, and we won't be
+ // able to parse this string.
+ if (!fractionPresent && result.length() == sizeBeforeIntegerPart)
+ result.append(digits[0]);
+ // [Spark/CDL] Add attribute for integer part.
+ if (parseAttr) {
+ addAttribute(Field.INTEGER, intBegin, result.length());
+ }
+ // Output the decimal separator if we always do so.
+ if (decimalSeparatorAlwaysShown || fractionPresent) {
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ result.append(decimal);
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ // [Spark/CDL] Add attribute for decimal separator
+ if (parseAttr) {
+ addAttribute(Field.DECIMAL_SEPARATOR, result.length() - 1, result.length());
+ }
+ }
+
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+ fieldPosition.setBeginIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+
+ // [Spark/CDL] Record the begin index of fraction part.
+ int fracBegin = result.length();
+ recordFractionDigits = fieldPosition instanceof UFieldPosition;
+
+ count = useSigDig ? Integer.MAX_VALUE : getMaximumFractionDigits();
+ if (useSigDig && (sigCount == maxSigDig ||
+ (sigCount >= minSigDig && digitIndex == digitList.count))) {
+ count = 0;
+ }
+ for (i = 0; i < count; ++i) {
+ // Here is where we escape from the loop. We escape if we've output the
+ // maximum fraction digits (specified in the for expression above). We
+ // also stop when we've output the minimum digits and either: we have an
+ // integer, so there is no fractional stuff to display, or we're out of
+ // significant digits.
+ if (!useSigDig && i >= getMinimumFractionDigits() &&
+ (isInteger || digitIndex >= digitList.count)) {
+ break;
+ }
+
+ // Output leading fractional zeros. These are zeros that come after the
+ // decimal but before any significant digits. These are only output if
+ // abs(number being formatted) < 1.0.
+ if (-1 - i > (digitList.decimalAt - 1)) {
+ result.append(digits[0]);
+ if (recordFractionDigits) {
+ ++fractionalDigitsCount;
+ fractionalDigits *= 10;
+ }
+ continue;
+ }
+
+ // Output a digit, if we have any precision left, or a zero if we
+ // don't. We don't want to output noise digits.
+ if (!isInteger && digitIndex < digitList.count) {
+ byte digit = digitList.getDigitValue(digitIndex++);
+ result.append(digits[digit]);
+ if (recordFractionDigits) {
+ ++fractionalDigitsCount;
+ fractionalDigits *= 10;
+ fractionalDigits += digit;
+ }
+ } else {
+ result.append(digits[0]);
+ if (recordFractionDigits) {
+ ++fractionalDigitsCount;
+ fractionalDigits *= 10;
+ }
+ }
+
+ // If we reach the maximum number of significant digits, or if we output
+ // all the real digits and reach the minimum, then we are done.
+ ++sigCount;
+ if (useSigDig && (sigCount == maxSigDig ||
+ (digitIndex == digitList.count && sigCount >= minSigDig))) {
+ break;
+ }
+ }
+
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+ fieldPosition.setEndIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ if (recordFractionDigits) {
+ ((UFieldPosition) fieldPosition).setFractionDigits(fractionalDigitsCount, fractionalDigits);
+ }
+
+ // [Spark/CDL] Add attribute information if necessary.
+ if (parseAttr && (decimalSeparatorAlwaysShown || fractionPresent)) {
+ addAttribute(Field.FRACTION, fracBegin, result.length());
+ }
+ }
+
+ private void subformatExponential(StringBuffer result,
+ FieldPosition fieldPosition,
+ boolean parseAttr) {
+ String[] digits = symbols.getDigitStringsLocal();
+ String decimal = currencySignCount == CURRENCY_SIGN_COUNT_ZERO ?
+ symbols.getDecimalSeparatorString() : symbols.getMonetaryDecimalSeparatorString();
+ boolean useSigDig = areSignificantDigitsUsed();
+ int maxIntDig = getMaximumIntegerDigits();
+ int minIntDig = getMinimumIntegerDigits();
+ int i;
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setBeginIndex(result.length());
+ fieldPosition.setEndIndex(-1);
+ } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+ fieldPosition.setBeginIndex(-1);
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setBeginIndex(result.length());
+ fieldPosition.setEndIndex(-1);
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+ fieldPosition.setBeginIndex(-1);
+ }
+
+ // [Spark/CDL]
+ // the begin index of integer part
+ // the end index of integer part
+ // the begin index of fractional part
+ int intBegin = result.length();
+ int intEnd = -1;
+ int fracBegin = -1;
+ int minFracDig = 0;
+ if (useSigDig) {
+ maxIntDig = minIntDig = 1;
+ minFracDig = getMinimumSignificantDigits() - 1;
+ } else {
+ minFracDig = getMinimumFractionDigits();
+ if (maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
+ maxIntDig = 1;
+ if (maxIntDig < minIntDig) {
+ maxIntDig = minIntDig;
+ }
+ }
+ if (maxIntDig > minIntDig) {
+ minIntDig = 1;
+ }
+ }
+ long fractionalDigits = 0;
+ int fractionalDigitsCount = 0;
+ boolean recordFractionDigits = false;
+
+ // Minimum integer digits are handled in exponential format by adjusting the
+ // exponent. For example, 0.01234 with 3 minimum integer digits is "123.4E-4".
+
+ // Maximum integer digits are interpreted as indicating the repeating
+ // range. This is useful for engineering notation, in which the exponent is
+ // restricted to a multiple of 3. For example, 0.01234 with 3 maximum integer
+ // digits is "12.34e-3". If maximum integer digits are defined and are larger
+ // than minimum integer digits, then minimum integer digits are ignored.
+
+ int exponent = digitList.decimalAt;
+ if (maxIntDig > 1 && maxIntDig != minIntDig) {
+ // A exponent increment is defined; adjust to it.
+ exponent = (exponent > 0) ? (exponent - 1) / maxIntDig : (exponent / maxIntDig) - 1;
+ exponent *= maxIntDig;
+ } else {
+ // No exponent increment is defined; use minimum integer digits.
+ // If none is specified, as in "#E0", generate 1 integer digit.
+ exponent -= (minIntDig > 0 || minFracDig > 0) ? minIntDig : 1;
+ }
+
+ // We now output a minimum number of digits, and more if there are more
+ // digits, up to the maximum number of digits. We place the decimal point
+ // after the "integer" digits, which are the first (decimalAt - exponent)
+ // digits.
+ int minimumDigits = minIntDig + minFracDig;
+ // The number of integer digits is handled specially if the number
+ // is zero, since then there may be no digits.
+ int integerDigits = digitList.isZero() ? minIntDig : digitList.decimalAt - exponent;
+ int totalDigits = digitList.count;
+ if (minimumDigits > totalDigits)
+ totalDigits = minimumDigits;
+ if (integerDigits > totalDigits)
+ totalDigits = integerDigits;
+
+ for (i = 0; i < totalDigits; ++i) {
+ if (i == integerDigits) {
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ fieldPosition.setEndIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ fieldPosition.setEndIndex(result.length());
+ }
+
+ // [Spark/CDL] Add attribute for integer part
+ if (parseAttr) {
+ intEnd = result.length();
+ addAttribute(Field.INTEGER, intBegin, result.length());
+ }
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ result.append(decimal);
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ // [Spark/CDL] Add attribute for decimal separator
+ fracBegin = result.length();
+ if (parseAttr) {
+ // Length of decimal separator is 1.
+ int decimalSeparatorBegin = result.length() - 1;
+ addAttribute(Field.DECIMAL_SEPARATOR, decimalSeparatorBegin,
+ result.length());
+ }
+ // Record field information for caller.
+ if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+ fieldPosition.setBeginIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ recordFractionDigits = fieldPosition instanceof UFieldPosition;
+
+ }
+ byte digit = (i < digitList.count) ? digitList.getDigitValue(i) : (byte)0;
+ result.append(digits[digit]);
+ if (recordFractionDigits) {
+ ++fractionalDigitsCount;
+ fractionalDigits *= 10;
+ fractionalDigits += digit;
+ }
+ }
+
+ // For ICU compatibility and format 0 to 0E0 with pattern "#E0" [Richard/GCL]
+ if (digitList.isZero() && (totalDigits == 0)) {
+ result.append(digits[0]);
+ }
+
+ // add the decimal separator if it is to be always shown AND there are no decimal digits
+ if ((fracBegin == -1) && this.decimalSeparatorAlwaysShown) {
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ result.append(decimal);
+ if (fieldPosition.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ if (parseAttr) {
+ // Length of decimal separator is 1.
+ int decimalSeparatorBegin = result.length() - 1;
+ addAttribute(Field.DECIMAL_SEPARATOR, decimalSeparatorBegin, result.length());
+ }
+ }
+
+ // Record field information
+ if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+ if (fieldPosition.getEndIndex() < 0) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+ if (fieldPosition.getBeginIndex() < 0) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ fieldPosition.setEndIndex(result.length());
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+ if (fieldPosition.getEndIndex() < 0) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+ if (fieldPosition.getBeginIndex() < 0) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ fieldPosition.setEndIndex(result.length());
+ }
+ if (recordFractionDigits) {
+ ((UFieldPosition) fieldPosition).setFractionDigits(fractionalDigitsCount, fractionalDigits);
+ }
+
+ // [Spark/CDL] Calculate the end index of integer part and fractional
+ // part if they are not properly processed yet.
+ if (parseAttr) {
+ if (intEnd < 0) {
+ addAttribute(Field.INTEGER, intBegin, result.length());
+ }
+ if (fracBegin > 0) {
+ addAttribute(Field.FRACTION, fracBegin, result.length());
+ }
+ }
+
+ // The exponent is output using the pattern-specified minimum exponent
+ // digits. There is no maximum limit to the exponent digits, since truncating
+ // the exponent would result in an unacceptable inaccuracy.
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SYMBOL) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+
+ result.append(symbols.getExponentSeparator());
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SYMBOL) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ // [Spark/CDL] For exponent symbol, add an attribute.
+ if (parseAttr) {
+ addAttribute(Field.EXPONENT_SYMBOL, result.length() -
+ symbols.getExponentSeparator().length(), result.length());
+ }
+ // For zero values, we force the exponent to zero. We must do this here, and
+ // not earlier, because the value is used to determine integer digit count
+ // above.
+ if (digitList.isZero())
+ exponent = 0;
+
+ boolean negativeExponent = exponent < 0;
+ if (negativeExponent) {
+ exponent = -exponent;
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SIGN) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ result.append(symbols.getMinusSignString());
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SIGN) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ // [Spark/CDL] If exponent has sign, then add an exponent sign
+ // attribute.
+ if (parseAttr) {
+ // Length of exponent sign is 1.
+ addAttribute(Field.EXPONENT_SIGN, result.length() - 1, result.length());
+ }
+ } else if (exponentSignAlwaysShown) {
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SIGN) {
+ fieldPosition.setBeginIndex(result.length());
+ }
+ result.append(symbols.getPlusSignString());
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT_SIGN) {
+ fieldPosition.setEndIndex(result.length());
+ }
+ // [Spark/CDL] Add an plus sign attribute.
+ if (parseAttr) {
+ // Length of exponent sign is 1.
+ int expSignBegin = result.length() - 1;
+ addAttribute(Field.EXPONENT_SIGN, expSignBegin, result.length());
+ }
+ }
+ int expBegin = result.length();
+ digitList.set(exponent);
+ {
+ int expDig = minExponentDigits;
+ if (useExponentialNotation && expDig < 1) {
+ expDig = 1;
+ }
+ for (i = digitList.decimalAt; i < expDig; ++i)
+ result.append(digits[0]);
+ }
+ for (i = 0; i < digitList.decimalAt; ++i) {
+ result.append((i < digitList.count) ? digits[digitList.getDigitValue(i)]
+ : digits[0]);
+ }
+ // [Spark/CDL] Add attribute for exponent part.
+ if (fieldPosition.getFieldAttribute() == Field.EXPONENT) {
+ fieldPosition.setBeginIndex(expBegin);
+ fieldPosition.setEndIndex(result.length());
+ }
+ if (parseAttr) {
+ addAttribute(Field.EXPONENT, expBegin, result.length());
+ }
+ }
+
+ private final void addPadding(StringBuffer result, FieldPosition fieldPosition, int prefixLen,
+ int suffixLen) {
+ if (formatWidth > 0) {
+ int len = formatWidth - result.length();
+ if (len > 0) {
+ char[] padding = new char[len];
+ for (int i = 0; i < len; ++i) {
+ padding[i] = pad;
+ }
+ switch (padPosition) {
+ case PAD_AFTER_PREFIX:
+ result.insert(prefixLen, padding);
+ break;
+ case PAD_BEFORE_PREFIX:
+ result.insert(0, padding);
+ break;
+ case PAD_BEFORE_SUFFIX:
+ result.insert(result.length() - suffixLen, padding);
+ break;
+ case PAD_AFTER_SUFFIX:
+ result.append(padding);
+ break;
+ }
+ if (padPosition == PAD_BEFORE_PREFIX || padPosition == PAD_AFTER_PREFIX) {
+ fieldPosition.setBeginIndex(fieldPosition.getBeginIndex() + len);
+ fieldPosition.setEndIndex(fieldPosition.getEndIndex() + len);
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses the given string, returning a <code>Number</code> object to represent the
+ * parsed value. <code>Double</code> objects are returned to represent non-integral
+ * values which cannot be stored in a <code>BigDecimal</code>. These are
+ * <code>NaN</code>, infinity, -infinity, and -0.0. If {@link #isParseBigDecimal()} is
+ * false (the default), all other values are returned as <code>Long</code>,
+ * <code>BigInteger</code>, or <code>BigDecimal</code> values, in that order of
+ * preference. If {@link #isParseBigDecimal()} is true, all other values are returned
+ * as <code>BigDecimal</code> valuse. If the parse fails, null is returned.
+ *
+ * @param text the string to be parsed
+ * @param parsePosition defines the position where parsing is to begin, and upon
+ * return, the position where parsing left off. If the position has not changed upon
+ * return, then parsing failed.
+ * @return a <code>Number</code> object with the parsed value or
+ * <code>null</code> if the parse failed
+ * @stable ICU 2.0
+ */
+ @Override
+ public Number parse(String text, ParsePosition parsePosition) {
+ return (Number) parse(text, parsePosition, null);
+ }
+
+ /**
+ * Parses text from the given string as a CurrencyAmount. Unlike the parse() method,
+ * this method will attempt to parse a generic currency name, searching for a match of
+ * this object's locale's currency display names, or for a 3-letter ISO currency
+ * code. This method will fail if this format is not a currency format, that is, if it
+ * does not contain the currency pattern symbol (U+00A4) in its prefix or suffix.
+ *
+ * @param text the text to parse
+ * @param pos input-output position; on input, the position within text to match; must
+ * have 0 &lt;= pos.getIndex() &lt; text.length(); on output, the position after the last
+ * matched character. If the parse fails, the position in unchanged upon output.
+ * @return a CurrencyAmount, or null upon failure
+ * @stable ICU 49
+ */
+ @Override
+ public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
+ Currency[] currency = new Currency[1];
+ return (CurrencyAmount) parse(text.toString(), pos, currency);
+ }
+
+ /**
+ * Parses the given text as either a Number or a CurrencyAmount.
+ *
+ * @param text the string to parse
+ * @param parsePosition input-output position; on input, the position within text to
+ * match; must have 0 <= pos.getIndex() < text.length(); on output, the position after
+ * the last matched character. If the parse fails, the position in unchanged upon
+ * output.
+ * @param currency if non-null, a CurrencyAmount is parsed and returned; otherwise a
+ * Number is parsed and returned
+ * @return a Number or CurrencyAmount or null
+ */
+ private Object parse(String text, ParsePosition parsePosition, Currency[] currency) {
+ int backup;
+ int i = backup = parsePosition.getIndex();
+
+ // Handle NaN as a special case:
+
+ // Skip padding characters, if around prefix
+ if (formatWidth > 0 &&
+ (padPosition == PAD_BEFORE_PREFIX || padPosition == PAD_AFTER_PREFIX)) {
+ i = skipPadding(text, i);
+ }
+ if (text.regionMatches(i, symbols.getNaN(), 0, symbols.getNaN().length())) {
+ i += symbols.getNaN().length();
+ // Skip padding characters, if around suffix
+ if (formatWidth > 0 && (padPosition == PAD_BEFORE_SUFFIX ||
+ padPosition == PAD_AFTER_SUFFIX)) {
+ i = skipPadding(text, i);
+ }
+ parsePosition.setIndex(i);
+ return new Double(Double.NaN);
+ }
+
+ // NaN parse failed; start over
+ i = backup;
+
+ boolean[] status = new boolean[STATUS_LENGTH];
+ if (currencySignCount != CURRENCY_SIGN_COUNT_ZERO) {
+ if (!parseForCurrency(text, parsePosition, currency, status)) {
+ return null;
+ }
+ } else if (currency != null) {
+ return null;
+ } else {
+ if (!subparse(text, parsePosition, digitList, status, currency, negPrefixPattern,
+ negSuffixPattern, posPrefixPattern, posSuffixPattern,
+ false, Currency.SYMBOL_NAME)) {
+ parsePosition.setIndex(backup);
+ return null;
+ }
+ }
+
+ Number n = null;
+
+ // Handle infinity
+ if (status[STATUS_INFINITE]) {
+ n = new Double(status[STATUS_POSITIVE] ? Double.POSITIVE_INFINITY :
+ Double.NEGATIVE_INFINITY);
+ }
+
+ // Handle underflow
+ else if (status[STATUS_UNDERFLOW]) {
+ n = status[STATUS_POSITIVE] ? new Double("0.0") : new Double("-0.0");
+ }
+
+ // Handle -0.0
+ else if (!status[STATUS_POSITIVE] && digitList.isZero()) {
+ n = new Double("-0.0");
+ }
+
+ else {
+ // Do as much of the multiplier conversion as possible without
+ // losing accuracy.
+ int mult = multiplier; // Don't modify this.multiplier
+ while (mult % 10 == 0) {
+ --digitList.decimalAt;
+ mult /= 10;
+ }
+
+ // Handle integral values
+ if (!parseBigDecimal && mult == 1 && digitList.isIntegral()) {
+ // hack quick long
+ if (digitList.decimalAt < 12) { // quick check for long
+ long l = 0;
+ if (digitList.count > 0) {
+ int nx = 0;
+ while (nx < digitList.count) {
+ l = l * 10 + (char) digitList.digits[nx++] - '0';
+ }
+ while (nx++ < digitList.decimalAt) {
+ l *= 10;
+ }
+ if (!status[STATUS_POSITIVE]) {
+ l = -l;
+ }
+ }
+ n = Long.valueOf(l);
+ } else {
+ BigInteger big = digitList.getBigInteger(status[STATUS_POSITIVE]);
+ n = (big.bitLength() < 64) ? (Number) Long.valueOf(big.longValue()) : (Number) big;
+ }
+ }
+ // Handle non-integral values or the case where parseBigDecimal is set
+ else {
+ BigDecimal big = digitList.getBigDecimalICU(status[STATUS_POSITIVE]);
+ n = big;
+ if (mult != 1) {
+ n = big.divide(BigDecimal.valueOf(mult), mathContext);
+ }
+ }
+ }
+
+ // Assemble into CurrencyAmount if necessary
+ return (currency != null) ? (Object) new CurrencyAmount(n, currency[0]) : (Object) n;
+ }
+
+ private boolean parseForCurrency(String text, ParsePosition parsePosition,
+ Currency[] currency, boolean[] status) {
+ int origPos = parsePosition.getIndex();
+ if (!isReadyForParsing) {
+ int savedCurrencySignCount = currencySignCount;
+ setupCurrencyAffixForAllPatterns();
+ // reset pattern back
+ if (savedCurrencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ applyPatternWithoutExpandAffix(formatPattern, false);
+ } else {
+ applyPattern(formatPattern, false);
+ }
+ isReadyForParsing = true;
+ }
+ int maxPosIndex = origPos;
+ int maxErrorPos = -1;
+ boolean[] savedStatus = null;
+ // First, parse against current pattern.
+ // Since current pattern could be set by applyPattern(),
+ // it could be an arbitrary pattern, and it may not be the one
+ // defined in current locale.
+ boolean[] tmpStatus = new boolean[STATUS_LENGTH];
+ ParsePosition tmpPos = new ParsePosition(origPos);
+ DigitList tmpDigitList = new DigitList();
+ boolean found;
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ found = subparse(text, tmpPos, tmpDigitList, tmpStatus, currency,
+ negPrefixPattern, negSuffixPattern, posPrefixPattern, posSuffixPattern,
+ true, Currency.LONG_NAME);
+ } else {
+ found = subparse(text, tmpPos, tmpDigitList, tmpStatus, currency,
+ negPrefixPattern, negSuffixPattern, posPrefixPattern, posSuffixPattern,
+ true, Currency.SYMBOL_NAME);
+ }
+ if (found) {
+ if (tmpPos.getIndex() > maxPosIndex) {
+ maxPosIndex = tmpPos.getIndex();
+ savedStatus = tmpStatus;
+ digitList = tmpDigitList;
+ }
+ } else {
+ maxErrorPos = tmpPos.getErrorIndex();
+ }
+ // Then, parse against affix patterns. Those are currency patterns and currency
+ // plural patterns defined in the locale.
+ for (AffixForCurrency affix : affixPatternsForCurrency) {
+ tmpStatus = new boolean[STATUS_LENGTH];
+ tmpPos = new ParsePosition(origPos);
+ tmpDigitList = new DigitList();
+ boolean result = subparse(text, tmpPos, tmpDigitList, tmpStatus, currency,
+ affix.getNegPrefix(), affix.getNegSuffix(),
+ affix.getPosPrefix(), affix.getPosSuffix(),
+ true, affix.getPatternType());
+ if (result) {
+ found = true;
+ if (tmpPos.getIndex() > maxPosIndex) {
+ maxPosIndex = tmpPos.getIndex();
+ savedStatus = tmpStatus;
+ digitList = tmpDigitList;
+ }
+ } else {
+ maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ? tmpPos.getErrorIndex()
+ : maxErrorPos;
+ }
+ }
+ // Finally, parse against simple affix to find the match. For example, in
+ // TestMonster suite, if the to-be-parsed text is "-\u00A40,00".
+ // complexAffixCompare will not find match, since there is no ISO code matches
+ // "\u00A4", and the parse stops at "\u00A4". We will just use simple affix
+ // comparison (look for exact match) to pass it.
+ //
+ // TODO: We should parse against simple affix first when
+ // output currency is not requested. After the complex currency
+ // parsing implementation was introduced, the default currency
+ // instance parsing slowed down because of the new code flow.
+ // I filed #10312 - Yoshito
+ tmpStatus = new boolean[STATUS_LENGTH];
+ tmpPos = new ParsePosition(origPos);
+ tmpDigitList = new DigitList();
+
+ // Disable complex currency parsing and try it again.
+ boolean result = subparse(text, tmpPos, tmpDigitList, tmpStatus, currency,
+ negativePrefix, negativeSuffix, positivePrefix, positiveSuffix,
+ false /* disable complex currency parsing */, Currency.SYMBOL_NAME);
+ if (result) {
+ if (tmpPos.getIndex() > maxPosIndex) {
+ maxPosIndex = tmpPos.getIndex();
+ savedStatus = tmpStatus;
+ digitList = tmpDigitList;
+ }
+ found = true;
+ } else {
+ maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ? tmpPos.getErrorIndex() :
+ maxErrorPos;
+ }
+
+ if (!found) {
+ // parsePosition.setIndex(origPos);
+ parsePosition.setErrorIndex(maxErrorPos);
+ } else {
+ parsePosition.setIndex(maxPosIndex);
+ parsePosition.setErrorIndex(-1);
+ for (int index = 0; index < STATUS_LENGTH; ++index) {
+ status[index] = savedStatus[index];
+ }
+ }
+ return found;
+ }
+
+ // Get affix patterns used in locale's currency pattern (NumberPatterns[1]) and
+ // currency plural pattern (CurrencyUnitPatterns).
+ private void setupCurrencyAffixForAllPatterns() {
+ if (currencyPluralInfo == null) {
+ currencyPluralInfo = new CurrencyPluralInfo(symbols.getULocale());
+ }
+ affixPatternsForCurrency = new HashSet<>();
+
+ // save the current pattern, since it will be changed by
+ // applyPatternWithoutExpandAffix
+ String savedFormatPattern = formatPattern;
+
+ // CURRENCYSTYLE and ISOCURRENCYSTYLE should have the same prefix and suffix, so,
+ // only need to save one of them. Here, chose onlyApplyPatternWithoutExpandAffix
+ // without saving the actualy pattern in 'pattern' data member. TODO: is it uloc?
+ applyPatternWithoutExpandAffix(getPattern(symbols.getULocale(), NumberFormat.CURRENCYSTYLE),
+ false);
+ AffixForCurrency affixes = new AffixForCurrency(
+ negPrefixPattern, negSuffixPattern, posPrefixPattern, posSuffixPattern,
+ Currency.SYMBOL_NAME);
+ affixPatternsForCurrency.add(affixes);
+
+ // add plural pattern
+ Iterator<String> iter = currencyPluralInfo.pluralPatternIterator();
+ Set<String> currencyUnitPatternSet = new HashSet<>();
+ while (iter.hasNext()) {
+ String pluralCount = iter.next();
+ String currencyPattern = currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
+ if (currencyPattern != null &&
+ currencyUnitPatternSet.contains(currencyPattern) == false) {
+ currencyUnitPatternSet.add(currencyPattern);
+ applyPatternWithoutExpandAffix(currencyPattern, false);
+ affixes = new AffixForCurrency(negPrefixPattern, negSuffixPattern, posPrefixPattern,
+ posSuffixPattern, Currency.LONG_NAME);
+ affixPatternsForCurrency.add(affixes);
+ }
+ }
+ // reset pattern back
+ formatPattern = savedFormatPattern;
+ }
+
+ // currency formatting style options
+ private static final int CURRENCY_SIGN_COUNT_ZERO = 0;
+ private static final int CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT = 1;
+ private static final int CURRENCY_SIGN_COUNT_IN_ISO_FORMAT = 2;
+ private static final int CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT = 3;
+
+ private static final int STATUS_INFINITE = 0;
+ private static final int STATUS_POSITIVE = 1;
+ private static final int STATUS_UNDERFLOW = 2;
+ private static final int STATUS_LENGTH = 3;
+
+ private static final UnicodeSet dotEquivalents = new UnicodeSet(
+ //"[.\u2024\u3002\uFE12\uFE52\uFF0E\uFF61]"
+ 0x002E, 0x002E,
+ 0x2024, 0x2024,
+ 0x3002, 0x3002,
+ 0xFE12, 0xFE12,
+ 0xFE52, 0xFE52,
+ 0xFF0E, 0xFF0E,
+ 0xFF61, 0xFF61).freeze();
+
+ private static final UnicodeSet commaEquivalents = new UnicodeSet(
+ //"[,\u060C\u066B\u3001\uFE10\uFE11\uFE50\uFE51\uFF0C\uFF64]"
+ 0x002C, 0x002C,
+ 0x060C, 0x060C,
+ 0x066B, 0x066B,
+ 0x3001, 0x3001,
+ 0xFE10, 0xFE11,
+ 0xFE50, 0xFE51,
+ 0xFF0C, 0xFF0C,
+ 0xFF64, 0xFF64).freeze();
+
+// private static final UnicodeSet otherGroupingSeparators = new UnicodeSet(
+// //"[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]"
+// 0x0020, 0x0020,
+// 0x0027, 0x0027,
+// 0x00A0, 0x00A0,
+// 0x066C, 0x066C,
+// 0x2000, 0x200A,
+// 0x2018, 0x2019,
+// 0x202F, 0x202F,
+// 0x205F, 0x205F,
+// 0x3000, 0x3000,
+// 0xFF07, 0xFF07).freeze();
+
+ private static final UnicodeSet strictDotEquivalents = new UnicodeSet(
+ //"[.\u2024\uFE52\uFF0E\uFF61]"
+ 0x002E, 0x002E,
+ 0x2024, 0x2024,
+ 0xFE52, 0xFE52,
+ 0xFF0E, 0xFF0E,
+ 0xFF61, 0xFF61).freeze();
+
+ private static final UnicodeSet strictCommaEquivalents = new UnicodeSet(
+ //"[,\u066B\uFE10\uFE50\uFF0C]"
+ 0x002C, 0x002C,
+ 0x066B, 0x066B,
+ 0xFE10, 0xFE10,
+ 0xFE50, 0xFE50,
+ 0xFF0C, 0xFF0C).freeze();
+
+// private static final UnicodeSet strictOtherGroupingSeparators = new UnicodeSet(
+// //"[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]"
+// 0x0020, 0x0020,
+// 0x0027, 0x0027,
+// 0x00A0, 0x00A0,
+// 0x066C, 0x066C,
+// 0x2000, 0x200A,
+// 0x2018, 0x2019,
+// 0x202F, 0x202F,
+// 0x205F, 0x205F,
+// 0x3000, 0x3000,
+// 0xFF07, 0xFF07).freeze();
+
+ private static final UnicodeSet defaultGroupingSeparators =
+ // new UnicodeSet(dotEquivalents).addAll(commaEquivalents)
+ // .addAll(otherGroupingSeparators).freeze();
+ new UnicodeSet(
+ 0x0020, 0x0020,
+ 0x0027, 0x0027,
+ 0x002C, 0x002C,
+ 0x002E, 0x002E,
+ 0x00A0, 0x00A0,
+ 0x060C, 0x060C,
+ 0x066B, 0x066C,
+ 0x2000, 0x200A,
+ 0x2018, 0x2019,
+ 0x2024, 0x2024,
+ 0x202F, 0x202F,
+ 0x205F, 0x205F,
+ 0x3000, 0x3002,
+ 0xFE10, 0xFE12,
+ 0xFE50, 0xFE52,
+ 0xFF07, 0xFF07,
+ 0xFF0C, 0xFF0C,
+ 0xFF0E, 0xFF0E,
+ 0xFF61, 0xFF61,
+ 0xFF64, 0xFF64).freeze();
+
+ private static final UnicodeSet strictDefaultGroupingSeparators =
+ // new UnicodeSet(strictDotEquivalents).addAll(strictCommaEquivalents)
+ // .addAll(strictOtherGroupingSeparators).freeze();
+ new UnicodeSet(
+ 0x0020, 0x0020,
+ 0x0027, 0x0027,
+ 0x002C, 0x002C,
+ 0x002E, 0x002E,
+ 0x00A0, 0x00A0,
+ 0x066B, 0x066C,
+ 0x2000, 0x200A,
+ 0x2018, 0x2019,
+ 0x2024, 0x2024,
+ 0x202F, 0x202F,
+ 0x205F, 0x205F,
+ 0x3000, 0x3000,
+ 0xFE10, 0xFE10,
+ 0xFE50, 0xFE50,
+ 0xFE52, 0xFE52,
+ 0xFF07, 0xFF07,
+ 0xFF0C, 0xFF0C,
+ 0xFF0E, 0xFF0E,
+ 0xFF61, 0xFF61).freeze();
+
+ static final UnicodeSet minusSigns =
+ new UnicodeSet(
+ 0x002D, 0x002D,
+ 0x207B, 0x207B,
+ 0x208B, 0x208B,
+ 0x2212, 0x2212,
+ 0x2796, 0x2796,
+ 0xFE63, 0xFE63,
+ 0xFF0D, 0xFF0D).freeze();
+
+ static final UnicodeSet plusSigns =
+ new UnicodeSet(
+ 0x002B, 0x002B,
+ 0x207A, 0x207A,
+ 0x208A, 0x208A,
+ 0x2795, 0x2795,
+ 0xFB29, 0xFB29,
+ 0xFE62, 0xFE62,
+ 0xFF0B, 0xFF0B).freeze();
+
+ // equivalent grouping and decimal support
+ static final boolean skipExtendedSeparatorParsing = ICUConfig.get(
+ "com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "false")
+ .equals("true");
+
+ // allow control of requiring a matching decimal point when parsing
+ boolean parseRequireDecimalPoint = false;
+
+ // When parsing a number with big exponential value, it requires to transform the
+ // value into a string representation to construct BigInteger instance. We want to
+ // set the maximum size because it can easily trigger OutOfMemoryException.
+ // PARSE_MAX_EXPONENT is currently set to 1000 (See getParseMaxDigits()),
+ // which is much bigger than MAX_VALUE of Double ( See the problem reported by ticket#5698
+ private int PARSE_MAX_EXPONENT = 1000;
+
+ /**
+ * Parses the given text into a number. The text is parsed beginning at parsePosition,
+ * until an unparseable character is seen.
+ *
+ * @param text the string to parse.
+ * @param parsePosition the position at which to being parsing. Upon return, the first
+ * unparseable character.
+ * @param digits the DigitList to set to the parsed value.
+ * @param status Upon return contains boolean status flags indicating whether the
+ * value was infinite and whether it was positive.
+ * @param currency return value for parsed currency, for generic currency parsing
+ * mode, or null for normal parsing. In generic currency parsing mode, any currency is
+ * parsed, not just the currency that this formatter is set to.
+ * @param negPrefix negative prefix pattern
+ * @param negSuffix negative suffix pattern
+ * @param posPrefix positive prefix pattern
+ * @param negSuffix negative suffix pattern
+ * @param parseComplexCurrency whether it is complex currency parsing or not.
+ * @param type type of currency to parse against, LONG_NAME only or not.
+ */
+ private final boolean subparse(
+ String text, ParsePosition parsePosition, DigitList digits,
+ boolean status[], Currency currency[], String negPrefix, String negSuffix, String posPrefix,
+ String posSuffix, boolean parseComplexCurrency, int type) {
+
+ int position = parsePosition.getIndex();
+ int oldStart = parsePosition.getIndex();
+
+ // Match padding before prefix
+ if (formatWidth > 0 && padPosition == PAD_BEFORE_PREFIX) {
+ position = skipPadding(text, position);
+ }
+
+ // Match positive and negative prefixes; prefer longest match.
+ int posMatch = compareAffix(text, position, false, true, posPrefix, parseComplexCurrency, type, currency);
+ int negMatch = compareAffix(text, position, true, true, negPrefix, parseComplexCurrency, type, currency);
+ if (posMatch >= 0 && negMatch >= 0) {
+ if (posMatch > negMatch) {
+ negMatch = -1;
+ } else if (negMatch > posMatch) {
+ posMatch = -1;
+ }
+ }
+ if (posMatch >= 0) {
+ position += posMatch;
+ } else if (negMatch >= 0) {
+ position += negMatch;
+ } else {
+ parsePosition.setErrorIndex(position);
+ return false;
+ }
+
+ // Match padding after prefix
+ if (formatWidth > 0 && padPosition == PAD_AFTER_PREFIX) {
+ position = skipPadding(text, position);
+ }
+
+ // process digits or Inf, find decimal position
+ status[STATUS_INFINITE] = false;
+ if (text.regionMatches(position, symbols.getInfinity(), 0,
+ symbols.getInfinity().length())) {
+ position += symbols.getInfinity().length();
+ status[STATUS_INFINITE] = true;
+ } else {
+ // We now have a string of digits, possibly with grouping symbols, and decimal
+ // points. We want to process these into a DigitList. We don't want to put a
+ // bunch of leading zeros into the DigitList though, so we keep track of the
+ // location of the decimal point, put only significant digits into the
+ // DigitList, and adjust the exponent as needed.
+
+ digits.decimalAt = digits.count = 0;
+ String decimal = (currencySignCount == CURRENCY_SIGN_COUNT_ZERO) ?
+ symbols.getDecimalSeparatorString() : symbols.getMonetaryDecimalSeparatorString();
+ String grouping = (currencySignCount == CURRENCY_SIGN_COUNT_ZERO) ?
+ symbols.getGroupingSeparatorString() : symbols.getMonetaryGroupingSeparatorString();
+
+ String exponentSep = symbols.getExponentSeparator();
+ boolean sawDecimal = false;
+ boolean sawGrouping = false;
+ boolean sawDigit = false;
+ long exponent = 0; // Set to the exponent value, if any
+
+ // strict parsing
+ boolean strictParse = isParseStrict();
+ boolean strictFail = false; // did we exit with a strict parse failure?
+ int lastGroup = -1; // where did we last see a grouping separator?
+ int groupedDigitCount = 0; // tracking count of digits delimited by grouping separator
+ int gs2 = groupingSize2 == 0 ? groupingSize : groupingSize2;
+
+ UnicodeSet decimalEquiv = skipExtendedSeparatorParsing ? UnicodeSet.EMPTY :
+ getEquivalentDecimals(decimal, strictParse);
+ UnicodeSet groupEquiv = skipExtendedSeparatorParsing ? UnicodeSet.EMPTY :
+ (strictParse ? strictDefaultGroupingSeparators : defaultGroupingSeparators);
+
+ // We have to track digitCount ourselves, because digits.count will pin when
+ // the maximum allowable digits is reached.
+ int digitCount = 0;
+
+ int backup = -1; // used for preserving the last confirmed position
+ int[] parsedDigit = {-1}; // allocates int[1] for parsing a single digit
+
+ while (position < text.length()) {
+ // Check if the sequence at the current position matches a decimal digit
+ int matchLen = matchesDigit(text, position, parsedDigit);
+ if (matchLen > 0) {
+ // matched a digit
+ // Cancel out backup setting (see grouping handler below)
+ if (backup != -1) {
+ if (strictParse) {
+ // comma followed by digit, so group before comma is a secondary
+ // group. If there was a group separator before that, the group
+ // must == the secondary group length, else it can be <= the the
+ // secondary group length.
+ if ((lastGroup != -1 && groupedDigitCount != gs2)
+ || (lastGroup == -1 && groupedDigitCount > gs2)) {
+ strictFail = true;
+ break;
+ }
+ }
+ lastGroup = backup;
+ groupedDigitCount = 0;
+ }
+
+ groupedDigitCount++;
+ position += matchLen;
+ backup = -1;
+ sawDigit = true;
+ if (parsedDigit[0] == 0 && digits.count == 0) {
+ // Handle leading zeros
+ if (!sawDecimal) {
+ // Ignore leading zeros in integer part of number.
+ continue;
+ }
+ // If we have seen the decimal, but no significant digits yet,
+ // then we account for leading zeros by decrementing the
+ // digits.decimalAt into negative values.
+ --digits.decimalAt;
+ } else {
+ ++digitCount;
+ digits.append((char) (parsedDigit[0] + '0'));
+ }
+ continue;
+ }
+
+ // Check if the sequence at the current position matches locale's decimal separator
+ int decimalStrLen = decimal.length();
+ if (text.regionMatches(position, decimal, 0, decimalStrLen)) {
+ // matched a decimal separator
+ if (strictParse) {
+ if (backup != -1 ||
+ (lastGroup != -1 && groupedDigitCount != groupingSize)) {
+ strictFail = true;
+ break;
+ }
+ }
+
+ // If we're only parsing integers, or if we ALREADY saw the decimal,
+ // then don't parse this one.
+ if (isParseIntegerOnly() || sawDecimal) {
+ break;
+ }
+
+ digits.decimalAt = digitCount; // Not digits.count!
+ sawDecimal = true;
+ position += decimalStrLen;
+ continue;
+ }
+
+ if (isGroupingUsed()) {
+ // Check if the sequence at the current position matches locale's grouping separator
+ int groupingStrLen = grouping.length();
+ if (text.regionMatches(position, grouping, 0, groupingStrLen)) {
+ if (sawDecimal) {
+ break;
+ }
+
+ if (strictParse) {
+ if ((!sawDigit || backup != -1)) {
+ // leading group, or two group separators in a row
+ strictFail = true;
+ break;
+ }
+ }
+
+ // Ignore grouping characters, if we are using them, but require that
+ // they be followed by a digit. Otherwise we backup and reprocess
+ // them.
+ backup = position;
+ position += groupingStrLen;
+ sawGrouping = true;
+ continue;
+ }
+ }
+
+ // Check if the code point at the current position matches one of decimal/grouping equivalent group chars
+ int cp = text.codePointAt(position);
+ if (!sawDecimal && decimalEquiv.contains(cp)) {
+ // matched a decimal separator
+ if (strictParse) {
+ if (backup != -1 ||
+ (lastGroup != -1 && groupedDigitCount != groupingSize)) {
+ strictFail = true;
+ break;
+ }
+ }
+
+ // If we're only parsing integers, or if we ALREADY saw the decimal,
+ // then don't parse this one.
+ if (isParseIntegerOnly()) {
+ break;
+ }
+
+ digits.decimalAt = digitCount; // Not digits.count!
+
+ // Once we see a decimal separator character, we only accept that
+ // decimal separator character from then on.
+ decimal = String.valueOf(Character.toChars(cp));
+
+ sawDecimal = true;
+ position += Character.charCount(cp);
+ continue;
+ }
+
+ if (isGroupingUsed() && !sawGrouping && groupEquiv.contains(cp)) {
+ // matched a grouping separator
+ if (sawDecimal) {
+ break;
+ }
+
+ if (strictParse) {
+ if ((!sawDigit || backup != -1)) {
+ // leading group, or two group separators in a row
+ strictFail = true;
+ break;
+ }
+ }
+
+ // Once we see a grouping character, we only accept that grouping
+ // character from then on.
+ grouping = String.valueOf(Character.toChars(cp));
+
+ // Ignore grouping characters, if we are using them, but require that
+ // they be followed by a digit. Otherwise we backup and reprocess
+ // them.
+ backup = position;
+ position += Character.charCount(cp);
+ sawGrouping = true;
+ continue;
+ }
+
+ // Check if the sequence at the current position matches locale's exponent separator
+ int exponentSepStrLen = exponentSep.length();
+ if (text.regionMatches(true, position, exponentSep, 0, exponentSepStrLen)) {
+ // parse sign, if present
+ boolean negExp = false;
+ int pos = position + exponentSep.length();
+ if (pos < text.length()) {
+ String plusSign = symbols.getPlusSignString();
+ String minusSign = symbols.getMinusSignString();
+ if (text.regionMatches(pos, plusSign, 0, plusSign.length())) {
+ pos += plusSign.length();
+ } else if (text.regionMatches(pos, minusSign, 0, minusSign.length())) {
+ pos += minusSign.length();
+ negExp = true;
+ }
+ }
+
+ DigitList exponentDigits = new DigitList();
+ exponentDigits.count = 0;
+ while (pos < text.length()) {
+ int digitMatchLen = matchesDigit(text, pos, parsedDigit);
+ if (digitMatchLen > 0) {
+ exponentDigits.append((char) (parsedDigit[0] + '0'));
+ pos += digitMatchLen;
+ } else {
+ break;
+ }
+ }
+
+ if (exponentDigits.count > 0) {
+ // defer strict parse until we know we have a bona-fide exponent
+ if (strictParse && sawGrouping) {
+ strictFail = true;
+ break;
+ }
+
+ // Quick overflow check for exponential part. Actual limit check
+ // will be done later in this code.
+ if (exponentDigits.count > 10 /* maximum decimal digits for int */) {
+ if (negExp) {
+ // set underflow flag
+ status[STATUS_UNDERFLOW] = true;
+ } else {
+ // set infinite flag
+ status[STATUS_INFINITE] = true;
+ }
+ } else {
+ exponentDigits.decimalAt = exponentDigits.count;
+ exponent = exponentDigits.getLong();
+ if (negExp) {
+ exponent = -exponent;
+ }
+ }
+ position = pos; // Advance past the exponent
+ }
+
+ break; // Whether we fail or succeed, we exit this loop
+ }
+
+ // All other cases, stop parsing
+ break;
+ }
+
+ if (digits.decimalAt == 0 && isDecimalPatternMatchRequired()) {
+ if (this.formatPattern.indexOf(decimal) != -1) {
+ parsePosition.setIndex(oldStart);
+ parsePosition.setErrorIndex(position);
+ return false;
+ }
+ }
+
+ if (backup != -1)
+ position = backup;
+
+ // If there was no decimal point we have an integer
+ if (!sawDecimal) {
+ digits.decimalAt = digitCount; // Not digits.count!
+ }
+
+ // check for strict parse errors
+ if (strictParse && !sawDecimal) {
+ if (lastGroup != -1 && groupedDigitCount != groupingSize) {
+ strictFail = true;
+ }
+ }
+ if (strictFail) {
+ // only set with strictParse and a leading zero error leading zeros are an
+ // error with strict parsing except immediately before nondigit (except
+ // group separator followed by digit), or end of text.
+
+ parsePosition.setIndex(oldStart);
+ parsePosition.setErrorIndex(position);
+ return false;
+ }
+
+ // Adjust for exponent, if any
+ exponent += digits.decimalAt;
+ if (exponent < -getParseMaxDigits()) {
+ status[STATUS_UNDERFLOW] = true;
+ } else if (exponent > getParseMaxDigits()) {
+ status[STATUS_INFINITE] = true;
+ } else {
+ digits.decimalAt = (int) exponent;
+ }
+
+ // If none of the text string was recognized. For example, parse "x" with
+ // pattern "#0.00" (return index and error index both 0) parse "$" with
+ // pattern "$#0.00". (return index 0 and error index 1).
+ if (!sawDigit && digitCount == 0) {
+ parsePosition.setIndex(oldStart);
+ parsePosition.setErrorIndex(oldStart);
+ return false;
+ }
+ }
+
+ // Match padding before suffix
+ if (formatWidth > 0 && padPosition == PAD_BEFORE_SUFFIX) {
+ position = skipPadding(text, position);
+ }
+
+ // Match positive and negative suffixes; prefer longest match.
+ if (posMatch >= 0) {
+ posMatch = compareAffix(text, position, false, false, posSuffix, parseComplexCurrency, type, currency);
+ }
+ if (negMatch >= 0) {
+ negMatch = compareAffix(text, position, true, false, negSuffix, parseComplexCurrency, type, currency);
+ }
+ if (posMatch >= 0 && negMatch >= 0) {
+ if (posMatch > negMatch) {
+ negMatch = -1;
+ } else if (negMatch > posMatch) {
+ posMatch = -1;
+ }
+ }
+
+ // Fail if neither or both
+ if ((posMatch >= 0) == (negMatch >= 0)) {
+ parsePosition.setErrorIndex(position);
+ return false;
+ }
+
+ position += (posMatch >= 0 ? posMatch : negMatch);
+
+ // Match padding after suffix
+ if (formatWidth > 0 && padPosition == PAD_AFTER_SUFFIX) {
+ position = skipPadding(text, position);
+ }
+
+ parsePosition.setIndex(position);
+
+ status[STATUS_POSITIVE] = (posMatch >= 0);
+
+ if (parsePosition.getIndex() == oldStart) {
+ parsePosition.setErrorIndex(position);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if the substring at the specified position matches a decimal digit.
+ * If matched, this method sets the decimal value to <code>decVal</code> and
+ * returns matched length.
+ *
+ * @param str The input string
+ * @param start The start index
+ * @param decVal Receives decimal value
+ * @return Length of match, or 0 if the sequence at the position is not
+ * a decimal digit.
+ */
+ private int matchesDigit(String str, int start, int[] decVal) {
+ String[] localeDigits = symbols.getDigitStringsLocal();
+
+ // Check if the sequence at the current position matches locale digits.
+ for (int i = 0; i < 10; i++) {
+ int digitStrLen = localeDigits[i].length();
+ if (str.regionMatches(start, localeDigits[i], 0, digitStrLen)) {
+ decVal[0] = i;
+ return digitStrLen;
+ }
+ }
+
+ // If no locale digit match, then check if this is a Unicode digit
+ int cp = str.codePointAt(start);
+ decVal[0] = UCharacter.digit(cp, 10);
+ if (decVal[0] >= 0) {
+ return Character.charCount(cp);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Returns a set of characters equivalent to the given desimal separator used for
+ * parsing number. This method may return an empty set.
+ */
+ private UnicodeSet getEquivalentDecimals(String decimal, boolean strictParse) {
+ UnicodeSet equivSet = UnicodeSet.EMPTY;
+ if (strictParse) {
+ if (strictDotEquivalents.contains(decimal)) {
+ equivSet = strictDotEquivalents;
+ } else if (strictCommaEquivalents.contains(decimal)) {
+ equivSet = strictCommaEquivalents;
+ }
+ } else {
+ if (dotEquivalents.contains(decimal)) {
+ equivSet = dotEquivalents;
+ } else if (commaEquivalents.contains(decimal)) {
+ equivSet = commaEquivalents;
+ }
+ }
+ return equivSet;
+ }
+
+ /**
+ * Starting at position, advance past a run of pad characters, if any. Return the
+ * index of the first character after position that is not a pad character. Result is
+ * >= position.
+ */
+ private final int skipPadding(String text, int position) {
+ while (position < text.length() && text.charAt(position) == pad) {
+ ++position;
+ }
+ return position;
+ }
+
+ /**
+ * Returns the length matched by the given affix, or -1 if none. Runs of white space
+ * in the affix, match runs of white space in the input. Pattern white space and input
+ * white space are determined differently; see code.
+ *
+ * @param text input text
+ * @param pos offset into input at which to begin matching
+ * @param isNegative
+ * @param isPrefix
+ * @param affixPat affix pattern used for currency affix comparison
+ * @param complexCurrencyParsing whether it is currency parsing or not
+ * @param type compare against currency type, LONG_NAME only or not.
+ * @param currency return value for parsed currency, for generic currency parsing
+ * mode, or null for normal parsing. In generic currency parsing mode, any currency
+ * is parsed, not just the currency that this formatter is set to.
+ * @return length of input that matches, or -1 if match failure
+ */
+ private int compareAffix(String text, int pos, boolean isNegative, boolean isPrefix,
+ String affixPat, boolean complexCurrencyParsing, int type, Currency[] currency) {
+ if (currency != null || currencyChoice != null || (currencySignCount != CURRENCY_SIGN_COUNT_ZERO && complexCurrencyParsing)) {
+ return compareComplexAffix(affixPat, text, pos, type, currency);
+ }
+ if (isPrefix) {
+ return compareSimpleAffix(isNegative ? negativePrefix : positivePrefix, text, pos);
+ } else {
+ return compareSimpleAffix(isNegative ? negativeSuffix : positiveSuffix, text, pos);
+ }
+
+ }
+
+ /**
+ * Check for bidi marks: LRM, RLM, ALM
+ */
+ private static boolean isBidiMark(int c) {
+ return (c==0x200E || c==0x200F || c==0x061C);
+ }
+
+ /**
+ * Remove bidi marks from affix
+ */
+ private static String trimMarksFromAffix(String affix) {
+ boolean hasBidiMark = false;
+ int idx = 0;
+ for (; idx < affix.length(); idx++) {
+ if (isBidiMark(affix.charAt(idx))) {
+ hasBidiMark = true;
+ break;
+ }
+ }
+ if (!hasBidiMark) {
+ return affix;
+ }
+
+ StringBuilder buf = new StringBuilder();
+ buf.append(affix, 0, idx);
+ idx++; // skip the first Bidi mark
+ for (; idx < affix.length(); idx++) {
+ char c = affix.charAt(idx);
+ if (!isBidiMark(c)) {
+ buf.append(c);
+ }
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Return the length matched by the given affix, or -1 if none. Runs of white space in
+ * the affix, match runs of white space in the input. Pattern white space and input
+ * white space are determined differently; see code.
+ *
+ * @param affix pattern string, taken as a literal
+ * @param input input text
+ * @param pos offset into input at which to begin matching
+ * @return length of input that matches, or -1 if match failure
+ */
+ private static int compareSimpleAffix(String affix, String input, int pos) {
+ int start = pos;
+ // Affixes here might consist of sign, currency symbol and related spacing, etc.
+ // For more efficiency we should keep lazily-created trimmed affixes around in
+ // instance variables instead of trimming each time they are used (the next step).
+ String trimmedAffix = (affix.length() > 1)? trimMarksFromAffix(affix): affix;
+ for (int i = 0; i < trimmedAffix.length();) {
+ int c = UTF16.charAt(trimmedAffix, i);
+ int len = UTF16.getCharCount(c);
+ if (PatternProps.isWhiteSpace(c)) {
+ // We may have a pattern like: \u200F and input text like: \u200F Note
+ // that U+200F and U+0020 are Pattern_White_Space but only U+0020 is
+ // UWhiteSpace. So we have to first do a direct match of the run of RULE
+ // whitespace in the pattern, then match any extra characters.
+ boolean literalMatch = false;
+ while (pos < input.length()) {
+ int ic = UTF16.charAt(input, pos);
+ if (ic == c) {
+ literalMatch = true;
+ i += len;
+ pos += len;
+ if (i == trimmedAffix.length()) {
+ break;
+ }
+ c = UTF16.charAt(trimmedAffix, i);
+ len = UTF16.getCharCount(c);
+ if (!PatternProps.isWhiteSpace(c)) {
+ break;
+ }
+ } else if (isBidiMark(ic)) {
+ pos++; // just skip over this input text
+ } else {
+ break;
+ }
+ }
+
+ // Advance over run in trimmedAffix
+ i = skipPatternWhiteSpace(trimmedAffix, i);
+
+ // Advance over run in input text. Must see at least one white space char
+ // in input, unless we've already matched some characters literally.
+ int s = pos;
+ pos = skipUWhiteSpace(input, pos);
+ if (pos == s && !literalMatch) {
+ return -1;
+ }
+ // If we skip UWhiteSpace in the input text, we need to skip it in the
+ // pattern. Otherwise, the previous lines may have skipped over text
+ // (such as U+00A0) that is also in the trimmedAffix.
+ i = skipUWhiteSpace(trimmedAffix, i);
+ } else {
+ boolean match = false;
+ while (pos < input.length()) {
+ int ic = UTF16.charAt(input, pos);
+ if (!match && equalWithSignCompatibility(ic, c)) {
+ i += len;
+ pos += len;
+ match = true;
+ } else if (isBidiMark(ic)) {
+ pos++; // just skip over this input text
+ } else {
+ break;
+ }
+ }
+ if (!match) {
+ return -1;
+ }
+ }
+ }
+ return pos - start;
+ }
+
+ private static boolean equalWithSignCompatibility(int lhs, int rhs) {
+ return lhs == rhs
+ || (minusSigns.contains(lhs) && minusSigns.contains(rhs))
+ || (plusSigns.contains(lhs) && plusSigns.contains(rhs));
+ }
+
+ /**
+ * Skips over a run of zero or more Pattern_White_Space characters at pos in text.
+ */
+ private static int skipPatternWhiteSpace(String text, int pos) {
+ while (pos < text.length()) {
+ int c = UTF16.charAt(text, pos);
+ if (!PatternProps.isWhiteSpace(c)) {
+ break;
+ }
+ pos += UTF16.getCharCount(c);
+ }
+ return pos;
+ }
+
+ /**
+ * Skips over a run of zero or more isUWhiteSpace() characters at pos in text.
+ */
+ private static int skipUWhiteSpace(String text, int pos) {
+ while (pos < text.length()) {
+ int c = UTF16.charAt(text, pos);
+ if (!UCharacter.isUWhiteSpace(c)) {
+ break;
+ }
+ pos += UTF16.getCharCount(c);
+ }
+ return pos;
+ }
+
+ /**
+ * Skips over a run of zero or more bidi marks at pos in text.
+ */
+ private static int skipBidiMarks(String text, int pos) {
+ while (pos < text.length()) {
+ int c = UTF16.charAt(text, pos);
+ if (!isBidiMark(c)) {
+ break;
+ }
+ pos += UTF16.getCharCount(c);
+ }
+ return pos;
+ }
+
+ /**
+ * Returns the length matched by the given affix, or -1 if none.
+ *
+ * @param affixPat pattern string
+ * @param text input text
+ * @param pos offset into input at which to begin matching
+ * @param type parse against currency type, LONG_NAME only or not.
+ * @param currency return value for parsed currency, for generic
+ * currency parsing mode, or null for normal parsing. In generic
+ * currency parsing mode, any currency is parsed, not just the
+ * currency that this formatter is set to.
+ * @return position after the matched text, or -1 if match failure
+ */
+ private int compareComplexAffix(String affixPat, String text, int pos, int type,
+ Currency[] currency) {
+ int start = pos;
+ for (int i = 0; i < affixPat.length() && pos >= 0;) {
+ char c = affixPat.charAt(i++);
+ if (c == QUOTE) {
+ for (;;) {
+ int j = affixPat.indexOf(QUOTE, i);
+ if (j == i) {
+ pos = match(text, pos, QUOTE);
+ i = j + 1;
+ break;
+ } else if (j > i) {
+ pos = match(text, pos, affixPat.substring(i, j));
+ i = j + 1;
+ if (i < affixPat.length() && affixPat.charAt(i) == QUOTE) {
+ pos = match(text, pos, QUOTE);
+ ++i;
+ // loop again
+ } else {
+ break;
+ }
+ } else {
+ // Unterminated quote; should be caught by apply
+ // pattern.
+ throw new RuntimeException();
+ }
+ }
+ continue;
+ }
+
+ String affix = null;
+
+ switch (c) {
+ case CURRENCY_SIGN:
+ // since the currency names in choice format is saved the same way as
+ // other currency names, do not need to do currency choice parsing here.
+ // the general currency parsing parse against all names, including names
+ // in choice format. assert(currency != null || (getCurrency() != null &&
+ // currencyChoice != null));
+ boolean intl = i < affixPat.length() && affixPat.charAt(i) == CURRENCY_SIGN;
+ if (intl) {
+ ++i;
+ }
+ boolean plural = i < affixPat.length() && affixPat.charAt(i) == CURRENCY_SIGN;
+ if (plural) {
+ ++i;
+ intl = false;
+ }
+ // Parse generic currency -- anything for which we have a display name, or
+ // any 3-letter ISO code. Try to parse display name for our locale; first
+ // determine our locale. TODO: use locale in CurrencyPluralInfo
+ ULocale uloc = getLocale(ULocale.VALID_LOCALE);
+ if (uloc == null) {
+ // applyPattern has been called; use the symbols
+ uloc = symbols.getLocale(ULocale.VALID_LOCALE);
+ }
+ // Delegate parse of display name => ISO code to Currency
+ ParsePosition ppos = new ParsePosition(pos);
+ // using Currency.parse to handle mixed style parsing.
+ String iso = Currency.parse(uloc, text, type, ppos);
+
+ // If parse succeeds, populate currency[0]
+ if (iso != null) {
+ if (currency != null) {
+ currency[0] = Currency.getInstance(iso);
+ } else {
+ // The formatter is currency-style but the client has not requested
+ // the value of the parsed currency. In this case, if that value does
+ // not match the formatter's current value, then the parse fails.
+ Currency effectiveCurr = getEffectiveCurrency();
+ if (iso.compareTo(effectiveCurr.getCurrencyCode()) != 0) {
+ pos = -1;
+ continue;
+ }
+ }
+ pos = ppos.getIndex();
+ } else {
+ pos = -1;
+ }
+ continue;
+ case PATTERN_PERCENT:
+ affix = symbols.getPercentString();
+ break;
+ case PATTERN_PER_MILLE:
+ affix = symbols.getPerMillString();
+ break;
+ case PATTERN_PLUS_SIGN:
+ affix = symbols.getPlusSignString();
+ break;
+ case PATTERN_MINUS_SIGN:
+ affix = symbols.getMinusSignString();
+ break;
+ default:
+ // fall through to affix != null test, which will fail
+ break;
+ }
+
+ if (affix != null) {
+ pos = match(text, pos, affix);
+ continue;
+ }
+
+ pos = match(text, pos, c);
+ if (PatternProps.isWhiteSpace(c)) {
+ i = skipPatternWhiteSpace(affixPat, i);
+ }
+ }
+
+ return pos - start;
+ }
+
+ /**
+ * Matches a single character at text[pos] and return the index of the next character
+ * upon success. Return -1 on failure. If ch is a Pattern_White_Space then match a run of
+ * white space in text.
+ */
+ static final int match(String text, int pos, int ch) {
+ if (pos < 0 || pos >= text.length()) {
+ return -1;
+ }
+ pos = skipBidiMarks(text, pos);
+ if (PatternProps.isWhiteSpace(ch)) {
+ // Advance over run of white space in input text
+ // Must see at least one white space char in input
+ int s = pos;
+ pos = skipPatternWhiteSpace(text, pos);
+ if (pos == s) {
+ return -1;
+ }
+ return pos;
+ }
+ if (pos >= text.length() || UTF16.charAt(text, pos) != ch) {
+ return -1;
+ }
+ pos = skipBidiMarks(text, pos + UTF16.getCharCount(ch));
+ return pos;
+ }
+
+ /**
+ * Matches a string at text[pos] and return the index of the next character upon
+ * success. Return -1 on failure. Match a run of white space in str with a run of
+ * white space in text.
+ */
+ static final int match(String text, int pos, String str) {
+ for (int i = 0; i < str.length() && pos >= 0;) {
+ int ch = UTF16.charAt(str, i);
+ i += UTF16.getCharCount(ch);
+ if (isBidiMark(ch)) {
+ continue;
+ }
+ pos = match(text, pos, ch);
+ if (PatternProps.isWhiteSpace(ch)) {
+ i = skipPatternWhiteSpace(str, i);
+ }
+ }
+ return pos;
+ }
+
+ /**
+ * Returns a copy of the decimal format symbols used by this format.
+ *
+ * @return desired DecimalFormatSymbols
+ * @see DecimalFormatSymbols
+ * @stable ICU 2.0
+ */
+ public DecimalFormatSymbols getDecimalFormatSymbols() {
+ try {
+ // don't allow multiple references
+ return (DecimalFormatSymbols) symbols.clone();
+ } catch (Exception foo) {
+ return null; // should never happen
+ }
+ }
+
+ /**
+ * Sets the decimal format symbols used by this format. The format uses a copy of the
+ * provided symbols.
+ *
+ * @param newSymbols desired DecimalFormatSymbols
+ * @see DecimalFormatSymbols
+ * @stable ICU 2.0
+ */
+ public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
+ symbols = (DecimalFormatSymbols) newSymbols.clone();
+ setCurrencyForSymbols();
+ expandAffixes(null);
+ }
+
+ /**
+ * Update the currency object to match the symbols. This method is used only when the
+ * caller has passed in a symbols object that may not be the default object for its
+ * locale.
+ */
+ private void setCurrencyForSymbols() {
+
+ // Bug 4212072 Update the affix strings according to symbols in order to keep the
+ // affix strings up to date. [Richard/GCL]
+
+ // With the introduction of the Currency object, the currency symbols in the DFS
+ // object are ignored. For backward compatibility, we check any explicitly set DFS
+ // object. If it is a default symbols object for its locale, we change the
+ // currency object to one for that locale. If it is custom, we set the currency to
+ // null.
+ DecimalFormatSymbols def = new DecimalFormatSymbols(symbols.getULocale());
+
+ if (symbols.getCurrencySymbol().equals(def.getCurrencySymbol())
+ && symbols.getInternationalCurrencySymbol()
+ .equals(def.getInternationalCurrencySymbol())) {
+ setCurrency(Currency.getInstance(symbols.getULocale()));
+ } else {
+ setCurrency(null);
+ }
+ }
+
+ /**
+ * Returns the positive prefix.
+ *
+ * <p>Examples: +123, $123, sFr123
+ * @return the prefix
+ * @stable ICU 2.0
+ */
+ public String getPositivePrefix() {
+ return positivePrefix;
+ }
+
+ /**
+ * Sets the positive prefix.
+ *
+ * <p>Examples: +123, $123, sFr123
+ * @param newValue the prefix
+ * @stable ICU 2.0
+ */
+ public void setPositivePrefix(String newValue) {
+ positivePrefix = newValue;
+ posPrefixPattern = null;
+ }
+
+ /**
+ * Returns the negative prefix.
+ *
+ * <p>Examples: -123, ($123) (with negative suffix), sFr-123
+ *
+ * @return the prefix
+ * @stable ICU 2.0
+ */
+ public String getNegativePrefix() {
+ return negativePrefix;
+ }
+
+ /**
+ * Sets the negative prefix.
+ *
+ * <p>Examples: -123, ($123) (with negative suffix), sFr-123
+ * @param newValue the prefix
+ * @stable ICU 2.0
+ */
+ public void setNegativePrefix(String newValue) {
+ negativePrefix = newValue;
+ negPrefixPattern = null;
+ }
+
+ /**
+ * Returns the positive suffix.
+ *
+ * <p>Example: 123%
+ *
+ * @return the suffix
+ * @stable ICU 2.0
+ */
+ public String getPositiveSuffix() {
+ return positiveSuffix;
+ }
+
+ /**
+ * Sets the positive suffix.
+ *
+ * <p>Example: 123%
+ * @param newValue the suffix
+ * @stable ICU 2.0
+ */
+ public void setPositiveSuffix(String newValue) {
+ positiveSuffix = newValue;
+ posSuffixPattern = null;
+ }
+
+ /**
+ * Returns the negative suffix.
+ *
+ * <p>Examples: -123%, ($123) (with positive suffixes)
+ *
+ * @return the suffix
+ * @stable ICU 2.0
+ */
+ public String getNegativeSuffix() {
+ return negativeSuffix;
+ }
+
+ /**
+ * Sets the positive suffix.
+ *
+ * <p>Examples: 123%
+ * @param newValue the suffix
+ * @stable ICU 2.0
+ */
+ public void setNegativeSuffix(String newValue) {
+ negativeSuffix = newValue;
+ negSuffixPattern = null;
+ }
+
+ /**
+ * Returns the multiplier for use in percent, permill, etc. For a percentage, set the
+ * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent
+ * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be
+ * 1000.
+ *
+ * <p>Examples: with 100, 1.23 -&gt; "123", and "123" -&gt; 1.23
+ *
+ * @return the multiplier
+ * @stable ICU 2.0
+ */
+ public int getMultiplier() {
+ return multiplier;
+ }
+
+ /**
+ * Sets the multiplier for use in percent, permill, etc. For a percentage, set the
+ * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent
+ * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be
+ * 1000.
+ *
+ * <p>Examples: with 100, 1.23 -&gt; "123", and "123" -&gt; 1.23
+ *
+ * @param newValue the multiplier
+ * @stable ICU 2.0
+ */
+ public void setMultiplier(int newValue) {
+ if (newValue == 0) {
+ throw new IllegalArgumentException("Bad multiplier: " + newValue);
+ }
+ multiplier = newValue;
+ }
+
+ /**
+ * {@icu} Returns the rounding increment.
+ *
+ * @return A positive rounding increment, or <code>null</code> if a custom rounding
+ * increment is not in effect.
+ * @see #setRoundingIncrement
+ * @see #getRoundingMode
+ * @see #setRoundingMode
+ * @stable ICU 2.0
+ */
+ public java.math.BigDecimal getRoundingIncrement() {
+ if (roundingIncrementICU == null)
+ return null;
+ return roundingIncrementICU.toBigDecimal();
+ }
+
+ /**
+ * {@icu} Sets the rounding increment. In the absence of a rounding increment, numbers
+ * will be rounded to the number of digits displayed.
+ *
+ * @param newValue A positive rounding increment, or <code>null</code> or
+ * <code>BigDecimal(0.0)</code> to use the default rounding increment.
+ * @throws IllegalArgumentException if <code>newValue</code> is &lt; 0.0
+ * @see #getRoundingIncrement
+ * @see #getRoundingMode
+ * @see #setRoundingMode
+ * @stable ICU 2.0
+ */
+ public void setRoundingIncrement(java.math.BigDecimal newValue) {
+ if (newValue == null) {
+ setRoundingIncrement((BigDecimal) null);
+ } else {
+ setRoundingIncrement(new BigDecimal(newValue));
+ }
+ }
+
+ /**
+ * {@icu} Sets the rounding increment. In the absence of a rounding increment, numbers
+ * will be rounded to the number of digits displayed.
+ *
+ * @param newValue A positive rounding increment, or <code>null</code> or
+ * <code>BigDecimal(0.0)</code> to use the default rounding increment.
+ * @throws IllegalArgumentException if <code>newValue</code> is &lt; 0.0
+ * @see #getRoundingIncrement
+ * @see #getRoundingMode
+ * @see #setRoundingMode
+ * @stable ICU 3.6
+ */
+ public void setRoundingIncrement(BigDecimal newValue) {
+ int i = newValue == null ? 0 : newValue.compareTo(BigDecimal.ZERO);
+ if (i < 0) {
+ throw new IllegalArgumentException("Illegal rounding increment");
+ }
+ if (i == 0) {
+ setInternalRoundingIncrement(null);
+ } else {
+ setInternalRoundingIncrement(newValue);
+ }
+ resetActualRounding();
+ }
+
+ /**
+ * {@icu} Sets the rounding increment. In the absence of a rounding increment, numbers
+ * will be rounded to the number of digits displayed.
+ *
+ * @param newValue A positive rounding increment, or 0.0 to use the default
+ * rounding increment.
+ * @throws IllegalArgumentException if <code>newValue</code> is &lt; 0.0
+ * @see #getRoundingIncrement
+ * @see #getRoundingMode
+ * @see #setRoundingMode
+ * @stable ICU 2.0
+ */
+ public void setRoundingIncrement(double newValue) {
+ if (newValue < 0.0) {
+ throw new IllegalArgumentException("Illegal rounding increment");
+ }
+ if (newValue == 0.0d) {
+ setInternalRoundingIncrement((BigDecimal) null);
+ } else {
+ // Should use BigDecimal#valueOf(double) instead of constructor
+ // to avoid the double precision problem.
+ setInternalRoundingIncrement(BigDecimal.valueOf(newValue));
+ }
+ resetActualRounding();
+ }
+
+ /**
+ * Returns the rounding mode.
+ *
+ * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
+ * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+ * @see #setRoundingIncrement
+ * @see #getRoundingIncrement
+ * @see #setRoundingMode
+ * @see java.math.BigDecimal
+ * @stable ICU 2.0
+ */
+ @Override
+ public int getRoundingMode() {
+ return roundingMode;
+ }
+
+ /**
+ * Sets the rounding mode. This has no effect unless the rounding increment is greater
+ * than zero.
+ *
+ * @param roundingMode A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
+ * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+ * @exception IllegalArgumentException if <code>roundingMode</code> is unrecognized.
+ * @see #setRoundingIncrement
+ * @see #getRoundingIncrement
+ * @see #getRoundingMode
+ * @see java.math.BigDecimal
+ * @stable ICU 2.0
+ */
+ @Override
+ public void setRoundingMode(int roundingMode) {
+ if (roundingMode < BigDecimal.ROUND_UP || roundingMode > BigDecimal.ROUND_UNNECESSARY) {
+ throw new IllegalArgumentException("Invalid rounding mode: " + roundingMode);
+ }
+
+ this.roundingMode = roundingMode;
+ resetActualRounding();
+ }
+
+ /**
+ * Returns the width to which the output of <code>format()</code> is padded. The width is
+ * counted in 16-bit code units.
+ *
+ * @return the format width, or zero if no padding is in effect
+ * @see #setFormatWidth
+ * @see #getPadCharacter
+ * @see #setPadCharacter
+ * @see #getPadPosition
+ * @see #setPadPosition
+ * @stable ICU 2.0
+ */
+ public int getFormatWidth() {
+ return formatWidth;
+ }
+
+ /**
+ * Sets the width to which the output of <code>format()</code> is
+ * padded. The width is counted in 16-bit code units. This method
+ * also controls whether padding is enabled.
+ *
+ * @param width the width to which to pad the result of
+ * <code>format()</code>, or zero to disable padding
+ * @exception IllegalArgumentException if <code>width</code> is &lt; 0
+ * @see #getFormatWidth
+ * @see #getPadCharacter
+ * @see #setPadCharacter
+ * @see #getPadPosition
+ * @see #setPadPosition
+ * @stable ICU 2.0
+ */
+ public void setFormatWidth(int width) {
+ if (width < 0) {
+ throw new IllegalArgumentException("Illegal format width");
+ }
+ formatWidth = width;
+ }
+
+ /**
+ * {@icu} Returns the character used to pad to the format width. The default is ' '.
+ *
+ * @return the pad character
+ * @see #setFormatWidth
+ * @see #getFormatWidth
+ * @see #setPadCharacter
+ * @see #getPadPosition
+ * @see #setPadPosition
+ * @stable ICU 2.0
+ */
+ public char getPadCharacter() {
+ return pad;
+ }
+
+ /**
+ * {@icu} Sets the character used to pad to the format width. If padding is not
+ * enabled, then this will take effect if padding is later enabled.
+ *
+ * @param padChar the pad character
+ * @see #setFormatWidth
+ * @see #getFormatWidth
+ * @see #getPadCharacter
+ * @see #getPadPosition
+ * @see #setPadPosition
+ * @stable ICU 2.0
+ */
+ public void setPadCharacter(char padChar) {
+ pad = padChar;
+ }
+
+ /**
+ * {@icu} Returns the position at which padding will take place. This is the location at
+ * which padding will be inserted if the result of <code>format()</code> is shorter
+ * than the format width.
+ *
+ * @return the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
+ * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
+ * <code>PAD_AFTER_SUFFIX</code>.
+ * @see #setFormatWidth
+ * @see #getFormatWidth
+ * @see #setPadCharacter
+ * @see #getPadCharacter
+ * @see #setPadPosition
+ * @see #PAD_BEFORE_PREFIX
+ * @see #PAD_AFTER_PREFIX
+ * @see #PAD_BEFORE_SUFFIX
+ * @see #PAD_AFTER_SUFFIX
+ * @stable ICU 2.0
+ */
+ public int getPadPosition() {
+ return padPosition;
+ }
+
+ /**
+ * {@icu} Sets the position at which padding will take place. This is the location at
+ * which padding will be inserted if the result of <code>format()</code> is shorter
+ * than the format width. This has no effect unless padding is enabled.
+ *
+ * @param padPos the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
+ * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
+ * <code>PAD_AFTER_SUFFIX</code>.
+ * @exception IllegalArgumentException if the pad position in unrecognized
+ * @see #setFormatWidth
+ * @see #getFormatWidth
+ * @see #setPadCharacter
+ * @see #getPadCharacter
+ * @see #getPadPosition
+ * @see #PAD_BEFORE_PREFIX
+ * @see #PAD_AFTER_PREFIX
+ * @see #PAD_BEFORE_SUFFIX
+ * @see #PAD_AFTER_SUFFIX
+ * @stable ICU 2.0
+ */
+ public void setPadPosition(int padPos) {
+ if (padPos < PAD_BEFORE_PREFIX || padPos > PAD_AFTER_SUFFIX) {
+ throw new IllegalArgumentException("Illegal pad position");
+ }
+ padPosition = padPos;
+ }
+
+ /**
+ * {@icu} Returns whether or not scientific notation is used.
+ *
+ * @return true if this object formats and parses scientific notation
+ * @see #setScientificNotation
+ * @see #getMinimumExponentDigits
+ * @see #setMinimumExponentDigits
+ * @see #isExponentSignAlwaysShown
+ * @see #setExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public boolean isScientificNotation() {
+ return useExponentialNotation;
+ }
+
+ /**
+ * {@icu} Sets whether or not scientific notation is used. When scientific notation is
+ * used, the effective maximum number of integer digits is &lt;= 8. If the maximum number
+ * of integer digits is set to more than 8, the effective maximum will be 1. This
+ * allows this call to generate a 'default' scientific number format without
+ * additional changes.
+ *
+ * @param useScientific true if this object formats and parses scientific notation
+ * @see #isScientificNotation
+ * @see #getMinimumExponentDigits
+ * @see #setMinimumExponentDigits
+ * @see #isExponentSignAlwaysShown
+ * @see #setExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public void setScientificNotation(boolean useScientific) {
+ useExponentialNotation = useScientific;
+ }
+
+ /**
+ * {@icu} Returns the minimum exponent digits that will be shown.
+ *
+ * @return the minimum exponent digits that will be shown
+ * @see #setScientificNotation
+ * @see #isScientificNotation
+ * @see #setMinimumExponentDigits
+ * @see #isExponentSignAlwaysShown
+ * @see #setExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public byte getMinimumExponentDigits() {
+ return minExponentDigits;
+ }
+
+ /**
+ * {@icu} Sets the minimum exponent digits that will be shown. This has no effect
+ * unless scientific notation is in use.
+ *
+ * @param minExpDig a value &gt;= 1 indicating the fewest exponent
+ * digits that will be shown
+ * @exception IllegalArgumentException if <code>minExpDig</code> &lt; 1
+ * @see #setScientificNotation
+ * @see #isScientificNotation
+ * @see #getMinimumExponentDigits
+ * @see #isExponentSignAlwaysShown
+ * @see #setExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public void setMinimumExponentDigits(byte minExpDig) {
+ if (minExpDig < 1) {
+ throw new IllegalArgumentException("Exponent digits must be >= 1");
+ }
+ minExponentDigits = minExpDig;
+ }
+
+ /**
+ * {@icu} Returns whether the exponent sign is always shown.
+ *
+ * @return true if the exponent is always prefixed with either the localized minus
+ * sign or the localized plus sign, false if only negative exponents are prefixed with
+ * the localized minus sign.
+ * @see #setScientificNotation
+ * @see #isScientificNotation
+ * @see #setMinimumExponentDigits
+ * @see #getMinimumExponentDigits
+ * @see #setExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public boolean isExponentSignAlwaysShown() {
+ return exponentSignAlwaysShown;
+ }
+
+ /**
+ * {@icu} Sets whether the exponent sign is always shown. This has no effect unless
+ * scientific notation is in use.
+ *
+ * @param expSignAlways true if the exponent is always prefixed with either the
+ * localized minus sign or the localized plus sign, false if only negative exponents
+ * are prefixed with the localized minus sign.
+ * @see #setScientificNotation
+ * @see #isScientificNotation
+ * @see #setMinimumExponentDigits
+ * @see #getMinimumExponentDigits
+ * @see #isExponentSignAlwaysShown
+ * @stable ICU 2.0
+ */
+ public void setExponentSignAlwaysShown(boolean expSignAlways) {
+ exponentSignAlwaysShown = expSignAlways;
+ }
+
+ /**
+ * Returns the grouping size. Grouping size is the number of digits between grouping
+ * separators in the integer portion of a number. For example, in the number
+ * "123,456.78", the grouping size is 3.
+ *
+ * @see #setGroupingSize
+ * @see NumberFormat#isGroupingUsed
+ * @see DecimalFormatSymbols#getGroupingSeparator
+ * @stable ICU 2.0
+ */
+ public int getGroupingSize() {
+ return groupingSize;
+ }
+
+ /**
+ * Sets the grouping size. Grouping size is the number of digits between grouping
+ * separators in the integer portion of a number. For example, in the number
+ * "123,456.78", the grouping size is 3.
+ *
+ * @see #getGroupingSize
+ * @see NumberFormat#setGroupingUsed
+ * @see DecimalFormatSymbols#setGroupingSeparator
+ * @stable ICU 2.0
+ */
+ public void setGroupingSize(int newValue) {
+ groupingSize = (byte) newValue;
+ }
+
+ /**
+ * {@icu} Returns the secondary grouping size. In some locales one grouping interval
+ * is used for the least significant integer digits (the primary grouping size), and
+ * another is used for all others (the secondary grouping size). A formatter
+ * supporting a secondary grouping size will return a positive integer unequal to the
+ * primary grouping size returned by <code>getGroupingSize()</code>. For example, if
+ * the primary grouping size is 4, and the secondary grouping size is 2, then the
+ * number 123456789 formats as "1,23,45,6789", and the pattern appears as "#,##,###0".
+ *
+ * @return the secondary grouping size, or a value less than one if there is none
+ * @see #setSecondaryGroupingSize
+ * @see NumberFormat#isGroupingUsed
+ * @see DecimalFormatSymbols#getGroupingSeparator
+ * @stable ICU 2.0
+ */
+ public int getSecondaryGroupingSize() {
+ return groupingSize2;
+ }
+
+ /**
+ * {@icu} Sets the secondary grouping size. If set to a value less than 1, then
+ * secondary grouping is turned off, and the primary grouping size is used for all
+ * intervals, not just the least significant.
+ *
+ * @see #getSecondaryGroupingSize
+ * @see NumberFormat#setGroupingUsed
+ * @see DecimalFormatSymbols#setGroupingSeparator
+ * @stable ICU 2.0
+ */
+ public void setSecondaryGroupingSize(int newValue) {
+ groupingSize2 = (byte) newValue;
+ }
+
+ /**
+ * {@icu} Returns the MathContext used by this format.
+ *
+ * @return desired MathContext
+ * @see #getMathContext
+ * @stable ICU 4.2
+ */
+ public MathContext getMathContextICU() {
+ return mathContext;
+ }
+
+ /**
+ * {@icu} Returns the MathContext used by this format.
+ *
+ * @return desired MathContext
+ * @see #getMathContext
+ * @stable ICU 4.2
+ */
+ public java.math.MathContext getMathContext() {
+ try {
+ // don't allow multiple references
+ return mathContext == null ? null : new java.math.MathContext(mathContext.getDigits(),
+ java.math.RoundingMode.valueOf(mathContext.getRoundingMode()));
+ } catch (Exception foo) {
+ return null; // should never happen
+ }
+ }
+
+ /**
+ * {@icu} Sets the MathContext used by this format.
+ *
+ * @param newValue desired MathContext
+ * @see #getMathContext
+ * @stable ICU 4.2
+ */
+ public void setMathContextICU(MathContext newValue) {
+ mathContext = newValue;
+ }
+
+ /**
+ * {@icu} Sets the MathContext used by this format.
+ *
+ * @param newValue desired MathContext
+ * @see #getMathContext
+ * @stable ICU 4.2
+ */
+ public void setMathContext(java.math.MathContext newValue) {
+ mathContext = new MathContext(newValue.getPrecision(), MathContext.SCIENTIFIC, false,
+ (newValue.getRoundingMode()).ordinal());
+ }
+
+ /**
+ * Returns the behavior of the decimal separator with integers. (The decimal
+ * separator will always appear with decimals.) <p> Example: Decimal ON: 12345 -&gt;
+ * 12345.; OFF: 12345 -&gt; 12345
+ *
+ * @stable ICU 2.0
+ */
+ public boolean isDecimalSeparatorAlwaysShown() {
+ return decimalSeparatorAlwaysShown;
+ }
+
+ /**
+ * When decimal match is not required, the input does not have to
+ * contain a decimal mark when there is a decimal mark specified in the
+ * pattern.
+ * @param value true if input must contain a match to decimal mark in pattern
+ * Default is false.
+ * @stable ICU 54
+ */
+ public void setDecimalPatternMatchRequired(boolean value) {
+ parseRequireDecimalPoint = value;
+ }
+
+ /**
+ * {@icu} Returns whether the input to parsing must contain a decimal mark if there
+ * is a decimal mark in the pattern.
+ * @return true if input must contain a match to decimal mark in pattern
+ * @stable ICU 54
+ */
+ public boolean isDecimalPatternMatchRequired() {
+ return parseRequireDecimalPoint;
+ }
+
+
+ /**
+ * Sets the behavior of the decimal separator with integers. (The decimal separator
+ * will always appear with decimals.)
+ *
+ * <p>This only affects formatting, and only where there might be no digits after the
+ * decimal point, e.g., if true, 3456.00 -&gt; "3,456." if false, 3456.00 -&gt; "3456" This
+ * is independent of parsing. If you want parsing to stop at the decimal point, use
+ * setParseIntegerOnly.
+ *
+ * <p>
+ * Example: Decimal ON: 12345 -&gt; 12345.; OFF: 12345 -&gt; 12345
+ *
+ * @stable ICU 2.0
+ */
+ public void setDecimalSeparatorAlwaysShown(boolean newValue) {
+ decimalSeparatorAlwaysShown = newValue;
+ }
+
+ /**
+ * {@icu} Returns a copy of the CurrencyPluralInfo used by this format. It might
+ * return null if the decimal format is not a plural type currency decimal
+ * format. Plural type currency decimal format means either the pattern in the decimal
+ * format contains 3 currency signs, or the decimal format is initialized with
+ * PLURALCURRENCYSTYLE.
+ *
+ * @return desired CurrencyPluralInfo
+ * @see CurrencyPluralInfo
+ * @stable ICU 4.2
+ */
+ public CurrencyPluralInfo getCurrencyPluralInfo() {
+ try {
+ // don't allow multiple references
+ return currencyPluralInfo == null ? null :
+ (CurrencyPluralInfo) currencyPluralInfo.clone();
+ } catch (Exception foo) {
+ return null; // should never happen
+ }
+ }
+
+ /**
+ * {@icu} Sets the CurrencyPluralInfo used by this format. The format uses a copy of
+ * the provided information.
+ *
+ * @param newInfo desired CurrencyPluralInfo
+ * @see CurrencyPluralInfo
+ * @stable ICU 4.2
+ */
+ public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
+ currencyPluralInfo = (CurrencyPluralInfo) newInfo.clone();
+ isReadyForParsing = false;
+ }
+
+ /**
+ * Overrides clone.
+ * @stable ICU 2.0
+ */
+ @Override
+ public Object clone() {
+ try {
+ DecimalFormat_ICU58 other = (DecimalFormat_ICU58) super.clone();
+ other.symbols = (DecimalFormatSymbols) symbols.clone();
+ other.digitList = new DigitList(); // fix for JB#5358
+ if (currencyPluralInfo != null) {
+ other.currencyPluralInfo = (CurrencyPluralInfo) currencyPluralInfo.clone();
+ }
+ other.attributes = new ArrayList<>(); // #9240
+ other.currencyUsage = currencyUsage;
+
+ // TODO: We need to figure out whether we share a single copy of DigitList by
+ // multiple cloned copies. format/subformat are designed to use a single
+ // instance, but parse/subparse implementation is not.
+ return other;
+ } catch (Exception e) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Overrides equals.
+ * @stable ICU 2.0
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!super.equals(obj))
+ return false; // super does class check
+
+ DecimalFormat_ICU58 other = (DecimalFormat_ICU58) obj;
+ // Add the comparison of the four new added fields ,they are posPrefixPattern,
+ // posSuffixPattern, negPrefixPattern, negSuffixPattern. [Richard/GCL]
+ // following are added to accomodate changes for currency plural format.
+ return currencySignCount == other.currencySignCount
+ && (style != NumberFormat.PLURALCURRENCYSTYLE ||
+ equals(posPrefixPattern, other.posPrefixPattern)
+ && equals(posSuffixPattern, other.posSuffixPattern)
+ && equals(negPrefixPattern, other.negPrefixPattern)
+ && equals(negSuffixPattern, other.negSuffixPattern))
+ && multiplier == other.multiplier
+ && groupingSize == other.groupingSize
+ && groupingSize2 == other.groupingSize2
+ && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
+ && useExponentialNotation == other.useExponentialNotation
+ && (!useExponentialNotation || minExponentDigits == other.minExponentDigits)
+ && useSignificantDigits == other.useSignificantDigits
+ && (!useSignificantDigits || minSignificantDigits == other.minSignificantDigits
+ && maxSignificantDigits == other.maxSignificantDigits)
+ && symbols.equals(other.symbols)
+ && Objects.equals(currencyPluralInfo, other.currencyPluralInfo)
+ && currencyUsage.equals(other.currencyUsage);
+ }
+
+ // method to unquote the strings and compare
+ private boolean equals(String pat1, String pat2) {
+ if (pat1 == null || pat2 == null) {
+ return (pat1 == null && pat2 == null);
+ }
+ // fast path
+ if (pat1.equals(pat2)) {
+ return true;
+ }
+ return unquote(pat1).equals(unquote(pat2));
+ }
+
+ private String unquote(String pat) {
+ StringBuilder buf = new StringBuilder(pat.length());
+ int i = 0;
+ while (i < pat.length()) {
+ char ch = pat.charAt(i++);
+ if (ch != QUOTE) {
+ buf.append(ch);
+ }
+ }
+ return buf.toString();
+ }
+
+ // protected void handleToString(StringBuffer buf) {
+ // buf.append("\nposPrefixPattern: '" + posPrefixPattern + "'\n");
+ // buf.append("positivePrefix: '" + positivePrefix + "'\n");
+ // buf.append("posSuffixPattern: '" + posSuffixPattern + "'\n");
+ // buf.append("positiveSuffix: '" + positiveSuffix + "'\n");
+ // buf.append("negPrefixPattern: '" +
+ // com.ibm.icu.impl.Utility.format1ForSource(negPrefixPattern) + "'\n");
+ // buf.append("negativePrefix: '" +
+ // com.ibm.icu.impl.Utility.format1ForSource(negativePrefix) + "'\n");
+ // buf.append("negSuffixPattern: '" + negSuffixPattern + "'\n");
+ // buf.append("negativeSuffix: '" + negativeSuffix + "'\n");
+ // buf.append("multiplier: '" + multiplier + "'\n");
+ // buf.append("groupingSize: '" + groupingSize + "'\n");
+ // buf.append("groupingSize2: '" + groupingSize2 + "'\n");
+ // buf.append("decimalSeparatorAlwaysShown: '" + decimalSeparatorAlwaysShown + "'\n");
+ // buf.append("useExponentialNotation: '" + useExponentialNotation + "'\n");
+ // buf.append("minExponentDigits: '" + minExponentDigits + "'\n");
+ // buf.append("useSignificantDigits: '" + useSignificantDigits + "'\n");
+ // buf.append("minSignificantDigits: '" + minSignificantDigits + "'\n");
+ // buf.append("maxSignificantDigits: '" + maxSignificantDigits + "'\n");
+ // buf.append("symbols: '" + symbols + "'");
+ // }
+
+ /**
+ * Overrides hashCode.
+ * @stable ICU 2.0
+ */
+ @Override
+ public int hashCode() {
+ return super.hashCode() * 37 + positivePrefix.hashCode();
+ // just enough fields for a reasonable distribution
+ }
+
+ /**
+ * Synthesizes a pattern string that represents the current state of this Format
+ * object.
+ *
+ * @see #applyPattern
+ * @stable ICU 2.0
+ */
+ public String toPattern() {
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ // the prefix or suffix pattern might not be defined yet, so they can not be
+ // synthesized, instead, get them directly. but it might not be the actual
+ // pattern used in formatting. the actual pattern used in formatting depends
+ // on the formatted number's plural count.
+ return formatPattern;
+ }
+ return toPattern(false);
+ }
+
+ /**
+ * Synthesizes a localized pattern string that represents the current state of this
+ * Format object.
+ *
+ * @see #applyPattern
+ * @stable ICU 2.0
+ */
+ public String toLocalizedPattern() {
+ if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+ return formatPattern;
+ }
+ return toPattern(true);
+ }
+
+ /**
+ * Expands the affix pattern strings into the expanded affix strings. If any affix
+ * pattern string is null, do not expand it. This method should be called any time the
+ * symbols or the affix patterns change in order to keep the expanded affix strings up
+ * to date. This method also will be called before formatting if format currency
+ * plural names, since the plural name is not a static one, it is based on the
+ * currency plural count, the affix will be known only after the currency plural count
+ * is know. In which case, the parameter 'pluralCount' will be a non-null currency
+ * plural count. In all other cases, the 'pluralCount' is null, which means it is not
+ * needed.
+ */
+ // Bug 4212072 [Richard/GCL]
+ private void expandAffixes(String pluralCount) {
+ // expandAffix() will set currencyChoice to a non-null value if
+ // appropriate AND if it is null.
+ currencyChoice = null;
+
+ // Reuse one StringBuffer for better performance
+ StringBuffer buffer = new StringBuffer();
+ if (posPrefixPattern != null) {
+ expandAffix(posPrefixPattern, pluralCount, buffer);
+ positivePrefix = buffer.toString();
+ }
+ if (posSuffixPattern != null) {
+ expandAffix(posSuffixPattern, pluralCount, buffer);
+ positiveSuffix = buffer.toString();
+ }
+ if (negPrefixPattern != null) {
+ expandAffix(negPrefixPattern, pluralCount, buffer);
+ negativePrefix = buffer.toString();
+ }
+ if (negSuffixPattern != null) {
+ expandAffix(negSuffixPattern, pluralCount, buffer);
+ negativeSuffix = buffer.toString();
+ }
+ }
+
+ /**
+ * Expands an affix pattern into an affix string. All characters in the pattern are
+ * literal unless bracketed by QUOTEs. The following characters outside QUOTE are
+ * recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, PATTERN_MINUS, and
+ * CURRENCY_SIGN. If CURRENCY_SIGN is doubled, it is interpreted as an international
+ * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as currency plural
+ * long names, such as "US Dollars". Any other character outside QUOTE represents
+ * itself. Quoted text must be well-formed.
+ *
+ * This method is used in two distinct ways. First, it is used to expand the stored
+ * affix patterns into actual affixes. For this usage, doFormat must be false. Second,
+ * it is used to expand the stored affix patterns given a specific number (doFormat ==
+ * true), for those rare cases in which a currency format references a ChoiceFormat
+ * (e.g., en_IN display name for INR). The number itself is taken from digitList.
+ * TODO: There are no currency ChoiceFormat patterns, figure out what is still relevant here.
+ *
+ * When used in the first way, this method has a side effect: It sets currencyChoice
+ * to a ChoiceFormat object, if the currency's display name in this locale is a
+ * ChoiceFormat pattern (very rare). It only does this if currencyChoice is null to
+ * start with.
+ *
+ * @param pattern the non-null, possibly empty pattern
+ * @param pluralCount the plural count. It is only used for currency plural format. In
+ * which case, it is the plural count of the currency amount. For example, in en_US,
+ * it is the singular "one", or the plural "other". For all other cases, it is null,
+ * and is not being used.
+ * @param buffer a scratch StringBuffer; its contents will be lost
+ */
+ // Bug 4212072 [Richard/GCL]
+ private void expandAffix(String pattern, String pluralCount, StringBuffer buffer) {
+ buffer.setLength(0);
+ for (int i = 0; i < pattern.length();) {
+ char c = pattern.charAt(i++);
+ if (c == QUOTE) {
+ for (;;) {
+ int j = pattern.indexOf(QUOTE, i);
+ if (j == i) {
+ buffer.append(QUOTE);
+ i = j + 1;
+ break;
+ } else if (j > i) {
+ buffer.append(pattern.substring(i, j));
+ i = j + 1;
+ if (i < pattern.length() && pattern.charAt(i) == QUOTE) {
+ buffer.append(QUOTE);
+ ++i;
+ // loop again
+ } else {
+ break;
+ }
+ } else {
+ // Unterminated quote; should be caught by apply
+ // pattern.
+ throw new RuntimeException();
+ }
+ }
+ continue;
+ }
+
+ switch (c) {
+ case CURRENCY_SIGN:
+ // As of ICU 2.2 we use the currency object, and ignore the currency
+ // symbols in the DFS, unless we have a null currency object. This occurs
+ // if resurrecting a pre-2.2 object or if the user sets a custom DFS.
+ boolean intl = i < pattern.length() && pattern.charAt(i) == CURRENCY_SIGN;
+ boolean plural = false;
+ if (intl) {
+ ++i;
+ if (i < pattern.length() && pattern.charAt(i) == CURRENCY_SIGN) {
+ plural = true;
+ intl = false;
+ ++i;
+ }
+ }
+ String s = null;
+ Currency currency = getCurrency();
+ if (currency != null) {
+ // plural name is only needed when pluralCount != null, which means
+ // when formatting currency plural names. For other cases,
+ // pluralCount == null, and plural names are not needed.
+ if (plural && pluralCount != null) {
+ s = currency.getName(symbols.getULocale(), Currency.PLURAL_LONG_NAME,
+ pluralCount, null);
+ } else if (!intl) {
+ s = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null);
+ } else {
+ s = currency.getCurrencyCode();
+ }
+ } else {
+ s = intl ? symbols.getInternationalCurrencySymbol() :
+ symbols.getCurrencySymbol();
+ }
+ // Here is where FieldPosition could be set for CURRENCY PLURAL.
+ buffer.append(s);
+ break;
+ case PATTERN_PERCENT:
+ buffer.append(symbols.getPercentString());
+ break;
+ case PATTERN_PER_MILLE:
+ buffer.append(symbols.getPerMillString());
+ break;
+ case PATTERN_MINUS_SIGN:
+ buffer.append(symbols.getMinusSignString());
+ break;
+ default:
+ buffer.append(c);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Append an affix to the given StringBuffer.
+ *
+ * @param buf
+ * buffer to append to
+ * @param isNegative
+ * @param isPrefix
+ * @param fieldPosition
+ * @param parseAttr
+ */
+ private int appendAffix(StringBuffer buf, boolean isNegative, boolean isPrefix,
+ FieldPosition fieldPosition,
+ boolean parseAttr) {
+ if (currencyChoice != null) {
+ String affixPat = null;
+ if (isPrefix) {
+ affixPat = isNegative ? negPrefixPattern : posPrefixPattern;
+ } else {
+ affixPat = isNegative ? negSuffixPattern : posSuffixPattern;
+ }
+ StringBuffer affixBuf = new StringBuffer();
+ expandAffix(affixPat, null, affixBuf);
+ buf.append(affixBuf);
+ return affixBuf.length();
+ }
+
+ String affix = null;
+ String pattern;
+ if (isPrefix) {
+ affix = isNegative ? negativePrefix : positivePrefix;
+ pattern = isNegative ? negPrefixPattern : posPrefixPattern;
+ } else {
+ affix = isNegative ? negativeSuffix : positiveSuffix;
+ pattern = isNegative ? negSuffixPattern : posSuffixPattern;
+ }
+ // [Spark/CDL] Invoke formatAffix2Attribute to add attributes for affix
+ if (parseAttr) {
+ // Updates for Ticket 11805.
+ int offset = affix.indexOf(symbols.getCurrencySymbol());
+ if (offset > -1) {
+ formatAffix2Attribute(isPrefix, Field.CURRENCY, buf, offset,
+ symbols.getCurrencySymbol().length());
+ }
+ offset = affix.indexOf(symbols.getMinusSignString());
+ if (offset > -1) {
+ formatAffix2Attribute(isPrefix, Field.SIGN, buf, offset,
+ symbols.getMinusSignString().length());
+ }
+ offset = affix.indexOf(symbols.getPercentString());
+ if (offset > -1) {
+ formatAffix2Attribute(isPrefix, Field.PERCENT, buf, offset,
+ symbols.getPercentString().length());
+ }
+ offset = affix.indexOf(symbols.getPerMillString());
+ if (offset > -1) {
+ formatAffix2Attribute(isPrefix, Field.PERMILLE, buf, offset,
+ symbols.getPerMillString().length());
+ }
+ offset = pattern.indexOf("¤¤¤");
+ if (offset > -1) {
+ formatAffix2Attribute(isPrefix, Field.CURRENCY, buf, offset,
+ affix.length() - offset);
+ }
+ }
+
+ // Look for SIGN, PERCENT, PERMILLE in the formatted affix.
+ if (fieldPosition.getFieldAttribute() == NumberFormat.Field.SIGN) {
+ String sign = isNegative ? symbols.getMinusSignString() : symbols.getPlusSignString();
+ int firstPos = affix.indexOf(sign);
+ if (firstPos > -1) {
+ int startPos = buf.length() + firstPos;
+ fieldPosition.setBeginIndex(startPos);
+ fieldPosition.setEndIndex(startPos + sign.length());
+ }
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.PERCENT) {
+ int firstPos = affix.indexOf(symbols.getPercentString());
+ if (firstPos > -1) {
+ int startPos = buf.length() + firstPos;
+ fieldPosition.setBeginIndex(startPos);
+ fieldPosition.setEndIndex(startPos + symbols.getPercentString().length());
+ }
+ } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.PERMILLE) {
+ int firstPos = affix.indexOf(symbols.getPerMillString());
+ if (firstPos > -1) {
+ int startPos = buf.length() + firstPos;
+ fieldPosition.setBeginIndex(startPos);
+ fieldPosition.setEndIndex(startPos + symbols.getPerMillString().length());
+ }
+ } else
+ // If CurrencySymbol or InternationalCurrencySymbol is in the affix, check for currency symbol.
+ // Get spelled out name if "¤¤¤" is in the pattern.
+ if (fieldPosition.getFieldAttribute() == NumberFormat.Field.CURRENCY) {
+ if (affix.indexOf(symbols.getCurrencySymbol()) > -1) {
+ String aff = symbols.getCurrencySymbol();
+ int firstPos = affix.indexOf(aff);
+ int start = buf.length() + firstPos;
+ int end = start + aff.length();
+ fieldPosition.setBeginIndex(start);
+ fieldPosition.setEndIndex(end);
+ } else if (affix.indexOf(symbols.getInternationalCurrencySymbol()) > -1) {
+ String aff = symbols.getInternationalCurrencySymbol();
+ int firstPos = affix.indexOf(aff);
+ int start = buf.length() + firstPos;
+ int end = start + aff.length();
+ fieldPosition.setBeginIndex(start);
+ fieldPosition.setEndIndex(end);
+ } else if (pattern.indexOf("¤¤¤") > -1) {
+ // It's a plural, and we know where it is in the pattern.
+ int firstPos = pattern.indexOf("¤¤¤");
+ int start = buf.length() + firstPos;
+ int end = buf.length() + affix.length(); // This seems clunky and wrong.
+ fieldPosition.setBeginIndex(start);
+ fieldPosition.setEndIndex(end);
+ }
+ }
+
+ buf.append(affix);
+ return affix.length();
+ }
+
+ // Fix for prefix and suffix in Ticket 11805.
+ private void formatAffix2Attribute(boolean isPrefix, Field fieldType,
+ StringBuffer buf, int offset, int symbolSize) {
+ int begin;
+ begin = offset;
+ if (!isPrefix) {
+ begin += buf.length();
+ }
+
+ addAttribute(fieldType, begin, begin + symbolSize);
+ }
+
+ /**
+ * [Spark/CDL] Use this method to add attribute.
+ */
+ private void addAttribute(Field field, int begin, int end) {
+ FieldPosition pos = new FieldPosition(field);
+ pos.setBeginIndex(begin);
+ pos.setEndIndex(end);
+ attributes.add(pos);
+ }
+
+ /**
+ * Formats the object to an attributed string, and return the corresponding iterator.
+ *
+ * @stable ICU 3.6
+ */
+ @Override
+ public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
+ return formatToCharacterIterator(obj, NULL_UNIT);
+ }
+
+ AttributedCharacterIterator formatToCharacterIterator(Object obj, Unit unit) {
+ if (!(obj instanceof Number))
+ throw new IllegalArgumentException();
+ Number number = (Number) obj;
+ StringBuffer text = new StringBuffer();
+ unit.writePrefix(text);
+ attributes.clear();
+ if (obj instanceof BigInteger) {
+ format((BigInteger) number, text, new FieldPosition(0), true);
+ } else if (obj instanceof java.math.BigDecimal) {
+ format((java.math.BigDecimal) number, text, new FieldPosition(0)
+ , true);
+ } else if (obj instanceof Double) {
+ format(number.doubleValue(), text, new FieldPosition(0), true);
+ } else if (obj instanceof Integer || obj instanceof Long) {
+ format(number.longValue(), text, new FieldPosition(0), true);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ unit.writeSuffix(text);
+ AttributedString as = new AttributedString(text.toString());
+
+ // add NumberFormat field attributes to the AttributedString
+ for (int i = 0; i < attributes.size(); i++) {
+ FieldPosition pos = attributes.get(i);
+ Format.Field attribute = pos.getFieldAttribute();
+ as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos.getEndIndex());
+ }
+
+ // return the CharacterIterator from AttributedString
+ return as.getIterator();
+ }
+
+ /**
+ * Appends an affix pattern to the given StringBuffer. Localize unquoted specials.
+ * <p>
+ * <b>Note:</b> This implementation does not support new String localized symbols.
+ */
+ private void appendAffixPattern(StringBuffer buffer, boolean isNegative, boolean isPrefix,
+ boolean localized) {
+ String affixPat = null;
+ if (isPrefix) {
+ affixPat = isNegative ? negPrefixPattern : posPrefixPattern;
+ } else {
+ affixPat = isNegative ? negSuffixPattern : posSuffixPattern;
+ }
+
+ // When there is a null affix pattern, we use the affix itself.
+ if (affixPat == null) {
+ String affix = null;
+ if (isPrefix) {
+ affix = isNegative ? negativePrefix : positivePrefix;
+ } else {
+ affix = isNegative ? negativeSuffix : positiveSuffix;
+ }
+ // Do this crudely for now: Wrap everything in quotes.
+ buffer.append(QUOTE);
+ for (int i = 0; i < affix.length(); ++i) {
+ char ch = affix.charAt(i);
+ if (ch == QUOTE) {
+ buffer.append(ch);
+ }
+ buffer.append(ch);
+ }
+ buffer.append(QUOTE);
+ return;
+ }
+
+ if (!localized) {
+ buffer.append(affixPat);
+ } else {
+ int i, j;
+ for (i = 0; i < affixPat.length(); ++i) {
+ char ch = affixPat.charAt(i);
+ switch (ch) {
+ case QUOTE:
+ j = affixPat.indexOf(QUOTE, i + 1);
+ if (j < 0) {
+ throw new IllegalArgumentException("Malformed affix pattern: " + affixPat);
+ }
+ buffer.append(affixPat.substring(i, j + 1));
+ i = j;
+ continue;
+ case PATTERN_PER_MILLE:
+ ch = symbols.getPerMill();
+ break;
+ case PATTERN_PERCENT:
+ ch = symbols.getPercent();
+ break;
+ case PATTERN_MINUS_SIGN:
+ ch = symbols.getMinusSign();
+ break;
+ }
+ // check if char is same as any other symbol
+ if (ch == symbols.getDecimalSeparator() || ch == symbols.getGroupingSeparator()) {
+ buffer.append(QUOTE);
+ buffer.append(ch);
+ buffer.append(QUOTE);
+ } else {
+ buffer.append(ch);
+ }
+ }
+ }
+ }
+
+ /**
+ * Does the real work of generating a pattern.
+ * <p>
+ * <b>Note:</b> This implementation does not support new String localized symbols.
+ */
+ private String toPattern(boolean localized) {
+ StringBuffer result = new StringBuffer();
+ char zero = localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT;
+ char digit = localized ? symbols.getDigit() : PATTERN_DIGIT;
+ char sigDigit = 0;
+ boolean useSigDig = areSignificantDigitsUsed();
+ if (useSigDig) {
+ sigDigit = localized ? symbols.getSignificantDigit() : PATTERN_SIGNIFICANT_DIGIT;
+ }
+ char group = localized ? symbols.getGroupingSeparator() : PATTERN_GROUPING_SEPARATOR;
+ int i;
+ int roundingDecimalPos = 0; // Pos of decimal in roundingDigits
+ String roundingDigits = null;
+ int padPos = (formatWidth > 0) ? padPosition : -1;
+ String padSpec = (formatWidth > 0)
+ ? new StringBuffer(2).append(localized
+ ? symbols.getPadEscape()
+ : PATTERN_PAD_ESCAPE).append(pad).toString()
+ : null;
+ if (roundingIncrementICU != null) {
+ i = roundingIncrementICU.scale();
+ roundingDigits = roundingIncrementICU.movePointRight(i).toString();
+ roundingDecimalPos = roundingDigits.length() - i;
+ }
+ for (int part = 0; part < 2; ++part) {
+ // variable not used int partStart = result.length();
+ if (padPos == PAD_BEFORE_PREFIX) {
+ result.append(padSpec);
+ }
+
+ // Use original symbols read from resources in pattern eg. use "\u00A4"
+ // instead of "$" in Locale.US [Richard/GCL]
+ appendAffixPattern(result, part != 0, true, localized);
+ if (padPos == PAD_AFTER_PREFIX) {
+ result.append(padSpec);
+ }
+ int sub0Start = result.length();
+ int g = isGroupingUsed() ? Math.max(0, groupingSize) : 0;
+ if (g > 0 && groupingSize2 > 0 && groupingSize2 != groupingSize) {
+ g += groupingSize2;
+ }
+ int maxDig = 0, minDig = 0, maxSigDig = 0;
+ if (useSigDig) {
+ minDig = getMinimumSignificantDigits();
+ maxDig = maxSigDig = getMaximumSignificantDigits();
+ } else {
+ minDig = getMinimumIntegerDigits();
+ maxDig = getMaximumIntegerDigits();
+ }
+ if (useExponentialNotation) {
+ if (maxDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
+ maxDig = 1;
+ }
+ } else if (useSigDig) {
+ maxDig = Math.max(maxDig, g + 1);
+ } else {
+ maxDig = Math.max(Math.max(g, getMinimumIntegerDigits()), roundingDecimalPos) + 1;
+ }
+ for (i = maxDig; i > 0; --i) {
+ if (!useExponentialNotation && i < maxDig && isGroupingPosition(i)) {
+ result.append(group);
+ }
+ if (useSigDig) {
+ // #@,@### (maxSigDig == 5, minSigDig == 2) 65 4321 (1-based pos,
+ // count from the right) Use # if pos > maxSigDig or 1 <= pos <=
+ // (maxSigDig - minSigDig) Use @ if (maxSigDig - minSigDig) < pos <=
+ // maxSigDig
+ result.append((maxSigDig >= i && i > (maxSigDig - minDig)) ? sigDigit : digit);
+ } else {
+ if (roundingDigits != null) {
+ int pos = roundingDecimalPos - i;
+ if (pos >= 0 && pos < roundingDigits.length()) {
+ result.append((char) (roundingDigits.charAt(pos) - '0' + zero));
+ continue;
+ }
+ }
+ result.append(i <= minDig ? zero : digit);
+ }
+ }
+ if (!useSigDig) {
+ if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown) {
+ result.append(localized ? symbols.getDecimalSeparator() :
+ PATTERN_DECIMAL_SEPARATOR);
+ }
+ int pos = roundingDecimalPos;
+ for (i = 0; i < getMaximumFractionDigits(); ++i) {
+ if (roundingDigits != null && pos < roundingDigits.length()) {
+ result.append(pos < 0 ? zero :
+ (char) (roundingDigits.charAt(pos) - '0' + zero));
+ ++pos;
+ continue;
+ }
+ result.append(i < getMinimumFractionDigits() ? zero : digit);
+ }
+ }
+ if (useExponentialNotation) {
+ if (localized) {
+ result.append(symbols.getExponentSeparator());
+ } else {
+ result.append(PATTERN_EXPONENT);
+ }
+ if (exponentSignAlwaysShown) {
+ result.append(localized ? symbols.getPlusSign() : PATTERN_PLUS_SIGN);
+ }
+ for (i = 0; i < minExponentDigits; ++i) {
+ result.append(zero);
+ }
+ }
+ if (padSpec != null && !useExponentialNotation) {
+ int add = formatWidth
+ - result.length()
+ + sub0Start
+ - ((part == 0)
+ ? positivePrefix.length() + positiveSuffix.length()
+ : negativePrefix.length() + negativeSuffix.length());
+ while (add > 0) {
+ result.insert(sub0Start, digit);
+ ++maxDig;
+ --add;
+ // Only add a grouping separator if we have at least 2 additional
+ // characters to be added, so we don't end up with ",###".
+ if (add > 1 && isGroupingPosition(maxDig)) {
+ result.insert(sub0Start, group);
+ --add;
+ }
+ }
+ }
+ if (padPos == PAD_BEFORE_SUFFIX) {
+ result.append(padSpec);
+ }
+ // Use original symbols read from resources in pattern eg. use "\u00A4"
+ // instead of "$" in Locale.US [Richard/GCL]
+ appendAffixPattern(result, part != 0, false, localized);
+ if (padPos == PAD_AFTER_SUFFIX) {
+ result.append(padSpec);
+ }
+ if (part == 0) {
+ if (negativeSuffix.equals(positiveSuffix) &&
+ negativePrefix.equals(PATTERN_MINUS_SIGN + positivePrefix)) {
+ break;
+ } else {
+ result.append(localized ? symbols.getPatternSeparator() : PATTERN_SEPARATOR);
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Applies the given pattern to this Format object. A pattern is a short-hand
+ * specification for the various formatting properties. These properties can also be
+ * changed individually through the various setter methods.
+ *
+ * <p>There is no limit to integer digits are set by this routine, since that is the
+ * typical end-user desire; use setMaximumInteger if you want to set a real value. For
+ * negative numbers, use a second pattern, separated by a semicolon
+ *
+ * <p>Example "#,#00.0#" -&gt; 1,234.56
+ *
+ * <p>This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2
+ * fraction digits.
+ *
+ * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.
+ *
+ * <p>In negative patterns, the minimum and maximum counts are ignored; these are
+ * presumed to be set in the positive pattern.
+ *
+ * @stable ICU 2.0
+ */
+ public void applyPattern(String pattern) {
+ applyPattern(pattern, false);
+ }
+
+ /**
+ * Applies the given pattern to this Format object. The pattern is assumed to be in a
+ * localized notation. A pattern is a short-hand specification for the various
+ * formatting properties. These properties can also be changed individually through
+ * the various setter methods.
+ *
+ * <p>There is no limit to integer digits are set by this routine, since that is the
+ * typical end-user desire; use setMaximumInteger if you want to set a real value. For
+ * negative numbers, use a second pattern, separated by a semicolon
+ *
+ * <p>Example "#,#00.0#" -&gt; 1,234.56
+ *
+ * <p>This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2
+ * fraction digits.
+ *
+ * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses.
+ *
+ * <p>In negative patterns, the minimum and maximum counts are ignored; these are
+ * presumed to be set in the positive pattern.
+ *
+ * @stable ICU 2.0
+ */
+ public void applyLocalizedPattern(String pattern) {
+ applyPattern(pattern, true);
+ }
+
+ /**
+ * Does the real work of applying a pattern.
+ */
+ private void applyPattern(String pattern, boolean localized) {
+ applyPatternWithoutExpandAffix(pattern, localized);
+ expandAffixAdjustWidth(null);
+ }
+
+ private void expandAffixAdjustWidth(String pluralCount) {
+ // Bug 4212072 Update the affix strings according to symbols in order to keep the
+ // affix strings up to date. [Richard/GCL]
+ expandAffixes(pluralCount);
+
+ // Now that we have the actual prefix and suffix, fix up formatWidth
+ if (formatWidth > 0) {
+ formatWidth += positivePrefix.length() + positiveSuffix.length();
+ }
+ }
+
+ private void applyPatternWithoutExpandAffix(String pattern, boolean localized) {
+ char zeroDigit = PATTERN_ZERO_DIGIT; // '0'
+ char sigDigit = PATTERN_SIGNIFICANT_DIGIT; // '@'
+ char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
+ char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
+ char percent = PATTERN_PERCENT;
+ char perMill = PATTERN_PER_MILLE;
+ char digit = PATTERN_DIGIT; // '#'
+ char separator = PATTERN_SEPARATOR;
+ String exponent = String.valueOf(PATTERN_EXPONENT);
+ char plus = PATTERN_PLUS_SIGN;
+ char padEscape = PATTERN_PAD_ESCAPE;
+ char minus = PATTERN_MINUS_SIGN; // Bug 4212072 [Richard/GCL]
+ if (localized) {
+ zeroDigit = symbols.getZeroDigit();
+ sigDigit = symbols.getSignificantDigit();
+ groupingSeparator = symbols.getGroupingSeparator();
+ decimalSeparator = symbols.getDecimalSeparator();
+ percent = symbols.getPercent();
+ perMill = symbols.getPerMill();
+ digit = symbols.getDigit();
+ separator = symbols.getPatternSeparator();
+ exponent = symbols.getExponentSeparator();
+ plus = symbols.getPlusSign();
+ padEscape = symbols.getPadEscape();
+ minus = symbols.getMinusSign(); // Bug 4212072 [Richard/GCL]
+ }
+ char nineDigit = (char) (zeroDigit + 9);
+
+ boolean gotNegative = false;
+
+ int pos = 0;
+ // Part 0 is the positive pattern. Part 1, if present, is the negative
+ // pattern.
+ for (int part = 0; part < 2 && pos < pattern.length(); ++part) {
+ // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 2=suffix,
+ // 3=prefix in quote, 4=suffix in quote. Subpart 0 is between the prefix and
+ // suffix, and consists of pattern characters. In the prefix and suffix,
+ // percent, permille, and currency symbols are recognized and translated.
+ int subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
+
+ // It's important that we don't change any fields of this object
+ // prematurely. We set the following variables for the multiplier, grouping,
+ // etc., and then only change the actual object fields if everything parses
+ // correctly. This also lets us register the data from part 0 and ignore the
+ // part 1, except for the prefix and suffix.
+ StringBuilder prefix = new StringBuilder();
+ StringBuilder suffix = new StringBuilder();
+ int decimalPos = -1;
+ int multpl = 1;
+ int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
+ byte groupingCount = -1;
+ byte groupingCount2 = -1;
+ int padPos = -1;
+ char padChar = 0;
+ int incrementPos = -1;
+ long incrementVal = 0;
+ byte expDigits = -1;
+ boolean expSignAlways = false;
+ int currencySignCnt = 0;
+
+ // The affix is either the prefix or the suffix.
+ StringBuilder affix = prefix;
+
+ int start = pos;
+
+ PARTLOOP: for (; pos < pattern.length(); ++pos) {
+ char ch = pattern.charAt(pos);
+ switch (subpart) {
+ case 0: // Pattern proper subpart (between prefix & suffix)
+ // Process the digits, decimal, and grouping characters. We record
+ // five pieces of information. We expect the digits to occur in the
+ // pattern ####00.00####, and we record the number of left digits,
+ // zero (central) digits, and right digits. The position of the last
+ // grouping character is recorded (should be somewhere within the
+ // first two blocks of characters), as is the position of the decimal
+ // point, if any (should be in the zero digits). If there is no
+ // decimal point, then there should be no right digits.
+ if (ch == digit) {
+ if (zeroDigitCount > 0 || sigDigitCount > 0) {
+ ++digitRightCount;
+ } else {
+ ++digitLeftCount;
+ }
+ if (groupingCount >= 0 && decimalPos < 0) {
+ ++groupingCount;
+ }
+ } else if ((ch >= zeroDigit && ch <= nineDigit) || ch == sigDigit) {
+ if (digitRightCount > 0) {
+ patternError("Unexpected '" + ch + '\'', pattern);
+ }
+ if (ch == sigDigit) {
+ ++sigDigitCount;
+ } else {
+ ++zeroDigitCount;
+ if (ch != zeroDigit) {
+ int p = digitLeftCount + zeroDigitCount + digitRightCount;
+ if (incrementPos >= 0) {
+ while (incrementPos < p) {
+ incrementVal *= 10;
+ ++incrementPos;
+ }
+ } else {
+ incrementPos = p;
+ }
+ incrementVal += ch - zeroDigit;
+ }
+ }
+ if (groupingCount >= 0 && decimalPos < 0) {
+ ++groupingCount;
+ }
+ } else if (ch == groupingSeparator) {
+ // Bug 4212072 process the Localized pattern like
+ // "'Fr. '#'##0.05;'Fr.-'#'##0.05" (Locale="CH", groupingSeparator
+ // == QUOTE) [Richard/GCL]
+ if (ch == QUOTE && (pos + 1) < pattern.length()) {
+ char after = pattern.charAt(pos + 1);
+ if (!(after == digit || (after >= zeroDigit && after <= nineDigit))) {
+ // A quote outside quotes indicates either the opening
+ // quote or two quotes, which is a quote literal. That is,
+ // we have the first quote in 'do' or o''clock.
+ if (after == QUOTE) {
+ ++pos;
+ // Fall through to append(ch)
+ } else {
+ if (groupingCount < 0) {
+ subpart = 3; // quoted prefix subpart
+ } else {
+ // Transition to suffix subpart
+ subpart = 2; // suffix subpart
+ affix = suffix;
+ sub0Limit = pos--;
+ }
+ continue;
+ }
+ }
+ }
+
+ if (decimalPos >= 0) {
+ patternError("Grouping separator after decimal", pattern);
+ }
+ groupingCount2 = groupingCount;
+ groupingCount = 0;
+ } else if (ch == decimalSeparator) {
+ if (decimalPos >= 0) {
+ patternError("Multiple decimal separators", pattern);
+ }
+ // Intentionally incorporate the digitRightCount, even though it
+ // is illegal for this to be > 0 at this point. We check pattern
+ // syntax below.
+ decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
+ } else {
+ if (pattern.regionMatches(pos, exponent, 0, exponent.length())) {
+ if (expDigits >= 0) {
+ patternError("Multiple exponential symbols", pattern);
+ }
+ if (groupingCount >= 0) {
+ patternError("Grouping separator in exponential", pattern);
+ }
+ pos += exponent.length();
+ // Check for positive prefix
+ if (pos < pattern.length() && pattern.charAt(pos) == plus) {
+ expSignAlways = true;
+ ++pos;
+ }
+ // Use lookahead to parse out the exponential part of the
+ // pattern, then jump into suffix subpart.
+ expDigits = 0;
+ while (pos < pattern.length() && pattern.charAt(pos) == zeroDigit) {
+ ++expDigits;
+ ++pos;
+ }
+
+ // 1. Require at least one mantissa pattern digit
+ // 2. Disallow "#+ @" in mantissa
+ // 3. Require at least one exponent pattern digit
+ if (((digitLeftCount + zeroDigitCount) < 1 &&
+ (sigDigitCount + digitRightCount) < 1)
+ || (sigDigitCount > 0 && digitLeftCount > 0) || expDigits < 1) {
+ patternError("Malformed exponential", pattern);
+ }
+ }
+ // Transition to suffix subpart
+ subpart = 2; // suffix subpart
+ affix = suffix;
+ sub0Limit = pos--; // backup: for() will increment
+ continue;
+ }
+ break;
+ case 1: // Prefix subpart
+ case 2: // Suffix subpart
+ // Process the prefix / suffix characters Process unquoted characters
+ // seen in prefix or suffix subpart.
+
+ // Several syntax characters implicitly begins the next subpart if we
+ // are in the prefix; otherwise they are illegal if unquoted.
+ if (ch == digit || ch == groupingSeparator || ch == decimalSeparator
+ || (ch >= zeroDigit && ch <= nineDigit) || ch == sigDigit) {
+ // Any of these characters implicitly begins the
+ // next subpart if we are in the prefix
+ if (subpart == 1) { // prefix subpart
+ subpart = 0; // pattern proper subpart
+ sub0Start = pos--; // Reprocess this character
+ continue;
+ } else if (ch == QUOTE) {
+ // Bug 4212072 process the Localized pattern like
+ // "'Fr. '#'##0.05;'Fr.-'#'##0.05" (Locale="CH",
+ // groupingSeparator == QUOTE) [Richard/GCL]
+
+ // A quote outside quotes indicates either the opening quote
+ // or two quotes, which is a quote literal. That is, we have
+ // the first quote in 'do' or o''clock.
+ if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
+ ++pos;
+ affix.append(ch);
+ } else {
+ subpart += 2; // open quote
+ }
+ continue;
+ }
+ patternError("Unquoted special character '" + ch + '\'', pattern);
+ } else if (ch == CURRENCY_SIGN) {
+ // Use lookahead to determine if the currency sign is
+ // doubled or not.
+ boolean doubled = (pos + 1) < pattern.length() &&
+ pattern.charAt(pos + 1) == CURRENCY_SIGN;
+
+ // Bug 4212072 To meet the need of expandAffix(String,
+ // StirngBuffer) [Richard/GCL]
+ if (doubled) {
+ ++pos; // Skip over the doubled character
+ affix.append(ch); // append two: one here, one below
+ if ((pos + 1) < pattern.length() &&
+ pattern.charAt(pos + 1) == CURRENCY_SIGN) {
+ ++pos; // Skip over the tripled character
+ affix.append(ch); // append again
+ currencySignCnt = CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT;
+ } else {
+ currencySignCnt = CURRENCY_SIGN_COUNT_IN_ISO_FORMAT;
+ }
+ } else {
+ currencySignCnt = CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT;
+ }
+ // Fall through to append(ch)
+ } else if (ch == QUOTE) {
+ // A quote outside quotes indicates either the opening quote or
+ // two quotes, which is a quote literal. That is, we have the
+ // first quote in 'do' or o''clock.
+ if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
+ ++pos;
+ affix.append(ch); // append two: one here, one below
+ } else {
+ subpart += 2; // open quote
+ }
+ // Fall through to append(ch)
+ } else if (ch == separator) {
+ // Don't allow separators in the prefix, and don't allow
+ // separators in the second pattern (part == 1).
+ if (subpart == 1 || part == 1) {
+ patternError("Unquoted special character '" + ch + '\'', pattern);
+ }
+ sub2Limit = pos++;
+ break PARTLOOP; // Go to next part
+ } else if (ch == percent || ch == perMill) {
+ // Next handle characters which are appended directly.
+ if (multpl != 1) {
+ patternError("Too many percent/permille characters", pattern);
+ }
+ multpl = (ch == percent) ? 100 : 1000;
+ // Convert to non-localized pattern
+ ch = (ch == percent) ? PATTERN_PERCENT : PATTERN_PER_MILLE;
+ // Fall through to append(ch)
+ } else if (ch == minus) {
+ // Convert to non-localized pattern
+ ch = PATTERN_MINUS_SIGN;
+ // Fall through to append(ch)
+ } else if (ch == padEscape) {
+ if (padPos >= 0) {
+ patternError("Multiple pad specifiers", pattern);
+ }
+ if ((pos + 1) == pattern.length()) {
+ patternError("Invalid pad specifier", pattern);
+ }
+ padPos = pos++; // Advance past pad char
+ padChar = pattern.charAt(pos);
+ continue;
+ }
+ affix.append(ch);
+ break;
+ case 3: // Prefix subpart, in quote
+ case 4: // Suffix subpart, in quote
+ // A quote within quotes indicates either the closing quote or two
+ // quotes, which is a quote literal. That is, we have the second quote
+ // in 'do' or 'don''t'.
+ if (ch == QUOTE) {
+ if ((pos + 1) < pattern.length() && pattern.charAt(pos + 1) == QUOTE) {
+ ++pos;
+ affix.append(ch);
+ } else {
+ subpart -= 2; // close quote
+ }
+ // Fall through to append(ch)
+ }
+ // NOTE: In ICU 2.2 there was code here to parse quoted percent and
+ // permille characters _within quotes_ and give them special
+ // meaning. This is incorrect, since quoted characters are literals
+ // without special meaning.
+ affix.append(ch);
+ break;
+ }
+ }
+
+ if (subpart == 3 || subpart == 4) {
+ patternError("Unterminated quote", pattern);
+ }
+
+ if (sub0Limit == 0) {
+ sub0Limit = pattern.length();
+ }
+
+ if (sub2Limit == 0) {
+ sub2Limit = pattern.length();
+ }
+
+ // Handle patterns with no '0' pattern character. These patterns are legal,
+ // but must be recodified to make sense. "##.###" -> "#0.###". ".###" ->
+ // ".0##".
+ //
+ // We allow patterns of the form "####" to produce a zeroDigitCount of zero
+ // (got that?); although this seems like it might make it possible for
+ // format() to produce empty strings, format() checks for this condition and
+ // outputs a zero digit in this situation. Having a zeroDigitCount of zero
+ // yields a minimum integer digits of zero, which allows proper round-trip
+ // patterns. We don't want "#" to become "#0" when toPattern() is called (even
+ // though that's what it really is, semantically).
+ if (zeroDigitCount == 0 && sigDigitCount == 0 &&
+ digitLeftCount > 0 && decimalPos >= 0) {
+ // Handle "###.###" and "###." and ".###"
+ int n = decimalPos;
+ if (n == 0)
+ ++n; // Handle ".###"
+ digitRightCount = digitLeftCount - n;
+ digitLeftCount = n - 1;
+ zeroDigitCount = 1;
+ }
+
+ // Do syntax checking on the digits, decimal points, and quotes.
+ if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0)
+ || (decimalPos >= 0
+ && (sigDigitCount > 0
+ || decimalPos < digitLeftCount
+ || decimalPos > (digitLeftCount + zeroDigitCount)))
+ || groupingCount == 0
+ || groupingCount2 == 0
+ || (sigDigitCount > 0 && zeroDigitCount > 0)
+ || subpart > 2) { // subpart > 2 == unmatched quote
+ patternError("Malformed pattern", pattern);
+ }
+
+ // Make sure pad is at legal position before or after affix.
+ if (padPos >= 0) {
+ if (padPos == start) {
+ padPos = PAD_BEFORE_PREFIX;
+ } else if (padPos + 2 == sub0Start) {
+ padPos = PAD_AFTER_PREFIX;
+ } else if (padPos == sub0Limit) {
+ padPos = PAD_BEFORE_SUFFIX;
+ } else if (padPos + 2 == sub2Limit) {
+ padPos = PAD_AFTER_SUFFIX;
+ } else {
+ patternError("Illegal pad position", pattern);
+ }
+ }
+
+ if (part == 0) {
+ // Set negative affixes temporarily to match the positive
+ // affixes. Fix this up later after processing both parts.
+
+ // Bug 4212072 To meet the need of expandAffix(String, StirngBuffer)
+ // [Richard/GCL]
+ posPrefixPattern = negPrefixPattern = prefix.toString();
+ posSuffixPattern = negSuffixPattern = suffix.toString();
+
+ useExponentialNotation = (expDigits >= 0);
+ if (useExponentialNotation) {
+ minExponentDigits = expDigits;
+ exponentSignAlwaysShown = expSignAlways;
+ }
+ int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
+ // The effectiveDecimalPos is the position the decimal is at or would be
+ // at if there is no decimal. Note that if decimalPos<0, then
+ // digitTotalCount == digitLeftCount + zeroDigitCount.
+ int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
+ boolean useSigDig = (sigDigitCount > 0);
+ setSignificantDigitsUsed(useSigDig);
+ if (useSigDig) {
+ setMinimumSignificantDigits(sigDigitCount);
+ setMaximumSignificantDigits(sigDigitCount + digitRightCount);
+ } else {
+ int minInt = effectiveDecimalPos - digitLeftCount;
+ setMinimumIntegerDigits(minInt);
+
+ // Upper limit on integer and fraction digits for a Java double
+ // [Richard/GCL]
+ setMaximumIntegerDigits(useExponentialNotation ? digitLeftCount + minInt :
+ DOUBLE_INTEGER_DIGITS);
+ _setMaximumFractionDigits(decimalPos >= 0 ?
+ (digitTotalCount - decimalPos) : 0);
+ setMinimumFractionDigits(decimalPos >= 0 ?
+ (digitLeftCount + zeroDigitCount - decimalPos) : 0);
+ }
+ setGroupingUsed(groupingCount > 0);
+ this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
+ this.groupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
+ ? groupingCount2 : 0;
+ this.multiplier = multpl;
+ setDecimalSeparatorAlwaysShown(decimalPos == 0 || decimalPos == digitTotalCount);
+ if (padPos >= 0) {
+ padPosition = padPos;
+ formatWidth = sub0Limit - sub0Start; // to be fixed up below
+ pad = padChar;
+ } else {
+ formatWidth = 0;
+ }
+ if (incrementVal != 0) {
+ // BigDecimal scale cannot be negative (even though this makes perfect
+ // sense), so we need to handle this.
+ int scale = incrementPos - effectiveDecimalPos;
+ roundingIncrementICU = BigDecimal.valueOf(incrementVal, scale > 0 ? scale : 0);
+ if (scale < 0) {
+ roundingIncrementICU = roundingIncrementICU.movePointRight(-scale);
+ }
+ roundingMode = BigDecimal.ROUND_HALF_EVEN;
+ } else {
+ setRoundingIncrement((BigDecimal) null);
+ }
+
+ // Update currency sign count for the new pattern
+ currencySignCount = currencySignCnt;
+ } else {
+ // Bug 4212072 To meet the need of expandAffix(String, StirngBuffer)
+ // [Richard/GCL]
+ negPrefixPattern = prefix.toString();
+ negSuffixPattern = suffix.toString();
+ gotNegative = true;
+ }
+ }
+
+
+ // Bug 4140009 Process the empty pattern [Richard/GCL]
+ if (pattern.length() == 0) {
+ posPrefixPattern = posSuffixPattern = "";
+ setMinimumIntegerDigits(0);
+ setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);
+ setMinimumFractionDigits(0);
+ _setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
+ }
+
+ // If there was no negative pattern, or if the negative pattern is identical to
+ // the positive pattern, then prepend the minus sign to the positive pattern to
+ // form the negative pattern.
+
+ // Bug 4212072 To meet the need of expandAffix(String, StirngBuffer) [Richard/GCL]
+
+ if (!gotNegative ||
+ (negPrefixPattern.equals(posPrefixPattern)
+ && negSuffixPattern.equals(posSuffixPattern))) {
+ negSuffixPattern = posSuffixPattern;
+ negPrefixPattern = PATTERN_MINUS_SIGN + posPrefixPattern;
+ }
+
+ // Can't call setLocale when not in the right package:
+ //setLocale(null, null);
+
+ // save the pattern
+ formatPattern = pattern;
+
+ // special handlings for currency instance
+ if (currencySignCount != CURRENCY_SIGN_COUNT_ZERO) {
+ // reset rounding increment and max/min fractional digits
+ // by the currency
+ Currency theCurrency = getCurrency();
+ if (theCurrency != null) {
+ setRoundingIncrement(theCurrency.getRoundingIncrement(currencyUsage));
+ int d = theCurrency.getDefaultFractionDigits(currencyUsage);
+ setMinimumFractionDigits(d);
+ _setMaximumFractionDigits(d);
+ }
+
+ // initialize currencyPluralInfo if needed
+ if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT
+ && currencyPluralInfo == null) {
+ currencyPluralInfo = new CurrencyPluralInfo(symbols.getULocale());
+ }
+ }
+ resetActualRounding();
+ }
+
+
+ private void patternError(String msg, String pattern) {
+ throw new IllegalArgumentException(msg + " in pattern \"" + pattern + '"');
+ }
+
+
+ // Rewrite the following 4 "set" methods Upper limit on integer and fraction digits
+ // for a Java double [Richard/GCL]
+
+ /**
+ * Sets the maximum number of digits allowed in the integer portion of a number. This
+ * override limits the integer digit count to 309.
+ *
+ * @see NumberFormat#setMaximumIntegerDigits
+ * @stable ICU 2.0
+ */
+ @Override
+ public void setMaximumIntegerDigits(int newValue) {
+ super.setMaximumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));
+ }
+
+ /**
+ * Sets the minimum number of digits allowed in the integer portion of a number. This
+ * override limits the integer digit count to 309.
+ *
+ * @see NumberFormat#setMinimumIntegerDigits
+ * @stable ICU 2.0
+ */
+ @Override
+ public void setMinimumIntegerDigits(int newValue) {
+ super.setMinimumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));
+ }
+
+ /**
+ * {@icu} Returns the minimum number of significant digits that will be
+ * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
+ * returns true.
+ *
+ * @return the fewest significant digits that will be shown
+ * @stable ICU 3.0
+ */
+ public int getMinimumSignificantDigits() {
+ return minSignificantDigits;
+ }
+
+ /**
+ * {@icu} Returns the maximum number of significant digits that will be
+ * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
+ * returns true.
+ *
+ * @return the most significant digits that will be shown
+ * @stable ICU 3.0
+ */
+ public int getMaximumSignificantDigits() {
+ return maxSignificantDigits;
+ }
+
+ /**
+ * {@icu} Sets the minimum number of significant digits that will be displayed. If
+ * <code>min</code> is less than one then it is set to one. If the maximum significant
+ * digits count is less than <code>min</code>, then it is set to <code>min</code>.
+ * This function also enables the use of significant digits by this formatter -
+ * {@link #areSignificantDigitsUsed()} will return true.
+ *
+ * @param min the fewest significant digits to be shown
+ * @stable ICU 3.0
+ */
+ public void setMinimumSignificantDigits(int min) {
+ if (min < 1) {
+ min = 1;
+ }
+ // pin max sig dig to >= min
+ int max = Math.max(maxSignificantDigits, min);
+ minSignificantDigits = min;
+ maxSignificantDigits = max;
+ setSignificantDigitsUsed(true);
+ }
+
+ /**
+ * {@icu} Sets the maximum number of significant digits that will be displayed. If
+ * <code>max</code> is less than one then it is set to one. If the minimum significant
+ * digits count is greater than <code>max</code>, then it is set to <code>max</code>.
+ * This function also enables the use of significant digits by this formatter -
+ * {@link #areSignificantDigitsUsed()} will return true.
+ *
+ * @param max the most significant digits to be shown
+ * @stable ICU 3.0
+ */
+ public void setMaximumSignificantDigits(int max) {
+ if (max < 1) {
+ max = 1;
+ }
+ // pin min sig dig to 1..max
+ int min = Math.min(minSignificantDigits, max);
+ minSignificantDigits = min;
+ maxSignificantDigits = max;
+ setSignificantDigitsUsed(true);
+ }
+
+ /**
+ * {@icu} Returns true if significant digits are in use or false if integer and
+ * fraction digit counts are in use.
+ *
+ * @return true if significant digits are in use
+ * @stable ICU 3.0
+ */
+ public boolean areSignificantDigitsUsed() {
+ return useSignificantDigits;
+ }
+
+ /**
+ * {@icu} Sets whether significant digits are in use, or integer and fraction digit
+ * counts are in use.
+ *
+ * @param useSignificantDigits true to use significant digits, or false to use integer
+ * and fraction digit counts
+ * @stable ICU 3.0
+ */
+ public void setSignificantDigitsUsed(boolean useSignificantDigits) {
+ this.useSignificantDigits = useSignificantDigits;
+ }
+
+ /**
+ * Sets the <tt>Currency</tt> object used to display currency amounts. This takes
+ * effect immediately, if this format is a currency format. If this format is not a
+ * currency format, then the currency object is used if and when this object becomes a
+ * currency format through the application of a new pattern.
+ *
+ * @param theCurrency new currency object to use. Must not be null.
+ * @stable ICU 2.2
+ */
+ @Override
+ public void setCurrency(Currency theCurrency) {
+ // If we are a currency format, then modify our affixes to
+ // encode the currency symbol for the given currency in our
+ // locale, and adjust the decimal digits and rounding for the
+ // given currency.
+
+ super.setCurrency(theCurrency);
+ if (theCurrency != null) {
+ String s = theCurrency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null);
+ symbols.setCurrency(theCurrency);
+ symbols.setCurrencySymbol(s);
+ }
+
+ if (currencySignCount != CURRENCY_SIGN_COUNT_ZERO) {
+ if (theCurrency != null) {
+ setRoundingIncrement(theCurrency.getRoundingIncrement(currencyUsage));
+ int d = theCurrency.getDefaultFractionDigits(currencyUsage);
+ setMinimumFractionDigits(d);
+ setMaximumFractionDigits(d);
+ }
+ if (currencySignCount != CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+ // This is not necessary for plural format type
+ // because affixes will be resolved in subformat
+ expandAffixes(null);
+ }
+ }
+ }
+
+ /**
+ * Sets the <tt>Currency Usage</tt> object used to display currency.
+ * This takes effect immediately, if this format is a
+ * currency format.
+ * @param newUsage new currency context object to use.
+ * @stable ICU 54
+ */
+ public void setCurrencyUsage(CurrencyUsage newUsage) {
+ if (newUsage == null) {
+ throw new NullPointerException("return value is null at method AAA");
+ }
+ currencyUsage = newUsage;
+ Currency theCurrency = this.getCurrency();
+
+ // We set rounding/digit based on currency context
+ if (theCurrency != null) {
+ setRoundingIncrement(theCurrency.getRoundingIncrement(currencyUsage));
+ int d = theCurrency.getDefaultFractionDigits(currencyUsage);
+ setMinimumFractionDigits(d);
+ _setMaximumFractionDigits(d);
+ }
+ }
+
+ /**
+ * Returns the <tt>Currency Usage</tt> object used to display currency
+ * @stable ICU 54
+ */
+ public CurrencyUsage getCurrencyUsage() {
+ return currencyUsage;
+ }
+
+ /**
+ * Returns the currency in effect for this formatter. Subclasses should override this
+ * method as needed. Unlike getCurrency(), this method should never return null.
+ *
+ * @internal
+ * @deprecated This API is ICU internal only.
+ */
+ @Deprecated
+ @Override
+ protected Currency getEffectiveCurrency() {
+ Currency c = getCurrency();
+ if (c == null) {
+ c = Currency.getInstance(symbols.getInternationalCurrencySymbol());
+ }
+ return c;
+ }
+
+ /**
+ * Sets the maximum number of digits allowed in the fraction portion of a number. This
+ * override limits the fraction digit count to 340.
+ *
+ * @see NumberFormat#setMaximumFractionDigits
+ * @stable ICU 2.0
+ */
+ @Override
+ public void setMaximumFractionDigits(int newValue) {
+ _setMaximumFractionDigits(newValue);
+ resetActualRounding();
+ }
+
+ /*
+ * Internal method for DecimalFormat, setting maximum fractional digits
+ * without triggering actual rounding recalculated.
+ */
+ private void _setMaximumFractionDigits(int newValue) {
+ super.setMaximumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));
+ }
+
+ /**
+ * Sets the minimum number of digits allowed in the fraction portion of a number. This
+ * override limits the fraction digit count to 340.
+ *
+ * @see NumberFormat#setMinimumFractionDigits
+ * @stable ICU 2.0
+ */
+ @Override
+ public void setMinimumFractionDigits(int newValue) {
+ super.setMinimumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));
+ }
+
+ /**
+ * Sets whether {@link #parse(String, ParsePosition)} returns BigDecimal. The
+ * default value is false.
+ *
+ * @param value true if {@link #parse(String, ParsePosition)}
+ * returns BigDecimal.
+ * @stable ICU 3.6
+ */
+ public void setParseBigDecimal(boolean value) {
+ parseBigDecimal = value;
+ }
+
+ /**
+ * Returns whether {@link #parse(String, ParsePosition)} returns BigDecimal.
+ *
+ * @return true if {@link #parse(String, ParsePosition)} returns BigDecimal.
+ * @stable ICU 3.6
+ */
+ public boolean isParseBigDecimal() {
+ return parseBigDecimal;
+ }
+
+ /**
+ * Set the maximum number of exponent digits when parsing a number.
+ * If the limit is set too high, an OutOfMemoryException may be triggered.
+ * The default value is 1000.
+ * @param newValue the new limit
+ * @stable ICU 51
+ */
+ public void setParseMaxDigits(int newValue) {
+ if (newValue > 0) {
+ PARSE_MAX_EXPONENT = newValue;
+ }
+ }
+
+ /**
+ * Get the current maximum number of exponent digits when parsing a
+ * number.
+ * @return the maximum number of exponent digits for parsing
+ * @stable ICU 51
+ */
+ public int getParseMaxDigits() {
+ return PARSE_MAX_EXPONENT;
+ }
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ // Ticket#6449 Format.Field instances are not serializable. When
+ // formatToCharacterIterator is called, attributes (ArrayList) stores
+ // FieldPosition instances with NumberFormat.Field. Because NumberFormat.Field is
+ // not serializable, we need to clear the contents of the list when writeObject is
+ // called. We could remove the field or make it transient, but it will break
+ // serialization compatibility.
+ attributes.clear();
+
+ stream.defaultWriteObject();
+ }
+
+ /**
+ * First, read the default serializable fields from the stream. Then if
+ * <code>serialVersionOnStream</code> is less than 1, indicating that the stream was
+ * written by JDK 1.1, initialize <code>useExponentialNotation</code> to false, since
+ * it was not present in JDK 1.1. Finally, set serialVersionOnStream back to the
+ * maximum allowed value so that default serialization will work properly if this
+ * object is streamed out again.
+ */
+ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ stream.defaultReadObject();
+
+ // Bug 4185761 validate fields [Richard/GCL]
+
+ // We only need to check the maximum counts because NumberFormat .readObject has
+ // already ensured that the maximum is greater than the minimum count.
+
+ // Commented for compatibility with previous version, and reserved for further use
+ // if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
+ // getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) { throw new
+ // InvalidObjectException("Digit count out of range"); }
+
+
+ // Truncate the maximumIntegerDigits to DOUBLE_INTEGER_DIGITS and
+ // maximumFractionDigits to DOUBLE_FRACTION_DIGITS
+
+ if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS) {
+ setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);
+ }
+ if (getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
+ _setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
+ }
+ if (serialVersionOnStream < 2) {
+ exponentSignAlwaysShown = false;
+ setInternalRoundingIncrement(null);
+ roundingMode = BigDecimal.ROUND_HALF_EVEN;
+ formatWidth = 0;
+ pad = ' ';
+ padPosition = PAD_BEFORE_PREFIX;
+ if (serialVersionOnStream < 1) {
+ // Didn't have exponential fields
+ useExponentialNotation = false;
+ }
+ }
+ if (serialVersionOnStream < 3) {
+ // Versions prior to 3 do not store a currency object. Create one to match
+ // the DecimalFormatSymbols object.
+ setCurrencyForSymbols();
+ }
+ if (serialVersionOnStream < 4) {
+ currencyUsage = CurrencyUsage.STANDARD;
+ }
+ serialVersionOnStream = currentSerialVersion;
+ digitList = new DigitList();
+
+ if (roundingIncrement != null) {
+ setInternalRoundingIncrement(new BigDecimal(roundingIncrement));
+ }
+ resetActualRounding();
+ }
+
+ private void setInternalRoundingIncrement(BigDecimal value) {
+ roundingIncrementICU = value;
+ roundingIncrement = value == null ? null : value.toBigDecimal();
+ }
+
+ // ----------------------------------------------------------------------
+ // INSTANCE VARIABLES
+ // ----------------------------------------------------------------------
+
+ private transient DigitList digitList = new DigitList();
+
+ /**
+ * The symbol used as a prefix when formatting positive numbers, e.g. "+".
+ *
+ * @serial
+ * @see #getPositivePrefix
+ */
+ private String positivePrefix = "";
+
+ /**
+ * The symbol used as a suffix when formatting positive numbers. This is often an
+ * empty string.
+ *
+ * @serial
+ * @see #getPositiveSuffix
+ */
+ private String positiveSuffix = "";
+
+ /**
+ * The symbol used as a prefix when formatting negative numbers, e.g. "-".
+ *
+ * @serial
+ * @see #getNegativePrefix
+ */
+ private String negativePrefix = "-";
+
+ /**
+ * The symbol used as a suffix when formatting negative numbers. This is often an
+ * empty string.
+ *
+ * @serial
+ * @see #getNegativeSuffix
+ */
+ private String negativeSuffix = "";
+
+ /**
+ * The prefix pattern for non-negative numbers. This variable corresponds to
+ * <code>positivePrefix</code>.
+ *
+ * <p>This pattern is expanded by the method <code>expandAffix()</code> to
+ * <code>positivePrefix</code> to update the latter to reflect changes in
+ * <code>symbols</code>. If this variable is <code>null</code> then
+ * <code>positivePrefix</code> is taken as a literal value that does not change when
+ * <code>symbols</code> changes. This variable is always <code>null</code> for
+ * <code>DecimalFormat</code> objects older than stream version 2 restored from
+ * stream.
+ *
+ * @serial
+ */
+ // [Richard/GCL]
+ private String posPrefixPattern;
+
+ /**
+ * The suffix pattern for non-negative numbers. This variable corresponds to
+ * <code>positiveSuffix</code>. This variable is analogous to
+ * <code>posPrefixPattern</code>; see that variable for further documentation.
+ *
+ * @serial
+ */
+ // [Richard/GCL]
+ private String posSuffixPattern;
+
+ /**
+ * The prefix pattern for negative numbers. This variable corresponds to
+ * <code>negativePrefix</code>. This variable is analogous to
+ * <code>posPrefixPattern</code>; see that variable for further documentation.
+ *
+ * @serial
+ */
+ // [Richard/GCL]
+ private String negPrefixPattern;
+
+ /**
+ * The suffix pattern for negative numbers. This variable corresponds to
+ * <code>negativeSuffix</code>. This variable is analogous to
+ * <code>posPrefixPattern</code>; see that variable for further documentation.
+ *
+ * @serial
+ */
+ // [Richard/GCL]
+ private String negSuffixPattern;
+
+ /**
+ * Formatter for ChoiceFormat-based currency names. If this field is not null, then
+ * delegate to it to format currency symbols.
+ * TODO: This is obsolete: Remove, and design extensible serialization. ICU ticket #12090.
+ *
+ * @since ICU 2.6
+ */
+ private ChoiceFormat currencyChoice;
+
+ /**
+ * The multiplier for use in percent, permill, etc.
+ *
+ * @serial
+ * @see #getMultiplier
+ */
+ private int multiplier = 1;
+
+ /**
+ * The number of digits between grouping separators in the integer portion of a
+ * number. Must be greater than 0 if <code>NumberFormat.groupingUsed</code> is true.
+ *
+ * @serial
+ * @see #getGroupingSize
+ * @see NumberFormat#isGroupingUsed
+ */
+ private byte groupingSize = 3; // invariant, > 0 if useThousands
+
+ /**
+ * The secondary grouping size. This is only used for Hindi numerals, which use a
+ * primary grouping of 3 and a secondary grouping of 2, e.g., "12,34,567". If this
+ * value is less than 1, then secondary grouping is equal to the primary grouping.
+ *
+ */
+ private byte groupingSize2 = 0;
+
+ /**
+ * If true, forces the decimal separator to always appear in a formatted number, even
+ * if the fractional part of the number is zero.
+ *
+ * @serial
+ * @see #isDecimalSeparatorAlwaysShown
+ */
+ private boolean decimalSeparatorAlwaysShown = false;
+
+ /**
+ * The <code>DecimalFormatSymbols</code> object used by this format. It contains the
+ * symbols used to format numbers, e.g. the grouping separator, decimal separator, and
+ * so on.
+ *
+ * @serial
+ * @see #setDecimalFormatSymbols
+ * @see DecimalFormatSymbols
+ */
+ private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
+
+ /**
+ * True to use significant digits rather than integer and fraction digit counts.
+ *
+ * @serial
+ * @since ICU 3.0
+ */
+ private boolean useSignificantDigits = false;
+
+ /**
+ * The minimum number of significant digits to show. Must be &gt;= 1 and &lt;=
+ * maxSignificantDigits. Ignored unless useSignificantDigits == true.
+ *
+ * @serial
+ * @since ICU 3.0
+ */
+ private int minSignificantDigits = 1;
+
+ /**
+ * The maximum number of significant digits to show. Must be &gt;=
+ * minSignficantDigits. Ignored unless useSignificantDigits == true.
+ *
+ * @serial
+ * @since ICU 3.0
+ */
+ private int maxSignificantDigits = 6;
+
+ /**
+ * True to force the use of exponential (i.e. scientific) notation
+ * when formatting numbers.
+ *
+ *<p> Note that the JDK 1.2 public API provides no way to set this
+ * field, even though it is supported by the implementation and
+ * the stream format. The intent is that this will be added to the
+ * API in the future.
+ *
+ * @serial
+ */
+ private boolean useExponentialNotation; // Newly persistent in JDK 1.2
+
+ /**
+ * The minimum number of digits used to display the exponent when a number is
+ * formatted in exponential notation. This field is ignored if
+ * <code>useExponentialNotation</code> is not true.
+ *
+ * <p>Note that the JDK 1.2 public API provides no way to set this field, even though
+ * it is supported by the implementation and the stream format. The intent is that
+ * this will be added to the API in the future.
+ *
+ * @serial
+ */
+ private byte minExponentDigits; // Newly persistent in JDK 1.2
+
+ /**
+ * If true, the exponent is always prefixed with either the plus sign or the minus
+ * sign. Otherwise, only negative exponents are prefixed with the minus sign. This has
+ * no effect unless <code>useExponentialNotation</code> is true.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private boolean exponentSignAlwaysShown = false;
+
+ /**
+ * The value to which numbers are rounded during formatting. For example, if the
+ * rounding increment is 0.05, then 13.371 would be formatted as 13.350, assuming 3
+ * fraction digits. Has the value <code>null</code> if rounding is not in effect, or a
+ * positive value if rounding is in effect. Default value <code>null</code>.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ // Note: this is kept in sync with roundingIncrementICU.
+ // it is only kept around to avoid a conversion when formatting a java.math.BigDecimal
+ private java.math.BigDecimal roundingIncrement = null;
+
+ /**
+ * The value to which numbers are rounded during formatting. For example, if the
+ * rounding increment is 0.05, then 13.371 would be formatted as 13.350, assuming 3
+ * fraction digits. Has the value <code>null</code> if rounding is not in effect, or a
+ * positive value if rounding is in effect. Default value <code>null</code>. WARNING:
+ * the roundingIncrement value is the one serialized.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private transient BigDecimal roundingIncrementICU = null;
+
+ /**
+ * The rounding mode. This value controls any rounding operations which occur when
+ * applying a rounding increment or when reducing the number of fraction digits to
+ * satisfy a maximum fraction digits limit. The value may assume any of the
+ * <code>BigDecimal</code> rounding mode values. Default value
+ * <code>BigDecimal.ROUND_HALF_EVEN</code>.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private int roundingMode = BigDecimal.ROUND_HALF_EVEN;
+
+ /**
+ * Operations on <code>BigDecimal</code> numbers are controlled by a {@link
+ * MathContext} object, which provides the context (precision and other information)
+ * for the operation. The default <code>MathContext</code> settings are
+ * <code>digits=0, form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>;
+ * these settings perform fixed point arithmetic with unlimited precision, as defined
+ * for the original BigDecimal class in Java 1.1 and Java 1.2
+ */
+ // context for plain unlimited math
+ private MathContext mathContext = new MathContext(0, MathContext.PLAIN);
+
+ /**
+ * The padded format width, or zero if there is no padding. Must be &gt;= 0. Default
+ * value zero.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private int formatWidth = 0;
+
+ /**
+ * The character used to pad the result of format to <code>formatWidth</code>, if
+ * padding is in effect. Default value ' '.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private char pad = ' ';
+
+ /**
+ * The position in the string at which the <code>pad</code> character will be
+ * inserted, if padding is in effect. Must have a value from
+ * <code>PAD_BEFORE_PREFIX</code> to <code>PAD_AFTER_SUFFIX</code>. Default value
+ * <code>PAD_BEFORE_PREFIX</code>.
+ *
+ * @serial
+ * @since AlphaWorks NumberFormat
+ */
+ private int padPosition = PAD_BEFORE_PREFIX;
+
+ /**
+ * True if {@link #parse(String, ParsePosition)} to return BigDecimal rather than
+ * Long, Double or BigDecimal except special values. This property is introduced for
+ * J2SE 5 compatibility support.
+ *
+ * @serial
+ * @since ICU 3.6
+ * @see #setParseBigDecimal(boolean)
+ * @see #isParseBigDecimal()
+ */
+ private boolean parseBigDecimal = false;
+
+ /**
+ * The currency usage for the NumberFormat(standard or cash usage).
+ * It is used as STANDARD by default
+ * @since ICU 54
+ */
+ private CurrencyUsage currencyUsage = CurrencyUsage.STANDARD;
+
+ // ----------------------------------------------------------------------
+
+ static final int currentSerialVersion = 4;
+
+ /**
+ * The internal serial version which says which version was written Possible values
+ * are:
+ *
+ * <ul>
+ *
+ * <li><b>0</b> (default): versions before JDK 1.2
+ *
+ * <li><b>1</b>: version from JDK 1.2 and later, which includes the two new fields
+ * <code>useExponentialNotation</code> and <code>minExponentDigits</code>.
+ *
+ * <li><b>2</b>: version on AlphaWorks, which adds roundingMode, formatWidth, pad,
+ * padPosition, exponentSignAlwaysShown, roundingIncrement.
+ *
+ * <li><b>3</b>: ICU 2.2. Adds currency object.
+ *
+ * <li><b>4</b>: ICU 54. Adds currency usage(standard vs cash)
+ *
+ * </ul>
+ *
+ * @serial
+ */
+ private int serialVersionOnStream = currentSerialVersion;
+
+ // ----------------------------------------------------------------------
+ // CONSTANTS
+ // ----------------------------------------------------------------------
+
+ /**
+ * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
+ * specify pad characters inserted before the prefix.
+ *
+ * @see #setPadPosition
+ * @see #getPadPosition
+ * @see #PAD_AFTER_PREFIX
+ * @see #PAD_BEFORE_SUFFIX
+ * @see #PAD_AFTER_SUFFIX
+ * @stable ICU 2.0
+ */
+ public static final int PAD_BEFORE_PREFIX = 0;
+
+ /**
+ * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
+ * specify pad characters inserted after the prefix.
+ *
+ * @see #setPadPosition
+ * @see #getPadPosition
+ * @see #PAD_BEFORE_PREFIX
+ * @see #PAD_BEFORE_SUFFIX
+ * @see #PAD_AFTER_SUFFIX
+ * @stable ICU 2.0
+ */
+ public static final int PAD_AFTER_PREFIX = 1;
+
+ /**
+ * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
+ * specify pad characters inserted before the suffix.
+ *
+ * @see #setPadPosition
+ * @see #getPadPosition
+ * @see #PAD_BEFORE_PREFIX
+ * @see #PAD_AFTER_PREFIX
+ * @see #PAD_AFTER_SUFFIX
+ * @stable ICU 2.0
+ */
+ public static final int PAD_BEFORE_SUFFIX = 2;
+
+ /**
+ * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
+ * specify pad characters inserted after the suffix.
+ *
+ * @see #setPadPosition
+ * @see #getPadPosition
+ * @see #PAD_BEFORE_PREFIX
+ * @see #PAD_AFTER_PREFIX
+ * @see #PAD_BEFORE_SUFFIX
+ * @stable ICU 2.0
+ */
+ public static final int PAD_AFTER_SUFFIX = 3;
+
+ // Constants for characters used in programmatic (unlocalized) patterns.
+ static final char PATTERN_ZERO_DIGIT = '0';
+ static final char PATTERN_ONE_DIGIT = '1';
+ static final char PATTERN_TWO_DIGIT = '2';
+ static final char PATTERN_THREE_DIGIT = '3';
+ static final char PATTERN_FOUR_DIGIT = '4';
+ static final char PATTERN_FIVE_DIGIT = '5';
+ static final char PATTERN_SIX_DIGIT = '6';
+ static final char PATTERN_SEVEN_DIGIT = '7';
+ static final char PATTERN_EIGHT_DIGIT = '8';
+ static final char PATTERN_NINE_DIGIT = '9';
+ static final char PATTERN_GROUPING_SEPARATOR = ',';
+ static final char PATTERN_DECIMAL_SEPARATOR = '.';
+ static final char PATTERN_DIGIT = '#';
+ static final char PATTERN_SIGNIFICANT_DIGIT = '@';
+ static final char PATTERN_EXPONENT = 'E';
+ static final char PATTERN_PLUS_SIGN = '+';
+ static final char PATTERN_MINUS_SIGN = '-';
+
+ // Affix
+ private static final char PATTERN_PER_MILLE = '\u2030';
+ private static final char PATTERN_PERCENT = '%';
+ static final char PATTERN_PAD_ESCAPE = '*';
+
+ // Other
+ private static final char PATTERN_SEPARATOR = ';';
+
+ // Pad escape is package private to allow access by DecimalFormatSymbols.
+ // Also plus sign. Also exponent.
+
+ /**
+ * The CURRENCY_SIGN is the standard Unicode symbol for currency. It is used in
+ * patterns and substitued with either the currency symbol, or if it is doubled, with
+ * the international currency symbol. If the CURRENCY_SIGN is seen in a pattern, then
+ * the decimal separator is replaced with the monetary decimal separator.
+ *
+ * The CURRENCY_SIGN is not localized.
+ */
+ private static final char CURRENCY_SIGN = '\u00A4';
+
+ private static final char QUOTE = '\'';
+
+ /**
+ * Upper limit on integer and fraction digits for a Java double [Richard/GCL]
+ */
+ static final int DOUBLE_INTEGER_DIGITS = 309;
+ static final int DOUBLE_FRACTION_DIGITS = 340;
+
+ /**
+ * When someone turns on scientific mode, we assume that more than this number of
+ * digits is due to flipping from some other mode that didn't restrict the maximum,
+ * and so we force 1 integer digit. We don't bother to track and see if someone is
+ * using exponential notation with more than this number, it wouldn't make sense
+ * anyway, and this is just to make sure that someone turning on scientific mode with
+ * default settings doesn't end up with lots of zeroes.
+ */
+ static final int MAX_SCIENTIFIC_INTEGER_DIGITS = 8;
+
+ // Proclaim JDK 1.1 serial compatibility.
+ private static final long serialVersionUID = 864413376551465018L;
+
+ private ArrayList<FieldPosition> attributes = new ArrayList<>();
+
+ // The following are used in currency format
+
+ // -- triple currency sign char array
+ // private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
+ // -- triple currency sign string
+ // private static final String tripleCurrencyStr = new String(tripleCurrencySign);
+ //
+ // -- default currency plural pattern char array
+ // private static final char[] defaultCurrencyPluralPatternChar =
+ // {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
+ // -- default currency plural pattern string
+ // private static final String defaultCurrencyPluralPattern =
+ // new String(defaultCurrencyPluralPatternChar);
+
+ // pattern used in this formatter
+ private String formatPattern = "";
+ // style is only valid when decimal formatter is constructed by
+ // DecimalFormat(pattern, decimalFormatSymbol, style)
+ private int style = NumberFormat.NUMBERSTYLE;
+ /**
+ * Represents whether this is a currency format, and which currency format style. 0:
+ * not currency format type; 1: currency style -- symbol name, such as "$" for US
+ * dollar. 2: currency style -- ISO name, such as USD for US dollar. 3: currency style
+ * -- plural long name, such as "US Dollar" for "1.00 US Dollar", or "US Dollars" for
+ * "3.00 US Dollars".
+ */
+ private int currencySignCount = CURRENCY_SIGN_COUNT_ZERO;
+
+ /**
+ * For parsing purposes, we need to remember all prefix patterns and suffix patterns
+ * of every currency format pattern, including the pattern of the default currency
+ * style, ISO currency style, and plural currency style. The patterns are set through
+ * applyPattern. The following are used to represent the affix patterns in currency
+ * plural formats.
+ */
+ private static final class AffixForCurrency {
+ // negative prefix pattern
+ private String negPrefixPatternForCurrency = null;
+ // negative suffix pattern
+ private String negSuffixPatternForCurrency = null;
+ // positive prefix pattern
+ private String posPrefixPatternForCurrency = null;
+ // positive suffix pattern
+ private String posSuffixPatternForCurrency = null;
+ private final int patternType;
+
+ public AffixForCurrency(String negPrefix, String negSuffix, String posPrefix,
+ String posSuffix, int type) {
+ negPrefixPatternForCurrency = negPrefix;
+ negSuffixPatternForCurrency = negSuffix;
+ posPrefixPatternForCurrency = posPrefix;
+ posSuffixPatternForCurrency = posSuffix;
+ patternType = type;
+ }
+
+ public String getNegPrefix() {
+ return negPrefixPatternForCurrency;
+ }
+
+ public String getNegSuffix() {
+ return negSuffixPatternForCurrency;
+ }
+
+ public String getPosPrefix() {
+ return posPrefixPatternForCurrency;
+ }
+
+ public String getPosSuffix() {
+ return posSuffixPatternForCurrency;
+ }
+
+ public int getPatternType() {
+ return patternType;
+ }
+ }
+
+ // Affix pattern set for currency. It is a set of AffixForCurrency, each element of
+ // the set saves the negative prefix, negative suffix, positive prefix, and positive
+ // suffix of a pattern.
+ private transient Set<AffixForCurrency> affixPatternsForCurrency = null;
+
+ // For currency parsing. Since currency parsing needs to parse against all currency
+ // patterns, before the parsing, we need to set up the affix patterns for all currencies.
+ private transient boolean isReadyForParsing = false;
+
+ // Information needed for DecimalFormat to format/parse currency plural.
+ private CurrencyPluralInfo currencyPluralInfo = null;
+
+ /**
+ * Unit is an immutable class for the textual representation of a unit, in
+ * particular its prefix and suffix.
+ *
+ * @author rocketman
+ *
+ */
+ static class Unit {
+ private final String prefix;
+ private final String suffix;
+
+ public Unit(String prefix, String suffix) {
+ this.prefix = prefix;
+ this.suffix = suffix;
+ }
+
+ public void writeSuffix(StringBuffer toAppendTo) {
+ toAppendTo.append(suffix);
+ }
+
+ public void writePrefix(StringBuffer toAppendTo) {
+ toAppendTo.append(prefix);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof Unit)) {
+ return false;
+ }
+ Unit other = (Unit) obj;
+ return prefix.equals(other.prefix) && suffix.equals(other.suffix);
+ }
+ @Override
+ public String toString() {
+ return prefix + "/" + suffix;
+ }
+ }
+
+ static final Unit NULL_UNIT = new Unit("", "");
+
+ // Note about rounding implementation
+ //
+ // The original design intended to skip rounding operation when roundingIncrement is not
+ // set. However, rounding may need to occur when fractional digits exceed the width of
+ // fractional part of pattern.
+ //
+ // DigitList class has built-in rounding mechanism, using ROUND_HALF_EVEN. This implementation
+ // forces non-null roundingIncrement if the setting is other than ROUND_HALF_EVEN, otherwise,
+ // when rounding occurs in DigitList by pattern's fractional digits' width, the result
+ // does not match the rounding mode.
+ //
+ // Ideally, all rounding operation should be done in one place like ICU4C trunk does
+ // (ICU4C rounding implementation was rewritten recently). This is intrim implemetation
+ // to fix various issues. In the future, we should entire implementation of rounding
+ // in this class, like ICU4C did.
+ //
+ // Once we fully implement rounding logic in DigitList, then following fields and methods
+ // should be gone.
+
+ private transient BigDecimal actualRoundingIncrementICU = null;
+ private transient java.math.BigDecimal actualRoundingIncrement = null;
+
+ /*
+ * The actual rounding increment as a double.
+ */
+ private transient double roundingDouble = 0.0;
+
+ /*
+ * If the roundingDouble is the reciprocal of an integer (the most common case!), this
+ * is set to be that integer. Otherwise it is 0.0.
+ */
+ private transient double roundingDoubleReciprocal = 0.0;
+
+ /*
+ * Set roundingDouble, roundingDoubleReciprocal and actualRoundingIncrement
+ * based on rounding mode and width of fractional digits. Whenever setting affecting
+ * rounding mode, rounding increment and maximum width of fractional digits, then
+ * this method must be called.
+ *
+ * roundingIncrementICU is the field storing the custom rounding increment value,
+ * while actual rounding increment could be larger.
+ */
+ private void resetActualRounding() {
+ if (roundingIncrementICU != null) {
+ BigDecimal byWidth = getMaximumFractionDigits() > 0 ?
+ BigDecimal.ONE.movePointLeft(getMaximumFractionDigits()) : BigDecimal.ONE;
+ if (roundingIncrementICU.compareTo(byWidth) >= 0) {
+ actualRoundingIncrementICU = roundingIncrementICU;
+ } else {
+ actualRoundingIncrementICU = byWidth.equals(BigDecimal.ONE) ? null : byWidth;
+ }
+ } else {
+ if (roundingMode == BigDecimal.ROUND_HALF_EVEN || isScientificNotation()) {
+ // This rounding fix is irrelevant if mode is ROUND_HALF_EVEN as DigitList
+ // does ROUND_HALF_EVEN for us. This rounding fix won't work at all for
+ // scientific notation.
+ actualRoundingIncrementICU = null;
+ } else {
+ if (getMaximumFractionDigits() > 0) {
+ actualRoundingIncrementICU = BigDecimal.ONE.movePointLeft(getMaximumFractionDigits());
+ } else {
+ actualRoundingIncrementICU = BigDecimal.ONE;
+ }
+ }
+ }
+
+ if (actualRoundingIncrementICU == null) {
+ setRoundingDouble(0.0d);
+ actualRoundingIncrement = null;
+ } else {
+ setRoundingDouble(actualRoundingIncrementICU.doubleValue());
+ actualRoundingIncrement = actualRoundingIncrementICU.toBigDecimal();
+ }
+ }
+
+ static final double roundingIncrementEpsilon = 0.000000001;
+
+ private void setRoundingDouble(double newValue) {
+ roundingDouble = newValue;
+ if (roundingDouble > 0.0d) {
+ double rawRoundedReciprocal = 1.0d / roundingDouble;
+ roundingDoubleReciprocal = Math.rint(rawRoundedReciprocal);
+ if (Math.abs(rawRoundedReciprocal - roundingDoubleReciprocal) > roundingIncrementEpsilon) {
+ roundingDoubleReciprocal = 0.0d;
+ }
+ } else {
+ roundingDoubleReciprocal = 0.0d;
+ }
+ }
+}
+
+// eof
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitList.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitList.java
new file mode 100644
index 000000000..1d80c5b08
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitList.java
@@ -0,0 +1,842 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+/*
+ *******************************************************************************
+ * Copyright (C) 1996-2015, International Business Machines Corporation and *
+ * others. All Rights Reserved. *
+ *******************************************************************************
+ */
+package com.ibm.icu.dev.text;
+
+import java.math.BigInteger;
+
+import com.ibm.icu.text.DecimalFormat;
+import com.ibm.icu.text.NumberFormat;
+
+/**
+ * <code>DigitList</code> handles the transcoding between numeric values and
+ * strings of characters. It only represents non-negative numbers. The
+ * division of labor between <code>DigitList</code> and
+ * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix
+ * 10 representation issues and numeric conversion, including rounding;
+ * <code>DecimalFormat</code> handles the locale-specific issues such as
+ * positive and negative representation, digit grouping, decimal point,
+ * currency, and so on.
+ *
+ * <p>A <code>DigitList</code> is a representation of a finite numeric value.
+ * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite
+ * values. A <code>DigitList</code> value can be converted to a
+ * <code>BigDecimal</code> without loss of precision. Conversion to other
+ * numeric formats may involve loss of precision, depending on the specific
+ * value.
+ *
+ * <p>The <code>DigitList</code> representation consists of a string of
+ * characters, which are the digits radix 10, from '0' to '9'. It also has a
+ * base 10 exponent associated with it. The value represented by a
+ * <code>DigitList</code> object can be computed by mulitplying the fraction
+ * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of
+ * the list to the right of the decimal point, by 10^exponent.
+ *
+ * @see java.util.Locale
+ * @see java.text.Format
+ * @see NumberFormat
+ * @see DecimalFormat
+ * @see java.text.ChoiceFormat
+ * @see java.text.MessageFormat
+ * @version 1.18 08/12/98
+ * @author Mark Davis, Alan Liu
+ * */
+public final class DigitList {
+ /**
+ * The maximum number of significant digits in an IEEE 754 double, that
+ * is, in a Java double. This must not be increased, or garbage digits
+ * will be generated, and should not be decreased, or accuracy will be lost.
+ */
+ public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length()
+ public static final int DBL_DIG = 17;
+
+ /**
+ * These data members are intentionally public and can be set directly.
+ *
+ * The value represented is given by placing the decimal point before
+ * digits[decimalAt]. If decimalAt is < 0, then leading zeros between
+ * the decimal point and the first nonzero digit are implied. If decimalAt
+ * is > count, then trailing zeros between the digits[count-1] and the
+ * decimal point are implied.
+ *
+ * Equivalently, the represented value is given by f * 10^decimalAt. Here
+ * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to
+ * the right of the decimal.
+ *
+ * DigitList is normalized, so if it is non-zero, figits[0] is non-zero. We
+ * don't allow denormalized numbers because our exponent is effectively of
+ * unlimited magnitude. The count value contains the number of significant
+ * digits present in digits[].
+ *
+ * Zero is represented by any DigitList with count == 0 or with each digits[i]
+ * for all i <= count == '0'.
+ */
+ public int decimalAt = 0;
+ public int count = 0;
+ public byte[] digits = new byte[MAX_LONG_DIGITS];
+
+ private final void ensureCapacity(int digitCapacity, int digitsToCopy) {
+ if (digitCapacity > digits.length) {
+ byte[] newDigits = new byte[digitCapacity * 2];
+ System.arraycopy(digits, 0, newDigits, 0, digitsToCopy);
+ digits = newDigits;
+ }
+ }
+
+ /**
+ * Return true if the represented number is zero.
+ */
+ boolean isZero()
+ {
+ for (int i=0; i<count; ++i) if (digits[i] != '0') return false;
+ return true;
+ }
+
+// Unused as of ICU 2.6 - alan
+// /**
+// * Clears out the digits.
+// * Use before appending them.
+// * Typically, you set a series of digits with append, then at the point
+// * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count;
+// * then go on appending digits.
+// */
+// public void clear () {
+// decimalAt = 0;
+// count = 0;
+// }
+
+ /**
+ * Appends digits to the list.
+ */
+ public void append (int digit) {
+ ensureCapacity(count+1, count);
+ digits[count++] = (byte) digit;
+ }
+
+ public byte getDigitValue(int i) {
+ return (byte) (digits[i] - '0');
+ }
+
+ /**
+ * Utility routine to get the value of the digit list
+ * If (count == 0) this throws a NumberFormatException, which
+ * mimics Long.parseLong().
+ */
+ public final double getDouble() {
+ if (count == 0) return 0.0;
+ StringBuilder temp = new StringBuilder(count);
+ temp.append('.');
+ for (int i = 0; i < count; ++i) temp.append((char)(digits[i]));
+ temp.append('E');
+ temp.append(Integer.toString(decimalAt));
+ return Double.valueOf(temp.toString()).doubleValue();
+ // long value = Long.parseLong(temp.toString());
+ // return (value * Math.pow(10, decimalAt - count));
+ }
+
+ /**
+ * Utility routine to get the value of the digit list.
+ * If (count == 0) this returns 0, unlike Long.parseLong().
+ */
+ public final long getLong() {
+ // for now, simple implementation; later, do proper IEEE native stuff
+
+ if (count == 0) return 0;
+
+ // We have to check for this, because this is the one NEGATIVE value
+ // we represent. If we tried to just pass the digits off to parseLong,
+ // we'd get a parse failure.
+ if (isLongMIN_VALUE()) return Long.MIN_VALUE;
+
+ StringBuilder temp = new StringBuilder(count);
+ for (int i = 0; i < decimalAt; ++i)
+ {
+ temp.append((i < count) ? (char)(digits[i]) : '0');
+ }
+ return Long.parseLong(temp.toString());
+ }
+
+ /**
+ * Return a <code>BigInteger</code> representing the value stored in this
+ * <code>DigitList</code>. This method assumes that this object contains
+ * an integral value; if not, it will return an incorrect value.
+ * [bnf]
+ * @param isPositive determines the sign of the returned result
+ * @return the value of this object as a <code>BigInteger</code>
+ */
+ public BigInteger getBigInteger(boolean isPositive) {
+ if (isZero()) return BigInteger.valueOf(0);
+ //Eclipse stated the following is "dead code"
+ /*if (false) {
+ StringBuilder stringRep = new StringBuilder(count);
+ if (!isPositive) {
+ stringRep.append('-');
+ }
+ for (int i=0; i<count; ++i) {
+ stringRep.append((char) digits[i]);
+ }
+ int d = decimalAt;
+ while (d-- > count) {
+ stringRep.append('0');
+ }
+ return new BigInteger(stringRep.toString());
+ } else*/ {
+ int len = decimalAt > count ? decimalAt : count;
+ if (!isPositive) {
+ len += 1;
+ }
+ char[] text = new char[len];
+ int n = 0;
+ if (!isPositive) {
+ text[0] = '-';
+ for (int i = 0; i < count; ++i) {
+ text[i+1] = (char)digits[i];
+ }
+ n = count+1;
+ } else {
+ for (int i = 0; i < count; ++i) {
+ text[i] = (char)digits[i];
+ }
+ n = count;
+ }
+ for (int i = n; i < text.length; ++i) {
+ text[i] = '0';
+ }
+ return new BigInteger(new String(text));
+ }
+ }
+
+ private String getStringRep(boolean isPositive) {
+ if (isZero()) return "0";
+ StringBuilder stringRep = new StringBuilder(count+1);
+ if (!isPositive) {
+ stringRep.append('-');
+ }
+ int d = decimalAt;
+ if (d < 0) {
+ stringRep.append('.');
+ while (d < 0) {
+ stringRep.append('0');
+ ++d;
+ }
+ d = -1;
+ }
+ for (int i=0; i<count; ++i) {
+ if (d == i) {
+ stringRep.append('.');
+ }
+ stringRep.append((char) digits[i]);
+ }
+ while (d-- > count) {
+ stringRep.append('0');
+ }
+ return stringRep.toString();
+ }
+
+ /**
+ * Return an <code>ICU BigDecimal</code> representing the value stored in this
+ * <code>DigitList</code>.
+ * [bnf]
+ * @param isPositive determines the sign of the returned result
+ * @return the value of this object as a <code>BigDecimal</code>
+ */
+ public com.ibm.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) {
+ if (isZero()) {
+ return com.ibm.icu.math.BigDecimal.valueOf(0);
+ }
+ // if exponential notion is negative,
+ // we prefer to use BigDecimal constructor with scale,
+ // because it works better when extremely small value
+ // is used. See #5698.
+ long scale = (long)count - (long)decimalAt;
+ if (scale > 0) {
+ int numDigits = count;
+ if (scale > Integer.MAX_VALUE) {
+ // try to reduce the scale
+ long numShift = scale - Integer.MAX_VALUE;
+ if (numShift < count) {
+ numDigits -= numShift;
+ } else {
+ // fallback to 0
+ return new com.ibm.icu.math.BigDecimal(0);
+ }
+ }
+ StringBuilder significantDigits = new StringBuilder(numDigits + 1);
+ if (!isPositive) {
+ significantDigits.append('-');
+ }
+ for (int i = 0; i < numDigits; i++) {
+ significantDigits.append((char)digits[i]);
+ }
+ BigInteger unscaledVal = new BigInteger(significantDigits.toString());
+ return new com.ibm.icu.math.BigDecimal(unscaledVal, (int)scale);
+ } else {
+ return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive));
+ }
+ }
+
+ /**
+ * Return whether or not this objects represented value is an integer.
+ * [bnf]
+ * @return true if the represented value of this object is an integer
+ */
+ boolean isIntegral() {
+ // Trim trailing zeros. This does not change the represented value.
+ while (count > 0 && digits[count - 1] == (byte)'0') --count;
+ return count == 0 || decimalAt >= count;
+ }
+
+// Unused as of ICU 2.6 - alan
+// /**
+// * Return true if the number represented by this object can fit into
+// * a long.
+// */
+// boolean fitsIntoLong(boolean isPositive)
+// {
+// // Figure out if the result will fit in a long. We have to
+// // first look for nonzero digits after the decimal point;
+// // then check the size. If the digit count is 18 or less, then
+// // the value can definitely be represented as a long. If it is 19
+// // then it may be too large.
+//
+// // Trim trailing zeros. This does not change the represented value.
+// while (count > 0 && digits[count - 1] == (byte)'0') --count;
+//
+// if (count == 0) {
+// // Positive zero fits into a long, but negative zero can only
+// // be represented as a double. - bug 4162852
+// return isPositive;
+// }
+//
+// if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false;
+//
+// if (decimalAt < MAX_LONG_DIGITS) return true;
+//
+// // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS.
+// // The number will overflow if it is larger than 9223372036854775807
+// // or smaller than -9223372036854775808.
+// for (int i=0; i<count; ++i)
+// {
+// byte dig = digits[i], max = LONG_MIN_REP[i];
+// if (dig > max) return false;
+// if (dig < max) return true;
+// }
+//
+// // At this point the first count digits match. If decimalAt is less
+// // than count, then the remaining digits are zero, and we return true.
+// if (count < decimalAt) return true;
+//
+// // Now we have a representation of Long.MIN_VALUE, without the leading
+// // negative sign. If this represents a positive value, then it does
+// // not fit; otherwise it fits.
+// return !isPositive;
+// }
+
+// Unused as of ICU 2.6 - alan
+// /**
+// * Set the digit list to a representation of the given double value.
+// * This method supports fixed-point notation.
+// * @param source Value to be converted; must not be Inf, -Inf, Nan,
+// * or a value <= 0.
+// * @param maximumFractionDigits The most fractional digits which should
+// * be converted.
+// */
+// public final void set(double source, int maximumFractionDigits)
+// {
+// set(source, maximumFractionDigits, true);
+// }
+
+ /**
+ * Set the digit list to a representation of the given double value.
+ * This method supports both fixed-point and exponential notation.
+ * @param source Value to be converted; must not be Inf, -Inf, Nan,
+ * or a value <= 0.
+ * @param maximumDigits The most fractional or total digits which should
+ * be converted.
+ * @param fixedPoint If true, then maximumDigits is the maximum
+ * fractional digits to be converted. If false, total digits.
+ */
+ final void set(double source, int maximumDigits, boolean fixedPoint)
+ {
+ if (source == 0) source = 0;
+ // Generate a representation of the form DDDDD, DDDDD.DDDDD, or
+ // DDDDDE+/-DDDDD.
+ String rep = Double.toString(source);
+
+ didRound = false;
+
+ set(rep, MAX_LONG_DIGITS);
+
+ if (fixedPoint) {
+ // The negative of the exponent represents the number of leading
+ // zeros between the decimal and the first non-zero digit, for
+ // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this
+ // is more than the maximum fraction digits, then we have an underflow
+ // for the printed representation.
+ if (-decimalAt > maximumDigits) {
+ count = 0;
+ return;
+ } else if (-decimalAt == maximumDigits) {
+ if (shouldRoundUp(0)) {
+ count = 1;
+ ++decimalAt;
+ digits[0] = (byte)'1';
+ } else {
+ count = 0;
+ }
+ return;
+ }
+ // else fall through
+ }
+
+ // Eliminate trailing zeros.
+ while (count > 1 && digits[count - 1] == '0')
+ --count;
+
+ // Eliminate digits beyond maximum digits to be displayed.
+ // Round up if appropriate.
+ round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
+ }
+
+ /**
+ * Given a string representation of the form DDDDD, DDDDD.DDDDD,
+ * or DDDDDE+/-DDDDD, set this object's value to it. Ignore
+ * any leading '-'.
+ */
+ private void set(String rep, int maxCount) {
+ decimalAt = -1;
+ count = 0;
+ int exponent = 0;
+ // Number of zeros between decimal point and first non-zero digit after
+ // decimal point, for numbers < 1.
+ int leadingZerosAfterDecimal = 0;
+ boolean nonZeroDigitSeen = false;
+ // Skip over leading '-'
+ int i=0;
+ if (rep.charAt(i) == '-') {
+ ++i;
+ }
+ for (; i < rep.length(); ++i) {
+ char c = rep.charAt(i);
+ if (c == '.') {
+ decimalAt = count;
+ } else if (c == 'e' || c == 'E') {
+ ++i;
+ // Integer.parseInt doesn't handle leading '+' signs
+ if (rep.charAt(i) == '+') {
+ ++i;
+ }
+ exponent = Integer.valueOf(rep.substring(i)).intValue();
+ break;
+ } else if (count < maxCount) {
+ if (!nonZeroDigitSeen) {
+ nonZeroDigitSeen = (c != '0');
+ if (!nonZeroDigitSeen && decimalAt != -1) {
+ ++leadingZerosAfterDecimal;
+ }
+ }
+
+ if (nonZeroDigitSeen) {
+ ensureCapacity(count+1, count);
+ digits[count++] = (byte)c;
+ }
+ }
+ }
+ if (decimalAt == -1) {
+ decimalAt = count;
+ }
+ decimalAt += exponent - leadingZerosAfterDecimal;
+ }
+
+ /**
+ * Return true if truncating the representation to the given number
+ * of digits will result in an increment to the last digit. This
+ * method implements half-even rounding, the default rounding mode.
+ * [bnf]
+ * @param maximumDigits the number of digits to keep, from 0 to
+ * <code>count-1</code>. If 0, then all digits are rounded away, and
+ * this method returns true if a one should be generated (e.g., formatting
+ * 0.09 with "#.#").
+ * @return true if digit <code>maximumDigits-1</code> should be
+ * incremented
+ */
+ private boolean shouldRoundUp(int maximumDigits) {
+ // variable not used boolean increment = false;
+ // Implement IEEE half-even rounding
+ /*Bug 4243108
+ format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL]
+ */
+ if (maximumDigits < count) {
+ if (digits[maximumDigits] > '5') {
+ return true;
+ } else if (digits[maximumDigits] == '5' ) {
+ for (int i=maximumDigits+1; i<count; ++i) {
+ if (digits[i] != '0') {
+ return true;
+ }
+ }
+ return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Round the representation to the given number of digits.
+ * @param maximumDigits The maximum number of digits to be shown.
+ * Upon return, count will be less than or equal to maximumDigits.
+ * This now performs rounding when maximumDigits is 0, formerly it did not.
+ */
+ public final void round(int maximumDigits) {
+ // Eliminate digits beyond maximum digits to be displayed.
+ // Round up if appropriate.
+ // [bnf] rewritten to fix 4179818
+ if (maximumDigits >= 0 && maximumDigits < count) {
+ if (shouldRoundUp(maximumDigits)) {
+ // Rounding up involves incrementing digits from LSD to MSD.
+ // In most cases this is simple, but in a worst case situation
+ // (9999..99) we have to adjust the decimalAt value.
+ for (;;)
+ {
+ --maximumDigits;
+ if (maximumDigits < 0)
+ {
+ // We have all 9's, so we increment to a single digit
+ // of one and adjust the exponent.
+ digits[0] = (byte) '1';
+ ++decimalAt;
+ maximumDigits = 0; // Adjust the count
+ didRound = true;
+ break;
+ }
+
+ ++digits[maximumDigits];
+ didRound = true;
+ if (digits[maximumDigits] <= '9') break;
+ // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
+ }
+ ++maximumDigits; // Increment for use as count
+ }
+ count = maximumDigits;
+ }
+ // Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1"
+ // Eliminate trailing zeros. [Richard/GCL]
+ // [dlf] moved outside if block, see ticket #6408
+ while (count > 1 && digits[count-1] == '0') {
+ --count;
+ }
+ }
+
+ // Value to indicate that rounding was done.
+ private boolean didRound = false;
+
+ /**
+ * Indicates if last digit set was rounded or not.
+ * true indicates it was rounded.
+ * false indicates rounding has not been done.
+ */
+ public boolean wasRounded() {
+ return didRound;
+ }
+
+ /**
+ * Utility routine to set the value of the digit list from a long
+ */
+ public final void set(long source)
+ {
+ set(source, 0);
+ }
+
+ /**
+ * Set the digit list to a representation of the given long value.
+ * @param source Value to be converted; must be >= 0 or ==
+ * Long.MIN_VALUE.
+ * @param maximumDigits The most digits which should be converted.
+ * If maximumDigits is lower than the number of significant digits
+ * in source, the representation will be rounded. Ignored if <= 0.
+ */
+ public final void set(long source, int maximumDigits)
+ {
+ // This method does not expect a negative number. However,
+ // "source" can be a Long.MIN_VALUE (-9223372036854775808),
+ // if the number being formatted is a Long.MIN_VALUE. In that
+ // case, it will be formatted as -Long.MIN_VALUE, a number
+ // which is outside the legal range of a long, but which can
+ // be represented by DigitList.
+ // [NEW] Faster implementation
+ didRound = false;
+
+ if (source <= 0) {
+ if (source == Long.MIN_VALUE) {
+ decimalAt = count = MAX_LONG_DIGITS;
+ System.arraycopy(LONG_MIN_REP, 0, digits, 0, count);
+ } else {
+ count = 0;
+ decimalAt = 0;
+ }
+ } else {
+ int left = MAX_LONG_DIGITS;
+ int right;
+ while (source > 0) {
+ digits[--left] = (byte) (('0') + (source % 10));
+ source /= 10;
+ }
+ decimalAt = MAX_LONG_DIGITS-left;
+ // Don't copy trailing zeros
+ // we are guaranteed that there is at least one non-zero digit,
+ // so we don't have to check lower bounds
+ for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {}
+ count = right - left + 1;
+ System.arraycopy(digits, left, digits, 0, count);
+ }
+ if (maximumDigits > 0) round(maximumDigits);
+ }
+
+ /**
+ * Set the digit list to a representation of the given BigInteger value.
+ * [bnf]
+ * @param source Value to be converted
+ * @param maximumDigits The most digits which should be converted.
+ * If maximumDigits is lower than the number of significant digits
+ * in source, the representation will be rounded. Ignored if <= 0.
+ */
+ public final void set(BigInteger source, int maximumDigits) {
+ String stringDigits = source.toString();
+
+ count = decimalAt = stringDigits.length();
+ didRound = false;
+
+ // Don't copy trailing zeros
+ while (count > 1 && stringDigits.charAt(count - 1) == '0') --count;
+
+ int offset = 0;
+ if (stringDigits.charAt(0) == '-') {
+ ++offset;
+ --count;
+ --decimalAt;
+ }
+
+ ensureCapacity(count, 0);
+ for (int i = 0; i < count; ++i) {
+ digits[i] = (byte) stringDigits.charAt(i + offset);
+ }
+
+ if (maximumDigits > 0) round(maximumDigits);
+ }
+
+ /**
+ * Internal method that sets this digit list to represent the
+ * given value. The value is given as a String of the format
+ * returned by BigDecimal.
+ * @param stringDigits value to be represented with the following
+ * syntax, expressed as a regular expression: -?\d*.?\d*
+ * Must not be an empty string.
+ * @param maximumDigits The most digits which should be converted.
+ * If maximumDigits is lower than the number of significant digits
+ * in source, the representation will be rounded. Ignored if <= 0.
+ * @param fixedPoint If true, then maximumDigits is the maximum
+ * fractional digits to be converted. If false, total digits.
+ */
+ private void setBigDecimalDigits(String stringDigits,
+ int maximumDigits, boolean fixedPoint) {
+//| // Find the first non-zero digit, the decimal, and the last non-zero digit.
+//| int first=-1, last=stringDigits.length()-1, decimal=-1;
+//| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) {
+//| char c = stringDigits.charAt(i);
+//| if (c == '.') {
+//| decimal = i;
+//| } else if (first < 0 && (c >= '1' && c <= '9')) {
+//| first = i;
+//| }
+//| }
+//|
+//| if (first < 0) {
+//| clear();
+//| return;
+//| }
+//|
+//| // At this point we know there is at least one non-zero digit, so the
+//| // following loop is safe.
+//| for (;;) {
+//| char c = stringDigits.charAt(last);
+//| if (c != '0' && c != '.') {
+//| break;
+//| }
+//| --last;
+//| }
+//|
+//| if (decimal < 0) {
+//| decimal = stringDigits.length();
+//| }
+//|
+//| count = last - first;
+//| if (decimal < first || decimal > last) {
+//| ++count;
+//| }
+//| decimalAt = decimal - first;
+//| if (decimalAt < 0) {
+//| ++decimalAt;
+//| }
+//|
+//| ensureCapacity(count, 0);
+//| for (int i = 0; i < count; ++i) {
+//| digits[i] = (byte) stringDigits.charAt(first++);
+//| if (first == decimal) {
+//| ++first;
+//| }
+//| }
+
+ didRound = false;
+
+ // The maxDigits here could also be Integer.MAX_VALUE
+ set(stringDigits, stringDigits.length());
+
+ // Eliminate digits beyond maximum digits to be displayed.
+ // Round up if appropriate.
+ // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but
+ // rather than pass that information explicitly, we rely on some magic with maximumDigits
+ // and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits
+ // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round
+ // changed to perform rounding when the argument is 0, we now force the argument
+ // to -1 in the situations where it matters.
+ round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
+ }
+
+ /**
+ * Set the digit list to a representation of the given BigDecimal value.
+ * [bnf]
+ * @param source Value to be converted
+ * @param maximumDigits The most digits which should be converted.
+ * If maximumDigits is lower than the number of significant digits
+ * in source, the representation will be rounded. Ignored if <= 0.
+ * @param fixedPoint If true, then maximumDigits is the maximum
+ * fractional digits to be converted. If false, total digits.
+ */
+ public final void set(java.math.BigDecimal source,
+ int maximumDigits, boolean fixedPoint) {
+ setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
+ }
+
+ /*
+ * Set the digit list to a representation of the given BigDecimal value.
+ * [bnf]
+ * @param source Value to be converted
+ * @param maximumDigits The most digits which should be converted.
+ * If maximumDigits is lower than the number of significant digits
+ * in source, the representation will be rounded. Ignored if <= 0.
+ * @param fixedPoint If true, then maximumDigits is the maximum
+ * fractional digits to be converted. If false, total digits.
+ */
+ public final void set(com.ibm.icu.math.BigDecimal source,
+ int maximumDigits, boolean fixedPoint) {
+ setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
+ }
+
+ /**
+ * Returns true if this DigitList represents Long.MIN_VALUE;
+ * false, otherwise. This is required so that getLong() works.
+ */
+ private boolean isLongMIN_VALUE()
+ {
+ if (decimalAt != count || count != MAX_LONG_DIGITS)
+ return false;
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (digits[i] != LONG_MIN_REP[i]) return false;
+ }
+
+ return true;
+ }
+
+ private static byte[] LONG_MIN_REP;
+
+ static
+ {
+ // Store the representation of LONG_MIN without the leading '-'
+ String s = Long.toString(Long.MIN_VALUE);
+ LONG_MIN_REP = new byte[MAX_LONG_DIGITS];
+ for (int i=0; i < MAX_LONG_DIGITS; ++i)
+ {
+ LONG_MIN_REP[i] = (byte)s.charAt(i + 1);
+ }
+ }
+
+// Unused -- Alan 2003-05
+// /**
+// * Return the floor of the log base 10 of a given double.
+// * This method compensates for inaccuracies which arise naturally when
+// * computing logs, and always give the correct value. The parameter
+// * must be positive and finite.
+// */
+// private static final int log10(double d)
+// {
+// // The reason this routine is needed is that simply taking the
+// // log and dividing by log10 yields a result which may be off
+// // by 1 due to rounding errors. For example, the naive log10
+// // of 1.0e300 taken this way is 299, rather than 300.
+// double log10 = Math.log(d) / LOG10;
+// int ilog10 = (int)Math.floor(log10);
+// // Positive logs could be too small, e.g. 0.99 instead of 1.0
+// if (log10 > 0 && d >= Math.pow(10, ilog10 + 1))
+// {
+// ++ilog10;
+// }
+// // Negative logs could be too big, e.g. -0.99 instead of -1.0
+// else if (log10 < 0 && d < Math.pow(10, ilog10))
+// {
+// --ilog10;
+// }
+// return ilog10;
+// }
+//
+// private static final double LOG10 = Math.log(10.0);
+
+ /**
+ * equality test between two digit lists.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) // quick check
+ return true;
+ if (!(obj instanceof DigitList)) // (1) same object?
+ return false;
+ DigitList other = (DigitList) obj;
+ if (count != other.count ||
+ decimalAt != other.decimalAt)
+ return false;
+ for (int i = 0; i < count; i++)
+ if (digits[i] != other.digits[i])
+ return false;
+ return true;
+ }
+
+ /**
+ * Generates the hash code for the digit list.
+ */
+ @Override
+ public int hashCode() {
+ int hashcode = decimalAt;
+
+ for (int i = 0; i < count; i++)
+ hashcode = hashcode * 37 + digits[i];
+
+ return hashcode;
+ }
+
+ @Override
+ public String toString()
+ {
+ if (isZero()) return "0";
+ StringBuilder buf = new StringBuilder("0.");
+ for (int i=0; i<count; ++i) buf.append((char)digits[i]);
+ buf.append("x10^");
+ buf.append(decimalAt);
+ return buf.toString();
+ }
+}
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitListTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitListTest.java
new file mode 100644
index 000000000..ac2153065
--- /dev/null
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/text/DigitListTest.java
@@ -0,0 +1,47 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+
+package com.ibm.icu.dev.text;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.ibm.icu.dev.test.TestFmwk;
+
+
+@RunWith(JUnit4.class)
+public class DigitListTest extends TestFmwk {
+
+ private static DigitList digitList = new DigitList();
+ private static long testdata = 1414213562;
+
+ @Before
+ public void init() {
+ digitList.set(testdata);
+ }
+
+ @Test
+ public void TestToString() {
+ String digitListStr = digitList.toString();
+ assertEquals("DigitList incorrect", "0.1414213562x10^10", digitListStr);
+ }
+ @Test
+ public void TestHashCode() {
+ int dlHashcode = digitList.hashCode();
+ assertEquals("DigitList hash code incorrect", -616183837, dlHashcode);
+ }
+
+ @Test
+ public void TestEquals() {
+ DigitList digitList2 = new DigitList();
+
+ // Test for success
+ digitList2.set(testdata);
+ assertTrue("DigitList objects with same values found unequal", digitList.equals(digitList2));
+ // Test for failure
+ digitList2.set(testdata+1);
+ assertFalse("DigitList objects with different values found equal", digitList.equals(digitList2));
+ }
+}