internal/cldrtree: print enum consts

- Also ensure that integer keys map to
  their corresponding value.
- Generate testdata for key lookup.
- Reuse compact summary info for Enum types

Change-Id: Ia445e93ff215c1c3d7f448e50efbf6026eb631da
Reviewed-on: https://go-review.googlesource.com/73351
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/internal/cldrtree/cldrtree.go b/internal/cldrtree/cldrtree.go
index a0a6b90..660a5b2 100644
--- a/internal/cldrtree/cldrtree.go
+++ b/internal/cldrtree/cldrtree.go
@@ -186,8 +186,12 @@
 	if err != nil {
 		return err
 	}
-	generate(b, t, w)
-	return nil
+	return generate(b, t, w)
+}
+
+// GenTestData generates tables useful for testing data generated with Gen.
+func (b *Builder) GenTestData(w *gen.CodeWriter) error {
+	return generateTestData(b, w)
 }
 
 type locale struct {
diff --git a/internal/cldrtree/cldrtree_test.go b/internal/cldrtree/cldrtree_test.go
index 232fb46..56637c7 100644
--- a/internal/cldrtree/cldrtree_test.go
+++ b/internal/cldrtree/cldrtree_test.go
@@ -8,10 +8,12 @@
 	"bytes"
 	"flag"
 	"io/ioutil"
+	"log"
 	"math/rand"
 	"path/filepath"
 	"reflect"
 	"regexp"
+	"strconv"
 	"strings"
 	"testing"
 
@@ -99,13 +101,13 @@
 		desc:   "und/chinese month format wide m1",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 0, month, 0, wide, 0),
+		path:   path(calendar, 0, month, 0, wide, 1),
 		result: "cM01",
 	}, {
 		desc:   "und/chinese month format wide m12",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 0, month, 0, wide, 11),
+		path:   path(calendar, 0, month, 0, wide, 12),
 		result: "cM12",
 	}, {
 		desc:   "und/non-existing value",
@@ -117,49 +119,49 @@
 		desc:   "und/dangi:chinese month format wide",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 1, month, 0, wide, 0),
+		path:   path(calendar, 1, month, 0, wide, 1),
 		result: "cM01",
 	}, {
 		desc:   "und/chinese month format abbreviated:wide",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 0, month, 0, abbreviated, 0),
+		path:   path(calendar, 0, month, 0, abbreviated, 1),
 		result: "cM01",
 	}, {
 		desc:   "und/chinese month format narrow:wide",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 0, month, 0, narrow, 0),
+		path:   path(calendar, 0, month, 0, narrow, 1),
 		result: "cM01",
 	}, {
 		desc:   "und/gregorian month format wide",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 2, month, 0, wide, 1),
+		path:   path(calendar, 2, month, 0, wide, 2),
 		result: "gM02",
 	}, {
 		desc:   "und/gregorian month format:stand-alone narrow",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 2, month, 0, narrow, 0),
+		path:   path(calendar, 2, month, 0, narrow, 1),
 		result: "1",
 	}, {
 		desc:   "und/gregorian month stand-alone:format abbreviated",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 2, month, 1, abbreviated, 0),
+		path:   path(calendar, 2, month, 1, abbreviated, 1),
 		result: "gM01",
 	}, {
 		desc:   "und/gregorian month stand-alone:format wide ",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 2, month, 1, abbreviated, 0),
+		path:   path(calendar, 2, month, 1, abbreviated, 1),
 		result: "gM01",
 	}, {
-		desc:   "und/dangi:chinese format narrow:wide ",
+		desc:   "und/dangi:chinese month format narrow:wide ",
 		tree:   tree1,
 		locale: "und",
-		path:   path(calendar, 1, month, 0, narrow, 3),
+		path:   path(calendar, 1, month, 0, narrow, 4),
 		result: "cM04",
 	}, {
 		desc:   "und/field era displayname 0",
@@ -177,43 +179,43 @@
 		desc:   "und/calendar hebrew format wide 7-leap",
 		tree:   tree2,
 		locale: "und",
-		path:   path(calendar, 7, month, 0, wide, 13),
+		path:   path(calendar, 7, month, 0, wide, 0),
 		result: "Adar II",
 	}, {
 		desc:   "en-GB:en-001:en:und/calendar hebrew format wide 7-leap",
 		tree:   tree2,
 		locale: "en-GB",
-		path:   path(calendar, 7, month, 0, wide, 13),
+		path:   path(calendar, 7, month, 0, wide, 0),
 		result: "Adar II",
 	}, {
 		desc:   "und/buddhist month format wide 11",
 		tree:   tree2,
 		locale: "und",
-		path:   path(calendar, 0, month, 0, wide, 11),
+		path:   path(calendar, 0, month, 0, wide, 12),
 		result: "genWideM12",
 	}, {
 		desc:   "en-GB/gregorian month stand-alone narrow 2",
 		tree:   tree2,
 		locale: "en-GB",
-		path:   path(calendar, 6, month, 1, narrow, 2),
+		path:   path(calendar, 6, month, 1, narrow, 3),
 		result: "gbNarrowM3",
 	}, {
 		desc:   "en-GB/gregorian month format narrow 3/missing in en-GB",
 		tree:   tree2,
 		locale: "en-GB",
-		path:   path(calendar, 6, month, 0, narrow, 3),
+		path:   path(calendar, 6, month, 0, narrow, 4),
 		result: "enNarrowM4",
 	}, {
 		desc:   "en-GB/gregorian month format narrow 3/missing in en and en-GB",
 		tree:   tree2,
 		locale: "en-GB",
-		path:   path(calendar, 6, month, 0, narrow, 6),
+		path:   path(calendar, 6, month, 0, narrow, 7),
 		result: "gregNarrowM7",
 	}, {
 		desc:   "en-GB/gregorian month format narrow 3/missing in en and en-GB",
 		tree:   tree2,
 		locale: "en-GB",
-		path:   path(calendar, 6, month, 0, narrow, 6),
+		path:   path(calendar, 6, month, 0, narrow, 7),
 		result: "gregNarrowM7",
 	}, {
 		desc:      "en-GB/gregorian era narrow",
@@ -240,7 +242,7 @@
 		desc:      "en-GB/dangi:chinese cyclicName, months, format, narrow:abbreviated 2",
 		tree:      tree2,
 		locale:    "en-GB",
-		path:      path(calendar, 1, cyclicNameSet, 3, 0, 1, 1),
+		path:      path(calendar, 1, cyclicNameSet, 3, 0, 1, 2),
 		isFeature: true,
 		result:    "year2",
 	}, {
@@ -339,6 +341,21 @@
 		return "w" + strings.Title(s)
 	}
 	width := EnumFunc("width", widthMap, "abbreviated", "narrow", "wide")
