language: move to CLDR test format

This helps exchanging test files between
platforms.

Change-Id: I1ed8e2a9d99d85afdeb0e8bd76cb1d6354cbbd67
Reviewed-on: https://go-review.googlesource.com/55391
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/language/data_test.go b/language/data_test.go
deleted file mode 100644
index e1b9606..0000000
--- a/language/data_test.go
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package language
-
-import (
-	"flag"
-	"fmt"
-	"os"
-	"testing"
-)
-
-var outfile = flag.String("genucd", "", "generate UCD file from test data")
-
-func TestGenerate(t *testing.T) {
-	if *outfile == "" {
-		return
-	}
-
-	w, err := os.Create(*outfile)
-	if err != nil {
-		t.Error(err)
-	}
-	defer w.Close()
-
-	for _, tc := range matchTests {
-		fmt.Fprintln(w, "# "+tc.comment)
-		for _, t := range tc.test {
-			fmt.Fprintf(w, "%s ; 	%s ; 	%s\n", tc.supported, t.desired, t.match)
-		}
-		fmt.Fprintln(w)
-	}
-}
-
-type matchTest struct {
-	comment   string
-	supported string
-	test      []struct{ match, desired string }
-}
-
-var matchTests = []matchTest{
-	{
-		"basics",
-		"fr, en-GB, en",
-		[]struct{ match, desired string }{
-			{"en-GB", "en-GB"},
-			{"en", "en-US"},
-			{"fr", "fr-FR"},
-			{"fr", "ja-JP"},
-		},
-	},
-	{
-		"script fallbacks",
-		"zh-CN, zh-TW, iw",
-		[]struct{ match, desired string }{
-			{"zh-TW", "zh-Hant"},
-			{"zh-CN", "zh"},
-			{"zh-CN", "zh-Hans-CN"},
-			{"zh-TW", "zh-Hant-HK"},
-			{"iw", "he-IT"},
-		},
-	},
-	{
-		"language-specific script fallbacks 1",
-		"en, sr, nl",
-		[]struct{ match, desired string }{
-			{"sr", "sr-Latn"},
-			{"en", "sh"},
-			{"en", "hr"},
-			{"en", "bs"},
-			// TODO: consider if the following match is a good one.
-			// Due to new script first rule, which maybe should be an option.
-			{"sr", "nl-Cyrl"},
-		},
-	},
-	{
-		"language-specific script fallbacks 2",
-		"en, sh",
-		[]struct{ match, desired string }{
-			{"sh", "sr"},
-			{"sh", "sr-Cyrl"},
-			{"sh", "hr"},
-		},
-	},
-	{
-		"don't match hr to sr-Latn",
-		"en, sr-Latn",
-		[]struct{ match, desired string }{
-			{"en", "hr"},
-		},
-	},
-	{
-		"both deprecated and not",
-		"fil, tl, iw, he",
-		[]struct{ match, desired string }{
-			{"he", "he-IT"},
-			{"he", "he"},
-			{"iw", "iw"},
-			{"fil", "fil-IT"},
-			{"fil", "fil"},
-			{"tl", "tl"},
-		},
-	},
-	{
-		"nearby languages",
-		"en, fil, ro, nn",
-		[]struct{ match, desired string }{
-			{"fil", "tl"},
-			{"ro", "mo"},
-			{"nn", "nb"},
-			{"en", "ja"}, // make sure default works
-		},
-	},
-	{
-		"nearby languages: Nynorsk to Bokmål",
-		"en, nb",
-		[]struct{ match, desired string }{
-			{"nb", "nn"},
-		},
-	},
-	{
-		"nearby languages: Danish does not match nn",
-		"en, nn",
-		[]struct{ match, desired string }{
-			{"en", "da"},
-		},
-	},
-	{
-		"nearby languages: Danish matches no",
-		"en, no",
-		[]struct{ match, desired string }{
-			{"no", "da"},
-		},
-	},
-	{
-		"nearby languages: Danish matches nb",
-		"en, nb",
-		[]struct{ match, desired string }{
-			{"nb", "da"},
-		},
-	},
-	{
-		"prefer matching languages over language variants.",
-		"nn, en-GB",
-		[]struct{ match, desired string }{
-			{"en-GB", "no, en-US"},
-			{"en-GB", "nb, en-US"},
-		},
-	},
-	{
-		"deprecated version is closer than same language with other differences",
-		"nl, he, en-GB",
-		[]struct{ match, desired string }{
-			{"he", "iw, en-US"},
-		},
-	},
-	{
-		"macro equivalent is closer than same language with other differences",
-		"nl, zh, en-GB, no",
-		[]struct{ match, desired string }{
-			{"zh", "cmn, en-US"},
-			{"no", "nb, en-US"},
-		},
-	},
-	{
-		"legacy equivalent is closer than same language with other differences",
-		"nl, fil, en-GB",
-		[]struct{ match, desired string }{
-			{"fil", "tl, en-US"},
-		},
-	},
-	{
-		"exact over equivalent",
-		"en, ro, mo, ro-MD",
-		[]struct{ match, desired string }{
-			{"ro", "ro"},
-			{"mo", "mo"},
-			{"ro-MD", "ro-MD"},
-		},
-	},
-	{
-		"maximization of legacy",
-		"sr-Cyrl, sr-Latn, ro, ro-MD",
-		[]struct{ match, desired string }{
-			{"sr-Latn", "sh"},
-			{"ro-MD", "mo"},
-		},
-	},
-	{
-		"empty",
-		"",
-		[]struct{ match, desired string }{
-			{"und", "fr"},
-			{"und", "en"},
-		},
-	},
-	{
-		"private use subtags",
-		"fr, en-GB, x-bork, es-ES, es-419",
-		[]struct{ match, desired string }{
-			{"fr", "x-piglatin"},
-			{"x-bork", "x-bork"},
-		},
-	},
-	{
-		"grandfathered codes",
-		"fr, i-klingon, en-Latn-US",
-		[]struct{ match, desired string }{
-			{"en-Latn-US", "en-GB-oed"},
-			{"tlh", "i-klingon"},
-		},
-	},
-	{
-		"exact match",
-		"fr, en-GB, ja, es-ES, es-MX",
-		[]struct{ match, desired string }{
-			{"ja", "ja, de"},
-		},
-	},
-	{
-		"simple variant match",
-		"fr, en-GB, ja, es-ES, es-MX",
-		[]struct{ match, desired string }{
-			// Intentionally avoiding a perfect-match or two candidates for variant matches.
-			{"en-GB", "de, en-US"},
-			// Fall back.
-			{"fr", "de, zh"},
-		},
-	},
-	{
-		"best match for traditional Chinese",
-		// 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.
-		"fr, zh-Hans-CN, en-US",
-		[]struct{ match, desired string }{
-			{"zh-Hans-CN", "zh-TW"},
-			{"zh-Hans-CN", "zh-Hant"},
-			// One can avoid a zh-Hant to zh-Hans match by including a second language
-			// preference which is a better match.
-			{"en-US", "zh-TW, en"},
-			{"en-US", "zh-Hant-CN, en"},
-			{"zh-Hans-CN", "zh-Hans, en"},
-		},
-	},
-	// More specific region and script tie-breakers.
-	{
-		"more specific script should win in case regions are identical",
-		"af, af-Latn, af-Arab",
-		[]struct{ match, desired string }{
-			{"af", "af"},
-			{"af", "af-ZA"},
-			{"af-Latn", "af-Latn-ZA"},
-			{"af-Latn", "af-Latn"},
-		},
-	},
-	{
-		"more specific region should win",
-		"nl, nl-NL, nl-BE",
-		[]struct{ match, desired string }{
-			{"nl", "nl"},
-			{"nl", "nl-Latn"},
-			{"nl-NL", "nl-Latn-NL"},
-			{"nl-NL", "nl-NL"},
-		},
-	},
-	{
-		"region may replace matched if matched is enclosing",
-		"es-419,es",
-		[]struct{ match, desired string }{
-			{"es-MX", "es-MX"},
-			{"es", "es-SG"},
-		},
-	},
-	{
-		"more specific region wins over more specific script",
-		"nl, nl-Latn, nl-NL, nl-BE",
-		[]struct{ match, desired string }{
-			{"nl", "nl"},
-			{"nl-Latn", "nl-Latn"},
-			{"nl-NL", "nl-NL"},
-			{"nl-NL", "nl-Latn-NL"},
-		},
-	},
-	// Region distance tie-breakers.
-	{
-		"region distance Portuguese",
-		"pt, pt-PT",
-		[]struct{ match, desired string }{
-			{"pt-PT", "pt-ES"},
-		},
-	},
-	{
-		"region distance French",
-		"en, fr, fr-CA, fr-CH",
-		[]struct{ match, desired string }{
-			{"fr-CA", "fr-US"},
-		},
-	},
-	{
-		"region distance German",
-		"de-AT, de-DE, de-CH",
-		[]struct{ match, desired string }{
-			{"de-DE", "de"},
-		},
-	},
-	{
-		"en-AU is closer to en-GB than to en (which is en-US)",
-		"en, en-GB, es-ES, es-419",
-		[]struct{ match, desired string }{
-			{"en-GB", "en-AU"},
-			{"es-MX", "es-MX"},
-			{"es-ES", "es-PT"},
-		},
-	},
-	// Test exceptions with "und".
-	// When the undefined language doesn't match anything in the list, return the default, as usual.
-	// 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.
-	// Matching "und" to "it,en" would be "en" matching "en" to "it,und" would be "und".
-	// To avoid this max("und") is defined as "und"
-	{
-		"undefined",
-		"it, fr",
-		[]struct{ match, desired string }{
-			{"it", "und"},
-		},
-	},
-	{
-		"und does not match en",
-		"it, en",
-		[]struct{ match, desired string }{
-			{"it", "und"},
-		},
-	},
-	{
-		"undefined in priority list",
-		"it, und",
-		[]struct{ match, desired string }{
-			{"und", "und"},
-			{"it", "en"},
-		},
-	},
-	// Undefined scripts and regions.
-	{
-		"undefined",
-		"it, fr, zh",
-		[]struct{ match, desired string }{
-			{"fr", "und-FR"},
-			{"zh", "und-CN"},
-			{"zh", "und-Hans"},
-			{"zh", "und-Hant"},
-			{"it", "und-Latn"},
-		},
-	},
-	// Early termination conditions: do not consider all desired strings if
-	// a match is good enough.
-	{
-		"match on maximized tag",
-		"fr, en-GB, ja, es-ES, es-MX",
-		[]struct{ match, desired string }{
-			// ja-JP matches ja on likely subtags, and it's listed first,
-			// thus it wins over the second preference en-GB.
-			{"ja", "ja-JP, en-GB"},
-			{"ja", "ja-Jpan-JP, en-GB"},
-		},
-	},
-	{
-		"pick best maximized tag",
-		"ja, ja-Jpan-US, ja-JP, en, ru",
-		[]struct{ match, desired string }{
-			{"ja", "ja-Jpan, ru"},
-			{"ja-JP", "ja-JP, ru"},
-			{"ja-Jpan-US", "ja-US, ru"},
-		},
-	},
-	{
-		"termination: pick best maximized match",
-		"ja, ja-Jpan, ja-JP, en, ru",
-		[]struct{ match, desired string }{
-			{"ja-JP", "ja-Jpan-JP, ru"},
-			{"ja-Jpan", "ja-Jpan, ru"},
-		},
-	},
-	{
-		"no match on maximized",
-		"en, de, fr, ja",
-		[]struct{ match, desired string }{
-			// de maximizes to de-DE.
-			// Pick the exact match for the secondary language instead.
-			{"fr", "de-CH, fr"},
-		},
-	},
-
-	// Test that the CLDR parent relations are correctly preserved by the matcher.
-	// These matches may change for different CLDR versions.
-	{
-		"parent relation preserved",
-		"en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK",
-		[]struct{ match, desired string }{
-			{"en-GB", "en-150"},
-			// {"en-GB", "en-001"}, // TODO: currently en, should probably be en-GB
-			{"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", "en-MT"},
-			{"es-AR", "es-AR"},
-			{"es-BO", "es-BO"},
-			{"es-CL", "es-CL"},
-			{"es-CO", "es-CO"},
-			{"es-CR", "es-CR"},
-			{"es-CU", "es-CU"},
-			{"es-DO", "es-DO"},
-			{"es-EC", "es-EC"},
-			{"es-GT", "es-GT"},
-			{"es-HN", "es-HN"},
-			{"es-MX", "es-MX"},
-			{"es-NI", "es-NI"},
-			{"es-PA", "es-PA"},
-			{"es-PE", "es-PE"},
-			{"es-PR", "es-PR"},
-			{"es", "es-PT"},
-			{"es-PY", "es-PY"},
-			{"es-SV", "es-SV"},
-			{"es-419", "es-US"}, // US is not in Latin America, so don't make more specific.
-			{"es-UY", "es-UY"},
-			{"es-VE", "es-VE"},
-			{"pt-PT", "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"},
-		},
-	},
-	// Options and variants are inherited from user-defined settings.
-	{
-		"preserve Unicode extension",
-		"en, de, sl-nedis",
-		[]struct{ match, desired string }{
-			{"de-u-co-phonebk", "de-FR-u-co-phonebk"},
-			{"sl-nedis-u-cu-eur", "sl-nedis-u-cu-eur"},
-			{"sl-nedis-u-cu-eur", "sl-u-cu-eur"},
-			{"sl-nedis-u-cu-eur", "sl-HR-nedis-u-cu-eur"},
-		},
-	},
-}
diff --git a/language/match_test.go b/language/match_test.go
index 4fb56a0..ae9a2f6 100644
--- a/language/match_test.go
+++ b/language/match_test.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"os"
 	"path"
