aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/text/language
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2016-10-29 01:05:01 +0800
committerFelix Lange <fjl@twurst.com>2016-10-29 01:05:01 +0800
commit289b30715d097edafd5562f66cb3567a70b2d330 (patch)
tree7eaaa6da97c84727469303b986e364606ece57ce /vendor/golang.org/x/text/language
parent77703045765343c489ded2f43e3ed0f332c5f148 (diff)
downloaddexon-289b30715d097edafd5562f66cb3567a70b2d330.tar.gz
dexon-289b30715d097edafd5562f66cb3567a70b2d330.tar.zst
dexon-289b30715d097edafd5562f66cb3567a70b2d330.zip
Godeps, vendor: convert dependency management to trash (#3198)
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
Diffstat (limited to 'vendor/golang.org/x/text/language')
-rw-r--r--vendor/golang.org/x/text/language/Makefile16
-rw-r--r--vendor/golang.org/x/text/language/common.go16
-rw-r--r--vendor/golang.org/x/text/language/coverage.go197
-rw-r--r--vendor/golang.org/x/text/language/gen_common.go20
-rw-r--r--vendor/golang.org/x/text/language/gen_index.go162
-rw-r--r--vendor/golang.org/x/text/language/go1_1.go38
-rw-r--r--vendor/golang.org/x/text/language/go1_2.go11
-rw-r--r--vendor/golang.org/x/text/language/index.go767
-rw-r--r--vendor/golang.org/x/text/language/language.go975
-rw-r--r--vendor/golang.org/x/text/language/lookup.go396
-rw-r--r--vendor/golang.org/x/text/language/maketables.go1648
-rw-r--r--vendor/golang.org/x/text/language/match.go841
-rw-r--r--vendor/golang.org/x/text/language/parse.go859
-rw-r--r--vendor/golang.org/x/text/language/tables.go3547
-rw-r--r--vendor/golang.org/x/text/language/tags.go143
15 files changed, 9636 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/language/Makefile b/vendor/golang.org/x/text/language/Makefile
new file mode 100644
index 000000000..79f005784
--- /dev/null
+++ b/vendor/golang.org/x/text/language/Makefile
@@ -0,0 +1,16 @@
+# Copyright 2013 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+CLEANFILES+=maketables
+
+maketables: maketables.go
+ go build $^
+
+tables: maketables
+ ./maketables > tables.go
+ gofmt -w -s tables.go
+
+# Build (but do not run) maketables during testing,
+# just to make sure it still compiles.
+testshort: maketables
diff --git a/vendor/golang.org/x/text/language/common.go b/vendor/golang.org/x/text/language/common.go
new file mode 100644
index 000000000..a255bb0a5
--- /dev/null
+++ b/vendor/golang.org/x/text/language/common.go
@@ -0,0 +1,16 @@
+// This file was generated by go generate; DO NOT EDIT
+
+package language
+
+// This file contains code common to the maketables.go and the package code.
+
+// langAliasType is the type of an alias in langAliasMap.
+type langAliasType int8
+
+const (
+ langDeprecated langAliasType = iota
+ langMacro
+ langLegacy
+
+ langAliasTypeUnknown langAliasType = -1
+)
diff --git a/vendor/golang.org/x/text/language/coverage.go b/vendor/golang.org/x/text/language/coverage.go
new file mode 100644
index 000000000..101fd23c1
--- /dev/null
+++ b/vendor/golang.org/x/text/language/coverage.go
@@ -0,0 +1,197 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "fmt"
+ "sort"
+)
+
+// The Coverage interface is used to define the level of coverage of an
+// internationalization service. Note that not all types are supported by all
+// services. As lists may be generated on the fly, it is recommended that users
+// of a Coverage cache the results.
+type Coverage interface {
+ // Tags returns the list of supported tags.
+ Tags() []Tag
+
+ // BaseLanguages returns the list of supported base languages.
+ BaseLanguages() []Base
+
+ // Scripts returns the list of supported scripts.
+ Scripts() []Script
+
+ // Regions returns the list of supported regions.
+ Regions() []Region
+}
+
+var (
+ // Supported defines a Coverage that lists all supported subtags. Tags
+ // always returns nil.
+ Supported Coverage = allSubtags{}
+)
+
+// TODO:
+// - Support Variants, numbering systems.
+// - CLDR coverage levels.
+// - Set of common tags defined in this package.
+
+type allSubtags struct{}
+
+// Regions returns the list of supported regions. As all regions are in a
+// consecutive range, it simply returns a slice of numbers in increasing order.
+// The "undefined" region is not returned.
+func (s allSubtags) Regions() []Region {
+ reg := make([]Region, numRegions)
+ for i := range reg {
+ reg[i] = Region{regionID(i + 1)}
+ }
+ return reg
+}
+
+// Scripts returns the list of supported scripts. As all scripts are in a
+// consecutive range, it simply returns a slice of numbers in increasing order.
+// The "undefined" script is not returned.
+func (s allSubtags) Scripts() []Script {
+ scr := make([]Script, numScripts)
+ for i := range scr {
+ scr[i] = Script{scriptID(i + 1)}
+ }
+ return scr
+}
+
+// BaseLanguages returns the list of all supported base languages. It generates
+// the list by traversing the internal structures.
+func (s allSubtags) BaseLanguages() []Base {
+ base := make([]Base, 0, numLanguages)
+ for i := 0; i < langNoIndexOffset; i++ {
+ // We included "und" already for the value 0.
+ if i != nonCanonicalUnd {
+ base = append(base, Base{langID(i)})
+ }
+ }
+ i := langNoIndexOffset
+ for _, v := range langNoIndex {
+ for k := 0; k < 8; k++ {
+ if v&1 == 1 {
+ base = append(base, Base{langID(i)})
+ }
+ v >>= 1
+ i++
+ }
+ }
+ return base
+}
+
+// Tags always returns nil.
+func (s allSubtags) Tags() []Tag {
+ return nil
+}
+
+// coverage is used used by NewCoverage which is used as a convenient way for
+// creating Coverage implementations for partially defined data. Very often a
+// package will only need to define a subset of slices. coverage provides a
+// convenient way to do this. Moreover, packages using NewCoverage, instead of
+// their own implementation, will not break if later new slice types are added.
+type coverage struct {
+ tags func() []Tag
+ bases func() []Base
+ scripts func() []Script
+ regions func() []Region
+}
+
+func (s *coverage) Tags() []Tag {
+ if s.tags == nil {
+ return nil
+ }
+ return s.tags()
+}
+
+// bases implements sort.Interface and is used to sort base languages.
+type bases []Base
+
+func (b bases) Len() int {
+ return len(b)
+}
+
+func (b bases) Swap(i, j int) {
+ b[i], b[j] = b[j], b[i]
+}
+
+func (b bases) Less(i, j int) bool {
+ return b[i].langID < b[j].langID
+}
+
+// BaseLanguages returns the result from calling s.bases if it is specified or
+// otherwise derives the set of supported base languages from tags.
+func (s *coverage) BaseLanguages() []Base {
+ if s.bases == nil {
+ tags := s.Tags()
+ if len(tags) == 0 {
+ return nil
+ }
+ a := make([]Base, len(tags))
+ for i, t := range tags {
+ a[i] = Base{langID(t.lang)}
+ }
+ sort.Sort(bases(a))
+ k := 0
+ for i := 1; i < len(a); i++ {
+ if a[k] != a[i] {
+ k++
+ a[k] = a[i]
+ }
+ }
+ return a[:k+1]
+ }
+ return s.bases()
+}
+
+func (s *coverage) Scripts() []Script {
+ if s.scripts == nil {
+ return nil
+ }
+ return s.scripts()
+}
+
+func (s *coverage) Regions() []Region {
+ if s.regions == nil {
+ return nil
+ }
+ return s.regions()
+}
+
+// NewCoverage returns a Coverage for the given lists. It is typically used by
+// packages providing internationalization services to define their level of
+// coverage. A list may be of type []T or func() []T, where T is either Tag,
+// Base, Script or Region. The returned Coverage derives the value for Bases
+// from Tags if no func or slice for []Base is specified. For other unspecified
+// types the returned Coverage will return nil for the respective methods.
+func NewCoverage(list ...interface{}) Coverage {
+ s := &coverage{}
+ for _, x := range list {
+ switch v := x.(type) {
+ case func() []Base:
+ s.bases = v
+ case func() []Script:
+ s.scripts = v
+ case func() []Region:
+ s.regions = v
+ case func() []Tag:
+ s.tags = v
+ case []Base:
+ s.bases = func() []Base { return v }
+ case []Script:
+ s.scripts = func() []Script { return v }
+ case []Region:
+ s.regions = func() []Region { return v }
+ case []Tag:
+ s.tags = func() []Tag { return v }
+ default:
+ panic(fmt.Sprintf("language: unsupported set type %T", v))
+ }
+ }
+ return s
+}
diff --git a/vendor/golang.org/x/text/language/gen_common.go b/vendor/golang.org/x/text/language/gen_common.go
new file mode 100644
index 000000000..83ce18013
--- /dev/null
+++ b/vendor/golang.org/x/text/language/gen_common.go
@@ -0,0 +1,20 @@
+// Copyright 2014 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 contains code common to the maketables.go and the package code.
+
+// langAliasType is the type of an alias in langAliasMap.
+type langAliasType int8
+
+const (
+ langDeprecated langAliasType = iota
+ langMacro
+ langLegacy
+
+ langAliasTypeUnknown langAliasType = -1
+)
diff --git a/vendor/golang.org/x/text/language/gen_index.go b/vendor/golang.org/x/text/language/gen_index.go
new file mode 100644
index 000000000..eef555cd3
--- /dev/null
+++ b/vendor/golang.org/x/text/language/gen_index.go
@@ -0,0 +1,162 @@
+// Copyright 2015 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 derivative tables based on the language package itself.
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "reflect"
+ "sort"
+ "strings"
+
+ "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.")
+
+ draft = flag.String("draft",
+ "contributed",
+ `Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
+)
+
+func main() {
+ gen.Init()
+
+ // Read the CLDR zip file.
+ r := gen.OpenCLDRCoreZip()
+ defer r.Close()
+
+ d := &cldr.Decoder{}
+ data, err := d.DecodeZip(r)
+ if err != nil {
+ log.Fatalf("DecodeZip: %v", err)
+ }
+
+ w := gen.NewCodeWriter()
+ defer func() {
+ buf := &bytes.Buffer{}
+
+ if _, err = w.WriteGo(buf, "language"); err != nil {
+ log.Fatalf("Error formatting file index.go: %v", err)
+ }
+
+ // Since we're generating a table for our own package we need to rewrite
+ // doing the equivalent of go fmt -r 'language.b -> b'. Using
+ // bytes.Replace will do.
+ out := bytes.Replace(buf.Bytes(), []byte("language."), nil, -1)
+ if err := ioutil.WriteFile("index.go", out, 0600); err != nil {
+ log.Fatalf("Could not create file index.go: %v", err)
+ }
+ }()
+
+ m := map[language.Tag]bool{}
+ for _, lang := range data.Locales() {
+ // We include all locales unconditionally to be consistent with en_US.
+ // We want en_US, even though it has no data associated with it.
+
+ // TODO: put any of the languages for which no data exists at the end
+ // of the index. This allows all components based on ICU to use that
+ // as the cutoff point.
+ // if x := data.RawLDML(lang); false ||
+ // x.LocaleDisplayNames != nil ||
+ // x.Characters != nil ||
+ // x.Delimiters != nil ||
+ // x.Measurement != nil ||
+ // x.Dates != nil ||
+ // x.Numbers != nil ||
+ // x.Units != nil ||
+ // x.ListPatterns != nil ||
+ // x.Collations != nil ||
+ // x.Segmentations != nil ||
+ // x.Rbnf != nil ||
+ // x.Annotations != nil ||
+ // x.Metadata != nil {
+
+ // TODO: support POSIX natively, albeit non-standard.
+ tag := language.Make(strings.Replace(lang, "_POSIX", "-u-va-posix", 1))
+ m[tag] = true
+ // }
+ }
+ // Include locales for plural rules, which uses a different structure.
+ for _, plurals := range data.Supplemental().Plurals {
+ for _, rules := range plurals.PluralRules {
+ for _, lang := range strings.Split(rules.Locales, " ") {
+ m[language.Make(lang)] = true
+ }
+ }
+ }
+
+ var core, special []language.Tag
+
+ for t := range m {
+ if x := t.Extensions(); len(x) != 0 && fmt.Sprint(x) != "[u-va-posix]" {
+ log.Fatalf("Unexpected extension %v in %v", x, t)
+ }
+ if len(t.Variants()) == 0 && len(t.Extensions()) == 0 {
+ core = append(core, t)
+ } else {
+ special = append(special, t)
+ }
+ }
+
+ w.WriteComment(`
+ NumCompactTags is the number of common tags. The maximum tag is
+ NumCompactTags-1.`)
+ w.WriteConst("NumCompactTags", len(core)+len(special))
+
+ sort.Sort(byAlpha(special))
+ w.WriteVar("specialTags", special)
+
+ // TODO: order by frequency?
+ sort.Sort(byAlpha(core))
+
+ // Size computations are just an estimate.
+ w.Size += int(reflect.TypeOf(map[uint32]uint16{}).Size())
+ w.Size += len(core) * 6 // size of uint32 and uint16
+
+ fmt.Fprintln(w)
+ fmt.Fprintln(w, "var coreTags = map[uint32]uint16{")
+ fmt.Fprintln(w, "0x0: 0, // und")
+ i := len(special) + 1 // Und and special tags already written.
+ for _, t := range core {
+ if t == language.Und {
+ continue
+ }
+ fmt.Fprint(w.Hash, t, i)
+ b, s, r := t.Raw()
+ fmt.Fprintf(w, "0x%s%s%s: %d, // %s\n",
+ getIndex(b, 3), // 3 is enough as it is guaranteed to be a compact number
+ getIndex(s, 2),
+ getIndex(r, 3),
+ i, t)
+ i++
+ }
+ fmt.Fprintln(w, "}")
+}
+
+// getIndex prints the subtag type and extracts its index of size nibble.
+// If the index is less than n nibbles, the result is prefixed with 0s.
+func getIndex(x interface{}, n int) string {
+ s := fmt.Sprintf("%#v", x) // s is of form Type{typeID: 0x00}
+ s = s[strings.Index(s, "0x")+2 : len(s)-1]
+ return strings.Repeat("0", n-len(s)) + s
+}
+
+type byAlpha []language.Tag
+
+func (a byAlpha) Len() int { return len(a) }
+func (a byAlpha) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byAlpha) Less(i, j int) bool { return a[i].String() < a[j].String() }
diff --git a/vendor/golang.org/x/text/language/go1_1.go b/vendor/golang.org/x/text/language/go1_1.go
new file mode 100644
index 000000000..380f4c09f
--- /dev/null
+++ b/vendor/golang.org/x/text/language/go1_1.go
@@ -0,0 +1,38 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.2
+
+package language
+
+import "sort"
+
+func sortStable(s sort.Interface) {
+ ss := stableSort{
+ s: s,
+ pos: make([]int, s.Len()),
+ }
+ for i := range ss.pos {
+ ss.pos[i] = i
+ }
+ sort.Sort(&ss)
+}
+
+type stableSort struct {
+ s sort.Interface
+ pos []int
+}
+
+func (s *stableSort) Len() int {
+ return len(s.pos)
+}
+
+func (s *stableSort) Less(i, j int) bool {
+ return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j]
+}
+
+func (s *stableSort) Swap(i, j int) {
+ s.s.Swap(i, j)
+ s.pos[i], s.pos[j] = s.pos[j], s.pos[i]
+}
diff --git a/vendor/golang.org/x/text/language/go1_2.go b/vendor/golang.org/x/text/language/go1_2.go
new file mode 100644
index 000000000..38268c57a
--- /dev/null
+++ b/vendor/golang.org/x/text/language/go1_2.go
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.2
+
+package language
+
+import "sort"
+
+var sortStable = sort.Stable
diff --git a/vendor/golang.org/x/text/language/index.go b/vendor/golang.org/x/text/language/index.go
new file mode 100644
index 000000000..50c752186
--- /dev/null
+++ b/vendor/golang.org/x/text/language/index.go
@@ -0,0 +1,767 @@
+// This file was generated by go generate; DO NOT EDIT
+
+package language
+
+// NumCompactTags is the number of common tags. The maximum tag is
+// NumCompactTags-1.
+const NumCompactTags = 752
+
+var specialTags = []Tag{ // 2 elements
+ 0: {lang: 0xd5, region: 0x6d, script: 0x0, pVariant: 0x5, pExt: 0xe, str: "ca-ES-valencia"},
+ 1: {lang: 0x134, region: 0x134, script: 0x0, pVariant: 0x5, pExt: 0x5, str: "en-US-u-va-posix"},
+} // Size: 72 bytes
+
+var coreTags = map[uint32]uint16{
+ 0x0: 0, // und
+ 0x01500000: 3, // af
+ 0x015000d1: 4, // af-NA
+ 0x01500160: 5, // af-ZA
+ 0x01b00000: 6, // agq
+ 0x01b00051: 7, // agq-CM
+ 0x02000000: 8, // ak
+ 0x0200007f: 9, // ak-GH
+ 0x02600000: 10, // am
+ 0x0260006e: 11, // am-ET
+ 0x03900000: 12, // ar
+ 0x03900001: 13, // ar-001
+ 0x03900022: 14, // ar-AE
+ 0x03900038: 15, // ar-BH
+ 0x03900061: 16, // ar-DJ
+ 0x03900066: 17, // ar-DZ
+ 0x0390006a: 18, // ar-EG
+ 0x0390006b: 19, // ar-EH
+ 0x0390006c: 20, // ar-ER
+ 0x03900096: 21, // ar-IL
+ 0x0390009a: 22, // ar-IQ
+ 0x039000a0: 23, // ar-JO
+ 0x039000a7: 24, // ar-KM
+ 0x039000ab: 25, // ar-KW
+ 0x039000af: 26, // ar-LB
+ 0x039000b8: 27, // ar-LY
+ 0x039000b9: 28, // ar-MA
+ 0x039000c8: 29, // ar-MR
+ 0x039000e0: 30, // ar-OM
+ 0x039000ec: 31, // ar-PS
+ 0x039000f2: 32, // ar-QA
+ 0x03900107: 33, // ar-SA
+ 0x0390010a: 34, // ar-SD
+ 0x03900114: 35, // ar-SO
+ 0x03900116: 36, // ar-SS
+ 0x0390011b: 37, // ar-SY
+ 0x0390011f: 38, // ar-TD
+ 0x03900127: 39, // ar-TN
+ 0x0390015d: 40, // ar-YE
+ 0x03f00000: 41, // ars
+ 0x04200000: 42, // as
+ 0x04200098: 43, // as-IN
+ 0x04300000: 44, // asa
+ 0x0430012e: 45, // asa-TZ
+ 0x04700000: 46, // ast
+ 0x0470006d: 47, // ast-ES
+ 0x05700000: 48, // az
+ 0x0571e000: 49, // az-Cyrl
+ 0x0571e031: 50, // az-Cyrl-AZ
+ 0x05752000: 51, // az-Latn
+ 0x05752031: 52, // az-Latn-AZ
+ 0x05d00000: 53, // bas
+ 0x05d00051: 54, // bas-CM
+ 0x07000000: 55, // be
+ 0x07000046: 56, // be-BY
+ 0x07400000: 57, // bem
+ 0x07400161: 58, // bem-ZM
+ 0x07800000: 59, // bez
+ 0x0780012e: 60, // bez-TZ
+ 0x07d00000: 61, // bg
+ 0x07d00037: 62, // bg-BG
+ 0x08100000: 63, // bh
+ 0x09e00000: 64, // bm
+ 0x09e000c2: 65, // bm-ML
+ 0x0a300000: 66, // bn
+ 0x0a300034: 67, // bn-BD
+ 0x0a300098: 68, // bn-IN
+ 0x0a700000: 69, // bo
+ 0x0a700052: 70, // bo-CN
+ 0x0a700098: 71, // bo-IN
+ 0x0b000000: 72, // br
+ 0x0b000077: 73, // br-FR
+ 0x0b300000: 74, // brx
+ 0x0b300098: 75, // brx-IN
+ 0x0b500000: 76, // bs
+ 0x0b51e000: 77, // bs-Cyrl
+ 0x0b51e032: 78, // bs-Cyrl-BA
+ 0x0b552000: 79, // bs-Latn
+ 0x0b552032: 80, // bs-Latn-BA
+ 0x0d500000: 81, // ca
+ 0x0d500021: 82, // ca-AD
+ 0x0d50006d: 83, // ca-ES
+ 0x0d500077: 84, // ca-FR
+ 0x0d50009d: 85, // ca-IT
+ 0x0da00000: 86, // ce
+ 0x0da00105: 87, // ce-RU
+ 0x0dd00000: 88, // cgg
+ 0x0dd00130: 89, // cgg-UG
+ 0x0e300000: 90, // chr
+ 0x0e300134: 91, // chr-US
+ 0x0e700000: 92, // ckb
+ 0x0e70009a: 93, // ckb-IQ
+ 0x0e70009b: 94, // ckb-IR
+ 0x0f600000: 95, // cs
+ 0x0f60005d: 96, // cs-CZ
+ 0x0fa00000: 97, // cu
+ 0x0fa00105: 98, // cu-RU
+ 0x0fc00000: 99, // cy
+ 0x0fc0007a: 100, // cy-GB
+ 0x0fd00000: 101, // da
+ 0x0fd00062: 102, // da-DK
+ 0x0fd00081: 103, // da-GL
+ 0x10400000: 104, // dav
+ 0x104000a3: 105, // dav-KE
+ 0x10900000: 106, // de
+ 0x1090002d: 107, // de-AT
+ 0x10900035: 108, // de-BE
+ 0x1090004d: 109, // de-CH
+ 0x1090005f: 110, // de-DE
+ 0x1090009d: 111, // de-IT
+ 0x109000b1: 112, // de-LI
+ 0x109000b6: 113, // de-LU
+ 0x11300000: 114, // dje
+ 0x113000d3: 115, // dje-NE
+ 0x11b00000: 116, // dsb
+ 0x11b0005f: 117, // dsb-DE
+ 0x12000000: 118, // dua
+ 0x12000051: 119, // dua-CM
+ 0x12400000: 120, // dv
+ 0x12700000: 121, // dyo
+ 0x12700113: 122, // dyo-SN
+ 0x12900000: 123, // dz
+ 0x12900042: 124, // dz-BT
+ 0x12b00000: 125, // ebu
+ 0x12b000a3: 126, // ebu-KE
+ 0x12c00000: 127, // ee
+ 0x12c0007f: 128, // ee-GH
+ 0x12c00121: 129, // ee-TG
+ 0x13100000: 130, // el
+ 0x1310005c: 131, // el-CY
+ 0x13100086: 132, // el-GR
+ 0x13400000: 133, // en
+ 0x13400001: 134, // en-001
+ 0x1340001a: 135, // en-150
+ 0x13400024: 136, // en-AG
+ 0x13400025: 137, // en-AI
+ 0x1340002c: 138, // en-AS
+ 0x1340002d: 139, // en-AT
+ 0x1340002e: 140, // en-AU
+ 0x13400033: 141, // en-BB
+ 0x13400035: 142, // en-BE
+ 0x13400039: 143, // en-BI
+ 0x1340003c: 144, // en-BM
+ 0x13400041: 145, // en-BS
+ 0x13400045: 146, // en-BW
+ 0x13400047: 147, // en-BZ
+ 0x13400048: 148, // en-CA
+ 0x13400049: 149, // en-CC
+ 0x1340004d: 150, // en-CH
+ 0x1340004f: 151, // en-CK
+ 0x13400051: 152, // en-CM
+ 0x1340005b: 153, // en-CX
+ 0x1340005c: 154, // en-CY
+ 0x1340005f: 155, // en-DE
+ 0x13400060: 156, // en-DG
+ 0x13400062: 157, // en-DK
+ 0x13400063: 158, // en-DM
+ 0x1340006c: 159, // en-ER
+ 0x13400071: 160, // en-FI
+ 0x13400072: 161, // en-FJ
+ 0x13400073: 162, // en-FK
+ 0x13400074: 163, // en-FM
+ 0x1340007a: 164, // en-GB
+ 0x1340007b: 165, // en-GD
+ 0x1340007e: 166, // en-GG
+ 0x1340007f: 167, // en-GH
+ 0x13400080: 168, // en-GI
+ 0x13400082: 169, // en-GM
+ 0x13400089: 170, // en-GU
+ 0x1340008b: 171, // en-GY
+ 0x1340008c: 172, // en-HK
+ 0x13400095: 173, // en-IE
+ 0x13400096: 174, // en-IL
+ 0x13400097: 175, // en-IM
+ 0x13400098: 176, // en-IN
+ 0x13400099: 177, // en-IO
+ 0x1340009e: 178, // en-JE
+ 0x1340009f: 179, // en-JM
+ 0x134000a3: 180, // en-KE
+ 0x134000a6: 181, // en-KI
+ 0x134000a8: 182, // en-KN
+ 0x134000ac: 183, // en-KY
+ 0x134000b0: 184, // en-LC
+ 0x134000b3: 185, // en-LR
+ 0x134000b4: 186, // en-LS
+ 0x134000be: 187, // en-MG
+ 0x134000bf: 188, // en-MH
+ 0x134000c5: 189, // en-MO
+ 0x134000c6: 190, // en-MP
+ 0x134000c9: 191, // en-MS
+ 0x134000ca: 192, // en-MT
+ 0x134000cb: 193, // en-MU
+ 0x134000cd: 194, // en-MW
+ 0x134000cf: 195, // en-MY
+ 0x134000d1: 196, // en-NA
+ 0x134000d4: 197, // en-NF
+ 0x134000d5: 198, // en-NG
+ 0x134000d8: 199, // en-NL
+ 0x134000dc: 200, // en-NR
+ 0x134000de: 201, // en-NU
+ 0x134000df: 202, // en-NZ
+ 0x134000e5: 203, // en-PG
+ 0x134000e6: 204, // en-PH
+ 0x134000e7: 205, // en-PK
+ 0x134000ea: 206, // en-PN
+ 0x134000eb: 207, // en-PR
+ 0x134000ef: 208, // en-PW
+ 0x13400106: 209, // en-RW
+ 0x13400108: 210, // en-SB
+ 0x13400109: 211, // en-SC
+ 0x1340010a: 212, // en-SD
+ 0x1340010b: 213, // en-SE
+ 0x1340010c: 214, // en-SG
+ 0x1340010d: 215, // en-SH
+ 0x1340010e: 216, // en-SI
+ 0x13400111: 217, // en-SL
+ 0x13400116: 218, // en-SS
+ 0x1340011a: 219, // en-SX
+ 0x1340011c: 220, // en-SZ
+ 0x1340011e: 221, // en-TC
+ 0x13400124: 222, // en-TK
+ 0x13400128: 223, // en-TO
+ 0x1340012b: 224, // en-TT
+ 0x1340012c: 225, // en-TV
+ 0x1340012e: 226, // en-TZ
+ 0x13400130: 227, // en-UG
+ 0x13400132: 228, // en-UM
+ 0x13400134: 229, // en-US
+ 0x13400138: 230, // en-VC
+ 0x1340013b: 231, // en-VG
+ 0x1340013c: 232, // en-VI
+ 0x1340013e: 233, // en-VU
+ 0x13400141: 234, // en-WS
+ 0x13400160: 235, // en-ZA
+ 0x13400161: 236, // en-ZM
+ 0x13400163: 237, // en-ZW
+ 0x13700000: 238, // eo
+ 0x13700001: 239, // eo-001
+ 0x13900000: 240, // es
+ 0x1390001e: 241, // es-419
+ 0x1390002b: 242, // es-AR
+ 0x1390003e: 243, // es-BO
+ 0x13900040: 244, // es-BR
+ 0x13900050: 245, // es-CL
+ 0x13900053: 246, // es-CO
+ 0x13900055: 247, // es-CR
+ 0x13900058: 248, // es-CU
+ 0x13900064: 249, // es-DO
+ 0x13900067: 250, // es-EA
+ 0x13900068: 251, // es-EC
+ 0x1390006d: 252, // es-ES
+ 0x13900085: 253, // es-GQ
+ 0x13900088: 254, // es-GT
+ 0x1390008e: 255, // es-HN
+ 0x13900093: 256, // es-IC
+ 0x139000ce: 257, // es-MX
+ 0x139000d7: 258, // es-NI
+ 0x139000e1: 259, // es-PA
+ 0x139000e3: 260, // es-PE
+ 0x139000e6: 261, // es-PH
+ 0x139000eb: 262, // es-PR
+ 0x139000f0: 263, // es-PY
+ 0x13900119: 264, // es-SV
+ 0x13900134: 265, // es-US
+ 0x13900135: 266, // es-UY
+ 0x1390013a: 267, // es-VE
+ 0x13b00000: 268, // et
+ 0x13b00069: 269, // et-EE
+ 0x14000000: 270, // eu
+ 0x1400006d: 271, // eu-ES
+ 0x14100000: 272, // ewo
+ 0x14100051: 273, // ewo-CM
+ 0x14300000: 274, // fa
+ 0x14300023: 275, // fa-AF
+ 0x1430009b: 276, // fa-IR
+ 0x14900000: 277, // ff
+ 0x14900051: 278, // ff-CM
+ 0x14900083: 279, // ff-GN
+ 0x149000c8: 280, // ff-MR
+ 0x14900113: 281, // ff-SN
+ 0x14c00000: 282, // fi
+ 0x14c00071: 283, // fi-FI
+ 0x14e00000: 284, // fil
+ 0x14e000e6: 285, // fil-PH
+ 0x15300000: 286, // fo
+ 0x15300062: 287, // fo-DK
+ 0x15300075: 288, // fo-FO
+ 0x15900000: 289, // fr
+ 0x15900035: 290, // fr-BE
+ 0x15900036: 291, // fr-BF
+ 0x15900039: 292, // fr-BI
+ 0x1590003a: 293, // fr-BJ
+ 0x1590003b: 294, // fr-BL
+ 0x15900048: 295, // fr-CA
+ 0x1590004a: 296, // fr-CD
+ 0x1590004b: 297, // fr-CF
+ 0x1590004c: 298, // fr-CG
+ 0x1590004d: 299, // fr-CH
+ 0x1590004e: 300, // fr-CI
+ 0x15900051: 301, // fr-CM
+ 0x15900061: 302, // fr-DJ
+ 0x15900066: 303, // fr-DZ
+ 0x15900077: 304, // fr-FR
+ 0x15900079: 305, // fr-GA
+ 0x1590007d: 306, // fr-GF
+ 0x15900083: 307, // fr-GN
+ 0x15900084: 308, // fr-GP
+ 0x15900085: 309, // fr-GQ
+ 0x15900090: 310, // fr-HT
+ 0x159000a7: 311, // fr-KM
+ 0x159000b6: 312, // fr-LU
+ 0x159000b9: 313, // fr-MA
+ 0x159000ba: 314, // fr-MC
+ 0x159000bd: 315, // fr-MF
+ 0x159000be: 316, // fr-MG
+ 0x159000c2: 317, // fr-ML
+ 0x159000c7: 318, // fr-MQ
+ 0x159000c8: 319, // fr-MR
+ 0x159000cb: 320, // fr-MU
+ 0x159000d2: 321, // fr-NC
+ 0x159000d3: 322, // fr-NE
+ 0x159000e4: 323, // fr-PF
+ 0x159000e9: 324, // fr-PM
+ 0x15900101: 325, // fr-RE
+ 0x15900106: 326, // fr-RW
+ 0x15900109: 327, // fr-SC
+ 0x15900113: 328, // fr-SN
+ 0x1590011b: 329, // fr-SY
+ 0x1590011f: 330, // fr-TD
+ 0x15900121: 331, // fr-TG
+ 0x15900127: 332, // fr-TN
+ 0x1590013e: 333, // fr-VU
+ 0x1590013f: 334, // fr-WF
+ 0x1590015e: 335, // fr-YT
+ 0x16400000: 336, // fur
+ 0x1640009d: 337, // fur-IT
+ 0x16800000: 338, // fy
+ 0x168000d8: 339, // fy-NL
+ 0x16900000: 340, // ga
+ 0x16900095: 341, // ga-IE
+ 0x17800000: 342, // gd
+ 0x1780007a: 343, // gd-GB
+ 0x18a00000: 344, // gl
+ 0x18a0006d: 345, // gl-ES
+ 0x19c00000: 346, // gsw
+ 0x19c0004d: 347, // gsw-CH
+ 0x19c00077: 348, // gsw-FR
+ 0x19c000b1: 349, // gsw-LI
+ 0x19d00000: 350, // gu
+ 0x19d00098: 351, // gu-IN
+ 0x1a200000: 352, // guw
+ 0x1a400000: 353, // guz
+ 0x1a4000a3: 354, // guz-KE
+ 0x1a500000: 355, // gv
+ 0x1a500097: 356, // gv-IM
+ 0x1ad00000: 357, // ha
+ 0x1ad0007f: 358, // ha-GH
+ 0x1ad000d3: 359, // ha-NE
+ 0x1ad000d5: 360, // ha-NG
+ 0x1b100000: 361, // haw
+ 0x1b100134: 362, // haw-US
+ 0x1b500000: 363, // he
+ 0x1b500096: 364, // he-IL
+ 0x1b700000: 365, // hi
+ 0x1b700098: 366, // hi-IN
+ 0x1ca00000: 367, // hr
+ 0x1ca00032: 368, // hr-BA
+ 0x1ca0008f: 369, // hr-HR
+ 0x1cb00000: 370, // hsb
+ 0x1cb0005f: 371, // hsb-DE
+ 0x1ce00000: 372, // hu
+ 0x1ce00091: 373, // hu-HU
+ 0x1d000000: 374, // hy
+ 0x1d000027: 375, // hy-AM
+ 0x1da00000: 376, // id
+ 0x1da00094: 377, // id-ID
+ 0x1df00000: 378, // ig
+ 0x1df000d5: 379, // ig-NG
+ 0x1e200000: 380, // ii
+ 0x1e200052: 381, // ii-CN
+ 0x1f000000: 382, // is
+ 0x1f00009c: 383, // is-IS
+ 0x1f100000: 384, // it
+ 0x1f10004d: 385, // it-CH
+ 0x1f10009d: 386, // it-IT
+ 0x1f100112: 387, // it-SM
+ 0x1f200000: 388, // iu
+ 0x1f800000: 389, // ja
+ 0x1f8000a1: 390, // ja-JP
+ 0x1fb00000: 391, // jbo
+ 0x1ff00000: 392, // jgo
+ 0x1ff00051: 393, // jgo-CM
+ 0x20200000: 394, // jmc
+ 0x2020012e: 395, // jmc-TZ
+ 0x20600000: 396, // jv
+ 0x20800000: 397, // ka
+ 0x2080007c: 398, // ka-GE
+ 0x20a00000: 399, // kab
+ 0x20a00066: 400, // kab-DZ
+ 0x20e00000: 401, // kaj
+ 0x20f00000: 402, // kam
+ 0x20f000a3: 403, // kam-KE
+ 0x21700000: 404, // kcg
+ 0x21b00000: 405, // kde
+ 0x21b0012e: 406, // kde-TZ
+ 0x21f00000: 407, // kea
+ 0x21f00059: 408, // kea-CV
+ 0x22c00000: 409, // khq
+ 0x22c000c2: 410, // khq-ML
+ 0x23100000: 411, // ki
+ 0x231000a3: 412, // ki-KE
+ 0x23a00000: 413, // kk
+ 0x23a000ad: 414, // kk-KZ
+ 0x23c00000: 415, // kkj
+ 0x23c00051: 416, // kkj-CM
+ 0x23d00000: 417, // kl
+ 0x23d00081: 418, // kl-GL
+ 0x23e00000: 419, // kln
+ 0x23e000a3: 420, // kln-KE
+ 0x24200000: 421, // km
+ 0x242000a5: 422, // km-KH
+ 0x24900000: 423, // kn
+ 0x24900098: 424, // kn-IN
+ 0x24b00000: 425, // ko
+ 0x24b000a9: 426, // ko-KP
+ 0x24b000aa: 427, // ko-KR
+ 0x24d00000: 428, // kok
+ 0x24d00098: 429, // kok-IN
+ 0x26100000: 430, // ks
+ 0x26100098: 431, // ks-IN
+ 0x26200000: 432, // ksb
+ 0x2620012e: 433, // ksb-TZ
+ 0x26400000: 434, // ksf
+ 0x26400051: 435, // ksf-CM
+ 0x26500000: 436, // ksh
+ 0x2650005f: 437, // ksh-DE
+ 0x26b00000: 438, // ku
+ 0x27800000: 439, // kw
+ 0x2780007a: 440, // kw-GB
+ 0x28100000: 441, // ky
+ 0x281000a4: 442, // ky-KG
+ 0x28800000: 443, // lag
+ 0x2880012e: 444, // lag-TZ
+ 0x28c00000: 445, // lb
+ 0x28c000b6: 446, // lb-LU
+ 0x29a00000: 447, // lg
+ 0x29a00130: 448, // lg-UG
+ 0x2a600000: 449, // lkt
+ 0x2a600134: 450, // lkt-US
+ 0x2ac00000: 451, // ln
+ 0x2ac00029: 452, // ln-AO
+ 0x2ac0004a: 453, // ln-CD
+ 0x2ac0004b: 454, // ln-CF
+ 0x2ac0004c: 455, // ln-CG
+ 0x2af00000: 456, // lo
+ 0x2af000ae: 457, // lo-LA
+ 0x2b600000: 458, // lrc
+ 0x2b60009a: 459, // lrc-IQ
+ 0x2b60009b: 460, // lrc-IR
+ 0x2b700000: 461, // lt
+ 0x2b7000b5: 462, // lt-LT
+ 0x2b900000: 463, // lu
+ 0x2b90004a: 464, // lu-CD
+ 0x2bb00000: 465, // luo
+ 0x2bb000a3: 466, // luo-KE
+ 0x2bc00000: 467, // luy
+ 0x2bc000a3: 468, // luy-KE
+ 0x2be00000: 469, // lv
+ 0x2be000b7: 470, // lv-LV
+ 0x2c800000: 471, // mas
+ 0x2c8000a3: 472, // mas-KE
+ 0x2c80012e: 473, // mas-TZ
+ 0x2e000000: 474, // mer
+ 0x2e0000a3: 475, // mer-KE
+ 0x2e400000: 476, // mfe
+ 0x2e4000cb: 477, // mfe-MU
+ 0x2e800000: 478, // mg
+ 0x2e8000be: 479, // mg-MG
+ 0x2e900000: 480, // mgh
+ 0x2e9000d0: 481, // mgh-MZ
+ 0x2eb00000: 482, // mgo
+ 0x2eb00051: 483, // mgo-CM
+ 0x2f600000: 484, // mk
+ 0x2f6000c1: 485, // mk-MK
+ 0x2fb00000: 486, // ml
+ 0x2fb00098: 487, // ml-IN
+ 0x30200000: 488, // mn
+ 0x302000c4: 489, // mn-MN
+ 0x31200000: 490, // mr
+ 0x31200098: 491, // mr-IN
+ 0x31600000: 492, // ms
+ 0x3160003d: 493, // ms-BN
+ 0x316000cf: 494, // ms-MY
+ 0x3160010c: 495, // ms-SG
+ 0x31700000: 496, // mt
+ 0x317000ca: 497, // mt-MT
+ 0x31c00000: 498, // mua
+ 0x31c00051: 499, // mua-CM
+ 0x32800000: 500, // my
+ 0x328000c3: 501, // my-MM
+ 0x33100000: 502, // mzn
+ 0x3310009b: 503, // mzn-IR
+ 0x33800000: 504, // nah
+ 0x33c00000: 505, // naq
+ 0x33c000d1: 506, // naq-NA
+ 0x33e00000: 507, // nb
+ 0x33e000d9: 508, // nb-NO
+ 0x33e0010f: 509, // nb-SJ
+ 0x34500000: 510, // nd
+ 0x34500163: 511, // nd-ZW
+ 0x34700000: 512, // nds
+ 0x3470005f: 513, // nds-DE
+ 0x347000d8: 514, // nds-NL
+ 0x34800000: 515, // ne
+ 0x34800098: 516, // ne-IN
+ 0x348000da: 517, // ne-NP
+ 0x35e00000: 518, // nl
+ 0x35e0002f: 519, // nl-AW
+ 0x35e00035: 520, // nl-BE
+ 0x35e0003f: 521, // nl-BQ
+ 0x35e0005a: 522, // nl-CW
+ 0x35e000d8: 523, // nl-NL
+ 0x35e00115: 524, // nl-SR
+ 0x35e0011a: 525, // nl-SX
+ 0x35f00000: 526, // nmg
+ 0x35f00051: 527, // nmg-CM
+ 0x36100000: 528, // nn
+ 0x361000d9: 529, // nn-NO
+ 0x36300000: 530, // nnh
+ 0x36300051: 531, // nnh-CM
+ 0x36600000: 532, // no
+ 0x36c00000: 533, // nqo
+ 0x36d00000: 534, // nr
+ 0x37100000: 535, // nso
+ 0x37700000: 536, // nus
+ 0x37700116: 537, // nus-SS
+ 0x37e00000: 538, // ny
+ 0x38000000: 539, // nyn
+ 0x38000130: 540, // nyn-UG
+ 0x38700000: 541, // om
+ 0x3870006e: 542, // om-ET
+ 0x387000a3: 543, // om-KE
+ 0x38c00000: 544, // or
+ 0x38c00098: 545, // or-IN
+ 0x38f00000: 546, // os
+ 0x38f0007c: 547, // os-GE
+ 0x38f00105: 548, // os-RU
+ 0x39400000: 549, // pa
+ 0x39405000: 550, // pa-Arab
+ 0x394050e7: 551, // pa-Arab-PK
+ 0x3942f000: 552, // pa-Guru
+ 0x3942f098: 553, // pa-Guru-IN
+ 0x39800000: 554, // pap
+ 0x3aa00000: 555, // pl
+ 0x3aa000e8: 556, // pl-PL
+ 0x3b400000: 557, // prg
+ 0x3b400001: 558, // prg-001
+ 0x3b500000: 559, // ps
+ 0x3b500023: 560, // ps-AF
+ 0x3b700000: 561, // pt
+ 0x3b700029: 562, // pt-AO
+ 0x3b700040: 563, // pt-BR
+ 0x3b70004d: 564, // pt-CH
+ 0x3b700059: 565, // pt-CV
+ 0x3b700085: 566, // pt-GQ
+ 0x3b70008a: 567, // pt-GW
+ 0x3b7000b6: 568, // pt-LU
+ 0x3b7000c5: 569, // pt-MO
+ 0x3b7000d0: 570, // pt-MZ
+ 0x3b7000ed: 571, // pt-PT
+ 0x3b700117: 572, // pt-ST
+ 0x3b700125: 573, // pt-TL
+ 0x3bb00000: 574, // qu
+ 0x3bb0003e: 575, // qu-BO
+ 0x3bb00068: 576, // qu-EC
+ 0x3bb000e3: 577, // qu-PE
+ 0x3cb00000: 578, // rm
+ 0x3cb0004d: 579, // rm-CH
+ 0x3d000000: 580, // rn
+ 0x3d000039: 581, // rn-BI
+ 0x3d300000: 582, // ro
+ 0x3d3000bb: 583, // ro-MD
+ 0x3d300103: 584, // ro-RO
+ 0x3d500000: 585, // rof
+ 0x3d50012e: 586, // rof-TZ
+ 0x3d900000: 587, // ru
+ 0x3d900046: 588, // ru-BY
+ 0x3d9000a4: 589, // ru-KG
+ 0x3d9000ad: 590, // ru-KZ
+ 0x3d9000bb: 591, // ru-MD
+ 0x3d900105: 592, // ru-RU
+ 0x3d90012f: 593, // ru-UA
+ 0x3dc00000: 594, // rw
+ 0x3dc00106: 595, // rw-RW
+ 0x3dd00000: 596, // rwk
+ 0x3dd0012e: 597, // rwk-TZ
+ 0x3e200000: 598, // sah
+ 0x3e200105: 599, // sah-RU
+ 0x3e300000: 600, // saq
+ 0x3e3000a3: 601, // saq-KE
+ 0x3e900000: 602, // sbp
+ 0x3e90012e: 603, // sbp-TZ
+ 0x3f200000: 604, // sdh
+ 0x3f300000: 605, // se
+ 0x3f300071: 606, // se-FI
+ 0x3f3000d9: 607, // se-NO
+ 0x3f30010b: 608, // se-SE
+ 0x3f500000: 609, // seh
+ 0x3f5000d0: 610, // seh-MZ
+ 0x3f700000: 611, // ses
+ 0x3f7000c2: 612, // ses-ML
+ 0x3f800000: 613, // sg
+ 0x3f80004b: 614, // sg-CF
+ 0x3fe00000: 615, // shi
+ 0x3fe52000: 616, // shi-Latn
+ 0x3fe520b9: 617, // shi-Latn-MA
+ 0x3fed2000: 618, // shi-Tfng
+ 0x3fed20b9: 619, // shi-Tfng-MA
+ 0x40200000: 620, // si
+ 0x402000b2: 621, // si-LK
+ 0x40800000: 622, // sk
+ 0x40800110: 623, // sk-SK
+ 0x40c00000: 624, // sl
+ 0x40c0010e: 625, // sl-SI
+ 0x41200000: 626, // sma
+ 0x41300000: 627, // smi
+ 0x41400000: 628, // smj
+ 0x41500000: 629, // smn
+ 0x41500071: 630, // smn-FI
+ 0x41800000: 631, // sms
+ 0x41900000: 632, // sn
+ 0x41900163: 633, // sn-ZW
+ 0x41f00000: 634, // so
+ 0x41f00061: 635, // so-DJ
+ 0x41f0006e: 636, // so-ET
+ 0x41f000a3: 637, // so-KE
+ 0x41f00114: 638, // so-SO
+ 0x42700000: 639, // sq
+ 0x42700026: 640, // sq-AL
+ 0x427000c1: 641, // sq-MK
+ 0x4270014c: 642, // sq-XK
+ 0x42800000: 643, // sr
+ 0x4281e000: 644, // sr-Cyrl
+ 0x4281e032: 645, // sr-Cyrl-BA
+ 0x4281e0bc: 646, // sr-Cyrl-ME
+ 0x4281e104: 647, // sr-Cyrl-RS
+ 0x4281e14c: 648, // sr-Cyrl-XK
+ 0x42852000: 649, // sr-Latn
+ 0x42852032: 650, // sr-Latn-BA
+ 0x428520bc: 651, // sr-Latn-ME
+ 0x42852104: 652, // sr-Latn-RS
+ 0x4285214c: 653, // sr-Latn-XK
+ 0x42d00000: 654, // ss
+ 0x43000000: 655, // ssy
+ 0x43100000: 656, // st
+ 0x43a00000: 657, // sv
+ 0x43a00030: 658, // sv-AX
+ 0x43a00071: 659, // sv-FI
+ 0x43a0010b: 660, // sv-SE
+ 0x43b00000: 661, // sw
+ 0x43b0004a: 662, // sw-CD
+ 0x43b000a3: 663, // sw-KE
+ 0x43b0012e: 664, // sw-TZ
+ 0x43b00130: 665, // sw-UG
+ 0x44400000: 666, // syr
+ 0x44600000: 667, // ta
+ 0x44600098: 668, // ta-IN
+ 0x446000b2: 669, // ta-LK
+ 0x446000cf: 670, // ta-MY
+ 0x4460010c: 671, // ta-SG
+ 0x45700000: 672, // te
+ 0x45700098: 673, // te-IN
+ 0x45a00000: 674, // teo
+ 0x45a000a3: 675, // teo-KE
+ 0x45a00130: 676, // teo-UG
+ 0x46100000: 677, // th
+ 0x46100122: 678, // th-TH
+ 0x46500000: 679, // ti
+ 0x4650006c: 680, // ti-ER
+ 0x4650006e: 681, // ti-ET
+ 0x46700000: 682, // tig
+ 0x46c00000: 683, // tk
+ 0x46c00126: 684, // tk-TM
+ 0x47600000: 685, // tn
+ 0x47800000: 686, // to
+ 0x47800128: 687, // to-TO
+ 0x48000000: 688, // tr
+ 0x4800005c: 689, // tr-CY
+ 0x4800012a: 690, // tr-TR
+ 0x48400000: 691, // ts
+ 0x49a00000: 692, // twq
+ 0x49a000d3: 693, // twq-NE
+ 0x49f00000: 694, // tzm
+ 0x49f000b9: 695, // tzm-MA
+ 0x4a200000: 696, // ug
+ 0x4a200052: 697, // ug-CN
+ 0x4a400000: 698, // uk
+ 0x4a40012f: 699, // uk-UA
+ 0x4aa00000: 700, // ur
+ 0x4aa00098: 701, // ur-IN
+ 0x4aa000e7: 702, // ur-PK
+ 0x4b200000: 703, // uz
+ 0x4b205000: 704, // uz-Arab
+ 0x4b205023: 705, // uz-Arab-AF
+ 0x4b21e000: 706, // uz-Cyrl
+ 0x4b21e136: 707, // uz-Cyrl-UZ
+ 0x4b252000: 708, // uz-Latn
+ 0x4b252136: 709, // uz-Latn-UZ
+ 0x4b400000: 710, // vai
+ 0x4b452000: 711, // vai-Latn
+ 0x4b4520b3: 712, // vai-Latn-LR
+ 0x4b4d9000: 713, // vai-Vaii
+ 0x4b4d90b3: 714, // vai-Vaii-LR
+ 0x4b600000: 715, // ve
+ 0x4b900000: 716, // vi
+ 0x4b90013d: 717, // vi-VN
+ 0x4bf00000: 718, // vo
+ 0x4bf00001: 719, // vo-001
+ 0x4c200000: 720, // vun
+ 0x4c20012e: 721, // vun-TZ
+ 0x4c400000: 722, // wa
+ 0x4c500000: 723, // wae
+ 0x4c50004d: 724, // wae-CH
+ 0x4db00000: 725, // wo
+ 0x4e800000: 726, // xh
+ 0x4f100000: 727, // xog
+ 0x4f100130: 728, // xog-UG
+ 0x4ff00000: 729, // yav
+ 0x4ff00051: 730, // yav-CM
+ 0x50800000: 731, // yi
+ 0x50800001: 732, // yi-001
+ 0x50e00000: 733, // yo
+ 0x50e0003a: 734, // yo-BJ
+ 0x50e000d5: 735, // yo-NG
+ 0x51500000: 736, // yue
+ 0x5150008c: 737, // yue-HK
+ 0x51e00000: 738, // zgh
+ 0x51e000b9: 739, // zgh-MA
+ 0x51f00000: 740, // zh
+ 0x51f34000: 741, // zh-Hans
+ 0x51f34052: 742, // zh-Hans-CN
+ 0x51f3408c: 743, // zh-Hans-HK
+ 0x51f340c5: 744, // zh-Hans-MO
+ 0x51f3410c: 745, // zh-Hans-SG
+ 0x51f35000: 746, // zh-Hant
+ 0x51f3508c: 747, // zh-Hant-HK
+ 0x51f350c5: 748, // zh-Hant-MO
+ 0x51f3512d: 749, // zh-Hant-TW
+ 0x52400000: 750, // zu
+ 0x52400160: 751, // zu-ZA
+}
+
+// Total table size 4580 bytes (4KiB); checksum: A7F72A2A
diff --git a/vendor/golang.org/x/text/language/language.go b/vendor/golang.org/x/text/language/language.go
new file mode 100644
index 000000000..5eecceb61
--- /dev/null
+++ b/vendor/golang.org/x/text/language/language.go
@@ -0,0 +1,975 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run maketables.go gen_common.go -output tables.go
+//go:generate go run gen_index.go
+
+// Package language implements BCP 47 language tags and related functionality.
+//
+// The Tag type, which is used to represent languages, is agnostic to the
+// meaning of its subtags. Tags are not fully canonicalized to preserve
+// information that may be valuable in certain contexts. As a consequence, two
+// different tags may represent identical languages.
+//
+// Initializing language- or locale-specific components usually consists of
+// two steps. The first step is to select a display language based on the
+// preferred languages of the user and the languages supported by an application.
+// The second step is to create the language-specific services based on
+// this selection. Each is discussed in more details below.
+//
+// Matching preferred against supported languages
+//
+// An application may support various languages. This list is typically limited
+// by the languages for which there exists translations of the user interface.
+// Similarly, a user may provide a list of preferred languages which is limited
+// by the languages understood by this user.
+// An application should use a Matcher to find the best supported language based
+// on the user's preferred list.
+// Matchers are aware of the intricacies of equivalence between languages.
+// The default Matcher implementation takes into account things such as
+// deprecated subtags, legacy tags, and mutual intelligibility between scripts
+// and languages.
+//
+// A Matcher for English, Australian English, Danish, and standard Mandarin can
+// be defined as follows:
+//
+// var matcher = language.NewMatcher([]language.Tag{
+// language.English, // The first language is used as fallback.
+// language.MustParse("en-AU"),
+// language.Danish,
+// language.Chinese,
+// })
+//
+// The following code selects the best match for someone speaking Spanish and
+// Norwegian:
+//
+// preferred := []language.Tag{ language.Spanish, language.Norwegian }
+// tag, _, _ := matcher.Match(preferred...)
+//
+// In this case, the best match is Danish, as Danish is sufficiently a match to
+// Norwegian to not have to fall back to the default.
+// See ParseAcceptLanguage on how to handle the Accept-Language HTTP header.
+//
+// Selecting language-specific services
+//
+// One should always use the Tag returned by the Matcher to create an instance
+// of any of the language-specific services provided by the text repository.
+// This prevents the mixing of languages, such as having a different language for
+// messages and display names, as well as improper casing or sorting order for
+// the selected language.
+// Using the returned Tag also allows user-defined settings, such as collation
+// order or numbering system to be transparently passed as options.
+//
+// If you have language-specific data in your application, however, it will in
+// most cases suffice to use the index returned by the matcher to identify
+// the user language.
+// The following loop provides an alternative in case this is not sufficient:
+//
+// supported := map[language.Tag]data{
+// language.English: enData,
+// language.MustParse("en-AU"): enAUData,
+// language.Danish: daData,
+// language.Chinese: zhData,
+// }
+// tag, _, _ := matcher.Match(preferred...)
+// for ; tag != language.Und; tag = tag.Parent() {
+// if v, ok := supported[tag]; ok {
+// return v
+// }
+// }
+// return enData // should not reach here
+//
+// Repeatedly taking the Parent of the tag returned by Match will eventually
+// match one of the tags used to initialize the Matcher.
+//
+// Canonicalization
+//
+// By default, only legacy and deprecated tags are converted into their
+// canonical equivalent. All other information is preserved. This approach makes
+// the confidence scores more accurate and allows matchers to distinguish
+// between variants that are otherwise lost.
+//
+// As a consequence, two tags that should be treated as identical according to
+// BCP 47 or CLDR, like "en-Latn" and "en", will be represented differently. The
+// Matchers will handle such distinctions, though, and are aware of the
+// equivalence relations. The CanonType type can be used to alter the
+// canonicalization form.
+//
+// References
+//
+// BCP 47 - Tags for Identifying Languages
+// http://tools.ietf.org/html/bcp47
+package language // import "golang.org/x/text/language"
+
+// TODO: Remove above NOTE after:
+// - verifying that tables are dropped correctly (most notably matcher tables).
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+const (
+ // maxCoreSize is the maximum size of a BCP 47 tag without variants and
+ // extensions. Equals max lang (3) + script (4) + max reg (3) + 2 dashes.
+ maxCoreSize = 12
+
+ // max99thPercentileSize is a somewhat arbitrary buffer size that presumably
+ // is large enough to hold at least 99% of the BCP 47 tags.
+ max99thPercentileSize = 32
+
+ // maxSimpleUExtensionSize is the maximum size of a -u extension with one
+ // key-type pair. Equals len("-u-") + key (2) + dash + max value (8).
+ maxSimpleUExtensionSize = 14
+)
+
+// Tag represents a BCP 47 language tag. It is used to specify an instance of a
+// specific language or locale. All language tag values are guaranteed to be
+// well-formed.
+type Tag struct {
+ lang langID
+ region regionID
+ script scriptID
+ pVariant byte // offset in str, includes preceding '-'
+ pExt uint16 // offset of first extension, includes preceding '-'
+
+ // str is the string representation of the Tag. It will only be used if the
+ // tag has variants or extensions.
+ str string
+}
+
+// Make is a convenience wrapper for Parse that omits the error.
+// In case of an error, a sensible default is returned.
+func Make(s string) Tag {
+ return Default.Make(s)
+}
+
+// Make is a convenience wrapper for c.Parse that omits the error.
+// In case of an error, a sensible default is returned.
+func (c CanonType) Make(s string) Tag {
+ t, _ := c.Parse(s)
+ return t
+}
+
+// Raw returns the raw base language, script and region, without making an
+// attempt to infer their values.
+func (t Tag) Raw() (b Base, s Script, r Region) {
+ return Base{t.lang}, Script{t.script}, Region{t.region}
+}
+
+// equalTags compares language, script and region subtags only.
+func (t Tag) equalTags(a Tag) bool {
+ return t.lang == a.lang && t.script == a.script && t.region == a.region
+}
+
+// IsRoot returns true if t is equal to language "und".
+func (t Tag) IsRoot() bool {
+ if int(t.pVariant) < len(t.str) {
+ return false
+ }
+ return t.equalTags(und)
+}
+
+// private reports whether the Tag consists solely of a private use tag.
+func (t Tag) private() bool {
+ return t.str != "" && t.pVariant == 0
+}
+
+// CanonType can be used to enable or disable various types of canonicalization.
+type CanonType int
+
+const (
+ // Replace deprecated base languages with their preferred replacements.
+ DeprecatedBase CanonType = 1 << iota
+ // Replace deprecated scripts with their preferred replacements.
+ DeprecatedScript
+ // Replace deprecated regions with their preferred replacements.
+ DeprecatedRegion
+ // Remove redundant scripts.
+ SuppressScript
+ // Normalize legacy encodings. This includes legacy languages defined in
+ // CLDR as well as bibliographic codes defined in ISO-639.
+ Legacy
+ // Map the dominant language of a macro language group to the macro language
+ // subtag. For example cmn -> zh.
+ Macro
+ // The CLDR flag should be used if full compatibility with CLDR is required.
+ // There are a few cases where language.Tag may differ from CLDR. To follow all
+ // of CLDR's suggestions, use All|CLDR.
+ CLDR
+
+ // Raw can be used to Compose or Parse without Canonicalization.
+ Raw CanonType = 0
+
+ // Replace all deprecated tags with their preferred replacements.
+ Deprecated = DeprecatedBase | DeprecatedScript | DeprecatedRegion
+
+ // All canonicalizations recommended by BCP 47.
+ BCP47 = Deprecated | SuppressScript
+
+ // All canonicalizations.
+ All = BCP47 | Legacy | Macro
+
+ // Default is the canonicalization used by Parse, Make and Compose. To
+ // preserve as much information as possible, canonicalizations that remove
+ // potentially valuable information are not included. The Matcher is
+ // designed to recognize similar tags that would be the same if
+ // they were canonicalized using All.
+ Default = Deprecated | Legacy
+
+ canonLang = DeprecatedBase | Legacy | Macro
+
+ // TODO: LikelyScript, LikelyRegion: suppress similar to ICU.
+)
+
+// canonicalize returns the canonicalized equivalent of the tag and
+// whether there was any change.
+func (t Tag) canonicalize(c CanonType) (Tag, bool) {
+ if c == Raw {
+ return t, false
+ }
+ changed := false
+ if c&SuppressScript != 0 {
+ if t.lang < langNoIndexOffset && uint8(t.script) == suppressScript[t.lang] {
+ t.script = 0
+ changed = true
+ }
+ }
+ if c&canonLang != 0 {
+ for {
+ if l, aliasType := normLang(t.lang); l != t.lang {
+ switch aliasType {
+ case langLegacy:
+ if c&Legacy != 0 {
+ if t.lang == _sh && t.script == 0 {
+ t.script = _Latn
+ }
+ t.lang = l
+ changed = true
+ }
+ case langMacro:
+ if c&Macro != 0 {
+ // We deviate here from CLDR. The mapping "nb" -> "no"
+ // qualifies as a typical Macro language mapping. However,
+ // for legacy reasons, CLDR maps "no", the macro language
+ // code for Norwegian, to the dominant variant "nb". This
+ // change is currently under consideration for CLDR as well.
+ // See http://unicode.org/cldr/trac/ticket/2698 and also
+ // http://unicode.org/cldr/trac/ticket/1790 for some of the
+ // practical implications. TODO: this check could be removed
+ // if CLDR adopts this change.
+ if c&CLDR == 0 || t.lang != _nb {
+ changed = true
+ t.lang = l
+ }
+ }
+ case langDeprecated:
+ if c&DeprecatedBase != 0 {
+ if t.lang == _mo && t.region == 0 {
+ t.region = _MD
+ }
+ t.lang = l
+ changed = true
+ // Other canonicalization types may still apply.
+ continue
+ }
+ }
+ } else if c&Legacy != 0 && t.lang == _no && c&CLDR != 0 {
+ t.lang = _nb
+ changed = true
+ }
+ break
+ }
+ }
+ if c&DeprecatedScript != 0 {
+ if t.script == _Qaai {
+ changed = true
+ t.script = _Zinh
+ }
+ }
+ if c&DeprecatedRegion != 0 {
+ if r := normRegion(t.region); r != 0 {
+ changed = true
+ t.region = r
+ }
+ }
+ return t, changed
+}
+
+// Canonicalize returns the canonicalized equivalent of the tag.
+func (c CanonType) Canonicalize(t Tag) (Tag, error) {
+ t, changed := t.canonicalize(c)
+ if changed {
+ t.remakeString()
+ }
+ return t, nil
+}
+
+// Confidence indicates the level of certainty for a given return value.
+// For example, Serbian may be written in Cyrillic or Latin script.
+// The confidence level indicates whether a value was explicitly specified,
+// whether it is typically the only possible value, or whether there is
+// an ambiguity.
+type Confidence int
+
+const (
+ No Confidence = iota // full confidence that there was no match
+ Low // most likely value picked out of a set of alternatives
+ High // value is generally assumed to be the correct match
+ Exact // exact match or explicitly specified value
+)
+
+var confName = []string{"No", "Low", "High", "Exact"}
+
+func (c Confidence) String() string {
+ return confName[c]
+}
+
+// remakeString is used to update t.str in case lang, script or region changed.
+// It is assumed that pExt and pVariant still point to the start of the
+// respective parts.
+func (t *Tag) remakeString() {
+ if t.str == "" {
+ return
+ }
+ extra := t.str[t.pVariant:]
+ if t.pVariant > 0 {
+ extra = extra[1:]
+ }
+ if t.equalTags(und) && strings.HasPrefix(extra, "x-") {
+ t.str = extra
+ t.pVariant = 0
+ t.pExt = 0
+ return
+ }
+ var buf [max99thPercentileSize]byte // avoid extra memory allocation in most cases.
+ b := buf[:t.genCoreBytes(buf[:])]
+ if extra != "" {
+ diff := len(b) - int(t.pVariant)
+ b = append(b, '-')
+ b = append(b, extra...)
+ t.pVariant = uint8(int(t.pVariant) + diff)
+ t.pExt = uint16(int(t.pExt) + diff)
+ } else {
+ t.pVariant = uint8(len(b))
+ t.pExt = uint16(len(b))
+ }
+ t.str = string(b)
+}
+
+// genCoreBytes writes a string for the base languages, script and region tags
+// to the given buffer and returns the number of bytes written. It will never
+// write more than maxCoreSize bytes.
+func (t *Tag) genCoreBytes(buf []byte) int {
+ n := t.lang.stringToBuf(buf[:])
+ if t.script != 0 {
+ n += copy(buf[n:], "-")
+ n += copy(buf[n:], t.script.String())
+ }
+ if t.region != 0 {
+ n += copy(buf[n:], "-")
+ n += copy(buf[n:], t.region.String())
+ }
+ return n
+}
+
+// String returns the canonical string representation of the language tag.
+func (t Tag) String() string {
+ if t.str != "" {
+ return t.str
+ }
+ if t.script == 0 && t.region == 0 {
+ return t.lang.String()
+ }
+ buf := [maxCoreSize]byte{}
+ return string(buf[:t.genCoreBytes(buf[:])])
+}
+
+// Base returns the base language of the language tag. If the base language is
+// unspecified, an attempt will be made to infer it from the context.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Base() (Base, Confidence) {
+ if t.lang != 0 {
+ return Base{t.lang}, Exact
+ }
+ c := High
+ if t.script == 0 && !(Region{t.region}).IsCountry() {
+ c = Low
+ }
+ if tag, err := addTags(t); err == nil && tag.lang != 0 {
+ return Base{tag.lang}, c
+ }
+ return Base{0}, No
+}
+
+// Script infers the script for the language tag. If it was not explicitly given, it will infer
+// a most likely candidate.
+// If more than one script is commonly used for a language, the most likely one
+// is returned with a low confidence indication. For example, it returns (Cyrl, Low)
+// for Serbian.
+// If a script cannot be inferred (Zzzz, No) is returned. We do not use Zyyy (undetermined)
+// as one would suspect from the IANA registry for BCP 47. In a Unicode context Zyyy marks
+// common characters (like 1, 2, 3, '.', etc.) and is therefore more like multiple scripts.
+// See http://www.unicode.org/reports/tr24/#Values for more details. Zzzz is also used for
+// unknown value in CLDR. (Zzzz, Exact) is returned if Zzzz was explicitly specified.
+// Note that an inferred script is never guaranteed to be the correct one. Latin is
+// almost exclusively used for Afrikaans, but Arabic has been used for some texts
+// in the past. Also, the script that is commonly used may change over time.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Script() (Script, Confidence) {
+ if t.script != 0 {
+ return Script{t.script}, Exact
+ }
+ sc, c := scriptID(_Zzzz), No
+ if t.lang < langNoIndexOffset {
+ if scr := scriptID(suppressScript[t.lang]); scr != 0 {
+ // Note: it is not always the case that a language with a suppress
+ // script value is only written in one script (e.g. kk, ms, pa).
+ if t.region == 0 {
+ return Script{scriptID(scr)}, High
+ }
+ sc, c = scr, High
+ }
+ }
+ if tag, err := addTags(t); err == nil {
+ if tag.script != sc {
+ sc, c = tag.script, Low
+ }
+ } else {
+ t, _ = (Deprecated | Macro).Canonicalize(t)
+ if tag, err := addTags(t); err == nil && tag.script != sc {
+ sc, c = tag.script, Low
+ }
+ }
+ return Script{sc}, c
+}
+
+// Region returns the region for the language tag. If it was not explicitly given, it will
+// infer a most likely candidate from the context.
+// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
+func (t Tag) Region() (Region, Confidence) {
+ if t.region != 0 {
+ return Region{t.region}, Exact
+ }
+ if t, err := addTags(t); err == nil {
+ return Region{t.region}, Low // TODO: differentiate between high and low.
+ }
+ t, _ = (Deprecated | Macro).Canonicalize(t)
+ if tag, err := addTags(t); err == nil {
+ return Region{tag.region}, Low
+ }
+ return Region{_ZZ}, No // TODO: return world instead of undetermined?
+}
+
+// Variant returns the variants specified explicitly for this language tag.
+// or nil if no variant was specified.
+func (t Tag) Variants() []Variant {
+ v := []Variant{}
+ if int(t.pVariant) < int(t.pExt) {
+ for x, str := "", t.str[t.pVariant:t.pExt]; str != ""; {
+ x, str = nextToken(str)
+ v = append(v, Variant{x})
+ }
+ }
+ return v
+}
+
+// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
+// specific language are substituted with fields from the parent language.
+// The parent for a language may change for newer versions of CLDR.
+func (t Tag) Parent() Tag {
+ if t.str != "" {
+ // Strip the variants and extensions.
+ t, _ = Raw.Compose(t.Raw())
+ if t.region == 0 && t.script != 0 && t.lang != 0 {
+ base, _ := addTags(Tag{lang: t.lang})
+ if base.script == t.script {
+ return Tag{lang: t.lang}
+ }
+ }
+ return t
+ }
+ if t.lang != 0 {
+ if t.region != 0 {
+ maxScript := t.script
+ if maxScript == 0 {
+ max, _ := addTags(t)
+ maxScript = max.script
+ }
+
+ for i := range parents {
+ if langID(parents[i].lang) == t.lang && scriptID(parents[i].maxScript) == maxScript {
+ for _, r := range parents[i].fromRegion {
+ if regionID(r) == t.region {
+ return Tag{
+ lang: t.lang,
+ script: scriptID(parents[i].script),
+ region: regionID(parents[i].toRegion),
+ }
+ }
+ }
+ }
+ }
+
+ // Strip the script if it is the default one.
+ base, _ := addTags(Tag{lang: t.lang})
+ if base.script != maxScript {
+ return Tag{lang: t.lang, script: maxScript}
+ }
+ return Tag{lang: t.lang}
+ } else if t.script != 0 {
+ // The parent for an base-script pair with a non-default script is
+ // "und" instead of the base language.
+ base, _ := addTags(Tag{lang: t.lang})
+ if base.script != t.script {
+ return und
+ }
+ return Tag{lang: t.lang}
+ }
+ }
+ return und
+}
+
+// returns token t and the rest of the string.
+func nextToken(s string) (t, tail string) {
+ p := strings.Index(s[1:], "-")
+ if p == -1 {
+ return s[1:], ""
+ }
+ p++
+ return s[1:p], s[p:]
+}
+
+// Extension is a single BCP 47 extension.
+type Extension struct {
+ s string
+}
+
+// String returns the string representation of the extension, including the
+// type tag.
+func (e Extension) String() string {
+ return e.s
+}
+
+// ParseExtension parses s as an extension and returns it on success.
+func ParseExtension(s string) (e Extension, err error) {
+ scan := makeScannerString(s)
+ var end int
+ if n := len(scan.token); n != 1 {
+ return Extension{}, errSyntax
+ }
+ scan.toLower(0, len(scan.b))
+ end = parseExtension(&scan)
+ if end != len(s) {
+ return Extension{}, errSyntax
+ }
+ return Extension{string(scan.b)}, nil
+}
+
+// Type returns the one-byte extension type of e. It returns 0 for the zero
+// exception.
+func (e Extension) Type() byte {
+ if e.s == "" {
+ return 0
+ }
+ return e.s[0]
+}
+
+// Tokens returns the list of tokens of e.
+func (e Extension) Tokens() []string {
+ return strings.Split(e.s, "-")
+}
+
+// Extension returns the extension of type x for tag t. It will return
+// false for ok if t does not have the requested extension. The returned
+// extension will be invalid in this case.
+func (t Tag) Extension(x byte) (ext Extension, ok bool) {
+ for i := int(t.pExt); i < len(t.str)-1; {
+ var ext string
+ i, ext = getExtension(t.str, i)
+ if ext[0] == x {
+ return Extension{ext}, true
+ }
+ }
+ return Extension{}, false
+}
+
+// Extensions returns all extensions of t.
+func (t Tag) Extensions() []Extension {
+ e := []Extension{}
+ for i := int(t.pExt); i < len(t.str)-1; {
+ var ext string
+ i, ext = getExtension(t.str, i)
+ e = append(e, Extension{ext})
+ }
+ return e
+}
+
+// TypeForKey returns the type associated with the given key, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// TypeForKey will traverse the inheritance chain to get the correct value.
+func (t Tag) TypeForKey(key string) string {
+ if start, end, _ := t.findTypeForKey(key); end != start {
+ return t.str[start:end]
+ }
+ return ""
+}
+
+var (
+ errPrivateUse = errors.New("cannot set a key on a private use tag")
+ errInvalidArguments = errors.New("invalid key or type")
+)
+
+// SetTypeForKey returns a new Tag with the key set to type, where key and type
+// are of the allowed values defined for the Unicode locale extension ('u') in
+// http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// An empty value removes an existing pair with the same key.
+func (t Tag) SetTypeForKey(key, value string) (Tag, error) {
+ if t.private() {
+ return t, errPrivateUse
+ }
+ if len(key) != 2 {
+ return t, errInvalidArguments
+ }
+
+ // Remove the setting if value is "".
+ if value == "" {
+ start, end, _ := t.findTypeForKey(key)
+ if start != end {
+ // Remove key tag and leading '-'.
+ start -= 4
+
+ // Remove a possible empty extension.
+ if (end == len(t.str) || t.str[end+2] == '-') && t.str[start-2] == '-' {
+ start -= 2
+ }
+ if start == int(t.pVariant) && end == len(t.str) {
+ t.str = ""
+ t.pVariant, t.pExt = 0, 0
+ } else {
+ t.str = fmt.Sprintf("%s%s", t.str[:start], t.str[end:])
+ }
+ }
+ return t, nil
+ }
+
+ if len(value) < 3 || len(value) > 8 {
+ return t, errInvalidArguments
+ }
+
+ var (
+ buf [maxCoreSize + maxSimpleUExtensionSize]byte
+ uStart int // start of the -u extension.
+ )
+
+ // Generate the tag string if needed.
+ if t.str == "" {
+ uStart = t.genCoreBytes(buf[:])
+ buf[uStart] = '-'
+ uStart++
+ }
+
+ // Create new key-type pair and parse it to verify.
+ b := buf[uStart:]
+ copy(b, "u-")
+ copy(b[2:], key)
+ b[4] = '-'
+ b = b[:5+copy(b[5:], value)]
+ scan := makeScanner(b)
+ if parseExtensions(&scan); scan.err != nil {
+ return t, scan.err
+ }
+
+ // Assemble the replacement string.
+ if t.str == "" {
+ t.pVariant, t.pExt = byte(uStart-1), uint16(uStart-1)
+ t.str = string(buf[:uStart+len(b)])
+ } else {
+ s := t.str
+ start, end, hasExt := t.findTypeForKey(key)
+ if start == end {
+ if hasExt {
+ b = b[2:]
+ }
+ t.str = fmt.Sprintf("%s-%s%s", s[:start], b, s[end:])
+ } else {
+ t.str = fmt.Sprintf("%s%s%s", s[:start], value, s[end:])
+ }
+ }
+ return t, nil
+}
+
+// findKeyAndType returns the start and end position for the type corresponding
+// to key or the point at which to insert the key-value pair if the type
+// wasn't found. The hasExt return value reports whether an -u extension was present.
+// Note: the extensions are typically very small and are likely to contain
+// only one key-type pair.
+func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
+ p := int(t.pExt)
+ if len(key) != 2 || p == len(t.str) || p == 0 {
+ return p, p, false
+ }
+ s := t.str
+
+ // Find the correct extension.
+ for p++; s[p] != 'u'; p++ {
+ if s[p] > 'u' {
+ p--
+ return p, p, false
+ }
+ if p = nextExtension(s, p); p == len(s) {
+ return len(s), len(s), false
+ }
+ }
+ // Proceed to the hyphen following the extension name.
+ p++
+
+ // curKey is the key currently being processed.
+ curKey := ""
+
+ // Iterate over keys until we get the end of a section.
+ for {
+ // p points to the hyphen preceding the current token.
+ if p3 := p + 3; s[p3] == '-' {
+ // Found a key.
+ // Check whether we just processed the key that was requested.
+ if curKey == key {
+ return start, p, true
+ }
+ // Set to the next key and continue scanning type tokens.
+ curKey = s[p+1 : p3]
+ if curKey > key {
+ return p, p, true
+ }
+ // Start of the type token sequence.
+ start = p + 4
+ // A type is at least 3 characters long.
+ p += 7 // 4 + 3
+ } else {
+ // Attribute or type, which is at least 3 characters long.
+ p += 4
+ }
+ // p points past the third character of a type or attribute.
+ max := p + 5 // maximum length of token plus hyphen.
+ if len(s) < max {
+ max = len(s)
+ }
+ for ; p < max && s[p] != '-'; p++ {
+ }
+ // Bail if we have exhausted all tokens or if the next token starts
+ // a new extension.
+ if p == len(s) || s[p+2] == '-' {
+ if curKey == key {
+ return start, p, true
+ }
+ return p, p, true
+ }
+ }
+}
+
+// CompactIndex returns an index, where 0 <= index < NumCompactTags, for tags
+// for which data exists in the text repository. The index will change over time
+// and should not be stored in persistent storage. Extensions, except for the
+// 'va' type of the 'u' extension, are ignored. It will return 0, false if no
+// compact tag exists, where 0 is the index for the root language (Und).
+func CompactIndex(t Tag) (index int, ok bool) {
+ // TODO: perhaps give more frequent tags a lower index.
+ // TODO: we could make the indexes stable. This will excluded some
+ // possibilities for optimization, so don't do this quite yet.
+ b, s, r := t.Raw()
+ if len(t.str) > 0 {
+ if strings.HasPrefix(t.str, "x-") {
+ // We have no entries for user-defined tags.
+ return 0, false
+ }
+ if uint16(t.pVariant) != t.pExt {
+ // There are no tags with variants and an u-va type.
+ if t.TypeForKey("va") != "" {
+ return 0, false
+ }
+ t, _ = Raw.Compose(b, s, r, t.Variants())
+ } else if _, ok := t.Extension('u'); ok {
+ // Strip all but the 'va' entry.
+ variant := t.TypeForKey("va")
+ t, _ = Raw.Compose(b, s, r)
+ t, _ = t.SetTypeForKey("va", variant)
+ }
+ if len(t.str) > 0 {
+ // We have some variants.
+ for i, s := range specialTags {
+ if s == t {
+ return i + 1, true
+ }
+ }
+ return 0, false
+ }
+ }
+ // No variants specified: just compare core components.
+ // The key has the form lllssrrr, where l, s, and r are nibbles for
+ // respectively the langID, scriptID, and regionID.
+ key := uint32(b.langID) << (8 + 12)
+ key |= uint32(s.scriptID) << 12
+ key |= uint32(r.regionID)
+ x, ok := coreTags[key]
+ return int(x), ok
+}
+
+// Base is an ISO 639 language code, used for encoding the base language
+// of a language tag.
+type Base struct {
+ langID
+}
+
+// ParseBase parses a 2- or 3-letter ISO 639 code.
+// It returns a ValueError if s is a well-formed but unknown language identifier
+// or another error if another error occurred.
+func ParseBase(s string) (Base, error) {
+ if n := len(s); n < 2 || 3 < n {
+ return Base{}, errSyntax
+ }
+ var buf [3]byte
+ l, err := getLangID(buf[:copy(buf[:], s)])
+ return Base{l}, err
+}
+
+// Script is a 4-letter ISO 15924 code for representing scripts.
+// It is idiomatically represented in title case.
+type Script struct {
+ scriptID
+}
+
+// ParseScript parses a 4-letter ISO 15924 code.
+// It returns a ValueError if s is a well-formed but unknown script identifier
+// or another error if another error occurred.
+func ParseScript(s string) (Script, error) {
+ if len(s) != 4 {
+ return Script{}, errSyntax
+ }
+ var buf [4]byte
+ sc, err := getScriptID(script, buf[:copy(buf[:], s)])
+ return Script{sc}, err
+}
+
+// Region is an ISO 3166-1 or UN M.49 code for representing countries and regions.
+type Region struct {
+ regionID
+}
+
+// EncodeM49 returns the Region for the given UN M.49 code.
+// It returns an error if r is not a valid code.
+func EncodeM49(r int) (Region, error) {
+ rid, err := getRegionM49(r)
+ return Region{rid}, err
+}
+
+// ParseRegion parses a 2- or 3-letter ISO 3166-1 or a UN M.49 code.
+// It returns a ValueError if s is a well-formed but unknown region identifier
+// or another error if another error occurred.
+func ParseRegion(s string) (Region, error) {
+ if n := len(s); n < 2 || 3 < n {
+ return Region{}, errSyntax
+ }
+ var buf [3]byte
+ r, err := getRegionID(buf[:copy(buf[:], s)])
+ return Region{r}, err
+}
+
+// IsCountry returns whether this region is a country or autonomous area. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsCountry() bool {
+ if r.regionID == 0 || r.IsGroup() || r.IsPrivateUse() && r.regionID != _XK {
+ return false
+ }
+ return true
+}
+
+// IsGroup returns whether this region defines a collection of regions. This
+// includes non-standard definitions from CLDR.
+func (r Region) IsGroup() bool {
+ if r.regionID == 0 {
+ return false
+ }
+ return int(regionInclusion[r.regionID]) < len(regionContainment)
+}
+
+// Contains returns whether Region c is contained by Region r. It returns true
+// if c == r.
+func (r Region) Contains(c Region) bool {
+ return r.regionID.contains(c.regionID)
+}
+
+func (r regionID) contains(c regionID) bool {
+ if r == c {
+ return true
+ }
+ g := regionInclusion[r]
+ if g >= nRegionGroups {
+ return false
+ }
+ m := regionContainment[g]
+
+ d := regionInclusion[c]
+ b := regionInclusionBits[d]
+
+ // A contained country may belong to multiple disjoint groups. Matching any
+ // of these indicates containment. If the contained region is a group, it
+ // must strictly be a subset.
+ if d >= nRegionGroups {
+ return b&m != 0
+ }
+ return b&^m == 0
+}
+
+var errNoTLD = errors.New("language: region is not a valid ccTLD")
+
+// TLD returns the country code top-level domain (ccTLD). UK is returned for GB.
+// In all other cases it returns either the region itself or an error.
+//
+// This method may return an error for a region for which there exists a
+// canonical form with a ccTLD. To get that ccTLD canonicalize r first. The
+// region will already be canonicalized it was obtained from a Tag that was
+// obtained using any of the default methods.
+func (r Region) TLD() (Region, error) {
+ // See http://en.wikipedia.org/wiki/Country_code_top-level_domain for the
+ // difference between ISO 3166-1 and IANA ccTLD.
+ if r.regionID == _GB {
+ r = Region{_UK}
+ }
+ if (r.typ() & ccTLD) == 0 {
+ return Region{}, errNoTLD
+ }
+ return r, nil
+}
+
+// Canonicalize returns the region or a possible replacement if the region is
+// deprecated. It will not return a replacement for deprecated regions that
+// are split into multiple regions.
+func (r Region) Canonicalize() Region {
+ if cr := normRegion(r.regionID); cr != 0 {
+ return Region{cr}
+ }
+ return r
+}
+
+// Variant represents a registered variant of a language as defined by BCP 47.
+type Variant struct {
+ variant string
+}
+
+// ParseVariant parses and returns a Variant. An error is returned if s is not
+// a valid variant.
+func ParseVariant(s string) (Variant, error) {
+ s = strings.ToLower(s)
+ if _, ok := variantIndex[s]; ok {
+ return Variant{s}, nil
+ }
+ return Variant{}, mkErrInvalid([]byte(s))
+}
+
+// String returns the string representation of the variant.
+func (v Variant) String() string {
+ return v.variant
+}
diff --git a/vendor/golang.org/x/text/language/lookup.go b/vendor/golang.org/x/text/language/lookup.go
new file mode 100644
index 000000000..1d80ac370
--- /dev/null
+++ b/vendor/golang.org/x/text/language/lookup.go
@@ -0,0 +1,396 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strconv"
+
+ "golang.org/x/text/internal/tag"
+)
+
+// findIndex tries to find the given tag in idx and returns a standardized error
+// if it could not be found.
+func findIndex(idx tag.Index, key []byte, form string) (index int, err error) {
+ if !tag.FixCase(form, key) {
+ return 0, errSyntax
+ }
+ i := idx.Index(key)
+ if i == -1 {
+ return 0, mkErrInvalid(key)
+ }
+ return i, nil
+}
+
+func searchUint(imap []uint16, key uint16) int {
+ return sort.Search(len(imap), func(i int) bool {
+ return imap[i] >= key
+ })
+}
+
+type langID uint16
+
+// getLangID returns the langID of s if s is a canonical subtag
+// or langUnknown if s is not a canonical subtag.
+func getLangID(s []byte) (langID, error) {
+ if len(s) == 2 {
+ return getLangISO2(s)
+ }
+ return getLangISO3(s)
+}
+
+// mapLang returns the mapped langID of id according to mapping m.
+func normLang(id langID) (langID, langAliasType) {
+ k := sort.Search(len(langAliasMap), func(i int) bool {
+ return langAliasMap[i].from >= uint16(id)
+ })
+ if k < len(langAliasMap) && langAliasMap[k].from == uint16(id) {
+ return langID(langAliasMap[k].to), langAliasTypes[k]
+ }
+ return id, langAliasTypeUnknown
+}
+
+// getLangISO2 returns the langID for the given 2-letter ISO language code
+// or unknownLang if this does not exist.
+func getLangISO2(s []byte) (langID, error) {
+ if !tag.FixCase("zz", s) {
+ return 0, errSyntax
+ }
+ if i := lang.Index(s); i != -1 && lang.Elem(i)[3] != 0 {
+ return langID(i), nil
+ }
+ return 0, mkErrInvalid(s)
+}
+
+const base = 'z' - 'a' + 1
+
+func strToInt(s []byte) uint {
+ v := uint(0)
+ for i := 0; i < len(s); i++ {
+ v *= base
+ v += uint(s[i] - 'a')
+ }
+ return v
+}
+
+// converts the given integer to the original ASCII string passed to strToInt.
+// len(s) must match the number of characters obtained.
+func intToStr(v uint, s []byte) {
+ for i := len(s) - 1; i >= 0; i-- {
+ s[i] = byte(v%base) + 'a'
+ v /= base
+ }
+}
+
+// getLangISO3 returns the langID for the given 3-letter ISO language code
+// or unknownLang if this does not exist.
+func getLangISO3(s []byte) (langID, error) {
+ if tag.FixCase("und", s) {
+ // first try to match canonical 3-letter entries
+ for i := lang.Index(s[:2]); i != -1; i = lang.Next(s[:2], i) {
+ if e := lang.Elem(i); e[3] == 0 && e[2] == s[2] {
+ // We treat "und" as special and always translate it to "unspecified".
+ // Note that ZZ and Zzzz are private use and are not treated as
+ // unspecified by default.
+ id := langID(i)
+ if id == nonCanonicalUnd {
+ return 0, nil
+ }
+ return id, nil
+ }
+ }
+ if i := altLangISO3.Index(s); i != -1 {
+ return langID(altLangIndex[altLangISO3.Elem(i)[3]]), nil
+ }
+ n := strToInt(s)
+ if langNoIndex[n/8]&(1<<(n%8)) != 0 {
+ return langID(n) + langNoIndexOffset, nil
+ }
+ // Check for non-canonical uses of ISO3.
+ for i := lang.Index(s[:1]); i != -1; i = lang.Next(s[:1], i) {
+ if e := lang.Elem(i); e[2] == s[1] && e[3] == s[2] {
+ return langID(i), nil
+ }
+ }
+ return 0, mkErrInvalid(s)
+ }
+ return 0, errSyntax
+}
+
+// stringToBuf writes the string to b and returns the number of bytes
+// written. cap(b) must be >= 3.
+func (id langID) stringToBuf(b []byte) int {
+ if id >= langNoIndexOffset {
+ intToStr(uint(id)-langNoIndexOffset, b[:3])
+ return 3
+ } else if id == 0 {
+ return copy(b, "und")
+ }
+ l := lang[id<<2:]
+ if l[3] == 0 {
+ return copy(b, l[:3])
+ }
+ return copy(b, l[:2])
+}
+
+// String returns the BCP 47 representation of the langID.
+// Use b as variable name, instead of id, to ensure the variable
+// used is consistent with that of Base in which this type is embedded.
+func (b langID) String() string {
+ if b == 0 {
+ return "und"
+ } else if b >= langNoIndexOffset {
+ b -= langNoIndexOffset
+ buf := [3]byte{}
+ intToStr(uint(b), buf[:])
+ return string(buf[:])
+ }
+ l := lang.Elem(int(b))
+ if l[3] == 0 {
+ return l[:3]
+ }
+ return l[:2]
+}
+
+// ISO3 returns the ISO 639-3 language code.
+func (b langID) ISO3() string {
+ if b == 0 || b >= langNoIndexOffset {
+ return b.String()
+ }
+ l := lang.Elem(int(b))
+ if l[3] == 0 {
+ return l[:3]
+ } else if l[2] == 0 {
+ return altLangISO3.Elem(int(l[3]))[:3]
+ }
+ // This allocation will only happen for 3-letter ISO codes
+ // that are non-canonical BCP 47 language identifiers.
+ return l[0:1] + l[2:4]
+}
+
+// IsPrivateUse reports whether this language code is reserved for private use.
+func (b langID) IsPrivateUse() bool {
+ return langPrivateStart <= b && b <= langPrivateEnd
+}
+
+type regionID uint16
+
+// getRegionID returns the region id for s if s is a valid 2-letter region code
+// or unknownRegion.
+func getRegionID(s []byte) (regionID, error) {
+ if len(s) == 3 {
+ if isAlpha(s[0]) {
+ return getRegionISO3(s)
+ }
+ if i, err := strconv.ParseUint(string(s), 10, 10); err == nil {
+ return getRegionM49(int(i))
+ }
+ }
+ return getRegionISO2(s)
+}
+
+// getRegionISO2 returns the regionID for the given 2-letter ISO country code
+// or unknownRegion if this does not exist.
+func getRegionISO2(s []byte) (regionID, error) {
+ i, err := findIndex(regionISO, s, "ZZ")
+ if err != nil {
+ return 0, err
+ }
+ return regionID(i) + isoRegionOffset, nil
+}
+
+// getRegionISO3 returns the regionID for the given 3-letter ISO country code
+// or unknownRegion if this does not exist.
+func getRegionISO3(s []byte) (regionID, error) {
+ if tag.FixCase("ZZZ", s) {
+ for i := regionISO.Index(s[:1]); i != -1; i = regionISO.Next(s[:1], i) {
+ if e := regionISO.Elem(i); e[2] == s[1] && e[3] == s[2] {
+ return regionID(i) + isoRegionOffset, nil
+ }
+ }
+ for i := 0; i < len(altRegionISO3); i += 3 {
+ if tag.Compare(altRegionISO3[i:i+3], s) == 0 {
+ return regionID(altRegionIDs[i/3]), nil
+ }
+ }
+ return 0, mkErrInvalid(s)
+ }
+ return 0, errSyntax
+}
+
+func getRegionM49(n int) (regionID, error) {
+ if 0 < n && n <= 999 {
+ const (
+ searchBits = 7
+ regionBits = 9
+ regionMask = 1<<regionBits - 1
+ )
+ idx := n >> searchBits
+ buf := fromM49[m49Index[idx]:m49Index[idx+1]]
+ val := uint16(n) << regionBits // we rely on bits shifting out
+ i := sort.Search(len(buf), func(i int) bool {
+ return buf[i] >= val
+ })
+ if r := fromM49[int(m49Index[idx])+i]; r&^regionMask == val {
+ return regionID(r & regionMask), nil
+ }
+ }
+ var e ValueError
+ fmt.Fprint(bytes.NewBuffer([]byte(e.v[:])), n)
+ return 0, e
+}
+
+// normRegion returns a region if r is deprecated or 0 otherwise.
+// TODO: consider supporting BYS (-> BLR), CSK (-> 200 or CZ), PHI (-> PHL) and AFI (-> DJ).
+// TODO: consider mapping split up regions to new most populous one (like CLDR).
+func normRegion(r regionID) regionID {
+ m := regionOldMap
+ k := sort.Search(len(m), func(i int) bool {
+ return m[i].from >= uint16(r)
+ })
+ if k < len(m) && m[k].from == uint16(r) {
+ return regionID(m[k].to)
+ }
+ return 0
+}
+
+const (
+ iso3166UserAssigned = 1 << iota
+ ccTLD
+ bcp47Region
+)
+
+func (r regionID) typ() byte {
+ return regionTypes[r]
+}
+
+// String returns the BCP 47 representation for the region.
+// It returns "ZZ" for an unspecified region.
+func (r regionID) String() string {
+ if r < isoRegionOffset {
+ if r == 0 {
+ return "ZZ"
+ }
+ return fmt.Sprintf("%03d", r.M49())
+ }
+ r -= isoRegionOffset
+ return regionISO.Elem(int(r))[:2]
+}
+
+// ISO3 returns the 3-letter ISO code of r.
+// Note that not all regions have a 3-letter ISO code.
+// In such cases this method returns "ZZZ".
+func (r regionID) ISO3() string {
+ if r < isoRegionOffset {
+ return "ZZZ"
+ }
+ r -= isoRegionOffset
+ reg := regionISO.Elem(int(r))
+ switch reg[2] {
+ case 0:
+ return altRegionISO3[reg[3]:][:3]
+ case ' ':
+ return "ZZZ"
+ }
+ return reg[0:1] + reg[2:4]
+}
+
+// M49 returns the UN M.49 encoding of r, or 0 if this encoding
+// is not defined for r.
+func (r regionID) M49() int {
+ return int(m49[r])
+}
+
+// IsPrivateUse reports whether r has the ISO 3166 User-assigned status. This
+// may include private-use tags that are assigned by CLDR and used in this
+// implementation. So IsPrivateUse and IsCountry can be simultaneously true.
+func (r regionID) IsPrivateUse() bool {
+ return r.typ()&iso3166UserAssigned != 0
+}
+
+type scriptID uint8
+
+// getScriptID returns the script id for string s. It assumes that s
+// is of the format [A-Z][a-z]{3}.
+func getScriptID(idx tag.Index, s []byte) (scriptID, error) {
+ i, err := findIndex(idx, s, "Zzzz")
+ return scriptID(i), err
+}
+
+// String returns the script code in title case.
+// It returns "Zzzz" for an unspecified script.
+func (s scriptID) String() string {
+ if s == 0 {
+ return "Zzzz"
+ }
+ return script.Elem(int(s))
+}
+
+// IsPrivateUse reports whether this script code is reserved for private use.
+func (s scriptID) IsPrivateUse() bool {
+ return _Qaaa <= s && s <= _Qabx
+}
+
+const (
+ maxAltTaglen = len("en-US-POSIX")
+ maxLen = maxAltTaglen
+)
+
+var (
+ // grandfatheredMap holds a mapping from legacy and grandfathered tags to
+ // their base language or index to more elaborate tag.
+ grandfatheredMap = map[[maxLen]byte]int16{
+ [maxLen]byte{'a', 'r', 't', '-', 'l', 'o', 'j', 'b', 'a', 'n'}: _jbo, // art-lojban
+ [maxLen]byte{'i', '-', 'a', 'm', 'i'}: _ami, // i-ami
+ [maxLen]byte{'i', '-', 'b', 'n', 'n'}: _bnn, // i-bnn
+ [maxLen]byte{'i', '-', 'h', 'a', 'k'}: _hak, // i-hak
+ [maxLen]byte{'i', '-', 'k', 'l', 'i', 'n', 'g', 'o', 'n'}: _tlh, // i-klingon
+ [maxLen]byte{'i', '-', 'l', 'u', 'x'}: _lb, // i-lux
+ [maxLen]byte{'i', '-', 'n', 'a', 'v', 'a', 'j', 'o'}: _nv, // i-navajo
+ [maxLen]byte{'i', '-', 'p', 'w', 'n'}: _pwn, // i-pwn
+ [maxLen]byte{'i', '-', 't', 'a', 'o'}: _tao, // i-tao
+ [maxLen]byte{'i', '-', 't', 'a', 'y'}: _tay, // i-tay
+ [maxLen]byte{'i', '-', 't', 's', 'u'}: _tsu, // i-tsu
+ [maxLen]byte{'n', 'o', '-', 'b', 'o', 'k'}: _nb, // no-bok
+ [maxLen]byte{'n', 'o', '-', 'n', 'y', 'n'}: _nn, // no-nyn
+ [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'f', 'r'}: _sfb, // sgn-BE-FR
+ [maxLen]byte{'s', 'g', 'n', '-', 'b', 'e', '-', 'n', 'l'}: _vgt, // sgn-BE-NL
+ [maxLen]byte{'s', 'g', 'n', '-', 'c', 'h', '-', 'd', 'e'}: _sgg, // sgn-CH-DE
+ [maxLen]byte{'z', 'h', '-', 'g', 'u', 'o', 'y', 'u'}: _cmn, // zh-guoyu
+ [maxLen]byte{'z', 'h', '-', 'h', 'a', 'k', 'k', 'a'}: _hak, // zh-hakka
+ [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n', '-', 'n', 'a', 'n'}: _nan, // zh-min-nan
+ [maxLen]byte{'z', 'h', '-', 'x', 'i', 'a', 'n', 'g'}: _hsn, // zh-xiang
+
+ // Grandfathered tags with no modern replacement will be converted as
+ // follows:
+ [maxLen]byte{'c', 'e', 'l', '-', 'g', 'a', 'u', 'l', 'i', 's', 'h'}: -1, // cel-gaulish
+ [maxLen]byte{'e', 'n', '-', 'g', 'b', '-', 'o', 'e', 'd'}: -2, // en-GB-oed
+ [maxLen]byte{'i', '-', 'd', 'e', 'f', 'a', 'u', 'l', 't'}: -3, // i-default
+ [maxLen]byte{'i', '-', 'e', 'n', 'o', 'c', 'h', 'i', 'a', 'n'}: -4, // i-enochian
+ [maxLen]byte{'i', '-', 'm', 'i', 'n', 'g', 'o'}: -5, // i-mingo
+ [maxLen]byte{'z', 'h', '-', 'm', 'i', 'n'}: -6, // zh-min
+
+ // CLDR-specific tag.
+ [maxLen]byte{'r', 'o', 'o', 't'}: 0, // root
+ [maxLen]byte{'e', 'n', '-', 'u', 's', '-', 'p', 'o', 's', 'i', 'x'}: -7, // en_US_POSIX"
+ }
+
+ altTagIndex = [...]uint8{0, 17, 31, 45, 61, 74, 86, 102}
+
+ altTags = "xtg-x-cel-gaulishen-GB-oxendicten-x-i-defaultund-x-i-enochiansee-x-i-mingonan-x-zh-minen-US-u-va-posix"
+)
+
+func grandfathered(s [maxAltTaglen]byte) (t Tag, ok bool) {
+ if v, ok := grandfatheredMap[s]; ok {
+ if v < 0 {
+ return Make(altTags[altTagIndex[-v-1]:altTagIndex[-v]]), true
+ }
+ t.lang = langID(v)
+ return t, true
+ }
+ return t, false
+}
diff --git a/vendor/golang.org/x/text/language/maketables.go b/vendor/golang.org/x/text/language/maketables.go
new file mode 100644
index 000000000..107f99254
--- /dev/null
+++ b/vendor/golang.org/x/text/language/maketables.go
@@ -0,0 +1,1648 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// Language tag table generator.
+// Data read from the web.
+
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "math"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+
+ "golang.org/x/text/internal/gen"
+ "golang.org/x/text/internal/tag"
+ "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 for generated tables")
+)
+
+var comment = []string{
+ `
+lang holds an alphabetically sorted list of ISO-639 language identifiers.
+All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag.
+For 2-byte language identifiers, the two successive bytes have the following meaning:
+ - if the first letter of the 2- and 3-letter ISO codes are the same:
+ the second and third letter of the 3-letter ISO code.
+ - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3.
+For 3-byte language identifiers the 4th byte is 0.`,
+ `
+langNoIndex is a bit vector of all 3-letter language codes that are not used as an index
+in lookup tables. The language ids for these language codes are derived directly
+from the letters and are not consecutive.`,
+ `
+altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives
+to 2-letter language codes that cannot be derived using the method described above.
+Each 3-letter code is followed by its 1-byte langID.`,
+ `
+altLangIndex is used to convert indexes in altLangISO3 to langIDs.`,
+ `
+langAliasMap maps langIDs to their suggested replacements.`,
+ `
+script is an alphabetically sorted list of ISO 15924 codes. The index
+of the script in the string, divided by 4, is the internal scriptID.`,
+ `
+isoRegionOffset needs to be added to the index of regionISO to obtain the regionID
+for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for
+the UN.M49 codes used for groups.)`,
+ `
+regionISO holds a list of alphabetically sorted 2-letter ISO region codes.
+Each 2-letter codes is followed by two bytes with the following meaning:
+ - [A-Z}{2}: the first letter of the 2-letter code plus these two
+ letters form the 3-letter ISO code.
+ - 0, n: index into altRegionISO3.`,
+ `
+regionTypes defines the status of a region for various standards.`,
+ `
+m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are
+codes indicating collections of regions.`,
+ `
+m49Index gives indexes into fromM49 based on the three most significant bits
+of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in
+ fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]]
+for an entry where the first 7 bits match the 7 lsb of the UN.M49 code.
+The region code is stored in the 9 lsb of the indexed value.`,
+ `
+fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details.`,
+ `
+altRegionISO3 holds a list of 3-letter region codes that cannot be
+mapped to 2-letter codes using the default algorithm. This is a short list.`,
+ `
+altRegionIDs holds a list of regionIDs the positions of which match those
+of the 3-letter ISO codes in altRegionISO3.`,
+ `
+variantNumSpecialized is the number of specialized variants in variants.`,
+ `
+suppressScript is an index from langID to the dominant script for that language,
+if it exists. If a script is given, it should be suppressed from the language tag.`,
+ `
+likelyLang is a lookup table, indexed by langID, for the most likely
+scripts and regions given incomplete information. If more entries exist for a
+given language, region and script are the index and size respectively
+of the list in likelyLangList.`,
+ `
+likelyLangList holds lists info associated with likelyLang.`,
+ `
+likelyRegion is a lookup table, indexed by regionID, for the most likely
+languages and scripts given incomplete information. If more entries exist
+for a given regionID, lang and script are the index and size respectively
+of the list in likelyRegionList.
+TODO: exclude containers and user-definable regions from the list.`,
+ `
+likelyRegionList holds lists info associated with likelyRegion.`,
+ `
+likelyScript is a lookup table, indexed by scriptID, for the most likely
+languages and regions given a script.`,
+ `
+matchLang holds pairs of langIDs of base languages that are typically
+mutually intelligible. Each pair is associated with a confidence and
+whether the intelligibility goes one or both ways.`,
+ `
+matchScript holds pairs of scriptIDs where readers of one script
+can typically also read the other. Each is associated with a confidence.`,
+ `
+nRegionGroups is the number of region groups.`,
+ `
+regionInclusion maps region identifiers to sets of regions in regionInclusionBits,
+where each set holds all groupings that are directly connected in a region
+containment graph.`,
+ `
+regionInclusionBits is an array of bit vectors where every vector represents
+a set of region groupings. These sets are used to compute the distance
+between two regions for the purpose of language matching.`,
+ `
+regionInclusionNext marks, for each entry in regionInclusionBits, the set of
+all groups that are reachable from the groups set in the respective entry.`,
+}
+
+// TODO: consider changing some of these structures to tries. This can reduce
+// memory, but may increase the need for memory allocations. This could be
+// mitigated if we can piggyback on language tags for common cases.
+
+func failOnError(e error) {
+ if e != nil {
+ log.Panic(e)
+ }
+}
+
+type setType int
+
+const (
+ Indexed setType = 1 + iota // all elements must be of same size
+ Linear
+)
+
+type stringSet struct {
+ s []string
+ sorted, frozen bool
+
+ // We often need to update values after the creation of an index is completed.
+ // We include a convenience map for keeping track of this.
+ update map[string]string
+ typ setType // used for checking.
+}
+
+func (ss *stringSet) clone() stringSet {
+ c := *ss
+ c.s = append([]string(nil), c.s...)
+ return c
+}
+
+func (ss *stringSet) setType(t setType) {
+ if ss.typ != t && ss.typ != 0 {
+ log.Panicf("type %d cannot be assigned as it was already %d", t, ss.typ)
+ }
+}
+
+// parse parses a whitespace-separated string and initializes ss with its
+// components.
+func (ss *stringSet) parse(s string) {
+ scan := bufio.NewScanner(strings.NewReader(s))
+ scan.Split(bufio.ScanWords)
+ for scan.Scan() {
+ ss.add(scan.Text())
+ }
+}
+
+func (ss *stringSet) assertChangeable() {
+ if ss.frozen {
+ log.Panic("attempt to modify a frozen stringSet")
+ }
+}
+
+func (ss *stringSet) add(s string) {
+ ss.assertChangeable()
+ ss.s = append(ss.s, s)
+ ss.sorted = ss.frozen
+}
+
+func (ss *stringSet) freeze() {
+ ss.compact()
+ ss.frozen = true
+}
+
+func (ss *stringSet) compact() {
+ if ss.sorted {
+ return
+ }
+ a := ss.s
+ sort.Strings(a)
+ k := 0
+ for i := 1; i < len(a); i++ {
+ if a[k] != a[i] {
+ a[k+1] = a[i]
+ k++
+ }
+ }
+ ss.s = a[:k+1]
+ ss.sorted = ss.frozen
+}
+
+type funcSorter struct {
+ fn func(a, b string) bool
+ sort.StringSlice
+}
+
+func (s funcSorter) Less(i, j int) bool {
+ return s.fn(s.StringSlice[i], s.StringSlice[j])
+}
+
+func (ss *stringSet) sortFunc(f func(a, b string) bool) {
+ ss.compact()
+ sort.Sort(funcSorter{f, sort.StringSlice(ss.s)})
+}
+
+func (ss *stringSet) remove(s string) {
+ ss.assertChangeable()
+ if i, ok := ss.find(s); ok {
+ copy(ss.s[i:], ss.s[i+1:])
+ ss.s = ss.s[:len(ss.s)-1]
+ }
+}
+
+func (ss *stringSet) replace(ol, nu string) {
+ ss.s[ss.index(ol)] = nu
+ ss.sorted = ss.frozen
+}
+
+func (ss *stringSet) index(s string) int {
+ ss.setType(Indexed)
+ i, ok := ss.find(s)
+ if !ok {
+ if i < len(ss.s) {
+ log.Panicf("find: item %q is not in list. Closest match is %q.", s, ss.s[i])
+ }
+ log.Panicf("find: item %q is not in list", s)
+
+ }
+ return i
+}
+
+func (ss *stringSet) find(s string) (int, bool) {
+ ss.compact()
+ i := sort.SearchStrings(ss.s, s)
+ return i, i != len(ss.s) && ss.s[i] == s
+}
+
+func (ss *stringSet) slice() []string {
+ ss.compact()
+ return ss.s
+}
+
+func (ss *stringSet) updateLater(v, key string) {
+ if ss.update == nil {
+ ss.update = map[string]string{}
+ }
+ ss.update[v] = key
+}
+
+// join joins the string and ensures that all entries are of the same length.
+func (ss *stringSet) join() string {
+ ss.setType(Indexed)
+ n := len(ss.s[0])
+ for _, s := range ss.s {
+ if len(s) != n {
+ log.Panicf("join: not all entries are of the same length: %q", s)
+ }
+ }
+ ss.s = append(ss.s, strings.Repeat("\xff", n))
+ return strings.Join(ss.s, "")
+}
+
+// ianaEntry holds information for an entry in the IANA Language Subtag Repository.
+// All types use the same entry.
+// See http://tools.ietf.org/html/bcp47#section-5.1 for a description of the various
+// fields.
+type ianaEntry struct {
+ typ string
+ description []string
+ scope string
+ added string
+ preferred string
+ deprecated string
+ suppressScript string
+ macro string
+ prefix []string
+}
+
+type builder struct {
+ w *gen.CodeWriter
+ hw io.Writer // MultiWriter for w and w.Hash
+ data *cldr.CLDR
+ supp *cldr.SupplementalData
+
+ // indices
+ locale stringSet // common locales
+ lang stringSet // canonical language ids (2 or 3 letter ISO codes) with data
+ langNoIndex stringSet // 3-letter ISO codes with no associated data
+ script stringSet // 4-letter ISO codes
+ region stringSet // 2-letter ISO or 3-digit UN M49 codes
+ variant stringSet // 4-8-alphanumeric variant code.
+
+ // Region codes that are groups with their corresponding group IDs.
+ groups map[int]index
+
+ // langInfo
+ registry map[string]*ianaEntry
+}
+
+type index uint
+
+func newBuilder(w *gen.CodeWriter) *builder {
+ r := gen.OpenCLDRCoreZip()
+ defer r.Close()
+ d := &cldr.Decoder{}
+ data, err := d.DecodeZip(r)
+ failOnError(err)
+ b := builder{
+ w: w,
+ hw: io.MultiWriter(w, w.Hash),
+ data: data,
+ supp: data.Supplemental(),
+ }
+ b.parseRegistry()
+ return &b
+}
+
+func (b *builder) parseRegistry() {
+ r := gen.OpenIANAFile("assignments/language-subtag-registry")
+ defer r.Close()
+ b.registry = make(map[string]*ianaEntry)
+
+ scan := bufio.NewScanner(r)
+ scan.Split(bufio.ScanWords)
+ var record *ianaEntry
+ for more := scan.Scan(); more; {
+ key := scan.Text()
+ more = scan.Scan()
+ value := scan.Text()
+ switch key {
+ case "Type:":
+ record = &ianaEntry{typ: value}
+ case "Subtag:", "Tag:":
+ if s := strings.SplitN(value, "..", 2); len(s) > 1 {
+ for a := s[0]; a <= s[1]; a = inc(a) {
+ b.addToRegistry(a, record)
+ }
+ } else {
+ b.addToRegistry(value, record)
+ }
+ case "Suppress-Script:":
+ record.suppressScript = value
+ case "Added:":
+ record.added = value
+ case "Deprecated:":
+ record.deprecated = value
+ case "Macrolanguage:":
+ record.macro = value
+ case "Preferred-Value:":
+ record.preferred = value
+ case "Prefix:":
+ record.prefix = append(record.prefix, value)
+ case "Scope:":
+ record.scope = value
+ case "Description:":
+ buf := []byte(value)
+ for more = scan.Scan(); more; more = scan.Scan() {
+ b := scan.Bytes()
+ if b[0] == '%' || b[len(b)-1] == ':' {
+ break
+ }
+ buf = append(buf, ' ')
+ buf = append(buf, b...)
+ }
+ record.description = append(record.description, string(buf))
+ continue
+ default:
+ continue
+ }
+ more = scan.Scan()
+ }
+ if scan.Err() != nil {
+ log.Panic(scan.Err())
+ }
+}
+
+func (b *builder) addToRegistry(key string, entry *ianaEntry) {
+ if info, ok := b.registry[key]; ok {
+ if info.typ != "language" || entry.typ != "extlang" {
+ log.Fatalf("parseRegistry: tag %q already exists", key)
+ }
+ } else {
+ b.registry[key] = entry
+ }
+}
+
+var commentIndex = make(map[string]string)
+
+func init() {
+ for _, s := range comment {
+ key := strings.TrimSpace(strings.SplitN(s, " ", 2)[0])
+ commentIndex[key] = s
+ }
+}
+
+func (b *builder) comment(name string) {
+ if s := commentIndex[name]; len(s) > 0 {
+ b.w.WriteComment(s)
+ } else {
+ fmt.Fprintln(b.w)
+ }
+}
+
+func (b *builder) pf(f string, x ...interface{}) {
+ fmt.Fprintf(b.hw, f, x...)
+ fmt.Fprint(b.hw, "\n")
+}
+
+func (b *builder) p(x ...interface{}) {
+ fmt.Fprintln(b.hw, x...)
+}
+
+func (b *builder) addSize(s int) {
+ b.w.Size += s
+ b.pf("// Size: %d bytes", s)
+}
+
+func (b *builder) writeConst(name string, x interface{}) {
+ b.comment(name)
+ b.w.WriteConst(name, x)
+}
+
+// writeConsts computes f(v) for all v in values and writes the results
+// as constants named _v to a single constant block.
+func (b *builder) writeConsts(f func(string) int, values ...string) {
+ b.pf("const (")
+ for _, v := range values {
+ b.pf("\t_%s = %v", v, f(v))
+ }
+ b.pf(")")
+}
+
+// writeType writes the type of the given value, which must be a struct.
+func (b *builder) writeType(value interface{}) {
+ b.comment(reflect.TypeOf(value).Name())
+ b.w.WriteType(value)
+}
+
+func (b *builder) writeSlice(name string, ss interface{}) {
+ b.writeSliceAddSize(name, 0, ss)
+}
+
+func (b *builder) writeSliceAddSize(name string, extraSize int, ss interface{}) {
+ b.comment(name)
+ b.w.Size += extraSize
+ v := reflect.ValueOf(ss)
+ t := v.Type().Elem()
+ b.pf("// Size: %d bytes, %d elements", v.Len()*int(t.Size())+extraSize, v.Len())
+
+ fmt.Fprintf(b.w, "var %s = ", name)
+ b.w.WriteArray(ss)
+ b.p()
+}
+
+type fromTo struct {
+ from, to uint16
+}
+
+func (b *builder) writeSortedMap(name string, ss *stringSet, index func(s string) uint16) {
+ ss.sortFunc(func(a, b string) bool {
+ return index(a) < index(b)
+ })
+ m := []fromTo{}
+ for _, s := range ss.s {
+ m = append(m, fromTo{index(s), index(ss.update[s])})
+ }
+ b.writeSlice(name, m)
+}
+
+const base = 'z' - 'a' + 1
+
+func strToInt(s string) uint {
+ v := uint(0)
+ for i := 0; i < len(s); i++ {
+ v *= base
+ v += uint(s[i] - 'a')
+ }
+ return v
+}
+
+// converts the given integer to the original ASCII string passed to strToInt.
+// len(s) must match the number of characters obtained.
+func intToStr(v uint, s []byte) {
+ for i := len(s) - 1; i >= 0; i-- {
+ s[i] = byte(v%base) + 'a'
+ v /= base
+ }
+}
+
+func (b *builder) writeBitVector(name string, ss []string) {
+ vec := make([]uint8, int(math.Ceil(math.Pow(base, float64(len(ss[0])))/8)))
+ for _, s := range ss {
+ v := strToInt(s)
+ vec[v/8] |= 1 << (v % 8)
+ }
+ b.writeSlice(name, vec)
+}
+
+// TODO: convert this type into a list or two-stage trie.
+func (b *builder) writeMapFunc(name string, m map[string]string, f func(string) uint16) {
+ b.comment(name)
+ v := reflect.ValueOf(m)
+ sz := v.Len() * (2 + int(v.Type().Key().Size()))
+ for _, k := range m {
+ sz += len(k)
+ }
+ b.addSize(sz)
+ keys := []string{}
+ b.pf(`var %s = map[string]uint16{`, name)
+ for k := range m {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ b.pf("\t%q: %v,", k, f(m[k]))
+ }
+ b.p("}")
+}
+
+func (b *builder) writeMap(name string, m interface{}) {
+ b.comment(name)
+ v := reflect.ValueOf(m)
+ sz := v.Len() * (2 + int(v.Type().Key().Size()) + int(v.Type().Elem().Size()))
+ b.addSize(sz)
+ f := strings.FieldsFunc(fmt.Sprintf("%#v", m), func(r rune) bool {
+ return strings.IndexRune("{}, ", r) != -1
+ })
+ sort.Strings(f[1:])
+ b.pf(`var %s = %s{`, name, f[0])
+ for _, kv := range f[1:] {
+ b.pf("\t%s,", kv)
+ }
+ b.p("}")
+}
+
+func (b *builder) langIndex(s string) uint16 {
+ if s == "und" {
+ return 0
+ }
+ if i, ok := b.lang.find(s); ok {
+ return uint16(i)
+ }
+ return uint16(strToInt(s)) + uint16(len(b.lang.s))
+}
+
+// inc advances the string to its lexicographical successor.
+func inc(s string) string {
+ const maxTagLength = 4
+ var buf [maxTagLength]byte
+ intToStr(strToInt(strings.ToLower(s))+1, buf[:len(s)])
+ for i := 0; i < len(s); i++ {
+ if s[i] <= 'Z' {
+ buf[i] -= 'a' - 'A'
+ }
+ }
+ return string(buf[:len(s)])
+}
+
+func (b *builder) parseIndices() {
+ meta := b.supp.Metadata
+
+ for k, v := range b.registry {
+ var ss *stringSet
+ switch v.typ {
+ case "language":
+ if len(k) == 2 || v.suppressScript != "" || v.scope == "special" {
+ b.lang.add(k)
+ continue
+ } else {
+ ss = &b.langNoIndex
+ }
+ case "region":
+ ss = &b.region
+ case "script":
+ ss = &b.script
+ case "variant":
+ ss = &b.variant
+ default:
+ continue
+ }
+ ss.add(k)
+ }
+ // Include any language for which there is data.
+ for _, lang := range b.data.Locales() {
+ if x := b.data.RawLDML(lang); false ||
+ x.LocaleDisplayNames != nil ||
+ x.Characters != nil ||
+ x.Delimiters != nil ||
+ x.Measurement != nil ||
+ x.Dates != nil ||
+ x.Numbers != nil ||
+ x.Units != nil ||
+ x.ListPatterns != nil ||
+ x.Collations != nil ||
+ x.Segmentations != nil ||
+ x.Rbnf != nil ||
+ x.Annotations != nil ||
+ x.Metadata != nil {
+
+ from := strings.Split(lang, "_")
+ if lang := from[0]; lang != "root" {
+ b.lang.add(lang)
+ }
+ }
+ }
+ // Include locales for plural rules, which uses a different structure.
+ for _, plurals := range b.data.Supplemental().Plurals {
+ for _, rules := range plurals.PluralRules {
+ for _, lang := range strings.Split(rules.Locales, " ") {
+ if lang = strings.Split(lang, "_")[0]; lang != "root" {
+ b.lang.add(lang)
+ }
+ }
+ }
+ }
+ // Include languages in likely subtags.
+ for _, m := range b.supp.LikelySubtags.LikelySubtag {
+ from := strings.Split(m.From, "_")
+ b.lang.add(from[0])
+ }
+ // Include ISO-639 alpha-3 bibliographic entries.
+ for _, a := range meta.Alias.LanguageAlias {
+ if a.Reason == "bibliographic" {
+ b.langNoIndex.add(a.Type)
+ }
+ }
+ // Include regions in territoryAlias (not all are in the IANA registry!)
+ for _, reg := range b.supp.Metadata.Alias.TerritoryAlias {
+ if len(reg.Type) == 2 {
+ b.region.add(reg.Type)
+ }
+ }
+
+ for _, s := range b.lang.s {
+ if len(s) == 3 {
+ b.langNoIndex.remove(s)
+ }
+ }
+ b.writeConst("numLanguages", len(b.lang.slice())+len(b.langNoIndex.slice()))
+ b.writeConst("numScripts", len(b.script.slice()))
+ b.writeConst("numRegions", len(b.region.slice()))
+
+ // Add dummy codes at the start of each list to represent "unspecified".
+ b.lang.add("---")
+ b.script.add("----")
+ b.region.add("---")
+
+ // common locales
+ b.locale.parse(meta.DefaultContent.Locales)
+}
+
+// TODO: region inclusion data will probably not be use used in future matchers.
+
+func (b *builder) computeRegionGroups() {
+ b.groups = make(map[int]index)
+
+ // Create group indices.
+ for i := 1; b.region.s[i][0] < 'A'; i++ { // Base M49 indices on regionID.
+ b.groups[i] = index(len(b.groups))
+ }
+ for _, g := range b.supp.TerritoryContainment.Group {
+ // Skip UN and EURO zone as they are flattening the containment
+ // relationship.
+ if g.Type == "EZ" || g.Type == "UN" {
+ continue
+ }
+ group := b.region.index(g.Type)
+ if _, ok := b.groups[group]; !ok {
+ b.groups[group] = index(len(b.groups))
+ }
+ }
+ if len(b.groups) > 32 {
+ log.Fatalf("only 32 groups supported, found %d", len(b.groups))
+ }
+ b.writeConst("nRegionGroups", len(b.groups))
+}
+
+var langConsts = []string{
+ "af", "am", "ar", "az", "bg", "bn", "ca", "cs", "da", "de", "el", "en", "es",
+ "et", "fa", "fi", "fil", "fr", "gu", "he", "hi", "hr", "hu", "hy", "id", "is",
+ "it", "ja", "ka", "kk", "km", "kn", "ko", "ky", "lo", "lt", "lv", "mk", "ml",
+ "mn", "mo", "mr", "ms", "mul", "my", "nb", "ne", "nl", "no", "pa", "pl", "pt",
+ "ro", "ru", "sh", "si", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th",
+ "tl", "tn", "tr", "uk", "ur", "uz", "vi", "zh", "zu",
+
+ // constants for grandfathered tags (if not already defined)
+ "jbo", "ami", "bnn", "hak", "tlh", "lb", "nv", "pwn", "tao", "tay", "tsu",
+ "nn", "sfb", "vgt", "sgg", "cmn", "nan", "hsn",
+}
+
+// writeLanguage generates all tables needed for language canonicalization.
+func (b *builder) writeLanguage() {
+ meta := b.supp.Metadata
+
+ b.writeConst("nonCanonicalUnd", b.lang.index("und"))
+ b.writeConsts(func(s string) int { return int(b.langIndex(s)) }, langConsts...)
+ b.writeConst("langPrivateStart", b.langIndex("qaa"))
+ b.writeConst("langPrivateEnd", b.langIndex("qtz"))
+
+ // Get language codes that need to be mapped (overlong 3-letter codes,
+ // deprecated 2-letter codes, legacy and grandfathered tags.)
+ langAliasMap := stringSet{}
+ aliasTypeMap := map[string]langAliasType{}
+
+ // altLangISO3 get the alternative ISO3 names that need to be mapped.
+ altLangISO3 := stringSet{}
+ // Add dummy start to avoid the use of index 0.
+ altLangISO3.add("---")
+ altLangISO3.updateLater("---", "aa")
+
+ lang := b.lang.clone()
+ for _, a := range meta.Alias.LanguageAlias {
+ if a.Replacement == "" {
+ a.Replacement = "und"
+ }
+ // TODO: support mapping to tags
+ repl := strings.SplitN(a.Replacement, "_", 2)[0]
+ if a.Reason == "overlong" {
+ if len(a.Replacement) == 2 && len(a.Type) == 3 {
+ lang.updateLater(a.Replacement, a.Type)
+ }
+ } else if len(a.Type) <= 3 {
+ switch a.Reason {
+ case "macrolanguage":
+ aliasTypeMap[a.Type] = langMacro
+ case "deprecated":
+ // handled elsewhere
+ continue
+ case "bibliographic", "legacy":
+ if a.Type == "no" {
+ continue
+ }
+ aliasTypeMap[a.Type] = langLegacy
+ default:
+ log.Fatalf("new %s alias: %s", a.Reason, a.Type)
+ }
+ langAliasMap.add(a.Type)
+ langAliasMap.updateLater(a.Type, repl)
+ }
+ }
+ // Manually add the mapping of "nb" (Norwegian) to its macro language.
+ // This can be removed if CLDR adopts this change.
+ langAliasMap.add("nb")
+ langAliasMap.updateLater("nb", "no")
+ aliasTypeMap["nb"] = langMacro
+
+ for k, v := range b.registry {
+ // Also add deprecated values for 3-letter ISO codes, which CLDR omits.
+ if v.typ == "language" && v.deprecated != "" && v.preferred != "" {
+ langAliasMap.add(k)
+ langAliasMap.updateLater(k, v.preferred)
+ aliasTypeMap[k] = langDeprecated
+ }
+ }
+ // Fix CLDR mappings.
+ lang.updateLater("tl", "tgl")
+ lang.updateLater("sh", "hbs")
+ lang.updateLater("mo", "mol")
+ lang.updateLater("no", "nor")
+ lang.updateLater("tw", "twi")
+ lang.updateLater("nb", "nob")
+ lang.updateLater("ak", "aka")
+ lang.updateLater("bh", "bih")
+
+ // Ensure that each 2-letter code is matched with a 3-letter code.
+ for _, v := range lang.s[1:] {
+ s, ok := lang.update[v]
+ if !ok {
+ if s, ok = lang.update[langAliasMap.update[v]]; !ok {
+ continue
+ }
+ lang.update[v] = s
+ }
+ if v[0] != s[0] {
+ altLangISO3.add(s)
+ altLangISO3.updateLater(s, v)
+ }
+ }
+
+ // Complete canonialized language tags.
+ lang.freeze()
+ for i, v := range lang.s {
+ // We can avoid these manual entries by using the IANI registry directly.
+ // Seems easier to update the list manually, as changes are rare.
+ // The panic in this loop will trigger if we miss an entry.
+ add := ""
+ if s, ok := lang.update[v]; ok {
+ if s[0] == v[0] {
+ add = s[1:]
+ } else {
+ add = string([]byte{0, byte(altLangISO3.index(s))})
+ }
+ } else if len(v) == 3 {
+ add = "\x00"
+ } else {
+ log.Panicf("no data for long form of %q", v)
+ }
+ lang.s[i] += add
+ }
+ b.writeConst("lang", tag.Index(lang.join()))
+
+ b.writeConst("langNoIndexOffset", len(b.lang.s))
+
+ // space of all valid 3-letter language identifiers.
+ b.writeBitVector("langNoIndex", b.langNoIndex.slice())
+
+ altLangIndex := []uint16{}
+ for i, s := range altLangISO3.slice() {
+ altLangISO3.s[i] += string([]byte{byte(len(altLangIndex))})
+ if i > 0 {
+ idx := b.lang.index(altLangISO3.update[s])
+ altLangIndex = append(altLangIndex, uint16(idx))
+ }
+ }
+ b.writeConst("altLangISO3", tag.Index(altLangISO3.join()))
+ b.writeSlice("altLangIndex", altLangIndex)
+
+ b.writeSortedMap("langAliasMap", &langAliasMap, b.langIndex)
+ types := make([]langAliasType, len(langAliasMap.s))
+ for i, s := range langAliasMap.s {
+ types[i] = aliasTypeMap[s]
+ }
+ b.writeSlice("langAliasTypes", types)
+}
+
+var scriptConsts = []string{
+ "Latn", "Hani", "Hans", "Hant", "Qaaa", "Qaai", "Qabx", "Zinh", "Zyyy",
+ "Zzzz",
+}
+
+func (b *builder) writeScript() {
+ b.writeConsts(b.script.index, scriptConsts...)
+ b.writeConst("script", tag.Index(b.script.join()))
+
+ supp := make([]uint8, len(b.lang.slice()))
+ for i, v := range b.lang.slice()[1:] {
+ if sc := b.registry[v].suppressScript; sc != "" {
+ supp[i+1] = uint8(b.script.index(sc))
+ }
+ }
+ b.writeSlice("suppressScript", supp)
+
+ // There is only one deprecated script in CLDR. This value is hard-coded.
+ // We check here if the code must be updated.
+ for _, a := range b.supp.Metadata.Alias.ScriptAlias {
+ if a.Type != "Qaai" {
+ log.Panicf("unexpected deprecated stript %q", a.Type)
+ }
+ }
+}
+
+func parseM49(s string) int16 {
+ if len(s) == 0 {
+ return 0
+ }
+ v, err := strconv.ParseUint(s, 10, 10)
+ failOnError(err)
+ return int16(v)
+}
+
+var regionConsts = []string{
+ "001", "419", "BR", "CA", "ES", "GB", "MD", "PT", "UK", "US",
+ "ZZ", "XA", "XC", "XK", // Unofficial tag for Kosovo.
+}
+
+func (b *builder) writeRegion() {
+ b.writeConsts(b.region.index, regionConsts...)
+
+ isoOffset := b.region.index("AA")
+ m49map := make([]int16, len(b.region.slice()))
+ fromM49map := make(map[int16]int)
+ altRegionISO3 := ""
+ altRegionIDs := []uint16{}
+
+ b.writeConst("isoRegionOffset", isoOffset)
+
+ // 2-letter region lookup and mapping to numeric codes.
+ regionISO := b.region.clone()
+ regionISO.s = regionISO.s[isoOffset:]
+ regionISO.sorted = false
+
+ regionTypes := make([]byte, len(b.region.s))
+
+ // Is the region valid BCP 47?
+ for s, e := range b.registry {
+ if len(s) == 2 && s == strings.ToUpper(s) {
+ i := b.region.index(s)
+ for _, d := range e.description {
+ if strings.Contains(d, "Private use") {
+ regionTypes[i] = iso3166UserAssgined
+ }
+ }
+ regionTypes[i] |= bcp47Region
+ }
+ }
+
+ // Is the region a valid ccTLD?
+ r := gen.OpenIANAFile("domains/root/db")
+ defer r.Close()
+
+ buf, err := ioutil.ReadAll(r)
+ failOnError(err)
+ re := regexp.MustCompile(`"/domains/root/db/([a-z]{2}).html"`)
+ for _, m := range re.FindAllSubmatch(buf, -1) {
+ i := b.region.index(strings.ToUpper(string(m[1])))
+ regionTypes[i] |= ccTLD
+ }
+
+ b.writeSlice("regionTypes", regionTypes)
+
+ iso3Set := make(map[string]int)
+ update := func(iso2, iso3 string) {
+ i := regionISO.index(iso2)
+ if j, ok := iso3Set[iso3]; !ok && iso3[0] == iso2[0] {
+ regionISO.s[i] += iso3[1:]
+ iso3Set[iso3] = -1
+ } else {
+ if ok && j >= 0 {
+ regionISO.s[i] += string([]byte{0, byte(j)})
+ } else {
+ iso3Set[iso3] = len(altRegionISO3)
+ regionISO.s[i] += string([]byte{0, byte(len(altRegionISO3))})
+ altRegionISO3 += iso3
+ altRegionIDs = append(altRegionIDs, uint16(isoOffset+i))
+ }
+ }
+ }
+ for _, tc := range b.supp.CodeMappings.TerritoryCodes {
+ i := regionISO.index(tc.Type) + isoOffset
+ if d := m49map[i]; d != 0 {
+ log.Panicf("%s found as a duplicate UN.M49 code of %03d", tc.Numeric, d)
+ }
+ m49 := parseM49(tc.Numeric)
+ m49map[i] = m49
+ if r := fromM49map[m49]; r == 0 {
+ fromM49map[m49] = i
+ } else if r != i {
+ dep := b.registry[regionISO.s[r-isoOffset]].deprecated
+ if t := b.registry[tc.Type]; t != nil && dep != "" && (t.deprecated == "" || t.deprecated > dep) {
+ fromM49map[m49] = i
+ }
+ }
+ }
+ for _, ta := range b.supp.Metadata.Alias.TerritoryAlias {
+ if len(ta.Type) == 3 && ta.Type[0] <= '9' && len(ta.Replacement) == 2 {
+ from := parseM49(ta.Type)
+ if r := fromM49map[from]; r == 0 {
+ fromM49map[from] = regionISO.index(ta.Replacement) + isoOffset
+ }
+ }
+ }
+ for _, tc := range b.supp.CodeMappings.TerritoryCodes {
+ if len(tc.Alpha3) == 3 {
+ update(tc.Type, tc.Alpha3)
+ }
+ }
+ // This entries are not included in territoryCodes. Mostly 3-letter variants
+ // of deleted codes and an entry for QU.
+ for _, m := range []struct{ iso2, iso3 string }{
+ {"CT", "CTE"},
+ {"DY", "DHY"},
+ {"HV", "HVO"},
+ {"JT", "JTN"},
+ {"MI", "MID"},
+ {"NH", "NHB"},
+ {"NQ", "ATN"},
+ {"PC", "PCI"},
+ {"PU", "PUS"},
+ {"PZ", "PCZ"},
+ {"RH", "RHO"},
+ {"VD", "VDR"},
+ {"WK", "WAK"},
+ // These three-letter codes are used for others as well.
+ {"FQ", "ATF"},
+ } {
+ update(m.iso2, m.iso3)
+ }
+ for i, s := range regionISO.s {
+ if len(s) != 4 {
+ regionISO.s[i] = s + " "
+ }
+ }
+ b.writeConst("regionISO", tag.Index(regionISO.join()))
+ b.writeConst("altRegionISO3", altRegionISO3)
+ b.writeSlice("altRegionIDs", altRegionIDs)
+
+ // Create list of deprecated regions.
+ // TODO: consider inserting SF -> FI. Not included by CLDR, but is the only
+ // Transitionally-reserved mapping not included.
+ regionOldMap := stringSet{}
+ // Include regions in territoryAlias (not all are in the IANA registry!)
+ for _, reg := range b.supp.Metadata.Alias.TerritoryAlias {
+ if len(reg.Type) == 2 && reg.Reason == "deprecated" && len(reg.Replacement) == 2 {
+ regionOldMap.add(reg.Type)
+ regionOldMap.updateLater(reg.Type, reg.Replacement)
+ i, _ := regionISO.find(reg.Type)
+ j, _ := regionISO.find(reg.Replacement)
+ if k := m49map[i+isoOffset]; k == 0 {
+ m49map[i+isoOffset] = m49map[j+isoOffset]
+ }
+ }
+ }
+ b.writeSortedMap("regionOldMap", &regionOldMap, func(s string) uint16 {
+ return uint16(b.region.index(s))
+ })
+ // 3-digit region lookup, groupings.
+ for i := 1; i < isoOffset; i++ {
+ m := parseM49(b.region.s[i])
+ m49map[i] = m
+ fromM49map[m] = i
+ }
+ b.writeSlice("m49", m49map)
+
+ const (
+ searchBits = 7
+ regionBits = 9
+ )
+ if len(m49map) >= 1<<regionBits {
+ log.Fatalf("Maximum number of regions exceeded: %d > %d", len(m49map), 1<<regionBits)
+ }
+ m49Index := [9]int16{}
+ fromM49 := []uint16{}
+ m49 := []int{}
+ for k, _ := range fromM49map {
+ m49 = append(m49, int(k))
+ }
+ sort.Ints(m49)
+ for _, k := range m49[1:] {
+ val := (k & (1<<searchBits - 1)) << regionBits
+ fromM49 = append(fromM49, uint16(val|fromM49map[int16(k)]))
+ m49Index[1:][k>>searchBits] = int16(len(fromM49))
+ }
+ b.writeSlice("m49Index", m49Index)
+ b.writeSlice("fromM49", fromM49)
+}
+
+const (
+ // TODO: put these lists in regionTypes as user data? Could be used for
+ // various optimizations and refinements and could be exposed in the API.
+ iso3166Except = "AC CP DG EA EU FX IC SU TA UK"
+ iso3166Trans = "AN BU CS NT TP YU ZR" // SF is not in our set of Regions.
+ // DY and RH are actually not deleted, but indeterminately reserved.
+ iso3166DelCLDR = "CT DD DY FQ HV JT MI NH NQ PC PU PZ RH VD WK YD"
+)
+
+const (
+ iso3166UserAssgined = 1 << iota
+ ccTLD
+ bcp47Region
+)
+
+func find(list []string, s string) int {
+ for i, t := range list {
+ if t == s {
+ return i
+ }
+ }
+ return -1
+}
+
+// writeVariants generates per-variant information and creates a map from variant
+// name to index value. We assign index values such that sorting multiple
+// variants by index value will result in the correct order.
+// There are two types of variants: specialized and general. Specialized variants
+// are only applicable to certain language or language-script pairs. Generalized
+// variants apply to any language. Generalized variants always sort after
+// specialized variants. We will therefore always assign a higher index value
+// to a generalized variant than any other variant. Generalized variants are
+// sorted alphabetically among themselves.
+// Specialized variants may also sort after other specialized variants. Such
+// variants will be ordered after any of the variants they may follow.
+// We assume that if a variant x is followed by a variant y, then for any prefix
+// p of x, p-x is a prefix of y. This allows us to order tags based on the
+// maximum of the length of any of its prefixes.
+// TODO: it is possible to define a set of Prefix values on variants such that
+// a total order cannot be defined to the point that this algorithm breaks.
+// In other words, we cannot guarantee the same order of variants for the
+// future using the same algorithm or for non-compliant combinations of
+// variants. For this reason, consider using simple alphabetic sorting
+// of variants and ignore Prefix restrictions altogether.
+func (b *builder) writeVariant() {
+ generalized := stringSet{}
+ specialized := stringSet{}
+ specializedExtend := stringSet{}
+ // Collate the variants by type and check assumptions.
+ for _, v := range b.variant.slice() {
+ e := b.registry[v]
+ if len(e.prefix) == 0 {
+ generalized.add(v)
+ continue
+ }
+ c := strings.Split(e.prefix[0], "-")
+ hasScriptOrRegion := false
+ if len(c) > 1 {
+ _, hasScriptOrRegion = b.script.find(c[1])
+ if !hasScriptOrRegion {
+ _, hasScriptOrRegion = b.region.find(c[1])
+
+ }
+ }
+ if len(c) == 1 || len(c) == 2 && hasScriptOrRegion {
+ // Variant is preceded by a language.
+ specialized.add(v)
+ continue
+ }
+ // Variant is preceded by another variant.
+ specializedExtend.add(v)
+ prefix := c[0] + "-"
+ if hasScriptOrRegion {
+ prefix += c[1]
+ }
+ for _, p := range e.prefix {
+ // Verify that the prefix minus the last element is a prefix of the
+ // predecessor element.
+ i := strings.LastIndex(p, "-")
+ pred := b.registry[p[i+1:]]
+ if find(pred.prefix, p[:i]) < 0 {
+ log.Fatalf("prefix %q for variant %q not consistent with predecessor spec", p, v)
+ }
+ // The sorting used below does not work in the general case. It works
+ // if we assume that variants that may be followed by others only have
+ // prefixes of the same length. Verify this.
+ count := strings.Count(p[:i], "-")
+ for _, q := range pred.prefix {
+ if c := strings.Count(q, "-"); c != count {
+ log.Fatalf("variant %q preceding %q has a prefix %q of size %d; want %d", p[i+1:], v, q, c, count)
+ }
+ }
+ if !strings.HasPrefix(p, prefix) {
+ log.Fatalf("prefix %q of variant %q should start with %q", p, v, prefix)
+ }
+ }
+ }
+
+ // Sort extended variants.
+ a := specializedExtend.s
+ less := func(v, w string) bool {
+ // Sort by the maximum number of elements.
+ maxCount := func(s string) (max int) {
+ for _, p := range b.registry[s].prefix {
+ if c := strings.Count(p, "-"); c > max {
+ max = c
+ }
+ }
+ return
+ }
+ if cv, cw := maxCount(v), maxCount(w); cv != cw {
+ return cv < cw
+ }
+ // Sort by name as tie breaker.
+ return v < w
+ }
+ sort.Sort(funcSorter{less, sort.StringSlice(a)})
+ specializedExtend.frozen = true
+
+ // Create index from variant name to index.
+ variantIndex := make(map[string]uint8)
+ add := func(s []string) {
+ for _, v := range s {
+ variantIndex[v] = uint8(len(variantIndex))
+ }
+ }
+ add(specialized.slice())
+ add(specializedExtend.s)
+ numSpecialized := len(variantIndex)
+ add(generalized.slice())
+ if n := len(variantIndex); n > 255 {
+ log.Fatalf("maximum number of variants exceeded: was %d; want <= 255", n)
+ }
+ b.writeMap("variantIndex", variantIndex)
+ b.writeConst("variantNumSpecialized", numSpecialized)
+}
+
+func (b *builder) writeLanguageInfo() {
+}
+
+// writeLikelyData writes tables that are used both for finding parent relations and for
+// language matching. Each entry contains additional bits to indicate the status of the
+// data to know when it cannot be used for parent relations.
+func (b *builder) writeLikelyData() {
+ const (
+ isList = 1 << iota
+ scriptInFrom
+ regionInFrom
+ )
+ type ( // generated types
+ likelyScriptRegion struct {
+ region uint16
+ script uint8
+ flags uint8
+ }
+ likelyLangScript struct {
+ lang uint16
+ script uint8
+ flags uint8
+ }
+ likelyLangRegion struct {
+ lang uint16
+ region uint16
+ }
+ // likelyTag is used for getting likely tags for group regions, where
+ // the likely region might be a region contained in the group.
+ likelyTag struct {
+ lang uint16
+ region uint16
+ script uint8
+ }
+ )
+ var ( // generated variables
+ likelyRegionGroup = make([]likelyTag, len(b.groups))
+ likelyLang = make([]likelyScriptRegion, len(b.lang.s))
+ likelyRegion = make([]likelyLangScript, len(b.region.s))
+ likelyScript = make([]likelyLangRegion, len(b.script.s))
+ likelyLangList = []likelyScriptRegion{}
+ likelyRegionList = []likelyLangScript{}
+ )
+ type fromTo struct {
+ from, to []string
+ }
+ langToOther := map[int][]fromTo{}
+ regionToOther := map[int][]fromTo{}
+ for _, m := range b.supp.LikelySubtags.LikelySubtag {
+ from := strings.Split(m.From, "_")
+ to := strings.Split(m.To, "_")
+ if len(to) != 3 {
+ log.Fatalf("invalid number of subtags in %q: found %d, want 3", m.To, len(to))
+ }
+ if len(from) > 3 {
+ log.Fatalf("invalid number of subtags: found %d, want 1-3", len(from))
+ }
+ if from[0] != to[0] && from[0] != "und" {
+ log.Fatalf("unexpected language change in expansion: %s -> %s", from, to)
+ }
+ if len(from) == 3 {
+ if from[2] != to[2] {
+ log.Fatalf("unexpected region change in expansion: %s -> %s", from, to)
+ }
+ if from[0] != "und" {
+ log.Fatalf("unexpected fully specified from tag: %s -> %s", from, to)
+ }
+ }
+ if len(from) == 1 || from[0] != "und" {
+ id := 0
+ if from[0] != "und" {
+ id = b.lang.index(from[0])
+ }
+ langToOther[id] = append(langToOther[id], fromTo{from, to})
+ } else if len(from) == 2 && len(from[1]) == 4 {
+ sid := b.script.index(from[1])
+ likelyScript[sid].lang = uint16(b.langIndex(to[0]))
+ likelyScript[sid].region = uint16(b.region.index(to[2]))
+ } else {
+ r := b.region.index(from[len(from)-1])
+ if id, ok := b.groups[r]; ok {
+ if from[0] != "und" {
+ log.Fatalf("region changed unexpectedly: %s -> %s", from, to)
+ }
+ likelyRegionGroup[id].lang = uint16(b.langIndex(to[0]))
+ likelyRegionGroup[id].script = uint8(b.script.index(to[1]))
+ likelyRegionGroup[id].region = uint16(b.region.index(to[2]))
+ } else {
+ regionToOther[r] = append(regionToOther[r], fromTo{from, to})
+ }
+ }
+ }
+ b.writeType(likelyLangRegion{})
+ b.writeSlice("likelyScript", likelyScript)
+
+ for id := range b.lang.s {
+ list := langToOther[id]
+ if len(list) == 1 {
+ likelyLang[id].region = uint16(b.region.index(list[0].to[2]))
+ likelyLang[id].script = uint8(b.script.index(list[0].to[1]))
+ } else if len(list) > 1 {
+ likelyLang[id].flags = isList
+ likelyLang[id].region = uint16(len(likelyLangList))
+ likelyLang[id].script = uint8(len(list))
+ for _, x := range list {
+ flags := uint8(0)
+ if len(x.from) > 1 {
+ if x.from[1] == x.to[2] {
+ flags = regionInFrom
+ } else {
+ flags = scriptInFrom
+ }
+ }
+ likelyLangList = append(likelyLangList, likelyScriptRegion{
+ region: uint16(b.region.index(x.to[2])),
+ script: uint8(b.script.index(x.to[1])),
+ flags: flags,
+ })
+ }
+ }
+ }
+ // TODO: merge suppressScript data with this table.
+ b.writeType(likelyScriptRegion{})
+ b.writeSlice("likelyLang", likelyLang)
+ b.writeSlice("likelyLangList", likelyLangList)
+
+ for id := range b.region.s {
+ list := regionToOther[id]
+ if len(list) == 1 {
+ likelyRegion[id].lang = uint16(b.langIndex(list[0].to[0]))
+ likelyRegion[id].script = uint8(b.script.index(list[0].to[1]))
+ if len(list[0].from) > 2 {
+ likelyRegion[id].flags = scriptInFrom
+ }
+ } else if len(list) > 1 {
+ likelyRegion[id].flags = isList
+ likelyRegion[id].lang = uint16(len(likelyRegionList))
+ likelyRegion[id].script = uint8(len(list))
+ for i, x := range list {
+ if len(x.from) == 2 && i != 0 || i > 0 && len(x.from) != 3 {
+ log.Fatalf("unspecified script must be first in list: %v at %d", x.from, i)
+ }
+ x := likelyLangScript{
+ lang: uint16(b.langIndex(x.to[0])),
+ script: uint8(b.script.index(x.to[1])),
+ }
+ if len(list[0].from) > 2 {
+ x.flags = scriptInFrom
+ }
+ likelyRegionList = append(likelyRegionList, x)
+ }
+ }
+ }
+ b.writeType(likelyLangScript{})
+ b.writeSlice("likelyRegion", likelyRegion)
+ b.writeSlice("likelyRegionList", likelyRegionList)
+
+ b.writeType(likelyTag{})
+ b.writeSlice("likelyRegionGroup", likelyRegionGroup)
+}
+
+type mutualIntelligibility struct {
+ want, have uint16
+ conf uint8
+ oneway bool
+}
+
+type scriptIntelligibility struct {
+ lang uint16 // langID or 0 if *
+ want, have uint8
+ conf uint8
+}
+
+type sortByConf []mutualIntelligibility
+
+func (l sortByConf) Less(a, b int) bool {
+ return l[a].conf > l[b].conf
+}
+
+func (l sortByConf) Swap(a, b int) {
+ l[a], l[b] = l[b], l[a]
+}
+
+func (l sortByConf) Len() int {
+ return len(l)
+}
+
+// toConf converts a percentage value [0, 100] to a confidence class.
+func toConf(pct uint8) uint8 {
+ switch {
+ case pct == 100:
+ return 3 // Exact
+ case pct >= 90:
+ return 2 // High
+ case pct > 50:
+ return 1 // Low
+ default:
+ return 0 // No
+ }
+}
+
+// writeMatchData writes tables with languages and scripts for which there is
+// mutual intelligibility. The data is based on CLDR's languageMatching data.
+// Note that we use a different algorithm than the one defined by CLDR and that
+// we slightly modify the data. For example, we convert scores to confidence levels.
+// We also drop all region-related data as we use a different algorithm to
+// determine region equivalence.
+func (b *builder) writeMatchData() {
+ b.writeType(mutualIntelligibility{})
+ b.writeType(scriptIntelligibility{})
+ lm := b.supp.LanguageMatching.LanguageMatches
+ cldr.MakeSlice(&lm).SelectAnyOf("type", "written")
+
+ matchLang := []mutualIntelligibility{}
+ matchScript := []scriptIntelligibility{}
+ // Convert the languageMatch entries in lists keyed by desired language.
+ for _, m := range lm[0].LanguageMatch {
+ // Different versions of CLDR use different separators.
+ desired := strings.Replace(m.Desired, "-", "_", -1)
+ supported := strings.Replace(m.Supported, "-", "_", -1)
+ d := strings.Split(desired, "_")
+ s := strings.Split(supported, "_")
+ if len(d) != len(s) || len(d) > 2 {
+ // Skip all entries with regions and work around CLDR bug.
+ continue
+ }
+ pct, _ := strconv.ParseInt(m.Percent, 10, 8)
+ if len(d) == 2 && d[0] == s[0] && len(d[1]) == 4 {
+ // language-script pair.
+ lang := uint16(0)
+ if d[0] != "*" {
+ lang = uint16(b.langIndex(d[0]))
+ }
+ matchScript = append(matchScript, scriptIntelligibility{
+ lang: lang,
+ want: uint8(b.script.index(d[1])),
+ have: uint8(b.script.index(s[1])),
+ conf: toConf(uint8(pct)),
+ })
+ if m.Oneway != "true" {
+ matchScript = append(matchScript, scriptIntelligibility{
+ lang: lang,
+ want: uint8(b.script.index(s[1])),
+ have: uint8(b.script.index(d[1])),
+ conf: toConf(uint8(pct)),
+ })
+ }
+ } else if len(d) == 1 && d[0] != "*" {
+ if pct == 100 {
+ // nb == no is already handled by macro mapping. Check there
+ // really is only this case.
+ if d[0] != "no" || s[0] != "nb" {
+ log.Fatalf("unhandled equivalence %s == %s", s[0], d[0])
+ }
+ continue
+ }
+ matchLang = append(matchLang, mutualIntelligibility{
+ want: uint16(b.langIndex(d[0])),
+ have: uint16(b.langIndex(s[0])),
+ conf: uint8(pct),
+ oneway: m.Oneway == "true",
+ })
+ } else {
+ // TODO: Handle other mappings.
+ a := []string{"*;*", "*_*;*_*", "es_MX;es_419"}
+ s := strings.Join([]string{desired, supported}, ";")
+ if i := sort.SearchStrings(a, s); i == len(a) || a[i] != s {
+ log.Printf("%q not handled", s)
+ }
+ }
+ }
+ sort.Stable(sortByConf(matchLang))
+ // collapse percentage into confidence classes
+ for i, m := range matchLang {
+ matchLang[i].conf = toConf(m.conf)
+ }
+ b.writeSlice("matchLang", matchLang)
+ b.writeSlice("matchScript", matchScript)
+}
+
+func (b *builder) writeRegionInclusionData() {
+ var (
+ // mm holds for each group the set of groups with a distance of 1.
+ mm = make(map[int][]index)
+
+ // containment holds for each group the transitive closure of
+ // containment of other groups.
+ containment = make(map[index][]index)
+ )
+ for _, g := range b.supp.TerritoryContainment.Group {
+ // Skip UN and EURO zone as they are flattening the containment
+ // relationship.
+ if g.Type == "EZ" || g.Type == "UN" {
+ continue
+ }
+ group := b.region.index(g.Type)
+ groupIdx := b.groups[group]
+ for _, mem := range strings.Split(g.Contains, " ") {
+ r := b.region.index(mem)
+ mm[r] = append(mm[r], groupIdx)
+ if g, ok := b.groups[r]; ok {
+ mm[group] = append(mm[group], g)
+ containment[groupIdx] = append(containment[groupIdx], g)
+ }
+ }
+ }
+
+ regionContainment := make([]uint32, len(b.groups))
+ for _, g := range b.groups {
+ l := containment[g]
+
+ // Compute the transitive closure of containment.
+ for i := 0; i < len(l); i++ {
+ l = append(l, containment[l[i]]...)
+ }
+
+ // Compute the bitmask.
+ regionContainment[g] = 1 << g
+ for _, v := range l {
+ regionContainment[g] |= 1 << v
+ }
+ // log.Printf("%d: %X", g, regionContainment[g])
+ }
+ b.writeSlice("regionContainment", regionContainment)
+
+ regionInclusion := make([]uint8, len(b.region.s))
+ bvs := make(map[uint32]index)
+ // Make the first bitvector positions correspond with the groups.
+ for r, i := range b.groups {
+ bv := uint32(1 << i)
+ for _, g := range mm[r] {
+ bv |= 1 << g
+ }
+ bvs[bv] = i
+ regionInclusion[r] = uint8(bvs[bv])
+ }
+ for r := 1; r < len(b.region.s); r++ {
+ if _, ok := b.groups[r]; !ok {
+ bv := uint32(0)
+ for _, g := range mm[r] {
+ bv |= 1 << g
+ }
+ if bv == 0 {
+ // Pick the world for unspecified regions.
+ bv = 1 << b.groups[b.region.index("001")]
+ }
+ if _, ok := bvs[bv]; !ok {
+ bvs[bv] = index(len(bvs))
+ }
+ regionInclusion[r] = uint8(bvs[bv])
+ }
+ }
+ b.writeSlice("regionInclusion", regionInclusion)
+ regionInclusionBits := make([]uint32, len(bvs))
+ for k, v := range bvs {
+ regionInclusionBits[v] = uint32(k)
+ }
+ // Add bit vectors for increasingly large distances until a fixed point is reached.
+ regionInclusionNext := []uint8{}
+ for i := 0; i < len(regionInclusionBits); i++ {
+ bits := regionInclusionBits[i]
+ next := bits
+ for i := uint(0); i < uint(len(b.groups)); i++ {
+ if bits&(1<<i) != 0 {
+ next |= regionInclusionBits[i]
+ }
+ }
+ if _, ok := bvs[next]; !ok {
+ bvs[next] = index(len(bvs))
+ regionInclusionBits = append(regionInclusionBits, next)
+ }
+ regionInclusionNext = append(regionInclusionNext, uint8(bvs[next]))
+ }
+ b.writeSlice("regionInclusionBits", regionInclusionBits)
+ b.writeSlice("regionInclusionNext", regionInclusionNext)
+}
+
+type parentRel struct {
+ lang uint16
+ script uint8
+ maxScript uint8
+ toRegion uint16
+ fromRegion []uint16
+}
+
+func (b *builder) writeParents() {
+ b.writeType(parentRel{})
+
+ parents := []parentRel{}
+
+ // Construct parent overrides.
+ n := 0
+ for _, p := range b.data.Supplemental().ParentLocales.ParentLocale {
+ // Skipping non-standard scripts to root is implemented using addTags.
+ if p.Parent == "root" {
+ continue
+ }
+
+ sub := strings.Split(p.Parent, "_")
+ parent := parentRel{lang: b.langIndex(sub[0])}
+ if len(sub) == 2 {
+ // TODO: check that all undefined scripts are indeed Latn in these
+ // cases.
+ parent.maxScript = uint8(b.script.index("Latn"))
+ parent.toRegion = uint16(b.region.index(sub[1]))
+ } else {
+ parent.script = uint8(b.script.index(sub[1]))
+ parent.maxScript = parent.script
+ parent.toRegion = uint16(b.region.index(sub[2]))
+ }
+ for _, c := range strings.Split(p.Locales, " ") {
+ region := b.region.index(c[strings.LastIndex(c, "_")+1:])
+ parent.fromRegion = append(parent.fromRegion, uint16(region))
+ }
+ parents = append(parents, parent)
+ n += len(parent.fromRegion)
+ }
+ b.writeSliceAddSize("parents", n*2, parents)
+}
+
+func main() {
+ gen.Init()
+
+ gen.Repackage("gen_common.go", "common.go", "language")
+
+ w := gen.NewCodeWriter()
+ defer w.WriteGoFile("tables.go", "language")
+
+ fmt.Fprintln(w, `import "golang.org/x/text/internal/tag"`)
+
+ b := newBuilder(w)
+ gen.WriteCLDRVersion(w)
+
+ b.parseIndices()
+ b.writeType(fromTo{})
+ b.writeLanguage()
+ b.writeScript()
+ b.writeRegion()
+ b.writeVariant()
+ // TODO: b.writeLocale()
+ b.computeRegionGroups()
+ b.writeLikelyData()
+ b.writeMatchData()
+ b.writeRegionInclusionData()
+ b.writeParents()
+}
diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go
new file mode 100644
index 000000000..8ad950533
--- /dev/null
+++ b/vendor/golang.org/x/text/language/match.go
@@ -0,0 +1,841 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import "errors"
+
+// Matcher is the interface that wraps the Match method.
+//
+// Match returns the best match for any of the given tags, along with
+// a unique index associated with the returned tag and a confidence
+// score.
+type Matcher interface {
+ Match(t ...Tag) (tag Tag, index int, c Confidence)
+}
+
+// Comprehends reports the confidence score for a speaker of a given language
+// to being able to comprehend the written form of an alternative language.
+func Comprehends(speaker, alternative Tag) Confidence {
+ _, _, c := NewMatcher([]Tag{alternative}).Match(speaker)
+ return c
+}
+
+// NewMatcher returns a Matcher that matches an ordered list of preferred tags
+// against a list of supported tags based on written intelligibility, closeness
+// of dialect, equivalence of subtags and various other rules. It is initialized
+// with the list of supported tags. The first element is used as the default
+// value in case no match is found.
+//
+// Its Match method matches the first of the given Tags to reach a certain
+// confidence threshold. The tags passed to Match should therefore be specified
+// in order of preference. Extensions are ignored for matching.
+//
+// The index returned by the Match method corresponds to the index of the
+// matched tag in t, but is augmented with the Unicode extension ('u')of the
+// corresponding preferred tag. This allows user locale options to be passed
+// transparently.
+func NewMatcher(t []Tag) Matcher {
+ return newMatcher(t)
+}
+
+func (m *matcher) Match(want ...Tag) (t Tag, index int, c Confidence) {
+ match, w, c := m.getBest(want...)
+ if match == nil {
+ t = m.default_.tag
+ } else {
+ t, index = match.tag, match.index
+ }
+ // Copy options from the user-provided tag into the result tag. This is hard
+ // to do after the fact, so we do it here.
+ // TODO: consider also adding in variants that are compatible with the
+ // matched language.
+ // TODO: Add back region if it is non-ambiguous? Or create another tag to
+ // preserve the region?
+ if u, ok := w.Extension('u'); ok {
+ t, _ = Raw.Compose(t, u)
+ }
+ return t, index, c
+}
+
+type scriptRegionFlags uint8
+
+const (
+ isList = 1 << iota
+ scriptInFrom
+ regionInFrom
+)
+
+func (t *Tag) setUndefinedLang(id langID) {
+ if t.lang == 0 {
+ t.lang = id
+ }
+}
+
+func (t *Tag) setUndefinedScript(id scriptID) {
+ if t.script == 0 {
+ t.script = id
+ }
+}
+
+func (t *Tag) setUndefinedRegion(id regionID) {
+ if t.region == 0 || t.region.contains(id) {
+ t.region = id
+ }
+}
+
+// ErrMissingLikelyTagsData indicates no information was available
+// to compute likely values of missing tags.
+var ErrMissingLikelyTagsData = errors.New("missing likely tags data")
+
+// addLikelySubtags sets subtags to their most likely value, given the locale.
+// In most cases this means setting fields for unknown values, but in some
+// cases it may alter a value. It returns a ErrMissingLikelyTagsData error
+// if the given locale cannot be expanded.
+func (t Tag) addLikelySubtags() (Tag, error) {
+ id, err := addTags(t)
+ if err != nil {
+ return t, err
+ } else if id.equalTags(t) {
+ return t, nil
+ }
+ id.remakeString()
+ return id, nil
+}
+
+// specializeRegion attempts to specialize a group region.
+func specializeRegion(t *Tag) bool {
+ if i := regionInclusion[t.region]; i < nRegionGroups {
+ x := likelyRegionGroup[i]
+ if langID(x.lang) == t.lang && scriptID(x.script) == t.script {
+ t.region = regionID(x.region)
+ }
+ return true
+ }
+ return false
+}
+
+func addTags(t Tag) (Tag, error) {
+ // We leave private use identifiers alone.
+ if t.private() {
+ return t, nil
+ }
+ if t.script != 0 && t.region != 0 {
+ if t.lang != 0 {
+ // already fully specified
+ specializeRegion(&t)
+ return t, nil
+ }
+ // Search matches for und-script-region. Note that for these cases
+ // region will never be a group so there is no need to check for this.
+ list := likelyRegion[t.region : t.region+1]
+ if x := list[0]; x.flags&isList != 0 {
+ list = likelyRegionList[x.lang : x.lang+uint16(x.script)]
+ }
+ for _, x := range list {
+ // Deviating from the spec. See match_test.go for details.
+ if scriptID(x.script) == t.script {
+ t.setUndefinedLang(langID(x.lang))
+ return t, nil
+ }
+ }
+ }
+ if t.lang != 0 {
+ // Search matches for lang-script and lang-region, where lang != und.
+ if t.lang < langNoIndexOffset {
+ x := likelyLang[t.lang]
+ if x.flags&isList != 0 {
+ list := likelyLangList[x.region : x.region+uint16(x.script)]
+ if t.script != 0 {
+ for _, x := range list {
+ if scriptID(x.script) == t.script && x.flags&scriptInFrom != 0 {
+ t.setUndefinedRegion(regionID(x.region))
+ return t, nil
+ }
+ }
+ } else if t.region != 0 {
+ count := 0
+ goodScript := true
+ tt := t
+ for _, x := range list {
+ // We visit all entries for which the script was not
+ // defined, including the ones where the region was not
+ // defined. This allows for proper disambiguation within
+ // regions.
+ if x.flags&scriptInFrom == 0 && t.region.contains(regionID(x.region)) {
+ tt.region = regionID(x.region)
+ tt.setUndefinedScript(scriptID(x.script))
+ goodScript = goodScript && tt.script == scriptID(x.script)
+ count++
+ }
+ }
+ if count == 1 {
+ return tt, nil
+ }
+ // Even if we fail to find a unique Region, we might have
+ // an unambiguous script.
+ if goodScript {
+ t.script = tt.script
+ }
+ }
+ }
+ }
+ } else {
+ // Search matches for und-script.
+ if t.script != 0 {
+ x := likelyScript[t.script]
+ if x.region != 0 {
+ t.setUndefinedRegion(regionID(x.region))
+ t.setUndefinedLang(langID(x.lang))
+ return t, nil
+ }
+ }
+ // Search matches for und-region. If und-script-region exists, it would
+ // have been found earlier.
+ if t.region != 0 {
+ if i := regionInclusion[t.region]; i < nRegionGroups {
+ x := likelyRegionGroup[i]
+ if x.region != 0 {
+ t.setUndefinedLang(langID(x.lang))
+ t.setUndefinedScript(scriptID(x.script))
+ t.region = regionID(x.region)
+ }
+ } else {
+ x := likelyRegion[t.region]
+ if x.flags&isList != 0 {
+ x = likelyRegionList[x.lang]
+ }
+ if x.script != 0 && x.flags != scriptInFrom {
+ t.setUndefinedLang(langID(x.lang))
+ t.setUndefinedScript(scriptID(x.script))
+ return t, nil
+ }
+ }
+ }
+ }
+
+ // Search matches for lang.
+ if t.lang < langNoIndexOffset {
+ x := likelyLang[t.lang]
+ if x.flags&isList != 0 {
+ x = likelyLangList[x.region]
+ }
+ if x.region != 0 {
+ t.setUndefinedScript(scriptID(x.script))
+ t.setUndefinedRegion(regionID(x.region))
+ }
+ specializeRegion(&t)
+ if t.lang == 0 {
+ t.lang = _en // default language
+ }
+ return t, nil
+ }
+ return t, ErrMissingLikelyTagsData
+}
+
+func (t *Tag) setTagsFrom(id Tag) {
+ t.lang = id.lang
+ t.script = id.script
+ t.region = id.region
+}
+
+// minimize removes the region or script subtags from t such that
+// t.addLikelySubtags() == t.minimize().addLikelySubtags().
+func (t Tag) minimize() (Tag, error) {
+ t, err := minimizeTags(t)
+ if err != nil {
+ return t, err
+ }
+ t.remakeString()
+ return t, nil
+}
+
+// minimizeTags mimics the behavior of the ICU 51 C implementation.
+func minimizeTags(t Tag) (Tag, error) {
+ if t.equalTags(und) {
+ return t, nil
+ }
+ max, err := addTags(t)
+ if err != nil {
+ return t, err
+ }
+ for _, id := range [...]Tag{
+ {lang: t.lang},
+ {lang: t.lang, region: t.region},
+ {lang: t.lang, script: t.script},
+ } {
+ if x, err := addTags(id); err == nil && max.equalTags(x) {
+ t.setTagsFrom(id)
+ break
+ }
+ }
+ return t, nil
+}
+
+// Tag Matching
+// CLDR defines an algorithm for finding the best match between two sets of language
+// tags. The basic algorithm defines how to score a possible match and then find
+// the match with the best score
+// (see http://www.unicode.org/reports/tr35/#LanguageMatching).
+// Using scoring has several disadvantages. The scoring obfuscates the importance of
+// the various factors considered, making the algorithm harder to understand. Using
+// scoring also requires the full score to be computed for each pair of tags.
+//
+// We will use a different algorithm which aims to have the following properties:
+// - clarity on the precedence of the various selection factors, and
+// - improved performance by allowing early termination of a comparison.
+//
+// Matching algorithm (overview)
+// Input:
+// - supported: a set of supported tags
+// - default: the default tag to return in case there is no match
+// - desired: list of desired tags, ordered by preference, starting with
+// the most-preferred.
+//
+// Algorithm:
+// 1) Set the best match to the lowest confidence level
+// 2) For each tag in "desired":
+// a) For each tag in "supported":
+// 1) compute the match between the two tags.
+// 2) if the match is better than the previous best match, replace it
+// with the new match. (see next section)
+// b) if the current best match is above a certain threshold, return this
+// match without proceeding to the next tag in "desired". [See Note 1]
+// 3) If the best match so far is below a certain threshold, return "default".
+//
+// Ranking:
+// We use two phases to determine whether one pair of tags are a better match
+// than another pair of tags. First, we determine a rough confidence level. If the
+// levels are different, the one with the highest confidence wins.
+// Second, if the rough confidence levels are identical, we use a set of tie-breaker
+// rules.
+//
+// The confidence level of matching a pair of tags is determined by finding the
+// lowest confidence level of any matches of the corresponding subtags (the
+// result is deemed as good as its weakest link).
+// We define the following levels:
+// Exact - An exact match of a subtag, before adding likely subtags.
+// MaxExact - An exact match of a subtag, after adding likely subtags.
+// [See Note 2].
+// High - High level of mutual intelligibility between different subtag
+// variants.
+// Low - Low level of mutual intelligibility between different subtag
+// variants.
+// No - No mutual intelligibility.
+//
+// The following levels can occur for each type of subtag:
+// Base: Exact, MaxExact, High, Low, No
+// Script: Exact, MaxExact [see Note 3], Low, No
+// Region: Exact, MaxExact, High
+// Variant: Exact, High
+// Private: Exact, No
+//
+// Any result with a confidence level of Low or higher is deemed a possible match.
+// Once a desired tag matches any of the supported tags with a level of MaxExact
+// or higher, the next desired tag is not considered (see Step 2.b).
+// Note that CLDR provides languageMatching data that defines close equivalence
+// classes for base languages, scripts and regions.
+//
+// Tie-breaking
+// If we get the same confidence level for two matches, we apply a sequence of
+// tie-breaking rules. The first that succeeds defines the result. The rules are
+// applied in the following order.
+// 1) Original language was defined and was identical.
+// 2) Original region was defined and was identical.
+// 3) Distance between two maximized regions was the smallest.
+// 4) Original script was defined and was identical.
+// 5) Distance from want tag to have tag using the parent relation [see Note 5.]
+// If there is still no winner after these rules are applied, the first match
+// found wins.
+//
+// Notes:
+// [1] Note that even if we may not have a perfect match, if a match is above a
+// certain threshold, it is considered a better match than any other match
+// to a tag later in the list of preferred language tags.
+// [2] In practice, as matching of Exact is done in a separate phase from
+// matching the other levels, we reuse the Exact level to mean MaxExact in
+// the second phase. As a consequence, we only need the levels defined by
+// the Confidence type. The MaxExact confidence level is mapped to High in
+// the public API.
+// [3] We do not differentiate between maximized script values that were derived
+// from suppressScript versus most likely tag data. We determined that in
+// ranking the two, one ranks just after the other. Moreover, the two cannot
+// occur concurrently. As a consequence, they are identical for practical
+// purposes.
+// [4] In case of deprecated, macro-equivalents and legacy mappings, we assign
+// the MaxExact level to allow iw vs he to still be a closer match than
+// en-AU vs en-US, for example.
+// [5] In CLDR a locale inherits fields that are unspecified for this locale
+// from its parent. Therefore, if a locale is a parent of another locale,
+// it is a strong measure for closeness, especially when no other tie
+// breaker rule applies. One could also argue it is inconsistent, for
+// example, when pt-AO matches pt (which CLDR equates with pt-BR), even
+// though its parent is pt-PT according to the inheritance rules.
+//
+// Implementation Details:
+// There are several performance considerations worth pointing out. Most notably,
+// we preprocess as much as possible (within reason) at the time of creation of a
+// matcher. This includes:
+// - creating a per-language map, which includes data for the raw base language
+// and its canonicalized variant (if applicable),
+// - expanding entries for the equivalence classes defined in CLDR's
+// languageMatch data.
+// The per-language map ensures that typically only a very small number of tags
+// need to be considered. The pre-expansion of canonicalized subtags and
+// equivalence classes reduces the amount of map lookups that need to be done at
+// runtime.
+
+// matcher keeps a set of supported language tags, indexed by language.
+type matcher struct {
+ default_ *haveTag
+ index map[langID]*matchHeader
+ passSettings bool
+}
+
+// matchHeader has the lists of tags for exact matches and matches based on
+// maximized and canonicalized tags for a given language.
+type matchHeader struct {
+ exact []*haveTag
+ max []*haveTag
+}
+
+// haveTag holds a supported Tag and its maximized script and region. The maximized
+// or canonicalized language is not stored as it is not needed during matching.
+type haveTag struct {
+ tag Tag
+
+ // index of this tag in the original list of supported tags.
+ index int
+
+ // conf is the maximum confidence that can result from matching this haveTag.
+ // When conf < Exact this means it was inserted after applying a CLDR equivalence rule.
+ conf Confidence
+
+ // Maximized region and script.
+ maxRegion regionID
+ maxScript scriptID
+
+ // altScript may be checked as an alternative match to maxScript. If altScript
+ // matches, the confidence level for this match is Low. Theoretically there
+ // could be multiple alternative scripts. This does not occur in practice.
+ altScript scriptID
+
+ // nextMax is the index of the next haveTag with the same maximized tags.
+ nextMax uint16
+}
+
+func makeHaveTag(tag Tag, index int) (haveTag, langID) {
+ max := tag
+ if tag.lang != 0 {
+ max, _ = max.canonicalize(All)
+ max, _ = addTags(max)
+ max.remakeString()
+ }
+ return haveTag{tag, index, Exact, max.region, max.script, altScript(max.lang, max.script), 0}, max.lang
+}
+
+// altScript returns an alternative script that may match the given script with
+// a low confidence. At the moment, the langMatch data allows for at most one
+// script to map to another and we rely on this to keep the code simple.
+func altScript(l langID, s scriptID) scriptID {
+ for _, alt := range matchScript {
+ if (alt.lang == 0 || langID(alt.lang) == l) && scriptID(alt.have) == s {
+ return scriptID(alt.want)
+ }
+ }
+ return 0
+}
+
+// addIfNew adds a haveTag to the list of tags only if it is a unique tag.
+// Tags that have the same maximized values are linked by index.
+func (h *matchHeader) addIfNew(n haveTag, exact bool) {
+ // Don't add new exact matches.
+ for _, v := range h.exact {
+ if v.tag.equalsRest(n.tag) {
+ return
+ }
+ }
+ if exact {
+ h.exact = append(h.exact, &n)
+ }
+ // Allow duplicate maximized tags, but create a linked list to allow quickly
+ // comparing the equivalents and bail out.
+ for i, v := range h.max {
+ if v.maxScript == n.maxScript &&
+ v.maxRegion == n.maxRegion &&
+ v.tag.variantOrPrivateTagStr() == n.tag.variantOrPrivateTagStr() {
+ for h.max[i].nextMax != 0 {
+ i = int(h.max[i].nextMax)
+ }
+ h.max[i].nextMax = uint16(len(h.max))
+ break
+ }
+ }
+ h.max = append(h.max, &n)
+}
+
+// header returns the matchHeader for the given language. It creates one if
+// it doesn't already exist.
+func (m *matcher) header(l langID) *matchHeader {
+ if h := m.index[l]; h != nil {
+ return h
+ }
+ h := &matchHeader{}
+ m.index[l] = h
+ return h
+}
+
+// newMatcher builds an index for the given supported tags and returns it as
+// a matcher. It also expands the index by considering various equivalence classes
+// for a given tag.
+func newMatcher(supported []Tag) *matcher {
+ m := &matcher{
+ index: make(map[langID]*matchHeader),
+ }
+ if len(supported) == 0 {
+ m.default_ = &haveTag{}
+ return m
+ }
+ // Add supported languages to the index. Add exact matches first to give
+ // them precedence.
+ for i, tag := range supported {
+ pair, _ := makeHaveTag(tag, i)
+ m.header(tag.lang).addIfNew(pair, true)
+ }
+ m.default_ = m.header(supported[0].lang).exact[0]
+ for i, tag := range supported {
+ pair, max := makeHaveTag(tag, i)
+ if max != tag.lang {
+ m.header(max).addIfNew(pair, false)
+ }
+ }
+
+ // update is used to add indexes in the map for equivalent languages.
+ // If force is true, the update will also apply to derived entries. To
+ // avoid applying a "transitive closure", use false.
+ update := func(want, have uint16, conf Confidence, force bool) {
+ if hh := m.index[langID(have)]; hh != nil {
+ if !force && len(hh.exact) == 0 {
+ return
+ }
+ hw := m.header(langID(want))
+ for _, ht := range hh.max {
+ v := *ht
+ if conf < v.conf {
+ v.conf = conf
+ }
+ v.nextMax = 0 // this value needs to be recomputed
+ if v.altScript != 0 {
+ v.altScript = altScript(langID(want), v.maxScript)
+ }
+ hw.addIfNew(v, conf == Exact && len(hh.exact) > 0)
+ }
+ }
+ }
+
+ // Add entries for languages with mutual intelligibility as defined by CLDR's
+ // languageMatch data.
+ for _, ml := range matchLang {
+ update(ml.want, ml.have, Confidence(ml.conf), false)
+ if !ml.oneway {
+ update(ml.have, ml.want, Confidence(ml.conf), false)
+ }
+ }
+
+ // Add entries for possible canonicalizations. This is an optimization to
+ // ensure that only one map lookup needs to be done at runtime per desired tag.
+ // First we match deprecated equivalents. If they are perfect equivalents
+ // (their canonicalization simply substitutes a different language code, but
+ // nothing else), the match confidence is Exact, otherwise it is High.
+ for i, lm := range langAliasMap {
+ if lm.from == _sh {
+ continue
+ }
+
+ // If deprecated codes match and there is no fiddling with the script or
+ // or region, we consider it an exact match.
+ conf := Exact
+ if langAliasTypes[i] != langMacro {
+ if !isExactEquivalent(langID(lm.from)) {
+ conf = High
+ }
+ update(lm.to, lm.from, conf, true)
+ }
+ update(lm.from, lm.to, conf, true)
+ }
+ return m
+}
+
+// getBest gets the best matching tag in m for any of the given tags, taking into
+// account the order of preference of the given tags.
+func (m *matcher) getBest(want ...Tag) (got *haveTag, orig Tag, c Confidence) {
+ best := bestMatch{}
+ for _, w := range want {
+ var max Tag
+ // Check for exact match first.
+ h := m.index[w.lang]
+ if w.lang != 0 {
+ // Base language is defined.
+ if h == nil {
+ continue
+ }
+ for i := range h.exact {
+ have := h.exact[i]
+ if have.tag.equalsRest(w) {
+ return have, w, Exact
+ }
+ }
+ max, _ = w.canonicalize(Legacy | Deprecated)
+ max, _ = addTags(max)
+ } else {
+ // Base language is not defined.
+ if h != nil {
+ for i := range h.exact {
+ have := h.exact[i]
+ if have.tag.equalsRest(w) {
+ return have, w, Exact
+ }
+ }
+ }
+ if w.script == 0 && w.region == 0 {
+ // We skip all tags matching und for approximate matching, including
+ // private tags.
+ continue
+ }
+ max, _ = addTags(w)
+ if h = m.index[max.lang]; h == nil {
+ continue
+ }
+ }
+ // Check for match based on maximized tag.
+ for i := range h.max {
+ have := h.max[i]
+ best.update(have, w, max.script, max.region)
+ if best.conf == Exact {
+ for have.nextMax != 0 {
+ have = h.max[have.nextMax]
+ best.update(have, w, max.script, max.region)
+ }
+ return best.have, best.want, High
+ }
+ }
+ }
+ if best.conf <= No {
+ if len(want) != 0 {
+ return nil, want[0], No
+ }
+ return nil, Tag{}, No
+ }
+ return best.have, best.want, best.conf
+}
+
+// bestMatch accumulates the best match so far.
+type bestMatch struct {
+ have *haveTag
+ want Tag
+ conf Confidence
+ // Cached results from applying tie-breaking rules.
+ origLang bool
+ origReg bool
+ regDist uint8
+ origScript bool
+ parentDist uint8 // 255 if have is not an ancestor of want tag.
+}
+
+// update updates the existing best match if the new pair is considered to be a
+// better match.
+// To determine if the given pair is a better match, it first computes the rough
+// confidence level. If this surpasses the current match, it will replace it and
+// update the tie-breaker rule cache. If there is a tie, it proceeds with applying
+// a series of tie-breaker rules. If there is no conclusive winner after applying
+// the tie-breaker rules, it leaves the current match as the preferred match.
+func (m *bestMatch) update(have *haveTag, tag Tag, maxScript scriptID, maxRegion regionID) {
+ // Bail if the maximum attainable confidence is below that of the current best match.
+ c := have.conf
+ if c < m.conf {
+ return
+ }
+ if have.maxScript != maxScript {
+ // There is usually very little comprehension between different scripts.
+ // In a few cases there may still be Low comprehension. This possibility is
+ // pre-computed and stored in have.altScript.
+ if Low < m.conf || have.altScript != maxScript {
+ return
+ }
+ c = Low
+ } else if have.maxRegion != maxRegion {
+ // There is usually a small difference between languages across regions.
+ // We use the region distance (below) to disambiguate between equal matches.
+ if High < c {
+ c = High
+ }
+ }
+
+ // We store the results of the computations of the tie-breaker rules along
+ // with the best match. There is no need to do the checks once we determine
+ // we have a winner, but we do still need to do the tie-breaker computations.
+ // We use "beaten" to keep track if we still need to do the checks.
+ beaten := false // true if the new pair defeats the current one.
+ if c != m.conf {
+ if c < m.conf {
+ return
+ }
+ beaten = true
+ }
+
+ // Tie-breaker rules:
+ // We prefer if the pre-maximized language was specified and identical.
+ origLang := have.tag.lang == tag.lang && tag.lang != 0
+ if !beaten && m.origLang != origLang {
+ if m.origLang {
+ return
+ }
+ beaten = true
+ }
+
+ // We prefer if the pre-maximized region was specified and identical.
+ origReg := have.tag.region == tag.region && tag.region != 0
+ if !beaten && m.origReg != origReg {
+ if m.origReg {
+ return
+ }
+ beaten = true
+ }
+
+ // Next we prefer smaller distances between regions, as defined by regionDist.
+ regDist := regionDist(have.maxRegion, maxRegion, tag.lang)
+ if !beaten && m.regDist != regDist {
+ if regDist > m.regDist {
+ return
+ }
+ beaten = true
+ }
+
+ // Next we prefer if the pre-maximized script was specified and identical.
+ origScript := have.tag.script == tag.script && tag.script != 0
+ if !beaten && m.origScript != origScript {
+ if m.origScript {
+ return
+ }
+ beaten = true
+ }
+
+ // Finally we prefer tags which have a closer parent relationship.
+ parentDist := parentDistance(have.tag.region, tag)
+ if !beaten && m.parentDist != parentDist {
+ if parentDist > m.parentDist {
+ return
+ }
+ beaten = true
+ }
+
+ // Update m to the newly found best match.
+ if beaten {
+ m.have = have
+ m.want = tag
+ m.conf = c
+ m.origLang = origLang
+ m.origReg = origReg
+ m.origScript = origScript
+ m.regDist = regDist
+ m.parentDist = parentDist
+ }
+}
+
+// parentDistance returns the number of times Parent must be called before the
+// regions match. It is assumed that it has already been checked that lang and
+// script are identical. If haveRegion does not occur in the ancestor chain of
+// tag, it returns 255.
+func parentDistance(haveRegion regionID, tag Tag) uint8 {
+ p := tag.Parent()
+ d := uint8(1)
+ for haveRegion != p.region {
+ if p.region == 0 {
+ return 255
+ }
+ p = p.Parent()
+ d++
+ }
+ return d
+}
+
+// regionDist wraps regionDistance with some exceptions to the algorithmic distance.
+func regionDist(a, b regionID, lang langID) uint8 {
+ if lang == _en {
+ // Two variants of non-US English are close to each other, regardless of distance.
+ if a != _US && b != _US {
+ return 2
+ }
+ }
+ return uint8(regionDistance(a, b))
+}
+
+// regionDistance computes the distance between two regions based on the
+// distance in the graph of region containments as defined in CLDR. It iterates
+// over increasingly inclusive sets of groups, represented as bit vectors, until
+// the source bit vector has bits in common with the destination vector.
+func regionDistance(a, b regionID) int {
+ if a == b {
+ return 0
+ }
+ p, q := regionInclusion[a], regionInclusion[b]
+ if p < nRegionGroups {
+ p, q = q, p
+ }
+ set := regionInclusionBits
+ if q < nRegionGroups && set[p]&(1<<q) != 0 {
+ return 1
+ }
+ d := 2
+ for goal := set[q]; set[p]&goal == 0; p = regionInclusionNext[p] {
+ d++
+ }
+ return d
+}
+
+func (t Tag) variants() string {
+ if t.pVariant == 0 {
+ return ""
+ }
+ return t.str[t.pVariant:t.pExt]
+}
+
+// variantOrPrivateTagStr returns variants or private use tags.
+func (t Tag) variantOrPrivateTagStr() string {
+ if t.pExt > 0 {
+ return t.str[t.pVariant:t.pExt]
+ }
+ return t.str[t.pVariant:]
+}
+
+// equalsRest compares everything except the language.
+func (a Tag) equalsRest(b Tag) bool {
+ // TODO: don't include extensions in this comparison. To do this efficiently,
+ // though, we should handle private tags separately.
+ return a.script == b.script && a.region == b.region && a.variantOrPrivateTagStr() == b.variantOrPrivateTagStr()
+}
+
+// isExactEquivalent returns true if canonicalizing the language will not alter
+// the script or region of a tag.
+func isExactEquivalent(l langID) bool {
+ for _, o := range notEquivalent {
+ if o == l {
+ return false
+ }
+ }
+ return true
+}
+
+var notEquivalent []langID
+
+func init() {
+ // Create a list of all languages for which canonicalization may alter the
+ // script or region.
+ for _, lm := range langAliasMap {
+ tag := Tag{lang: langID(lm.from)}
+ if tag, _ = tag.canonicalize(All); tag.script != 0 || tag.region != 0 {
+ notEquivalent = append(notEquivalent, langID(lm.from))
+ }
+ }
+}
diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go
new file mode 100644
index 000000000..cfa28f56e
--- /dev/null
+++ b/vendor/golang.org/x/text/language/parse.go
@@ -0,0 +1,859 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "sort"
+ "strconv"
+ "strings"
+
+ "golang.org/x/text/internal/tag"
+)
+
+// isAlpha returns true if the byte is not a digit.
+// b must be an ASCII letter or digit.
+func isAlpha(b byte) bool {
+ return b > '9'
+}
+
+// isAlphaNum returns true if the string contains only ASCII letters or digits.
+func isAlphaNum(s []byte) bool {
+ for _, c := range s {
+ if !('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9') {
+ return false
+ }
+ }
+ return true
+}
+
+// errSyntax is returned by any of the parsing functions when the
+// input is not well-formed, according to BCP 47.
+// TODO: return the position at which the syntax error occurred?
+var errSyntax = errors.New("language: tag is not well-formed")
+
+// ValueError is returned by any of the parsing functions when the
+// input is well-formed but the respective subtag is not recognized
+// as a valid value.
+type ValueError struct {
+ v [8]byte
+}
+
+func mkErrInvalid(s []byte) error {
+ var e ValueError
+ copy(e.v[:], s)
+ return e
+}
+
+func (e ValueError) tag() []byte {
+ n := bytes.IndexByte(e.v[:], 0)
+ if n == -1 {
+ n = 8
+ }
+ return e.v[:n]
+}
+
+// Error implements the error interface.
+func (e ValueError) Error() string {
+ return fmt.Sprintf("language: subtag %q is well-formed but unknown", e.tag())
+}
+
+// Subtag returns the subtag for which the error occurred.
+func (e ValueError) Subtag() string {
+ return string(e.tag())
+}
+
+// scanner is used to scan BCP 47 tokens, which are separated by _ or -.
+type scanner struct {
+ b []byte
+ bytes [max99thPercentileSize]byte
+ token []byte
+ start int // start position of the current token
+ end int // end position of the current token
+ next int // next point for scan
+ err error
+ done bool
+}
+
+func makeScannerString(s string) scanner {
+ scan := scanner{}
+ if len(s) <= len(scan.bytes) {
+ scan.b = scan.bytes[:copy(scan.bytes[:], s)]
+ } else {
+ scan.b = []byte(s)
+ }
+ scan.init()
+ return scan
+}
+
+// makeScanner returns a scanner using b as the input buffer.
+// b is not copied and may be modified by the scanner routines.
+func makeScanner(b []byte) scanner {
+ scan := scanner{b: b}
+ scan.init()
+ return scan
+}
+
+func (s *scanner) init() {
+ for i, c := range s.b {
+ if c == '_' {
+ s.b[i] = '-'
+ }
+ }
+ s.scan()
+}
+
+// restToLower converts the string between start and end to lower case.
+func (s *scanner) toLower(start, end int) {
+ for i := start; i < end; i++ {
+ c := s.b[i]
+ if 'A' <= c && c <= 'Z' {
+ s.b[i] += 'a' - 'A'
+ }
+ }
+}
+
+func (s *scanner) setError(e error) {
+ if s.err == nil || (e == errSyntax && s.err != errSyntax) {
+ s.err = e
+ }
+}
+
+// resizeRange shrinks or grows the array at position oldStart such that
+// a new string of size newSize can fit between oldStart and oldEnd.
+// Sets the scan point to after the resized range.
+func (s *scanner) resizeRange(oldStart, oldEnd, newSize int) {
+ s.start = oldStart
+ if end := oldStart + newSize; end != oldEnd {
+ diff := end - oldEnd
+ if end < cap(s.b) {
+ b := make([]byte, len(s.b)+diff)
+ copy(b, s.b[:oldStart])
+ copy(b[end:], s.b[oldEnd:])
+ s.b = b
+ } else {
+ s.b = append(s.b[end:], s.b[oldEnd:]...)
+ }
+ s.next = end + (s.next - s.end)
+ s.end = end
+ }
+}
+
+// replace replaces the current token with repl.
+func (s *scanner) replace(repl string) {
+ s.resizeRange(s.start, s.end, len(repl))
+ copy(s.b[s.start:], repl)
+}
+
+// gobble removes the current token from the input.
+// Caller must call scan after calling gobble.
+func (s *scanner) gobble(e error) {
+ s.setError(e)
+ if s.start == 0 {
+ s.b = s.b[:+copy(s.b, s.b[s.next:])]
+ s.end = 0
+ } else {
+ s.b = s.b[:s.start-1+copy(s.b[s.start-1:], s.b[s.end:])]
+ s.end = s.start - 1
+ }
+ s.next = s.start
+}
+
+// deleteRange removes the given range from s.b before the current token.
+func (s *scanner) deleteRange(start, end int) {
+ s.setError(errSyntax)
+ s.b = s.b[:start+copy(s.b[start:], s.b[end:])]
+ diff := end - start
+ s.next -= diff
+ s.start -= diff
+ s.end -= diff
+}
+
+// scan parses the next token of a BCP 47 string. Tokens that are larger
+// than 8 characters or include non-alphanumeric characters result in an error
+// and are gobbled and removed from the output.
+// It returns the end position of the last token consumed.
+func (s *scanner) scan() (end int) {
+ end = s.end
+ s.token = nil
+ for s.start = s.next; s.next < len(s.b); {
+ i := bytes.IndexByte(s.b[s.next:], '-')
+ if i == -1 {
+ s.end = len(s.b)
+ s.next = len(s.b)
+ i = s.end - s.start
+ } else {
+ s.end = s.next + i
+ s.next = s.end + 1
+ }
+ token := s.b[s.start:s.end]
+ if i < 1 || i > 8 || !isAlphaNum(token) {
+ s.gobble(errSyntax)
+ continue
+ }
+ s.token = token
+ return end
+ }
+ if n := len(s.b); n > 0 && s.b[n-1] == '-' {
+ s.setError(errSyntax)
+ s.b = s.b[:len(s.b)-1]
+ }
+ s.done = true
+ return end
+}
+
+// acceptMinSize parses multiple tokens of the given size or greater.
+// It returns the end position of the last token consumed.
+func (s *scanner) acceptMinSize(min int) (end int) {
+ end = s.end
+ s.scan()
+ for ; len(s.token) >= min; s.scan() {
+ end = s.end
+ }
+ return end
+}
+
+// Parse parses the given BCP 47 string and returns a valid Tag. If parsing
+// failed it returns an error and any part of the tag that could be parsed.
+// If parsing succeeded but an unknown value was found, it returns
+// ValueError. The Tag returned in this case is just stripped of the unknown
+// value. All other values are preserved. It accepts tags in the BCP 47 format
+// and extensions to this standard defined in
+// http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// The resulting tag is canonicalized using the default canonicalization type.
+func Parse(s string) (t Tag, err error) {
+ return Default.Parse(s)
+}
+
+// Parse parses the given BCP 47 string and returns a valid Tag. If parsing
+// failed it returns an error and any part of the tag that could be parsed.
+// If parsing succeeded but an unknown value was found, it returns
+// ValueError. The Tag returned in this case is just stripped of the unknown
+// value. All other values are preserved. It accepts tags in the BCP 47 format
+// and extensions to this standard defined in
+// http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
+// The resulting tag is canonicalized using the the canonicalization type c.
+func (c CanonType) Parse(s string) (t Tag, err error) {
+ // TODO: consider supporting old-style locale key-value pairs.
+ if s == "" {
+ return und, errSyntax
+ }
+ if len(s) <= maxAltTaglen {
+ b := [maxAltTaglen]byte{}
+ for i, c := range s {
+ // Generating invalid UTF-8 is okay as it won't match.
+ if 'A' <= c && c <= 'Z' {
+ c += 'a' - 'A'
+ } else if c == '_' {
+ c = '-'
+ }
+ b[i] = byte(c)
+ }
+ if t, ok := grandfathered(b); ok {
+ return t, nil
+ }
+ }
+ scan := makeScannerString(s)
+ t, err = parse(&scan, s)
+ t, changed := t.canonicalize(c)
+ if changed {
+ t.remakeString()
+ }
+ return t, err
+}
+
+func parse(scan *scanner, s string) (t Tag, err error) {
+ t = und
+ var end int
+ if n := len(scan.token); n <= 1 {
+ scan.toLower(0, len(scan.b))
+ if n == 0 || scan.token[0] != 'x' {
+ return t, errSyntax
+ }
+ end = parseExtensions(scan)
+ } else if n >= 4 {
+ return und, errSyntax
+ } else { // the usual case
+ t, end = parseTag(scan)
+ if n := len(scan.token); n == 1 {
+ t.pExt = uint16(end)
+ end = parseExtensions(scan)
+ } else if end < len(scan.b) {
+ scan.setError(errSyntax)
+ scan.b = scan.b[:end]
+ }
+ }
+ if int(t.pVariant) < len(scan.b) {
+ if end < len(s) {
+ s = s[:end]
+ }
+ if len(s) > 0 && tag.Compare(s, scan.b) == 0 {
+ t.str = s
+ } else {
+ t.str = string(scan.b)
+ }
+ } else {
+ t.pVariant, t.pExt = 0, 0
+ }
+ return t, scan.err
+}
+
+// parseTag parses language, script, region and variants.
+// It returns a Tag and the end position in the input that was parsed.
+func parseTag(scan *scanner) (t Tag, end int) {
+ var e error
+ // TODO: set an error if an unknown lang, script or region is encountered.
+ t.lang, e = getLangID(scan.token)
+ scan.setError(e)
+ scan.replace(t.lang.String())
+ langStart := scan.start
+ end = scan.scan()
+ for len(scan.token) == 3 && isAlpha(scan.token[0]) {
+ // From http://tools.ietf.org/html/bcp47, <lang>-<extlang> tags are equivalent
+ // to a tag of the form <extlang>.
+ lang, e := getLangID(scan.token)
+ if lang != 0 {
+ t.lang = lang
+ copy(scan.b[langStart:], lang.String())
+ scan.b[langStart+3] = '-'
+ scan.start = langStart + 4
+ }
+ scan.gobble(e)
+ end = scan.scan()
+ }
+ if len(scan.token) == 4 && isAlpha(scan.token[0]) {
+ t.script, e = getScriptID(script, scan.token)
+ if t.script == 0 {
+ scan.gobble(e)
+ }
+ end = scan.scan()
+ }
+ if n := len(scan.token); n >= 2 && n <= 3 {
+ t.region, e = getRegionID(scan.token)
+ if t.region == 0 {
+ scan.gobble(e)
+ } else {
+ scan.replace(t.region.String())
+ }
+ end = scan.scan()
+ }
+ scan.toLower(scan.start, len(scan.b))
+ t.pVariant = byte(end)
+ end = parseVariants(scan, end, t)
+ t.pExt = uint16(end)
+ return t, end
+}
+
+var separator = []byte{'-'}
+
+// parseVariants scans tokens as long as each token is a valid variant string.
+// Duplicate variants are removed.
+func parseVariants(scan *scanner, end int, t Tag) int {
+ start := scan.start
+ varIDBuf := [4]uint8{}
+ variantBuf := [4][]byte{}
+ varID := varIDBuf[:0]
+ variant := variantBuf[:0]
+ last := -1
+ needSort := false
+ for ; len(scan.token) >= 4; scan.scan() {
+ // TODO: measure the impact of needing this conversion and redesign
+ // the data structure if there is an issue.
+ v, ok := variantIndex[string(scan.token)]
+ if !ok {
+ // unknown variant
+ // TODO: allow user-defined variants?
+ scan.gobble(mkErrInvalid(scan.token))
+ continue
+ }
+ varID = append(varID, v)
+ variant = append(variant, scan.token)
+ if !needSort {
+ if last < int(v) {
+ last = int(v)
+ } else {
+ needSort = true
+ // There is no legal combinations of more than 7 variants
+ // (and this is by no means a useful sequence).
+ const maxVariants = 8
+ if len(varID) > maxVariants {
+ break
+ }
+ }
+ }
+ end = scan.end
+ }
+ if needSort {
+ sort.Sort(variantsSort{varID, variant})
+ k, l := 0, -1
+ for i, v := range varID {
+ w := int(v)
+ if l == w {
+ // Remove duplicates.
+ continue
+ }
+ varID[k] = varID[i]
+ variant[k] = variant[i]
+ k++
+ l = w
+ }
+ if str := bytes.Join(variant[:k], separator); len(str) == 0 {
+ end = start - 1
+ } else {
+ scan.resizeRange(start, end, len(str))
+ copy(scan.b[scan.start:], str)
+ end = scan.end
+ }
+ }
+ return end
+}
+
+type variantsSort struct {
+ i []uint8
+ v [][]byte
+}
+
+func (s variantsSort) Len() int {
+ return len(s.i)
+}
+
+func (s variantsSort) Swap(i, j int) {
+ s.i[i], s.i[j] = s.i[j], s.i[i]
+ s.v[i], s.v[j] = s.v[j], s.v[i]
+}
+
+func (s variantsSort) Less(i, j int) bool {
+ return s.i[i] < s.i[j]
+}
+
+type bytesSort [][]byte
+
+func (b bytesSort) Len() int {
+ return len(b)
+}
+
+func (b bytesSort) Swap(i, j int) {
+ b[i], b[j] = b[j], b[i]
+}
+
+func (b bytesSort) Less(i, j int) bool {
+ return bytes.Compare(b[i], b[j]) == -1
+}
+
+// parseExtensions parses and normalizes the extensions in the buffer.
+// It returns the last position of scan.b that is part of any extension.
+// It also trims scan.b to remove excess parts accordingly.
+func parseExtensions(scan *scanner) int {
+ start := scan.start
+ exts := [][]byte{}
+ private := []byte{}
+ end := scan.end
+ for len(scan.token) == 1 {
+ extStart := scan.start
+ ext := scan.token[0]
+ end = parseExtension(scan)
+ extension := scan.b[extStart:end]
+ if len(extension) < 3 || (ext != 'x' && len(extension) < 4) {
+ scan.setError(errSyntax)
+ end = extStart
+ continue
+ } else if start == extStart && (ext == 'x' || scan.start == len(scan.b)) {
+ scan.b = scan.b[:end]
+ return end
+ } else if ext == 'x' {
+ private = extension
+ break
+ }
+ exts = append(exts, extension)
+ }
+ sort.Sort(bytesSort(exts))
+ if len(private) > 0 {
+ exts = append(exts, private)
+ }
+ scan.b = scan.b[:start]
+ if len(exts) > 0 {
+ scan.b = append(scan.b, bytes.Join(exts, separator)...)
+ } else if start > 0 {
+ // Strip trailing '-'.
+ scan.b = scan.b[:start-1]
+ }
+ return end
+}
+
+// parseExtension parses a single extension and returns the position of
+// the extension end.
+func parseExtension(scan *scanner) int {
+ start, end := scan.start, scan.end
+ switch scan.token[0] {
+ case 'u':
+ attrStart := end
+ scan.scan()
+ for last := []byte{}; len(scan.token) > 2; scan.scan() {
+ if bytes.Compare(scan.token, last) != -1 {
+ // Attributes are unsorted. Start over from scratch.
+ p := attrStart + 1
+ scan.next = p
+ attrs := [][]byte{}
+ for scan.scan(); len(scan.token) > 2; scan.scan() {
+ attrs = append(attrs, scan.token)
+ end = scan.end
+ }
+ sort.Sort(bytesSort(attrs))
+ copy(scan.b[p:], bytes.Join(attrs, separator))
+ break
+ }
+ last = scan.token
+ end = scan.end
+ }
+ var last, key []byte
+ for attrEnd := end; len(scan.token) == 2; last = key {
+ key = scan.token
+ keyEnd := scan.end
+ end = scan.acceptMinSize(3)
+ // TODO: check key value validity
+ if keyEnd == end || bytes.Compare(key, last) != 1 {
+ // We have an invalid key or the keys are not sorted.
+ // Start scanning keys from scratch and reorder.
+ p := attrEnd + 1
+ scan.next = p
+ keys := [][]byte{}
+ for scan.scan(); len(scan.token) == 2; {
+ keyStart, keyEnd := scan.start, scan.end
+ end = scan.acceptMinSize(3)
+ if keyEnd != end {
+ keys = append(keys, scan.b[keyStart:end])
+ } else {
+ scan.setError(errSyntax)
+ end = keyStart
+ }
+ }
+ sort.Sort(bytesSort(keys))
+ reordered := bytes.Join(keys, separator)
+ if e := p + len(reordered); e < end {
+ scan.deleteRange(e, end)
+ end = e
+ }
+ copy(scan.b[p:], bytes.Join(keys, separator))
+ break
+ }
+ }
+ case 't':
+ scan.scan()
+ if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) {
+ _, end = parseTag(scan)
+ scan.toLower(start, end)
+ }
+ for len(scan.token) == 2 && !isAlpha(scan.token[1]) {
+ end = scan.acceptMinSize(3)
+ }
+ case 'x':
+ end = scan.acceptMinSize(1)
+ default:
+ end = scan.acceptMinSize(2)
+ }
+ return end
+}
+
+// Compose creates a Tag from individual parts, which may be of type Tag, Base,
+// Script, Region, Variant, []Variant, Extension, []Extension or error. If a
+// Base, Script or Region or slice of type Variant or Extension is passed more
+// than once, the latter will overwrite the former. Variants and Extensions are
+// accumulated, but if two extensions of the same type are passed, the latter
+// will replace the former. A Tag overwrites all former values and typically
+// only makes sense as the first argument. The resulting tag is returned after
+// canonicalizing using the Default CanonType. If one or more errors are
+// encountered, one of the errors is returned.
+func Compose(part ...interface{}) (t Tag, err error) {
+ return Default.Compose(part...)
+}
+
+// Compose creates a Tag from individual parts, which may be of type Tag, Base,
+// Script, Region, Variant, []Variant, Extension, []Extension or error. If a
+// Base, Script or Region or slice of type Variant or Extension is passed more
+// than once, the latter will overwrite the former. Variants and Extensions are
+// accumulated, but if two extensions of the same type are passed, the latter
+// will replace the former. A Tag overwrites all former values and typically
+// only makes sense as the first argument. The resulting tag is returned after
+// canonicalizing using CanonType c. If one or more errors are encountered,
+// one of the errors is returned.
+func (c CanonType) Compose(part ...interface{}) (t Tag, err error) {
+ var b builder
+ if err = b.update(part...); err != nil {
+ return und, err
+ }
+ t, _ = b.tag.canonicalize(c)
+
+ if len(b.ext) > 0 || len(b.variant) > 0 {
+ sort.Sort(sortVariant(b.variant))
+ sort.Strings(b.ext)
+ if b.private != "" {
+ b.ext = append(b.ext, b.private)
+ }
+ n := maxCoreSize + tokenLen(b.variant...) + tokenLen(b.ext...)
+ buf := make([]byte, n)
+ p := t.genCoreBytes(buf)
+ t.pVariant = byte(p)
+ p += appendTokens(buf[p:], b.variant...)
+ t.pExt = uint16(p)
+ p += appendTokens(buf[p:], b.ext...)
+ t.str = string(buf[:p])
+ } else if b.private != "" {
+ t.str = b.private
+ t.remakeString()
+ }
+ return
+}
+
+type builder struct {
+ tag Tag
+
+ private string // the x extension
+ ext []string
+ variant []string
+
+ err error
+}
+
+func (b *builder) addExt(e string) {
+ if e == "" {
+ } else if e[0] == 'x' {
+ b.private = e
+ } else {
+ b.ext = append(b.ext, e)
+ }
+}
+
+var errInvalidArgument = errors.New("invalid Extension or Variant")
+
+func (b *builder) update(part ...interface{}) (err error) {
+ replace := func(l *[]string, s string, eq func(a, b string) bool) bool {
+ if s == "" {
+ b.err = errInvalidArgument
+ return true
+ }
+ for i, v := range *l {
+ if eq(v, s) {
+ (*l)[i] = s
+ return true
+ }
+ }
+ return false
+ }
+ for _, x := range part {
+ switch v := x.(type) {
+ case Tag:
+ b.tag.lang = v.lang
+ b.tag.region = v.region
+ b.tag.script = v.script
+ if v.str != "" {
+ b.variant = nil
+ for x, s := "", v.str[v.pVariant:v.pExt]; s != ""; {
+ x, s = nextToken(s)
+ b.variant = append(b.variant, x)
+ }
+ b.ext, b.private = nil, ""
+ for i, e := int(v.pExt), ""; i < len(v.str); {
+ i, e = getExtension(v.str, i)
+ b.addExt(e)
+ }
+ }
+ case Base:
+ b.tag.lang = v.langID
+ case Script:
+ b.tag.script = v.scriptID
+ case Region:
+ b.tag.region = v.regionID
+ case Variant:
+ if !replace(&b.variant, v.variant, func(a, b string) bool { return a == b }) {
+ b.variant = append(b.variant, v.variant)
+ }
+ case Extension:
+ if !replace(&b.ext, v.s, func(a, b string) bool { return a[0] == b[0] }) {
+ b.addExt(v.s)
+ }
+ case []Variant:
+ b.variant = nil
+ for _, x := range v {
+ b.update(x)
+ }
+ case []Extension:
+ b.ext, b.private = nil, ""
+ for _, e := range v {
+ b.update(e)
+ }
+ // TODO: support parsing of raw strings based on morphology or just extensions?
+ case error:
+ err = v
+ }
+ }
+ return
+}
+
+func tokenLen(token ...string) (n int) {
+ for _, t := range token {
+ n += len(t) + 1
+ }
+ return
+}
+
+func appendTokens(b []byte, token ...string) int {
+ p := 0
+ for _, t := range token {
+ b[p] = '-'
+ copy(b[p+1:], t)
+ p += 1 + len(t)
+ }
+ return p
+}
+
+type sortVariant []string
+
+func (s sortVariant) Len() int {
+ return len(s)
+}
+
+func (s sortVariant) Swap(i, j int) {
+ s[j], s[i] = s[i], s[j]
+}
+
+func (s sortVariant) Less(i, j int) bool {
+ return variantIndex[s[i]] < variantIndex[s[j]]
+}
+
+func findExt(list []string, x byte) int {
+ for i, e := range list {
+ if e[0] == x {
+ return i
+ }
+ }
+ return -1
+}
+
+// getExtension returns the name, body and end position of the extension.
+func getExtension(s string, p int) (end int, ext string) {
+ if s[p] == '-' {
+ p++
+ }
+ if s[p] == 'x' {
+ return len(s), s[p:]
+ }
+ end = nextExtension(s, p)
+ return end, s[p:end]
+}
+
+// nextExtension finds the next extension within the string, searching
+// for the -<char>- pattern from position p.
+// In the fast majority of cases, language tags will have at most
+// one extension and extensions tend to be small.
+func nextExtension(s string, p int) int {
+ for n := len(s) - 3; p < n; {
+ if s[p] == '-' {
+ if s[p+2] == '-' {
+ return p
+ }
+ p += 3
+ } else {
+ p++
+ }
+ }
+ return len(s)
+}
+
+var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight")
+
+// ParseAcceptLanguage parses the contents of a Accept-Language header as
+// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and
+// a list of corresponding quality weights. It is more permissive than RFC 2616
+// and may return non-nil slices even if the input is not valid.
+// The Tags will be sorted by highest weight first and then by first occurrence.
+// Tags with a weight of zero will be dropped. An error will be returned if the
+// input could not be parsed.
+func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) {
+ var entry string
+ for s != "" {
+ if entry, s = split(s, ','); entry == "" {
+ continue
+ }
+
+ entry, weight := split(entry, ';')
+
+ // Scan the language.
+ t, err := Parse(entry)
+ if err != nil {
+ id, ok := acceptFallback[entry]
+ if !ok {
+ return nil, nil, err
+ }
+ t = Tag{lang: id}
+ }
+
+ // Scan the optional weight.
+ w := 1.0
+ if weight != "" {
+ weight = consume(weight, 'q')
+ weight = consume(weight, '=')
+ // consume returns the empty string when a token could not be
+ // consumed, resulting in an error for ParseFloat.
+ if w, err = strconv.ParseFloat(weight, 32); err != nil {
+ return nil, nil, errInvalidWeight
+ }
+ // Drop tags with a quality weight of 0.
+ if w <= 0 {
+ continue
+ }
+ }
+
+ tag = append(tag, t)
+ q = append(q, float32(w))
+ }
+ sortStable(&tagSort{tag, q})
+ return tag, q, nil
+}
+
+// consume removes a leading token c from s and returns the result or the empty
+// string if there is no such token.
+func consume(s string, c byte) string {
+ if s == "" || s[0] != c {
+ return ""
+ }
+ return strings.TrimSpace(s[1:])
+}
+
+func split(s string, c byte) (head, tail string) {
+ if i := strings.IndexByte(s, c); i >= 0 {
+ return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+1:])
+ }
+ return strings.TrimSpace(s), ""
+}
+
+// Add hack mapping to deal with a small number of cases that that occur
+// in Accept-Language (with reasonable frequency).
+var acceptFallback = map[string]langID{
+ "english": _en,
+ "deutsch": _de,
+ "italian": _it,
+ "french": _fr,
+ "*": _mul, // defined in the spec to match all languages.
+}
+
+type tagSort struct {
+ tag []Tag
+ q []float32
+}
+
+func (s *tagSort) Len() int {
+ return len(s.q)
+}
+
+func (s *tagSort) Less(i, j int) bool {
+ return s.q[i] > s.q[j]
+}
+
+func (s *tagSort) Swap(i, j int) {
+ s.tag[i], s.tag[j] = s.tag[j], s.tag[i]
+ s.q[i], s.q[j] = s.q[j], s.q[i]
+}
diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go
new file mode 100644
index 000000000..1a92e582b
--- /dev/null
+++ b/vendor/golang.org/x/text/language/tables.go
@@ -0,0 +1,3547 @@
+// This file was generated by go generate; DO NOT EDIT
+
+package language
+
+import "golang.org/x/text/internal/tag"
+
+// CLDRVersion is the CLDR version from which the tables in this package are derived.
+const CLDRVersion = "30"
+
+const numLanguages = 8654
+
+const numScripts = 230
+
+const numRegions = 356
+
+type fromTo struct {
+ from uint16
+ to uint16
+}
+
+const nonCanonicalUnd = 1191
+const (
+ _af = 21
+ _am = 38
+ _ar = 57
+ _az = 87
+ _bg = 125
+ _bn = 163
+ _ca = 213
+ _cs = 246
+ _da = 253
+ _de = 265
+ _el = 305
+ _en = 308
+ _es = 313
+ _et = 315
+ _fa = 323
+ _fi = 332
+ _fil = 334
+ _fr = 345
+ _gu = 413
+ _he = 437
+ _hi = 439
+ _hr = 458
+ _hu = 462
+ _hy = 464
+ _id = 474
+ _is = 496
+ _it = 497
+ _ja = 504
+ _ka = 520
+ _kk = 570
+ _km = 578
+ _kn = 585
+ _ko = 587
+ _ky = 641
+ _lo = 687
+ _lt = 695
+ _lv = 702
+ _mk = 758
+ _ml = 763
+ _mn = 770
+ _mo = 775
+ _mr = 786
+ _ms = 790
+ _mul = 797
+ _my = 808
+ _nb = 830
+ _ne = 840
+ _nl = 862
+ _no = 870
+ _pa = 916
+ _pl = 938
+ _pt = 951
+ _ro = 979
+ _ru = 985
+ _sh = 1021
+ _si = 1026
+ _sk = 1032
+ _sl = 1036
+ _sq = 1063
+ _sr = 1064
+ _sv = 1082
+ _sw = 1083
+ _ta = 1094
+ _te = 1111
+ _th = 1121
+ _tl = 1136
+ _tn = 1142
+ _tr = 1152
+ _uk = 1188
+ _ur = 1194
+ _uz = 1202
+ _vi = 1209
+ _zh = 1311
+ _zu = 1316
+ _jbo = 507
+ _ami = 1639
+ _bnn = 2346
+ _hak = 431
+ _tlh = 14456
+ _lb = 652
+ _nv = 890
+ _pwn = 12044
+ _tao = 14177
+ _tay = 14187
+ _tsu = 14651
+ _nn = 865
+ _sfb = 13618
+ _vgt = 15690
+ _sgg = 13649
+ _cmn = 2996
+ _nan = 826
+ _hsn = 460
+)
+
+const langPrivateStart = 0x2f67
+
+const langPrivateEnd = 0x316e
+
+// lang holds an alphabetically sorted list of ISO-639 language identifiers.
+// All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag.
+// For 2-byte language identifiers, the two successive bytes have the following meaning:
+// - if the first letter of the 2- and 3-letter ISO codes are the same:
+// the second and third letter of the 3-letter ISO code.
+// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3.
+// For 3-byte language identifiers the 4th byte is 0.
+var lang tag.Index = "" + // Size: 5280 bytes
+ "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abr\x00abt\x00aby\x00acd\x00a" +
+ "ce\x00ach\x00ada\x00ade\x00adj\x00ady\x00adz\x00aeveaeb\x00aey\x00affrag" +
+ "c\x00agd\x00agg\x00agm\x00ago\x00agq\x00aha\x00ahl\x00aho\x00ajg\x00akka" +
+ "akk\x00ala\x00ali\x00aln\x00alt\x00ammhamm\x00amn\x00amo\x00amp\x00anrga" +
+ "nc\x00ank\x00ann\x00any\x00aoj\x00aom\x00aoz\x00apc\x00apd\x00ape\x00apr" +
+ "\x00aps\x00apz\x00arraarc\x00arh\x00arn\x00aro\x00arq\x00ars\x00ary\x00a" +
+ "rz\x00assmasa\x00ase\x00asg\x00aso\x00ast\x00ata\x00atg\x00atj\x00auy" +
+ "\x00avvaavl\x00avn\x00avt\x00avu\x00awa\x00awb\x00awo\x00awx\x00ayymayb" +
+ "\x00azzebaakbal\x00ban\x00bap\x00bar\x00bas\x00bav\x00bax\x00bba\x00bbb" +
+ "\x00bbc\x00bbd\x00bbj\x00bbp\x00bbr\x00bcf\x00bch\x00bci\x00bcm\x00bcn" +
+ "\x00bco\x00bcq\x00bcu\x00bdd\x00beelbef\x00beh\x00bej\x00bem\x00bet\x00b" +
+ "ew\x00bex\x00bez\x00bfd\x00bfq\x00bft\x00bfy\x00bgulbgc\x00bgn\x00bgx" +
+ "\x00bhihbhb\x00bhg\x00bhi\x00bhk\x00bhl\x00bho\x00bhy\x00biisbib\x00big" +
+ "\x00bik\x00bim\x00bin\x00bio\x00biq\x00bjh\x00bji\x00bjj\x00bjn\x00bjo" +
+ "\x00bjr\x00bjz\x00bkc\x00bkm\x00bkq\x00bku\x00bkv\x00blt\x00bmambmh\x00b" +
+ "mk\x00bmq\x00bmu\x00bnenbng\x00bnm\x00bnp\x00boodboj\x00bom\x00bon\x00bp" +
+ "y\x00bqc\x00bqi\x00bqp\x00bqv\x00brrebra\x00brh\x00brx\x00brz\x00bsosbsj" +
+ "\x00bsq\x00bss\x00bst\x00bto\x00btt\x00btv\x00bua\x00buc\x00bud\x00bug" +
+ "\x00buk\x00bum\x00buo\x00bus\x00buu\x00bvb\x00bwd\x00bwr\x00bxh\x00bye" +
+ "\x00byn\x00byr\x00bys\x00byv\x00byx\x00bza\x00bze\x00bzf\x00bzh\x00bzw" +
+ "\x00caatcan\x00cbj\x00cch\x00ccp\x00ceheceb\x00cfa\x00cgg\x00chhachk\x00" +
+ "chm\x00cho\x00chp\x00chr\x00cja\x00cjm\x00cjv\x00ckb\x00ckl\x00cko\x00ck" +
+ "y\x00cla\x00cme\x00cooscop\x00cps\x00crrecrj\x00crk\x00crl\x00crm\x00crs" +
+ "\x00csescsb\x00csw\x00ctd\x00cuhucvhvcyymdaandad\x00daf\x00dag\x00dah" +
+ "\x00dak\x00dar\x00dav\x00dbd\x00dbq\x00dcc\x00ddn\x00deeuded\x00den\x00d" +
+ "ga\x00dgh\x00dgi\x00dgl\x00dgr\x00dgz\x00dia\x00dje\x00dnj\x00dob\x00doi" +
+ "\x00dop\x00dow\x00dri\x00drs\x00dsb\x00dtm\x00dtp\x00dts\x00dty\x00dua" +
+ "\x00duc\x00dud\x00dug\x00dvivdva\x00dww\x00dyo\x00dyu\x00dzzodzg\x00ebu" +
+ "\x00eeweefi\x00egl\x00egy\x00eky\x00elllema\x00emi\x00enngenn\x00enq\x00" +
+ "eopoeri\x00es\x00\x05esu\x00etstetr\x00ett\x00etu\x00etx\x00euusewo\x00e" +
+ "xt\x00faasfaa\x00fab\x00fag\x00fai\x00fan\x00ffulffi\x00ffm\x00fiinfia" +
+ "\x00fil\x00fit\x00fjijflr\x00fmp\x00foaofod\x00fon\x00for\x00fpe\x00fqs" +
+ "\x00frrafrc\x00frp\x00frr\x00frs\x00fub\x00fud\x00fue\x00fuf\x00fuh\x00f" +
+ "uq\x00fur\x00fuv\x00fuy\x00fvr\x00fyrygalegaa\x00gaf\x00gag\x00gah\x00ga" +
+ "j\x00gam\x00gan\x00gaw\x00gay\x00gbf\x00gbm\x00gby\x00gbz\x00gcr\x00gdla" +
+ "gde\x00gdn\x00gdr\x00geb\x00gej\x00gel\x00gez\x00gfk\x00ggn\x00ghs\x00gi" +
+ "l\x00gim\x00gjk\x00gjn\x00gju\x00gkn\x00gkp\x00gllgglk\x00gmm\x00gmv\x00" +
+ "gnrngnd\x00gng\x00god\x00gof\x00goi\x00gom\x00gon\x00gor\x00gos\x00got" +
+ "\x00grc\x00grt\x00grw\x00gsw\x00guujgub\x00guc\x00gud\x00gur\x00guw\x00g" +
+ "ux\x00guz\x00gvlvgvf\x00gvr\x00gvs\x00gwc\x00gwi\x00gwt\x00gyi\x00haauha" +
+ "g\x00hak\x00ham\x00haw\x00haz\x00hbb\x00hdy\x00heebhhy\x00hiinhia\x00hif" +
+ "\x00hig\x00hih\x00hil\x00hla\x00hlu\x00hmd\x00hmt\x00hnd\x00hne\x00hnj" +
+ "\x00hnn\x00hno\x00homohoc\x00hoj\x00hot\x00hrrvhsb\x00hsn\x00htathuunhui" +
+ "\x00hyyehzerianaian\x00iar\x00iba\x00ibb\x00iby\x00ica\x00ich\x00idndidd" +
+ "\x00idi\x00idu\x00ieleigboigb\x00ige\x00iiiiijj\x00ikpkikk\x00ikt\x00ikw" +
+ "\x00ikx\x00ilo\x00imo\x00inndinh\x00iodoiou\x00iri\x00isslittaiukuiw\x00" +
+ "\x03iwm\x00iws\x00izh\x00izi\x00japnjab\x00jam\x00jbo\x00jbu\x00jen\x00j" +
+ "gk\x00jgo\x00ji\x00\x06jib\x00jmc\x00jml\x00jra\x00jut\x00jvavjwavkaatka" +
+ "a\x00kab\x00kac\x00kad\x00kai\x00kaj\x00kam\x00kao\x00kbd\x00kbm\x00kbp" +
+ "\x00kbq\x00kbx\x00kby\x00kcg\x00kck\x00kcl\x00kct\x00kde\x00kdh\x00kdl" +
+ "\x00kdt\x00kea\x00ken\x00kez\x00kfo\x00kfr\x00kfy\x00kgonkge\x00kgf\x00k" +
+ "gp\x00kha\x00khb\x00khn\x00khq\x00khs\x00kht\x00khw\x00khz\x00kiikkij" +
+ "\x00kiu\x00kiw\x00kjuakjd\x00kjg\x00kjs\x00kjy\x00kkazkkc\x00kkj\x00klal" +
+ "kln\x00klq\x00klt\x00klx\x00kmhmkmb\x00kmh\x00kmo\x00kms\x00kmu\x00kmw" +
+ "\x00knanknp\x00koorkoi\x00kok\x00kol\x00kos\x00koz\x00kpe\x00kpf\x00kpo" +
+ "\x00kpr\x00kpx\x00kqb\x00kqf\x00kqs\x00kqy\x00kraukrc\x00kri\x00krj\x00k" +
+ "rl\x00krs\x00kru\x00ksasksb\x00ksd\x00ksf\x00ksh\x00ksj\x00ksr\x00ktb" +
+ "\x00ktm\x00kto\x00kuurkub\x00kud\x00kue\x00kuj\x00kum\x00kun\x00kup\x00k" +
+ "us\x00kvomkvg\x00kvr\x00kvx\x00kw\x00\x01kwj\x00kwo\x00kxa\x00kxc\x00kxm" +
+ "\x00kxp\x00kxw\x00kxz\x00kyirkye\x00kyx\x00kzr\x00laatlab\x00lad\x00lag" +
+ "\x00lah\x00laj\x00las\x00lbtzlbe\x00lbu\x00lbw\x00lcm\x00lcp\x00ldb\x00l" +
+ "ed\x00lee\x00lem\x00lep\x00leq\x00leu\x00lez\x00lguglgg\x00liimlia\x00li" +
+ "d\x00lif\x00lig\x00lih\x00lij\x00lis\x00ljp\x00lki\x00lkt\x00lle\x00lln" +
+ "\x00lmn\x00lmo\x00lmp\x00lninlns\x00lnu\x00loaoloj\x00lok\x00lol\x00lor" +
+ "\x00los\x00loz\x00lrc\x00ltitltg\x00luublua\x00luo\x00luy\x00luz\x00lvav" +
+ "lwl\x00lzh\x00lzz\x00mad\x00maf\x00mag\x00mai\x00mak\x00man\x00mas\x00ma" +
+ "w\x00maz\x00mbh\x00mbo\x00mbq\x00mbu\x00mbw\x00mci\x00mcp\x00mcq\x00mcr" +
+ "\x00mcu\x00mda\x00mde\x00mdf\x00mdh\x00mdj\x00mdr\x00mdx\x00med\x00mee" +
+ "\x00mek\x00men\x00mer\x00met\x00meu\x00mfa\x00mfe\x00mfn\x00mfo\x00mfq" +
+ "\x00mglgmgh\x00mgl\x00mgo\x00mgp\x00mgy\x00mhahmhi\x00mhl\x00mirimif\x00" +
+ "min\x00mis\x00miw\x00mkkdmki\x00mkl\x00mkp\x00mkw\x00mlalmle\x00mlp\x00m" +
+ "ls\x00mmo\x00mmu\x00mmx\x00mnonmna\x00mnf\x00mni\x00mnw\x00moolmoa\x00mo" +
+ "e\x00moh\x00mos\x00mox\x00mpp\x00mps\x00mpt\x00mpx\x00mql\x00mrarmrd\x00" +
+ "mrj\x00mro\x00mssamtltmtc\x00mtf\x00mti\x00mtr\x00mua\x00mul\x00mur\x00m" +
+ "us\x00mva\x00mvn\x00mvy\x00mwk\x00mwr\x00mwv\x00mxc\x00mxm\x00myyamyk" +
+ "\x00mym\x00myv\x00myw\x00myx\x00myz\x00mzk\x00mzm\x00mzn\x00mzp\x00mzw" +
+ "\x00mzz\x00naaunac\x00naf\x00nah\x00nak\x00nan\x00nap\x00naq\x00nas\x00n" +
+ "bobnca\x00nce\x00ncf\x00nch\x00nco\x00ncu\x00nddendc\x00nds\x00neepneb" +
+ "\x00new\x00nex\x00nfr\x00ngdonga\x00ngb\x00ngl\x00nhb\x00nhe\x00nhw\x00n" +
+ "if\x00nii\x00nij\x00nin\x00niu\x00niy\x00niz\x00njo\x00nkg\x00nko\x00nll" +
+ "dnmg\x00nmz\x00nnnonnf\x00nnh\x00nnk\x00nnm\x00noornod\x00noe\x00non\x00" +
+ "nop\x00nou\x00nqo\x00nrblnrb\x00nsk\x00nsn\x00nso\x00nss\x00ntm\x00ntr" +
+ "\x00nui\x00nup\x00nus\x00nuv\x00nux\x00nvavnwb\x00nxq\x00nxr\x00nyyanym" +
+ "\x00nyn\x00nzi\x00occiogc\x00ojjiokr\x00okv\x00omrmong\x00onn\x00ons\x00" +
+ "opm\x00orrioro\x00oru\x00osssosa\x00ota\x00otk\x00ozm\x00paanpag\x00pal" +
+ "\x00pam\x00pap\x00pau\x00pbi\x00pcd\x00pcm\x00pdc\x00pdt\x00ped\x00peo" +
+ "\x00pex\x00pfl\x00phl\x00phn\x00pilipil\x00pip\x00pka\x00pko\x00plolpla" +
+ "\x00pms\x00png\x00pnn\x00pnt\x00pon\x00ppo\x00pra\x00prd\x00prg\x00psusp" +
+ "ss\x00ptorptp\x00puu\x00pwa\x00quuequc\x00qug\x00rai\x00raj\x00rao\x00rc" +
+ "f\x00rej\x00rel\x00res\x00rgn\x00rhg\x00ria\x00rif\x00rjs\x00rkt\x00rmoh" +
+ "rmf\x00rmo\x00rmt\x00rmu\x00rnunrna\x00rng\x00roonrob\x00rof\x00roo\x00r" +
+ "ro\x00rtm\x00ruusrue\x00rug\x00rw\x00\x04rwk\x00rwo\x00ryu\x00saansaf" +
+ "\x00sah\x00saq\x00sas\x00sat\x00saz\x00sba\x00sbe\x00sbp\x00scrdsck\x00s" +
+ "cl\x00scn\x00sco\x00scs\x00sdndsdc\x00sdh\x00semesef\x00seh\x00sei\x00se" +
+ "s\x00sgagsga\x00sgs\x00sgw\x00sgz\x00sh\x00\x02shi\x00shk\x00shn\x00shu" +
+ "\x00siinsid\x00sig\x00sil\x00sim\x00sjr\x00sklkskc\x00skr\x00sks\x00sllv" +
+ "sld\x00sli\x00sll\x00sly\x00smmosma\x00smi\x00smj\x00smn\x00smp\x00smq" +
+ "\x00sms\x00snnasnc\x00snk\x00snp\x00snx\x00sny\x00soomsok\x00soq\x00sou" +
+ "\x00soy\x00spd\x00spl\x00sps\x00sqqisrrpsrb\x00srn\x00srr\x00srx\x00sssw" +
+ "ssd\x00ssg\x00ssy\x00stotstk\x00stq\x00suunsua\x00sue\x00suk\x00sur\x00s" +
+ "us\x00svweswwaswb\x00swc\x00swg\x00swp\x00swv\x00sxn\x00sxw\x00syl\x00sy" +
+ "r\x00szl\x00taamtaj\x00tal\x00tan\x00taq\x00tbc\x00tbd\x00tbf\x00tbg\x00" +
+ "tbo\x00tbw\x00tbz\x00tci\x00tcy\x00tdd\x00tdg\x00tdh\x00teelted\x00tem" +
+ "\x00teo\x00tet\x00tfi\x00tggktgc\x00tgo\x00tgu\x00thhathl\x00thq\x00thr" +
+ "\x00tiirtif\x00tig\x00tik\x00tim\x00tio\x00tiv\x00tkuktkl\x00tkr\x00tkt" +
+ "\x00tlgltlf\x00tlx\x00tly\x00tmh\x00tmy\x00tnsntnh\x00toontof\x00tog\x00" +
+ "toq\x00tpi\x00tpm\x00tpz\x00tqo\x00trurtru\x00trv\x00trw\x00tssotsd\x00t" +
+ "sf\x00tsg\x00tsj\x00tsw\x00ttatttd\x00tte\x00ttj\x00ttr\x00tts\x00ttt" +
+ "\x00tuh\x00tul\x00tum\x00tuq\x00tvd\x00tvl\x00tvu\x00twwitwh\x00twq\x00t" +
+ "xg\x00tyahtya\x00tyv\x00tzm\x00ubu\x00udm\x00ugiguga\x00ukkruli\x00umb" +
+ "\x00und\x00unr\x00unx\x00urrduri\x00urt\x00urw\x00usa\x00utr\x00uvh\x00u" +
+ "vl\x00uzzbvag\x00vai\x00van\x00veenvec\x00vep\x00viievic\x00viv\x00vls" +
+ "\x00vmf\x00vmw\x00voolvot\x00vro\x00vun\x00vut\x00walnwae\x00waj\x00wal" +
+ "\x00wan\x00war\x00wbp\x00wbq\x00wbr\x00wci\x00wer\x00wgi\x00whg\x00wib" +
+ "\x00wiu\x00wiv\x00wja\x00wji\x00wls\x00wmo\x00wnc\x00wni\x00wnu\x00woolw" +
+ "ob\x00wos\x00wrs\x00wsk\x00wtm\x00wuu\x00wuv\x00wwa\x00xav\x00xbi\x00xcr" +
+ "\x00xes\x00xhhoxla\x00xlc\x00xld\x00xmf\x00xmn\x00xmr\x00xna\x00xnr\x00x" +
+ "og\x00xon\x00xpr\x00xrb\x00xsa\x00xsi\x00xsm\x00xsr\x00xwe\x00yam\x00yao" +
+ "\x00yap\x00yas\x00yat\x00yav\x00yay\x00yaz\x00yba\x00ybb\x00yby\x00yer" +
+ "\x00ygr\x00ygw\x00yiidyko\x00yle\x00ylg\x00yll\x00yml\x00yooryon\x00yrb" +
+ "\x00yre\x00yrl\x00yss\x00yua\x00yue\x00yuj\x00yut\x00yuw\x00zahazag\x00z" +
+ "bl\x00zdj\x00zea\x00zgh\x00zhhozia\x00zlm\x00zmi\x00zne\x00zuulzxx\x00zz" +
+ "a\x00\xff\xff\xff\xff"
+
+const langNoIndexOffset = 1319
+
+// langNoIndex is a bit vector of all 3-letter language codes that are not used as an index
+// in lookup tables. The language ids for these language codes are derived directly
+// from the letters and are not consecutive.
+// Size: 2197 bytes, 2197 elements
+var langNoIndex = [2197]uint8{
+ // Entry 0 - 3F
+ 0xff, 0xf8, 0xed, 0xfe, 0xeb, 0xd7, 0x3b, 0xd2,
+ 0xfb, 0xbf, 0x7a, 0xfa, 0x37, 0x1d, 0x3c, 0x57,
+ 0x6e, 0x97, 0x73, 0x38, 0xfb, 0xea, 0xbf, 0x70,
+ 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x62,
+ 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77,
+ 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2,
+ 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xb8, 0x0a, 0x6a,
+ 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff,
+ // Entry 40 - 7F
+ 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0,
+ 0x5d, 0xe3, 0x97, 0x14, 0x07, 0x20, 0xdd, 0xed,
+ 0x9f, 0x3f, 0xc9, 0x21, 0xf8, 0x3f, 0x94, 0x35,
+ 0x7c, 0x5f, 0xff, 0x5f, 0x8e, 0x6e, 0xdf, 0xff,
+ 0xff, 0xff, 0x55, 0x7c, 0xd3, 0xfd, 0xbf, 0xb5,
+ 0x7b, 0xdf, 0x7f, 0xf7, 0xca, 0xfe, 0xdb, 0xa3,
+ 0xa8, 0xff, 0x1f, 0x67, 0x7f, 0xeb, 0xef, 0xce,
+ 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf,
+ // Entry 80 - BF
+ 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x2f, 0xff, 0xff,
+ 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7,
+ 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba,
+ 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff,
+ 0xfd, 0xdf, 0xfb, 0xfe, 0x9d, 0xb4, 0xd3, 0xff,
+ 0xef, 0xff, 0xdf, 0xf7, 0x7f, 0xb7, 0xfd, 0xd5,
+ 0xa5, 0x77, 0x40, 0xff, 0x9c, 0xc1, 0x41, 0x2c,
+ 0x08, 0x20, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80,
+ // Entry C0 - FF
+ 0xfb, 0x4a, 0xf2, 0x9f, 0xb4, 0x42, 0x41, 0x96,
+ 0x1b, 0x14, 0x08, 0xf2, 0x2b, 0xe7, 0x17, 0x56,
+ 0x45, 0x7d, 0x0e, 0x1c, 0x37, 0x71, 0xf3, 0xef,
+ 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10,
+ 0xbc, 0x87, 0xaf, 0xdf, 0xff, 0xf7, 0x73, 0x35,
+ 0x3e, 0x87, 0xc7, 0xdf, 0xff, 0x00, 0x81, 0x00,
+ 0xb0, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d,
+ // Entry 100 - 13F
+ 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64,
+ 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00,
+ 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3,
+ 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x01, 0x0c,
+ 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc5, 0x67, 0x5f,
+ 0x56, 0x89, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56,
+ 0x90, 0x69, 0x01, 0x2c, 0x96, 0x69, 0x20, 0xfb,
+ // Entry 140 - 17F
+ 0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x08, 0x16,
+ 0x01, 0x00, 0x00, 0xb0, 0x14, 0x03, 0x50, 0x06,
+ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x09,
+ 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x04,
+ 0x08, 0x00, 0x00, 0x04, 0x00, 0x80, 0x28, 0x04,
+ 0x00, 0x00, 0x50, 0xd5, 0x2d, 0x00, 0x64, 0x35,
+ 0x24, 0x52, 0xf4, 0xd4, 0xbd, 0x62, 0xc9, 0x03,
+ // Entry 180 - 1BF
+ 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98,
+ 0x21, 0x18, 0x81, 0x00, 0x00, 0x01, 0x40, 0x82,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x40, 0x00, 0x44, 0x00, 0x00, 0x80, 0xea,
+ 0xa9, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ // Entry 1C0 - 1FF
+ 0x00, 0x01, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x20, 0x04, 0xa6, 0x00, 0x04, 0x00, 0x00,
+ 0x81, 0x50, 0x00, 0x00, 0x00, 0x11, 0x84, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x55,
+ 0x02, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x40,
+ 0x30, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0xcd, 0xbf, 0x7e, 0xbf,
+ // Entry 200 - 23F
+ 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27,
+ 0xcd, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5,
+ 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xcf, 0xe0, 0xdf,
+ 0x03, 0x44, 0x08, 0x10, 0x01, 0x04, 0x01, 0xe3,
+ 0x92, 0x54, 0xdb, 0x28, 0xd1, 0x5f, 0xf6, 0x6d,
+ 0x79, 0xed, 0x1c, 0x7d, 0x04, 0x08, 0x00, 0x01,
+ 0x21, 0x12, 0x6c, 0x5f, 0xdd, 0x0e, 0x85, 0x4f,
+ 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54,
+ // Entry 240 - 27F
+ 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00,
+ 0x20, 0x7b, 0x38, 0x02, 0x05, 0x84, 0x00, 0xf0,
+ 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00,
+ 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04,
+ 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00,
+ 0x11, 0x04, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff,
+ 0x7b, 0x7f, 0x60, 0x00, 0x05, 0x9b, 0xdd, 0x66,
+ // Entry 280 - 2BF
+ 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05,
+ 0xb5, 0xb6, 0x80, 0x08, 0x04, 0x00, 0x04, 0x51,
+ 0xe2, 0xef, 0xfd, 0x3f, 0x05, 0x09, 0x08, 0x05,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60,
+ 0xe5, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80,
+ 0x03, 0x00, 0x00, 0x00, 0xcc, 0x50, 0x40, 0x04,
+ 0x84, 0x47, 0x84, 0x40, 0x20, 0x10, 0x00, 0x20,
+ // Entry 2C0 - 2FF
+ 0x02, 0x50, 0x80, 0x11, 0x00, 0x91, 0x6c, 0xe2,
+ 0x50, 0x27, 0x1d, 0x11, 0x29, 0x06, 0x59, 0xe9,
+ 0x33, 0x08, 0x00, 0x20, 0x04, 0x40, 0x10, 0x00,
+ 0x00, 0x00, 0x50, 0x44, 0x92, 0x49, 0xd6, 0x5d,
+ 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00,
+ 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01,
+ 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x00, 0x08,
+ 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x89, 0x12, 0x00,
+ // Entry 300 - 33F
+ 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0,
+ 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80,
+ 0x00, 0x01, 0xd0, 0x12, 0x40, 0x00, 0x10, 0xb0,
+ 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00,
+ 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80,
+ 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0xf0, 0xd8, 0x6f, 0x15, 0x02, 0x08, 0x00,
+ // Entry 340 - 37F
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xe3,
+ 0xdd, 0xbf, 0xf9, 0xf9, 0x3b, 0x7f, 0x7f, 0xdb,
+ 0xfd, 0xfc, 0xfe, 0xdf, 0xff, 0xfd, 0xff, 0xf6,
+ 0xfb, 0xfc, 0xf7, 0x1f, 0xff, 0xb3, 0x6c, 0xff,
+ 0xd9, 0xad, 0xdf, 0xfe, 0xef, 0xba, 0xdf, 0xff,
+ 0xff, 0xff, 0xb7, 0xdd, 0x7d, 0xbf, 0xab, 0xff,
+ 0xfd, 0xfd, 0xdf, 0x2f, 0x9c, 0xdf, 0xf3, 0x6f,
+ // Entry 380 - 3BF
+ 0xdf, 0xdd, 0xff, 0xfb, 0xee, 0xd2, 0xab, 0x5f,
+ 0xd5, 0xdf, 0x7f, 0xff, 0xeb, 0xff, 0xe4, 0x4d,
+ 0xf9, 0xff, 0xfe, 0xf7, 0xfd, 0xdf, 0xfb, 0xbf,
+ 0xee, 0xdb, 0x6f, 0xef, 0xff, 0x7f, 0xff, 0xff,
+ 0xf7, 0x5f, 0xd3, 0x3b, 0xfd, 0xd9, 0xdf, 0xeb,
+ 0xbc, 0x08, 0x05, 0x24, 0xff, 0x07, 0x70, 0xfe,
+ 0xe6, 0x5e, 0x00, 0x08, 0x00, 0x83, 0x3d, 0x1b,
+ 0x06, 0xe6, 0x72, 0x60, 0xd1, 0x3c, 0x7f, 0x44,
+ // Entry 3C0 - 3FF
+ 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57,
+ 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7,
+ 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x00,
+ 0x40, 0x54, 0x9f, 0x8a, 0xd9, 0xd9, 0x0e, 0x11,
+ 0x84, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x00, 0x01,
+ 0x05, 0xd1, 0x50, 0x58, 0x00, 0x00, 0x00, 0x10,
+ 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2,
+ 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe,
+ // Entry 400 - 43F
+ 0x53, 0x6f, 0xdf, 0xe7, 0xdb, 0x65, 0xbb, 0x7f,
+ 0xfa, 0xff, 0x77, 0xf3, 0xef, 0xbf, 0xfd, 0xf7,
+ 0xdf, 0xdf, 0x9b, 0x7f, 0xff, 0xff, 0x7f, 0x6f,
+ 0xf7, 0xfb, 0xeb, 0xdf, 0xbc, 0xff, 0xbf, 0x6b,
+ 0x7b, 0xfb, 0xff, 0xce, 0x76, 0xbd, 0xf7, 0xf7,
+ 0xdf, 0xdc, 0xf7, 0xf7, 0xff, 0xdf, 0xf3, 0xfe,
+ 0xef, 0xff, 0xff, 0xff, 0xb6, 0x7f, 0x7f, 0xde,
+ 0xf7, 0xb9, 0xeb, 0x77, 0xff, 0xfb, 0xbf, 0xdf,
+ // Entry 440 - 47F
+ 0xfd, 0xfe, 0xfb, 0xff, 0xfe, 0xeb, 0x1f, 0x7d,
+ 0x2f, 0xfd, 0xb6, 0xb5, 0xa5, 0xfc, 0xff, 0xfd,
+ 0x7f, 0x4e, 0xbf, 0x8e, 0xae, 0xff, 0xee, 0xdf,
+ 0x7f, 0xf7, 0x73, 0x02, 0x02, 0x04, 0xfc, 0xf7,
+ 0xff, 0xb7, 0xd7, 0xef, 0xfe, 0xcd, 0xf5, 0xce,
+ 0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xbd,
+ 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff,
+ 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x04, 0x44,
+ // Entry 480 - 4BF
+ 0x13, 0x50, 0x5d, 0xaf, 0xa6, 0xfd, 0x99, 0xfb,
+ 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20,
+ 0x14, 0x00, 0x55, 0x51, 0x82, 0x65, 0xf5, 0x41,
+ 0xe2, 0xff, 0xfc, 0xdf, 0x00, 0x05, 0xc5, 0x05,
+ 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x04,
+ 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00,
+ 0x06, 0x01, 0x20, 0x00, 0x18, 0x01, 0x92, 0xb1,
+ // Entry 4C0 - 4FF
+ 0xfd, 0x47, 0x49, 0x06, 0x95, 0x06, 0x57, 0xed,
+ 0xfb, 0x4c, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40,
+ 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83,
+ 0xb8, 0x4f, 0x10, 0x8c, 0x89, 0x46, 0xde, 0xf7,
+ 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00,
+ 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d,
+ 0xba, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41,
+ // Entry 500 - 53F
+ 0x30, 0xff, 0x79, 0x72, 0x04, 0x00, 0x00, 0x49,
+ 0x2d, 0x14, 0x27, 0x57, 0xed, 0xf1, 0x3f, 0xe7,
+ 0x3f, 0x00, 0x00, 0x02, 0xc6, 0xa0, 0x1e, 0xf8,
+ 0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe5, 0xf7,
+ 0xfd, 0xfc, 0xd5, 0xed, 0x47, 0xf4, 0x7e, 0x10,
+ 0x01, 0x01, 0x84, 0x6d, 0xff, 0xf7, 0xdd, 0xf9,
+ 0x5b, 0x05, 0x86, 0xed, 0xf5, 0x77, 0xbd, 0x3c,
+ 0x00, 0x00, 0x00, 0x42, 0x71, 0x42, 0x00, 0x40,
+ // Entry 540 - 57F
+ 0x00, 0x00, 0x01, 0x43, 0x19, 0x00, 0x08, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ // Entry 580 - 5BF
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xab, 0xbd, 0xe7, 0x57, 0xee, 0x13, 0x5d,
+ 0x09, 0xc1, 0x40, 0x21, 0xfa, 0x17, 0x01, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xce, 0xfb, 0xbf,
+ 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x30, 0x15, 0xa3, 0x10, 0x00, 0x00, 0x00,
+ 0x11, 0x04, 0x16, 0x00, 0x00, 0x02, 0x00, 0x81,
+ 0xa3, 0x01, 0x50, 0x00, 0x00, 0x83, 0x11, 0x40,
+ // Entry 5C0 - 5FF
+ 0x00, 0x00, 0x00, 0xf0, 0xdd, 0x7b, 0x3e, 0x02,
+ 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02,
+ 0x19, 0x00, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d,
+ 0x31, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x20,
+ 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00,
+ 0x00, 0x1f, 0xdf, 0xf2, 0xb9, 0xff, 0xfd, 0x3f,
+ 0x1f, 0x18, 0xcf, 0x9c, 0xbf, 0xaf, 0x5f, 0xfe,
+ // Entry 600 - 63F
+ 0x7b, 0x4b, 0x40, 0x10, 0xe1, 0xfd, 0xaf, 0xd9,
+ 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1,
+ 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7,
+ 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd,
+ 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x1f,
+ 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe,
+ 0xbe, 0x5f, 0x46, 0x1b, 0xe9, 0x5f, 0x50, 0x18,
+ 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f,
+ // Entry 640 - 67F
+ 0x75, 0xc4, 0x7d, 0x81, 0x82, 0xf1, 0x57, 0x6c,
+ 0xff, 0xe4, 0xef, 0x6f, 0xff, 0xfc, 0xdd, 0xde,
+ 0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x1f, 0x00, 0x98,
+ 0x02, 0xfb, 0xa3, 0xef, 0xf3, 0xd6, 0xf2, 0xff,
+ 0xb9, 0xda, 0x7d, 0x50, 0x1e, 0x15, 0x7b, 0xb4,
+ 0xf5, 0x3e, 0xff, 0xff, 0xf1, 0xf7, 0xff, 0xe7,
+ 0x5f, 0xff, 0xff, 0x9e, 0xdb, 0xf6, 0xd7, 0xb9,
+ 0xef, 0x27, 0x80, 0xbb, 0xc5, 0xff, 0xff, 0xe3,
+ // Entry 680 - 6BF
+ 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37,
+ 0xce, 0x7f, 0x04, 0x1d, 0x53, 0x7f, 0xf8, 0xda,
+ 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x69, 0xa0,
+ 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08,
+ 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00,
+ 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x01, 0x06,
+ 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00,
+ 0x04, 0x00, 0x10, 0x8c, 0x58, 0xd5, 0x0d, 0x0f,
+ // Entry 6C0 - 6FF
+ 0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd1, 0x42, 0x08,
+ 0x40, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x08, 0x41,
+ 0x04, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x80, 0x10, 0x10, 0xab,
+ 0x6d, 0x93, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x25, 0x00, 0x00,
+ // Entry 700 - 73F
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x80, 0x86, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xdf, 0x18, 0x00, 0x00, 0x02, 0xf0, 0xfd, 0x79,
+ 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 740 - 77F
+ 0x00, 0x00, 0x00, 0xef, 0xd5, 0xfd, 0xcf, 0x7e,
+ 0xa0, 0x11, 0x00, 0x00, 0x00, 0x92, 0x01, 0x44,
+ 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04,
+ 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a,
+ 0x01, 0x00, 0x00, 0xb0, 0x80, 0x00, 0x55, 0x55,
+ 0x97, 0x7c, 0x9f, 0x31, 0xcc, 0x68, 0xd1, 0x03,
+ 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60,
+ // Entry 780 - 7BF
+ 0x03, 0x68, 0x01, 0x10, 0x8b, 0x38, 0x8a, 0x01,
+ 0x00, 0x00, 0x20, 0x00, 0x24, 0x44, 0x00, 0x00,
+ 0x10, 0x03, 0x11, 0x02, 0x01, 0x00, 0x00, 0xf0,
+ 0xf5, 0xff, 0xd5, 0x97, 0xbc, 0x70, 0xd6, 0x78,
+ 0x78, 0x15, 0x50, 0x00, 0xa4, 0x84, 0xa9, 0x41,
+ 0x00, 0x00, 0x00, 0x6b, 0x39, 0x52, 0x74, 0x00,
+ 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02,
+ 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed,
+ // Entry 7C0 - 7FF
+ 0xdd, 0xbf, 0x72, 0x19, 0xc7, 0x0c, 0xd5, 0x42,
+ 0x54, 0xdd, 0x77, 0x14, 0x00, 0x80, 0x40, 0x56,
+ 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff,
+ 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d,
+ 0x4e, 0x4a, 0x08, 0x50, 0x28, 0x30, 0xe0, 0x80,
+ 0x10, 0x20, 0x24, 0x00, 0xff, 0x2f, 0xd3, 0x60,
+ 0xfe, 0x01, 0x02, 0x88, 0x0a, 0x40, 0x16, 0x01,
+ 0x01, 0x15, 0x2b, 0x3c, 0x01, 0x00, 0x00, 0x10,
+ // Entry 800 - 83F
+ 0x90, 0x49, 0x41, 0x02, 0x02, 0x01, 0xe1, 0xbf,
+ 0xbf, 0x03, 0x00, 0x00, 0x10, 0xd4, 0xa3, 0xd1,
+ 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3,
+ 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80,
+ 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84,
+ 0x2e, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93,
+ 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10,
+ 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00,
+ // Entry 840 - 87F
+ 0xf0, 0xfb, 0xfd, 0x3f, 0x05, 0x00, 0x12, 0x81,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28,
+ 0x84, 0x00, 0x23, 0xc0, 0x23, 0x24, 0x00, 0x00,
+ 0x00, 0xcb, 0xe4, 0x3a, 0x42, 0x88, 0x14, 0xf1,
+ 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50,
+ 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40,
+ 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1,
+ // Entry 880 - 8BF
+ 0x76, 0x16, 0x08, 0x03, 0x10, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x24,
+ 0x0a, 0x00, 0x80, 0x00, 0x00,
+}
+
+// altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives
+// to 2-letter language codes that cannot be derived using the method described above.
+// Each 3-letter code is followed by its 1-byte langID.
+var altLangISO3 tag.Index = "---\x00cor\x00hbs\x01heb\x02kin\x03spa\x04yid\x05\xff\xff\xff\xff"
+
+// altLangIndex is used to convert indexes in altLangISO3 to langIDs.
+// Size: 12 bytes, 6 elements
+var altLangIndex = [6]uint16{
+ 0x0278, 0x03fd, 0x01f3, 0x03dc, 0x0139, 0x0200,
+}
+
+// langAliasMap maps langIDs to their suggested replacements.
+// Size: 644 bytes, 161 elements
+var langAliasMap = [161]fromTo{
+ 0: {from: 0x81, to: 0x87},
+ 1: {from: 0x181, to: 0x1a7},
+ 2: {from: 0x1eb, to: 0x1da},
+ 3: {from: 0x1f3, to: 0x1b5},
+ 4: {from: 0x200, to: 0x508},
+ 5: {from: 0x207, to: 0x206},
+ 6: {from: 0x307, to: 0x3d3},
+ 7: {from: 0x33e, to: 0x366},
+ 8: {from: 0x3fd, to: 0x428},
+ 9: {from: 0x470, to: 0x14e},
+ 10: {from: 0x486, to: 0x447},
+ 11: {from: 0x498, to: 0x20},
+ 12: {from: 0x533, to: 0x539},
+ 13: {from: 0x584, to: 0x129},
+ 14: {from: 0x625, to: 0x1ea6},
+ 15: {from: 0x646, to: 0x427},
+ 16: {from: 0x657, to: 0x427},
+ 17: {from: 0x6e2, to: 0x39},
+ 18: {from: 0x6ed, to: 0x1d0},
+ 19: {from: 0x733, to: 0x2196},
+ 20: {from: 0x7a8, to: 0x55},
+ 21: {from: 0x7ae, to: 0x2990},
+ 22: {from: 0x7ba, to: 0x57},
+ 23: {from: 0x7db, to: 0x140},
+ 24: {from: 0x801, to: 0x59},
+ 25: {from: 0x80a, to: 0x8c},
+ 26: {from: 0x873, to: 0x805},
+ 27: {from: 0x8b8, to: 0xed8},
+ 28: {from: 0x9e4, to: 0x328},
+ 29: {from: 0xa2b, to: 0x2bc},
+ 30: {from: 0xa32, to: 0xbd},
+ 31: {from: 0xab3, to: 0x3317},
+ 32: {from: 0xb2d, to: 0x51f},
+ 33: {from: 0xb6a, to: 0x264f},
+ 34: {from: 0xb73, to: 0xbb8},
+ 35: {from: 0xb90, to: 0x444},
+ 36: {from: 0xbb1, to: 0x421e},
+ 37: {from: 0xbb4, to: 0x51f},
+ 38: {from: 0xbf3, to: 0x2d9c},
+ 39: {from: 0xc23, to: 0x3176},
+ 40: {from: 0xcae, to: 0xf0},
+ 41: {from: 0xcfd, to: 0xf6},
+ 42: {from: 0xdbd, to: 0x116},
+ 43: {from: 0xdcc, to: 0x324},
+ 44: {from: 0xded, to: 0xdf0},
+ 45: {from: 0xdf3, to: 0x526},
+ 46: {from: 0xed4, to: 0x204f},
+ 47: {from: 0xee3, to: 0x2e8f},
+ 48: {from: 0xf2e, to: 0x35e},
+ 49: {from: 0x10c5, to: 0x13b},
+ 50: {from: 0x10f9, to: 0x2c7},
+ 51: {from: 0x1195, to: 0x1e4},
+ 52: {from: 0x126e, to: 0x20},
+ 53: {from: 0x1419, to: 0x159},
+ 54: {from: 0x1465, to: 0x149},
+ 55: {from: 0x1514, to: 0xd90},
+ 56: {from: 0x1518, to: 0x387},
+ 57: {from: 0x1527, to: 0x16ba},
+ 58: {from: 0x1575, to: 0x208},
+ 59: {from: 0x1578, to: 0x109},
+ 60: {from: 0x1598, to: 0x3ca4},
+ 61: {from: 0x165f, to: 0x195},
+ 62: {from: 0x16bd, to: 0x131},
+ 63: {from: 0x16f5, to: 0x29ed},
+ 64: {from: 0x170d, to: 0x18e},
+ 65: {from: 0x171c, to: 0xf34},
+ 66: {from: 0x176f, to: 0x1519},
+ 67: {from: 0x17fe, to: 0x17ab},
+ 68: {from: 0x180b, to: 0x18e8},
+ 69: {from: 0x187f, to: 0x42c},
+ 70: {from: 0x196e, to: 0x1cf6},
+ 71: {from: 0x1a69, to: 0x2ba5},
+ 72: {from: 0x1a7f, to: 0x1f0},
+ 73: {from: 0x1b4f, to: 0x1f2},
+ 74: {from: 0x1b7b, to: 0x150a},
+ 75: {from: 0x202d, to: 0x37a6},
+ 76: {from: 0x2032, to: 0x20d2},
+ 77: {from: 0x204f, to: 0x302},
+ 78: {from: 0x20d8, to: 0x26b},
+ 79: {from: 0x20e3, to: 0x25a},
+ 80: {from: 0x20e7, to: 0x225},
+ 81: {from: 0x20ee, to: 0x24d},
+ 82: {from: 0x2104, to: 0x21e0},
+ 83: {from: 0x212a, to: 0x274},
+ 84: {from: 0x218e, to: 0x11d},
+ 85: {from: 0x21c3, to: 0x1556},
+ 86: {from: 0x21db, to: 0x4fa},
+ 87: {from: 0x21e9, to: 0x495},
+ 88: {from: 0x2222, to: 0x11d},
+ 89: {from: 0x222c, to: 0x11d},
+ 90: {from: 0x2257, to: 0x91f},
+ 91: {from: 0x230b, to: 0x321b},
+ 92: {from: 0x2377, to: 0x335a},
+ 93: {from: 0x2467, to: 0x2be},
+ 94: {from: 0x24d9, to: 0x2f6},
+ 95: {from: 0x24e5, to: 0x2f1},
+ 96: {from: 0x24ef, to: 0x316},
+ 97: {from: 0x2545, to: 0xb50},
+ 98: {from: 0x259e, to: 0xe0},
+ 99: {from: 0x2633, to: 0x2c7},
+ 100: {from: 0x26be, to: 0x26a9},
+ 101: {from: 0x26ee, to: 0x3bf},
+ 102: {from: 0x271c, to: 0x3ca4},
+ 103: {from: 0x275a, to: 0x26a9},
+ 104: {from: 0x277e, to: 0x434d},
+ 105: {from: 0x28e4, to: 0x282c},
+ 106: {from: 0x2909, to: 0x348},
+ 107: {from: 0x297b, to: 0x2d9c},
+ 108: {from: 0x2b0f, to: 0x384},
+ 109: {from: 0x2bf1, to: 0x38c},
+ 110: {from: 0x2c34, to: 0x3ca4},
+ 111: {from: 0x2cf1, to: 0x3b5},
+ 112: {from: 0x2d08, to: 0x58c},
+ 113: {from: 0x2d3c, to: 0x143},
+ 114: {from: 0x2d3d, to: 0x143},
+ 115: {from: 0x2df4, to: 0x2e8},
+ 116: {from: 0x2dfd, to: 0x19c1},
+ 117: {from: 0x2e0f, to: 0x2d8a},
+ 118: {from: 0x2e16, to: 0x289},
+ 119: {from: 0x2e49, to: 0x7c},
+ 120: {from: 0x2e5a, to: 0x2277},
+ 121: {from: 0x2e95, to: 0x2e90},
+ 122: {from: 0x2ee4, to: 0x2ecc},
+ 123: {from: 0x3188, to: 0x3bb},
+ 124: {from: 0x335b, to: 0x3383},
+ 125: {from: 0x341f, to: 0x3d3},
+ 126: {from: 0x34e3, to: 0x18c5},
+ 127: {from: 0x35db, to: 0x408},
+ 128: {from: 0x364d, to: 0x23e},
+ 129: {from: 0x366b, to: 0x3ea},
+ 130: {from: 0x36f2, to: 0x43b},
+ 131: {from: 0x37b5, to: 0x11d},
+ 132: {from: 0x380b, to: 0x38e7},
+ 133: {from: 0x3820, to: 0x2c90},
+ 134: {from: 0x3824, to: 0xa7},
+ 135: {from: 0x3827, to: 0x321d},
+ 136: {from: 0x3861, to: 0x399b},
+ 137: {from: 0x3887, to: 0x3fb5},
+ 138: {from: 0x389a, to: 0x39cc},
+ 139: {from: 0x38a9, to: 0x1f99},
+ 140: {from: 0x38aa, to: 0x2e8f},
+ 141: {from: 0x3951, to: 0x474},
+ 142: {from: 0x3b43, to: 0xd86},
+ 143: {from: 0x3b6d, to: 0x132},
+ 144: {from: 0x3c8e, to: 0x4b2},
+ 145: {from: 0x3fb2, to: 0xfc},
+ 146: {from: 0x41fd, to: 0xa86},
+ 147: {from: 0x42b3, to: 0x568},
+ 148: {from: 0x42ee, to: 0x3f55},
+ 149: {from: 0x436d, to: 0x251},
+ 150: {from: 0x43c0, to: 0x36c0},
+ 151: {from: 0x43c2, to: 0x10b},
+ 152: {from: 0x44a4, to: 0x3317},
+ 153: {from: 0x44d8, to: 0x508},
+ 154: {from: 0x45bf, to: 0x23fe},
+ 155: {from: 0x45d2, to: 0x26d1},
+ 156: {from: 0x4605, to: 0x48a3},
+ 157: {from: 0x46a3, to: 0x4695},
+ 158: {from: 0x4733, to: 0x473a},
+ 159: {from: 0x490b, to: 0x316},
+ 160: {from: 0x499c, to: 0x519},
+}
+
+// Size: 161 bytes, 161 elements
+var langAliasTypes = [161]langAliasType{
+ // Entry 0 - 3F
+ 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 1, 2,
+ 1, 1, 2, 0, 1, 0, 1, 2, 1, 1, 0, 0, 2, 1, 1, 0,
+ 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0,
+ 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0, 1, 2, 0,
+ // Entry 40 - 7F
+ 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,
+ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 2,
+ 2, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1,
+ 0, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 2,
+ // Entry 80 - BF
+ 1, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ 1, 2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1,
+ 1,
+}
+
+const (
+ _Latn = 82
+ _Hani = 50
+ _Hans = 52
+ _Hant = 53
+ _Qaaa = 131
+ _Qaai = 139
+ _Qabx = 180
+ _Zinh = 224
+ _Zyyy = 229
+ _Zzzz = 230
+)
+
+// script is an alphabetically sorted list of ISO 15924 codes. The index
+// of the script in the string, divided by 4, is the internal scriptID.
+var script tag.Index = "" + // Size: 928 bytes
+ "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" +
+ "BrahBraiBugiBuhdCakmCansCariChamCherCirtCoptCprtCyrlCyrsDevaDsrtDuplEgyd" +
+ "EgyhEgypElbaEthiGeokGeorGlagGothGranGrekGujrGuruHanbHangHaniHanoHansHant" +
+ "HatrHebrHiraHluwHmngHrktHungIndsItalJamoJavaJpanJurcKaliKanaKharKhmrKhoj" +
+ "KitlKitsKndaKoreKpelKthiLanaLaooLatfLatgLatnLekeLepcLimbLinaLinbLisuLoma" +
+ "LyciLydiMahjMandManiMarcMayaMendMercMeroMlymModiMongMoonMrooMteiMultMymr" +
+ "NarbNbatNewaNkgbNkooNshuOgamOlckOrkhOryaOsgeOsmaPalmPaucPermPhagPhliPhlp" +
+ "PhlvPhnxPiqdPlrdPrtiQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaam" +
+ "QaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabe" +
+ "QabfQabgQabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabw" +
+ "QabxRjngRoroRunrSamrSaraSarbSaurSgnwShawShrdSiddSindSinhSoraSundSyloSyrc" +
+ "SyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglgThaaThaiTibtTirh" +
+ "UgarVaiiVispWaraWoleXpeoXsuxYiiiZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff" +
+ "\xff"
+
+// suppressScript is an index from langID to the dominant script for that language,
+// if it exists. If a script is given, it should be suppressed from the language tag.
+// Size: 1319 bytes, 1319 elements
+var suppressScript = [1319]uint8{
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 40 - 7F
+ 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 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,
+ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
+ // Entry 80 - BF
+ 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, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry C0 - FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x52, 0x00, 0x00,
+ // Entry 100 - 13F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x2d, 0x00, 0x00, 0x52, 0x00, 0x00, 0x52,
+ 0x00, 0x52, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ // Entry 140 - 17F
+ 0x52, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x52, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 180 - 1BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x2e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 1C0 - 1FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x52, 0x00, 0x52, 0x52, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x52, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 200 - 23F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x29, 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, 0x1e, 0x00, 0x00, 0x52, 0x00, 0x00,
+ // Entry 240 - 27F
+ 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x20, 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, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 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, 0x52, 0x00, 0x00, 0x4f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ // Entry 2C0 - 2FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 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, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00,
+ // Entry 300 - 33F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x52, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ // Entry 340 - 37F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x52, 0x00, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ // Entry 380 - 3BF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ // Entry 3C0 - 3FF
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1e, 0x00, 0x00, 0x52, 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,
+ 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 400 - 43F
+ 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x52, 0x00, 0x00, 0x00, 0x00,
+ // Entry 440 - 47F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd5, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+ 0x52, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52, 0x00,
+ 0x52, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
+ // Entry 480 - 4BF
+ 0x52, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
+ 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 4C0 - 4FF
+ 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,
+ 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Entry 500 - 53F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00,
+}
+
+const (
+ _001 = 1
+ _419 = 30
+ _BR = 64
+ _CA = 72
+ _ES = 109
+ _GB = 122
+ _MD = 187
+ _PT = 237
+ _UK = 305
+ _US = 308
+ _ZZ = 356
+ _XA = 322
+ _XC = 324
+ _XK = 332
+)
+
+// isoRegionOffset needs to be added to the index of regionISO to obtain the regionID
+// for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for
+// the UN.M49 codes used for groups.)
+const isoRegionOffset = 31
+
+// regionTypes defines the status of a region for various standards.
+// Size: 357 bytes, 357 elements
+var regionTypes = [357]uint8{
+ // Entry 0 - 3F
+ 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, 0x05,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry 40 - 7F
+ 0x06, 0x06, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x04, 0x00,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06,
+ 0x04, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x04,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06,
+ 0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry 80 - BF
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x04, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry C0 - FF
+ 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06,
+ 0x06, 0x06, 0x06, 0x00, 0x06, 0x04, 0x06, 0x06,
+ 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06,
+ 0x06, 0x00, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ // Entry 100 - 13F
+ 0x05, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x02, 0x06, 0x04, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ // Entry 140 - 17F
+ 0x00, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, 0x06, 0x04,
+ 0x06, 0x06, 0x04, 0x06, 0x05,
+}
+
+// regionISO holds a list of alphabetically sorted 2-letter ISO region codes.
+// Each 2-letter codes is followed by two bytes with the following meaning:
+// - [A-Z}{2}: the first letter of the 2-letter code plus these two
+// letters form the 3-letter ISO code.
+// - 0, n: index into altRegionISO3.
+var regionISO tag.Index = "" + // Size: 1308 bytes
+ "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" +
+ "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" +
+ "BUURBVVTBWWABYLRBZLZCAANCCCKCDODCFAFCGOGCHHECIIVCKOKCLHLCMMRCNHNCOOLCPPT" +
+ "CRRICS\x00\x00CTTECUUBCVPVCWUWCXXRCYYPCZZEDDDRDEEUDGGADJJIDKNKDMMADOOMDY" +
+ "HYDZZAEA ECCUEESTEGGYEHSHERRIESSPETTHEU\x00\x03EZ FIINFJJIFKLKFMSMFORO" +
+ "FQ\x00\x18FRRAFXXXGAABGBBRGDRDGEEOGFUFGGGYGHHAGIIBGLRLGMMBGNINGPLPGQNQGR" +
+ "RCGS\x00\x06GTTMGUUMGWNBGYUYHKKGHMMDHNNDHRRVHTTIHUUNHVVOIC IDDNIERLILSR" +
+ "IMMNINNDIOOTIQRQIRRNISSLITTAJEEYJMAMJOORJPPNJTTNKEENKGGZKHHMKIIRKM\x00" +
+ "\x09KNNAKP\x00\x0cKRORKWWTKY\x00\x0fKZAZLAAOLBBNLCCALIIELKKALRBRLSSOLTTU" +
+ "LUUXLVVALYBYMAARMCCOMDDAMENEMFAFMGDGMHHLMIIDMKKDMLLIMMMRMNNGMOACMPNPMQTQ" +
+ "MRRTMSSRMTLTMUUSMVDVMWWIMXEXMYYSMZOZNAAMNCCLNEERNFFKNGGANHHBNIICNLLDNOOR" +
+ "NPPLNQ\x00\x1eNRRUNTTZNUIUNZZLOMMNPAANPCCIPEERPFYFPGNGPHHLPKAKPLOLPM\x00" +
+ "\x12PNCNPRRIPSSEPTRTPUUSPWLWPYRYPZCZQAATQMMMQNNNQOOOQPPPQQQQQRRRQSSSQTTT" +
+ "QU\x00\x03QVVVQWWWQXXXQYYYQZZZREEURHHOROOURS\x00\x15RUUSRWWASAAUSBLBSCYC" +
+ "SDDNSEWESGGPSHHNSIVNSJJMSKVKSLLESMMRSNENSOOMSRURSSSDSTTPSUUNSVLVSXXMSYYR" +
+ "SZWZTAAATCCATDCDTF\x00\x18TGGOTHHATJJKTKKLTLLSTMKMTNUNTOONTPMPTRURTTTOTV" +
+ "UVTWWNTZZAUAKRUGGAUK UMMIUN USSAUYRYUZZBVAATVCCTVDDRVEENVGGBVIIRVNNMVU" +
+ "UTWFLFWKAKWSSMXAAAXBBBXCCCXDDDXEEEXFFFXGGGXHHHXIIIXJJJXKKKXLLLXMMMXNNNXO" +
+ "OOXPPPXQQQXRRRXSSSXTTTXUUUXVVVXWWWXXXXXYYYXZZZYDMDYEEMYT\x00\x1bYUUGZAAF" +
+ "ZMMBZRARZWWEZZZZ\xff\xff\xff\xff"
+
+// altRegionISO3 holds a list of 3-letter region codes that cannot be
+// mapped to 2-letter codes using the default algorithm. This is a short list.
+var altRegionISO3 string = "SCGQUUSGSCOMPRKCYMSPMSRBATFMYTATN"
+
+// altRegionIDs holds a list of regionIDs the positions of which match those
+// of the 3-letter ISO codes in altRegionISO3.
+// Size: 22 bytes, 11 elements
+var altRegionIDs = [11]uint16{
+ 0x0056, 0x006f, 0x0087, 0x00a7, 0x00a9, 0x00ac, 0x00e9, 0x0104,
+ 0x0120, 0x015e, 0x00db,
+}
+
+// Size: 80 bytes, 20 elements
+var regionOldMap = [20]fromTo{
+ 0: {from: 0x43, to: 0xc3},
+ 1: {from: 0x57, to: 0xa6},
+ 2: {from: 0x5e, to: 0x5f},
+ 3: {from: 0x65, to: 0x3a},
+ 4: {from: 0x78, to: 0x77},
+ 5: {from: 0x92, to: 0x36},
+ 6: {from: 0xa2, to: 0x132},
+ 7: {from: 0xc0, to: 0x132},
+ 8: {from: 0xd6, to: 0x13e},
+ 9: {from: 0xdb, to: 0x2a},
+ 10: {from: 0xee, to: 0x132},
+ 11: {from: 0xf1, to: 0xe1},
+ 12: {from: 0xfb, to: 0x6f},
+ 13: {from: 0x102, to: 0x163},
+ 14: {from: 0x129, to: 0x125},
+ 15: {from: 0x131, to: 0x7a},
+ 16: {from: 0x139, to: 0x13d},
+ 17: {from: 0x140, to: 0x132},
+ 18: {from: 0x15c, to: 0x15d},
+ 19: {from: 0x162, to: 0x4a},
+}
+
+// m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are
+// codes indicating collections of regions.
+// Size: 714 bytes, 357 elements
+var m49 = [357]int16{
+ // Entry 0 - 3F
+ 0, 1, 2, 3, 5, 9, 11, 13,
+ 14, 15, 17, 18, 19, 21, 29, 30,
+ 34, 35, 39, 53, 54, 57, 61, 142,
+ 143, 145, 150, 151, 154, 155, 419, 958,
+ 0, 20, 784, 4, 28, 660, 8, 51,
+ 530, 24, 10, 32, 16, 40, 36, 533,
+ 248, 31, 70, 52, 50, 56, 854, 100,
+ 48, 108, 204, 652, 60, 96, 68, 535,
+ // Entry 40 - 7F
+ 76, 44, 64, 104, 74, 72, 112, 84,
+ 124, 166, 180, 140, 178, 756, 384, 184,
+ 152, 120, 156, 170, 0, 188, 891, 296,
+ 192, 132, 531, 162, 196, 203, 278, 276,
+ 0, 262, 208, 212, 214, 204, 12, 0,
+ 218, 233, 818, 732, 232, 724, 231, 967,
+ 0, 246, 242, 238, 583, 234, 0, 250,
+ 249, 266, 826, 308, 268, 254, 831, 288,
+ // Entry 80 - BF
+ 292, 304, 270, 324, 312, 226, 300, 239,
+ 320, 316, 624, 328, 344, 334, 340, 191,
+ 332, 348, 854, 0, 360, 372, 376, 833,
+ 356, 86, 368, 364, 352, 380, 832, 388,
+ 400, 392, 581, 404, 417, 116, 296, 174,
+ 659, 408, 410, 414, 136, 398, 418, 422,
+ 662, 438, 144, 430, 426, 440, 442, 428,
+ 434, 504, 492, 498, 499, 663, 450, 584,
+ // Entry C0 - FF
+ 581, 807, 466, 104, 496, 446, 580, 474,
+ 478, 500, 470, 480, 462, 454, 484, 458,
+ 508, 516, 540, 562, 574, 566, 548, 558,
+ 528, 578, 524, 10, 520, 536, 570, 554,
+ 512, 591, 0, 604, 258, 598, 608, 586,
+ 616, 666, 612, 630, 275, 620, 581, 585,
+ 600, 591, 634, 959, 960, 961, 962, 963,
+ 964, 965, 966, 967, 968, 969, 970, 971,
+ // Entry 100 - 13F
+ 972, 638, 716, 642, 688, 643, 646, 682,
+ 90, 690, 729, 752, 702, 654, 705, 744,
+ 703, 694, 674, 686, 706, 740, 728, 678,
+ 810, 222, 534, 760, 748, 0, 796, 148,
+ 260, 768, 764, 762, 772, 626, 795, 788,
+ 776, 626, 792, 780, 798, 158, 834, 804,
+ 800, 826, 581, 0, 840, 858, 860, 336,
+ 670, 704, 862, 92, 850, 704, 548, 876,
+ // Entry 140 - 17F
+ 581, 882, 973, 974, 975, 976, 977, 978,
+ 979, 980, 981, 982, 983, 984, 985, 986,
+ 987, 988, 989, 990, 991, 992, 993, 994,
+ 995, 996, 997, 998, 720, 887, 175, 891,
+ 710, 894, 180, 716, 999,
+}
+
+// m49Index gives indexes into fromM49 based on the three most significant bits
+// of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in
+// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]]
+// for an entry where the first 7 bits match the 7 lsb of the UN.M49 code.
+// The region code is stored in the 9 lsb of the indexed value.
+// Size: 18 bytes, 9 elements
+var m49Index = [9]int16{
+ 0, 59, 107, 142, 180, 219, 258, 290,
+ 332,
+}
+
+// fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details.
+// Size: 664 bytes, 332 elements
+var fromM49 = [332]uint16{
+ // Entry 0 - 3F
+ 0x0201, 0x0402, 0x0603, 0x0823, 0x0a04, 0x1026, 0x1205, 0x142a,
+ 0x1606, 0x1866, 0x1a07, 0x1c08, 0x1e09, 0x202c, 0x220a, 0x240b,
+ 0x260c, 0x2821, 0x2a0d, 0x3029, 0x3824, 0x3a0e, 0x3c0f, 0x3e31,
+ 0x402b, 0x4410, 0x4611, 0x482e, 0x4e12, 0x502d, 0x5841, 0x6038,
+ 0x6434, 0x6627, 0x6833, 0x6a13, 0x6c14, 0x7035, 0x7215, 0x783c,
+ 0x7a16, 0x8042, 0x883e, 0x8c32, 0x9045, 0x9444, 0x9840, 0xa847,
+ 0xac99, 0xb508, 0xb93b, 0xc03d, 0xc837, 0xd0c3, 0xd839, 0xe046,
+ 0xe8a5, 0xf051, 0xf848, 0x0859, 0x10ac, 0x184b, 0x1c17, 0x1e18,
+ // Entry 40 - 7F
+ 0x20b2, 0x2219, 0x291f, 0x2c1a, 0x2e1b, 0x3050, 0x341c, 0x361d,
+ 0x3852, 0x3d2d, 0x445b, 0x4c49, 0x5453, 0x5ca7, 0x5f5e, 0x644c,
+ 0x684a, 0x704f, 0x7855, 0x7e8f, 0x8058, 0x885c, 0x965d, 0x983a,
+ 0xa062, 0xa863, 0xac64, 0xb468, 0xbd19, 0xc485, 0xcc6e, 0xce6e,
+ 0xd06c, 0xd269, 0xd475, 0xdc73, 0xde87, 0xe472, 0xec71, 0xf030,
+ 0xf278, 0xf477, 0xfc7d, 0x04e4, 0x0920, 0x0c61, 0x1479, 0x187c,
+ 0x1c82, 0x26ec, 0x285f, 0x2c5e, 0x305f, 0x407f, 0x4880, 0x50a6,
+ 0x5886, 0x6081, 0x687b, 0x7084, 0x7889, 0x8088, 0x8883, 0x908b,
+ // Entry 80 - BF
+ 0x9890, 0x9c8d, 0xa137, 0xa88e, 0xb08c, 0xb891, 0xc09c, 0xc898,
+ 0xd094, 0xd89b, 0xe09a, 0xe895, 0xf096, 0xf89d, 0x004e, 0x089f,
+ 0x10a1, 0x1cad, 0x20a0, 0x28a3, 0x30a9, 0x34aa, 0x3cab, 0x42a4,
+ 0x44ae, 0x461e, 0x4caf, 0x54b4, 0x58b7, 0x5cb3, 0x64b8, 0x6cb1,
+ 0x70b5, 0x74b6, 0x7cc5, 0x84be, 0x8ccd, 0x94cf, 0x9ccc, 0xa4c2,
+ 0xacca, 0xb4c7, 0xbcc8, 0xc0cb, 0xc8ce, 0xd8ba, 0xe0c4, 0xe4bb,
+ 0xe6bc, 0xe8c9, 0xf0b9, 0xf8d0, 0x00e0, 0x08d1, 0x10dc, 0x18da,
+ 0x20d8, 0x2428, 0x265a, 0x2a2f, 0x2d1a, 0x2e3f, 0x30dd, 0x38d2,
+ // Entry C0 - FF
+ 0x493e, 0x54df, 0x5cd7, 0x64d3, 0x6cd5, 0x74de, 0x7cd4, 0x84d9,
+ 0x88c6, 0x8b32, 0x8e74, 0x90bf, 0x92ef, 0x94e7, 0x9ee1, 0xace5,
+ 0xb0f0, 0xb8e3, 0xc0e6, 0xc8ea, 0xd0e8, 0xd8ed, 0xe08a, 0xe525,
+ 0xeceb, 0xf4f2, 0xfd01, 0x0503, 0x0705, 0x0d06, 0x183b, 0x1d0d,
+ 0x26a8, 0x2825, 0x2cb0, 0x2ebd, 0x34e9, 0x3d38, 0x4512, 0x4d17,
+ 0x5507, 0x5d13, 0x6104, 0x6509, 0x6d11, 0x7d0c, 0x7f10, 0x813d,
+ 0x830e, 0x8514, 0x8d60, 0x9963, 0xa15c, 0xa86d, 0xb116, 0xb30a,
+ 0xb86b, 0xc10a, 0xc915, 0xd10f, 0xd91c, 0xe10b, 0xe84d, 0xf11b,
+ // Entry 100 - 13F
+ 0xf523, 0xf922, 0x0121, 0x0924, 0x1128, 0x192b, 0x2022, 0x2927,
+ 0x312a, 0x3726, 0x391e, 0x3d2c, 0x4130, 0x492f, 0x4ec1, 0x5518,
+ 0x646a, 0x747a, 0x7e7e, 0x809e, 0x8297, 0x852e, 0x9134, 0xa53c,
+ 0xac36, 0xb535, 0xb936, 0xbd3a, 0xd93f, 0xe541, 0xed5d, 0xef5d,
+ 0xf656, 0xfd61, 0x7c1f, 0x7ef3, 0x80f4, 0x82f5, 0x84f6, 0x86f7,
+ 0x88f8, 0x8af9, 0x8cfa, 0x8e6f, 0x90fc, 0x92fd, 0x94fe, 0x96ff,
+ 0x9900, 0x9b42, 0x9d43, 0x9f44, 0xa145, 0xa346, 0xa547, 0xa748,
+ 0xa949, 0xab4a, 0xad4b, 0xaf4c, 0xb14d, 0xb34e, 0xb54f, 0xb750,
+ // Entry 140 - 17F
+ 0xb951, 0xbb52, 0xbd53, 0xbf54, 0xc155, 0xc356, 0xc557, 0xc758,
+ 0xc959, 0xcb5a, 0xcd5b, 0xcf64,
+}
+
+// Size: 1463 bytes
+var variantIndex = map[string]uint8{
+ "1606nict": 0x0,
+ "1694acad": 0x1,
+ "1901": 0x2,
+ "1959acad": 0x3,
+ "1994": 0x45,
+ "1996": 0x4,
+ "abl1943": 0x5,
+ "alalc97": 0x47,
+ "aluku": 0x6,
+ "ao1990": 0x7,
+ "arevela": 0x8,
+ "arevmda": 0x9,
+ "baku1926": 0xa,
+ "balanka": 0xb,
+ "barla": 0xc,
+ "basiceng": 0xd,
+ "bauddha": 0xe,
+ "biscayan": 0xf,
+ "biske": 0x40,
+ "bohoric": 0x10,
+ "boont": 0x11,
+ "colb1945": 0x12,
+ "cornu": 0x13,
+ "dajnko": 0x14,
+ "ekavsk": 0x15,
+ "emodeng": 0x16,
+ "fonipa": 0x48,
+ "fonnapa": 0x49,
+ "fonupa": 0x4a,
+ "fonxsamp": 0x4b,
+ "hepburn": 0x17,
+ "heploc": 0x46,
+ "hognorsk": 0x18,
+ "ijekavsk": 0x19,
+ "itihasa": 0x1a,
+ "jauer": 0x1b,
+ "jyutping": 0x1c,
+ "kkcor": 0x1d,
+ "kociewie": 0x1e,
+ "kscor": 0x1f,
+ "laukika": 0x20,
+ "lipaw": 0x41,
+ "luna1918": 0x21,
+ "metelko": 0x22,
+ "monoton": 0x23,
+ "ndyuka": 0x24,
+ "nedis": 0x25,
+ "newfound": 0x26,
+ "njiva": 0x42,
+ "nulik": 0x27,
+ "osojs": 0x43,
+ "oxendict": 0x28,
+ "pamaka": 0x29,
+ "petr1708": 0x2a,
+ "pinyin": 0x2b,
+ "polyton": 0x2c,
+ "puter": 0x2d,
+ "rigik": 0x2e,
+ "rozaj": 0x2f,
+ "rumgr": 0x30,
+ "scotland": 0x31,
+ "scouse": 0x32,
+ "simple": 0x4c,
+ "solba": 0x44,
+ "sotav": 0x33,
+ "surmiran": 0x34,
+ "sursilv": 0x35,
+ "sutsilv": 0x36,
+ "tarask": 0x37,
+ "uccor": 0x38,
+ "ucrcor": 0x39,
+ "ulster": 0x3a,
+ "unifon": 0x3b,
+ "vaidika": 0x3c,
+ "valencia": 0x3d,
+ "vallader": 0x3e,
+ "wadegile": 0x3f,
+}
+
+// variantNumSpecialized is the number of specialized variants in variants.
+const variantNumSpecialized = 71
+
+// nRegionGroups is the number of region groups.
+const nRegionGroups = 32
+
+type likelyLangRegion struct {
+ lang uint16
+ region uint16
+}
+
+// likelyScript is a lookup table, indexed by scriptID, for the most likely
+// languages and regions given a script.
+// Size: 928 bytes, 232 elements
+var likelyScript = [232]likelyLangRegion{
+ 1: {lang: 0x149, region: 0x83},
+ 3: {lang: 0x299, region: 0x105},
+ 4: {lang: 0x1e, region: 0x98},
+ 5: {lang: 0x39, region: 0x6a},
+ 7: {lang: 0x3a, region: 0x9b},
+ 8: {lang: 0x1d0, region: 0x27},
+ 9: {lang: 0x12, region: 0x9b},
+ 10: {lang: 0x5a, region: 0x94},
+ 11: {lang: 0x5f, region: 0x51},
+ 12: {lang: 0xb7, region: 0xb3},
+ 13: {lang: 0x62, region: 0x94},
+ 14: {lang: 0xa3, region: 0x34},
+ 15: {lang: 0x3e0, region: 0x98},
+ 17: {lang: 0x51f, region: 0x12d},
+ 18: {lang: 0x3a8, region: 0x98},
+ 19: {lang: 0x159, region: 0x77},
+ 20: {lang: 0xc0, region: 0x94},
+ 21: {lang: 0x9b, region: 0xe6},
+ 22: {lang: 0xd9, region: 0x34},
+ 23: {lang: 0xf0, region: 0x48},
+ 24: {lang: 0x4e6, region: 0x12a},
+ 25: {lang: 0xe5, region: 0x13d},
+ 26: {lang: 0xe3, region: 0x134},
+ 28: {lang: 0xee, region: 0x6a},
+ 29: {lang: 0x199, region: 0x5c},
+ 30: {lang: 0x3d9, region: 0x105},
+ 32: {lang: 0x1b7, region: 0x98},
+ 34: {lang: 0x159, region: 0x77},
+ 37: {lang: 0x12f, region: 0x6a},
+ 38: {lang: 0x427, region: 0x26},
+ 39: {lang: 0x26, region: 0x6e},
+ 41: {lang: 0x208, region: 0x7c},
+ 42: {lang: 0xfa, region: 0x37},
+ 43: {lang: 0x198, region: 0x12f},
+ 44: {lang: 0x3e0, region: 0x98},
+ 45: {lang: 0x131, region: 0x86},
+ 46: {lang: 0x19d, region: 0x98},
+ 47: {lang: 0x394, region: 0x98},
+ 48: {lang: 0x51f, region: 0x12d},
+ 49: {lang: 0x24b, region: 0xaa},
+ 50: {lang: 0x51f, region: 0x52},
+ 51: {lang: 0x1c4, region: 0xe6},
+ 52: {lang: 0x51f, region: 0x52},
+ 53: {lang: 0x51f, region: 0x12d},
+ 54: {lang: 0x2f4, region: 0x9a},
+ 55: {lang: 0x1b5, region: 0x96},
+ 56: {lang: 0x1f8, region: 0xa1},
+ 57: {lang: 0x1be, region: 0x12a},
+ 58: {lang: 0x1c3, region: 0xae},
+ 60: {lang: 0x1ce, region: 0x91},
+ 62: {lang: 0x13d, region: 0x9d},
+ 63: {lang: 0x24b, region: 0xaa},
+ 64: {lang: 0x206, region: 0x94},
+ 65: {lang: 0x1f8, region: 0xa1},
+ 67: {lang: 0x130, region: 0xc3},
+ 68: {lang: 0x1f8, region: 0xa1},
+ 69: {lang: 0x3b2, region: 0xe7},
+ 70: {lang: 0x242, region: 0xa5},
+ 71: {lang: 0x3f0, region: 0x98},
+ 74: {lang: 0x249, region: 0x98},
+ 75: {lang: 0x24b, region: 0xaa},
+ 77: {lang: 0x87, region: 0x98},
+ 78: {lang: 0x367, region: 0x122},
+ 79: {lang: 0x2af, region: 0xae},
+ 84: {lang: 0x296, region: 0x98},
+ 85: {lang: 0x29f, region: 0x98},
+ 86: {lang: 0x286, region: 0x86},
+ 87: {lang: 0x199, region: 0x86},
+ 88: {lang: 0x2a3, region: 0x52},
+ 90: {lang: 0x4ea, region: 0x12a},
+ 91: {lang: 0x4eb, region: 0x12a},
+ 92: {lang: 0x1b7, region: 0x98},
+ 93: {lang: 0x32e, region: 0x9b},
+ 94: {lang: 0x4ed, region: 0x52},
+ 95: {lang: 0xa7, region: 0x52},
+ 97: {lang: 0x2df, region: 0x111},
+ 98: {lang: 0x4ee, region: 0x10a},
+ 99: {lang: 0x4ee, region: 0x10a},
+ 100: {lang: 0x2fb, region: 0x98},
+ 101: {lang: 0x312, region: 0x98},
+ 102: {lang: 0x302, region: 0x52},
+ 104: {lang: 0x315, region: 0x34},
+ 105: {lang: 0x305, region: 0x98},
+ 106: {lang: 0x40a, region: 0xe7},
+ 107: {lang: 0x328, region: 0xc3},
+ 108: {lang: 0x4ef, region: 0x107},
+ 109: {lang: 0x3a, region: 0xa0},
+ 110: {lang: 0x34a, region: 0xda},
+ 112: {lang: 0x2c7, region: 0x83},
+ 114: {lang: 0x3f9, region: 0x95},
+ 115: {lang: 0x3e5, region: 0x98},
+ 116: {lang: 0x392, region: 0xc4},
+ 117: {lang: 0x38c, region: 0x98},
+ 118: {lang: 0x390, region: 0x134},
+ 119: {lang: 0x41f, region: 0x114},
+ 120: {lang: 0x3a, region: 0x11b},
+ 121: {lang: 0xf9, region: 0xc3},
+ 122: {lang: 0x274, region: 0x105},
+ 123: {lang: 0x2c0, region: 0x52},
+ 124: {lang: 0x396, region: 0x9b},
+ 125: {lang: 0x396, region: 0x52},
+ 127: {lang: 0x3a4, region: 0xaf},
+ 129: {lang: 0x1bf, region: 0x52},
+ 130: {lang: 0x4f3, region: 0x9b},
+ 181: {lang: 0x3c2, region: 0x94},
+ 183: {lang: 0x369, region: 0x10b},
+ 184: {lang: 0x416, region: 0x96},
+ 186: {lang: 0x4f5, region: 0x15d},
+ 187: {lang: 0x3e6, region: 0x98},
+ 188: {lang: 0x44, region: 0x134},
+ 189: {lang: 0x134, region: 0x7a},
+ 190: {lang: 0x3e0, region: 0x98},
+ 191: {lang: 0x3e0, region: 0x98},
+ 192: {lang: 0x3f0, region: 0x98},
+ 193: {lang: 0x402, region: 0xb2},
+ 194: {lang: 0x429, region: 0x98},
+ 195: {lang: 0x434, region: 0x94},
+ 196: {lang: 0x443, region: 0x34},
+ 197: {lang: 0x444, region: 0x9a},
+ 201: {lang: 0x450, region: 0xe6},
+ 202: {lang: 0x116, region: 0x98},
+ 203: {lang: 0x454, region: 0x52},
+ 204: {lang: 0x22a, region: 0x52},
+ 205: {lang: 0x446, region: 0x98},
+ 206: {lang: 0x49b, region: 0x52},
+ 207: {lang: 0x9d, region: 0x13d},
+ 208: {lang: 0x457, region: 0x98},
+ 210: {lang: 0x51e, region: 0xb9},
+ 211: {lang: 0x14e, region: 0xe6},
+ 212: {lang: 0x124, region: 0xcc},
+ 213: {lang: 0x461, region: 0x122},
+ 214: {lang: 0xa7, region: 0x52},
+ 215: {lang: 0x2c5, region: 0x98},
+ 216: {lang: 0x4a3, region: 0x11b},
+ 217: {lang: 0x4b4, region: 0xb3},
+ 219: {lang: 0x1c7, region: 0x98},
+ 221: {lang: 0x3a0, region: 0x9b},
+ 222: {lang: 0x21, region: 0x9a},
+ 223: {lang: 0x1e2, region: 0x52},
+}
+
+type likelyScriptRegion struct {
+ region uint16
+ script uint8
+ flags uint8
+}
+
+// likelyLang is a lookup table, indexed by langID, for the most likely
+// scripts and regions given incomplete information. If more entries exist for a
+// given language, region and script are the index and size respectively
+// of the list in likelyLangList.
+// Size: 5276 bytes, 1319 elements
+var likelyLang = [1319]likelyScriptRegion{
+ 0: {region: 0x134, script: 0x52, flags: 0x0},
+ 1: {region: 0x6e, script: 0x52, flags: 0x0},
+ 2: {region: 0x164, script: 0x52, flags: 0x0},
+ 3: {region: 0x164, script: 0x52, flags: 0x0},
+ 4: {region: 0x164, script: 0x52, flags: 0x0},
+ 5: {region: 0x7c, script: 0x1e, flags: 0x0},
+ 6: {region: 0x164, script: 0x52, flags: 0x0},
+ 7: {region: 0x7f, script: 0x52, flags: 0x0},
+ 8: {region: 0x164, script: 0x52, flags: 0x0},
+ 9: {region: 0x164, script: 0x52, flags: 0x0},
+ 10: {region: 0x164, script: 0x52, flags: 0x0},
+ 11: {region: 0x94, script: 0x52, flags: 0x0},
+ 12: {region: 0x130, script: 0x52, flags: 0x0},
+ 13: {region: 0x7f, script: 0x52, flags: 0x0},
+ 14: {region: 0x164, script: 0x52, flags: 0x0},
+ 15: {region: 0x164, script: 0x52, flags: 0x0},
+ 16: {region: 0x105, script: 0x1e, flags: 0x0},
+ 17: {region: 0x164, script: 0x52, flags: 0x0},
+ 18: {region: 0x9b, script: 0x9, flags: 0x0},
+ 19: {region: 0x127, script: 0x5, flags: 0x0},
+ 20: {region: 0x164, script: 0x52, flags: 0x0},
+ 21: {region: 0x160, script: 0x52, flags: 0x0},
+ 22: {region: 0x164, script: 0x52, flags: 0x0},
+ 23: {region: 0x164, script: 0x52, flags: 0x0},
+ 24: {region: 0x164, script: 0x52, flags: 0x0},
+ 25: {region: 0x164, script: 0x52, flags: 0x0},
+ 26: {region: 0x164, script: 0x52, flags: 0x0},
+ 27: {region: 0x51, script: 0x52, flags: 0x0},
+ 28: {region: 0x164, script: 0x52, flags: 0x0},
+ 29: {region: 0x164, script: 0x52, flags: 0x0},
+ 30: {region: 0x98, script: 0x4, flags: 0x0},
+ 31: {region: 0x164, script: 0x52, flags: 0x0},
+ 32: {region: 0x7f, script: 0x52, flags: 0x0},
+ 33: {region: 0x9a, script: 0xde, flags: 0x0},
+ 34: {region: 0x164, script: 0x52, flags: 0x0},
+ 35: {region: 0x164, script: 0x52, flags: 0x0},
+ 36: {region: 0x14c, script: 0x52, flags: 0x0},
+ 37: {region: 0x105, script: 0x1e, flags: 0x0},
+ 38: {region: 0x6e, script: 0x27, flags: 0x0},
+ 39: {region: 0x164, script: 0x52, flags: 0x0},
+ 40: {region: 0x164, script: 0x52, flags: 0x0},
+ 41: {region: 0xd5, script: 0x52, flags: 0x0},
+ 42: {region: 0x164, script: 0x52, flags: 0x0},
+ 44: {region: 0x164, script: 0x52, flags: 0x0},
+ 45: {region: 0x164, script: 0x52, flags: 0x0},
+ 46: {region: 0x164, script: 0x52, flags: 0x0},
+ 47: {region: 0x164, script: 0x52, flags: 0x0},
+ 48: {region: 0x164, script: 0x52, flags: 0x0},
+ 49: {region: 0x164, script: 0x52, flags: 0x0},
+ 50: {region: 0x94, script: 0x52, flags: 0x0},
+ 51: {region: 0x164, script: 0x5, flags: 0x0},
+ 52: {region: 0x121, script: 0x5, flags: 0x0},
+ 53: {region: 0x164, script: 0x52, flags: 0x0},
+ 54: {region: 0x164, script: 0x52, flags: 0x0},
+ 55: {region: 0x164, script: 0x52, flags: 0x0},
+ 56: {region: 0x164, script: 0x52, flags: 0x0},
+ 57: {region: 0x6a, script: 0x5, flags: 0x0},
+ 58: {region: 0x0, script: 0x3, flags: 0x1},
+ 59: {region: 0x164, script: 0x52, flags: 0x0},
+ 60: {region: 0x50, script: 0x52, flags: 0x0},
+ 61: {region: 0x3e, script: 0x52, flags: 0x0},
+ 62: {region: 0x66, script: 0x5, flags: 0x0},
+ 64: {region: 0xb9, script: 0x5, flags: 0x0},
+ 65: {region: 0x6a, script: 0x5, flags: 0x0},
+ 66: {region: 0x98, script: 0xe, flags: 0x0},
+ 67: {region: 0x12e, script: 0x52, flags: 0x0},
+ 68: {region: 0x134, script: 0xbc, flags: 0x0},
+ 69: {region: 0x164, script: 0x52, flags: 0x0},
+ 70: {region: 0x164, script: 0x52, flags: 0x0},
+ 71: {region: 0x6d, script: 0x52, flags: 0x0},
+ 72: {region: 0x164, script: 0x52, flags: 0x0},
+ 73: {region: 0x164, script: 0x52, flags: 0x0},
+ 74: {region: 0x48, script: 0x52, flags: 0x0},
+ 75: {region: 0x164, script: 0x52, flags: 0x0},
+ 76: {region: 0x105, script: 0x1e, flags: 0x0},
+ 77: {region: 0x164, script: 0x5, flags: 0x0},
+ 78: {region: 0x164, script: 0x52, flags: 0x0},
+ 79: {region: 0x164, script: 0x52, flags: 0x0},
+ 80: {region: 0x164, script: 0x52, flags: 0x0},
+ 81: {region: 0x98, script: 0x20, flags: 0x0},
+ 82: {region: 0x164, script: 0x52, flags: 0x0},
+ 83: {region: 0x164, script: 0x52, flags: 0x0},
+ 84: {region: 0x164, script: 0x52, flags: 0x0},
+ 85: {region: 0x3e, script: 0x52, flags: 0x0},
+ 86: {region: 0x164, script: 0x52, flags: 0x0},
+ 87: {region: 0x3, script: 0x5, flags: 0x1},
+ 88: {region: 0x105, script: 0x1e, flags: 0x0},
+ 89: {region: 0xe7, script: 0x5, flags: 0x0},
+ 90: {region: 0x94, script: 0x52, flags: 0x0},
+ 91: {region: 0xda, script: 0x20, flags: 0x0},
+ 92: {region: 0x2d, script: 0x52, flags: 0x0},
+ 93: {region: 0x51, script: 0x52, flags: 0x0},
+ 94: {region: 0x164, script: 0x52, flags: 0x0},
+ 95: {region: 0x51, script: 0xb, flags: 0x0},
+ 96: {region: 0x164, script: 0x52, flags: 0x0},
+ 97: {region: 0x164, script: 0x52, flags: 0x0},
+ 98: {region: 0x94, script: 0x52, flags: 0x0},
+ 99: {region: 0x164, script: 0x52, flags: 0x0},
+ 100: {region: 0x51, script: 0x52, flags: 0x0},
+ 101: {region: 0x164, script: 0x52, flags: 0x0},
+ 102: {region: 0x164, script: 0x52, flags: 0x0},
+ 103: {region: 0x164, script: 0x52, flags: 0x0},
+ 104: {region: 0x164, script: 0x52, flags: 0x0},
+ 105: {region: 0x4e, script: 0x52, flags: 0x0},
+ 106: {region: 0x164, script: 0x52, flags: 0x0},
+ 107: {region: 0x164, script: 0x52, flags: 0x0},
+ 108: {region: 0x164, script: 0x52, flags: 0x0},
+ 109: {region: 0x164, script: 0x27, flags: 0x0},
+ 110: {region: 0x164, script: 0x52, flags: 0x0},
+ 111: {region: 0x164, script: 0x52, flags: 0x0},
+ 112: {region: 0x46, script: 0x1e, flags: 0x0},
+ 113: {region: 0x164, script: 0x52, flags: 0x0},
+ 114: {region: 0x164, script: 0x52, flags: 0x0},
+ 115: {region: 0x10a, script: 0x5, flags: 0x0},
+ 116: {region: 0x161, script: 0x52, flags: 0x0},
+ 117: {region: 0x164, script: 0x52, flags: 0x0},
+ 118: {region: 0x94, script: 0x52, flags: 0x0},
+ 119: {region: 0x164, script: 0x52, flags: 0x0},
+ 120: {region: 0x12e, script: 0x52, flags: 0x0},
+ 121: {region: 0x51, script: 0x52, flags: 0x0},
+ 122: {region: 0x98, script: 0xcd, flags: 0x0},
+ 123: {region: 0xe7, script: 0x5, flags: 0x0},
+ 124: {region: 0x98, script: 0x20, flags: 0x0},
+ 125: {region: 0x37, script: 0x1e, flags: 0x0},
+ 126: {region: 0x98, script: 0x20, flags: 0x0},
+ 127: {region: 0xe7, script: 0x5, flags: 0x0},
+ 128: {region: 0x12a, script: 0x2d, flags: 0x0},
+ 130: {region: 0x98, script: 0x20, flags: 0x0},
+ 131: {region: 0x164, script: 0x52, flags: 0x0},
+ 132: {region: 0x98, script: 0x20, flags: 0x0},
+ 133: {region: 0xe6, script: 0x52, flags: 0x0},
+ 134: {region: 0x164, script: 0x52, flags: 0x0},
+ 135: {region: 0x98, script: 0x20, flags: 0x0},
+ 136: {region: 0x164, script: 0x52, flags: 0x0},
+ 137: {region: 0x13e, script: 0x52, flags: 0x0},
+ 138: {region: 0x164, script: 0x52, flags: 0x0},
+ 139: {region: 0x164, script: 0x52, flags: 0x0},
+ 140: {region: 0xe6, script: 0x52, flags: 0x0},
+ 141: {region: 0x164, script: 0x52, flags: 0x0},
+ 142: {region: 0xd5, script: 0x52, flags: 0x0},
+ 143: {region: 0x164, script: 0x52, flags: 0x0},
+ 144: {region: 0x164, script: 0x52, flags: 0x0},
+ 145: {region: 0x164, script: 0x52, flags: 0x0},
+ 146: {region: 0x164, script: 0x27, flags: 0x0},
+ 147: {region: 0x98, script: 0x20, flags: 0x0},
+ 148: {region: 0x94, script: 0x52, flags: 0x0},
+ 149: {region: 0x164, script: 0x52, flags: 0x0},
+ 150: {region: 0x164, script: 0x52, flags: 0x0},
+ 151: {region: 0x164, script: 0x52, flags: 0x0},
+ 152: {region: 0x164, script: 0x52, flags: 0x0},
+ 153: {region: 0x51, script: 0x52, flags: 0x0},
+ 154: {region: 0x164, script: 0x52, flags: 0x0},
+ 155: {region: 0xe6, script: 0x52, flags: 0x0},
+ 156: {region: 0x164, script: 0x52, flags: 0x0},
+ 157: {region: 0x13d, script: 0xcf, flags: 0x0},
+ 158: {region: 0xc2, script: 0x52, flags: 0x0},
+ 159: {region: 0x164, script: 0x52, flags: 0x0},
+ 160: {region: 0x164, script: 0x52, flags: 0x0},
+ 161: {region: 0xc2, script: 0x52, flags: 0x0},
+ 162: {region: 0x164, script: 0x52, flags: 0x0},
+ 163: {region: 0x34, script: 0xe, flags: 0x0},
+ 164: {region: 0x164, script: 0x52, flags: 0x0},
+ 165: {region: 0x164, script: 0x52, flags: 0x0},
+ 166: {region: 0x164, script: 0x52, flags: 0x0},
+ 167: {region: 0x52, script: 0xd6, flags: 0x0},
+ 168: {region: 0x164, script: 0x52, flags: 0x0},
+ 169: {region: 0x164, script: 0x52, flags: 0x0},
+ 170: {region: 0x164, script: 0x52, flags: 0x0},
+ 171: {region: 0x98, script: 0xe, flags: 0x0},
+ 172: {region: 0x164, script: 0x52, flags: 0x0},
+ 173: {region: 0x9b, script: 0x5, flags: 0x0},
+ 174: {region: 0x164, script: 0x52, flags: 0x0},
+ 175: {region: 0x4e, script: 0x52, flags: 0x0},
+ 176: {region: 0x77, script: 0x52, flags: 0x0},
+ 177: {region: 0x98, script: 0x20, flags: 0x0},
+ 178: {region: 0xe7, script: 0x5, flags: 0x0},
+ 179: {region: 0x98, script: 0x20, flags: 0x0},
+ 180: {region: 0x164, script: 0x52, flags: 0x0},
+ 181: {region: 0x32, script: 0x52, flags: 0x0},
+ 182: {region: 0x164, script: 0x52, flags: 0x0},
+ 183: {region: 0xb3, script: 0xc, flags: 0x0},
+ 184: {region: 0x51, script: 0x52, flags: 0x0},
+ 185: {region: 0x164, script: 0x27, flags: 0x0},
+ 186: {region: 0xe6, script: 0x52, flags: 0x0},
+ 187: {region: 0x164, script: 0x52, flags: 0x0},
+ 188: {region: 0xe7, script: 0x20, flags: 0x0},
+ 189: {region: 0x105, script: 0x1e, flags: 0x0},
+ 190: {region: 0x15e, script: 0x52, flags: 0x0},
+ 191: {region: 0x164, script: 0x52, flags: 0x0},
+ 192: {region: 0x94, script: 0x52, flags: 0x0},
+ 193: {region: 0x164, script: 0x52, flags: 0x0},
+ 194: {region: 0x51, script: 0x52, flags: 0x0},
+ 195: {region: 0x164, script: 0x52, flags: 0x0},
+ 196: {region: 0x164, script: 0x52, flags: 0x0},
+ 197: {region: 0x164, script: 0x52, flags: 0x0},
+ 198: {region: 0x85, script: 0x52, flags: 0x0},
+ 199: {region: 0x164, script: 0x52, flags: 0x0},
+ 200: {region: 0x164, script: 0x52, flags: 0x0},
+ 201: {region: 0x164, script: 0x52, flags: 0x0},
+ 202: {region: 0x164, script: 0x52, flags: 0x0},
+ 203: {region: 0x6c, script: 0x27, flags: 0x0},
+ 204: {region: 0x164, script: 0x52, flags: 0x0},
+ 205: {region: 0x164, script: 0x52, flags: 0x0},
+ 206: {region: 0x51, script: 0x52, flags: 0x0},
+ 207: {region: 0x164, script: 0x52, flags: 0x0},
+ 208: {region: 0x164, script: 0x52, flags: 0x0},
+ 209: {region: 0xc2, script: 0x52, flags: 0x0},
+ 210: {region: 0x164, script: 0x52, flags: 0x0},
+ 211: {region: 0x164, script: 0x52, flags: 0x0},
+ 212: {region: 0x164, script: 0x52, flags: 0x0},
+ 213: {region: 0x6d, script: 0x52, flags: 0x0},
+ 214: {region: 0x164, script: 0x52, flags: 0x0},
+ 215: {region: 0x164, script: 0x52, flags: 0x0},
+ 216: {region: 0xd5, script: 0x52, flags: 0x0},
+ 217: {region: 0x8, script: 0x2, flags: 0x1},
+ 218: {region: 0x105, script: 0x1e, flags: 0x0},
+ 219: {region: 0xe6, script: 0x52, flags: 0x0},
+ 220: {region: 0x164, script: 0x52, flags: 0x0},
+ 221: {region: 0x130, script: 0x52, flags: 0x0},
+ 222: {region: 0x89, script: 0x52, flags: 0x0},
+ 223: {region: 0x74, script: 0x52, flags: 0x0},
+ 224: {region: 0x105, script: 0x1e, flags: 0x0},
+ 225: {region: 0x134, script: 0x52, flags: 0x0},
+ 226: {region: 0x48, script: 0x52, flags: 0x0},
+ 227: {region: 0x134, script: 0x1a, flags: 0x0},
+ 228: {region: 0xa5, script: 0x5, flags: 0x0},
+ 229: {region: 0x13d, script: 0x19, flags: 0x0},
+ 230: {region: 0x164, script: 0x52, flags: 0x0},
+ 231: {region: 0x9a, script: 0x5, flags: 0x0},
+ 232: {region: 0x164, script: 0x52, flags: 0x0},
+ 233: {region: 0x164, script: 0x52, flags: 0x0},
+ 234: {region: 0x164, script: 0x52, flags: 0x0},
+ 235: {region: 0x164, script: 0x52, flags: 0x0},
+ 236: {region: 0x164, script: 0x52, flags: 0x0},
+ 237: {region: 0x77, script: 0x52, flags: 0x0},
+ 238: {region: 0x6a, script: 0x1c, flags: 0x0},
+ 239: {region: 0xe6, script: 0x52, flags: 0x0},
+ 240: {region: 0x48, script: 0x17, flags: 0x0},
+ 241: {region: 0x48, script: 0x17, flags: 0x0},
+ 242: {region: 0x48, script: 0x17, flags: 0x0},
+ 243: {region: 0x48, script: 0x17, flags: 0x0},
+ 244: {region: 0x48, script: 0x17, flags: 0x0},
+ 245: {region: 0x109, script: 0x52, flags: 0x0},
+ 246: {region: 0x5d, script: 0x52, flags: 0x0},
+ 247: {region: 0xe8, script: 0x52, flags: 0x0},
+ 248: {region: 0x48, script: 0x17, flags: 0x0},
+ 249: {region: 0xc3, script: 0x79, flags: 0x0},
+ 250: {region: 0xa, script: 0x2, flags: 0x1},
+ 251: {region: 0x105, script: 0x1e, flags: 0x0},
+ 252: {region: 0x7a, script: 0x52, flags: 0x0},
+ 253: {region: 0x62, script: 0x52, flags: 0x0},
+ 254: {region: 0x164, script: 0x52, flags: 0x0},
+ 255: {region: 0x164, script: 0x52, flags: 0x0},
+ 256: {region: 0x164, script: 0x52, flags: 0x0},
+ 257: {region: 0x164, script: 0x52, flags: 0x0},
+ 258: {region: 0x134, script: 0x52, flags: 0x0},
+ 259: {region: 0x105, script: 0x1e, flags: 0x0},
+ 260: {region: 0xa3, script: 0x52, flags: 0x0},
+ 261: {region: 0x164, script: 0x52, flags: 0x0},
+ 262: {region: 0x164, script: 0x52, flags: 0x0},
+ 263: {region: 0x98, script: 0x5, flags: 0x0},
+ 264: {region: 0x164, script: 0x52, flags: 0x0},
+ 265: {region: 0x5f, script: 0x52, flags: 0x0},
+ 266: {region: 0x164, script: 0x52, flags: 0x0},
+ 267: {region: 0x48, script: 0x52, flags: 0x0},
+ 268: {region: 0x164, script: 0x52, flags: 0x0},
+ 269: {region: 0x164, script: 0x52, flags: 0x0},
+ 270: {region: 0x164, script: 0x52, flags: 0x0},
+ 271: {region: 0x164, script: 0x5, flags: 0x0},
+ 272: {region: 0x48, script: 0x52, flags: 0x0},
+ 273: {region: 0x164, script: 0x52, flags: 0x0},
+ 274: {region: 0x164, script: 0x52, flags: 0x0},
+ 275: {region: 0xd3, script: 0x52, flags: 0x0},
+ 276: {region: 0x4e, script: 0x52, flags: 0x0},
+ 277: {region: 0x164, script: 0x52, flags: 0x0},
+ 278: {region: 0x98, script: 0x5, flags: 0x0},
+ 279: {region: 0x164, script: 0x52, flags: 0x0},
+ 280: {region: 0x164, script: 0x52, flags: 0x0},
+ 281: {region: 0x164, script: 0x52, flags: 0x0},
+ 282: {region: 0x164, script: 0x27, flags: 0x0},
+ 283: {region: 0x5f, script: 0x52, flags: 0x0},
+ 284: {region: 0xc2, script: 0x52, flags: 0x0},
+ 285: {region: 0xcf, script: 0x52, flags: 0x0},
+ 286: {region: 0x164, script: 0x52, flags: 0x0},
+ 287: {region: 0xda, script: 0x20, flags: 0x0},
+ 288: {region: 0x51, script: 0x52, flags: 0x0},
+ 289: {region: 0x164, script: 0x52, flags: 0x0},
+ 290: {region: 0x164, script: 0x52, flags: 0x0},
+ 291: {region: 0x164, script: 0x52, flags: 0x0},
+ 292: {region: 0xcc, script: 0xd4, flags: 0x0},
+ 293: {region: 0x164, script: 0x52, flags: 0x0},
+ 294: {region: 0x164, script: 0x52, flags: 0x0},
+ 295: {region: 0x113, script: 0x52, flags: 0x0},
+ 296: {region: 0x36, script: 0x52, flags: 0x0},
+ 297: {region: 0x42, script: 0xd6, flags: 0x0},
+ 298: {region: 0x164, script: 0x52, flags: 0x0},
+ 299: {region: 0xa3, script: 0x52, flags: 0x0},
+ 300: {region: 0x7f, script: 0x52, flags: 0x0},
+ 301: {region: 0xd5, script: 0x52, flags: 0x0},
+ 302: {region: 0x9d, script: 0x52, flags: 0x0},
+ 303: {region: 0x6a, script: 0x25, flags: 0x0},
+ 304: {region: 0xc3, script: 0x43, flags: 0x0},
+ 305: {region: 0x86, script: 0x2d, flags: 0x0},
+ 306: {region: 0x164, script: 0x52, flags: 0x0},
+ 307: {region: 0x164, script: 0x52, flags: 0x0},
+ 308: {region: 0xc, script: 0x2, flags: 0x1},
+ 309: {region: 0x164, script: 0x52, flags: 0x0},
+ 310: {region: 0x164, script: 0x52, flags: 0x0},
+ 311: {region: 0x1, script: 0x52, flags: 0x0},
+ 312: {region: 0x164, script: 0x52, flags: 0x0},
+ 313: {region: 0x6d, script: 0x52, flags: 0x0},
+ 314: {region: 0x134, script: 0x52, flags: 0x0},
+ 315: {region: 0x69, script: 0x52, flags: 0x0},
+ 316: {region: 0x164, script: 0x52, flags: 0x0},
+ 317: {region: 0x9d, script: 0x3e, flags: 0x0},
+ 318: {region: 0x164, script: 0x52, flags: 0x0},
+ 319: {region: 0x164, script: 0x52, flags: 0x0},
+ 320: {region: 0x6d, script: 0x52, flags: 0x0},
+ 321: {region: 0x51, script: 0x52, flags: 0x0},
+ 322: {region: 0x6d, script: 0x52, flags: 0x0},
+ 323: {region: 0x9b, script: 0x5, flags: 0x0},
+ 324: {region: 0x164, script: 0x52, flags: 0x0},
+ 325: {region: 0x164, script: 0x52, flags: 0x0},
+ 326: {region: 0x164, script: 0x52, flags: 0x0},
+ 327: {region: 0x164, script: 0x52, flags: 0x0},
+ 328: {region: 0x85, script: 0x52, flags: 0x0},
+ 329: {region: 0xe, script: 0x2, flags: 0x1},
+ 330: {region: 0x164, script: 0x52, flags: 0x0},
+ 331: {region: 0xc2, script: 0x52, flags: 0x0},
+ 332: {region: 0x71, script: 0x52, flags: 0x0},
+ 333: {region: 0x10a, script: 0x5, flags: 0x0},
+ 334: {region: 0xe6, script: 0x52, flags: 0x0},
+ 335: {region: 0x10b, script: 0x52, flags: 0x0},
+ 336: {region: 0x72, script: 0x52, flags: 0x0},
+ 337: {region: 0x164, script: 0x52, flags: 0x0},
+ 338: {region: 0x164, script: 0x52, flags: 0x0},
+ 339: {region: 0x75, script: 0x52, flags: 0x0},
+ 340: {region: 0x164, script: 0x52, flags: 0x0},
+ 341: {region: 0x3a, script: 0x52, flags: 0x0},
+ 342: {region: 0x164, script: 0x52, flags: 0x0},
+ 343: {region: 0x164, script: 0x52, flags: 0x0},
+ 344: {region: 0x164, script: 0x52, flags: 0x0},
+ 345: {region: 0x77, script: 0x52, flags: 0x0},
+ 346: {region: 0x134, script: 0x52, flags: 0x0},
+ 347: {region: 0x77, script: 0x52, flags: 0x0},
+ 348: {region: 0x5f, script: 0x52, flags: 0x0},
+ 349: {region: 0x5f, script: 0x52, flags: 0x0},
+ 350: {region: 0x51, script: 0x5, flags: 0x0},
+ 351: {region: 0x13f, script: 0x52, flags: 0x0},
+ 352: {region: 0x164, script: 0x52, flags: 0x0},
+ 353: {region: 0x83, script: 0x52, flags: 0x0},
+ 354: {region: 0x164, script: 0x52, flags: 0x0},
+ 355: {region: 0xd3, script: 0x52, flags: 0x0},
+ 356: {region: 0x9d, script: 0x52, flags: 0x0},
+ 357: {region: 0xd5, script: 0x52, flags: 0x0},
+ 358: {region: 0x164, script: 0x52, flags: 0x0},
+ 359: {region: 0x10a, script: 0x52, flags: 0x0},
+ 360: {region: 0xd8, script: 0x52, flags: 0x0},
+ 361: {region: 0x95, script: 0x52, flags: 0x0},
+ 362: {region: 0x7f, script: 0x52, flags: 0x0},
+ 363: {region: 0x164, script: 0x52, flags: 0x0},
+ 364: {region: 0xbb, script: 0x52, flags: 0x0},
+ 365: {region: 0x164, script: 0x52, flags: 0x0},
+ 366: {region: 0x164, script: 0x52, flags: 0x0},
+ 367: {region: 0x164, script: 0x52, flags: 0x0},
+ 368: {region: 0x52, script: 0x34, flags: 0x0},
+ 369: {region: 0x164, script: 0x52, flags: 0x0},
+ 370: {region: 0x94, script: 0x52, flags: 0x0},
+ 371: {region: 0x164, script: 0x52, flags: 0x0},
+ 372: {region: 0x98, script: 0x20, flags: 0x0},
+ 373: {region: 0x164, script: 0x52, flags: 0x0},
+ 374: {region: 0x9b, script: 0x5, flags: 0x0},
+ 375: {region: 0x7d, script: 0x52, flags: 0x0},
+ 376: {region: 0x7a, script: 0x52, flags: 0x0},
+ 377: {region: 0x164, script: 0x52, flags: 0x0},
+ 378: {region: 0x164, script: 0x52, flags: 0x0},
+ 379: {region: 0x164, script: 0x52, flags: 0x0},
+ 380: {region: 0x164, script: 0x52, flags: 0x0},
+ 381: {region: 0x164, script: 0x52, flags: 0x0},
+ 382: {region: 0x164, script: 0x52, flags: 0x0},
+ 383: {region: 0x6e, script: 0x27, flags: 0x0},
+ 384: {region: 0x164, script: 0x52, flags: 0x0},
+ 385: {region: 0xda, script: 0x20, flags: 0x0},
+ 386: {region: 0x164, script: 0x52, flags: 0x0},
+ 387: {region: 0xa6, script: 0x52, flags: 0x0},
+ 388: {region: 0x164, script: 0x52, flags: 0x0},
+ 389: {region: 0xe7, script: 0x5, flags: 0x0},
+ 390: {region: 0x164, script: 0x52, flags: 0x0},
+ 391: {region: 0xe7, script: 0x5, flags: 0x0},
+ 392: {region: 0x164, script: 0x52, flags: 0x0},
+ 393: {region: 0x164, script: 0x52, flags: 0x0},
+ 394: {region: 0x6d, script: 0x52, flags: 0x0},
+ 395: {region: 0x9b, script: 0x5, flags: 0x0},
+ 396: {region: 0x164, script: 0x52, flags: 0x0},
+ 397: {region: 0x164, script: 0x27, flags: 0x0},
+ 398: {region: 0xf0, script: 0x52, flags: 0x0},
+ 399: {region: 0x164, script: 0x52, flags: 0x0},
+ 400: {region: 0x164, script: 0x52, flags: 0x0},
+ 401: {region: 0x164, script: 0x52, flags: 0x0},
+ 402: {region: 0x164, script: 0x27, flags: 0x0},
+ 403: {region: 0x164, script: 0x52, flags: 0x0},
+ 404: {region: 0x98, script: 0x20, flags: 0x0},
+ 405: {region: 0x98, script: 0xd0, flags: 0x0},
+ 406: {region: 0x94, script: 0x52, flags: 0x0},
+ 407: {region: 0xd8, script: 0x52, flags: 0x0},
+ 408: {region: 0x12f, script: 0x2b, flags: 0x0},
+ 409: {region: 0x10, script: 0x2, flags: 0x1},
+ 410: {region: 0x98, script: 0xe, flags: 0x0},
+ 411: {region: 0x164, script: 0x52, flags: 0x0},
+ 412: {region: 0x4d, script: 0x52, flags: 0x0},
+ 413: {region: 0x98, script: 0x2e, flags: 0x0},
+ 414: {region: 0x40, script: 0x52, flags: 0x0},
+ 415: {region: 0x53, script: 0x52, flags: 0x0},
+ 416: {region: 0x164, script: 0x52, flags: 0x0},
+ 417: {region: 0x7f, script: 0x52, flags: 0x0},
+ 418: {region: 0x164, script: 0x52, flags: 0x0},
+ 419: {region: 0x164, script: 0x52, flags: 0x0},
+ 420: {region: 0xa3, script: 0x52, flags: 0x0},
+ 421: {region: 0x97, script: 0x52, flags: 0x0},
+ 422: {region: 0x164, script: 0x52, flags: 0x0},
+ 423: {region: 0xda, script: 0x20, flags: 0x0},
+ 424: {region: 0x164, script: 0x52, flags: 0x0},
+ 425: {region: 0x164, script: 0x5, flags: 0x0},
+ 426: {region: 0x48, script: 0x52, flags: 0x0},
+ 427: {region: 0x164, script: 0x5, flags: 0x0},
+ 428: {region: 0x164, script: 0x52, flags: 0x0},
+ 429: {region: 0x12, script: 0x3, flags: 0x1},
+ 430: {region: 0x164, script: 0x52, flags: 0x0},
+ 431: {region: 0x52, script: 0x34, flags: 0x0},
+ 432: {region: 0x164, script: 0x52, flags: 0x0},
+ 433: {region: 0x134, script: 0x52, flags: 0x0},
+ 434: {region: 0x23, script: 0x5, flags: 0x0},
+ 435: {region: 0x164, script: 0x52, flags: 0x0},
+ 436: {region: 0x164, script: 0x27, flags: 0x0},
+ 437: {region: 0x96, script: 0x37, flags: 0x0},
+ 438: {region: 0x164, script: 0x52, flags: 0x0},
+ 439: {region: 0x98, script: 0x20, flags: 0x0},
+ 440: {region: 0x164, script: 0x52, flags: 0x0},
+ 441: {region: 0x72, script: 0x52, flags: 0x0},
+ 442: {region: 0x164, script: 0x52, flags: 0x0},
+ 443: {region: 0x164, script: 0x52, flags: 0x0},
+ 444: {region: 0xe6, script: 0x52, flags: 0x0},
+ 445: {region: 0x164, script: 0x52, flags: 0x0},
+ 446: {region: 0x12a, script: 0x39, flags: 0x0},
+ 447: {region: 0x52, script: 0x81, flags: 0x0},
+ 448: {region: 0x164, script: 0x52, flags: 0x0},
+ 449: {region: 0xe7, script: 0x5, flags: 0x0},
+ 450: {region: 0x98, script: 0x20, flags: 0x0},
+ 451: {region: 0xae, script: 0x3a, flags: 0x0},
+ 452: {region: 0xe6, script: 0x52, flags: 0x0},
+ 453: {region: 0xe7, script: 0x5, flags: 0x0},
+ 454: {region: 0xe5, script: 0x52, flags: 0x0},
+ 455: {region: 0x98, script: 0x20, flags: 0x0},
+ 456: {region: 0x98, script: 0x20, flags: 0x0},
+ 457: {region: 0x164, script: 0x52, flags: 0x0},
+ 458: {region: 0x8f, script: 0x52, flags: 0x0},
+ 459: {region: 0x5f, script: 0x52, flags: 0x0},
+ 460: {region: 0x52, script: 0x34, flags: 0x0},
+ 461: {region: 0x90, script: 0x52, flags: 0x0},
+ 462: {region: 0x91, script: 0x52, flags: 0x0},
+ 463: {region: 0x164, script: 0x52, flags: 0x0},
+ 464: {region: 0x27, script: 0x8, flags: 0x0},
+ 465: {region: 0xd1, script: 0x52, flags: 0x0},
+ 466: {region: 0x77, script: 0x52, flags: 0x0},
+ 467: {region: 0x164, script: 0x52, flags: 0x0},
+ 468: {region: 0x164, script: 0x52, flags: 0x0},
+ 469: {region: 0xcf, script: 0x52, flags: 0x0},
+ 470: {region: 0xd5, script: 0x52, flags: 0x0},
+ 471: {region: 0x164, script: 0x52, flags: 0x0},
+ 472: {region: 0x164, script: 0x52, flags: 0x0},
+ 473: {region: 0x164, script: 0x52, flags: 0x0},
+ 474: {region: 0x94, script: 0x52, flags: 0x0},
+ 475: {region: 0x164, script: 0x52, flags: 0x0},
+ 476: {region: 0x164, script: 0x52, flags: 0x0},
+ 477: {region: 0x164, script: 0x52, flags: 0x0},
+ 479: {region: 0xd5, script: 0x52, flags: 0x0},
+ 480: {region: 0x164, script: 0x52, flags: 0x0},
+ 481: {region: 0x164, script: 0x52, flags: 0x0},
+ 482: {region: 0x52, script: 0xdf, flags: 0x0},
+ 483: {region: 0x164, script: 0x52, flags: 0x0},
+ 484: {region: 0x134, script: 0x52, flags: 0x0},
+ 485: {region: 0x164, script: 0x52, flags: 0x0},
+ 486: {region: 0x48, script: 0x52, flags: 0x0},
+ 487: {region: 0x164, script: 0x52, flags: 0x0},
+ 488: {region: 0x164, script: 0x52, flags: 0x0},
+ 489: {region: 0xe6, script: 0x52, flags: 0x0},
+ 490: {region: 0x164, script: 0x52, flags: 0x0},
+ 491: {region: 0x94, script: 0x52, flags: 0x0},
+ 492: {region: 0x105, script: 0x1e, flags: 0x0},
+ 494: {region: 0x164, script: 0x52, flags: 0x0},
+ 495: {region: 0x164, script: 0x52, flags: 0x0},
+ 496: {region: 0x9c, script: 0x52, flags: 0x0},
+ 497: {region: 0x9d, script: 0x52, flags: 0x0},
+ 498: {region: 0x48, script: 0x17, flags: 0x0},
+ 499: {region: 0x96, script: 0x37, flags: 0x0},
+ 500: {region: 0x164, script: 0x52, flags: 0x0},
+ 501: {region: 0x164, script: 0x52, flags: 0x0},
+ 502: {region: 0x105, script: 0x52, flags: 0x0},
+ 503: {region: 0x164, script: 0x52, flags: 0x0},
+ 504: {region: 0xa1, script: 0x41, flags: 0x0},
+ 505: {region: 0x164, script: 0x52, flags: 0x0},
+ 506: {region: 0x9f, script: 0x52, flags: 0x0},
+ 508: {region: 0x164, script: 0x52, flags: 0x0},
+ 509: {region: 0x164, script: 0x52, flags: 0x0},
+ 510: {region: 0x164, script: 0x52, flags: 0x0},
+ 511: {region: 0x51, script: 0x52, flags: 0x0},
+ 512: {region: 0x12f, script: 0x37, flags: 0x0},
+ 513: {region: 0x164, script: 0x52, flags: 0x0},
+ 514: {region: 0x12e, script: 0x52, flags: 0x0},
+ 515: {region: 0xda, script: 0x20, flags: 0x0},
+ 516: {region: 0x164, script: 0x52, flags: 0x0},
+ 517: {region: 0x62, script: 0x52, flags: 0x0},
+ 518: {region: 0x94, script: 0x52, flags: 0x0},
+ 519: {region: 0x94, script: 0x52, flags: 0x0},
+ 520: {region: 0x7c, script: 0x29, flags: 0x0},
+ 521: {region: 0x136, script: 0x1e, flags: 0x0},
+ 522: {region: 0x66, script: 0x52, flags: 0x0},
+ 523: {region: 0xc3, script: 0x52, flags: 0x0},
+ 524: {region: 0x164, script: 0x52, flags: 0x0},
+ 525: {region: 0x164, script: 0x52, flags: 0x0},
+ 526: {region: 0xd5, script: 0x52, flags: 0x0},
+ 527: {region: 0xa3, script: 0x52, flags: 0x0},
+ 528: {region: 0xc2, script: 0x52, flags: 0x0},
+ 529: {region: 0x105, script: 0x1e, flags: 0x0},
+ 530: {region: 0x164, script: 0x52, flags: 0x0},
+ 531: {region: 0x164, script: 0x52, flags: 0x0},
+ 532: {region: 0x164, script: 0x52, flags: 0x0},
+ 533: {region: 0x164, script: 0x52, flags: 0x0},
+ 534: {region: 0xd3, script: 0x5, flags: 0x0},
+ 535: {region: 0xd5, script: 0x52, flags: 0x0},
+ 536: {region: 0x163, script: 0x52, flags: 0x0},
+ 537: {region: 0x164, script: 0x52, flags: 0x0},
+ 538: {region: 0x164, script: 0x52, flags: 0x0},
+ 539: {region: 0x12e, script: 0x52, flags: 0x0},
+ 540: {region: 0x121, script: 0x5, flags: 0x0},
+ 541: {region: 0x164, script: 0x52, flags: 0x0},
+ 542: {region: 0x122, script: 0xd5, flags: 0x0},
+ 543: {region: 0x59, script: 0x52, flags: 0x0},
+ 544: {region: 0x51, script: 0x52, flags: 0x0},
+ 545: {region: 0x164, script: 0x52, flags: 0x0},
+ 546: {region: 0x4e, script: 0x52, flags: 0x0},
+ 547: {region: 0x98, script: 0x20, flags: 0x0},
+ 548: {region: 0x98, script: 0x20, flags: 0x0},
+ 549: {region: 0x4a, script: 0x52, flags: 0x0},
+ 550: {region: 0x94, script: 0x52, flags: 0x0},
+ 551: {region: 0x164, script: 0x52, flags: 0x0},
+ 552: {region: 0x40, script: 0x52, flags: 0x0},
+ 553: {region: 0x98, script: 0x52, flags: 0x0},
+ 554: {region: 0x52, script: 0xcc, flags: 0x0},
+ 555: {region: 0x98, script: 0x20, flags: 0x0},
+ 556: {region: 0xc2, script: 0x52, flags: 0x0},
+ 557: {region: 0x164, script: 0x52, flags: 0x0},
+ 558: {region: 0x98, script: 0x6b, flags: 0x0},
+ 559: {region: 0xe7, script: 0x5, flags: 0x0},
+ 560: {region: 0x164, script: 0x52, flags: 0x0},
+ 561: {region: 0xa3, script: 0x52, flags: 0x0},
+ 562: {region: 0x164, script: 0x52, flags: 0x0},
+ 563: {region: 0x12a, script: 0x52, flags: 0x0},
+ 564: {region: 0x164, script: 0x52, flags: 0x0},
+ 565: {region: 0xd1, script: 0x52, flags: 0x0},
+ 566: {region: 0x164, script: 0x52, flags: 0x0},
+ 567: {region: 0xae, script: 0x4f, flags: 0x0},
+ 568: {region: 0x164, script: 0x52, flags: 0x0},
+ 569: {region: 0x164, script: 0x52, flags: 0x0},
+ 570: {region: 0x15, script: 0x6, flags: 0x1},
+ 571: {region: 0x164, script: 0x52, flags: 0x0},
+ 572: {region: 0x51, script: 0x52, flags: 0x0},
+ 573: {region: 0x81, script: 0x52, flags: 0x0},
+ 574: {region: 0xa3, script: 0x52, flags: 0x0},
+ 575: {region: 0x164, script: 0x52, flags: 0x0},
+ 576: {region: 0x164, script: 0x52, flags: 0x0},
+ 577: {region: 0x164, script: 0x52, flags: 0x0},
+ 578: {region: 0xa5, script: 0x46, flags: 0x0},
+ 579: {region: 0x29, script: 0x52, flags: 0x0},
+ 580: {region: 0x164, script: 0x52, flags: 0x0},
+ 581: {region: 0x164, script: 0x52, flags: 0x0},
+ 582: {region: 0x164, script: 0x52, flags: 0x0},
+ 583: {region: 0x164, script: 0x52, flags: 0x0},
+ 584: {region: 0x164, script: 0x52, flags: 0x0},
+ 585: {region: 0x98, script: 0x4a, flags: 0x0},
+ 586: {region: 0x164, script: 0x52, flags: 0x0},
+ 587: {region: 0xaa, script: 0x4b, flags: 0x0},
+ 588: {region: 0x105, script: 0x1e, flags: 0x0},
+ 589: {region: 0x98, script: 0x20, flags: 0x0},
+ 590: {region: 0x164, script: 0x52, flags: 0x0},
+ 591: {region: 0x74, script: 0x52, flags: 0x0},
+ 592: {region: 0x164, script: 0x52, flags: 0x0},
+ 593: {region: 0xb3, script: 0x52, flags: 0x0},
+ 594: {region: 0x164, script: 0x52, flags: 0x0},
+ 595: {region: 0x164, script: 0x52, flags: 0x0},
+ 596: {region: 0x164, script: 0x52, flags: 0x0},
+ 597: {region: 0x164, script: 0x52, flags: 0x0},
+ 598: {region: 0x164, script: 0x52, flags: 0x0},
+ 599: {region: 0x164, script: 0x52, flags: 0x0},
+ 600: {region: 0x164, script: 0x52, flags: 0x0},
+ 601: {region: 0x164, script: 0x27, flags: 0x0},
+ 603: {region: 0x105, script: 0x1e, flags: 0x0},
+ 604: {region: 0x111, script: 0x52, flags: 0x0},
+ 605: {region: 0xe6, script: 0x52, flags: 0x0},
+ 606: {region: 0x105, script: 0x52, flags: 0x0},
+ 607: {region: 0x164, script: 0x52, flags: 0x0},
+ 608: {region: 0x98, script: 0x20, flags: 0x0},
+ 609: {region: 0x98, script: 0x5, flags: 0x0},
+ 610: {region: 0x12e, script: 0x52, flags: 0x0},
+ 611: {region: 0x164, script: 0x52, flags: 0x0},
+ 612: {region: 0x51, script: 0x52, flags: 0x0},
+ 613: {region: 0x5f, script: 0x52, flags: 0x0},
+ 614: {region: 0x164, script: 0x52, flags: 0x0},
+ 615: {region: 0x164, script: 0x52, flags: 0x0},
+ 616: {region: 0x164, script: 0x27, flags: 0x0},
+ 617: {region: 0x164, script: 0x52, flags: 0x0},
+ 618: {region: 0x164, script: 0x52, flags: 0x0},
+ 619: {region: 0x1b, script: 0x3, flags: 0x1},
+ 620: {region: 0x164, script: 0x52, flags: 0x0},
+ 621: {region: 0x164, script: 0x52, flags: 0x0},
+ 622: {region: 0x164, script: 0x52, flags: 0x0},
+ 623: {region: 0x164, script: 0x52, flags: 0x0},
+ 624: {region: 0x105, script: 0x1e, flags: 0x0},
+ 625: {region: 0x164, script: 0x52, flags: 0x0},
+ 626: {region: 0x164, script: 0x52, flags: 0x0},
+ 627: {region: 0x164, script: 0x52, flags: 0x0},
+ 628: {region: 0x105, script: 0x1e, flags: 0x0},
+ 629: {region: 0x164, script: 0x52, flags: 0x0},
+ 630: {region: 0x94, script: 0x52, flags: 0x0},
+ 631: {region: 0xe7, script: 0x5, flags: 0x0},
+ 632: {region: 0x7a, script: 0x52, flags: 0x0},
+ 633: {region: 0x164, script: 0x52, flags: 0x0},
+ 634: {region: 0x164, script: 0x52, flags: 0x0},
+ 635: {region: 0x164, script: 0x52, flags: 0x0},
+ 636: {region: 0x164, script: 0x27, flags: 0x0},
+ 637: {region: 0x122, script: 0xd5, flags: 0x0},
+ 638: {region: 0xe7, script: 0x5, flags: 0x0},
+ 639: {region: 0x164, script: 0x52, flags: 0x0},
+ 640: {region: 0x164, script: 0x52, flags: 0x0},
+ 641: {region: 0x1e, script: 0x5, flags: 0x1},
+ 642: {region: 0x164, script: 0x52, flags: 0x0},
+ 643: {region: 0x164, script: 0x52, flags: 0x0},
+ 644: {region: 0x164, script: 0x52, flags: 0x0},
+ 645: {region: 0x137, script: 0x52, flags: 0x0},
+ 646: {region: 0x86, script: 0x56, flags: 0x0},
+ 647: {region: 0x96, script: 0x37, flags: 0x0},
+ 648: {region: 0x12e, script: 0x52, flags: 0x0},
+ 649: {region: 0xe7, script: 0x5, flags: 0x0},
+ 650: {region: 0x130, script: 0x52, flags: 0x0},
+ 651: {region: 0x164, script: 0x52, flags: 0x0},
+ 652: {region: 0xb6, script: 0x52, flags: 0x0},
+ 653: {region: 0x105, script: 0x1e, flags: 0x0},
+ 654: {region: 0x164, script: 0x52, flags: 0x0},
+ 655: {region: 0x94, script: 0x52, flags: 0x0},
+ 656: {region: 0x164, script: 0x52, flags: 0x0},
+ 657: {region: 0x52, script: 0xd5, flags: 0x0},
+ 658: {region: 0x164, script: 0x52, flags: 0x0},
+ 659: {region: 0x164, script: 0x52, flags: 0x0},
+ 660: {region: 0x164, script: 0x52, flags: 0x0},
+ 661: {region: 0x164, script: 0x52, flags: 0x0},
+ 662: {region: 0x98, script: 0x54, flags: 0x0},
+ 663: {region: 0x164, script: 0x52, flags: 0x0},
+ 664: {region: 0x164, script: 0x52, flags: 0x0},
+ 665: {region: 0x105, script: 0x1e, flags: 0x0},
+ 666: {region: 0x130, script: 0x52, flags: 0x0},
+ 667: {region: 0x164, script: 0x52, flags: 0x0},
+ 668: {region: 0xd8, script: 0x52, flags: 0x0},
+ 669: {region: 0x164, script: 0x52, flags: 0x0},
+ 670: {region: 0x164, script: 0x52, flags: 0x0},
+ 671: {region: 0x23, script: 0x2, flags: 0x1},
+ 672: {region: 0x164, script: 0x52, flags: 0x0},
+ 673: {region: 0x164, script: 0x52, flags: 0x0},
+ 674: {region: 0x9d, script: 0x52, flags: 0x0},
+ 675: {region: 0x52, script: 0x58, flags: 0x0},
+ 676: {region: 0x94, script: 0x52, flags: 0x0},
+ 677: {region: 0x9b, script: 0x5, flags: 0x0},
+ 678: {region: 0x134, script: 0x52, flags: 0x0},
+ 679: {region: 0x164, script: 0x52, flags: 0x0},
+ 680: {region: 0x164, script: 0x52, flags: 0x0},
+ 681: {region: 0x98, script: 0xd0, flags: 0x0},
+ 682: {region: 0x9d, script: 0x52, flags: 0x0},
+ 683: {region: 0x164, script: 0x52, flags: 0x0},
+ 684: {region: 0x4a, script: 0x52, flags: 0x0},
+ 685: {region: 0x164, script: 0x52, flags: 0x0},
+ 686: {region: 0x164, script: 0x52, flags: 0x0},
+ 687: {region: 0xae, script: 0x4f, flags: 0x0},
+ 688: {region: 0x164, script: 0x52, flags: 0x0},
+ 689: {region: 0x164, script: 0x52, flags: 0x0},
+ 690: {region: 0x4a, script: 0x52, flags: 0x0},
+ 691: {region: 0x164, script: 0x52, flags: 0x0},
+ 692: {region: 0x164, script: 0x52, flags: 0x0},
+ 693: {region: 0x161, script: 0x52, flags: 0x0},
+ 694: {region: 0x9b, script: 0x5, flags: 0x0},
+ 695: {region: 0xb5, script: 0x52, flags: 0x0},
+ 696: {region: 0xb7, script: 0x52, flags: 0x0},
+ 697: {region: 0x4a, script: 0x52, flags: 0x0},
+ 698: {region: 0x4a, script: 0x52, flags: 0x0},
+ 699: {region: 0xa3, script: 0x52, flags: 0x0},
+ 700: {region: 0xa3, script: 0x52, flags: 0x0},
+ 701: {region: 0x9b, script: 0x5, flags: 0x0},
+ 702: {region: 0xb7, script: 0x52, flags: 0x0},
+ 703: {region: 0x122, script: 0xd5, flags: 0x0},
+ 704: {region: 0x52, script: 0x34, flags: 0x0},
+ 705: {region: 0x12a, script: 0x52, flags: 0x0},
+ 706: {region: 0x94, script: 0x52, flags: 0x0},
+ 707: {region: 0x51, script: 0x52, flags: 0x0},
+ 708: {region: 0x98, script: 0x20, flags: 0x0},
+ 709: {region: 0x98, script: 0x20, flags: 0x0},
+ 710: {region: 0x94, script: 0x52, flags: 0x0},
+ 711: {region: 0x25, script: 0x3, flags: 0x1},
+ 712: {region: 0xa3, script: 0x52, flags: 0x0},
+ 713: {region: 0x164, script: 0x52, flags: 0x0},
+ 714: {region: 0xce, script: 0x52, flags: 0x0},
+ 715: {region: 0x164, script: 0x52, flags: 0x0},
+ 716: {region: 0x164, script: 0x52, flags: 0x0},
+ 717: {region: 0x164, script: 0x52, flags: 0x0},
+ 718: {region: 0x164, script: 0x52, flags: 0x0},
+ 719: {region: 0x164, script: 0x52, flags: 0x0},
+ 720: {region: 0x164, script: 0x52, flags: 0x0},
+ 721: {region: 0x164, script: 0x52, flags: 0x0},
+ 722: {region: 0x164, script: 0x52, flags: 0x0},
+ 723: {region: 0x164, script: 0x52, flags: 0x0},
+ 724: {region: 0x164, script: 0x52, flags: 0x0},
+ 725: {region: 0x164, script: 0x52, flags: 0x0},
+ 726: {region: 0x164, script: 0x5, flags: 0x0},
+ 727: {region: 0x105, script: 0x1e, flags: 0x0},
+ 728: {region: 0xe6, script: 0x52, flags: 0x0},
+ 729: {region: 0x164, script: 0x52, flags: 0x0},
+ 730: {region: 0x94, script: 0x52, flags: 0x0},
+ 731: {region: 0x164, script: 0x27, flags: 0x0},
+ 732: {region: 0x164, script: 0x52, flags: 0x0},
+ 733: {region: 0x164, script: 0x52, flags: 0x0},
+ 734: {region: 0x164, script: 0x52, flags: 0x0},
+ 735: {region: 0x111, script: 0x52, flags: 0x0},
+ 736: {region: 0xa3, script: 0x52, flags: 0x0},
+ 737: {region: 0x164, script: 0x52, flags: 0x0},
+ 738: {region: 0x164, script: 0x52, flags: 0x0},
+ 739: {region: 0x122, script: 0x5, flags: 0x0},
+ 740: {region: 0xcb, script: 0x52, flags: 0x0},
+ 741: {region: 0x164, script: 0x52, flags: 0x0},
+ 742: {region: 0x164, script: 0x52, flags: 0x0},
+ 743: {region: 0x164, script: 0x52, flags: 0x0},
+ 744: {region: 0xbe, script: 0x52, flags: 0x0},
+ 745: {region: 0xd0, script: 0x52, flags: 0x0},
+ 746: {region: 0x164, script: 0x52, flags: 0x0},
+ 747: {region: 0x51, script: 0x52, flags: 0x0},
+ 748: {region: 0xda, script: 0x20, flags: 0x0},
+ 749: {region: 0x12e, script: 0x52, flags: 0x0},
+ 750: {region: 0xbf, script: 0x52, flags: 0x0},
+ 751: {region: 0x164, script: 0x52, flags: 0x0},
+ 752: {region: 0x164, script: 0x52, flags: 0x0},
+ 753: {region: 0xdf, script: 0x52, flags: 0x0},
+ 754: {region: 0x164, script: 0x52, flags: 0x0},
+ 755: {region: 0x94, script: 0x52, flags: 0x0},
+ 756: {region: 0x9a, script: 0x36, flags: 0x0},
+ 757: {region: 0x164, script: 0x52, flags: 0x0},
+ 758: {region: 0xc1, script: 0x1e, flags: 0x0},
+ 759: {region: 0x164, script: 0x5, flags: 0x0},
+ 760: {region: 0x164, script: 0x52, flags: 0x0},
+ 761: {region: 0x164, script: 0x52, flags: 0x0},
+ 762: {region: 0x164, script: 0x52, flags: 0x0},
+ 763: {region: 0x98, script: 0x64, flags: 0x0},
+ 764: {region: 0x164, script: 0x52, flags: 0x0},
+ 765: {region: 0x164, script: 0x52, flags: 0x0},
+ 766: {region: 0x10a, script: 0x52, flags: 0x0},
+ 767: {region: 0x164, script: 0x52, flags: 0x0},
+ 768: {region: 0x164, script: 0x52, flags: 0x0},
+ 769: {region: 0x164, script: 0x52, flags: 0x0},
+ 770: {region: 0x28, script: 0x3, flags: 0x1},
+ 771: {region: 0x164, script: 0x52, flags: 0x0},
+ 772: {region: 0x164, script: 0x52, flags: 0x0},
+ 773: {region: 0x98, script: 0xe, flags: 0x0},
+ 774: {region: 0xc3, script: 0x6b, flags: 0x0},
+ 776: {region: 0x164, script: 0x52, flags: 0x0},
+ 777: {region: 0x48, script: 0x52, flags: 0x0},
+ 778: {region: 0x48, script: 0x52, flags: 0x0},
+ 779: {region: 0x36, script: 0x52, flags: 0x0},
+ 780: {region: 0x164, script: 0x52, flags: 0x0},
+ 781: {region: 0x164, script: 0x52, flags: 0x0},
+ 782: {region: 0x164, script: 0x52, flags: 0x0},
+ 783: {region: 0x164, script: 0x52, flags: 0x0},
+ 784: {region: 0x164, script: 0x52, flags: 0x0},
+ 785: {region: 0x164, script: 0x52, flags: 0x0},
+ 786: {region: 0x98, script: 0x20, flags: 0x0},
+ 787: {region: 0xda, script: 0x20, flags: 0x0},
+ 788: {region: 0x105, script: 0x1e, flags: 0x0},
+ 789: {region: 0x34, script: 0x68, flags: 0x0},
+ 790: {region: 0x2b, script: 0x3, flags: 0x1},
+ 791: {region: 0xca, script: 0x52, flags: 0x0},
+ 792: {region: 0x164, script: 0x52, flags: 0x0},
+ 793: {region: 0x164, script: 0x52, flags: 0x0},
+ 794: {region: 0x164, script: 0x52, flags: 0x0},
+ 795: {region: 0x98, script: 0x20, flags: 0x0},
+ 796: {region: 0x51, script: 0x52, flags: 0x0},
+ 798: {region: 0x164, script: 0x52, flags: 0x0},
+ 799: {region: 0x134, script: 0x52, flags: 0x0},
+ 800: {region: 0x164, script: 0x52, flags: 0x0},
+ 801: {region: 0x164, script: 0x52, flags: 0x0},
+ 802: {region: 0xe7, script: 0x5, flags: 0x0},
+ 803: {region: 0xc2, script: 0x52, flags: 0x0},
+ 804: {region: 0x98, script: 0x20, flags: 0x0},
+ 805: {region: 0x94, script: 0x52, flags: 0x0},
+ 806: {region: 0x163, script: 0x52, flags: 0x0},
+ 807: {region: 0x164, script: 0x52, flags: 0x0},
+ 808: {region: 0xc3, script: 0x6b, flags: 0x0},
+ 809: {region: 0x164, script: 0x52, flags: 0x0},
+ 810: {region: 0x164, script: 0x27, flags: 0x0},
+ 811: {region: 0x105, script: 0x1e, flags: 0x0},
+ 812: {region: 0x164, script: 0x52, flags: 0x0},
+ 813: {region: 0x130, script: 0x52, flags: 0x0},
+ 814: {region: 0x9b, script: 0x5d, flags: 0x0},
+ 815: {region: 0x164, script: 0x52, flags: 0x0},
+ 816: {region: 0x164, script: 0x52, flags: 0x0},
+ 817: {region: 0x9b, script: 0x5, flags: 0x0},
+ 818: {region: 0x164, script: 0x52, flags: 0x0},
+ 819: {region: 0x164, script: 0x52, flags: 0x0},
+ 820: {region: 0x164, script: 0x52, flags: 0x0},
+ 821: {region: 0xdc, script: 0x52, flags: 0x0},
+ 822: {region: 0x164, script: 0x52, flags: 0x0},
+ 823: {region: 0x164, script: 0x52, flags: 0x0},
+ 825: {region: 0x164, script: 0x52, flags: 0x0},
+ 826: {region: 0x52, script: 0x34, flags: 0x0},
+ 827: {region: 0x9d, script: 0x52, flags: 0x0},
+ 828: {region: 0xd1, script: 0x52, flags: 0x0},
+ 829: {region: 0x164, script: 0x52, flags: 0x0},
+ 830: {region: 0xd9, script: 0x52, flags: 0x0},
+ 831: {region: 0x164, script: 0x52, flags: 0x0},
+ 832: {region: 0x164, script: 0x52, flags: 0x0},
+ 833: {region: 0x164, script: 0x52, flags: 0x0},
+ 834: {region: 0xce, script: 0x52, flags: 0x0},
+ 835: {region: 0x164, script: 0x52, flags: 0x0},
+ 836: {region: 0x164, script: 0x52, flags: 0x0},
+ 837: {region: 0x163, script: 0x52, flags: 0x0},
+ 838: {region: 0xd0, script: 0x52, flags: 0x0},
+ 839: {region: 0x5f, script: 0x52, flags: 0x0},
+ 840: {region: 0xda, script: 0x20, flags: 0x0},
+ 841: {region: 0x164, script: 0x52, flags: 0x0},
+ 842: {region: 0xda, script: 0x20, flags: 0x0},
+ 843: {region: 0x164, script: 0x52, flags: 0x0},
+ 844: {region: 0x164, script: 0x52, flags: 0x0},
+ 845: {region: 0xd1, script: 0x52, flags: 0x0},
+ 846: {region: 0x164, script: 0x52, flags: 0x0},
+ 847: {region: 0x164, script: 0x52, flags: 0x0},
+ 848: {region: 0xd0, script: 0x52, flags: 0x0},
+ 849: {region: 0x164, script: 0x52, flags: 0x0},
+ 850: {region: 0xce, script: 0x52, flags: 0x0},
+ 851: {region: 0xce, script: 0x52, flags: 0x0},
+ 852: {region: 0x164, script: 0x52, flags: 0x0},
+ 853: {region: 0x164, script: 0x52, flags: 0x0},
+ 854: {region: 0x94, script: 0x52, flags: 0x0},
+ 855: {region: 0x164, script: 0x52, flags: 0x0},
+ 856: {region: 0xde, script: 0x52, flags: 0x0},
+ 857: {region: 0x164, script: 0x52, flags: 0x0},
+ 858: {region: 0x164, script: 0x52, flags: 0x0},
+ 859: {region: 0x98, script: 0x52, flags: 0x0},
+ 860: {region: 0x164, script: 0x52, flags: 0x0},
+ 861: {region: 0x164, script: 0x52, flags: 0x0},
+ 862: {region: 0xd8, script: 0x52, flags: 0x0},
+ 863: {region: 0x51, script: 0x52, flags: 0x0},
+ 864: {region: 0x164, script: 0x52, flags: 0x0},
+ 865: {region: 0xd9, script: 0x52, flags: 0x0},
+ 866: {region: 0x164, script: 0x52, flags: 0x0},
+ 867: {region: 0x51, script: 0x52, flags: 0x0},
+ 868: {region: 0x164, script: 0x52, flags: 0x0},
+ 869: {region: 0x164, script: 0x52, flags: 0x0},
+ 870: {region: 0xd9, script: 0x52, flags: 0x0},
+ 871: {region: 0x122, script: 0x4e, flags: 0x0},
+ 872: {region: 0x98, script: 0x20, flags: 0x0},
+ 873: {region: 0x10b, script: 0xb7, flags: 0x0},
+ 874: {region: 0x164, script: 0x52, flags: 0x0},
+ 875: {region: 0x164, script: 0x52, flags: 0x0},
+ 876: {region: 0x83, script: 0x70, flags: 0x0},
+ 877: {region: 0x160, script: 0x52, flags: 0x0},
+ 878: {region: 0x164, script: 0x52, flags: 0x0},
+ 879: {region: 0x48, script: 0x17, flags: 0x0},
+ 880: {region: 0x164, script: 0x52, flags: 0x0},
+ 881: {region: 0x160, script: 0x52, flags: 0x0},
+ 882: {region: 0x164, script: 0x52, flags: 0x0},
+ 883: {region: 0x164, script: 0x52, flags: 0x0},
+ 884: {region: 0x164, script: 0x52, flags: 0x0},
+ 885: {region: 0x164, script: 0x52, flags: 0x0},
+ 886: {region: 0x164, script: 0x52, flags: 0x0},
+ 887: {region: 0x116, script: 0x52, flags: 0x0},
+ 888: {region: 0x164, script: 0x52, flags: 0x0},
+ 889: {region: 0x164, script: 0x52, flags: 0x0},
+ 890: {region: 0x134, script: 0x52, flags: 0x0},
+ 891: {region: 0x164, script: 0x52, flags: 0x0},
+ 892: {region: 0x52, script: 0x52, flags: 0x0},
+ 893: {region: 0x164, script: 0x52, flags: 0x0},
+ 894: {region: 0xcd, script: 0x52, flags: 0x0},
+ 895: {region: 0x12e, script: 0x52, flags: 0x0},
+ 896: {region: 0x130, script: 0x52, flags: 0x0},
+ 897: {region: 0x7f, script: 0x52, flags: 0x0},
+ 898: {region: 0x77, script: 0x52, flags: 0x0},
+ 899: {region: 0x164, script: 0x52, flags: 0x0},
+ 901: {region: 0x164, script: 0x52, flags: 0x0},
+ 902: {region: 0x164, script: 0x52, flags: 0x0},
+ 903: {region: 0x6e, script: 0x52, flags: 0x0},
+ 904: {region: 0x164, script: 0x52, flags: 0x0},
+ 905: {region: 0x164, script: 0x52, flags: 0x0},
+ 906: {region: 0x164, script: 0x52, flags: 0x0},
+ 907: {region: 0x164, script: 0x52, flags: 0x0},
+ 908: {region: 0x98, script: 0x75, flags: 0x0},
+ 909: {region: 0x164, script: 0x52, flags: 0x0},
+ 910: {region: 0x164, script: 0x5, flags: 0x0},
+ 911: {region: 0x7c, script: 0x1e, flags: 0x0},
+ 912: {region: 0x134, script: 0x76, flags: 0x0},
+ 913: {region: 0x164, script: 0x5, flags: 0x0},
+ 914: {region: 0xc4, script: 0x74, flags: 0x0},
+ 915: {region: 0x164, script: 0x52, flags: 0x0},
+ 916: {region: 0x2e, script: 0x3, flags: 0x1},
+ 917: {region: 0xe6, script: 0x52, flags: 0x0},
+ 918: {region: 0x31, script: 0x2, flags: 0x1},
+ 919: {region: 0xe6, script: 0x52, flags: 0x0},
+ 920: {region: 0x2f, script: 0x52, flags: 0x0},
+ 921: {region: 0xef, script: 0x52, flags: 0x0},
+ 922: {region: 0x164, script: 0x52, flags: 0x0},
+ 923: {region: 0x77, script: 0x52, flags: 0x0},
+ 924: {region: 0xd5, script: 0x52, flags: 0x0},
+ 925: {region: 0x134, script: 0x52, flags: 0x0},
+ 926: {region: 0x48, script: 0x52, flags: 0x0},
+ 927: {region: 0x164, script: 0x52, flags: 0x0},
+ 928: {region: 0x9b, script: 0xdd, flags: 0x0},
+ 929: {region: 0x164, script: 0x52, flags: 0x0},
+ 930: {region: 0x5f, script: 0x52, flags: 0x0},
+ 931: {region: 0x164, script: 0x5, flags: 0x0},
+ 932: {region: 0xaf, script: 0x7f, flags: 0x0},
+ 934: {region: 0x164, script: 0x52, flags: 0x0},
+ 935: {region: 0x164, script: 0x52, flags: 0x0},
+ 936: {region: 0x98, script: 0x12, flags: 0x0},
+ 937: {region: 0xa3, script: 0x52, flags: 0x0},
+ 938: {region: 0xe8, script: 0x52, flags: 0x0},
+ 939: {region: 0x164, script: 0x52, flags: 0x0},
+ 940: {region: 0x9d, script: 0x52, flags: 0x0},
+ 941: {region: 0x164, script: 0x52, flags: 0x0},
+ 942: {region: 0x164, script: 0x52, flags: 0x0},
+ 943: {region: 0x86, script: 0x2d, flags: 0x0},
+ 944: {region: 0x74, script: 0x52, flags: 0x0},
+ 945: {region: 0x164, script: 0x52, flags: 0x0},
+ 946: {region: 0xe7, script: 0x45, flags: 0x0},
+ 947: {region: 0x9b, script: 0x5, flags: 0x0},
+ 948: {region: 0x1, script: 0x52, flags: 0x0},
+ 949: {region: 0x23, script: 0x5, flags: 0x0},
+ 950: {region: 0x164, script: 0x52, flags: 0x0},
+ 951: {region: 0x40, script: 0x52, flags: 0x0},
+ 952: {region: 0x164, script: 0x52, flags: 0x0},
+ 953: {region: 0x79, script: 0x52, flags: 0x0},
+ 954: {region: 0x164, script: 0x52, flags: 0x0},
+ 955: {region: 0xe3, script: 0x52, flags: 0x0},
+ 956: {region: 0x88, script: 0x52, flags: 0x0},
+ 957: {region: 0x68, script: 0x52, flags: 0x0},
+ 958: {region: 0x164, script: 0x52, flags: 0x0},
+ 959: {region: 0x98, script: 0x20, flags: 0x0},
+ 960: {region: 0x164, script: 0x52, flags: 0x0},
+ 961: {region: 0x101, script: 0x52, flags: 0x0},
+ 962: {region: 0x94, script: 0x52, flags: 0x0},
+ 963: {region: 0x164, script: 0x52, flags: 0x0},
+ 964: {region: 0x164, script: 0x52, flags: 0x0},
+ 965: {region: 0x9d, script: 0x52, flags: 0x0},
+ 966: {region: 0x164, script: 0x5, flags: 0x0},
+ 967: {region: 0x98, script: 0x52, flags: 0x0},
+ 968: {region: 0x33, script: 0x2, flags: 0x1},
+ 969: {region: 0xda, script: 0x20, flags: 0x0},
+ 970: {region: 0x34, script: 0xe, flags: 0x0},
+ 971: {region: 0x4d, script: 0x52, flags: 0x0},
+ 972: {region: 0x71, script: 0x52, flags: 0x0},
+ 973: {region: 0x4d, script: 0x52, flags: 0x0},
+ 974: {region: 0x9b, script: 0x5, flags: 0x0},
+ 975: {region: 0x10b, script: 0x52, flags: 0x0},
+ 976: {region: 0x39, script: 0x52, flags: 0x0},
+ 977: {region: 0x164, script: 0x52, flags: 0x0},
+ 978: {region: 0xd0, script: 0x52, flags: 0x0},
+ 979: {region: 0x103, script: 0x52, flags: 0x0},
+ 980: {region: 0x94, script: 0x52, flags: 0x0},
+ 981: {region: 0x12e, script: 0x52, flags: 0x0},
+ 982: {region: 0x164, script: 0x52, flags: 0x0},
+ 983: {region: 0x164, script: 0x52, flags: 0x0},
+ 984: {region: 0x72, script: 0x52, flags: 0x0},
+ 985: {region: 0x105, script: 0x1e, flags: 0x0},
+ 986: {region: 0x12f, script: 0x1e, flags: 0x0},
+ 987: {region: 0x108, script: 0x52, flags: 0x0},
+ 988: {region: 0x106, script: 0x52, flags: 0x0},
+ 989: {region: 0x12e, script: 0x52, flags: 0x0},
+ 990: {region: 0x164, script: 0x52, flags: 0x0},
+ 991: {region: 0xa1, script: 0x44, flags: 0x0},
+ 992: {region: 0x98, script: 0x20, flags: 0x0},
+ 993: {region: 0x7f, script: 0x52, flags: 0x0},
+ 994: {region: 0x105, script: 0x1e, flags: 0x0},
+ 995: {region: 0xa3, script: 0x52, flags: 0x0},
+ 996: {region: 0x94, script: 0x52, flags: 0x0},
+ 997: {region: 0x98, script: 0x52, flags: 0x0},
+ 998: {region: 0x98, script: 0xbb, flags: 0x0},
+ 999: {region: 0x164, script: 0x52, flags: 0x0},
+ 1000: {region: 0x164, script: 0x52, flags: 0x0},
+ 1001: {region: 0x12e, script: 0x52, flags: 0x0},
+ 1002: {region: 0x9d, script: 0x52, flags: 0x0},
+ 1003: {region: 0x98, script: 0x20, flags: 0x0},
+ 1004: {region: 0x164, script: 0x5, flags: 0x0},
+ 1005: {region: 0x9d, script: 0x52, flags: 0x0},
+ 1006: {region: 0x7a, script: 0x52, flags: 0x0},
+ 1007: {region: 0x48, script: 0x52, flags: 0x0},
+ 1008: {region: 0x35, script: 0x4, flags: 0x1},
+ 1009: {region: 0x9d, script: 0x52, flags: 0x0},
+ 1010: {region: 0x9b, script: 0x5, flags: 0x0},
+ 1011: {region: 0xd9, script: 0x52, flags: 0x0},
+ 1012: {region: 0x4e, script: 0x52, flags: 0x0},
+ 1013: {region: 0xd0, script: 0x52, flags: 0x0},
+ 1014: {region: 0xce, script: 0x52, flags: 0x0},
+ 1015: {region: 0xc2, script: 0x52, flags: 0x0},
+ 1016: {region: 0x4b, script: 0x52, flags: 0x0},
+ 1017: {region: 0x95, script: 0x72, flags: 0x0},
+ 1018: {region: 0xb5, script: 0x52, flags: 0x0},
+ 1019: {region: 0x164, script: 0x27, flags: 0x0},
+ 1020: {region: 0x164, script: 0x52, flags: 0x0},
+ 1022: {region: 0xb9, script: 0xd2, flags: 0x0},
+ 1023: {region: 0x164, script: 0x52, flags: 0x0},
+ 1024: {region: 0xc3, script: 0x6b, flags: 0x0},
+ 1025: {region: 0x164, script: 0x5, flags: 0x0},
+ 1026: {region: 0xb2, script: 0xc1, flags: 0x0},
+ 1027: {region: 0x6e, script: 0x52, flags: 0x0},
+ 1028: {region: 0x164, script: 0x52, flags: 0x0},
+ 1029: {region: 0x164, script: 0x52, flags: 0x0},
+ 1030: {region: 0x164, script: 0x52, flags: 0x0},
+ 1031: {region: 0x164, script: 0x52, flags: 0x0},
+ 1032: {region: 0x110, script: 0x52, flags: 0x0},
+ 1033: {region: 0x164, script: 0x52, flags: 0x0},
+ 1034: {region: 0xe7, script: 0x5, flags: 0x0},
+ 1035: {region: 0x164, script: 0x52, flags: 0x0},
+ 1036: {region: 0x10e, script: 0x52, flags: 0x0},
+ 1037: {region: 0x164, script: 0x52, flags: 0x0},
+ 1038: {region: 0xe8, script: 0x52, flags: 0x0},
+ 1039: {region: 0x164, script: 0x52, flags: 0x0},
+ 1040: {region: 0x94, script: 0x52, flags: 0x0},
+ 1041: {region: 0x141, script: 0x52, flags: 0x0},
+ 1042: {region: 0x10b, script: 0x52, flags: 0x0},
+ 1044: {region: 0x10b, script: 0x52, flags: 0x0},
+ 1045: {region: 0x71, script: 0x52, flags: 0x0},
+ 1046: {region: 0x96, script: 0xb8, flags: 0x0},
+ 1047: {region: 0x164, script: 0x52, flags: 0x0},
+ 1048: {region: 0x71, script: 0x52, flags: 0x0},
+ 1049: {region: 0x163, script: 0x52, flags: 0x0},
+ 1050: {region: 0x164, script: 0x52, flags: 0x0},
+ 1051: {region: 0xc2, script: 0x52, flags: 0x0},
+ 1052: {region: 0x164, script: 0x52, flags: 0x0},
+ 1053: {region: 0x164, script: 0x52, flags: 0x0},
+ 1054: {region: 0x164, script: 0x52, flags: 0x0},
+ 1055: {region: 0x114, script: 0x52, flags: 0x0},
+ 1056: {region: 0x164, script: 0x52, flags: 0x0},
+ 1057: {region: 0x164, script: 0x52, flags: 0x0},
+ 1058: {region: 0x122, script: 0xd5, flags: 0x0},
+ 1059: {region: 0x164, script: 0x52, flags: 0x0},
+ 1060: {region: 0x164, script: 0x52, flags: 0x0},
+ 1061: {region: 0x164, script: 0x52, flags: 0x0},
+ 1062: {region: 0x164, script: 0x52, flags: 0x0},
+ 1063: {region: 0x26, script: 0x52, flags: 0x0},
+ 1064: {region: 0x39, script: 0x5, flags: 0x1},
+ 1065: {region: 0x98, script: 0xc2, flags: 0x0},
+ 1066: {region: 0x115, script: 0x52, flags: 0x0},
+ 1067: {region: 0x113, script: 0x52, flags: 0x0},
+ 1068: {region: 0x98, script: 0x20, flags: 0x0},
+ 1069: {region: 0x160, script: 0x52, flags: 0x0},
+ 1070: {region: 0x164, script: 0x52, flags: 0x0},
+ 1071: {region: 0x164, script: 0x52, flags: 0x0},
+ 1072: {region: 0x6c, script: 0x52, flags: 0x0},
+ 1073: {region: 0x160, script: 0x52, flags: 0x0},
+ 1074: {region: 0x164, script: 0x52, flags: 0x0},
+ 1075: {region: 0x5f, script: 0x52, flags: 0x0},
+ 1076: {region: 0x94, script: 0x52, flags: 0x0},
+ 1077: {region: 0x164, script: 0x52, flags: 0x0},
+ 1078: {region: 0x164, script: 0x52, flags: 0x0},
+ 1079: {region: 0x12e, script: 0x52, flags: 0x0},
+ 1080: {region: 0x164, script: 0x52, flags: 0x0},
+ 1081: {region: 0x83, script: 0x52, flags: 0x0},
+ 1082: {region: 0x10b, script: 0x52, flags: 0x0},
+ 1083: {region: 0x12e, script: 0x52, flags: 0x0},
+ 1084: {region: 0x15e, script: 0x5, flags: 0x0},
+ 1085: {region: 0x4a, script: 0x52, flags: 0x0},
+ 1086: {region: 0x5f, script: 0x52, flags: 0x0},
+ 1087: {region: 0x164, script: 0x52, flags: 0x0},
+ 1088: {region: 0x98, script: 0x20, flags: 0x0},
+ 1089: {region: 0x94, script: 0x52, flags: 0x0},
+ 1090: {region: 0x164, script: 0x52, flags: 0x0},
+ 1091: {region: 0x34, script: 0xe, flags: 0x0},
+ 1092: {region: 0x9a, script: 0xc5, flags: 0x0},
+ 1093: {region: 0xe8, script: 0x52, flags: 0x0},
+ 1094: {region: 0x98, script: 0xcd, flags: 0x0},
+ 1095: {region: 0xda, script: 0x20, flags: 0x0},
+ 1096: {region: 0x164, script: 0x52, flags: 0x0},
+ 1097: {region: 0x164, script: 0x52, flags: 0x0},
+ 1098: {region: 0x164, script: 0x52, flags: 0x0},
+ 1099: {region: 0x164, script: 0x52, flags: 0x0},
+ 1100: {region: 0x164, script: 0x52, flags: 0x0},
+ 1101: {region: 0x164, script: 0x52, flags: 0x0},
+ 1102: {region: 0x164, script: 0x52, flags: 0x0},
+ 1103: {region: 0x164, script: 0x52, flags: 0x0},
+ 1104: {region: 0xe6, script: 0x52, flags: 0x0},
+ 1105: {region: 0x164, script: 0x52, flags: 0x0},
+ 1106: {region: 0x164, script: 0x52, flags: 0x0},
+ 1107: {region: 0x98, script: 0x4a, flags: 0x0},
+ 1108: {region: 0x52, script: 0xcb, flags: 0x0},
+ 1109: {region: 0xda, script: 0x20, flags: 0x0},
+ 1110: {region: 0xda, script: 0x20, flags: 0x0},
+ 1111: {region: 0x98, script: 0xd0, flags: 0x0},
+ 1112: {region: 0x164, script: 0x52, flags: 0x0},
+ 1113: {region: 0x111, script: 0x52, flags: 0x0},
+ 1114: {region: 0x130, script: 0x52, flags: 0x0},
+ 1115: {region: 0x125, script: 0x52, flags: 0x0},
+ 1116: {region: 0x164, script: 0x52, flags: 0x0},
+ 1117: {region: 0x3e, script: 0x3, flags: 0x1},
+ 1118: {region: 0x164, script: 0x52, flags: 0x0},
+ 1119: {region: 0x164, script: 0x52, flags: 0x0},
+ 1120: {region: 0x164, script: 0x52, flags: 0x0},
+ 1121: {region: 0x122, script: 0xd5, flags: 0x0},
+ 1122: {region: 0xda, script: 0x20, flags: 0x0},
+ 1123: {region: 0xda, script: 0x20, flags: 0x0},
+ 1124: {region: 0xda, script: 0x20, flags: 0x0},
+ 1125: {region: 0x6e, script: 0x27, flags: 0x0},
+ 1126: {region: 0x164, script: 0x52, flags: 0x0},
+ 1127: {region: 0x6c, script: 0x27, flags: 0x0},
+ 1128: {region: 0x164, script: 0x52, flags: 0x0},
+ 1129: {region: 0x164, script: 0x52, flags: 0x0},
+ 1130: {region: 0x164, script: 0x52, flags: 0x0},
+ 1131: {region: 0xd5, script: 0x52, flags: 0x0},
+ 1132: {region: 0x126, script: 0x52, flags: 0x0},
+ 1133: {region: 0x124, script: 0x52, flags: 0x0},
+ 1134: {region: 0x31, script: 0x52, flags: 0x0},
+ 1135: {region: 0xda, script: 0x20, flags: 0x0},
+ 1136: {region: 0xe6, script: 0x52, flags: 0x0},
+ 1137: {region: 0x164, script: 0x52, flags: 0x0},
+ 1138: {region: 0x164, script: 0x52, flags: 0x0},
+ 1139: {region: 0x31, script: 0x52, flags: 0x0},
+ 1140: {region: 0xd3, script: 0x52, flags: 0x0},
+ 1141: {region: 0x164, script: 0x52, flags: 0x0},
+ 1142: {region: 0x160, script: 0x52, flags: 0x0},
+ 1143: {region: 0x164, script: 0x52, flags: 0x0},
+ 1144: {region: 0x128, script: 0x52, flags: 0x0},
+ 1145: {region: 0x164, script: 0x52, flags: 0x0},
+ 1146: {region: 0xcd, script: 0x52, flags: 0x0},
+ 1147: {region: 0x164, script: 0x52, flags: 0x0},
+ 1148: {region: 0xe5, script: 0x52, flags: 0x0},
+ 1149: {region: 0x164, script: 0x52, flags: 0x0},
+ 1150: {region: 0x164, script: 0x52, flags: 0x0},
+ 1151: {region: 0x164, script: 0x52, flags: 0x0},
+ 1152: {region: 0x12a, script: 0x52, flags: 0x0},
+ 1153: {region: 0x12a, script: 0x52, flags: 0x0},
+ 1154: {region: 0x12d, script: 0x52, flags: 0x0},
+ 1155: {region: 0x164, script: 0x5, flags: 0x0},
+ 1156: {region: 0x160, script: 0x52, flags: 0x0},
+ 1157: {region: 0x86, script: 0x2d, flags: 0x0},
+ 1158: {region: 0xda, script: 0x20, flags: 0x0},
+ 1159: {region: 0xe6, script: 0x52, flags: 0x0},
+ 1160: {region: 0x42, script: 0xd6, flags: 0x0},
+ 1161: {region: 0x164, script: 0x52, flags: 0x0},
+ 1162: {region: 0x105, script: 0x1e, flags: 0x0},
+ 1163: {region: 0x164, script: 0x52, flags: 0x0},
+ 1164: {region: 0x164, script: 0x52, flags: 0x0},
+ 1165: {region: 0x130, script: 0x52, flags: 0x0},
+ 1166: {region: 0x164, script: 0x52, flags: 0x0},
+ 1167: {region: 0x122, script: 0xd5, flags: 0x0},
+ 1168: {region: 0x31, script: 0x52, flags: 0x0},
+ 1169: {region: 0x164, script: 0x52, flags: 0x0},
+ 1170: {region: 0x164, script: 0x52, flags: 0x0},
+ 1171: {region: 0xcd, script: 0x52, flags: 0x0},
+ 1172: {region: 0x164, script: 0x52, flags: 0x0},
+ 1173: {region: 0x164, script: 0x52, flags: 0x0},
+ 1174: {region: 0x12c, script: 0x52, flags: 0x0},
+ 1175: {region: 0x164, script: 0x52, flags: 0x0},
+ 1177: {region: 0x164, script: 0x52, flags: 0x0},
+ 1178: {region: 0xd3, script: 0x52, flags: 0x0},
+ 1179: {region: 0x52, script: 0xce, flags: 0x0},
+ 1180: {region: 0xe4, script: 0x52, flags: 0x0},
+ 1181: {region: 0x164, script: 0x52, flags: 0x0},
+ 1182: {region: 0x105, script: 0x1e, flags: 0x0},
+ 1183: {region: 0xb9, script: 0x52, flags: 0x0},
+ 1184: {region: 0x164, script: 0x52, flags: 0x0},
+ 1185: {region: 0x105, script: 0x1e, flags: 0x0},
+ 1186: {region: 0x41, script: 0x4, flags: 0x1},
+ 1187: {region: 0x11b, script: 0xd8, flags: 0x0},
+ 1188: {region: 0x12f, script: 0x1e, flags: 0x0},
+ 1189: {region: 0x74, script: 0x52, flags: 0x0},
+ 1190: {region: 0x29, script: 0x52, flags: 0x0},
+ 1192: {region: 0x45, script: 0x3, flags: 0x1},
+ 1193: {region: 0x98, script: 0xe, flags: 0x0},
+ 1194: {region: 0xe7, script: 0x5, flags: 0x0},
+ 1195: {region: 0x164, script: 0x52, flags: 0x0},
+ 1196: {region: 0x164, script: 0x52, flags: 0x0},
+ 1197: {region: 0x164, script: 0x52, flags: 0x0},
+ 1198: {region: 0x164, script: 0x52, flags: 0x0},
+ 1199: {region: 0x164, script: 0x52, flags: 0x0},
+ 1200: {region: 0x164, script: 0x52, flags: 0x0},
+ 1201: {region: 0x164, script: 0x52, flags: 0x0},
+ 1202: {region: 0x48, script: 0x4, flags: 0x1},
+ 1203: {region: 0x164, script: 0x52, flags: 0x0},
+ 1204: {region: 0xb3, script: 0xd9, flags: 0x0},
+ 1205: {region: 0x164, script: 0x52, flags: 0x0},
+ 1206: {region: 0x160, script: 0x52, flags: 0x0},
+ 1207: {region: 0x9d, script: 0x52, flags: 0x0},
+ 1208: {region: 0x105, script: 0x52, flags: 0x0},
+ 1209: {region: 0x13d, script: 0x52, flags: 0x0},
+ 1210: {region: 0x11a, script: 0x52, flags: 0x0},
+ 1211: {region: 0x164, script: 0x52, flags: 0x0},
+ 1212: {region: 0x35, script: 0x52, flags: 0x0},
+ 1213: {region: 0x5f, script: 0x52, flags: 0x0},
+ 1214: {region: 0xd0, script: 0x52, flags: 0x0},
+ 1215: {region: 0x1, script: 0x52, flags: 0x0},
+ 1216: {region: 0x105, script: 0x52, flags: 0x0},
+ 1217: {region: 0x69, script: 0x52, flags: 0x0},
+ 1218: {region: 0x12e, script: 0x52, flags: 0x0},
+ 1219: {region: 0x164, script: 0x52, flags: 0x0},
+ 1220: {region: 0x35, script: 0x52, flags: 0x0},
+ 1221: {region: 0x4d, script: 0x52, flags: 0x0},
+ 1222: {region: 0x164, script: 0x52, flags: 0x0},
+ 1223: {region: 0x6e, script: 0x27, flags: 0x0},
+ 1224: {region: 0x164, script: 0x52, flags: 0x0},
+ 1225: {region: 0xe6, script: 0x52, flags: 0x0},
+ 1226: {region: 0x2e, script: 0x52, flags: 0x0},
+ 1227: {region: 0x98, script: 0xd0, flags: 0x0},
+ 1228: {region: 0x98, script: 0x20, flags: 0x0},
+ 1229: {region: 0x164, script: 0x52, flags: 0x0},
+ 1230: {region: 0x164, script: 0x52, flags: 0x0},
+ 1231: {region: 0x164, script: 0x52, flags: 0x0},
+ 1232: {region: 0x164, script: 0x52, flags: 0x0},
+ 1233: {region: 0x164, script: 0x52, flags: 0x0},
+ 1234: {region: 0x164, script: 0x52, flags: 0x0},
+ 1235: {region: 0x164, script: 0x52, flags: 0x0},
+ 1236: {region: 0x164, script: 0x52, flags: 0x0},
+ 1237: {region: 0x164, script: 0x52, flags: 0x0},
+ 1238: {region: 0x13f, script: 0x52, flags: 0x0},
+ 1239: {region: 0x164, script: 0x52, flags: 0x0},
+ 1240: {region: 0x164, script: 0x52, flags: 0x0},
+ 1241: {region: 0xa7, script: 0x5, flags: 0x0},
+ 1242: {region: 0x164, script: 0x52, flags: 0x0},
+ 1243: {region: 0x113, script: 0x52, flags: 0x0},
+ 1244: {region: 0x164, script: 0x52, flags: 0x0},
+ 1245: {region: 0x164, script: 0x52, flags: 0x0},
+ 1246: {region: 0x164, script: 0x52, flags: 0x0},
+ 1247: {region: 0x164, script: 0x52, flags: 0x0},
+ 1248: {region: 0x98, script: 0x20, flags: 0x0},
+ 1249: {region: 0x52, script: 0x34, flags: 0x0},
+ 1250: {region: 0x164, script: 0x52, flags: 0x0},
+ 1251: {region: 0x164, script: 0x52, flags: 0x0},
+ 1252: {region: 0x40, script: 0x52, flags: 0x0},
+ 1253: {region: 0x164, script: 0x52, flags: 0x0},
+ 1254: {region: 0x12a, script: 0x18, flags: 0x0},
+ 1255: {region: 0x164, script: 0x52, flags: 0x0},
+ 1256: {region: 0x160, script: 0x52, flags: 0x0},
+ 1257: {region: 0x164, script: 0x52, flags: 0x0},
+ 1258: {region: 0x12a, script: 0x5a, flags: 0x0},
+ 1259: {region: 0x12a, script: 0x5b, flags: 0x0},
+ 1260: {region: 0x7c, script: 0x29, flags: 0x0},
+ 1261: {region: 0x52, script: 0x5e, flags: 0x0},
+ 1262: {region: 0x10a, script: 0x62, flags: 0x0},
+ 1263: {region: 0x107, script: 0x6c, flags: 0x0},
+ 1264: {region: 0x98, script: 0x20, flags: 0x0},
+ 1265: {region: 0x130, script: 0x52, flags: 0x0},
+ 1266: {region: 0x164, script: 0x52, flags: 0x0},
+ 1267: {region: 0x9b, script: 0x82, flags: 0x0},
+ 1268: {region: 0x164, script: 0x52, flags: 0x0},
+ 1269: {region: 0x15d, script: 0xba, flags: 0x0},
+ 1270: {region: 0x164, script: 0x52, flags: 0x0},
+ 1271: {region: 0x164, script: 0x52, flags: 0x0},
+ 1272: {region: 0xda, script: 0x20, flags: 0x0},
+ 1273: {region: 0x164, script: 0x52, flags: 0x0},
+ 1274: {region: 0x164, script: 0x52, flags: 0x0},
+ 1275: {region: 0xd0, script: 0x52, flags: 0x0},
+ 1276: {region: 0x74, script: 0x52, flags: 0x0},
+ 1277: {region: 0x164, script: 0x52, flags: 0x0},
+ 1278: {region: 0x164, script: 0x52, flags: 0x0},
+ 1279: {region: 0x51, script: 0x52, flags: 0x0},
+ 1280: {region: 0x164, script: 0x52, flags: 0x0},
+ 1281: {region: 0x164, script: 0x52, flags: 0x0},
+ 1282: {region: 0x164, script: 0x52, flags: 0x0},
+ 1283: {region: 0x51, script: 0x52, flags: 0x0},
+ 1284: {region: 0x164, script: 0x52, flags: 0x0},
+ 1285: {region: 0x164, script: 0x52, flags: 0x0},
+ 1286: {region: 0x164, script: 0x52, flags: 0x0},
+ 1287: {region: 0x164, script: 0x52, flags: 0x0},
+ 1288: {region: 0x1, script: 0x37, flags: 0x0},
+ 1289: {region: 0x164, script: 0x52, flags: 0x0},
+ 1290: {region: 0x164, script: 0x52, flags: 0x0},
+ 1291: {region: 0x164, script: 0x52, flags: 0x0},
+ 1292: {region: 0x164, script: 0x52, flags: 0x0},
+ 1293: {region: 0x164, script: 0x52, flags: 0x0},
+ 1294: {region: 0xd5, script: 0x52, flags: 0x0},
+ 1295: {region: 0x164, script: 0x52, flags: 0x0},
+ 1296: {region: 0x164, script: 0x52, flags: 0x0},
+ 1297: {region: 0x164, script: 0x52, flags: 0x0},
+ 1298: {region: 0x40, script: 0x52, flags: 0x0},
+ 1299: {region: 0x164, script: 0x52, flags: 0x0},
+ 1300: {region: 0xce, script: 0x52, flags: 0x0},
+ 1301: {region: 0x4c, script: 0x3, flags: 0x1},
+ 1302: {region: 0x164, script: 0x52, flags: 0x0},
+ 1303: {region: 0x164, script: 0x52, flags: 0x0},
+ 1304: {region: 0x164, script: 0x52, flags: 0x0},
+ 1305: {region: 0x52, script: 0x52, flags: 0x0},
+ 1306: {region: 0x10a, script: 0x52, flags: 0x0},
+ 1308: {region: 0xa7, script: 0x5, flags: 0x0},
+ 1309: {region: 0xd8, script: 0x52, flags: 0x0},
+ 1310: {region: 0xb9, script: 0xd2, flags: 0x0},
+ 1311: {region: 0x4f, script: 0x14, flags: 0x1},
+ 1312: {region: 0x164, script: 0x52, flags: 0x0},
+ 1313: {region: 0x121, script: 0x52, flags: 0x0},
+ 1314: {region: 0xcf, script: 0x52, flags: 0x0},
+ 1315: {region: 0x164, script: 0x52, flags: 0x0},
+ 1316: {region: 0x160, script: 0x52, flags: 0x0},
+ 1318: {region: 0x12a, script: 0x52, flags: 0x0},
+}
+
+// likelyLangList holds lists info associated with likelyLang.
+// Size: 396 bytes, 99 elements
+var likelyLangList = [99]likelyScriptRegion{
+ 0: {region: 0x9b, script: 0x7, flags: 0x0},
+ 1: {region: 0xa0, script: 0x6d, flags: 0x2},
+ 2: {region: 0x11b, script: 0x78, flags: 0x2},
+ 3: {region: 0x31, script: 0x52, flags: 0x0},
+ 4: {region: 0x9a, script: 0x5, flags: 0x4},
+ 5: {region: 0x9b, script: 0x5, flags: 0x4},
+ 6: {region: 0x105, script: 0x1e, flags: 0x4},
+ 7: {region: 0x9b, script: 0x5, flags: 0x2},
+ 8: {region: 0x98, script: 0xe, flags: 0x0},
+ 9: {region: 0x34, script: 0x16, flags: 0x2},
+ 10: {region: 0x105, script: 0x1e, flags: 0x0},
+ 11: {region: 0x37, script: 0x2a, flags: 0x2},
+ 12: {region: 0x134, script: 0x52, flags: 0x0},
+ 13: {region: 0x7a, script: 0xbd, flags: 0x2},
+ 14: {region: 0x113, script: 0x52, flags: 0x0},
+ 15: {region: 0x83, script: 0x1, flags: 0x2},
+ 16: {region: 0x5c, script: 0x1d, flags: 0x0},
+ 17: {region: 0x86, script: 0x57, flags: 0x2},
+ 18: {region: 0xd5, script: 0x52, flags: 0x0},
+ 19: {region: 0x51, script: 0x5, flags: 0x4},
+ 20: {region: 0x10a, script: 0x5, flags: 0x4},
+ 21: {region: 0xad, script: 0x1e, flags: 0x0},
+ 22: {region: 0x23, script: 0x5, flags: 0x4},
+ 23: {region: 0x52, script: 0x5, flags: 0x4},
+ 24: {region: 0x9b, script: 0x5, flags: 0x4},
+ 25: {region: 0xc4, script: 0x5, flags: 0x4},
+ 26: {region: 0x52, script: 0x5, flags: 0x2},
+ 27: {region: 0x12a, script: 0x52, flags: 0x0},
+ 28: {region: 0xaf, script: 0x5, flags: 0x4},
+ 29: {region: 0x9a, script: 0x5, flags: 0x2},
+ 30: {region: 0xa4, script: 0x1e, flags: 0x0},
+ 31: {region: 0x52, script: 0x5, flags: 0x4},
+ 32: {region: 0x12a, script: 0x52, flags: 0x4},
+ 33: {region: 0x52, script: 0x5, flags: 0x2},
+ 34: {region: 0x12a, script: 0x52, flags: 0x2},
+ 35: {region: 0xda, script: 0x20, flags: 0x0},
+ 36: {region: 0x98, script: 0x55, flags: 0x2},
+ 37: {region: 0x82, script: 0x52, flags: 0x0},
+ 38: {region: 0x83, script: 0x70, flags: 0x4},
+ 39: {region: 0x83, script: 0x70, flags: 0x2},
+ 40: {region: 0xc4, script: 0x1e, flags: 0x0},
+ 41: {region: 0x52, script: 0x66, flags: 0x4},
+ 42: {region: 0x52, script: 0x66, flags: 0x2},
+ 43: {region: 0xcf, script: 0x52, flags: 0x0},
+ 44: {region: 0x49, script: 0x5, flags: 0x4},
+ 45: {region: 0x94, script: 0x5, flags: 0x4},
+ 46: {region: 0x98, script: 0x2f, flags: 0x0},
+ 47: {region: 0xe7, script: 0x5, flags: 0x4},
+ 48: {region: 0xe7, script: 0x5, flags: 0x2},
+ 49: {region: 0x9b, script: 0x7c, flags: 0x0},
+ 50: {region: 0x52, script: 0x7d, flags: 0x2},
+ 51: {region: 0xb9, script: 0xd2, flags: 0x0},
+ 52: {region: 0xd8, script: 0x52, flags: 0x4},
+ 53: {region: 0xe7, script: 0x5, flags: 0x0},
+ 54: {region: 0x98, script: 0x20, flags: 0x2},
+ 55: {region: 0x98, script: 0x47, flags: 0x2},
+ 56: {region: 0x98, script: 0xc0, flags: 0x2},
+ 57: {region: 0x104, script: 0x1e, flags: 0x0},
+ 58: {region: 0xbc, script: 0x52, flags: 0x4},
+ 59: {region: 0x103, script: 0x52, flags: 0x4},
+ 60: {region: 0x105, script: 0x52, flags: 0x4},
+ 61: {region: 0x12a, script: 0x52, flags: 0x4},
+ 62: {region: 0x123, script: 0x1e, flags: 0x0},
+ 63: {region: 0xe7, script: 0x5, flags: 0x4},
+ 64: {region: 0xe7, script: 0x5, flags: 0x2},
+ 65: {region: 0x52, script: 0x5, flags: 0x0},
+ 66: {region: 0xad, script: 0x1e, flags: 0x4},
+ 67: {region: 0xc4, script: 0x1e, flags: 0x4},
+ 68: {region: 0xad, script: 0x1e, flags: 0x2},
+ 69: {region: 0x98, script: 0xe, flags: 0x0},
+ 70: {region: 0xda, script: 0x20, flags: 0x4},
+ 71: {region: 0xda, script: 0x20, flags: 0x2},
+ 72: {region: 0x136, script: 0x52, flags: 0x0},
+ 73: {region: 0x23, script: 0x5, flags: 0x4},
+ 74: {region: 0x52, script: 0x1e, flags: 0x4},
+ 75: {region: 0x23, script: 0x5, flags: 0x2},
+ 76: {region: 0x8c, script: 0x35, flags: 0x0},
+ 77: {region: 0x52, script: 0x34, flags: 0x4},
+ 78: {region: 0x52, script: 0x34, flags: 0x2},
+ 79: {region: 0x52, script: 0x34, flags: 0x0},
+ 80: {region: 0x2e, script: 0x35, flags: 0x4},
+ 81: {region: 0x3d, script: 0x35, flags: 0x4},
+ 82: {region: 0x7a, script: 0x35, flags: 0x4},
+ 83: {region: 0x7d, script: 0x35, flags: 0x4},
+ 84: {region: 0x8c, script: 0x35, flags: 0x4},
+ 85: {region: 0x94, script: 0x35, flags: 0x4},
+ 86: {region: 0xc5, script: 0x35, flags: 0x4},
+ 87: {region: 0xcf, script: 0x35, flags: 0x4},
+ 88: {region: 0xe1, script: 0x35, flags: 0x4},
+ 89: {region: 0xe4, script: 0x35, flags: 0x4},
+ 90: {region: 0xe6, script: 0x35, flags: 0x4},
+ 91: {region: 0x115, script: 0x35, flags: 0x4},
+ 92: {region: 0x122, script: 0x35, flags: 0x4},
+ 93: {region: 0x12d, script: 0x35, flags: 0x4},
+ 94: {region: 0x134, script: 0x35, flags: 0x4},
+ 95: {region: 0x13d, script: 0x35, flags: 0x4},
+ 96: {region: 0x12d, script: 0x11, flags: 0x2},
+ 97: {region: 0x12d, script: 0x30, flags: 0x2},
+ 98: {region: 0x12d, script: 0x35, flags: 0x2},
+}
+
+type likelyLangScript struct {
+ lang uint16
+ script uint8
+ flags uint8
+}
+
+// likelyRegion is a lookup table, indexed by regionID, for the most likely
+// languages and scripts given incomplete information. If more entries exist
+// for a given regionID, lang and script are the index and size respectively
+// of the list in likelyRegionList.
+// TODO: exclude containers and user-definable regions from the list.
+// Size: 1428 bytes, 357 elements
+var likelyRegion = [357]likelyLangScript{
+ 33: {lang: 0xd5, script: 0x52, flags: 0x0},
+ 34: {lang: 0x39, script: 0x5, flags: 0x0},
+ 35: {lang: 0x0, script: 0x2, flags: 0x1},
+ 38: {lang: 0x2, script: 0x2, flags: 0x1},
+ 39: {lang: 0x4, script: 0x2, flags: 0x1},
+ 41: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 42: {lang: 0x0, script: 0x52, flags: 0x0},
+ 43: {lang: 0x139, script: 0x52, flags: 0x0},
+ 44: {lang: 0x411, script: 0x52, flags: 0x0},
+ 45: {lang: 0x109, script: 0x52, flags: 0x0},
+ 47: {lang: 0x35e, script: 0x52, flags: 0x0},
+ 48: {lang: 0x43a, script: 0x52, flags: 0x0},
+ 49: {lang: 0x57, script: 0x52, flags: 0x0},
+ 50: {lang: 0x6, script: 0x2, flags: 0x1},
+ 52: {lang: 0xa3, script: 0xe, flags: 0x0},
+ 53: {lang: 0x35e, script: 0x52, flags: 0x0},
+ 54: {lang: 0x159, script: 0x52, flags: 0x0},
+ 55: {lang: 0x7d, script: 0x1e, flags: 0x0},
+ 56: {lang: 0x39, script: 0x5, flags: 0x0},
+ 57: {lang: 0x3d0, script: 0x52, flags: 0x0},
+ 58: {lang: 0x159, script: 0x52, flags: 0x0},
+ 59: {lang: 0x159, script: 0x52, flags: 0x0},
+ 61: {lang: 0x316, script: 0x52, flags: 0x0},
+ 62: {lang: 0x139, script: 0x52, flags: 0x0},
+ 63: {lang: 0x398, script: 0x52, flags: 0x0},
+ 64: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 66: {lang: 0x8, script: 0x2, flags: 0x1},
+ 68: {lang: 0x0, script: 0x52, flags: 0x0},
+ 70: {lang: 0x70, script: 0x1e, flags: 0x0},
+ 72: {lang: 0x508, script: 0x37, flags: 0x2},
+ 73: {lang: 0x316, script: 0x5, flags: 0x2},
+ 74: {lang: 0x43b, script: 0x52, flags: 0x0},
+ 75: {lang: 0x159, script: 0x52, flags: 0x0},
+ 76: {lang: 0x159, script: 0x52, flags: 0x0},
+ 77: {lang: 0x109, script: 0x52, flags: 0x0},
+ 78: {lang: 0x159, script: 0x52, flags: 0x0},
+ 80: {lang: 0x139, script: 0x52, flags: 0x0},
+ 81: {lang: 0x159, script: 0x52, flags: 0x0},
+ 82: {lang: 0xa, script: 0x5, flags: 0x1},
+ 83: {lang: 0x139, script: 0x52, flags: 0x0},
+ 84: {lang: 0x0, script: 0x52, flags: 0x0},
+ 85: {lang: 0x139, script: 0x52, flags: 0x0},
+ 88: {lang: 0x139, script: 0x52, flags: 0x0},
+ 89: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 90: {lang: 0x398, script: 0x52, flags: 0x0},
+ 92: {lang: 0xf, script: 0x2, flags: 0x1},
+ 93: {lang: 0xf6, script: 0x52, flags: 0x0},
+ 95: {lang: 0x109, script: 0x52, flags: 0x0},
+ 97: {lang: 0x1, script: 0x52, flags: 0x0},
+ 98: {lang: 0xfd, script: 0x52, flags: 0x0},
+ 100: {lang: 0x139, script: 0x52, flags: 0x0},
+ 102: {lang: 0x11, script: 0x2, flags: 0x1},
+ 103: {lang: 0x139, script: 0x52, flags: 0x0},
+ 104: {lang: 0x139, script: 0x52, flags: 0x0},
+ 105: {lang: 0x13b, script: 0x52, flags: 0x0},
+ 106: {lang: 0x39, script: 0x5, flags: 0x0},
+ 107: {lang: 0x39, script: 0x5, flags: 0x0},
+ 108: {lang: 0x465, script: 0x27, flags: 0x0},
+ 109: {lang: 0x139, script: 0x52, flags: 0x0},
+ 110: {lang: 0x13, script: 0x2, flags: 0x1},
+ 112: {lang: 0x109, script: 0x52, flags: 0x0},
+ 113: {lang: 0x14c, script: 0x52, flags: 0x0},
+ 114: {lang: 0x1b9, script: 0x20, flags: 0x2},
+ 117: {lang: 0x153, script: 0x52, flags: 0x0},
+ 119: {lang: 0x159, script: 0x52, flags: 0x0},
+ 121: {lang: 0x159, script: 0x52, flags: 0x0},
+ 122: {lang: 0x15, script: 0x2, flags: 0x1},
+ 124: {lang: 0x17, script: 0x3, flags: 0x1},
+ 125: {lang: 0x159, script: 0x52, flags: 0x0},
+ 127: {lang: 0x20, script: 0x52, flags: 0x0},
+ 129: {lang: 0x23d, script: 0x52, flags: 0x0},
+ 131: {lang: 0x159, script: 0x52, flags: 0x0},
+ 132: {lang: 0x159, script: 0x52, flags: 0x0},
+ 133: {lang: 0x139, script: 0x52, flags: 0x0},
+ 134: {lang: 0x1a, script: 0x2, flags: 0x1},
+ 135: {lang: 0x0, script: 0x52, flags: 0x0},
+ 136: {lang: 0x139, script: 0x52, flags: 0x0},
+ 138: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 140: {lang: 0x51f, script: 0x35, flags: 0x0},
+ 141: {lang: 0x0, script: 0x52, flags: 0x0},
+ 142: {lang: 0x139, script: 0x52, flags: 0x0},
+ 143: {lang: 0x1ca, script: 0x52, flags: 0x0},
+ 144: {lang: 0x1cd, script: 0x52, flags: 0x0},
+ 145: {lang: 0x1ce, script: 0x52, flags: 0x0},
+ 147: {lang: 0x139, script: 0x52, flags: 0x0},
+ 148: {lang: 0x1c, script: 0x2, flags: 0x1},
+ 150: {lang: 0x1b5, script: 0x37, flags: 0x0},
+ 152: {lang: 0x1e, script: 0x3, flags: 0x1},
+ 154: {lang: 0x39, script: 0x5, flags: 0x0},
+ 155: {lang: 0x21, script: 0x2, flags: 0x1},
+ 156: {lang: 0x1f0, script: 0x52, flags: 0x0},
+ 157: {lang: 0x1f1, script: 0x52, flags: 0x0},
+ 160: {lang: 0x39, script: 0x5, flags: 0x0},
+ 161: {lang: 0x1f8, script: 0x41, flags: 0x0},
+ 163: {lang: 0x43b, script: 0x52, flags: 0x0},
+ 164: {lang: 0x281, script: 0x1e, flags: 0x0},
+ 165: {lang: 0x23, script: 0x3, flags: 0x1},
+ 167: {lang: 0x26, script: 0x2, flags: 0x1},
+ 169: {lang: 0x24b, script: 0x4b, flags: 0x0},
+ 170: {lang: 0x24b, script: 0x4b, flags: 0x0},
+ 171: {lang: 0x39, script: 0x5, flags: 0x0},
+ 173: {lang: 0x3d9, script: 0x1e, flags: 0x0},
+ 174: {lang: 0x28, script: 0x2, flags: 0x1},
+ 175: {lang: 0x39, script: 0x5, flags: 0x0},
+ 177: {lang: 0x109, script: 0x52, flags: 0x0},
+ 178: {lang: 0x402, script: 0xc1, flags: 0x0},
+ 180: {lang: 0x431, script: 0x52, flags: 0x0},
+ 181: {lang: 0x2b7, script: 0x52, flags: 0x0},
+ 182: {lang: 0x159, script: 0x52, flags: 0x0},
+ 183: {lang: 0x2be, script: 0x52, flags: 0x0},
+ 184: {lang: 0x39, script: 0x5, flags: 0x0},
+ 185: {lang: 0x2a, script: 0x2, flags: 0x1},
+ 186: {lang: 0x159, script: 0x52, flags: 0x0},
+ 187: {lang: 0x2c, script: 0x2, flags: 0x1},
+ 188: {lang: 0x428, script: 0x52, flags: 0x0},
+ 189: {lang: 0x159, script: 0x52, flags: 0x0},
+ 190: {lang: 0x2e8, script: 0x52, flags: 0x0},
+ 193: {lang: 0x2e, script: 0x2, flags: 0x1},
+ 194: {lang: 0x9e, script: 0x52, flags: 0x0},
+ 195: {lang: 0x30, script: 0x2, flags: 0x1},
+ 196: {lang: 0x32, script: 0x2, flags: 0x1},
+ 197: {lang: 0x34, script: 0x2, flags: 0x1},
+ 199: {lang: 0x159, script: 0x52, flags: 0x0},
+ 200: {lang: 0x36, script: 0x2, flags: 0x1},
+ 202: {lang: 0x317, script: 0x52, flags: 0x0},
+ 203: {lang: 0x38, script: 0x3, flags: 0x1},
+ 204: {lang: 0x124, script: 0xd4, flags: 0x0},
+ 206: {lang: 0x139, script: 0x52, flags: 0x0},
+ 207: {lang: 0x316, script: 0x52, flags: 0x0},
+ 208: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 209: {lang: 0x15, script: 0x52, flags: 0x0},
+ 210: {lang: 0x159, script: 0x52, flags: 0x0},
+ 211: {lang: 0x1ad, script: 0x52, flags: 0x0},
+ 213: {lang: 0x1ad, script: 0x5, flags: 0x2},
+ 215: {lang: 0x139, script: 0x52, flags: 0x0},
+ 216: {lang: 0x35e, script: 0x52, flags: 0x0},
+ 217: {lang: 0x33e, script: 0x52, flags: 0x0},
+ 218: {lang: 0x348, script: 0x20, flags: 0x0},
+ 224: {lang: 0x39, script: 0x5, flags: 0x0},
+ 225: {lang: 0x139, script: 0x52, flags: 0x0},
+ 227: {lang: 0x139, script: 0x52, flags: 0x0},
+ 228: {lang: 0x159, script: 0x52, flags: 0x0},
+ 229: {lang: 0x47c, script: 0x52, flags: 0x0},
+ 230: {lang: 0x14e, script: 0x52, flags: 0x0},
+ 231: {lang: 0x3b, script: 0x3, flags: 0x1},
+ 232: {lang: 0x3e, script: 0x2, flags: 0x1},
+ 233: {lang: 0x159, script: 0x52, flags: 0x0},
+ 235: {lang: 0x139, script: 0x52, flags: 0x0},
+ 236: {lang: 0x39, script: 0x5, flags: 0x0},
+ 237: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 239: {lang: 0x399, script: 0x52, flags: 0x0},
+ 240: {lang: 0x18e, script: 0x52, flags: 0x0},
+ 242: {lang: 0x39, script: 0x5, flags: 0x0},
+ 257: {lang: 0x159, script: 0x52, flags: 0x0},
+ 259: {lang: 0x40, script: 0x2, flags: 0x1},
+ 260: {lang: 0x428, script: 0x1e, flags: 0x0},
+ 261: {lang: 0x42, script: 0x2, flags: 0x1},
+ 262: {lang: 0x3dc, script: 0x52, flags: 0x0},
+ 263: {lang: 0x39, script: 0x5, flags: 0x0},
+ 265: {lang: 0x159, script: 0x52, flags: 0x0},
+ 266: {lang: 0x39, script: 0x5, flags: 0x0},
+ 267: {lang: 0x44, script: 0x2, flags: 0x1},
+ 270: {lang: 0x40c, script: 0x52, flags: 0x0},
+ 271: {lang: 0x33e, script: 0x52, flags: 0x0},
+ 272: {lang: 0x46, script: 0x2, flags: 0x1},
+ 274: {lang: 0x1f1, script: 0x52, flags: 0x0},
+ 275: {lang: 0x159, script: 0x52, flags: 0x0},
+ 276: {lang: 0x41f, script: 0x52, flags: 0x0},
+ 277: {lang: 0x35e, script: 0x52, flags: 0x0},
+ 279: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 281: {lang: 0x139, script: 0x52, flags: 0x0},
+ 283: {lang: 0x48, script: 0x2, flags: 0x1},
+ 287: {lang: 0x159, script: 0x52, flags: 0x0},
+ 288: {lang: 0x159, script: 0x52, flags: 0x0},
+ 289: {lang: 0x4a, script: 0x2, flags: 0x1},
+ 290: {lang: 0x4c, script: 0x3, flags: 0x1},
+ 291: {lang: 0x4f, script: 0x2, flags: 0x1},
+ 292: {lang: 0x46d, script: 0x52, flags: 0x0},
+ 293: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 294: {lang: 0x46c, script: 0x52, flags: 0x0},
+ 295: {lang: 0x51, script: 0x2, flags: 0x1},
+ 296: {lang: 0x478, script: 0x52, flags: 0x0},
+ 298: {lang: 0x53, script: 0x4, flags: 0x1},
+ 300: {lang: 0x496, script: 0x52, flags: 0x0},
+ 301: {lang: 0x57, script: 0x2, flags: 0x1},
+ 302: {lang: 0x43b, script: 0x52, flags: 0x0},
+ 303: {lang: 0x59, script: 0x3, flags: 0x1},
+ 304: {lang: 0x43b, script: 0x52, flags: 0x0},
+ 308: {lang: 0x508, script: 0x37, flags: 0x2},
+ 309: {lang: 0x139, script: 0x52, flags: 0x0},
+ 310: {lang: 0x4b2, script: 0x52, flags: 0x0},
+ 311: {lang: 0x1f1, script: 0x52, flags: 0x0},
+ 314: {lang: 0x139, script: 0x52, flags: 0x0},
+ 317: {lang: 0x4b9, script: 0x52, flags: 0x0},
+ 318: {lang: 0x89, script: 0x52, flags: 0x0},
+ 319: {lang: 0x159, script: 0x52, flags: 0x0},
+ 321: {lang: 0x411, script: 0x52, flags: 0x0},
+ 332: {lang: 0x5c, script: 0x2, flags: 0x1},
+ 349: {lang: 0x39, script: 0x5, flags: 0x0},
+ 350: {lang: 0x5e, script: 0x2, flags: 0x1},
+ 355: {lang: 0x419, script: 0x52, flags: 0x0},
+}
+
+// likelyRegionList holds lists info associated with likelyRegion.
+// Size: 384 bytes, 96 elements
+var likelyRegionList = [96]likelyLangScript{
+ 0: {lang: 0x143, script: 0x5, flags: 0x0},
+ 1: {lang: 0x46c, script: 0x52, flags: 0x0},
+ 2: {lang: 0x427, script: 0x52, flags: 0x0},
+ 3: {lang: 0x2f6, script: 0x1e, flags: 0x0},
+ 4: {lang: 0x1d0, script: 0x8, flags: 0x0},
+ 5: {lang: 0x26b, script: 0x52, flags: 0x0},
+ 6: {lang: 0xb5, script: 0x52, flags: 0x0},
+ 7: {lang: 0x428, script: 0x1e, flags: 0x0},
+ 8: {lang: 0x129, script: 0xd6, flags: 0x0},
+ 9: {lang: 0x348, script: 0x20, flags: 0x0},
+ 10: {lang: 0x51f, script: 0x34, flags: 0x0},
+ 11: {lang: 0x4a2, script: 0x5, flags: 0x0},
+ 12: {lang: 0x515, script: 0x35, flags: 0x0},
+ 13: {lang: 0x519, script: 0x52, flags: 0x0},
+ 14: {lang: 0x291, script: 0xd5, flags: 0x0},
+ 15: {lang: 0x131, script: 0x2d, flags: 0x0},
+ 16: {lang: 0x480, script: 0x52, flags: 0x0},
+ 17: {lang: 0x39, script: 0x5, flags: 0x0},
+ 18: {lang: 0x159, script: 0x52, flags: 0x0},
+ 19: {lang: 0x26, script: 0x27, flags: 0x0},
+ 20: {lang: 0x134, script: 0x52, flags: 0x0},
+ 21: {lang: 0x261, script: 0x5, flags: 0x2},
+ 22: {lang: 0x508, script: 0x37, flags: 0x2},
+ 23: {lang: 0x208, script: 0x29, flags: 0x0},
+ 24: {lang: 0x5, script: 0x1e, flags: 0x0},
+ 25: {lang: 0x26b, script: 0x52, flags: 0x0},
+ 26: {lang: 0x131, script: 0x2d, flags: 0x0},
+ 27: {lang: 0x2f6, script: 0x1e, flags: 0x0},
+ 28: {lang: 0x1da, script: 0x52, flags: 0x0},
+ 29: {lang: 0x316, script: 0x5, flags: 0x0},
+ 30: {lang: 0x1b7, script: 0x20, flags: 0x0},
+ 31: {lang: 0x4aa, script: 0x5, flags: 0x0},
+ 32: {lang: 0x22e, script: 0x6b, flags: 0x0},
+ 33: {lang: 0x143, script: 0x5, flags: 0x0},
+ 34: {lang: 0x46c, script: 0x52, flags: 0x0},
+ 35: {lang: 0x242, script: 0x46, flags: 0x0},
+ 36: {lang: 0xe4, script: 0x5, flags: 0x0},
+ 37: {lang: 0x21e, script: 0xd5, flags: 0x0},
+ 38: {lang: 0x39, script: 0x5, flags: 0x0},
+ 39: {lang: 0x159, script: 0x52, flags: 0x0},
+ 40: {lang: 0x2af, script: 0x4f, flags: 0x0},
+ 41: {lang: 0x21e, script: 0xd5, flags: 0x0},
+ 42: {lang: 0x39, script: 0x5, flags: 0x0},
+ 43: {lang: 0x159, script: 0x52, flags: 0x0},
+ 44: {lang: 0x3d3, script: 0x52, flags: 0x0},
+ 45: {lang: 0x4a4, script: 0x1e, flags: 0x0},
+ 46: {lang: 0x2f6, script: 0x1e, flags: 0x0},
+ 47: {lang: 0x427, script: 0x52, flags: 0x0},
+ 48: {lang: 0x328, script: 0x6b, flags: 0x0},
+ 49: {lang: 0x20b, script: 0x52, flags: 0x0},
+ 50: {lang: 0x302, script: 0x1e, flags: 0x0},
+ 51: {lang: 0x23a, script: 0x5, flags: 0x0},
+ 52: {lang: 0x51f, script: 0x35, flags: 0x0},
+ 53: {lang: 0x3b7, script: 0x52, flags: 0x0},
+ 54: {lang: 0x39, script: 0x5, flags: 0x0},
+ 55: {lang: 0x159, script: 0x52, flags: 0x0},
+ 56: {lang: 0x2e4, script: 0x52, flags: 0x0},
+ 57: {lang: 0x4aa, script: 0x5, flags: 0x0},
+ 58: {lang: 0x87, script: 0x20, flags: 0x0},
+ 59: {lang: 0x4aa, script: 0x5, flags: 0x0},
+ 60: {lang: 0x4aa, script: 0x5, flags: 0x0},
+ 61: {lang: 0xbc, script: 0x20, flags: 0x0},
+ 62: {lang: 0x3aa, script: 0x52, flags: 0x0},
+ 63: {lang: 0x70, script: 0x1e, flags: 0x0},
+ 64: {lang: 0x3d3, script: 0x52, flags: 0x0},
+ 65: {lang: 0x7d, script: 0x1e, flags: 0x0},
+ 66: {lang: 0x3d9, script: 0x1e, flags: 0x0},
+ 67: {lang: 0x25e, script: 0x52, flags: 0x0},
+ 68: {lang: 0x43a, script: 0x52, flags: 0x0},
+ 69: {lang: 0x508, script: 0x37, flags: 0x0},
+ 70: {lang: 0x408, script: 0x52, flags: 0x0},
+ 71: {lang: 0x4a4, script: 0x1e, flags: 0x0},
+ 72: {lang: 0x39, script: 0x5, flags: 0x0},
+ 73: {lang: 0x159, script: 0x52, flags: 0x0},
+ 74: {lang: 0x159, script: 0x52, flags: 0x0},
+ 75: {lang: 0x34, script: 0x5, flags: 0x0},
+ 76: {lang: 0x461, script: 0xd5, flags: 0x0},
+ 77: {lang: 0x2e3, script: 0x5, flags: 0x0},
+ 78: {lang: 0x306, script: 0x6b, flags: 0x0},
+ 79: {lang: 0x45d, script: 0x1e, flags: 0x0},
+ 80: {lang: 0x143, script: 0x5, flags: 0x0},
+ 81: {lang: 0x39, script: 0x5, flags: 0x0},
+ 82: {lang: 0x159, script: 0x52, flags: 0x0},
+ 83: {lang: 0x480, script: 0x52, flags: 0x0},
+ 84: {lang: 0x57, script: 0x5, flags: 0x0},
+ 85: {lang: 0x211, script: 0x1e, flags: 0x0},
+ 86: {lang: 0x80, script: 0x2d, flags: 0x0},
+ 87: {lang: 0x51f, script: 0x35, flags: 0x0},
+ 88: {lang: 0x482, script: 0x52, flags: 0x0},
+ 89: {lang: 0x4a4, script: 0x1e, flags: 0x0},
+ 90: {lang: 0x508, script: 0x37, flags: 0x0},
+ 91: {lang: 0x3aa, script: 0x52, flags: 0x0},
+ 92: {lang: 0x427, script: 0x52, flags: 0x0},
+ 93: {lang: 0x428, script: 0x1e, flags: 0x0},
+ 94: {lang: 0x159, script: 0x52, flags: 0x0},
+ 95: {lang: 0x43c, script: 0x5, flags: 0x0},
+}
+
+type likelyTag struct {
+ lang uint16
+ region uint16
+ script uint8
+}
+
+// Size: 192 bytes, 32 elements
+var likelyRegionGroup = [32]likelyTag{
+ 1: {lang: 0x134, region: 0xd5, script: 0x52},
+ 2: {lang: 0x134, region: 0x134, script: 0x52},
+ 3: {lang: 0x3b7, region: 0x40, script: 0x52},
+ 4: {lang: 0x134, region: 0x2e, script: 0x52},
+ 5: {lang: 0x134, region: 0xd5, script: 0x52},
+ 6: {lang: 0x139, region: 0xce, script: 0x52},
+ 7: {lang: 0x43b, region: 0x12e, script: 0x52},
+ 8: {lang: 0x39, region: 0x6a, script: 0x5},
+ 9: {lang: 0x43b, region: 0x4a, script: 0x52},
+ 10: {lang: 0x134, region: 0x160, script: 0x52},
+ 11: {lang: 0x134, region: 0x134, script: 0x52},
+ 12: {lang: 0x134, region: 0x134, script: 0x52},
+ 13: {lang: 0x139, region: 0x58, script: 0x52},
+ 14: {lang: 0x51f, region: 0x52, script: 0x34},
+ 15: {lang: 0x1b7, region: 0x98, script: 0x20},
+ 16: {lang: 0x1da, region: 0x94, script: 0x52},
+ 17: {lang: 0x1f1, region: 0x9d, script: 0x52},
+ 18: {lang: 0x134, region: 0x2e, script: 0x52},
+ 19: {lang: 0x134, region: 0xe5, script: 0x52},
+ 20: {lang: 0x134, region: 0x89, script: 0x52},
+ 21: {lang: 0x411, region: 0x141, script: 0x52},
+ 22: {lang: 0x51f, region: 0x52, script: 0x34},
+ 23: {lang: 0x4b2, region: 0x136, script: 0x52},
+ 24: {lang: 0x39, region: 0x107, script: 0x5},
+ 25: {lang: 0x3d9, region: 0x105, script: 0x1e},
+ 26: {lang: 0x3d9, region: 0x105, script: 0x1e},
+ 27: {lang: 0x134, region: 0x7a, script: 0x52},
+ 28: {lang: 0x109, region: 0x5f, script: 0x52},
+ 29: {lang: 0x139, region: 0x1e, script: 0x52},
+ 30: {lang: 0x134, region: 0x99, script: 0x52},
+ 31: {lang: 0x134, region: 0x7a, script: 0x52},
+}
+
+type mutualIntelligibility struct {
+ want uint16
+ have uint16
+ conf uint8
+ oneway bool
+}
+
+type scriptIntelligibility struct {
+ lang uint16
+ want uint8
+ have uint8
+ conf uint8
+}
+
+// matchLang holds pairs of langIDs of base languages that are typically
+// mutually intelligible. Each pair is associated with a confidence and
+// whether the intelligibility goes one or both ways.
+// Size: 708 bytes, 118 elements
+var matchLang = [118]mutualIntelligibility{
+ 0: {want: 0x366, have: 0x33e, conf: 0x2, oneway: false},
+ 1: {want: 0x26b, have: 0xe7, conf: 0x2, oneway: false},
+ 2: {want: 0x1ca, have: 0xb5, conf: 0x2, oneway: false},
+ 3: {want: 0x3fd, have: 0xb5, conf: 0x2, oneway: false},
+ 4: {want: 0x428, have: 0xb5, conf: 0x2, oneway: false},
+ 5: {want: 0x3fd, have: 0x1ca, conf: 0x2, oneway: false},
+ 6: {want: 0x428, have: 0x1ca, conf: 0x2, oneway: false},
+ 7: {want: 0x3fd, have: 0x428, conf: 0x2, oneway: false},
+ 8: {want: 0x430, have: 0x1, conf: 0x2, oneway: false},
+ 9: {want: 0x19c, have: 0x109, conf: 0x2, oneway: true},
+ 10: {want: 0x28c, have: 0x109, conf: 0x2, oneway: true},
+ 11: {want: 0xfd, have: 0x366, conf: 0x2, oneway: false},
+ 12: {want: 0xfd, have: 0x33e, conf: 0x2, oneway: false},
+ 13: {want: 0xe7, have: 0x26b, conf: 0x2, oneway: false},
+ 14: {want: 0x5, have: 0x3d9, conf: 0x2, oneway: true},
+ 15: {want: 0xc, have: 0x134, conf: 0x2, oneway: true},
+ 16: {want: 0x15, have: 0x35e, conf: 0x2, oneway: true},
+ 17: {want: 0x20, have: 0x134, conf: 0x2, oneway: true},
+ 18: {want: 0x55, have: 0x139, conf: 0x2, oneway: true},
+ 19: {want: 0x57, have: 0x3d9, conf: 0x2, oneway: true},
+ 20: {want: 0x70, have: 0x3d9, conf: 0x2, oneway: true},
+ 21: {want: 0x74, have: 0x134, conf: 0x2, oneway: true},
+ 22: {want: 0x81, have: 0x1b7, conf: 0x2, oneway: true},
+ 23: {want: 0xa3, have: 0x134, conf: 0x2, oneway: true},
+ 24: {want: 0xb0, have: 0x159, conf: 0x2, oneway: true},
+ 25: {want: 0xdb, have: 0x14e, conf: 0x2, oneway: true},
+ 26: {want: 0xe3, have: 0x134, conf: 0x2, oneway: true},
+ 27: {want: 0xe7, have: 0x39, conf: 0x2, oneway: true},
+ 28: {want: 0xed, have: 0x159, conf: 0x2, oneway: true},
+ 29: {want: 0xf5, have: 0x159, conf: 0x2, oneway: true},
+ 30: {want: 0xfc, have: 0x134, conf: 0x2, oneway: true},
+ 31: {want: 0x12c, have: 0x134, conf: 0x2, oneway: true},
+ 32: {want: 0x137, have: 0x134, conf: 0x2, oneway: true},
+ 33: {want: 0x13b, have: 0x14c, conf: 0x2, oneway: true},
+ 34: {want: 0x140, have: 0x139, conf: 0x2, oneway: true},
+ 35: {want: 0x153, have: 0xfd, conf: 0x2, oneway: true},
+ 36: {want: 0x168, have: 0x35e, conf: 0x2, oneway: true},
+ 37: {want: 0x169, have: 0x134, conf: 0x2, oneway: true},
+ 38: {want: 0x16a, have: 0x134, conf: 0x2, oneway: true},
+ 39: {want: 0x178, have: 0x134, conf: 0x2, oneway: true},
+ 40: {want: 0x18a, have: 0x139, conf: 0x2, oneway: true},
+ 41: {want: 0x18e, have: 0x139, conf: 0x2, oneway: true},
+ 42: {want: 0x19d, have: 0x1b7, conf: 0x2, oneway: true},
+ 43: {want: 0x1ad, have: 0x134, conf: 0x2, oneway: true},
+ 44: {want: 0x1b1, have: 0x134, conf: 0x2, oneway: true},
+ 45: {want: 0x1cd, have: 0x159, conf: 0x2, oneway: true},
+ 46: {want: 0x1d0, have: 0x3d9, conf: 0x2, oneway: true},
+ 47: {want: 0x1d2, have: 0x134, conf: 0x2, oneway: true},
+ 48: {want: 0x1df, have: 0x134, conf: 0x2, oneway: true},
+ 49: {want: 0x1f0, have: 0x134, conf: 0x2, oneway: true},
+ 50: {want: 0x206, have: 0x1da, conf: 0x2, oneway: true},
+ 51: {want: 0x208, have: 0x134, conf: 0x2, oneway: true},
+ 52: {want: 0x225, have: 0x159, conf: 0x2, oneway: true},
+ 53: {want: 0x23a, have: 0x3d9, conf: 0x2, oneway: true},
+ 54: {want: 0x242, have: 0x134, conf: 0x2, oneway: true},
+ 55: {want: 0x249, have: 0x134, conf: 0x2, oneway: true},
+ 56: {want: 0x25c, have: 0x134, conf: 0x2, oneway: true},
+ 57: {want: 0x26b, have: 0x480, conf: 0x2, oneway: true},
+ 58: {want: 0x281, have: 0x3d9, conf: 0x2, oneway: true},
+ 59: {want: 0x285, have: 0x1f1, conf: 0x2, oneway: true},
+ 60: {want: 0x29a, have: 0x134, conf: 0x2, oneway: true},
+ 61: {want: 0x2ac, have: 0x159, conf: 0x2, oneway: true},
+ 62: {want: 0x2af, have: 0x134, conf: 0x2, oneway: true},
+ 63: {want: 0x2b5, have: 0x134, conf: 0x2, oneway: true},
+ 64: {want: 0x2ba, have: 0x159, conf: 0x2, oneway: true},
+ 65: {want: 0x2e4, have: 0x134, conf: 0x2, oneway: true},
+ 66: {want: 0x2e8, have: 0x159, conf: 0x2, oneway: true},
+ 67: {want: 0x2f1, have: 0x134, conf: 0x2, oneway: true},
+ 68: {want: 0x2f6, have: 0x7d, conf: 0x2, oneway: true},
+ 69: {want: 0x2fb, have: 0x134, conf: 0x2, oneway: true},
+ 70: {want: 0x302, have: 0x3d9, conf: 0x2, oneway: true},
+ 71: {want: 0x312, have: 0x1b7, conf: 0x2, oneway: true},
+ 72: {want: 0x316, have: 0x1da, conf: 0x2, oneway: true},
+ 73: {want: 0x317, have: 0x134, conf: 0x2, oneway: true},
+ 74: {want: 0x328, have: 0x134, conf: 0x2, oneway: true},
+ 75: {want: 0x348, have: 0x134, conf: 0x2, oneway: true},
+ 76: {want: 0x361, have: 0x33e, conf: 0x2, oneway: false},
+ 77: {want: 0x361, have: 0x366, conf: 0x2, oneway: true},
+ 78: {want: 0x371, have: 0x134, conf: 0x2, oneway: true},
+ 79: {want: 0x37e, have: 0x134, conf: 0x2, oneway: true},
+ 80: {want: 0x380, have: 0x134, conf: 0x2, oneway: true},
+ 81: {want: 0x382, have: 0x159, conf: 0x2, oneway: true},
+ 82: {want: 0x387, have: 0x134, conf: 0x2, oneway: true},
+ 83: {want: 0x38c, have: 0x134, conf: 0x2, oneway: true},
+ 84: {want: 0x394, have: 0x134, conf: 0x2, oneway: true},
+ 85: {want: 0x39c, have: 0x134, conf: 0x2, oneway: true},
+ 86: {want: 0x3b5, have: 0x134, conf: 0x2, oneway: true},
+ 87: {want: 0x3bb, have: 0x139, conf: 0x2, oneway: true},
+ 88: {want: 0x3cb, have: 0x109, conf: 0x2, oneway: true},
+ 89: {want: 0x3d0, have: 0x134, conf: 0x2, oneway: true},
+ 90: {want: 0x3dc, have: 0x159, conf: 0x2, oneway: true},
+ 91: {want: 0x3e0, have: 0x1b7, conf: 0x2, oneway: true},
+ 92: {want: 0x3f0, have: 0x134, conf: 0x2, oneway: true},
+ 93: {want: 0x402, have: 0x134, conf: 0x2, oneway: true},
+ 94: {want: 0x419, have: 0x134, conf: 0x2, oneway: true},
+ 95: {want: 0x41f, have: 0x134, conf: 0x2, oneway: true},
+ 96: {want: 0x427, have: 0x134, conf: 0x2, oneway: true},
+ 97: {want: 0x431, have: 0x134, conf: 0x2, oneway: true},
+ 98: {want: 0x434, have: 0x1da, conf: 0x2, oneway: true},
+ 99: {want: 0x43b, have: 0x134, conf: 0x2, oneway: true},
+ 100: {want: 0x446, have: 0x134, conf: 0x2, oneway: true},
+ 101: {want: 0x457, have: 0x134, conf: 0x2, oneway: true},
+ 102: {want: 0x45d, have: 0x3d9, conf: 0x2, oneway: true},
+ 103: {want: 0x465, have: 0x134, conf: 0x2, oneway: true},
+ 104: {want: 0x46c, have: 0x3d9, conf: 0x2, oneway: true},
+ 105: {want: 0x3878, have: 0x134, conf: 0x2, oneway: true},
+ 106: {want: 0x476, have: 0x134, conf: 0x2, oneway: true},
+ 107: {want: 0x478, have: 0x134, conf: 0x2, oneway: true},
+ 108: {want: 0x48a, have: 0x3d9, conf: 0x2, oneway: true},
+ 109: {want: 0x493, have: 0x134, conf: 0x2, oneway: true},
+ 110: {want: 0x4a2, have: 0x51f, conf: 0x2, oneway: true},
+ 111: {want: 0x4aa, have: 0x134, conf: 0x2, oneway: true},
+ 112: {want: 0x4b2, have: 0x3d9, conf: 0x2, oneway: true},
+ 113: {want: 0x4db, have: 0x159, conf: 0x2, oneway: true},
+ 114: {want: 0x4e8, have: 0x134, conf: 0x2, oneway: true},
+ 115: {want: 0x508, have: 0x134, conf: 0x2, oneway: true},
+ 116: {want: 0x50e, have: 0x134, conf: 0x2, oneway: true},
+ 117: {want: 0x524, have: 0x134, conf: 0x2, oneway: true},
+}
+
+// matchScript holds pairs of scriptIDs where readers of one script
+// can typically also read the other. Each is associated with a confidence.
+// Size: 24 bytes, 4 elements
+var matchScript = [4]scriptIntelligibility{
+ 0: {lang: 0x428, want: 0x52, have: 0x1e, conf: 0x2},
+ 1: {lang: 0x428, want: 0x1e, have: 0x52, conf: 0x2},
+ 2: {lang: 0x0, want: 0x34, have: 0x35, conf: 0x1},
+ 3: {lang: 0x0, want: 0x35, have: 0x34, conf: 0x1},
+}
+
+// Size: 128 bytes, 32 elements
+var regionContainment = [32]uint32{
+ 0xffffffff, 0x000007a2, 0x00003044, 0x00000008,
+ 0x403c0010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x2000384c,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x01c1c000, 0x00800000,
+ 0x01000000, 0x1e020000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20002048, 0x40000000, 0x80000000,
+}
+
+// regionInclusion maps region identifiers to sets of regions in regionInclusionBits,
+// where each set holds all groupings that are directly connected in a region
+// containment graph.
+// Size: 357 bytes, 357 elements
+var regionInclusion = [357]uint8{
+ // Entry 0 - 3F
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x25, 0x22, 0x23,
+ 0x25, 0x26, 0x21, 0x27, 0x28, 0x29, 0x2a, 0x25,
+ 0x2b, 0x23, 0x22, 0x25, 0x24, 0x29, 0x2c, 0x2d,
+ 0x23, 0x2e, 0x2c, 0x25, 0x2f, 0x30, 0x27, 0x25,
+ // Entry 40 - 7F
+ 0x27, 0x25, 0x24, 0x30, 0x21, 0x31, 0x32, 0x33,
+ 0x2f, 0x21, 0x26, 0x26, 0x26, 0x34, 0x2c, 0x28,
+ 0x27, 0x26, 0x35, 0x27, 0x21, 0x33, 0x22, 0x20,
+ 0x25, 0x2c, 0x25, 0x21, 0x36, 0x2d, 0x34, 0x29,
+ 0x21, 0x2e, 0x37, 0x25, 0x25, 0x20, 0x38, 0x38,
+ 0x27, 0x37, 0x38, 0x38, 0x2e, 0x39, 0x2e, 0x1f,
+ 0x20, 0x37, 0x3a, 0x27, 0x3b, 0x2b, 0x20, 0x29,
+ 0x34, 0x26, 0x37, 0x25, 0x23, 0x27, 0x2b, 0x2c,
+ // Entry 80 - BF
+ 0x22, 0x2f, 0x2c, 0x2c, 0x25, 0x26, 0x39, 0x21,
+ 0x33, 0x3b, 0x2c, 0x27, 0x35, 0x21, 0x33, 0x39,
+ 0x25, 0x2d, 0x20, 0x38, 0x30, 0x37, 0x23, 0x2b,
+ 0x24, 0x21, 0x23, 0x24, 0x2b, 0x39, 0x2b, 0x25,
+ 0x23, 0x35, 0x20, 0x2e, 0x3c, 0x30, 0x3b, 0x2e,
+ 0x25, 0x35, 0x35, 0x23, 0x25, 0x3c, 0x30, 0x23,
+ 0x25, 0x34, 0x24, 0x2c, 0x31, 0x37, 0x29, 0x37,
+ 0x38, 0x38, 0x34, 0x32, 0x22, 0x25, 0x2e, 0x3b,
+ // Entry C0 - FF
+ 0x20, 0x22, 0x2c, 0x30, 0x35, 0x35, 0x3b, 0x25,
+ 0x2c, 0x25, 0x39, 0x2e, 0x24, 0x2e, 0x33, 0x30,
+ 0x2e, 0x31, 0x3a, 0x2c, 0x2a, 0x2c, 0x20, 0x33,
+ 0x29, 0x2b, 0x24, 0x20, 0x3b, 0x23, 0x28, 0x2a,
+ 0x23, 0x33, 0x20, 0x27, 0x28, 0x3a, 0x30, 0x24,
+ 0x2d, 0x2f, 0x28, 0x25, 0x23, 0x39, 0x20, 0x3b,
+ 0x27, 0x20, 0x23, 0x20, 0x20, 0x1e, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ // Entry 100 - 13F
+ 0x20, 0x2e, 0x20, 0x2d, 0x22, 0x32, 0x2e, 0x23,
+ 0x3a, 0x2e, 0x38, 0x37, 0x30, 0x2c, 0x39, 0x2b,
+ 0x2d, 0x2c, 0x22, 0x2c, 0x2e, 0x27, 0x2e, 0x26,
+ 0x32, 0x33, 0x25, 0x23, 0x31, 0x21, 0x25, 0x26,
+ 0x21, 0x2c, 0x30, 0x3c, 0x28, 0x30, 0x3c, 0x38,
+ 0x28, 0x30, 0x23, 0x25, 0x28, 0x35, 0x2e, 0x32,
+ 0x2e, 0x20, 0x21, 0x20, 0x2f, 0x27, 0x3c, 0x22,
+ 0x25, 0x20, 0x27, 0x25, 0x25, 0x30, 0x3a, 0x28,
+ // Entry 140 - 17F
+ 0x20, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x22, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x2e, 0x22,
+ 0x31, 0x2e, 0x26, 0x2e, 0x20,
+}
+
+// regionInclusionBits is an array of bit vectors where every vector represents
+// a set of region groupings. These sets are used to compute the distance
+// between two regions for the purpose of language matching.
+// Size: 288 bytes, 72 elements
+var regionInclusionBits = [72]uint32{
+ // Entry 0 - 1F
+ 0x82400813, 0x000007a3, 0x00003844, 0x20000808,
+ 0x403c0011, 0x00000022, 0x20000844, 0x00000082,
+ 0x00000102, 0x00000202, 0x00000402, 0x2000384d,
+ 0x00001804, 0x20002804, 0x00404000, 0x00408000,
+ 0x00410000, 0x02020000, 0x00040010, 0x00080010,
+ 0x00100010, 0x00200010, 0x01c1c001, 0x00c00000,
+ 0x01400000, 0x1e020001, 0x06000000, 0x0a000000,
+ 0x12000000, 0x20002848, 0x40000010, 0x80000001,
+ // Entry 20 - 3F
+ 0x00000001, 0x40000000, 0x00020000, 0x01000000,
+ 0x00008000, 0x00002000, 0x00000200, 0x00000008,
+ 0x00200000, 0x90000000, 0x00040000, 0x08000000,
+ 0x00000020, 0x84000000, 0x00000080, 0x00001000,
+ 0x00010000, 0x00000400, 0x04000000, 0x00000040,
+ 0x10000000, 0x00004000, 0x81000000, 0x88000000,
+ 0x00000100, 0x80020000, 0x00080000, 0x00100000,
+ 0x00800000, 0xffffffff, 0x82400fb3, 0xc27c0813,
+ // Entry 40 - 5F
+ 0xa240385f, 0x83c1c813, 0x9e420813, 0x92000001,
+ 0x86000001, 0x81400001, 0x8a000001, 0x82020001,
+}
+
+// regionInclusionNext marks, for each entry in regionInclusionBits, the set of
+// all groups that are reachable from the groups set in the respective entry.
+// Size: 72 bytes, 72 elements
+var regionInclusionNext = [72]uint8{
+ // Entry 0 - 3F
+ 0x3d, 0x3e, 0x0b, 0x0b, 0x3f, 0x01, 0x0b, 0x01,
+ 0x01, 0x01, 0x01, 0x40, 0x0b, 0x0b, 0x16, 0x16,
+ 0x16, 0x19, 0x04, 0x04, 0x04, 0x04, 0x41, 0x16,
+ 0x16, 0x42, 0x19, 0x19, 0x19, 0x0b, 0x04, 0x00,
+ 0x00, 0x1e, 0x11, 0x18, 0x0f, 0x0d, 0x09, 0x03,
+ 0x15, 0x43, 0x12, 0x1b, 0x05, 0x44, 0x07, 0x0c,
+ 0x10, 0x0a, 0x1a, 0x06, 0x1c, 0x0e, 0x45, 0x46,
+ 0x08, 0x47, 0x13, 0x14, 0x17, 0x3d, 0x3d, 0x3d,
+ // Entry 40 - 7F
+ 0x3d, 0x3d, 0x3d, 0x42, 0x42, 0x41, 0x42, 0x42,
+}
+
+type parentRel struct {
+ lang uint16
+ script uint8
+ maxScript uint8
+ toRegion uint16
+ fromRegion []uint16
+}
+
+// Size: 412 bytes, 5 elements
+var parents = [5]parentRel{
+ 0: {lang: 0x134, script: 0x0, maxScript: 0x52, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x24, 0x25, 0x2e, 0x33, 0x35, 0x3c, 0x41, 0x45, 0x47, 0x48, 0x49, 0x4f, 0x51, 0x5b, 0x5c, 0x60, 0x63, 0x6c, 0x72, 0x73, 0x74, 0x7a, 0x7b, 0x7e, 0x7f, 0x80, 0x82, 0x8b, 0x8c, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9e, 0x9f, 0xa3, 0xa6, 0xa8, 0xac, 0xb0, 0xb3, 0xb4, 0xbe, 0xc5, 0xc9, 0xca, 0xcb, 0xcd, 0xcf, 0xd1, 0xd4, 0xd5, 0xdc, 0xde, 0xdf, 0xe5, 0xe6, 0xe7, 0xea, 0xef, 0x106, 0x108, 0x109, 0x10a, 0x10c, 0x10d, 0x111, 0x116, 0x11a, 0x11c, 0x11e, 0x124, 0x128, 0x12b, 0x12c, 0x12e, 0x130, 0x138, 0x13b, 0x13e, 0x141, 0x160, 0x161, 0x163}},
+ 1: {lang: 0x134, script: 0x0, maxScript: 0x52, toRegion: 0x1a, fromRegion: []uint16{0x2d, 0x4d, 0x5f, 0x62, 0x71, 0xd8, 0x10b, 0x10e}},
+ 2: {lang: 0x139, script: 0x0, maxScript: 0x52, toRegion: 0x1e, fromRegion: []uint16{0x2b, 0x3e, 0x40, 0x50, 0x53, 0x55, 0x58, 0x64, 0x68, 0x88, 0x8e, 0xce, 0xd7, 0xe1, 0xe3, 0xeb, 0xf0, 0x119, 0x134, 0x135, 0x13a}},
+ 3: {lang: 0x3b7, script: 0x0, maxScript: 0x52, toRegion: 0xed, fromRegion: []uint16{0x29, 0x4d, 0x59, 0x85, 0x8a, 0xb6, 0xc5, 0xd0, 0x117, 0x125}},
+ 4: {lang: 0x51f, script: 0x35, maxScript: 0x35, toRegion: 0x8c, fromRegion: []uint16{0xc5}},
+}
+
+// Total table size 25825 bytes (25KiB); checksum: 4E97CC5E
diff --git a/vendor/golang.org/x/text/language/tags.go b/vendor/golang.org/x/text/language/tags.go
new file mode 100644
index 000000000..de30155a2
--- /dev/null
+++ b/vendor/golang.org/x/text/language/tags.go
@@ -0,0 +1,143 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package language
+
+// TODO: Various sets of commonly use tags and regions.
+
+// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
+// It simplifies safe initialization of Tag values.
+func MustParse(s string) Tag {
+ t, err := Parse(s)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed.
+// It simplifies safe initialization of Tag values.
+func (c CanonType) MustParse(s string) Tag {
+ t, err := c.Parse(s)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+// MustParseBase is like ParseBase, but panics if the given base cannot be parsed.
+// It simplifies safe initialization of Base values.
+func MustParseBase(s string) Base {
+ b, err := ParseBase(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+// MustParseScript is like ParseScript, but panics if the given script cannot be
+// parsed. It simplifies safe initialization of Script values.
+func MustParseScript(s string) Script {
+ scr, err := ParseScript(s)
+ if err != nil {
+ panic(err)
+ }
+ return scr
+}
+
+// MustParseRegion is like ParseRegion, but panics if the given region cannot be
+// parsed. It simplifies safe initialization of Region values.
+func MustParseRegion(s string) Region {
+ r, err := ParseRegion(s)
+ if err != nil {
+ panic(err)
+ }
+ return r
+}
+
+var (
+ und = Tag{}
+
+ Und Tag = Tag{}
+
+ Afrikaans Tag = Tag{lang: _af} // af
+ Amharic Tag = Tag{lang: _am} // am
+ Arabic Tag = Tag{lang: _ar} // ar
+ ModernStandardArabic Tag = Tag{lang: _ar, region: _001} // ar-001
+ Azerbaijani Tag = Tag{lang: _az} // az
+ Bulgarian Tag = Tag{lang: _bg} // bg
+ Bengali Tag = Tag{lang: _bn} // bn
+ Catalan Tag = Tag{lang: _ca} // ca
+ Czech Tag = Tag{lang: _cs} // cs
+ Danish Tag = Tag{lang: _da} // da
+ German Tag = Tag{lang: _de} // de
+ Greek Tag = Tag{lang: _el} // el
+ English Tag = Tag{lang: _en} // en
+ AmericanEnglish Tag = Tag{lang: _en, region: _US} // en-US
+ BritishEnglish Tag = Tag{lang: _en, region: _GB} // en-GB
+ Spanish Tag = Tag{lang: _es} // es
+ EuropeanSpanish Tag = Tag{lang: _es, region: _ES} // es-ES
+ LatinAmericanSpanish Tag = Tag{lang: _es, region: _419} // es-419
+ Estonian Tag = Tag{lang: _et} // et
+ Persian Tag = Tag{lang: _fa} // fa
+ Finnish Tag = Tag{lang: _fi} // fi
+ Filipino Tag = Tag{lang: _fil} // fil
+ French Tag = Tag{lang: _fr} // fr
+ CanadianFrench Tag = Tag{lang: _fr, region: _CA} // fr-CA
+ Gujarati Tag = Tag{lang: _gu} // gu
+ Hebrew Tag = Tag{lang: _he} // he
+ Hindi Tag = Tag{lang: _hi} // hi
+ Croatian Tag = Tag{lang: _hr} // hr
+ Hungarian Tag = Tag{lang: _hu} // hu
+ Armenian Tag = Tag{lang: _hy} // hy
+ Indonesian Tag = Tag{lang: _id} // id
+ Icelandic Tag = Tag{lang: _is} // is
+ Italian Tag = Tag{lang: _it} // it
+ Japanese Tag = Tag{lang: _ja} // ja
+ Georgian Tag = Tag{lang: _ka} // ka
+ Kazakh Tag = Tag{lang: _kk} // kk
+ Khmer Tag = Tag{lang: _km} // km
+ Kannada Tag = Tag{lang: _kn} // kn
+ Korean Tag = Tag{lang: _ko} // ko
+ Kirghiz Tag = Tag{lang: _ky} // ky
+ Lao Tag = Tag{lang: _lo} // lo
+ Lithuanian Tag = Tag{lang: _lt} // lt
+ Latvian Tag = Tag{lang: _lv} // lv
+ Macedonian Tag = Tag{lang: _mk} // mk
+ Malayalam Tag = Tag{lang: _ml} // ml
+ Mongolian Tag = Tag{lang: _mn} // mn
+ Marathi Tag = Tag{lang: _mr} // mr
+ Malay Tag = Tag{lang: _ms} // ms
+ Burmese Tag = Tag{lang: _my} // my
+ Nepali Tag = Tag{lang: _ne} // ne
+ Dutch Tag = Tag{lang: _nl} // nl
+ Norwegian Tag = Tag{lang: _no} // no
+ Punjabi Tag = Tag{lang: _pa} // pa
+ Polish Tag = Tag{lang: _pl} // pl
+ Portuguese Tag = Tag{lang: _pt} // pt
+ BrazilianPortuguese Tag = Tag{lang: _pt, region: _BR} // pt-BR
+ EuropeanPortuguese Tag = Tag{lang: _pt, region: _PT} // pt-PT
+ Romanian Tag = Tag{lang: _ro} // ro
+ Russian Tag = Tag{lang: _ru} // ru
+ Sinhala Tag = Tag{lang: _si} // si
+ Slovak Tag = Tag{lang: _sk} // sk
+ Slovenian Tag = Tag{lang: _sl} // sl
+ Albanian Tag = Tag{lang: _sq} // sq
+ Serbian Tag = Tag{lang: _sr} // sr
+ SerbianLatin Tag = Tag{lang: _sr, script: _Latn} // sr-Latn
+ Swedish Tag = Tag{lang: _sv} // sv
+ Swahili Tag = Tag{lang: _sw} // sw
+ Tamil Tag = Tag{lang: _ta} // ta
+ Telugu Tag = Tag{lang: _te} // te
+ Thai Tag = Tag{lang: _th} // th
+ Turkish Tag = Tag{lang: _tr} // tr
+ Ukrainian Tag = Tag{lang: _uk} // uk
+ Urdu Tag = Tag{lang: _ur} // ur
+ Uzbek Tag = Tag{lang: _uz} // uz
+ Vietnamese Tag = Tag{lang: _vi} // vi
+ Chinese Tag = Tag{lang: _zh} // zh
+ SimplifiedChinese Tag = Tag{lang: _zh, script: _Hans} // zh-Hans
+ TraditionalChinese Tag = Tag{lang: _zh, script: _Hant} // zh-Hant
+ Zulu Tag = Tag{lang: _zu} // zu
+)