+	month := Enum("month", "leap7")
+	relative := EnumFunc("relative", func(s string) string {
+		x, err := strconv.ParseInt(s, 10, 8)
+		if err != nil {
+			log.Fatal("Invalid number:", err)
+		}
+		return []string{
+			"before1",
+			"current",
+			"after1",
+		}[x+1]
+	})
+	cycleType := EnumFunc("cycleType", func(s string) string {
+		return "cyc" + strings.Title(s)
+	})
 	r := rand.New(rand.NewSource(0))
 
 	for _, loc := range data.Locales() {
@@ -354,14 +371,14 @@
 						for _, mw := range mc.MonthWidth {
 							x := x.IndexFromType(mw, width)
 							for _, m := range mw.Month {
-								x.SetValue(m.Type+m.Yeartype, m)
+								x.SetValue(m.Yeartype+m.Type, m, month)
 							}
 						}
 					}
 				}
 				if x := x.Index(cal.CyclicNameSets); x != nil {
 					for _, cns := range cal.CyclicNameSets.CyclicNameSet {
-						x := x.IndexFromType(cns)
+						x := x.IndexFromType(cns, cycleType)
 						for _, cc := range cns.CyclicNameContext {
 							x := x.IndexFromType(cc, context)
 							for _, cw := range cc.CyclicNameWidth {
@@ -408,7 +425,7 @@
 					x.Index(d).SetValue("", d)
 				}
 				for _, r := range f.Relative {
-					x.Index(r).SetValue(r.Type, r)
+					x.Index(r).SetValue(r.Type, r, relative)
 				}
 				for _, rt := range f.RelativeTime {
 					x := x.Index(rt).IndexFromType(rt)
@@ -429,8 +446,10 @@
 	}
 	w := gen.NewCodeWriter()
 	generate(b, tree, w)
+	generateTestData(b, w)
 	buf := &bytes.Buffer{}
 	if _, err = w.WriteGo(buf, "test"); err != nil {
+		t.Log(buf.String())
 		t.Fatal("error generating code:", err)
 	}
 	return tree, buf.Bytes()
diff --git a/internal/cldrtree/generate.go b/internal/cldrtree/generate.go
index e06459c..0f0b5f3 100644
--- a/internal/cldrtree/generate.go
+++ b/internal/cldrtree/generate.go
@@ -15,7 +15,7 @@
 	"golang.org/x/text/internal/gen"
 )
 
-func generate(b *Builder, t *Tree, w *gen.CodeWriter) {
+func generate(b *Builder, t *Tree, w *gen.CodeWriter) error {
 	fmt.Fprintln(w, `import "golang.org/x/text/internal/cldrtree"`)
 	fmt.Fprintln(w)
 
@@ -28,15 +28,19 @@
 	for _, e := range b.enums {
 		// Build enum types.
 		w.WriteComment("%s specifies a property of a CLDR field.", e.name)
-		fmt.Fprintf(w, "type %s int\n", e.name)
-		fmt.Fprintln(w, "const (")
-		fmt.Fprintf(w, "%v %v = iota\n", toCamel(e.keys[0]), e.name)
-		for _, s := range e.keys[1:] {
-			fmt.Fprintln(w, toCamel(s))
-		}
-		fmt.Fprintln(w, ")")
+		fmt.Fprintf(w, "type %s uint16\n", e.name)
 	}
 
+	d, err := getEnumData(b)
+	if err != nil {
+		return err
+	}
+	fmt.Fprintln(w, "const (")
+	for i, k := range d.keys {
+		fmt.Fprintf(w, "%s %s = %d // %s\n", toCamel(k), d.enums[i], d.m[k], k)
+	}
+	fmt.Fprintln(w, ")")
+
 	w.WriteVar("locales", t.Locales)
 	w.WriteVar("indices", t.Indices)
 
@@ -52,6 +56,23 @@
 	for i, bucket := range t.Buckets {
 		w.WriteVar(fmt.Sprint("bucket", i), bucket)
 	}
+	return nil
+}
+
+func generateTestData(b *Builder, w *gen.CodeWriter) error {
+	d, err := getEnumData(b)
+	if err != nil {
+		return err
+	}
+
+	fmt.Fprintln(w)
+	fmt.Fprintln(w, "var enumMap = map[string]uint16{")
+	fmt.Fprintln(w, `"": 0,`)
+	for _, k := range d.keys {
+		fmt.Fprintf(w, "%q: %d,\n", k, d.m[k])
+	}
+	fmt.Fprintln(w, "}")
+	return nil
 }
 
 func toCamel(s string) string {
@@ -59,7 +80,7 @@
 	for i, s := range p[1:] {
 		p[i+1] = strings.Title(s)
 	}
-	return strings.Join(p, "")
+	return strings.Replace(strings.Join(p, ""), "/", "", -1)
 }
 
 func (b *Builder) stats() string {
@@ -68,9 +89,7 @@
 	b.rootMeta.validate()
 	for _, es := range b.enums {
 		fmt.Fprintf(w, "<%s>\n", es.name)
-		for _, s := range es.keys {
-			fmt.Fprintf(w, "  - %s\n", s)
-		}
+		printEnumValues(w, es, 1, nil)
 	}
 	fmt.Fprintln(w)
 	printEnums(w, b.rootMeta.typeInfo, 0)
@@ -95,39 +114,7 @@
 	if e.name != "" {
 		fmt.Fprintf(w, "%s<%s>\n", idStr, e.name)
 	} else {
-		for i := 0; i < len(e.keys); i++ {
-			fmt.Fprint(w, idStr)
-			// fmt.Fprint(w, "- ")
-			k := e.keys[i]
-			if u, err := strconv.ParseUint(k, 10, 16); err == nil {
-				fmt.Fprintf(w, "%s", k)
-				// Skip contiguous integers
-				var v, last uint64
-				for i++; i < len(e.keys); i++ {
-					k = e.keys[i]
-					if v, err = strconv.ParseUint(k, 10, 16); err != nil {
-						break
-					}
-					last = v
-				}
-				if u < last {
-					fmt.Fprintf(w, `..%d`, last)
-				}
-				fmt.Fprintln(w)
-				if err != nil {
-					fmt.Fprintf(w, "%s%s\n", idStr, k)
-				}
-			} else if k == "" {
-				fmt.Fprintln(w, `""`)
-			} else {
-				fmt.Fprintf(w, "%s\n", k)
-			}
-			if !s.sharedKeys() {
-				if e := s.entries[enumIndex(i)]; e != nil {
-					printEnums(w, e, indent+1)
-				}
-			}
-		}
+		printEnumValues(w, e, indent, s)
 	}
 	if s.sharedKeys() {
 		for _, v := range s.entries {
@@ -136,3 +123,86 @@
 		}
 	}
 }
+
+func printEnumValues(w io.Writer, e *enum, indent int, info *typeInfo) {
+	idStr := strings.Repeat("  ", indent) + "- "
+	for i := 0; i < len(e.keys); i++ {
+		fmt.Fprint(w, idStr)
+		k := e.keys[i]
+		if u, err := strconv.ParseUint(k, 10, 16); err == nil {
+			fmt.Fprintf(w, "%s", k)
+			// Skip contiguous integers
+			var v, last uint64
+			for i++; i < len(e.keys); i++ {
+				k = e.keys[i]
+				if v, err = strconv.ParseUint(k, 10, 16); err != nil {
+					break
+				}
+				last = v
+			}
+			if u < last {
+				fmt.Fprintf(w, `..%d`, last)
+			}
+			fmt.Fprintln(w)
+			if err != nil {
+				fmt.Fprintf(w, "%s%s\n", idStr, k)
+			}
+		} else if k == "" {
+			fmt.Fprintln(w, `""`)
+		} else {
+			fmt.Fprintf(w, "%s\n", k)
+		}
+		if info != nil && !info.sharedKeys() {
+			if e := info.entries[enumIndex(i)]; e != nil {
+				printEnums(w, e, indent+1)
+			}
+		}
+	}
+}
+
+func getEnumData(b *Builder) (*enumData, error) {
+	d := &enumData{m: map[string]int{}}
+	if errStr := d.insert(b.rootMeta.typeInfo); errStr != "" {
+		// TODO: consider returning the error.
+		return nil, fmt.Errorf("cldrtree: %s", errStr)
+	}
+	return d, nil
+}
+
+type enumData struct {
+	m     map[string]int
+	keys  []string
+	enums []string
+}
+
+func (d *enumData) insert(t *typeInfo) (errStr string) {
+	e := t.enum
+	if e == nil {
+		return ""
+	}
+	for i, k := range e.keys {
+		if _, err := strconv.ParseUint(k, 10, 16); err == nil {
+			// We don't include any enum that has integer values.
+			break
+		}
+		if v, ok := d.m[k]; ok {
+			if v != i {
+				return fmt.Sprintf("%q has value %d and %d", k, i, v)
+			}
+		} else {
+			d.m[k] = i
+			if k != "" {
+				d.keys = append(d.keys, k)
+				d.enums = append(d.enums, e.name)
+			}
+		}
+	}
+	for i := range t.enum.keys {
+		if e := t.entries[enumIndex(i)]; e != nil {
+			if errStr := d.insert(e); errStr != "" {
+				return fmt.Sprintf("%q>%v", t.enum.keys[i], errStr)
+			}
+		}
+	}
+	return ""
+}
diff --git a/internal/cldrtree/testdata/test1/output.go b/internal/cldrtree/testdata/test1/output.go
index effda4c..9c17a7d 100755
--- a/internal/cldrtree/testdata/test1/output.go
+++ b/internal/cldrtree/testdata/test1/output.go
@@ -14,6 +14,9 @@
 //   - wAbbreviated
 //   - wNarrow
 //   - wWide
+// <month>
+//   - leap7
+//   - 1..12
 //
 // - calendars
 //   - chinese
@@ -22,7 +25,7 @@
 //     - months
 //       - <context>
 //         - <width>
-//           - 1..12
+//           - <month>
 //     - filler
 //       - 0
 //
@@ -32,20 +35,27 @@
 // bucket waste:       0
 
 // context specifies a property of a CLDR field.
-type context int
-
-const (
-	format context = iota
-	standAlone
-)
+type context uint16
 
 // width specifies a property of a CLDR field.
-type width int
+type width uint16
+
+// month specifies a property of a CLDR field.
+type month uint16
 
 const (
-	wAbbreviated width = iota
-	wNarrow
-	wWide
+	calendars            = 0 // calendars
+	chinese              = 0 // chinese
+	dangi                = 1 // dangi
+	gregorian            = 2 // gregorian
+	months               = 0 // months
+	filler               = 1 // filler
+	format       context = 0 // format
+	standAlone   context = 1 // stand-alone
+	wAbbreviated width   = 0 // wAbbreviated
+	wNarrow      width   = 1 // wNarrow
+	wWide        width   = 2 // wWide
+	leap7        month   = 0 // leap7
 )
 
 var locales = []uint32{ // 754 elements
@@ -264,20 +274,20 @@
 	0x00000000, 0x00000000,
 } // Size: xxxx bytes
 
-var indices = []uint16{ // 83 elements
+var indices = []uint16{ // 86 elements
 	// Entry 0 - 3F
-	0x0001, 0x0002, 0x0003, 0x0006, 0x0020, 0x0026, 0x0002, 0x0009,
-	0x001d, 0x0001, 0x000b, 0x0003, 0x8002, 0x8002, 0x000f, 0x000c,
-	0x0000, 0x0000, 0x0005, 0x000a, 0x000f, 0x0014, 0x0019, 0x001e,
-	0x0023, 0x0028, 0x002d, 0x0032, 0x0037, 0x0001, 0x0000, 0x003c,
-	0x0002, 0x9000, 0x0023, 0x0001, 0x0000, 0x013b, 0x0002, 0x0029,
-	0x0050, 0x0002, 0x002c, 0x003e, 0x0003, 0x8002, 0x9001, 0x0030,
-	0x000c, 0x0000, 0x023a, 0x023f, 0x0244, 0x0249, 0x024e, 0x0253,
-	0x0258, 0x025d, 0x0262, 0x0267, 0x026c, 0x0271, 0x0003, 0x9000,
+	0x0001, 0x0002, 0x0003, 0x0006, 0x0021, 0x0027, 0x0002, 0x0009,
+	0x001e, 0x0001, 0x000b, 0x0003, 0x8002, 0x8002, 0x000f, 0x000d,
+	0x0000, 0xffff, 0x0000, 0x0005, 0x000a, 0x000f, 0x0014, 0x0019,
+	0x001e, 0x0023, 0x0028, 0x002d, 0x0032, 0x0037, 0x0001, 0x0000,
+	0x003c, 0x0002, 0x9000, 0x0024, 0x0001, 0x0000, 0x013b, 0x0002,
+	0x002a, 0x0053, 0x0002, 0x002d, 0x0040, 0x0003, 0x8002, 0x9001,
+	0x0031, 0x000d, 0x0000, 0xffff, 0x023a, 0x023f, 0x0244, 0x0249,
+	0x024e, 0x0253, 0x0258, 0x025d, 0x0262, 0x0267, 0x026c, 0x0271,
 	// Entry 40 - 7F
-	0x0042, 0x9000, 0x000c, 0x0000, 0x0276, 0x0278, 0x027a, 0x027c,
-	0x027e, 0x0280, 0x0282, 0x0284, 0x0286, 0x0288, 0x028b, 0x028e,
-	0x0001, 0x0000, 0x0291,
+	0x0003, 0x9000, 0x0044, 0x9000, 0x000d, 0x0000, 0xffff, 0x0276,
+	0x0278, 0x027a, 0x027c, 0x027e, 0x0280, 0x0282, 0x0284, 0x0286,
+	0x0288, 0x028b, 0x028e, 0x0001, 0x0000, 0x0291,
 } // Size: xxxx bytes
 
 var buckets = []string{
@@ -318,4 +328,20 @@
 	"\xc97\x88\xa5@\x9f\x8bnB\xc2݃\xaaFa\x18R\xad\x0bP(w\\w\x16\x90\xb6\x85N" +
 	"\x05\xb3w$\x1es\xa8\x83\xddw\xaf\xf00,m\xa8f\\B4\x1d\xdaJ\xda\xea"
 
-	// Total table size: xxxx bytes (4KiB); checksum: DB2842B6
+var enumMap = map[string]uint16{
+	"":             0,
+	"calendars":    0,
+	"chinese":      0,
+	"dangi":        1,
+	"gregorian":    2,
+	"months":       0,
+	"filler":       1,
+	"format":       0,
+	"stand-alone":  1,
+	"wAbbreviated": 0,
+	"wNarrow":      1,
+	"wWide":        2,
+	"leap7":        0,
+}
+
+// Total table size: xxxx bytes (4KiB); checksum: DFE9E450
diff --git a/internal/cldrtree/testdata/test2/output.go b/internal/cldrtree/testdata/test2/output.go
index aea79c8..4b00e06 100755
--- a/internal/cldrtree/testdata/test2/output.go
+++ b/internal/cldrtree/testdata/test2/output.go
@@ -14,6 +14,19 @@
 // <context>
 //   - format
 //   - stand-alone
+// <month>
+//   - leap7
+//   - 1..13
+// <cycleType>
+//   - cycDayParts
+//   - cycDays
+//   - cycMonths
+//   - cycYears
+//   - cycZodiacs
+// <relative>
+//   - before1
+//   - current
+//   - after1
 //
 // - calendars
 //   - buddhist
@@ -33,8 +46,7 @@
 //     - months
 //       - <context>
 //         - <width>
-//           - 1..13
-//           - 7leap
+//           - <month>
 //     - eras
 //       - <width>
 //         - ""
@@ -43,14 +55,10 @@
 //     - filler
 //       - 0
 //     - cyclicNameSets
-//       - dayParts
-//       - days
-//       - months
-//       - years
-//       - zodiacs
+//       - <cycleType>
 //         - <context>
 //           - <width>
-//             - 1..60
+//             - 0..60
 // - fields
 //   - era
 //   - era-short
@@ -61,8 +69,7 @@
 //     - displayName
 //       - ""
 //     - relative
-//       - -1
-//       - 0..1
+//       - <relative>
 //     - relativeTime
 //       - future
 //       - past
@@ -76,25 +83,75 @@
 // bucket waste:       0
 
 // width specifies a property of a CLDR field.
-type width int
-
-const (
-	wAbbreviated width = iota
-	wNarrow
-	wWide
-)
+type width uint16
 
 // context specifies a property of a CLDR field.
-type context int
+type context uint16
+
+// month specifies a property of a CLDR field.
+type month uint16
+
+// cycleType specifies a property of a CLDR field.
+type cycleType uint16
+
+// relative specifies a property of a CLDR field.
+type relative uint16
 
 const (
-	format context = iota
-	standAlone
+	calendars                   = 0  // calendars
+	fields                      = 1  // fields
+	buddhist                    = 0  // buddhist
+	chinese                     = 1  // chinese
+	dangi                       = 2  // dangi
+	ethiopic                    = 3  // ethiopic
+	ethiopicAmeteAlem           = 4  // ethiopic-amete-alem
+	generic                     = 5  // generic
+	gregorian                   = 6  // gregorian
+	hebrew                      = 7  // hebrew
+	islamic                     = 8  // islamic
+	islamicCivil                = 9  // islamic-civil
+	islamicRgsa                 = 10 // islamic-rgsa
+	islamicTbla                 = 11 // islamic-tbla
+	islamicUmalqura             = 12 // islamic-umalqura
+	persian                     = 13 // persian
+	months                      = 0  // months
+	eras                        = 1  // eras
+	filler                      = 2  // filler
+	cyclicNameSets              = 3  // cyclicNameSets
+	format            context   = 0  // format
+	standAlone        context   = 1  // stand-alone
+	wAbbreviated      width     = 0  // wAbbreviated
+	wNarrow           width     = 1  // wNarrow
+	wWide             width     = 2  // wWide
+	leap7             month     = 0  // leap7
+	variant                     = 1  // variant
+	cycDayParts       cycleType = 0  // cycDayParts
+	cycDays           cycleType = 1  // cycDays
+	cycMonths         cycleType = 2  // cycMonths
+	cycYears          cycleType = 3  // cycYears
+	cycZodiacs        cycleType = 4  // cycZodiacs
+	era                         = 0  // era
+	eraShort                    = 1  // era-short
+	eraNarrow                   = 2  // era-narrow
+	month                       = 3  // month
+	monthShort                  = 4  // month-short
+	monthNarrow                 = 5  // month-narrow
+	displayName                 = 0  // displayName
+	relative                    = 1  // relative
+	relativeTime                = 2  // relativeTime
+	before1           relative  = 0  // before1
+	current           relative  = 1  // current
+	after1            relative  = 2  // after1
+	future                      = 0  // future
+	past                        = 1  // past
+	other                       = 0  // other
+	one                         = 1  // one
+	two                         = 2  // two
 )
 
 var locales = []uint32{ // 754 elements
 	// Entry 0 - 1F
-	0x00000000, 0x00000000, 0x0000026b, 0x00000000,
+	0x00000000, 0x00000000, 0x0000027a, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -131,36 +188,36 @@
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	// Entry 80 - 9F
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x0000026b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000026b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000026b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
+	0x00000000, 0x0000027a, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000027a, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000027a,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
 	// Entry A0 - BF
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x000003c8, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000026b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000026b, 0x0000036b, 0x0000026b, 0x0000036b,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x000003dd, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000027a, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000027a, 0x0000037f, 0x0000027a, 0x0000037f,
 	// Entry C0 - DF
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000026b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000027a,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
 	// Entry E0 - FF
-	0x0000036b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000026b, 0x0000026b, 0x0000036b, 0x0000036b,
-	0x0000026b, 0x0000036b, 0x0000036b, 0x0000036b,
-	0x0000036b, 0x0000036b, 0x00000000, 0x00000000,
+	0x0000037f, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000027a, 0x0000027a, 0x0000037f, 0x0000037f,
+	0x0000027a, 0x0000037f, 0x0000037f, 0x0000037f,
+	0x0000037f, 0x0000037f, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -308,155 +365,158 @@
 	0x00000000, 0x00000000,
 } // Size: xxxx bytes
 
-var indices = []uint16{ // 1046 elements
+var indices = []uint16{ // 1070 elements
 	// Entry 0 - 3F
-	0x0002, 0x0003, 0x024a, 0x000e, 0x0012, 0x0022, 0x00b5, 0x00bd,
-	0x00f7, 0x0107, 0x013f, 0x0177, 0x01b2, 0x01f7, 0x01fe, 0x0205,
-	0x020c, 0x0213, 0x0003, 0x9005, 0x0016, 0x001f, 0x0003, 0x001a,
+	0x0002, 0x0003, 0x0259, 0x000e, 0x0012, 0x0022, 0x00b9, 0x00c1,
+	0x00fd, 0x010d, 0x0147, 0x0181, 0x01bc, 0x0204, 0x020b, 0x0212,
+	0x0219, 0x0220, 0x0003, 0x9005, 0x0016, 0x001f, 0x0003, 0x001a,
 	0x8000, 0x8000, 0x0001, 0x001c, 0x0001, 0x0000, 0x0000, 0x0001,
-	0x0000, 0x0003, 0x0004, 0x0027, 0x0000, 0x00b2, 0x004e, 0x0002,
-	0x002a, 0x003c, 0x0003, 0x8002, 0x9001, 0x002e, 0x000c, 0x0000,
-	0x0102, 0x0111, 0x0120, 0x012f, 0x013e, 0x014d, 0x015c, 0x016b,
-	0x017a, 0x0189, 0x0198, 0x01a7, 0x0003, 0x9000, 0x0040, 0x9000,
+	0x0000, 0x0003, 0x0004, 0x0027, 0x0000, 0x00b6, 0x0050, 0x0002,
+	0x002a, 0x003d, 0x0003, 0x8002, 0x9001, 0x002e, 0x000d, 0x0000,
+	0xffff, 0x0102, 0x0111, 0x0120, 0x012f, 0x013e, 0x014d, 0x015c,
+	0x016b, 0x017a, 0x0189, 0x0198, 0x01a7, 0x0003, 0x9000, 0x0041,
 	// Entry 40 - 7F
-	0x000c, 0x0000, 0x01b6, 0x01c6, 0x01d6, 0x01e6, 0x01f6, 0x0206,
-	0x0216, 0x0226, 0x0236, 0x0246, 0x0257, 0x0268, 0x0005, 0x0054,
-	0x8003, 0x8003, 0x0068, 0x00ac, 0x0001, 0x0056, 0x0003, 0x005a,
-	0x8000, 0x8000, 0x000c, 0x0000, 0x0279, 0x0281, 0x0289, 0x0291,
-	0x0299, 0x02a1, 0x02a9, 0x02b1, 0x02b9, 0x02c1, 0x02ca, 0x02d3,
-	0x0001, 0x006a, 0x0003, 0x006e, 0x8000, 0x8000, 0x003c, 0x0000,
-	0x02dc, 0x02e2, 0x02e8, 0x02ee, 0x02f4, 0x02fa, 0x0300, 0x0306,
-	0x030c, 0x0312, 0x0319, 0x0320, 0x0327, 0x032e, 0x0335, 0x033c,
+	0x9000, 0x000d, 0x0000, 0xffff, 0x01b6, 0x01c6, 0x01d6, 0x01e6,
+	0x01f6, 0x0206, 0x0216, 0x0226, 0x0236, 0x0246, 0x0257, 0x0268,
+	0x0005, 0x0056, 0x8003, 0x8003, 0x006b, 0x00b0, 0x0001, 0x0058,
+	0x0003, 0x005c, 0x8000, 0x8000, 0x000d, 0x0000, 0xffff, 0x0279,
+	0x0281, 0x0289, 0x0291, 0x0299, 0x02a1, 0x02a9, 0x02b1, 0x02b9,
+	0x02c1, 0x02ca, 0x02d3, 0x0001, 0x006d, 0x0003, 0x0071, 0x8000,
+	0x8000, 0x003d, 0x0000, 0xffff, 0x02dc, 0x02e2, 0x02e8, 0x02ee,
+	0x02f4, 0x02fa, 0x0300, 0x0306, 0x030c, 0x0312, 0x0319, 0x0320,
 	// Entry 80 - BF
-	0x0343, 0x034a, 0x0351, 0x0358, 0x035f, 0x0366, 0x036d, 0x0374,
-	0x037b, 0x0382, 0x0389, 0x0390, 0x0397, 0x039e, 0x03a5, 0x03ac,
-	0x03b3, 0x03ba, 0x03c1, 0x03c8, 0x03cf, 0x03d6, 0x03dd, 0x03e4,
-	0x03eb, 0x03f2, 0x03f9, 0x0400, 0x0407, 0x040e, 0x0415, 0x041c,
-	0x0423, 0x042a, 0x0431, 0x0438, 0x043f, 0x0446, 0x044d, 0x0454,
-	0x045b, 0x0462, 0x0469, 0x0470, 0x0001, 0x00ae, 0x0003, 0xa000,
-	0x8000, 0x8000, 0x0001, 0x0000, 0x0477, 0x0004, 0x9001, 0x0000,
-	0x00ba, 0x9001, 0x0001, 0x0000, 0x0576, 0x0003, 0x00c1, 0x00ea,
+	0x0327, 0x032e, 0x0335, 0x033c, 0x0343, 0x034a, 0x0351, 0x0358,
+	0x035f, 0x0366, 0x036d, 0x0374, 0x037b, 0x0382, 0x0389, 0x0390,
+	0x0397, 0x039e, 0x03a5, 0x03ac, 0x03b3, 0x03ba, 0x03c1, 0x03c8,
+	0x03cf, 0x03d6, 0x03dd, 0x03e4, 0x03eb, 0x03f2, 0x03f9, 0x0400,
+	0x0407, 0x040e, 0x0415, 0x041c, 0x0423, 0x042a, 0x0431, 0x0438,
+	0x043f, 0x0446, 0x044d, 0x0454, 0x045b, 0x0462, 0x0469, 0x0470,
+	0x0001, 0x00b2, 0x0003, 0xa000, 0x8000, 0x8000, 0x0001, 0x0000,
+	0x0477, 0x0004, 0x9001, 0x0000, 0x00be, 0x9001, 0x0001, 0x0000,
 	// Entry C0 - FF
-	0x00f4, 0x0002, 0x00c4, 0x00d7, 0x0003, 0x8002, 0x9001, 0x00c8,
-	0x000d, 0x0000, 0x0675, 0x067e, 0x0685, 0x068b, 0x0692, 0x0696,
-	0x069e, 0x06a6, 0x06ad, 0x06b4, 0x06b9, 0x06bf, 0x06c7, 0x0003,
-	0x9000, 0x00db, 0x9000, 0x000d, 0x0000, 0x06cf, 0x06d1, 0x06d3,
-	0x06d5, 0x06d7, 0x06d9, 0x06db, 0x06dd, 0x06df, 0x06e1, 0x06e4,
-	0x06e7, 0x06ea, 0x0003, 0x00ee, 0x8000, 0x8000, 0x0001, 0x00f0,
-	0x0002, 0x0000, 0x06ed, 0x06f2, 0x0001, 0x0000, 0x06f7, 0x0003,
-	0x9003, 0x00fb, 0x0104, 0x0003, 0x00ff, 0x8000, 0x8000, 0x0001,
+	0x0576, 0x0003, 0x00c5, 0x00f0, 0x00fa, 0x0002, 0x00c8, 0x00dc,
+	0x0003, 0x8002, 0x9001, 0x00cc, 0x000e, 0x0000, 0xffff, 0x0675,
+	0x067e, 0x0685, 0x068b, 0x0692, 0x0696, 0x069e, 0x06a6, 0x06ad,
+	0x06b4, 0x06b9, 0x06bf, 0x06c7, 0x0003, 0x9000, 0x00e0, 0x9000,
+	0x000e, 0x0000, 0xffff, 0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d7,
+	0x06d9, 0x06db, 0x06dd, 0x06df, 0x06e1, 0x06e4, 0x06e7, 0x06ea,
+	0x0003, 0x00f4, 0x8000, 0x8000, 0x0001, 0x00f6, 0x0002, 0x0000,
+	0x06ed, 0x06f2, 0x0001, 0x0000, 0x06f7, 0x0003, 0x9003, 0x0101,
 	// Entry 100 - 13F
-	0x0101, 0x0001, 0x0000, 0x06ed, 0x0001, 0x0000, 0x07f6, 0x0003,
-	0x010b, 0x0132, 0x013c, 0x0002, 0x010e, 0x0120, 0x0003, 0x8002,
-	0x9001, 0x0112, 0x000c, 0x0000, 0x08f5, 0x0900, 0x090b, 0x0916,
-	0x0921, 0x092c, 0x0937, 0x0942, 0x094d, 0x0958, 0x0963, 0x096e,
-	0x0003, 0x9000, 0x0124, 0x9000, 0x000c, 0x0000, 0x0979, 0x0985,
+	0x010a, 0x0003, 0x0105, 0x8000, 0x8000, 0x0001, 0x0107, 0x0001,
+	0x0000, 0x06ed, 0x0001, 0x0000, 0x07f6, 0x0003, 0x0111, 0x013a,
+	0x0144, 0x0002, 0x0114, 0x0127, 0x0003, 0x8002, 0x9001, 0x0118,
+	0x000d, 0x0000, 0xffff, 0x08f5, 0x0900, 0x090b, 0x0916, 0x0921,
+	0x092c, 0x0937, 0x0942, 0x094d, 0x0958, 0x0963, 0x096e, 0x0003,
+	0x9000, 0x012b, 0x9000, 0x000d, 0x0000, 0xffff, 0x0979, 0x0985,
 	0x0991, 0x099d, 0x09a9, 0x09b5, 0x09c1, 0x09cd, 0x09d9, 0x09e5,
-	0x09f2, 0x09ff, 0x0003, 0x0136, 0x8000, 0x8000, 0x0001, 0x0138,
-	0x0002, 0x0000, 0x06ed, 0x06f2, 0x0001, 0x0000, 0x0a0c, 0x0003,
+	0x09f2, 0x09ff, 0x0003, 0x013e, 0x8000, 0x8000, 0x0001, 0x0140,
 	// Entry 140 - 17F
-	0x0143, 0x016a, 0x0174, 0x0002, 0x0146, 0x0158, 0x0003, 0x8002,
-	0x9001, 0x014a, 0x000c, 0x0000, 0x0b0b, 0x0b17, 0x0b23, 0x0b2f,
-	0x0b3b, 0x0b47, 0x0b53, 0x0b5f, 0x0b6b, 0x0b77, 0x0b83, 0x0b8f,
-	0x0003, 0x9000, 0x015c, 0x9000, 0x000c, 0x0000, 0x0b9b, 0x0ba8,
-	0x0bb5, 0x0bc2, 0x0bcf, 0x0bdc, 0x0be9, 0x0bf6, 0x0c03, 0x0c10,
-	0x0c1e, 0x0c2c, 0x0003, 0x016e, 0x8000, 0x8000, 0x0001, 0x0170,
-	0x0002, 0x0000, 0x0c3a, 0x0c3e, 0x0001, 0x0000, 0x0c41, 0x0003,
-	0x017b, 0x01a6, 0x01af, 0x0002, 0x017e, 0x0192, 0x0003, 0x8002,
+	0x0002, 0x0000, 0x06ed, 0x06f2, 0x0001, 0x0000, 0x0a0c, 0x0003,
+	0x014b, 0x0174, 0x017e, 0x0002, 0x014e, 0x0161, 0x0003, 0x8002,
+	0x9001, 0x0152, 0x000d, 0x0000, 0xffff, 0x0b0b, 0x0b17, 0x0b23,
+	0x0b2f, 0x0b3b, 0x0b47, 0x0b53, 0x0b5f, 0x0b6b, 0x0b77, 0x0b83,
+	0x0b8f, 0x0003, 0x9000, 0x0165, 0x9000, 0x000d, 0x0000, 0xffff,
+	0x0b9b, 0x0ba8, 0x0bb5, 0x0bc2, 0x0bcf, 0x0bdc, 0x0be9, 0x0bf6,
+	0x0c03, 0x0c10, 0x0c1e, 0x0c2c, 0x0003, 0x0178, 0x8000, 0x8000,
+	0x0001, 0x017a, 0x0002, 0x0000, 0x0c3a, 0x0c3e, 0x0001, 0x0000,
 	// Entry 180 - 1BF
-	0x9001, 0x0182, 0x000e, 0x0000, 0x0d40, 0x0d47, 0x0d4f, 0x0d56,
-	0x0d5c, 0x0d63, 0x0d6a, 0x0d77, 0x0d7d, 0x0d82, 0x0d88, 0x0d8e,
-	0x0d91, 0x0d6f, 0x0003, 0x9000, 0x0196, 0x9000, 0x000e, 0x0000,
-	0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d7, 0x06d9, 0x06db, 0x06dd,
-	0x06df, 0x06e1, 0x06e4, 0x06e7, 0x06ea, 0x06db, 0x0003, 0x01aa,
-	0x8000, 0x8000, 0x0001, 0x01ac, 0x0001, 0x0000, 0x0d96, 0x0001,
-	0x0000, 0x0d99, 0x0003, 0x01b6, 0x01eb, 0x01f4, 0x0002, 0x01b9,
-	0x01d9, 0x0003, 0x01bd, 0x9001, 0x01cb, 0x000c, 0x0000, 0x0e98,
+	0x0c41, 0x0003, 0x0185, 0x01b0, 0x01b9, 0x0002, 0x0188, 0x019c,
+	0x0003, 0x8002, 0x9001, 0x018c, 0x000e, 0x0000, 0x0d6f, 0x0d40,
+	0x0d47, 0x0d4f, 0x0d56, 0x0d5c, 0x0d63, 0x0d6a, 0x0d77, 0x0d7d,
+	0x0d82, 0x0d88, 0x0d8e, 0x0d91, 0x0003, 0x9000, 0x01a0, 0x9000,
+	0x000e, 0x0000, 0x06db, 0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d7,
+	0x06d9, 0x06db, 0x06dd, 0x06df, 0x06e1, 0x06e4, 0x06e7, 0x06ea,
+	0x0003, 0x01b4, 0x8000, 0x8000, 0x0001, 0x01b6, 0x0001, 0x0000,
+	0x0d96, 0x0001, 0x0000, 0x0d99, 0x0003, 0x01c0, 0x01f8, 0x0201,
 	// Entry 1C0 - 1FF
-	0x0ea1, 0x0eaa, 0x0eb3, 0x0ebc, 0x0ec5, 0x0ece, 0x0ed7, 0x0ee0,
-	0x0ee9, 0x0ef3, 0x0efd, 0x000c, 0x0000, 0x0f07, 0x0f10, 0x0f19,
-	0x0f22, 0x0f2b, 0x0f34, 0x0f3d, 0x0f46, 0x0f4f, 0x0f58, 0x0f62,
-	0x0f6c, 0x0003, 0x9000, 0x01dd, 0x9000, 0x000c, 0x0000, 0x06cf,
-	0x06d1, 0x06d3, 0x06d5, 0x06d7, 0x06d9, 0x06db, 0x06dd, 0x06df,
-	0x06e1, 0x06e4, 0x06e7, 0x0003, 0x01ef, 0x8000, 0x8000, 0x0001,
-	0x01f1, 0x0001, 0x0000, 0x0f76, 0x0001, 0x0000, 0x0f79, 0x0003,
-	0x9008, 0x9008, 0x01fb, 0x0001, 0x0000, 0x1078, 0x0003, 0x9008,
+	0x0002, 0x01c3, 0x01e5, 0x0003, 0x01c7, 0x9001, 0x01d6, 0x000d,
+	0x0000, 0xffff, 0x0e98, 0x0ea1, 0x0eaa, 0x0eb3, 0x0ebc, 0x0ec5,
+	0x0ece, 0x0ed7, 0x0ee0, 0x0ee9, 0x0ef3, 0x0efd, 0x000d, 0x0000,
+	0xffff, 0x0f07, 0x0f10, 0x0f19, 0x0f22, 0x0f2b, 0x0f34, 0x0f3d,
+	0x0f46, 0x0f4f, 0x0f58, 0x0f62, 0x0f6c, 0x0003, 0x9000, 0x01e9,
+	0x9000, 0x000d, 0x0000, 0xffff, 0x06cf, 0x06d1, 0x06d3, 0x06d5,
+	0x06d7, 0x06d9, 0x06db, 0x06dd, 0x06df, 0x06e1, 0x06e4, 0x06e7,
+	0x0003, 0x01fc, 0x8000, 0x8000, 0x0001, 0x01fe, 0x0001, 0x0000,
 	// Entry 200 - 23F
-	0x9008, 0x0202, 0x0001, 0x0000, 0x1177, 0x0003, 0x9008, 0x0000,
-	0x0209, 0x0001, 0x0000, 0x1276, 0x0003, 0x9008, 0x0000, 0x0210,
-	0x0001, 0x0000, 0x1375, 0x0003, 0x0217, 0x023e, 0x0247, 0x0002,
-	0x021a, 0x022c, 0x0003, 0x8002, 0x9001, 0x021e, 0x000c, 0x0000,
-	0x1474, 0x147e, 0x148a, 0x1492, 0x1496, 0x149d, 0x14a7, 0x14ac,
-	0x14b1, 0x14b6, 0x14ba, 0x14c1, 0x0003, 0x9000, 0x0230, 0x9000,
-	0x000c, 0x0000, 0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d7, 0x06d9,
-	0x06db, 0x06dd, 0x06df, 0x06e1, 0x06e4, 0x06e7, 0x0003, 0x0242,
+	0x0f76, 0x0001, 0x0000, 0x0f79, 0x0003, 0x9008, 0x9008, 0x0208,
+	0x0001, 0x0000, 0x1078, 0x0003, 0x9008, 0x9008, 0x020f, 0x0001,
+	0x0000, 0x1177, 0x0003, 0x9008, 0x0000, 0x0216, 0x0001, 0x0000,
+	0x1276, 0x0003, 0x9008, 0x0000, 0x021d, 0x0001, 0x0000, 0x1375,
+	0x0003, 0x0224, 0x024d, 0x0256, 0x0002, 0x0227, 0x023a, 0x0003,
+	0x8002, 0x9001, 0x022b, 0x000d, 0x0000, 0xffff, 0x1474, 0x147e,
+	0x148a, 0x1492, 0x1496, 0x149d, 0x14a7, 0x14ac, 0x14b1, 0x14b6,
+	0x14ba, 0x14c1, 0x0003, 0x9000, 0x023e, 0x9000, 0x000d, 0x0000,
 	// Entry 240 - 27F
-	0x8000, 0x8000, 0x0001, 0x0244, 0x0001, 0x0000, 0x14c8, 0x0001,
-	0x0000, 0x14cb, 0x0006, 0x0251, 0x8000, 0x8001, 0x0256, 0x8003,
-	0x8004, 0x0001, 0x0253, 0x0001, 0x0000, 0x15ca, 0x0003, 0x025a,
-	0x025d, 0x0262, 0x0001, 0x0000, 0x15ce, 0x0003, 0x0000, 0x15d4,
-	0x15df, 0x15ea, 0x0002, 0x0265, 0x0268, 0x0001, 0x0000, 0x15f5,
-	0x0001, 0x0000, 0x15fc, 0x0002, 0x0003, 0x00c7, 0x0009, 0x000d,
-	0x001b, 0x0000, 0x0000, 0x0000, 0x005d, 0x0064, 0x00ab, 0x00b9,
-	0x0003, 0x0000, 0x0011, 0x0018, 0x0001, 0x0013, 0x0001, 0x0015,
+	0xffff, 0x06cf, 0x06d1, 0x06d3, 0x06d5, 0x06d7, 0x06d9, 0x06db,
+	0x06dd, 0x06df, 0x06e1, 0x06e4, 0x06e7, 0x0003, 0x0251, 0x8000,
+	0x8000, 0x0001, 0x0253, 0x0001, 0x0000, 0x14c8, 0x0001, 0x0000,
+	0x14cb, 0x0006, 0x0260, 0x8000, 0x8001, 0x0265, 0x8003, 0x8004,
+	0x0001, 0x0262, 0x0001, 0x0000, 0x15ca, 0x0003, 0x0269, 0x026c,
+	0x0271, 0x0001, 0x0000, 0x15ce, 0x0003, 0x0000, 0x15d4, 0x15df,
+	0x15ea, 0x0002, 0x0274, 0x0277, 0x0001, 0x0000, 0x15f5, 0x0001,
+	0x0000, 0x15fc, 0x0002, 0x0003, 0x00cc, 0x0009, 0x000d, 0x001b,
 	// Entry 280 - 2BF
-	0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x1603, 0x0004, 0x0020,
-	0x0000, 0x005a, 0x0042, 0x0001, 0x0022, 0x0003, 0x0026, 0x0000,
-	0x0034, 0x000c, 0x0000, 0x1702, 0x1706, 0x170a, 0x170e, 0x1712,
-	0x1716, 0x171a, 0x171e, 0x1722, 0x1726, 0x172b, 0x1730, 0x000c,
-	0x0000, 0x1735, 0x1741, 0x174e, 0x175a, 0x1767, 0x1773, 0x177f,
-	0x178d, 0x179a, 0x17a6, 0x17b2, 0x17c1, 0x0005, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0048, 0x0001, 0x004a, 0x0001, 0x004c, 0x000c,
-	0x0000, 0x17cf, 0x17d3, 0x17d6, 0x17dc, 0x17e3, 0x17ea, 0x17f0,
+	0x0000, 0x0000, 0x0000, 0x0060, 0x0067, 0x00b0, 0x00be, 0x0003,
+	0x0000, 0x0011, 0x0018, 0x0001, 0x0013, 0x0001, 0x0015, 0x0001,
+	0x0000, 0x0000, 0x0001, 0x0000, 0x1603, 0x0004, 0x0020, 0x0000,
+	0x005d, 0x0044, 0x0001, 0x0022, 0x0003, 0x0026, 0x0000, 0x0035,
+	0x000d, 0x0000, 0xffff, 0x1702, 0x1706, 0x170a, 0x170e, 0x1712,
+	0x1716, 0x171a, 0x171e, 0x1722, 0x1726, 0x172b, 0x1730, 0x000d,
+	0x0000, 0xffff, 0x1735, 0x1741, 0x174e, 0x175a, 0x1767, 0x1773,
+	0x177f, 0x178d, 0x179a, 0x17a6, 0x17b2, 0x17c1, 0x0005, 0x0000,
 	// Entry 2C0 - 2FF
-	0x17f6, 0x17fb, 0x1802, 0x180a, 0x180e, 0x0001, 0x0000, 0x1812,
-	0x0003, 0x0000, 0x0000, 0x0061, 0x0001, 0x0000, 0x1911, 0x0003,
-	0x0068, 0x008e, 0x00a8, 0x0002, 0x006b, 0x007d, 0x0003, 0x0000,
-	0x0000, 0x006f, 0x000c, 0x0000, 0x1a10, 0x1a19, 0x1a22, 0x1a2b,
-	0x1a34, 0x1a3d, 0x1a46, 0x1a4f, 0x1a58, 0x1a61, 0x1a6b, 0x1a75,
-	0x0002, 0x0000, 0x0080, 0x000c, 0x0000, 0x1a7f, 0x1a8a, 0x1a95,
-	0x1aa0, 0x1aab, 0x1ab6, 0xffff, 0x1ac1, 0x1acc, 0x1ad7, 0x1ae3,
-	0x1aef, 0x0003, 0x009d, 0x0000, 0x0092, 0x0002, 0x0095, 0x0099,
+	0x0000, 0x0000, 0x0000, 0x004a, 0x0001, 0x004c, 0x0001, 0x004e,
+	0x000d, 0x0000, 0xffff, 0x17cf, 0x17d3, 0x17d6, 0x17dc, 0x17e3,
+	0x17ea, 0x17f0, 0x17f6, 0x17fb, 0x1802, 0x180a, 0x180e, 0x0001,
+	0x0000, 0x1812, 0x0003, 0x0000, 0x0000, 0x0064, 0x0001, 0x0000,
+	0x1911, 0x0003, 0x006b, 0x0093, 0x00ad, 0x0002, 0x006e, 0x0081,
+	0x0003, 0x0000, 0x0000, 0x0072, 0x000d, 0x0000, 0xffff, 0x1a10,
+	0x1a19, 0x1a22, 0x1a2b, 0x1a34, 0x1a3d, 0x1a46, 0x1a4f, 0x1a58,
+	0x1a61, 0x1a6b, 0x1a75, 0x0002, 0x0000, 0x0084, 0x000d, 0x0000,
 	// Entry 300 - 33F
-	0x0002, 0x0000, 0x1afb, 0x1b1b, 0x0002, 0x0000, 0x1b09, 0x1b27,
-	0x0002, 0x00a0, 0x00a4, 0x0002, 0x0000, 0x1b32, 0x1b35, 0x0002,
-	0x0000, 0x0c3a, 0x0c3e, 0x0001, 0x0000, 0x1b38, 0x0003, 0x0000,
-	0x00af, 0x00b6, 0x0001, 0x00b1, 0x0001, 0x00b3, 0x0001, 0x0000,
-	0x0d96, 0x0001, 0x0000, 0x1c37, 0x0003, 0x0000, 0x00bd, 0x00c4,
-	0x0001, 0x00bf, 0x0001, 0x00c1, 0x0001, 0x0000, 0x0f76, 0x0001,
-	0x0000, 0x1d36, 0x0005, 0x00cd, 0x0000, 0x0000, 0x00d2, 0x00e9,
-	0x0001, 0x00cf, 0x0001, 0x0000, 0x1e35, 0x0003, 0x00d6, 0x00d9,
+	0xffff, 0x1a7f, 0x1a8a, 0x1a95, 0x1aa0, 0x1aab, 0x1ab6, 0xffff,
+	0x1ac1, 0x1acc, 0x1ad7, 0x1ae3, 0x1aef, 0x0003, 0x00a2, 0x0000,
+	0x0097, 0x0002, 0x009a, 0x009e, 0x0002, 0x0000, 0x1afb, 0x1b1b,
+	0x0002, 0x0000, 0x1b09, 0x1b27, 0x0002, 0x00a5, 0x00a9, 0x0002,
+	0x0000, 0x1b32, 0x1b35, 0x0002, 0x0000, 0x0c3a, 0x0c3e, 0x0001,
+	0x0000, 0x1b38, 0x0003, 0x0000, 0x00b4, 0x00bb, 0x0001, 0x00b6,
+	0x0001, 0x00b8, 0x0001, 0x0000, 0x0d96, 0x0001, 0x0000, 0x1c37,
+	0x0003, 0x0000, 0x00c2, 0x00c9, 0x0001, 0x00c4, 0x0001, 0x00c6,
 	// Entry 340 - 37F
-	0x00de, 0x0001, 0x0000, 0x1e39, 0x0003, 0x0000, 0x15d4, 0x15df,
-	0x15ea, 0x0002, 0x00e1, 0x00e5, 0x0002, 0x0000, 0x1e49, 0x1e3f,
-	0x0002, 0x0000, 0x1e60, 0x1e55, 0x0003, 0x00ed, 0x00f0, 0x00f5,
-	0x0001, 0x0000, 0x1e6d, 0x0003, 0x0000, 0x1e71, 0x1e7a, 0x1e83,
-	0x0002, 0x00f8, 0x00fc, 0x0002, 0x0000, 0x1e9b, 0x1e8c, 0x0002,
-	0x0000, 0x1ebc, 0x1eac, 0x0002, 0x0003, 0x0032, 0x0007, 0x0000,
-	0x000b, 0x0000, 0x0000, 0x0000, 0x0024, 0x002b, 0x0003, 0x000f,
-	0x0000, 0x0021, 0x0001, 0x0011, 0x0001, 0x0013, 0x000c, 0x0000,
+	0x0001, 0x0000, 0x0f76, 0x0001, 0x0000, 0x1d36, 0x0005, 0x00d2,
+	0x0000, 0x0000, 0x00d7, 0x00ee, 0x0001, 0x00d4, 0x0001, 0x0000,
+	0x1e35, 0x0003, 0x00db, 0x00de, 0x00e3, 0x0001, 0x0000, 0x1e39,
+	0x0003, 0x0000, 0x15d4, 0x15df, 0x15ea, 0x0002, 0x00e6, 0x00ea,
+	0x0002, 0x0000, 0x1e49, 0x1e3f, 0x0002, 0x0000, 0x1e60, 0x1e55,
+	0x0003, 0x00f2, 0x00f5, 0x00fa, 0x0001, 0x0000, 0x1e6d, 0x0003,
+	0x0000, 0x1e71, 0x1e7a, 0x1e83, 0x0002, 0x00fd, 0x0101, 0x0002,
+	0x0000, 0x1e9b, 0x1e8c, 0x0002, 0x0000, 0x1ebc, 0x1eac, 0x0002,
 	// Entry 380 - 3BF
-	0x1ece, 0x1ed9, 0x1ee4, 0x1eef, 0x1efa, 0x1f05, 0x1f10, 0x1f1b,
-	0x1f26, 0x1f31, 0x1f3d, 0x1f49, 0x0001, 0x0001, 0x0000, 0x0003,
-	0x0000, 0x0000, 0x0028, 0x0001, 0x0001, 0x00ff, 0x0003, 0x0000,
-	0x0000, 0x002f, 0x0001, 0x0001, 0x01fe, 0x0006, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0039, 0x004a, 0x0003, 0x003d, 0x0000, 0x0040,
-	0x0001, 0x0001, 0x02fd, 0x0002, 0x0043, 0x0047, 0x0002, 0x0001,
-	0x0310, 0x0300, 0x0001, 0x0001, 0x0322, 0x0003, 0x004e, 0x0000,
-	0x0051, 0x0001, 0x0001, 0x02fd, 0x0002, 0x0054, 0x0059, 0x0003,
+	0x0003, 0x0033, 0x0007, 0x0000, 0x000b, 0x0000, 0x0000, 0x0000,
+	0x0025, 0x002c, 0x0003, 0x000f, 0x0000, 0x0022, 0x0001, 0x0011,
+	0x0001, 0x0013, 0x000d, 0x0000, 0xffff, 0x1ece, 0x1ed9, 0x1ee4,
+	0x1eef, 0x1efa, 0x1f05, 0x1f10, 0x1f1b, 0x1f26, 0x1f31, 0x1f3d,
+	0x1f49, 0x0001, 0x0001, 0x0000, 0x0003, 0x0000, 0x0000, 0x0029,
+	0x0001, 0x0001, 0x00ff, 0x0003, 0x0000, 0x0000, 0x0030, 0x0001,
+	0x0001, 0x01fe, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x003a,
+	0x004b, 0x0003, 0x003e, 0x0000, 0x0041, 0x0001, 0x0001, 0x02fd,
 	// Entry 3C0 - 3FF
-	0x0001, 0x0357, 0x0335, 0x0346, 0x0002, 0x0001, 0x037c, 0x036a,
-	0x0001, 0x0002, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x000c, 0x0000, 0x0047, 0x0003, 0x0010, 0x0000, 0x0044,
-	0x0002, 0x0013, 0x0033, 0x0003, 0x0017, 0x0000, 0x0025, 0x000c,
-	0x0001, 0x0390, 0x0399, 0x03a2, 0x03ab, 0x03b4, 0x03bd, 0x03c6,
-	0x03cf, 0x03d8, 0x03e1, 0x03eb, 0x03f5, 0x000c, 0x0001, 0x03ff,
-	0x0408, 0x0411, 0x041a, 0x0423, 0x042c, 0x0435, 0x043e, 0x0447,
-	0x0450, 0x045a, 0x0464, 0x0002, 0x0000, 0x0036, 0x000c, 0x0001,
+	0x0002, 0x0044, 0x0048, 0x0002, 0x0001, 0x0310, 0x0300, 0x0001,
+	0x0001, 0x0322, 0x0003, 0x004f, 0x0000, 0x0052, 0x0001, 0x0001,
+	0x02fd, 0x0002, 0x0055, 0x005a, 0x0003, 0x0001, 0x0357, 0x0335,
+	0x0346, 0x0002, 0x0001, 0x037c, 0x036a, 0x0001, 0x0002, 0x0009,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x0000,
+	0x004a, 0x0003, 0x0010, 0x0000, 0x0047, 0x0002, 0x0013, 0x0035,
+	0x0003, 0x0017, 0x0000, 0x0026, 0x000d, 0x0001, 0xffff, 0x0390,
+	0x0399, 0x03a2, 0x03ab, 0x03b4, 0x03bd, 0x03c6, 0x03cf, 0x03d8,
 	// Entry 400 - 43F
+	0x03e1, 0x03eb, 0x03f5, 0x000d, 0x0001, 0xffff, 0x03ff, 0x0408,
+	0x0411, 0x041a, 0x0423, 0x042c, 0x0435, 0x043e, 0x0447, 0x0450,
+	0x045a, 0x0464, 0x0002, 0x0000, 0x0038, 0x000d, 0x0001, 0xffff,
 	0x046e, 0x0479, 0x0484, 0xffff, 0x048f, 0x049a, 0xffff, 0x04a5,
 	0x04b0, 0x04bb, 0x04c7, 0x04d3, 0x0001, 0x0001, 0x04df, 0x0003,
-	0x0000, 0x0000, 0x004b, 0x0001, 0x0001, 0x05de,
+	0x0000, 0x0000, 0x004e, 0x0001, 0x0001, 0x05de,
 } // Size: xxxx bytes
 
 var buckets = []string{
@@ -770,4 +830,57 @@
 	"\xf3?ݔ7\x84\xb2b\x0c4\x81\x17\xf2K@\xde\x18\x99Q\x17n\xe5?\xdao\xc6(\xfc" +
 	"\x9b\xees\xc6V\x91\x0dْ\x1d\x06g9o"
 
-	// Total table size: xxxx bytes (14KiB); checksum: C44173A9
+var enumMap = map[string]uint16{
+	"":                    0,
+	"calendars":           0,
+	"fields":              1,
+	"buddhist":            0,
+	"chinese":             1,
+	"dangi":               2,
+	"ethiopic":            3,
+	"ethiopic-amete-alem": 4,
+	"generic":             5,
+	"gregorian":           6,
+	"hebrew":              7,
+	"islamic":             8,
+	"islamic-civil":       9,
+	"islamic-rgsa":        10,
+	"islamic-tbla":        11,
+	"islamic-umalqura":    12,
+	"persian":             13,
+	"months":              0,
+	"eras":                1,
+	"filler":              2,
+	"cyclicNameSets":      3,
+	"format":              0,
+	"stand-alone":         1,
+	"wAbbreviated":        0,
+	"wNarrow":             1,
+	"wWide":               2,
+	"leap7":               0,
+	"variant":             1,
+	"cycDayParts":         0,
+	"cycDays":             1,
+	"cycMonths":           2,
+	"cycYears":            3,
+	"cycZodiacs":          4,
+	"era":                 0,
+	"era-short":           1,
+	"era-narrow":          2,
+	"month":               3,
+	"month-short":         4,
+	"month-narrow":        5,
+	"displayName":         0,
+	"relative":            1,
+	"relativeTime":        2,
+	"before1":             0,
+	"current":             1,
+	"after1":              2,
+	"future":              0,
+	"past":                1,
+	"other":               0,
+	"one":                 1,
+	"two":                 2,
+}
+
+// Total table size: xxxx bytes (14KiB); checksum: FE165D0A
diff --git a/internal/cldrtree/type.go b/internal/cldrtree/type.go
index a7897c6..65f9b46 100644
--- a/internal/cldrtree/type.go
+++ b/internal/cldrtree/type.go
@@ -4,6 +4,11 @@
 
 package cldrtree
 
+import (
+	"log"
+	"strconv"
+)
+
 // enumIndex is the numerical value of an enum value.
 type enumIndex int
 
@@ -26,6 +31,20 @@
 		if e.keyMap == nil {
 			e.keyMap = map[string]enumIndex{}
 		}
+		u, err := strconv.ParseUint(s, 10, 32)
+		if err == nil {
+			for len(e.keys) <= int(u) {
+				x := enumIndex(len(e.keys))
+				s := strconv.Itoa(int(x))
+				e.keyMap[s] = x
+				e.keys = append(e.keys, s)
+			}
+			if e.keyMap[s] != enumIndex(u) {
+				// TODO: handle more gracefully.
+				log.Fatalf("cldrtree: mix of integer and non-integer for %q %v", s, e.keys)
+			}
+			return enumIndex(u)
+		}
 		x = enumIndex(len(e.keys))
 		e.keyMap[s] = x
 		e.keys = append(e.keys, s)