+	"path/filepath"
 	"strings"
 	"testing"
 
@@ -19,31 +20,37 @@
 
 var verbose = flag.Bool("verbose", false, "set to true to print the internal tables of matchers")
 
-func TestCLDRCompliance(t *testing.T) {
-	r, err := os.Open("testdata/localeMatcherTest.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-	ucd.Parse(r, func(p *ucd.Parser) {
-		name := strings.Replace(path.Join(p.String(0), p.String(1)), " ", "", -1)
-		if skip[name] {
-			return
+func TestCompliance(t *testing.T) {
+	filepath.Walk("testdata", func(file string, info os.FileInfo, err error) error {
+		if info.IsDir() {
+			return nil
 		}
-		t.Run(name, func(t *testing.T) {
-			supported := makeTagList(p.String(0))
-			desired := makeTagList(p.String(1))
-			gotCombined, index, _ := NewMatcher(supported).Match(desired...)
+		r, err := os.Open(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+		ucd.Parse(r, func(p *ucd.Parser) {
+			name := strings.Replace(path.Join(p.String(0), p.String(1)), " ", "", -1)
+			if skip[name] {
+				return
+			}
+			t.Run(info.Name()+"/"+name, func(t *testing.T) {
+				supported := makeTagList(p.String(0))
+				desired := makeTagList(p.String(1))
+				gotCombined, index, _ := NewMatcher(supported).Match(desired...)
 
-			gotMatch := supported[index]
-			wantMatch := Make(p.String(2))
-			if gotMatch != wantMatch {
-				t.Fatalf("match: got %q; want %q", gotMatch, wantMatch)
-			}
-			wantCombined, err := Parse(p.String(3))
-			if err == nil && gotCombined != wantCombined {
-				t.Errorf("combined: got %q; want %q", gotCombined, wantCombined)
-			}
+				gotMatch := supported[index]
+				wantMatch := mk(p.String(2))
+				if gotMatch != wantMatch {
+					t.Fatalf("match: got %q; want %q", gotMatch, wantMatch)
+				}
+				wantCombined, err := Raw.Parse(p.String(3))
+				if err == nil && gotCombined != wantCombined {
+					t.Errorf("combined: got %q; want %q", gotCombined, wantCombined)
+				}
+			})
 		})
+		return nil
 	})
 }
 
@@ -106,7 +113,7 @@
 
 func makeTagList(s string) (tags []Tag) {
 	for _, s := range strings.Split(s, ",") {
-		tags = append(tags, Make(strings.TrimSpace(s)))
+		tags = append(tags, mk(strings.TrimSpace(s)))
 	}
 	return tags
 }
@@ -370,35 +377,8 @@
 	return fmt.Sprintf("%v:%d:%v:%v-%v|%v", t.tag, t.index, t.conf, t.maxRegion, t.maxScript, t.altScript)
 }
 
-func parseSupported(list string) (out []Tag) {
-	for _, s := range strings.Split(list, ",") {
-		out = append(out, mk(strings.TrimSpace(s)))
-	}
-	return out
-}
-
-// The test set for TestBestMatch is defined in data_test.go.
-func TestBestMatch(t *testing.T) {
-	for _, tt := range matchTests {
-		supported := parseSupported(tt.supported)
-		m := newMatcher(supported, nil)
-		if *verbose {
-			fmt.Printf("%s:\n%v\n", tt.comment, m)
-		}
-		for _, tm := range tt.test {
-			t.Run(path.Join(tt.comment, tt.supported, tm.desired), func(t *testing.T) {
-				tag, _, conf := m.Match(parseSupported(tm.desired)...)
-				if tag.String() != tm.match {
-					t.Errorf("find %s in %q: have %s; want %s (%v)", tm.desired, tt.supported, tag, tm.match, conf)
-				}
-			})
-
-		}
-	}
-}
-
 func TestBestMatchAlloc(t *testing.T) {
-	m := NewMatcher(parseSupported("en sr nl"))
+	m := NewMatcher(makeTagList("en sr nl"))
 	// Go allocates when creating a list of tags from a single tag!
 	list := []Tag{English}
 	avg := testtext.AllocsPerRun(1, func() {
diff --git a/language/testdata/localeMatcherTest.txt b/language/testdata/CLDRLocaleMatcherTest.txt
similarity index 100%
rename from language/testdata/localeMatcherTest.txt
rename to language/testdata/CLDRLocaleMatcherTest.txt
diff --git a/language/testdata/GoLocaleMatcherTest.txt b/language/testdata/GoLocaleMatcherTest.txt
index cc59e9b..7817979 100644
--- a/language/testdata/GoLocaleMatcherTest.txt
+++ b/language/testdata/GoLocaleMatcherTest.txt
@@ -9,7 +9,7 @@
 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
+zh-CN, zh-TW, iw ; 	he-IT ; 	iw ; iw  # should the surface tag be he?
 
 # language-specific script fallbacks 1
 en, sr, nl ; 	sr-Latn ; 	sr
@@ -114,7 +114,7 @@
 nl, nl-NL, nl-BE ; 	nl-NL ; 	nl-NL
 
 # region may replace matched if matched is enclosing
-es-419,es ; 	es-MX ; 	es-MX
+es-419,es ; 	es-MX ; 	es-419 ; es-MX
 es-419,es ; 	es-SG ; 	es
 
 # more specific region wins over more specific script
@@ -134,7 +134,7 @@
 
 # en-AU is closer to en-GB than to en (which is en-US)
 en, en-GB, es-ES, es-419 ; 	en-AU ; 	en-GB
-en, en-GB, es-ES, es-419 ; 	es-MX ; 	es-MX
+en, en-GB, es-ES, es-419 ; 	es-MX ; 	es-419 ; es-MX
 en, en-GB, es-ES, es-419 ; 	es-PT ; 	es-ES
 
 # undefined
@@ -187,27 +187,27 @@
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	en-SG ; 	en-GB
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	en-DE ; 	en-GB
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	en-MT ; 	en-GB
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-AR ; 	es-AR
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-BO ; 	es-BO
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CL ; 	es-CL
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CO ; 	es-CO
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CR ; 	es-CR
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CU ; 	es-CU
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-DO ; 	es-DO
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-EC ; 	es-EC
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-GT ; 	es-GT
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-HN ; 	es-HN
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-MX ; 	es-MX
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-NI ; 	es-NI
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PA ; 	es-PA
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PE ; 	es-PE
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PR ; 	es-PR
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-AR ; 	es-419 ; es-AR
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-BO ; 	es-419 ; es-BO
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CL ; 	es-419 ; es-CL
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CO ; 	es-419 ; es-CO
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CR ; 	es-419 ; es-CR
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-CU ; 	es-419 ; es-CU
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-DO ; 	es-419 ; es-DO
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-EC ; 	es-419 ; es-EC
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-GT ; 	es-419 ; es-GT
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-HN ; 	es-419 ; es-HN
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-MX ; 	es-419 ; es-MX
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-NI ; 	es-419 ; es-NI
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PA ; 	es-419 ; es-PA
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PE ; 	es-419 ; es-PE
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PR ; 	es-419 ; es-PR
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PT ; 	es
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PY ; 	es-PY
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-SV ; 	es-SV
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-PY ; 	es-419 ; es-PY
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-SV ; 	es-419 ; es-SV
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-US ; 	es-419
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-UY ; 	es-UY
-en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-VE ; 	es-VE
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-UY ; 	es-419 ; es-UY
+en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	es-VE ; 	es-419 ; es-VE
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	pt-AO ; 	pt-PT
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	pt-CV ; 	pt-PT
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	pt-GW ; 	pt-PT
@@ -217,8 +217,8 @@
 en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh,  zh-Hant, zh-Hant-HK ; 	pt-TL ; 	pt-PT
 
 # preserve Unicode extension
-en, de, sl-nedis ; 	de-FR-u-co-phonebk ; 	de-u-co-phonebk
-en, de, sl-nedis ; 	sl-nedis-u-cu-eur ; 	sl-nedis-u-cu-eur
-en, de, sl-nedis ; 	sl-u-cu-eur ; 	sl-nedis-u-cu-eur
-en, de, sl-nedis ; 	sl-HR-nedis-u-cu-eur ; 	sl-nedis-u-cu-eur
+en, de, sl-nedis ; 	de-FR-u-co-phonebk ; 	de ; de-u-co-phonebk
+en, de, sl-nedis ; 	sl-nedis-u-cu-eur ; 	sl-nedis ; sl-nedis-u-cu-eur
+en, de, sl-nedis ; 	sl-u-cu-eur ; 	sl-nedis ; sl-nedis-u-cu-eur
+en, de, sl-nedis ; 	sl-HR-nedis-u-cu-eur ; 	sl-nedis ; sl-nedis-u-cu-eur