aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/text/feature
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/feature')
-rw-r--r--vendor/golang.org/x/text/feature/plural/common.go70
-rw-r--r--vendor/golang.org/x/text/feature/plural/data_test.go190
-rw-r--r--vendor/golang.org/x/text/feature/plural/example_test.go46
-rw-r--r--vendor/golang.org/x/text/feature/plural/gen.go513
-rw-r--r--vendor/golang.org/x/text/feature/plural/gen_common.go74
-rwxr-xr-xvendor/golang.org/x/text/feature/plural/message.go244
-rw-r--r--vendor/golang.org/x/text/feature/plural/message_test.go197
-rw-r--r--vendor/golang.org/x/text/feature/plural/plural.go258
-rw-r--r--vendor/golang.org/x/text/feature/plural/plural_test.go216
-rw-r--r--vendor/golang.org/x/text/feature/plural/tables.go540
10 files changed, 2348 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/feature/plural/common.go b/vendor/golang.org/x/text/feature/plural/common.go
new file mode 100644
index 0000000..fdcb373
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/common.go
@@ -0,0 +1,70 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package plural
+
+// Form defines a plural form.
+//
+// Not all languages support all forms. Also, the meaning of each form varies
+// per language. It is important to note that the name of a form does not
+// necessarily correspond one-to-one with the set of numbers. For instance,
+// for Croation, One matches not only 1, but also 11, 21, etc.
+//
+// Each language must at least support the form "other".
+type Form byte
+
+const (
+ Other Form = iota
+ Zero
+ One
+ Two
+ Few
+ Many
+)
+
+var countMap = map[string]Form{
+ "other": Other,
+ "zero": Zero,
+ "one": One,
+ "two": Two,
+ "few": Few,
+ "many": Many,
+}
+
+type pluralCheck struct {
+ // category:
+ // 3..7: opID
+ // 0..2: category
+ cat byte
+ setID byte
+}
+
+// opID identifies the type of operand in the plural rule, being i, n or f.
+// (v, w, and t are treated as filters in our implementation.)
+type opID byte
+
+const (
+ opMod opID = 0x1 // is '%' used?
+ opNotEqual opID = 0x2 // using "!=" to compare
+ opI opID = 0 << 2 // integers after taking the absolute value
+ opN opID = 1 << 2 // full number (must be integer)
+ opF opID = 2 << 2 // fraction
+ opV opID = 3 << 2 // number of visible digits
+ opW opID = 4 << 2 // number of visible digits without trailing zeros
+ opBretonM opID = 5 << 2 // hard-wired rule for Breton
+ opItalian800 opID = 6 << 2 // hard-wired rule for Italian
+ opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
+)
+const (
+ // Use this plural form to indicate the next rule needs to match as well.
+ // The last condition in the list will have the correct plural form.
+ andNext = 0x7
+ formMask = 0x7
+
+ opShift = 3
+
+ // numN indicates the maximum integer, or maximum mod value, for which we
+ // have inclusion masks.
+ numN = 100
+ // The common denominator of the modulo that is taken.
+ maxMod = 100
+)
diff --git a/vendor/golang.org/x/text/feature/plural/data_test.go b/vendor/golang.org/x/text/feature/plural/data_test.go
new file mode 100644
index 0000000..8cffbbe
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/data_test.go
@@ -0,0 +1,190 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package plural
+
+type pluralTest struct {
+ locales string
+ form int
+ integer []string
+ decimal []string
+}
+
+var ordinalTests = []pluralTest{ // 59 elements
+ 0: {locales: "af am ar bg bs ce cs da de dsb el es et eu fa fi fy gl gsw he hr hsb id in is iw ja km kn ko ky lt lv ml mn my nb nl pa pl prg pt root ru sh si sk sl sr sw ta te th tr ur uz yue zh zu", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 1: {locales: "sv", form: 2, integer: []string{"1", "2", "21", "22", "31", "32", "41", "42", "51", "52", "61", "62", "71", "72", "81", "82", "101", "1001"}, decimal: []string(nil)},
+ 2: {locales: "sv", form: 0, integer: []string{"0", "3~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 3: {locales: "fil fr ga hy lo mo ms ro tl vi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 4: {locales: "fil fr ga hy lo mo ms ro tl vi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 5: {locales: "hu", form: 2, integer: []string{"1", "5"}, decimal: []string(nil)},
+ 6: {locales: "hu", form: 0, integer: []string{"0", "2~4", "6~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 7: {locales: "ne", form: 2, integer: []string{"1~4"}, decimal: []string(nil)},
+ 8: {locales: "ne", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 9: {locales: "be", form: 4, integer: []string{"2", "3", "22", "23", "32", "33", "42", "43", "52", "53", "62", "63", "72", "73", "82", "83", "102", "1002"}, decimal: []string(nil)},
+ 10: {locales: "be", form: 0, integer: []string{"0", "1", "4~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 11: {locales: "uk", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
+ 12: {locales: "uk", form: 0, integer: []string{"0~2", "4~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 13: {locales: "kk", form: 5, integer: []string{"6", "9", "10", "16", "19", "20", "26", "29", "30", "36", "39", "40", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 14: {locales: "kk", form: 0, integer: []string{"0~5", "7", "8", "11~15", "17", "18", "21", "101", "1001"}, decimal: []string(nil)},
+ 15: {locales: "it", form: 5, integer: []string{"8", "11", "80", "800"}, decimal: []string(nil)},
+ 16: {locales: "it", form: 0, integer: []string{"0~7", "9", "10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 17: {locales: "ka", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 18: {locales: "ka", form: 5, integer: []string{"0", "2~16", "102", "1002"}, decimal: []string(nil)},
+ 19: {locales: "ka", form: 0, integer: []string{"21~36", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 20: {locales: "sq", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 21: {locales: "sq", form: 5, integer: []string{"4", "24", "34", "44", "54", "64", "74", "84", "104", "1004"}, decimal: []string(nil)},
+ 22: {locales: "sq", form: 0, integer: []string{"0", "2", "3", "5~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 23: {locales: "en", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
+ 24: {locales: "en", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
+ 25: {locales: "en", form: 4, integer: []string{"3", "23", "33", "43", "53", "63", "73", "83", "103", "1003"}, decimal: []string(nil)},
+ 26: {locales: "en", form: 0, integer: []string{"0", "4~18", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 27: {locales: "mr", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 28: {locales: "mr", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
+ 29: {locales: "mr", form: 4, integer: []string{"4"}, decimal: []string(nil)},
+ 30: {locales: "mr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 31: {locales: "ca", form: 2, integer: []string{"1", "3"}, decimal: []string(nil)},
+ 32: {locales: "ca", form: 3, integer: []string{"2"}, decimal: []string(nil)},
+ 33: {locales: "ca", form: 4, integer: []string{"4"}, decimal: []string(nil)},
+ 34: {locales: "ca", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 35: {locales: "mk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
+ 36: {locales: "mk", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "72", "82", "102", "1002"}, decimal: []string(nil)},
+ 37: {locales: "mk", form: 5, integer: []string{"7", "8", "27", "28", "37", "38", "47", "48", "57", "58", "67", "68", "77", "78", "87", "88", "107", "1007"}, decimal: []string(nil)},
+ 38: {locales: "mk", form: 0, integer: []string{"0", "3~6", "9~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 39: {locales: "az", form: 2, integer: []string{"1", "2", "5", "7", "8", "11", "12", "15", "17", "18", "20~22", "25", "101", "1001"}, decimal: []string(nil)},
+ 40: {locales: "az", form: 4, integer: []string{"3", "4", "13", "14", "23", "24", "33", "34", "43", "44", "53", "54", "63", "64", "73", "74", "100", "1003"}, decimal: []string(nil)},
+ 41: {locales: "az", form: 5, integer: []string{"0", "6", "16", "26", "36", "40", "46", "56", "106", "1006"}, decimal: []string(nil)},
+ 42: {locales: "az", form: 0, integer: []string{"9", "10", "19", "29", "30", "39", "49", "59", "69", "79", "109", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 43: {locales: "gu hi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 44: {locales: "gu hi", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
+ 45: {locales: "gu hi", form: 4, integer: []string{"4"}, decimal: []string(nil)},
+ 46: {locales: "gu hi", form: 5, integer: []string{"6"}, decimal: []string(nil)},
+ 47: {locales: "gu hi", form: 0, integer: []string{"0", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 48: {locales: "as bn", form: 2, integer: []string{"1", "5", "7~10"}, decimal: []string(nil)},
+ 49: {locales: "as bn", form: 3, integer: []string{"2", "3"}, decimal: []string(nil)},
+ 50: {locales: "as bn", form: 4, integer: []string{"4"}, decimal: []string(nil)},
+ 51: {locales: "as bn", form: 5, integer: []string{"6"}, decimal: []string(nil)},
+ 52: {locales: "as bn", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 53: {locales: "cy", form: 1, integer: []string{"0", "7~9"}, decimal: []string(nil)},
+ 54: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 55: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string(nil)},
+ 56: {locales: "cy", form: 4, integer: []string{"3", "4"}, decimal: []string(nil)},
+ 57: {locales: "cy", form: 5, integer: []string{"5", "6"}, decimal: []string(nil)},
+ 58: {locales: "cy", form: 0, integer: []string{"10~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+} // Size: 4272 bytes
+
+var cardinalTests = []pluralTest{ // 113 elements
+ 0: {locales: "bm bo dz id ig ii in ja jbo jv jw kde kea km ko lkt lo ms my nqo root sah ses sg th to vi wo yo yue zh", form: 0, integer: []string{"0~15", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 1: {locales: "am as bn fa gu hi kn mr zu", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.0", "0.00~0.04"}},
+ 2: {locales: "am as bn fa gu hi kn mr zu", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"1.1~2.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 3: {locales: "ff fr hy kab", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.5"}},
+ 4: {locales: "ff fr hy kab", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 5: {locales: "pt", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.5"}},
+ 6: {locales: "pt", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 7: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 8: {locales: "ast ca de en et fi fy gl it ji nl sv sw ur yi", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 9: {locales: "si", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "0.1", "1.0", "0.00", "0.01", "1.00", "0.000", "0.001", "1.000", "0.0000", "0.0001", "1.0000"}},
+ 10: {locales: "si", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.2~0.9", "1.1~1.8", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 11: {locales: "ak bh guw ln mg nso pa ti wa", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0", "1.0", "0.00", "1.00", "0.000", "1.000", "0.0000", "1.0000"}},
+ 12: {locales: "ak bh guw ln mg nso pa ti wa", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 13: {locales: "tzm", form: 2, integer: []string{"0", "1", "11~24"}, decimal: []string{"0.0", "1.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "19.0", "20.0", "21.0", "22.0", "23.0", "24.0"}},
+ 14: {locales: "tzm", form: 0, integer: []string{"2~10", "100~106", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 15: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 16: {locales: "af asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 17: {locales: "da", form: 2, integer: []string{"1"}, decimal: []string{"0.1~1.6"}},
+ 18: {locales: "da", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "2.0~3.4", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 19: {locales: "is", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1~1.6", "10.1", "100.1", "1000.1"}},
+ 20: {locales: "is", form: 0, integer: []string{"0", "2~16", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 21: {locales: "mk", form: 2, integer: []string{"1", "11", "21", "31", "41", "51", "61", "71", "101", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
+ 22: {locales: "mk", form: 0, integer: []string{"0", "2~10", "12~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.2~1.0", "1.2~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 23: {locales: "fil tl", form: 2, integer: []string{"0~3", "5", "7", "8", "10~13", "15", "17", "18", "20", "21", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.3", "0.5", "0.7", "0.8", "1.0~1.3", "1.5", "1.7", "1.8", "2.0", "2.1", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 24: {locales: "fil tl", form: 0, integer: []string{"4", "6", "9", "14", "16", "19", "24", "26", "104", "1004"}, decimal: []string{"0.4", "0.6", "0.9", "1.4", "1.6", "1.9", "2.4", "2.6", "10.4", "100.4", "1000.4"}},
+ 25: {locales: "lv prg", form: 1, integer: []string{"0", "10~20", "30", "40", "50", "60", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 26: {locales: "lv prg", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1", "1.0", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
+ 27: {locales: "lv prg", form: 0, integer: []string{"2~9", "22~29", "102", "1002"}, decimal: []string{"0.2~0.9", "1.2~1.9", "10.2", "100.2", "1000.2"}},
+ 28: {locales: "lag", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
+ 29: {locales: "lag", form: 2, integer: []string{"1"}, decimal: []string{"0.1~1.6"}},
+ 30: {locales: "lag", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"2.0~3.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 31: {locales: "ksh", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
+ 32: {locales: "ksh", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 33: {locales: "ksh", form: 0, integer: []string{"2~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 34: {locales: "iu kw naq se sma smi smj smn sms", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 35: {locales: "iu kw naq se sma smi smj smn sms", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
+ 36: {locales: "iu kw naq se sma smi smj smn sms", form: 0, integer: []string{"0", "3~17", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 37: {locales: "shi", form: 2, integer: []string{"0", "1"}, decimal: []string{"0.0~1.0", "0.00~0.04"}},
+ 38: {locales: "shi", form: 4, integer: []string{"2~10"}, decimal: []string{"2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "2.00", "3.00", "4.00", "5.00", "6.00", "7.00", "8.00"}},
+ 39: {locales: "shi", form: 0, integer: []string{"11~26", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"1.1~1.9", "2.1~2.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 40: {locales: "mo ro", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 41: {locales: "mo ro", form: 4, integer: []string{"0", "2~16", "101", "1001"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 42: {locales: "mo ro", form: 0, integer: []string{"20~35", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 43: {locales: "bs hr sh sr", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
+ 44: {locales: "bs hr sh sr", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string{"0.2~0.4", "1.2~1.4", "2.2~2.4", "3.2~3.4", "4.2~4.4", "5.2", "10.2", "100.2", "1000.2"}},
+ 45: {locales: "bs hr sh sr", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.5~1.0", "1.5~2.0", "2.5~2.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 46: {locales: "gd", form: 2, integer: []string{"1", "11"}, decimal: []string{"1.0", "11.0", "1.00", "11.00", "1.000", "11.000", "1.0000"}},
+ 47: {locales: "gd", form: 3, integer: []string{"2", "12"}, decimal: []string{"2.0", "12.0", "2.00", "12.00", "2.000", "12.000", "2.0000"}},
+ 48: {locales: "gd", form: 4, integer: []string{"3~10", "13~19"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "19.0", "3.00"}},
+ 49: {locales: "gd", form: 0, integer: []string{"0", "20~34", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 50: {locales: "sl", form: 2, integer: []string{"1", "101", "201", "301", "401", "501", "601", "701", "1001"}, decimal: []string(nil)},
+ 51: {locales: "sl", form: 3, integer: []string{"2", "102", "202", "302", "402", "502", "602", "702", "1002"}, decimal: []string(nil)},
+ 52: {locales: "sl", form: 4, integer: []string{"3", "4", "103", "104", "203", "204", "303", "304", "403", "404", "503", "504", "603", "604", "703", "704", "1003"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 53: {locales: "sl", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 54: {locales: "dsb hsb", form: 2, integer: []string{"1", "101", "201", "301", "401", "501", "601", "701", "1001"}, decimal: []string{"0.1", "1.1", "2.1", "3.1", "4.1", "5.1", "6.1", "7.1", "10.1", "100.1", "1000.1"}},
+ 55: {locales: "dsb hsb", form: 3, integer: []string{"2", "102", "202", "302", "402", "502", "602", "702", "1002"}, decimal: []string{"0.2", "1.2", "2.2", "3.2", "4.2", "5.2", "6.2", "7.2", "10.2", "100.2", "1000.2"}},
+ 56: {locales: "dsb hsb", form: 4, integer: []string{"3", "4", "103", "104", "203", "204", "303", "304", "403", "404", "503", "504", "603", "604", "703", "704", "1003"}, decimal: []string{"0.3", "0.4", "1.3", "1.4", "2.3", "2.4", "3.3", "3.4", "4.3", "4.4", "5.3", "5.4", "6.3", "6.4", "7.3", "7.4", "10.3", "100.3", "1000.3"}},
+ 57: {locales: "dsb hsb", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "0.5~1.0", "1.5~2.0", "2.5~2.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 58: {locales: "he iw", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 59: {locales: "he iw", form: 3, integer: []string{"2"}, decimal: []string(nil)},
+ 60: {locales: "he iw", form: 5, integer: []string{"20", "30", "40", "50", "60", "70", "80", "90", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 61: {locales: "he iw", form: 0, integer: []string{"0", "3~17", "101", "1001"}, decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 62: {locales: "cs sk", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 63: {locales: "cs sk", form: 4, integer: []string{"2~4"}, decimal: []string(nil)},
+ 64: {locales: "cs sk", form: 5, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 65: {locales: "cs sk", form: 0, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 66: {locales: "pl", form: 2, integer: []string{"1"}, decimal: []string(nil)},
+ 67: {locales: "pl", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string(nil)},
+ 68: {locales: "pl", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 69: {locales: "pl", form: 0, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 70: {locales: "be", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "71.0", "81.0", "101.0", "1001.0"}},
+ 71: {locales: "be", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string{"2.0", "3.0", "4.0", "22.0", "23.0", "24.0", "32.0", "33.0", "102.0", "1002.0"}},
+ 72: {locales: "be", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "11.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 73: {locales: "be", form: 0, integer: []string(nil), decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.1", "1000.1"}},
+ 74: {locales: "lt", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "71.0", "81.0", "101.0", "1001.0"}},
+ 75: {locales: "lt", form: 4, integer: []string{"2~9", "22~29", "102", "1002"}, decimal: []string{"2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "22.0", "102.0", "1002.0"}},
+ 76: {locales: "lt", form: 5, integer: []string(nil), decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.1", "1000.1"}},
+ 77: {locales: "lt", form: 0, integer: []string{"0", "10~20", "30", "40", "50", "60", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 78: {locales: "mt", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 79: {locales: "mt", form: 4, integer: []string{"0", "2~10", "102~107", "1002"}, decimal: []string{"0.0", "2.0", "3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "10.0", "102.0", "1002.0"}},
+ 80: {locales: "mt", form: 5, integer: []string{"11~19", "111~117", "1011"}, decimal: []string{"11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "111.0", "1011.0"}},
+ 81: {locales: "mt", form: 0, integer: []string{"20~35", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 82: {locales: "ru uk", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "71", "81", "101", "1001"}, decimal: []string(nil)},
+ 83: {locales: "ru uk", form: 4, integer: []string{"2~4", "22~24", "32~34", "42~44", "52~54", "62", "102", "1002"}, decimal: []string(nil)},
+ 84: {locales: "ru uk", form: 5, integer: []string{"0", "5~19", "100", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 85: {locales: "ru uk", form: 0, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 86: {locales: "br", form: 2, integer: []string{"1", "21", "31", "41", "51", "61", "81", "101", "1001"}, decimal: []string{"1.0", "21.0", "31.0", "41.0", "51.0", "61.0", "81.0", "101.0", "1001.0"}},
+ 87: {locales: "br", form: 3, integer: []string{"2", "22", "32", "42", "52", "62", "82", "102", "1002"}, decimal: []string{"2.0", "22.0", "32.0", "42.0", "52.0", "62.0", "82.0", "102.0", "1002.0"}},
+ 88: {locales: "br", form: 4, integer: []string{"3", "4", "9", "23", "24", "29", "33", "34", "39", "43", "44", "49", "103", "1003"}, decimal: []string{"3.0", "4.0", "9.0", "23.0", "24.0", "29.0", "33.0", "34.0", "103.0", "1003.0"}},
+ 89: {locales: "br", form: 5, integer: []string{"1000000"}, decimal: []string{"1000000.0", "1000000.00", "1000000.000"}},
+ 90: {locales: "br", form: 0, integer: []string{"0", "5~8", "10~20", "100", "1000", "10000", "100000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.0", "100.0", "1000.0", "10000.0", "100000.0"}},
+ 91: {locales: "ga", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 92: {locales: "ga", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
+ 93: {locales: "ga", form: 4, integer: []string{"3~6"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "3.00", "4.00", "5.00", "6.00", "3.000", "4.000", "5.000", "6.000", "3.0000", "4.0000", "5.0000", "6.0000"}},
+ 94: {locales: "ga", form: 5, integer: []string{"7~10"}, decimal: []string{"7.0", "8.0", "9.0", "10.0", "7.00", "8.00", "9.00", "10.00", "7.000", "8.000", "9.000", "10.000", "7.0000", "8.0000", "9.0000", "10.0000"}},
+ 95: {locales: "ga", form: 0, integer: []string{"0", "11~25", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.0~0.9", "1.1~1.6", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 96: {locales: "gv", form: 2, integer: []string{"1", "11", "21", "31", "41", "51", "61", "71", "101", "1001"}, decimal: []string(nil)},
+ 97: {locales: "gv", form: 3, integer: []string{"2", "12", "22", "32", "42", "52", "62", "72", "102", "1002"}, decimal: []string(nil)},
+ 98: {locales: "gv", form: 4, integer: []string{"0", "20", "40", "60", "80", "100", "120", "140", "1000", "10000", "100000", "1000000"}, decimal: []string(nil)},
+ 99: {locales: "gv", form: 5, integer: []string(nil), decimal: []string{"0.0~1.5", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 100: {locales: "gv", form: 0, integer: []string{"3~10", "13~19", "23", "103", "1003"}, decimal: []string(nil)},
+ 101: {locales: "ar ars", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
+ 102: {locales: "ar ars", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 103: {locales: "ar ars", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
+ 104: {locales: "ar ars", form: 4, integer: []string{"3~10", "103~110", "1003"}, decimal: []string{"3.0", "4.0", "5.0", "6.0", "7.0", "8.0", "9.0", "10.0", "103.0", "1003.0"}},
+ 105: {locales: "ar ars", form: 5, integer: []string{"11~26", "111", "1011"}, decimal: []string{"11.0", "12.0", "13.0", "14.0", "15.0", "16.0", "17.0", "18.0", "111.0", "1011.0"}},
+ 106: {locales: "ar ars", form: 0, integer: []string{"100~102", "200~202", "300~302", "400~402", "500~502", "600", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.1", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+ 107: {locales: "cy", form: 1, integer: []string{"0"}, decimal: []string{"0.0", "0.00", "0.000", "0.0000"}},
+ 108: {locales: "cy", form: 2, integer: []string{"1"}, decimal: []string{"1.0", "1.00", "1.000", "1.0000"}},
+ 109: {locales: "cy", form: 3, integer: []string{"2"}, decimal: []string{"2.0", "2.00", "2.000", "2.0000"}},
+ 110: {locales: "cy", form: 4, integer: []string{"3"}, decimal: []string{"3.0", "3.00", "3.000", "3.0000"}},
+ 111: {locales: "cy", form: 5, integer: []string{"6"}, decimal: []string{"6.0", "6.00", "6.000", "6.0000"}},
+ 112: {locales: "cy", form: 0, integer: []string{"4", "5", "7~20", "100", "1000", "10000", "100000", "1000000"}, decimal: []string{"0.1~0.9", "1.1~1.7", "10.0", "100.0", "1000.0", "10000.0", "100000.0", "1000000.0"}},
+} // Size: 8160 bytes
+
+// Total table size 12432 bytes (12KiB); checksum: 166DAB71
diff --git a/vendor/golang.org/x/text/feature/plural/example_test.go b/vendor/golang.org/x/text/feature/plural/example_test.go
new file mode 100644
index 0000000..c75408c
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/example_test.go
@@ -0,0 +1,46 @@
+// Copyright 2017 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 plural_test
+
+import (
+ "golang.org/x/text/feature/plural"
+ "golang.org/x/text/language"
+ "golang.org/x/text/message"
+)
+
+func ExampleSelect() {
+ // Manually set some translations. This is typically done programmatically.
+ message.Set(language.English, "%d files remaining",
+ plural.Selectf(1, "%d",
+ "=0", "done!",
+ plural.One, "one file remaining",
+ plural.Other, "%[1]d files remaining",
+ ))
+ message.Set(language.Dutch, "%d files remaining",
+ plural.Selectf(1, "%d",
+ "=0", "klaar!",
+ // One can also use a string instead of a Kind
+ "one", "nog één bestand te gaan",
+ "other", "nog %[1]d bestanden te gaan",
+ ))
+
+ p := message.NewPrinter(language.English)
+ p.Printf("%d files remaining", 5)
+ p.Println()
+ p.Printf("%d files remaining", 1)
+ p.Println()
+
+ p = message.NewPrinter(language.Dutch)
+ p.Printf("%d files remaining", 1)
+ p.Println()
+ p.Printf("%d files remaining", 0)
+ p.Println()
+
+ // Output:
+ // 5 files remaining
+ // one file remaining
+ // nog één bestand te gaan
+ // klaar!
+}
diff --git a/vendor/golang.org/x/text/feature/plural/gen.go b/vendor/golang.org/x/text/feature/plural/gen.go
new file mode 100644
index 0000000..a0de986
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/gen.go
@@ -0,0 +1,513 @@
+// Copyright 2016 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.
+
+// +build ignore
+
+package main
+
+// This file generates data for the CLDR plural rules, as defined in
+// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules
+//
+// We assume a slightly simplified grammar:
+//
+// condition = and_condition ('or' and_condition)* samples
+// and_condition = relation ('and' relation)*
+// relation = expr ('=' | '!=') range_list
+// expr = operand ('%' '10' '0'* )?
+// operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
+// range_list = (range | value) (',' range_list)*
+// range = value'..'value
+// value = digit+
+// digit = 0|1|2|3|4|5|6|7|8|9
+//
+// samples = ('@integer' sampleList)?
+// ('@decimal' sampleList)?
+// sampleList = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
+// sampleRange = decimalValue ('~' decimalValue)?
+// decimalValue = value ('.' value)?
+//
+// Symbol Value
+// n absolute value of the source number (integer and decimals).
+// i integer digits of n.
+// v number of visible fraction digits in n, with trailing zeros.
+// w number of visible fraction digits in n, without trailing zeros.
+// f visible fractional digits in n, with trailing zeros.
+// t visible fractional digits in n, without trailing zeros.
+//
+// The algorithm for which the data is generated is based on the following
+// observations
+//
+// - the number of different sets of numbers which the plural rules use to
+// test inclusion is limited,
+// - most numbers that are tested on are < 100
+//
+// This allows us to define a bitmap for each number < 100 where a bit i
+// indicates whether this number is included in some defined set i.
+// The function matchPlural in plural.go defines how we can subsequently use
+// this data to determine inclusion.
+//
+// There are a few languages for which this doesn't work. For one Italian and
+// Azerbaijan, which both test against numbers > 100 for ordinals and Breton,
+// which considers whether numbers are multiples of hundreds. The model here
+// could be extended to handle Italian and Azerbaijan fairly easily (by
+// considering the numbers 100, 200, 300, ..., 800, 900 in addition to the first
+// 100), but for now it seems easier to just hard-code these cases.
+
+import (
+ "bufio"
+ "bytes"
+ "flag"
+ "fmt"
+ "log"
+ "strconv"
+ "strings"
+
+ "golang.org/x/text/internal"
+ "golang.org/x/text/internal/gen"
+ "golang.org/x/text/language"
+ "golang.org/x/text/unicode/cldr"
+)
+
+var (
+ test = flag.Bool("test", false,
+ "test existing tables; can be used to compare web data with package data.")
+ outputFile = flag.String("output", "tables.go", "output file")
+ outputTestFile = flag.String("testoutput", "data_test.go", "output file")
+
+ draft = flag.String("draft",
+ "contributed",
+ `Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
+)
+
+func main() {
+ gen.Init()
+
+ const pkg = "plural"
+
+ gen.Repackage("gen_common.go", "common.go", pkg)
+ // Read the CLDR zip file.
+ r := gen.OpenCLDRCoreZip()
+ defer r.Close()
+
+ d := &cldr.Decoder{}
+ d.SetDirFilter("supplemental", "main")
+ d.SetSectionFilter("numbers", "plurals")
+ data, err := d.DecodeZip(r)
+ if err != nil {
+ log.Fatalf("DecodeZip: %v", err)
+ }
+
+ w := gen.NewCodeWriter()
+ defer w.WriteGoFile(*outputFile, pkg)
+
+ gen.WriteCLDRVersion(w)
+
+ genPlurals(w, data)
+
+ w = gen.NewCodeWriter()
+ defer w.WriteGoFile(*outputTestFile, pkg)
+
+ genPluralsTests(w, data)
+}
+
+type pluralTest struct {
+ locales string // space-separated list of locales for this test
+ form int // Use int instead of Form to simplify generation.
+ integer []string // Entries of the form \d+ or \d+~\d+
+ decimal []string // Entries of the form \f+ or \f+ +~\f+, where f is \d+\.\d+
+}
+
+func genPluralsTests(w *gen.CodeWriter, data *cldr.CLDR) {
+ w.WriteType(pluralTest{})
+
+ for _, plurals := range data.Supplemental().Plurals {
+ if plurals.Type == "" {
+ // The empty type is reserved for plural ranges.
+ continue
+ }
+ tests := []pluralTest{}
+
+ for _, pRules := range plurals.PluralRules {
+ for _, rule := range pRules.PluralRule {
+ test := pluralTest{
+ locales: pRules.Locales,
+ form: int(countMap[rule.Count]),
+ }
+ scan := bufio.NewScanner(strings.NewReader(rule.Data()))
+ scan.Split(splitTokens)
+ var p *[]string
+ for scan.Scan() {
+ switch t := scan.Text(); t {
+ case "@integer":
+ p = &test.integer
+ case "@decimal":
+ p = &test.decimal
+ case ",", "…":
+ default:
+ if p != nil {
+ *p = append(*p, t)
+ }
+ }
+ }
+ tests = append(tests, test)
+ }
+ }
+ w.WriteVar(plurals.Type+"Tests", tests)
+ }
+}
+
+func genPlurals(w *gen.CodeWriter, data *cldr.CLDR) {
+ for _, plurals := range data.Supplemental().Plurals {
+ if plurals.Type == "" {
+ continue
+ }
+ // Initialize setMap and inclusionMasks. They are already populated with
+ // a few entries to serve as an example and to assign nice numbers to
+ // common cases.
+
+ // setMap contains sets of numbers represented by boolean arrays where
+ // a true value for element i means that the number i is included.
+ setMap := map[[numN]bool]int{
+ // The above init func adds an entry for including all numbers.
+ [numN]bool{1: true}: 1, // fix {1} to a nice value
+ [numN]bool{2: true}: 2, // fix {2} to a nice value
+ [numN]bool{0: true}: 3, // fix {0} to a nice value
+ }
+
+ // inclusionMasks contains bit masks for every number under numN to
+ // indicate in which set the number is included. Bit 1 << x will be set
+ // if it is included in set x.
+ inclusionMasks := [numN]uint64{
+ // Note: these entries are not complete: more bits will be set along the way.
+ 0: 1 << 3,
+ 1: 1 << 1,
+ 2: 1 << 2,
+ }
+
+ // Create set {0..99}. We will assign this set the identifier 0.
+ var all [numN]bool
+ for i := range all {
+ // Mark number i as being included in the set (which has identifier 0).
+ inclusionMasks[i] |= 1 << 0
+ // Mark number i as included in the set.
+ all[i] = true
+ }
+ // Register the identifier for the set.
+ setMap[all] = 0
+
+ rules := []pluralCheck{}
+ index := []byte{0}
+ langMap := map[int]byte{0: 0} // From compact language index to index
+
+ for _, pRules := range plurals.PluralRules {
+ // Parse the rules.
+ var conds []orCondition
+ for _, rule := range pRules.PluralRule {
+ form := countMap[rule.Count]
+ conds = parsePluralCondition(conds, rule.Data(), form)
+ }
+ // Encode the rules.
+ for _, c := range conds {
+ // If an or condition only has filters, we create an entry for
+ // this filter and the set that contains all values.
+ empty := true
+ for _, b := range c.used {
+ empty = empty && !b
+ }
+ if empty {
+ rules = append(rules, pluralCheck{
+ cat: byte(opMod<<opShift) | byte(c.form),
+ setID: 0, // all values
+ })
+ continue
+ }
+ // We have some entries with values.
+ for i, set := range c.set {
+ if !c.used[i] {
+ continue
+ }
+ index, ok := setMap[set]
+ if !ok {
+ index = len(setMap)
+ setMap[set] = index
+ for i := range inclusionMasks {
+ if set[i] {
+ inclusionMasks[i] |= 1 << uint64(index)
+ }
+ }
+ }
+ rules = append(rules, pluralCheck{
+ cat: byte(i<<opShift | andNext),
+ setID: byte(index),
+ })
+ }
+ // Now set the last entry to the plural form the rule matches.
+ rules[len(rules)-1].cat &^= formMask
+ rules[len(rules)-1].cat |= byte(c.form)
+ }
+ // Point the relevant locales to the created entries.
+ for _, loc := range strings.Split(pRules.Locales, " ") {
+ if strings.TrimSpace(loc) == "" {
+ continue
+ }
+ lang, ok := language.CompactIndex(language.MustParse(loc))
+ if !ok {
+ log.Printf("No compact index for locale %q", loc)
+ }
+ langMap[lang] = byte(len(index) - 1)
+ }
+ index = append(index, byte(len(rules)))
+ }
+ w.WriteVar(plurals.Type+"Rules", rules)
+ w.WriteVar(plurals.Type+"Index", index)
+ // Expand the values.
+ langToIndex := make([]byte, language.NumCompactTags)
+ for i := range langToIndex {
+ for p := i; ; p = int(internal.Parent[p]) {
+ if x, ok := langMap[p]; ok {
+ langToIndex[i] = x
+ break
+ }
+ }
+ }
+ w.WriteVar(plurals.Type+"LangToIndex", langToIndex)
+ // Need to convert array to slice because of golang.org/issue/7651.
+ // This will allow tables to be dropped when unused. This is especially
+ // relevant for the ordinal data, which I suspect won't be used as much.
+ w.WriteVar(plurals.Type+"InclusionMasks", inclusionMasks[:])
+
+ if len(rules) > 0xFF {
+ log.Fatalf("Too many entries for rules: %#x", len(rules))
+ }
+ if len(index) > 0xFF {
+ log.Fatalf("Too many entries for index: %#x", len(index))
+ }
+ if len(setMap) > 64 { // maximum number of bits.
+ log.Fatalf("Too many entries for setMap: %d", len(setMap))
+ }
+ w.WriteComment(
+ "Slots used for %s: %X of 0xFF rules; %X of 0xFF indexes; %d of 64 sets",
+ plurals.Type, len(rules), len(index), len(setMap))
+ // Prevent comment from attaching to the next entry.
+ fmt.Fprint(w, "\n\n")
+ }
+}
+
+type orCondition struct {
+ original string // for debugging
+
+ form Form
+ used [32]bool
+ set [32][numN]bool
+}
+
+func (o *orCondition) add(op opID, mod int, v []int) (ok bool) {
+ ok = true
+ for _, x := range v {
+ if x >= maxMod {
+ ok = false
+ break
+ }
+ }
+ for i := 0; i < numN; i++ {
+ m := i
+ if mod != 0 {
+ m = i % mod
+ }
+ if !intIn(m, v) {
+ o.set[op][i] = false
+ }
+ }
+ if ok {
+ o.used[op] = true
+ }
+ return ok
+}
+
+func intIn(x int, a []int) bool {
+ for _, y := range a {
+ if x == y {
+ return true
+ }
+ }
+ return false
+}
+
+var operandIndex = map[string]opID{
+ "i": opI,
+ "n": opN,
+ "f": opF,
+ "v": opV,
+ "w": opW,
+}
+
+// parsePluralCondition parses the condition of a single pluralRule and appends
+// the resulting or conditions to conds.
+//
+// Example rules:
+// // Category "one" in English: only allow 1 with no visible fraction
+// i = 1 and v = 0 @integer 1
+//
+// // Category "few" in Czech: all numbers with visible fractions
+// v != 0 @decimal ...
+//
+// // Category "zero" in Latvian: all multiples of 10 or the numbers 11-19 or
+// // numbers with a fraction 11..19 and no trailing zeros.
+// n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19 @integer ...
+//
+// @integer and @decimal are followed by examples and are not relevant for the
+// rule itself. The are used here to signal the termination of the rule.
+func parsePluralCondition(conds []orCondition, s string, f Form) []orCondition {
+ scan := bufio.NewScanner(strings.NewReader(s))
+ scan.Split(splitTokens)
+ for {
+ cond := orCondition{original: s, form: f}
+ // Set all numbers to be allowed for all number classes and restrict
+ // from here on.
+ for i := range cond.set {
+ for j := range cond.set[i] {
+ cond.set[i][j] = true
+ }
+ }
+ andLoop:
+ for {
+ var token string
+ scan.Scan() // Must exist.
+ switch class := scan.Text(); class {
+ case "t":
+ class = "w" // equal to w for t == 0
+ fallthrough
+ case "n", "i", "f", "v", "w":
+ op := scanToken(scan)
+ opCode := operandIndex[class]
+ mod := 0
+ if op == "%" {
+ opCode |= opMod
+
+ switch v := scanUint(scan); v {
+ case 10, 100:
+ mod = v
+ case 1000:
+ // A more general solution would be to allow checking
+ // against multiples of 100 and include entries for the
+ // numbers 100..900 in the inclusion masks. At the
+ // moment this would only help Azerbaijan and Italian.
+
+ // Italian doesn't use '%', so this must be Azerbaijan.
+ cond.used[opAzerbaijan00s] = true
+ return append(conds, cond)
+
+ case 1000000:
+ cond.used[opBretonM] = true
+ return append(conds, cond)
+
+ default:
+ log.Fatalf("Modulo value not supported %d", v)
+ }
+ op = scanToken(scan)
+ }
+ if op != "=" && op != "!=" {
+ log.Fatalf("Unexpected op %q", op)
+ }
+ if op == "!=" {
+ opCode |= opNotEqual
+ }
+ a := []int{}
+ v := scanUint(scan)
+ if class == "w" && v != 0 {
+ log.Fatalf("Must compare against zero for operand type %q", class)
+ }
+ token = scanToken(scan)
+ for {
+ switch token {
+ case "..":
+ end := scanUint(scan)
+ for ; v <= end; v++ {
+ a = append(a, v)
+ }
+ token = scanToken(scan)
+ default: // ",", "or", "and", "@..."
+ a = append(a, v)
+ }
+ if token != "," {
+ break
+ }
+ v = scanUint(scan)
+ token = scanToken(scan)
+ }
+ if !cond.add(opCode, mod, a) {
+ // Detected large numbers. As we ruled out Azerbaijan, this
+ // must be the many rule for Italian ordinals.
+ cond.set[opItalian800] = cond.set[opN]
+ cond.used[opItalian800] = true
+ }
+
+ case "@integer", "@decimal": // "other" entry: tests only.
+ return conds
+ default:
+ log.Fatalf("Unexpected operand class %q (%s)", class, s)
+ }
+ switch token {
+ case "or":
+ conds = append(conds, cond)
+ break andLoop
+ case "@integer", "@decimal": // examples
+ // There is always an example in practice, so we always terminate here.
+ if err := scan.Err(); err != nil {
+ log.Fatal(err)
+ }
+ return append(conds, cond)
+ case "and":
+ // keep accumulating
+ default:
+ log.Fatalf("Unexpected token %q", token)
+ }
+ }
+ }
+}
+
+func scanToken(scan *bufio.Scanner) string {
+ scan.Scan()
+ return scan.Text()
+}
+
+func scanUint(scan *bufio.Scanner) int {
+ scan.Scan()
+ val, err := strconv.ParseUint(scan.Text(), 10, 32)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return int(val)
+}
+
+// splitTokens can be used with bufio.Scanner to tokenize CLDR plural rules.
+func splitTokens(data []byte, atEOF bool) (advance int, token []byte, err error) {
+ condTokens := [][]byte{
+ []byte(".."),
+ []byte(","),
+ []byte("!="),
+ []byte("="),
+ }
+ advance, token, err = bufio.ScanWords(data, atEOF)
+ for _, t := range condTokens {
+ if len(t) >= len(token) {
+ continue
+ }
+ switch p := bytes.Index(token, t); {
+ case p == -1:
+ case p == 0:
+ advance = len(t)
+ token = token[:len(t)]
+ return advance - len(token) + len(t), token[:len(t)], err
+ case p < advance:
+ // Don't split when "=" overlaps "!=".
+ if t[0] == '=' && token[p-1] == '!' {
+ continue
+ }
+ advance = p
+ token = token[:p]
+ }
+ }
+ return advance, token, err
+}
diff --git a/vendor/golang.org/x/text/feature/plural/gen_common.go b/vendor/golang.org/x/text/feature/plural/gen_common.go
new file mode 100644
index 0000000..24aa415
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/gen_common.go
@@ -0,0 +1,74 @@
+// Copyright 2016 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.
+
+// +build ignore
+
+package main
+
+// Form defines a plural form.
+//
+// Not all languages support all forms. Also, the meaning of each form varies
+// per language. It is important to note that the name of a form does not
+// necessarily correspond one-to-one with the set of numbers. For instance,
+// for Croation, One matches not only 1, but also 11, 21, etc.
+//
+// Each language must at least support the form "other".
+type Form byte
+
+const (
+ Other Form = iota
+ Zero
+ One
+ Two
+ Few
+ Many
+)
+
+var countMap = map[string]Form{
+ "other": Other,
+ "zero": Zero,
+ "one": One,
+ "two": Two,
+ "few": Few,
+ "many": Many,
+}
+
+type pluralCheck struct {
+ // category:
+ // 3..7: opID
+ // 0..2: category
+ cat byte
+ setID byte
+}
+
+// opID identifies the type of operand in the plural rule, being i, n or f.
+// (v, w, and t are treated as filters in our implementation.)
+type opID byte
+
+const (
+ opMod opID = 0x1 // is '%' used?
+ opNotEqual opID = 0x2 // using "!=" to compare
+ opI opID = 0 << 2 // integers after taking the absolute value
+ opN opID = 1 << 2 // full number (must be integer)
+ opF opID = 2 << 2 // fraction
+ opV opID = 3 << 2 // number of visible digits
+ opW opID = 4 << 2 // number of visible digits without trailing zeros
+ opBretonM opID = 5 << 2 // hard-wired rule for Breton
+ opItalian800 opID = 6 << 2 // hard-wired rule for Italian
+ opAzerbaijan00s opID = 7 << 2 // hard-wired rule for Azerbaijan
+)
+const (
+ // Use this plural form to indicate the next rule needs to match as well.
+ // The last condition in the list will have the correct plural form.
+ andNext = 0x7
+ formMask = 0x7
+
+ opShift = 3
+
+ // numN indicates the maximum integer, or maximum mod value, for which we
+ // have inclusion masks.
+ numN = 100
+ // The common denominator of the modulo that is taken.
+ maxMod = 100
+)
diff --git a/vendor/golang.org/x/text/feature/plural/message.go b/vendor/golang.org/x/text/feature/plural/message.go
new file mode 100755
index 0000000..f931f8a
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/message.go
@@ -0,0 +1,244 @@
+// Copyright 2017 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 plural
+
+import (
+ "fmt"
+ "io/ioutil"
+ "reflect"
+ "strconv"
+
+ "golang.org/x/text/internal/catmsg"
+ "golang.org/x/text/internal/number"
+ "golang.org/x/text/language"
+ "golang.org/x/text/message/catalog"
+)
+
+// TODO: consider deleting this interface. Maybe VisibleDigits is always
+// sufficient and practical.
+
+// Interface is used for types that can determine their own plural form.
+type Interface interface {
+ // PluralForm reports the plural form for the given language of the
+ // underlying value. It also returns the integer value. If the integer value
+ // is larger than fits in n, PluralForm may return a value modulo
+ // 10,000,000.
+ PluralForm(t language.Tag, scale int) (f Form, n int)
+}
+
+// Selectf returns the first case for which its selector is a match for the
+// arg-th substitution argument to a formatting call, formatting it as indicated
+// by format.
+//
+// The cases argument are pairs of selectors and messages. Selectors are of type
+// string or Form. Messages are of type string or catalog.Message. A selector
+// matches an argument if:
+// - it is "other" or Other
+// - it matches the plural form of the argument: "zero", "one", "two", "few",
+// or "many", or the equivalent Form
+// - it is of the form "=x" where x is an integer that matches the value of
+// the argument.
+// - it is of the form "<x" where x is an integer that is larger than the
+// argument.
+//
+// The format argument determines the formatting parameters for which to
+// determine the plural form. This is especially relevant for non-integer
+// values.
+//
+// The format string may be "", in which case a best-effort attempt is made to
+// find a reasonable representation on which to base the plural form. Examples
+// of format strings are:
+// - %.2f decimal with scale 2
+// - %.2e scientific notation with precision 3 (scale + 1)
+// - %d integer
+func Selectf(arg int, format string, cases ...interface{}) catalog.Message {
+ var p parser
+ // Intercept the formatting parameters of format by doing a dummy print.
+ fmt.Fprintf(ioutil.Discard, format, &p)
+ m := &message{arg, kindDefault, 0, cases}
+ switch p.verb {
+ case 'g':
+ m.kind = kindPrecision
+ m.scale = p.scale
+ case 'f':
+ m.kind = kindScale
+ m.scale = p.scale
+ case 'e':
+ m.kind = kindScientific
+ m.scale = p.scale
+ case 'd':
+ m.kind = kindScale
+ m.scale = 0
+ default:
+ // TODO: do we need to handle errors?
+ }
+ return m
+}
+
+type parser struct {
+ verb rune
+ scale int
+}
+
+func (p *parser) Format(s fmt.State, verb rune) {
+ p.verb = verb
+ p.scale = -1
+ if prec, ok := s.Precision(); ok {
+ p.scale = prec
+ }
+}
+
+type message struct {
+ arg int
+ kind int
+ scale int
+ cases []interface{}
+}
+
+const (
+ // Start with non-ASCII to allow skipping values.
+ kindDefault = 0x80 + iota
+ kindScale // verb f, number of fraction digits follows
+ kindScientific // verb e, number of fraction digits follows
+ kindPrecision // verb g, number of significant digits follows
+)
+
+var handle = catmsg.Register("golang.org/x/text/feature/plural:plural", execute)
+
+func (m *message) Compile(e *catmsg.Encoder) error {
+ e.EncodeMessageType(handle)
+
+ e.EncodeUint(uint64(m.arg))
+
+ e.EncodeUint(uint64(m.kind))
+ if m.kind > kindDefault {
+ e.EncodeUint(uint64(m.scale))
+ }
+
+ forms := validForms(cardinal, e.Language())
+
+ for i := 0; i < len(m.cases); {
+ if err := compileSelector(e, forms, m.cases[i]); err != nil {
+ return err
+ }
+ if i++; i >= len(m.cases) {
+ return fmt.Errorf("plural: no message defined for selector %v", m.cases[i-1])
+ }
+ var msg catalog.Message
+ switch x := m.cases[i].(type) {
+ case string:
+ msg = catalog.String(x)
+ case catalog.Message:
+ msg = x
+ default:
+ return fmt.Errorf("plural: message of type %T; must be string or catalog.Message", x)
+ }
+ if err := e.EncodeMessage(msg); err != nil {
+ return err
+ }
+ i++
+ }
+ return nil
+}
+
+func compileSelector(e *catmsg.Encoder, valid []Form, selector interface{}) error {
+ form := Other
+ switch x := selector.(type) {
+ case string:
+ if x == "" {
+ return fmt.Errorf("plural: empty selector")
+ }
+ if c := x[0]; c == '=' || c == '<' {
+ val, err := strconv.ParseUint(x[1:], 10, 16)
+ if err != nil {
+ return fmt.Errorf("plural: invalid number in selector %q: %v", selector, err)
+ }
+ e.EncodeUint(uint64(c))
+ e.EncodeUint(val)
+ return nil
+ }
+ var ok bool
+ form, ok = countMap[x]
+ if !ok {
+ return fmt.Errorf("plural: invalid plural form %q", selector)
+ }
+ case Form:
+ form = x
+ default:
+ return fmt.Errorf("plural: selector of type %T; want string or Form", selector)
+ }
+
+ ok := false
+ for _, f := range valid {
+ if f == form {
+ ok = true
+ break
+ }
+ }
+ if !ok {
+ return fmt.Errorf("plural: form %q not supported for language %q", selector, e.Language())
+ }
+ e.EncodeUint(uint64(form))
+ return nil
+}
+
+func execute(d *catmsg.Decoder) bool {
+ lang := d.Language()
+ argN := int(d.DecodeUint())
+ kind := int(d.DecodeUint())
+ scale := -1 // default
+ if kind > kindDefault {
+ scale = int(d.DecodeUint())
+ }
+ form := Other
+ n := -1
+ if arg := d.Arg(argN); arg == nil {
+ // Default to Other.
+ } else if x, ok := arg.(number.VisibleDigits); ok {
+ d := x.Digits(nil, lang, scale)
+ form, n = cardinal.matchDisplayDigits(lang, &d)
+ } else if x, ok := arg.(Interface); ok {
+ // This covers lists and formatters from the number package.
+ form, n = x.PluralForm(lang, scale)
+ } else {
+ var f number.Formatter
+ switch kind {
+ case kindScale:
+ f.InitDecimal(lang)
+ f.SetScale(scale)
+ case kindScientific:
+ f.InitScientific(lang)
+ f.SetScale(scale)
+ case kindPrecision:
+ f.InitDecimal(lang)
+ f.SetPrecision(scale)
+ case kindDefault:
+ // sensible default
+ f.InitDecimal(lang)
+ if k := reflect.TypeOf(arg).Kind(); reflect.Int <= k && k <= reflect.Uintptr {
+ f.SetScale(0)
+ } else {
+ f.SetScale(2)
+ }
+ }
+ var dec number.Decimal // TODO: buffer in Printer
+ dec.Convert(f.RoundingContext, arg)
+ v := number.FormatDigits(&dec, f.RoundingContext)
+ if !v.NaN && !v.Inf {
+ form, n = cardinal.matchDisplayDigits(d.Language(), &v)
+ }
+ }
+ for !d.Done() {
+ f := d.DecodeUint()
+ if (f == '=' && n == int(d.DecodeUint())) ||
+ (f == '<' && 0 <= n && n < int(d.DecodeUint())) ||
+ form == Form(f) ||
+ Other == Form(f) {
+ return d.ExecuteMessage()
+ }
+ d.SkipMessage()
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/text/feature/plural/message_test.go b/vendor/golang.org/x/text/feature/plural/message_test.go
new file mode 100644
index 0000000..b5bc47e
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/message_test.go
@@ -0,0 +1,197 @@
+// Copyright 2017 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 plural
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "golang.org/x/text/internal/catmsg"
+ "golang.org/x/text/language"
+ "golang.org/x/text/message/catalog"
+)
+
+func TestSelect(t *testing.T) {
+ lang := language.English
+ type test struct {
+ arg interface{}
+ result string
+ err string
+ }
+ testCases := []struct {
+ desc string
+ msg catalog.Message
+ err string
+ tests []test
+ }{{
+ desc: "basic",
+ msg: Selectf(1, "%d", "one", "foo", "other", "bar"),
+ tests: []test{
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ {arg: 2, result: "bar"},
+ {arg: opposite(1), result: "bar"},
+ {arg: opposite(2), result: "foo"},
+ {arg: "unknown", result: "bar"}, // other
+ },
+ }, {
+ desc: "comparisons",
+ msg: Selectf(1, "%d",
+ "=0", "zero",
+ "=1", "one",
+ "one", "cannot match", // never matches
+ "<5", "<5", // never matches
+ "=5", "=5",
+ Other, "other"),
+ tests: []test{
+ {arg: 0, result: "zero"},
+ {arg: 1, result: "one"},
+ {arg: 2, result: "<5"},
+ {arg: 4, result: "<5"},
+ {arg: 5, result: "=5"},
+ {arg: 6, result: "other"},
+ {arg: "unknown", result: "other"},
+ },
+ }, {
+ desc: "fractions",
+ msg: Selectf(1, "%.2f", "one", "foo", "other", "bar"),
+ tests: []test{
+ // fractions are always plural in english
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "bar"},
+ },
+ }, {
+ desc: "decimal without fractions",
+ msg: Selectf(1, "%.0f", "one", "foo", "other", "bar"),
+ tests: []test{
+ // fractions are always plural in english
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ },
+ }, {
+ desc: "scientific",
+ msg: Selectf(1, "%.0e", "one", "foo", "other", "bar"),
+ tests: []test{
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ },
+ }, {
+ desc: "variable",
+ msg: Selectf(1, "%.1g", "one", "foo", "other", "bar"),
+ tests: []test{
+ // fractions are always plural in english
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ {arg: 2, result: "bar"},
+ },
+ }, {
+ desc: "default",
+ msg: Selectf(1, "", "one", "foo", "other", "bar"),
+ tests: []test{
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ {arg: 2, result: "bar"},
+ {arg: 1.0, result: "bar"},
+ },
+ }, {
+ desc: "nested",
+ msg: Selectf(1, "", "other", Selectf(2, "", "one", "foo", "other", "bar")),
+ tests: []test{
+ {arg: 0, result: "bar"},
+ {arg: 1, result: "foo"},
+ {arg: 2, result: "bar"},
+ },
+ }, {
+ desc: "arg unavailable",
+ msg: Selectf(100, "%.2f", "one", "foo", "other", "bar"),
+ tests: []test{{arg: 1, result: "bar"}},
+ }, {
+ desc: "no match",
+ msg: Selectf(1, "%.2f", "one", "foo"),
+ tests: []test{{arg: 0, result: "bar", err: catmsg.ErrNoMatch.Error()}},
+ }, {
+ desc: "error invalid form",
+ err: `invalid plural form "excessive"`,
+ msg: Selectf(1, "%d", "excessive", "foo"),
+ }, {
+ desc: "error form not used by language",
+ err: `form "many" not supported for language "en"`,
+ msg: Selectf(1, "%d", "many", "foo"),
+ }, {
+ desc: "error invalid selector",
+ err: `selector of type int; want string or Form`,
+ msg: Selectf(1, "%d", 1, "foo"),
+ }, {
+ desc: "error missing message",
+ err: `no message defined for selector one`,
+ msg: Selectf(1, "%d", "one"),
+ }, {
+ desc: "error invalid number",
+ err: `invalid number in selector "<1.00"`,
+ msg: Selectf(1, "%d", "<1.00"),
+ }, {
+ desc: "error empty selector",
+ err: `empty selector`,
+ msg: Selectf(1, "%d", "", "foo"),
+ }, {
+ desc: "error invalid message",
+ err: `message of type int; must be string or catalog.Message`,
+ msg: Selectf(1, "%d", "one", 3),
+ }, {
+ desc: "nested error",
+ err: `empty selector`,
+ msg: Selectf(1, "", "other", Selectf(2, "", "")),
+ }}
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ data, err := catmsg.Compile(lang, nil, tc.msg)
+ chkError(t, err, tc.err)
+ for _, tx := range tc.tests {
+ t.Run(fmt.Sprint(tx.arg), func(t *testing.T) {
+ r := renderer{arg: tx.arg}
+ d := catmsg.NewDecoder(lang, &r, nil)
+ err := d.Execute(data)
+ chkError(t, err, tx.err)
+ if r.result != tx.result {
+ t.Errorf("got %q; want %q", r.result, tx.result)
+ }
+ })
+ }
+ })
+ }
+}
+
+func chkError(t *testing.T, got error, want string) {
+ if (got == nil && want != "") ||
+ (got != nil && (want == "" || !strings.Contains(got.Error(), want))) {
+ t.Fatalf("got %v; want %v", got, want)
+ }
+ if got != nil {
+ t.SkipNow()
+ }
+}
+
+type renderer struct {
+ arg interface{}
+ result string
+}
+
+func (r *renderer) Render(s string) { r.result += s }
+func (r *renderer) Arg(i int) interface{} {
+ if i > 10 { // Allow testing "arg unavailable" path
+ return nil
+ }
+ return r.arg
+}
+
+type opposite int
+
+func (o opposite) PluralForm(lang language.Tag, scale int) (Form, int) {
+ if o == 1 {
+ return Other, 1
+ }
+ return One, int(o)
+}
diff --git a/vendor/golang.org/x/text/feature/plural/plural.go b/vendor/golang.org/x/text/feature/plural/plural.go
new file mode 100644
index 0000000..61faf18
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/plural.go
@@ -0,0 +1,258 @@
+// Copyright 2016 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.
+
+//go:generate go run gen.go gen_common.go
+
+// Package plural provides utilities for handling linguistic plurals in text.
+//
+// The definitions in this package are based on the plural rule handling defined
+// in CLDR. See
+// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules for
+// details.
+package plural
+
+import (
+ "golang.org/x/text/internal/number"
+ "golang.org/x/text/language"
+)
+
+// Rules defines the plural rules for all languages for a certain plural type.
+//
+//
+// This package is UNDER CONSTRUCTION and its API may change.
+type Rules struct {
+ rules []pluralCheck
+ index []byte
+ langToIndex []byte
+ inclusionMasks []uint64
+}
+
+var (
+ // Cardinal defines the plural rules for numbers indicating quantities.
+ Cardinal *Rules = cardinal
+
+ // Ordinal defines the plural rules for numbers indicating position
+ // (first, second, etc.).
+ Ordinal *Rules = ordinal
+
+ ordinal = &Rules{
+ ordinalRules,
+ ordinalIndex,
+ ordinalLangToIndex,
+ ordinalInclusionMasks[:],
+ }
+
+ cardinal = &Rules{
+ cardinalRules,
+ cardinalIndex,
+ cardinalLangToIndex,
+ cardinalInclusionMasks[:],
+ }
+)
+
+// getIntApprox converts the digits in slice digits[start:end] to an integer
+// according to the following rules:
+// - Let i be asInt(digits[start:end]), where out-of-range digits are assumed
+// to be zero.
+// - Result n is big if i / 10^nMod > 1.
+// - Otherwise the result is i % 10^nMod.
+//
+// For example, if digits is {1, 2, 3} and start:end is 0:5, then the result
+// for various values of nMod is:
+// - when nMod == 2, n == big
+// - when nMod == 3, n == big
+// - when nMod == 4, n == big
+// - when nMod == 5, n == 12300
+// - when nMod == 6, n == 12300
+// - when nMod == 7, n == 12300
+func getIntApprox(digits []byte, start, end, nMod, big int) (n int) {
+ // Leading 0 digits just result in 0.
+ p := start
+ if p < 0 {
+ p = 0
+ }
+ // Range only over the part for which we have digits.
+ mid := end
+ if mid >= len(digits) {
+ mid = len(digits)
+ }
+ // Check digits more significant that nMod.
+ if q := end - nMod; q > 0 {
+ if q > mid {
+ q = mid
+ }
+ for ; p < q; p++ {
+ if digits[p] != 0 {
+ return big
+ }
+ }
+ }
+ for ; p < mid; p++ {
+ n = 10*n + int(digits[p])
+ }
+ // Multiply for trailing zeros.
+ for ; p < end; p++ {
+ n *= 10
+ }
+ return n
+}
+
+// MatchDigits computes the plural form for the given language and the given
+// decimal floating point digits. The digits are stored in big-endian order and
+// are of value byte(0) - byte(9). The floating point position is indicated by
+// exp and the number of visible decimals is scale. All leading and trailing
+// zeros may be omitted from digits.
+//
+// The following table contains examples of possible arguments to represent
+// the given numbers.
+// decimal digits exp scale
+// 123 []byte{1, 2, 3} 3 0
+// 123.4 []byte{1, 2, 3, 4} 3 1
+// 123.40 []byte{1, 2, 3, 4} 3 2
+// 100000 []byte{1} 6 0
+// 100000.00 []byte{1} 6 3
+func (p *Rules) MatchDigits(t language.Tag, digits []byte, exp, scale int) Form {
+ index, _ := language.CompactIndex(t)
+
+ // Differentiate up to including mod 1000000 for the integer part.
+ n := getIntApprox(digits, 0, exp, 6, 1000000)
+
+ // Differentiate up to including mod 100 for the fractional part.
+ f := getIntApprox(digits, exp, exp+scale, 2, 100)
+
+ return matchPlural(p, index, n, f, scale)
+}
+
+func (p *Rules) matchDisplayDigits(t language.Tag, d *number.Digits) (Form, int) {
+ n := getIntApprox(d.Digits, 0, int(d.Exp), 6, 1000000)
+ return p.MatchDigits(t, d.Digits, int(d.Exp), d.NumFracDigits()), n
+}
+
+func validForms(p *Rules, t language.Tag) (forms []Form) {
+ index, _ := language.CompactIndex(t)
+ offset := p.langToIndex[index]
+ rules := p.rules[p.index[offset]:p.index[offset+1]]
+
+ forms = append(forms, Other)
+ last := Other
+ for _, r := range rules {
+ if cat := Form(r.cat & formMask); cat != andNext && last != cat {
+ forms = append(forms, cat)
+ last = cat
+ }
+ }
+ return forms
+}
+
+func (p *Rules) matchComponents(t language.Tag, n, f, scale int) Form {
+ index, _ := language.CompactIndex(t)
+ return matchPlural(p, index, n, f, scale)
+}
+
+// MatchPlural returns the plural form for the given language and plural
+// operands (as defined in
+// http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules):
+// where
+// n absolute value of the source number (integer and decimals)
+// input
+// i integer digits of n.
+// v number of visible fraction digits in n, with trailing zeros.
+// w number of visible fraction digits in n, without trailing zeros.
+// f visible fractional digits in n, with trailing zeros (f = t * 10^(v-w))
+// t visible fractional digits in n, without trailing zeros.
+//
+// If any of the operand values is too large to fit in an int, it is okay to
+// pass the value modulo 10,000,000.
+func (p *Rules) MatchPlural(lang language.Tag, i, v, w, f, t int) Form {
+ index, _ := language.CompactIndex(lang)
+ return matchPlural(p, index, i, f, v)
+}
+
+func matchPlural(p *Rules, index int, n, f, v int) Form {
+ nMask := p.inclusionMasks[n%maxMod]
+ // Compute the fMask inline in the rules below, as it is relatively rare.
+ // fMask := p.inclusionMasks[f%maxMod]
+ vMask := p.inclusionMasks[v%maxMod]
+
+ // Do the matching
+ offset := p.langToIndex[index]
+ rules := p.rules[p.index[offset]:p.index[offset+1]]
+ for i := 0; i < len(rules); i++ {
+ rule := rules[i]
+ setBit := uint64(1 << rule.setID)
+ var skip bool
+ switch op := opID(rule.cat >> opShift); op {
+ case opI: // i = x
+ skip = n >= numN || nMask&setBit == 0
+
+ case opI | opNotEqual: // i != x
+ skip = n < numN && nMask&setBit != 0
+
+ case opI | opMod: // i % m = x
+ skip = nMask&setBit == 0
+
+ case opI | opMod | opNotEqual: // i % m != x
+ skip = nMask&setBit != 0
+
+ case opN: // n = x
+ skip = f != 0 || n >= numN || nMask&setBit == 0
+
+ case opN | opNotEqual: // n != x
+ skip = f == 0 && n < numN && nMask&setBit != 0
+
+ case opN | opMod: // n % m = x
+ skip = f != 0 || nMask&setBit == 0
+
+ case opN | opMod | opNotEqual: // n % m != x
+ skip = f == 0 && nMask&setBit != 0
+
+ case opF: // f = x
+ skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0
+
+ case opF | opNotEqual: // f != x
+ skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0
+
+ case opF | opMod: // f % m = x
+ skip = p.inclusionMasks[f%maxMod]&setBit == 0
+
+ case opF | opMod | opNotEqual: // f % m != x
+ skip = p.inclusionMasks[f%maxMod]&setBit != 0
+
+ case opV: // v = x
+ skip = v < numN && vMask&setBit == 0
+
+ case opV | opNotEqual: // v != x
+ skip = v < numN && vMask&setBit != 0
+
+ case opW: // w == 0
+ skip = f != 0
+
+ case opW | opNotEqual: // w != 0
+ skip = f == 0
+
+ // Hard-wired rules that cannot be handled by our algorithm.
+
+ case opBretonM:
+ skip = f != 0 || n == 0 || n%1000000 != 0
+
+ case opAzerbaijan00s:
+ // 100,200,300,400,500,600,700,800,900
+ skip = n == 0 || n >= 1000 || n%100 != 0
+
+ case opItalian800:
+ skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800
+ }
+ if skip {
+ // advance over AND entries.
+ for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ {
+ }
+ continue
+ }
+ // return if we have a final entry.
+ if cat := rule.cat & formMask; cat != andNext {
+ return Form(cat)
+ }
+ }
+ return Other
+}
diff --git a/vendor/golang.org/x/text/feature/plural/plural_test.go b/vendor/golang.org/x/text/feature/plural/plural_test.go
new file mode 100644
index 0000000..b3cf4c4
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/plural_test.go
@@ -0,0 +1,216 @@
+// Copyright 2016 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 plural
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "testing"
+
+ "golang.org/x/text/language"
+)
+
+func TestGetIntApprox(t *testing.T) {
+ const big = 1234567890
+ testCases := []struct {
+ digits string
+ start int
+ end int
+ nMod int
+ want int
+ }{
+ {"123", 0, 1, 1, 1},
+ {"123", 0, 2, 1, big},
+ {"123", 0, 2, 2, 12},
+ {"123", 3, 4, 2, 0},
+ {"12345", 3, 4, 2, 4},
+ {"40", 0, 1, 2, 4},
+ {"1", 0, 7, 2, big},
+
+ {"123", 0, 5, 2, big},
+ {"123", 0, 5, 3, big},
+ {"123", 0, 5, 4, big},
+ {"123", 0, 5, 5, 12300},
+ {"123", 0, 5, 6, 12300},
+ {"123", 0, 5, 7, 12300},
+
+ // Translation of examples in MatchDigits.
+ // Integer parts
+ {"123", 0, 3, 3, 123}, // 123
+ {"1234", 0, 3, 3, 123}, // 123.4
+ {"1", 0, 6, 8, 100000}, // 100000
+
+ // Fraction parts
+ {"123", 3, 3, 3, 0}, // 123
+ {"1234", 3, 4, 3, 4}, // 123.4
+ {"1234", 3, 5, 3, 40}, // 123.40
+ {"1", 6, 8, 8, 0}, // 100000.00
+ }
+ for _, tc := range testCases {
+ t.Run(fmt.Sprintf("%s:%d:%d/%d", tc.digits, tc.start, tc.end, tc.nMod), func(t *testing.T) {
+ got := getIntApprox(mkDigits(tc.digits), tc.start, tc.end, tc.nMod, big)
+ if got != tc.want {
+ t.Errorf("got %d; want %d", got, tc.want)
+ }
+ })
+ }
+}
+
+func mkDigits(s string) []byte {
+ b := []byte(s)
+ for i := range b {
+ b[i] -= '0'
+ }
+ return b
+}
+
+func TestValidForms(t *testing.T) {
+ testCases := []struct {
+ tag language.Tag
+ want []Form
+ }{
+ {language.AmericanEnglish, []Form{Other, One}},
+ {language.Portuguese, []Form{Other, One}},
+ {language.Latvian, []Form{Other, Zero, One}},
+ {language.Arabic, []Form{Other, Zero, One, Two, Few, Many}},
+ {language.Russian, []Form{Other, One, Few, Many}},
+ }
+ for _, tc := range testCases {
+ got := validForms(cardinal, tc.tag)
+ if !reflect.DeepEqual(got, tc.want) {
+ t.Errorf("validForms(%v): got %v; want %v", tc.tag, got, tc.want)
+ }
+ }
+}
+
+func TestOrdinal(t *testing.T) {
+ testPlurals(t, Ordinal, ordinalTests)
+}
+
+func TestCardinal(t *testing.T) {
+ testPlurals(t, Cardinal, cardinalTests)
+}
+
+func testPlurals(t *testing.T, p *Rules, testCases []pluralTest) {
+ for _, tc := range testCases {
+ for _, loc := range strings.Split(tc.locales, " ") {
+ tag := language.MustParse(loc)
+ // Test integers
+ for _, s := range tc.integer {
+ a := strings.Split(s, "~")
+ from := parseUint(t, a[0])
+ to := from
+ if len(a) > 1 {
+ to = parseUint(t, a[1])
+ }
+ for n := from; n <= to; n++ {
+ t.Run(fmt.Sprintf("%s/int(%d)", loc, n), func(t *testing.T) {
+ if f := p.matchComponents(tag, n, 0, 0); f != Form(tc.form) {
+ t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
+ }
+ digits := []byte(fmt.Sprint(n))
+ for i := range digits {
+ digits[i] -= '0'
+ }
+ if f := p.MatchDigits(tag, digits, len(digits), 0); f != Form(tc.form) {
+ t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
+ }
+ })
+ }
+ }
+ // Test decimals
+ for _, s := range tc.decimal {
+ a := strings.Split(s, "~")
+ from, scale := parseFixedPoint(t, a[0])
+ to := from
+ if len(a) > 1 {
+ var toScale int
+ if to, toScale = parseFixedPoint(t, a[1]); toScale != scale {
+ t.Fatalf("%s:%s: non-matching scales %d versus %d", loc, s, scale, toScale)
+ }
+ }
+ m := 1
+ for i := 0; i < scale; i++ {
+ m *= 10
+ }
+ for n := from; n <= to; n++ {
+ num := fmt.Sprintf("%[1]d.%0[3]*[2]d", n/m, n%m, scale)
+ name := fmt.Sprintf("%s:dec(%s)", loc, num)
+ t.Run(name, func(t *testing.T) {
+ ff := n % m
+ tt := ff
+ w := scale
+ for tt > 0 && tt%10 == 0 {
+ w--
+ tt /= 10
+ }
+ if f := p.MatchPlural(tag, n/m, scale, w, ff, tt); f != Form(tc.form) {
+ t.Errorf("MatchPlural: got %v; want %v", f, Form(tc.form))
+ }
+ if f := p.matchComponents(tag, n/m, n%m, scale); f != Form(tc.form) {
+ t.Errorf("matchComponents: got %v; want %v", f, Form(tc.form))
+ }
+ exp := strings.IndexByte(num, '.')
+ digits := []byte(strings.Replace(num, ".", "", 1))
+ for i := range digits {
+ digits[i] -= '0'
+ }
+ if f := p.MatchDigits(tag, digits, exp, scale); f != Form(tc.form) {
+ t.Errorf("MatchDigits: got %v; want %v", f, Form(tc.form))
+ }
+ })
+ }
+ }
+ }
+ }
+}
+
+func parseUint(t *testing.T, s string) int {
+ val, err := strconv.ParseUint(s, 10, 32)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return int(val)
+}
+
+func parseFixedPoint(t *testing.T, s string) (val, scale int) {
+ p := strings.Index(s, ".")
+ s = strings.Replace(s, ".", "", 1)
+ v, err := strconv.ParseUint(s, 10, 32)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return int(v), len(s) - p
+}
+
+func BenchmarkPluralSimpleCases(b *testing.B) {
+ p := Cardinal
+ en, _ := language.CompactIndex(language.English)
+ zh, _ := language.CompactIndex(language.Chinese)
+ for i := 0; i < b.N; i++ {
+ matchPlural(p, en, 0, 0, 0) // 0
+ matchPlural(p, en, 1, 0, 0) // 1
+ matchPlural(p, en, 2, 12, 3) // 2.120
+ matchPlural(p, zh, 0, 0, 0) // 0
+ matchPlural(p, zh, 1, 0, 0) // 1
+ matchPlural(p, zh, 2, 12, 3) // 2.120
+ }
+}
+
+func BenchmarkPluralComplexCases(b *testing.B) {
+ p := Cardinal
+ ar, _ := language.CompactIndex(language.Arabic)
+ lv, _ := language.CompactIndex(language.Latvian)
+ for i := 0; i < b.N; i++ {
+ matchPlural(p, lv, 0, 19, 2) // 0.19
+ matchPlural(p, lv, 11, 0, 3) // 11.000
+ matchPlural(p, lv, 100, 123, 4) // 0.1230
+ matchPlural(p, ar, 0, 0, 0) // 0
+ matchPlural(p, ar, 110, 0, 0) // 110
+ matchPlural(p, ar, 99, 99, 2) // 99.99
+ }
+}
diff --git a/vendor/golang.org/x/text/feature/plural/tables.go b/vendor/golang.org/x/text/feature/plural/tables.go
new file mode 100644
index 0000000..cdbc93a
--- /dev/null
+++ b/vendor/golang.org/x/text/feature/plural/tables.go
@@ -0,0 +1,540 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package plural
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "31"
+
+var ordinalRules = []pluralCheck{ // 58 elements
+ 0: {cat: 0x2f, setID: 0x4},
+ 1: {cat: 0x3a, setID: 0x5},
+ 2: {cat: 0x22, setID: 0x1},
+ 3: {cat: 0x22, setID: 0x6},
+ 4: {cat: 0x22, setID: 0x7},
+ 5: {cat: 0x2f, setID: 0x8},
+ 6: {cat: 0x3c, setID: 0x9},
+ 7: {cat: 0x2f, setID: 0xa},
+ 8: {cat: 0x3c, setID: 0xb},
+ 9: {cat: 0x2d, setID: 0xc},
+ 10: {cat: 0x2d, setID: 0xd},
+ 11: {cat: 0x2f, setID: 0xe},
+ 12: {cat: 0x35, setID: 0x3},
+ 13: {cat: 0xc5, setID: 0xf},
+ 14: {cat: 0x2, setID: 0x1},
+ 15: {cat: 0x5, setID: 0x3},
+ 16: {cat: 0xd, setID: 0x10},
+ 17: {cat: 0x22, setID: 0x1},
+ 18: {cat: 0x2f, setID: 0x11},
+ 19: {cat: 0x3d, setID: 0x12},
+ 20: {cat: 0x2f, setID: 0x13},
+ 21: {cat: 0x3a, setID: 0x14},
+ 22: {cat: 0x2f, setID: 0x15},
+ 23: {cat: 0x3b, setID: 0x16},
+ 24: {cat: 0x2f, setID: 0xa},
+ 25: {cat: 0x3c, setID: 0xb},
+ 26: {cat: 0x22, setID: 0x1},
+ 27: {cat: 0x23, setID: 0x17},
+ 28: {cat: 0x24, setID: 0x18},
+ 29: {cat: 0x22, setID: 0x19},
+ 30: {cat: 0x23, setID: 0x2},
+ 31: {cat: 0x24, setID: 0x18},
+ 32: {cat: 0xf, setID: 0x13},
+ 33: {cat: 0x1a, setID: 0x14},
+ 34: {cat: 0xf, setID: 0x15},
+ 35: {cat: 0x1b, setID: 0x16},
+ 36: {cat: 0xf, setID: 0x1a},
+ 37: {cat: 0x1d, setID: 0x1b},
+ 38: {cat: 0xa, setID: 0x1c},
+ 39: {cat: 0xa, setID: 0x1d},
+ 40: {cat: 0xc, setID: 0x1e},
+ 41: {cat: 0xe4, setID: 0x0},
+ 42: {cat: 0x5, setID: 0x3},
+ 43: {cat: 0xd, setID: 0xc},
+ 44: {cat: 0xd, setID: 0x1f},
+ 45: {cat: 0x22, setID: 0x1},
+ 46: {cat: 0x23, setID: 0x17},
+ 47: {cat: 0x24, setID: 0x18},
+ 48: {cat: 0x25, setID: 0x20},
+ 49: {cat: 0x22, setID: 0x21},
+ 50: {cat: 0x23, setID: 0x17},
+ 51: {cat: 0x24, setID: 0x18},
+ 52: {cat: 0x25, setID: 0x20},
+ 53: {cat: 0x21, setID: 0x22},
+ 54: {cat: 0x22, setID: 0x1},
+ 55: {cat: 0x23, setID: 0x2},
+ 56: {cat: 0x24, setID: 0x23},
+ 57: {cat: 0x25, setID: 0x24},
+} // Size: 140 bytes
+
+var ordinalIndex = []uint8{ // 20 elements
+ 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x07, 0x09,
+ 0x0d, 0x0e, 0x11, 0x14, 0x1a, 0x1d, 0x20, 0x26,
+ 0x2d, 0x31, 0x35, 0x3a,
+} // Size: 44 bytes
+
+var ordinalLangToIndex = []uint8{ // 754 elements
+ // Entry 0 - 3F
+ 0x00, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x05,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 40 - 7F
+ 0x00, 0x00, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 80 - BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ // Entry C0 - FF
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 100 - 13F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ // Entry 140 - 17F
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 180 - 1BF
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 1C0 - 1FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e,
+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x02, 0x02,
+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 200 - 23F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 240 - 27F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 280 - 2BF
+ 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00,
+ // Entry 2C0 - 2FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+} // Size: 778 bytes
+
+var ordinalInclusionMasks = []uint64{ // 100 elements
+ // Entry 0 - 1F
+ 0x0000000400004009, 0x00000002120800d3, 0x0000000010a10195, 0x0000000842810581,
+ 0x0000000841030081, 0x0000001210010041, 0x0000001100011001, 0x0000000614010001,
+ 0x0000000614018001, 0x0000000600012001, 0x0000000200014001, 0x0000000010198031,
+ 0x0000000010610331, 0x0000000040010f01, 0x0000000040070001, 0x0000000010010001,
+ 0x0000000000011001, 0x000000001c010001, 0x000000001c010001, 0x0000000000012001,
+ 0x0000000020014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+ 0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+ 0x0000000014000001, 0x0000000000002001, 0x0000000000004001, 0x0000000010080011,
+ // Entry 20 - 3F
+ 0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+ 0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+ 0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+ 0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+ 0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
+ 0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+ 0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+ 0x0000000080014001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+ // Entry 40 - 5F
+ 0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+ 0x0000000014000001, 0x0000000000002001, 0x0000000020004001, 0x0000000010080011,
+ 0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+ 0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+ 0x000000002001c001, 0x0000000010080011, 0x0000000010200111, 0x0000000040000501,
+ 0x0000000040020001, 0x0000000010000001, 0x0000000000001001, 0x0000000014000001,
+ 0x0000000014000001, 0x0000000000002001, 0x0000000080004001, 0x0000000010080011,
+ 0x0000000010200111, 0x0000000040000501, 0x0000000040020001, 0x0000000010000001,
+ // Entry 60 - 7F
+ 0x0000000000001001, 0x0000000014000001, 0x0000000014000001, 0x0000000000002001,
+} // Size: 824 bytes
+
+// Slots used for ordinal: 3A of 0xFF rules; 14 of 0xFF indexes; 37 of 64 sets
+
+var cardinalRules = []pluralCheck{ // 166 elements
+ 0: {cat: 0x2, setID: 0x3},
+ 1: {cat: 0x22, setID: 0x1},
+ 2: {cat: 0x2, setID: 0x4},
+ 3: {cat: 0x2, setID: 0x4},
+ 4: {cat: 0x7, setID: 0x1},
+ 5: {cat: 0x62, setID: 0x3},
+ 6: {cat: 0x22, setID: 0x4},
+ 7: {cat: 0x7, setID: 0x3},
+ 8: {cat: 0x42, setID: 0x1},
+ 9: {cat: 0x22, setID: 0x4},
+ 10: {cat: 0x22, setID: 0x4},
+ 11: {cat: 0x22, setID: 0x5},
+ 12: {cat: 0x22, setID: 0x1},
+ 13: {cat: 0x22, setID: 0x1},
+ 14: {cat: 0x7, setID: 0x4},
+ 15: {cat: 0x92, setID: 0x3},
+ 16: {cat: 0xf, setID: 0x6},
+ 17: {cat: 0x1f, setID: 0x7},
+ 18: {cat: 0x82, setID: 0x3},
+ 19: {cat: 0x92, setID: 0x3},
+ 20: {cat: 0xf, setID: 0x6},
+ 21: {cat: 0x62, setID: 0x3},
+ 22: {cat: 0x4a, setID: 0x6},
+ 23: {cat: 0x7, setID: 0x8},
+ 24: {cat: 0x62, setID: 0x3},
+ 25: {cat: 0x1f, setID: 0x9},
+ 26: {cat: 0x62, setID: 0x3},
+ 27: {cat: 0x5f, setID: 0x9},
+ 28: {cat: 0x72, setID: 0x3},
+ 29: {cat: 0x29, setID: 0xa},
+ 30: {cat: 0x29, setID: 0xb},
+ 31: {cat: 0x4f, setID: 0xb},
+ 32: {cat: 0x61, setID: 0x2},
+ 33: {cat: 0x2f, setID: 0x6},
+ 34: {cat: 0x3a, setID: 0x7},
+ 35: {cat: 0x4f, setID: 0x6},
+ 36: {cat: 0x5f, setID: 0x7},
+ 37: {cat: 0x62, setID: 0x2},
+ 38: {cat: 0x4f, setID: 0x6},
+ 39: {cat: 0x72, setID: 0x2},
+ 40: {cat: 0x21, setID: 0x3},
+ 41: {cat: 0x7, setID: 0x4},
+ 42: {cat: 0x32, setID: 0x3},
+ 43: {cat: 0x21, setID: 0x3},
+ 44: {cat: 0x22, setID: 0x1},
+ 45: {cat: 0x22, setID: 0x1},
+ 46: {cat: 0x23, setID: 0x2},
+ 47: {cat: 0x2, setID: 0x3},
+ 48: {cat: 0x22, setID: 0x1},
+ 49: {cat: 0x24, setID: 0xc},
+ 50: {cat: 0x7, setID: 0x1},
+ 51: {cat: 0x62, setID: 0x3},
+ 52: {cat: 0x74, setID: 0x3},
+ 53: {cat: 0x24, setID: 0x3},
+ 54: {cat: 0x2f, setID: 0xd},
+ 55: {cat: 0x34, setID: 0x1},
+ 56: {cat: 0xf, setID: 0x6},
+ 57: {cat: 0x1f, setID: 0x7},
+ 58: {cat: 0x62, setID: 0x3},
+ 59: {cat: 0x4f, setID: 0x6},
+ 60: {cat: 0x5a, setID: 0x7},
+ 61: {cat: 0xf, setID: 0xe},
+ 62: {cat: 0x1f, setID: 0xf},
+ 63: {cat: 0x64, setID: 0x3},
+ 64: {cat: 0x4f, setID: 0xe},
+ 65: {cat: 0x5c, setID: 0xf},
+ 66: {cat: 0x22, setID: 0x10},
+ 67: {cat: 0x23, setID: 0x11},
+ 68: {cat: 0x24, setID: 0x12},
+ 69: {cat: 0xf, setID: 0x1},
+ 70: {cat: 0x62, setID: 0x3},
+ 71: {cat: 0xf, setID: 0x2},
+ 72: {cat: 0x63, setID: 0x3},
+ 73: {cat: 0xf, setID: 0x13},
+ 74: {cat: 0x64, setID: 0x3},
+ 75: {cat: 0x74, setID: 0x3},
+ 76: {cat: 0xf, setID: 0x1},
+ 77: {cat: 0x62, setID: 0x3},
+ 78: {cat: 0x4a, setID: 0x1},
+ 79: {cat: 0xf, setID: 0x2},
+ 80: {cat: 0x63, setID: 0x3},
+ 81: {cat: 0x4b, setID: 0x2},
+ 82: {cat: 0xf, setID: 0x13},
+ 83: {cat: 0x64, setID: 0x3},
+ 84: {cat: 0x4c, setID: 0x13},
+ 85: {cat: 0x7, setID: 0x1},
+ 86: {cat: 0x62, setID: 0x3},
+ 87: {cat: 0x7, setID: 0x2},
+ 88: {cat: 0x63, setID: 0x3},
+ 89: {cat: 0x2f, setID: 0xa},
+ 90: {cat: 0x37, setID: 0x14},
+ 91: {cat: 0x65, setID: 0x3},
+ 92: {cat: 0x7, setID: 0x1},
+ 93: {cat: 0x62, setID: 0x3},
+ 94: {cat: 0x7, setID: 0x15},
+ 95: {cat: 0x64, setID: 0x3},
+ 96: {cat: 0x75, setID: 0x3},
+ 97: {cat: 0x7, setID: 0x1},
+ 98: {cat: 0x62, setID: 0x3},
+ 99: {cat: 0xf, setID: 0xe},
+ 100: {cat: 0x1f, setID: 0xf},
+ 101: {cat: 0x64, setID: 0x3},
+ 102: {cat: 0xf, setID: 0x16},
+ 103: {cat: 0x17, setID: 0x1},
+ 104: {cat: 0x65, setID: 0x3},
+ 105: {cat: 0xf, setID: 0x17},
+ 106: {cat: 0x65, setID: 0x3},
+ 107: {cat: 0xf, setID: 0xf},
+ 108: {cat: 0x65, setID: 0x3},
+ 109: {cat: 0x2f, setID: 0x6},
+ 110: {cat: 0x3a, setID: 0x7},
+ 111: {cat: 0x2f, setID: 0xe},
+ 112: {cat: 0x3c, setID: 0xf},
+ 113: {cat: 0x2d, setID: 0xa},
+ 114: {cat: 0x2d, setID: 0x17},
+ 115: {cat: 0x2d, setID: 0x18},
+ 116: {cat: 0x2f, setID: 0x6},
+ 117: {cat: 0x3a, setID: 0xb},
+ 118: {cat: 0x2f, setID: 0x19},
+ 119: {cat: 0x3c, setID: 0xb},
+ 120: {cat: 0x55, setID: 0x3},
+ 121: {cat: 0x22, setID: 0x1},
+ 122: {cat: 0x24, setID: 0x3},
+ 123: {cat: 0x2c, setID: 0xc},
+ 124: {cat: 0x2d, setID: 0xb},
+ 125: {cat: 0xf, setID: 0x6},
+ 126: {cat: 0x1f, setID: 0x7},
+ 127: {cat: 0x62, setID: 0x3},
+ 128: {cat: 0xf, setID: 0xe},
+ 129: {cat: 0x1f, setID: 0xf},
+ 130: {cat: 0x64, setID: 0x3},
+ 131: {cat: 0xf, setID: 0xa},
+ 132: {cat: 0x65, setID: 0x3},
+ 133: {cat: 0xf, setID: 0x17},
+ 134: {cat: 0x65, setID: 0x3},
+ 135: {cat: 0xf, setID: 0x18},
+ 136: {cat: 0x65, setID: 0x3},
+ 137: {cat: 0x2f, setID: 0x6},
+ 138: {cat: 0x3a, setID: 0x1a},
+ 139: {cat: 0x2f, setID: 0x1b},
+ 140: {cat: 0x3b, setID: 0x1c},
+ 141: {cat: 0x2f, setID: 0x1d},
+ 142: {cat: 0x3c, setID: 0x1e},
+ 143: {cat: 0x37, setID: 0x3},
+ 144: {cat: 0xa5, setID: 0x0},
+ 145: {cat: 0x22, setID: 0x1},
+ 146: {cat: 0x23, setID: 0x2},
+ 147: {cat: 0x24, setID: 0x1f},
+ 148: {cat: 0x25, setID: 0x20},
+ 149: {cat: 0xf, setID: 0x6},
+ 150: {cat: 0x62, setID: 0x3},
+ 151: {cat: 0xf, setID: 0x1b},
+ 152: {cat: 0x63, setID: 0x3},
+ 153: {cat: 0xf, setID: 0x21},
+ 154: {cat: 0x64, setID: 0x3},
+ 155: {cat: 0x75, setID: 0x3},
+ 156: {cat: 0x21, setID: 0x3},
+ 157: {cat: 0x22, setID: 0x1},
+ 158: {cat: 0x23, setID: 0x2},
+ 159: {cat: 0x2c, setID: 0x22},
+ 160: {cat: 0x2d, setID: 0x5},
+ 161: {cat: 0x21, setID: 0x3},
+ 162: {cat: 0x22, setID: 0x1},
+ 163: {cat: 0x23, setID: 0x2},
+ 164: {cat: 0x24, setID: 0x23},
+ 165: {cat: 0x25, setID: 0x24},
+} // Size: 356 bytes
+
+var cardinalIndex = []uint8{ // 36 elements
+ 0x00, 0x00, 0x02, 0x03, 0x04, 0x06, 0x09, 0x0a,
+ 0x0c, 0x0d, 0x10, 0x14, 0x17, 0x1d, 0x28, 0x2b,
+ 0x2d, 0x2f, 0x32, 0x38, 0x42, 0x45, 0x4c, 0x55,
+ 0x5c, 0x61, 0x6d, 0x74, 0x79, 0x7d, 0x89, 0x91,
+ 0x95, 0x9c, 0xa1, 0xa6,
+} // Size: 60 bytes
+
+var cardinalLangToIndex = []uint8{ // 754 elements
+ // Entry 0 - 3F
+ 0x00, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00,
+ 0x06, 0x06, 0x01, 0x01, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ 0x21, 0x21, 0x01, 0x01, 0x08, 0x08, 0x04, 0x04,
+ 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x1a,
+ 0x1a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06,
+ // Entry 40 - 7F
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x1e, 0x1e, 0x08, 0x08, 0x13, 0x00, 0x00, 0x13,
+ 0x13, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18,
+ 0x18, 0x00, 0x00, 0x22, 0x22, 0x09, 0x09, 0x09,
+ 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x00, 0x00, 0x16, 0x16, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ // Entry 80 - BF
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ // Entry C0 - FF
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ // Entry 100 - 13F
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x08,
+ 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x04, 0x04, 0x0c, 0x0c, 0x08,
+ 0x08, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ // Entry 140 - 17F
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x08, 0x08, 0x04, 0x04, 0x1f, 0x1f, 0x14,
+ 0x14, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x01,
+ 0x01, 0x06, 0x00, 0x00, 0x20, 0x20, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x17, 0x17, 0x01, 0x01,
+ 0x13, 0x13, 0x13, 0x16, 0x16, 0x08, 0x08, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ // Entry 180 - 1BF
+ 0x0a, 0x04, 0x04, 0x04, 0x04, 0x04, 0x10, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
+ 0x08, 0x02, 0x02, 0x08, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0f, 0x0f,
+ 0x08, 0x10, 0x10, 0x08, 0x08, 0x0e, 0x0e, 0x08,
+ // Entry 1C0 - 1FF
+ 0x08, 0x08, 0x08, 0x00, 0x00, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x0d, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x06, 0x00, 0x00, 0x08, 0x08, 0x0b, 0x0b,
+ 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x10, 0x08, 0x08, 0x08,
+ // Entry 200 - 23F
+ 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x08, 0x06, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x06,
+ 0x00, 0x00, 0x06, 0x06, 0x08, 0x19, 0x19, 0x0d,
+ 0x0d, 0x08, 0x08, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ // Entry 240 - 27F
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
+ 0x12, 0x12, 0x12, 0x08, 0x08, 0x1d, 0x1d, 0x1d,
+ 0x1d, 0x1d, 0x1d, 0x1d, 0x00, 0x00, 0x08, 0x08,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x10,
+ 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x11, 0x00, 0x00, 0x11, 0x11, 0x05, 0x05,
+ 0x18, 0x18, 0x15, 0x15, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ // Entry 280 - 2BF
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x00, 0x06, 0x06, 0x06, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+ 0x07, 0x07, 0x08, 0x08, 0x1d, 0x1d, 0x04, 0x04,
+ // Entry 2C0 - 2FF
+ 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x00,
+ 0x08, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01,
+} // Size: 778 bytes
+
+var cardinalInclusionMasks = []uint64{ // 100 elements
+ // Entry 0 - 1F
+ 0x0000000200500419, 0x0000000000512153, 0x000000000a327105, 0x0000000ca23c7101,
+ 0x00000004a23c7201, 0x0000000482943001, 0x0000001482943201, 0x0000000502943001,
+ 0x0000000502943001, 0x0000000522943201, 0x0000000540543401, 0x00000000454128e1,
+ 0x000000005b02e821, 0x000000006304e821, 0x000000006304ea21, 0x0000000042842821,
+ 0x0000000042842a21, 0x0000000042842821, 0x0000000042842821, 0x0000000062842a21,
+ 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021,
+ 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021,
+ 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061,
+ // Entry 20 - 3F
+ 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021,
+ 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221,
+ 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021,
+ 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021,
+ 0x0000000002800021, 0x0000000022800221, 0x0000000000400421, 0x0000000000400061,
+ 0x000000000a004021, 0x0000000022004021, 0x0000000022004221, 0x0000000002800021,
+ 0x0000000002800221, 0x0000000002800021, 0x0000000002800021, 0x0000000022800221,
+ 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021,
+ // Entry 40 - 5F
+ 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021,
+ 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061,
+ 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021,
+ 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221,
+ 0x0000000200400421, 0x0000000000400061, 0x000000000a004021, 0x0000000022004021,
+ 0x0000000022004221, 0x0000000002800021, 0x0000000002800221, 0x0000000002800021,
+ 0x0000000002800021, 0x0000000022800221, 0x0000000040400421, 0x0000000044400061,
+ 0x000000005a004021, 0x0000000062004021, 0x0000000062004221, 0x0000000042800021,
+ // Entry 60 - 7F
+ 0x0000000042800221, 0x0000000042800021, 0x0000000042800021, 0x0000000062800221,
+} // Size: 824 bytes
+
+// Slots used for cardinal: A6 of 0xFF rules; 24 of 0xFF indexes; 37 of 64 sets
+
+// Total table size 3804 bytes (3KiB); checksum: FFC009FC