diff options
author | Niall Sheridan <nsheridan@gmail.com> | 2017-10-18 13:15:14 +0100 |
---|---|---|
committer | Niall Sheridan <niall@intercom.io> | 2017-10-18 13:25:46 +0100 |
commit | 7b320119ba532fd409ec7dade7ad02011c309599 (patch) | |
tree | a39860f35b55e6cc499f8f5bfa969138c5dd6b73 /vendor/golang.org/x/text/language | |
parent | 7c99874c7a3e7a89716f3ee0cdf696532e35ae35 (diff) |
Update dependencies
Diffstat (limited to 'vendor/golang.org/x/text/language')
-rw-r--r-- | vendor/golang.org/x/text/language/Makefile | 16 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/common.go | 16 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/coverage.go | 197 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/doc.go | 102 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/gen.go | 1706 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/gen_common.go | 20 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/gen_index.go | 162 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/go1_1.go | 38 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/go1_2.go | 11 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/index.go | 769 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/language.go | 887 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/lookup.go | 396 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/match.go | 933 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/parse.go | 859 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/tables.go | 3675 | ||||
-rw-r--r-- | vendor/golang.org/x/text/language/tags.go | 143 |
16 files changed, 9930 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 0000000..79f0057 --- /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 0000000..9d86e18 --- /dev/null +++ b/vendor/golang.org/x/text/language/common.go @@ -0,0 +1,16 @@ +// Code generated by running "go generate" in golang.org/x/text. 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 0000000..101fd23 --- /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/doc.go b/vendor/golang.org/x/text/language/doc.go new file mode 100644 index 0000000..8afecd5 --- /dev/null +++ b/vendor/golang.org/x/text/language/doc.go @@ -0,0 +1,102 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package language implements BCP 47 language tags and related functionality. +// +// The most important function of package language is to match a list of +// user-preferred languages to a list of supported languages. +// It alleviates the developer of dealing with the complexity of this process +// and provides the user with the best experience +// (see https://blog.golang.org/matchlang). +// +// +// Matching preferred against supported languages +// +// A Matcher for an application that supports English, Australian English, +// Danish, and standard Mandarin can be created 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, +// }) +// +// This list of supported languages is typically implied by the languages for +// which there exists translations of the user interface. +// +// User-preferred languages usually come as a comma-separated list of BCP 47 +// language tags. +// The MatchString finds best matches for such strings: +// +// handler(w http.ResponseWriter, r *http.Request) { +// lang, _ := r.Cookie("lang") +// accept := r.Header.Get("Accept-Language") +// tag, _ := language.MatchStrings(matcher, lang.String(), accept) +// +// // tag should now be used for the initialization of any +// // locale-specific service. +// } +// +// The Matcher's Match method can be used to match Tags directly. +// +// Matchers are aware of the intricacies of equivalence between languages, such +// as deprecated subtags, legacy tags, macro languages, mutual +// intelligibility between scripts and languages, and transparently passing +// BCP 47 user configuration. +// For instance, it will know that a reader of BokmÃ¥l Danish can read Norwegian +// and will know that Cantonese ("yue") is a good match for "zh-HK". +// +// +// Using match results +// +// To guarantee a consistent user experience to the user it is important to +// use the same language tag for the selection of any locale-specific services. +// For example, it is utterly confusing to substitute spelled-out numbers +// or dates in one language in text of another language. +// More subtly confusing is using the wrong sorting order or casing +// algorithm for a certain language. +// +// All the packages in x/text that provide locale-specific services +// (e.g. collate, cases) should be initialized with the tag that was +// obtained at the start of an interaction with the user. +// +// Note that Tag that is returned by Match and MatchString may differ from any +// of the supported languages, as it may contain carried over settings from +// the user tags. +// This may be inconvenient when your application has some additional +// locale-specific data for your supported languages. +// Match and MatchString both return the index of the matched supported tag +// to simplify associating such data with the matched tag. +// +// +// Canonicalization +// +// If one uses the Matcher to compare languages one does not need to +// worry about canonicalization. +// +// The meaning of a Tag varies per application. The language package +// therefore delays canonicalization and preserves information as much +// as possible. The Matcher, however, will always take into account that +// two different tags may represent the same language. +// +// 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 +// Matcher handles such distinctions, though, and is 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: explanation on how to match languages for your own locale-specific +// service. diff --git a/vendor/golang.org/x/text/language/gen.go b/vendor/golang.org/x/text/language/gen.go new file mode 100644 index 0000000..7c260e5 --- /dev/null +++ b/vendor/golang.org/x/text/language/gen.go @@ -0,0 +1,1706 @@ +// 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) > 64 { + log.Fatalf("only 64 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 canonicalized language tags. + lang.freeze() + for i, v := range lang.s { + // We can avoid these manual entries by using the IANA 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] = iso3166UserAssigned + } + } + 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", ®ionOldMap, 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 ( + iso3166UserAssigned = 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 + distance uint8 + oneway bool +} + +type scriptIntelligibility struct { + wantLang, haveLang uint16 + wantScript, haveScript uint8 + distance uint8 + // Always oneway +} + +type regionIntelligibility struct { + lang uint16 // compact language id + script uint8 // 0 means any + group uint8 // 0 means any; if bit 7 is set it means inverse + distance uint8 + // Always twoway. +} + +// 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() { + lm := b.supp.LanguageMatching.LanguageMatches + cldr.MakeSlice(&lm).SelectAnyOf("type", "written_new") + + regionHierarchy := map[string][]string{} + for _, g := range b.supp.TerritoryContainment.Group { + regions := strings.Split(g.Contains, " ") + regionHierarchy[g.Type] = append(regionHierarchy[g.Type], regions...) + } + regionToGroups := make([]uint8, len(b.region.s)) + + idToIndex := map[string]uint8{} + for i, mv := range lm[0].MatchVariable { + if i > 6 { + log.Fatalf("Too many groups: %d", i) + } + idToIndex[mv.Id] = uint8(i + 1) + // TODO: also handle '-' + for _, r := range strings.Split(mv.Value, "+") { + todo := []string{r} + for k := 0; k < len(todo); k++ { + r := todo[k] + regionToGroups[b.region.index(r)] |= 1 << uint8(i) + todo = append(todo, regionHierarchy[r]...) + } + } + } + b.writeSlice("regionToGroups", regionToGroups) + + // maps language id to in- and out-of-group region. + paradigmLocales := [][3]uint16{} + locales := strings.Split(lm[0].ParadigmLocales[0].Locales, " ") + for i := 0; i < len(locales); i += 2 { + x := [3]uint16{} + for j := 0; j < 2; j++ { + pc := strings.SplitN(locales[i+j], "-", 2) + x[0] = b.langIndex(pc[0]) + if len(pc) == 2 { + x[1+j] = uint16(b.region.index(pc[1])) + } + } + paradigmLocales = append(paradigmLocales, x) + } + b.writeSlice("paradigmLocales", paradigmLocales) + + b.writeType(mutualIntelligibility{}) + b.writeType(scriptIntelligibility{}) + b.writeType(regionIntelligibility{}) + + matchLang := []mutualIntelligibility{} + matchScript := []scriptIntelligibility{} + matchRegion := []regionIntelligibility{} + // 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) { + log.Fatalf("not supported: desired=%q; supported=%q", desired, supported) + continue + } + distance, _ := strconv.ParseInt(m.Distance, 10, 8) + switch len(d) { + case 2: + if desired == supported && desired == "*_*" { + continue + } + // language-script pair. + matchScript = append(matchScript, scriptIntelligibility{ + wantLang: uint16(b.langIndex(d[0])), + haveLang: uint16(b.langIndex(s[0])), + wantScript: uint8(b.script.index(d[1])), + haveScript: uint8(b.script.index(s[1])), + distance: uint8(distance), + }) + if m.Oneway != "true" { + matchScript = append(matchScript, scriptIntelligibility{ + wantLang: uint16(b.langIndex(s[0])), + haveLang: uint16(b.langIndex(d[0])), + wantScript: uint8(b.script.index(s[1])), + haveScript: uint8(b.script.index(d[1])), + distance: uint8(distance), + }) + } + case 1: + if desired == supported && desired == "*" { + continue + } + if distance == 1 { + // 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 + } + // TODO: consider dropping oneway field and just doubling the entry. + matchLang = append(matchLang, mutualIntelligibility{ + want: uint16(b.langIndex(d[0])), + have: uint16(b.langIndex(s[0])), + distance: uint8(distance), + oneway: m.Oneway == "true", + }) + case 3: + if desired == supported && desired == "*_*_*" { + continue + } + if desired != supported { // (Weird but correct.) + log.Fatalf("not supported: desired=%q; supported=%q", desired, supported) + continue + } + ri := regionIntelligibility{ + lang: b.langIndex(d[0]), + distance: uint8(distance), + } + if d[1] != "*" { + ri.script = uint8(b.script.index(d[1])) + } + switch { + case d[2] == "*": + ri.group = 0x80 // not contained in anything + case strings.HasPrefix(d[2], "$!"): + ri.group = 0x80 + d[2] = "$" + d[2][len("$!"):] + fallthrough + case strings.HasPrefix(d[2], "$"): + ri.group |= idToIndex[d[2]] + } + matchRegion = append(matchRegion, ri) + default: + log.Fatalf("not supported: desired=%q; supported=%q", desired, supported) + } + } + sort.SliceStable(matchLang, func(i, j int) bool { + return matchLang[i].distance < matchLang[j].distance + }) + b.writeSlice("matchLang", matchLang) + + sort.SliceStable(matchScript, func(i, j int) bool { + return matchScript[i].distance < matchScript[j].distance + }) + b.writeSlice("matchScript", matchScript) + + sort.SliceStable(matchRegion, func(i, j int) bool { + return matchRegion[i].distance < matchRegion[j].distance + }) + b.writeSlice("matchRegion", matchRegion) +} + +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([]uint64, 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 + } + } + b.writeSlice("regionContainment", regionContainment) + + regionInclusion := make([]uint8, len(b.region.s)) + bvs := make(map[uint64]index) + // Make the first bitvector positions correspond with the groups. + for r, i := range b.groups { + bv := uint64(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 := uint64(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([]uint64, len(bvs)) + for k, v := range bvs { + regionInclusionBits[v] = uint64(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/gen_common.go b/vendor/golang.org/x/text/language/gen_common.go new file mode 100644 index 0000000..83ce180 --- /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 0000000..eef555c --- /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 0000000..380f4c0 --- /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 0000000..38268c5 --- /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 0000000..69ac557 --- /dev/null +++ b/vendor/golang.org/x/text/language/index.go @@ -0,0 +1,769 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package language + +// NumCompactTags is the number of common tags. The maximum tag is +// NumCompactTags-1. +const NumCompactTags = 754 + +var specialTags = []Tag{ // 2 elements + 0: {lang: 0xd7, region: 0x6e, script: 0x0, pVariant: 0x5, pExt: 0xe, str: "ca-ES-valencia"}, + 1: {lang: 0x138, region: 0x135, script: 0x0, pVariant: 0x5, pExt: 0x5, str: "en-US-u-va-posix"}, +} // Size: 72 bytes + +var coreTags = map[uint32]uint16{ + 0x0: 0, // und + 0x01600000: 3, // af + 0x016000d2: 4, // af-NA + 0x01600161: 5, // af-ZA + 0x01c00000: 6, // agq + 0x01c00052: 7, // agq-CM + 0x02100000: 8, // ak + 0x02100080: 9, // ak-GH + 0x02700000: 10, // am + 0x0270006f: 11, // am-ET + 0x03a00000: 12, // ar + 0x03a00001: 13, // ar-001 + 0x03a00023: 14, // ar-AE + 0x03a00039: 15, // ar-BH + 0x03a00062: 16, // ar-DJ + 0x03a00067: 17, // ar-DZ + 0x03a0006b: 18, // ar-EG + 0x03a0006c: 19, // ar-EH + 0x03a0006d: 20, // ar-ER + 0x03a00097: 21, // ar-IL + 0x03a0009b: 22, // ar-IQ + 0x03a000a1: 23, // ar-JO + 0x03a000a8: 24, // ar-KM + 0x03a000ac: 25, // ar-KW + 0x03a000b0: 26, // ar-LB + 0x03a000b9: 27, // ar-LY + 0x03a000ba: 28, // ar-MA + 0x03a000c9: 29, // ar-MR + 0x03a000e1: 30, // ar-OM + 0x03a000ed: 31, // ar-PS + 0x03a000f3: 32, // ar-QA + 0x03a00108: 33, // ar-SA + 0x03a0010b: 34, // ar-SD + 0x03a00115: 35, // ar-SO + 0x03a00117: 36, // ar-SS + 0x03a0011c: 37, // ar-SY + 0x03a00120: 38, // ar-TD + 0x03a00128: 39, // ar-TN + 0x03a0015e: 40, // ar-YE + 0x04000000: 41, // ars + 0x04300000: 42, // as + 0x04300099: 43, // as-IN + 0x04400000: 44, // asa + 0x0440012f: 45, // asa-TZ + 0x04800000: 46, // ast + 0x0480006e: 47, // ast-ES + 0x05800000: 48, // az + 0x0581e000: 49, // az-Cyrl + 0x0581e032: 50, // az-Cyrl-AZ + 0x05855000: 51, // az-Latn + 0x05855032: 52, // az-Latn-AZ + 0x05e00000: 53, // bas + 0x05e00052: 54, // bas-CM + 0x07100000: 55, // be + 0x07100047: 56, // be-BY + 0x07500000: 57, // bem + 0x07500162: 58, // bem-ZM + 0x07900000: 59, // bez + 0x0790012f: 60, // bez-TZ + 0x07e00000: 61, // bg + 0x07e00038: 62, // bg-BG + 0x08200000: 63, // bh + 0x0a000000: 64, // bm + 0x0a0000c3: 65, // bm-ML + 0x0a500000: 66, // bn + 0x0a500035: 67, // bn-BD + 0x0a500099: 68, // bn-IN + 0x0a900000: 69, // bo + 0x0a900053: 70, // bo-CN + 0x0a900099: 71, // bo-IN + 0x0b200000: 72, // br + 0x0b200078: 73, // br-FR + 0x0b500000: 74, // brx + 0x0b500099: 75, // brx-IN + 0x0b700000: 76, // bs + 0x0b71e000: 77, // bs-Cyrl + 0x0b71e033: 78, // bs-Cyrl-BA + 0x0b755000: 79, // bs-Latn + 0x0b755033: 80, // bs-Latn-BA + 0x0d700000: 81, // ca + 0x0d700022: 82, // ca-AD + 0x0d70006e: 83, // ca-ES + 0x0d700078: 84, // ca-FR + 0x0d70009e: 85, // ca-IT + 0x0dc00000: 86, // ce + 0x0dc00106: 87, // ce-RU + 0x0df00000: 88, // cgg + 0x0df00131: 89, // cgg-UG + 0x0e500000: 90, // chr + 0x0e500135: 91, // chr-US + 0x0e900000: 92, // ckb + 0x0e90009b: 93, // ckb-IQ + 0x0e90009c: 94, // ckb-IR + 0x0f900000: 95, // cs + 0x0f90005e: 96, // cs-CZ + 0x0fd00000: 97, // cu + 0x0fd00106: 98, // cu-RU + 0x0ff00000: 99, // cy + 0x0ff0007b: 100, // cy-GB + 0x10000000: 101, // da + 0x10000063: 102, // da-DK + 0x10000082: 103, // da-GL + 0x10700000: 104, // dav + 0x107000a4: 105, // dav-KE + 0x10c00000: 106, // de + 0x10c0002e: 107, // de-AT + 0x10c00036: 108, // de-BE + 0x10c0004e: 109, // de-CH + 0x10c00060: 110, // de-DE + 0x10c0009e: 111, // de-IT + 0x10c000b2: 112, // de-LI + 0x10c000b7: 113, // de-LU + 0x11600000: 114, // dje + 0x116000d4: 115, // dje-NE + 0x11e00000: 116, // dsb + 0x11e00060: 117, // dsb-DE + 0x12300000: 118, // dua + 0x12300052: 119, // dua-CM + 0x12700000: 120, // dv + 0x12a00000: 121, // dyo + 0x12a00114: 122, // dyo-SN + 0x12c00000: 123, // dz + 0x12c00043: 124, // dz-BT + 0x12e00000: 125, // ebu + 0x12e000a4: 126, // ebu-KE + 0x12f00000: 127, // ee + 0x12f00080: 128, // ee-GH + 0x12f00122: 129, // ee-TG + 0x13500000: 130, // el + 0x1350005d: 131, // el-CY + 0x13500087: 132, // el-GR + 0x13800000: 133, // en + 0x13800001: 134, // en-001 + 0x1380001a: 135, // en-150 + 0x13800025: 136, // en-AG + 0x13800026: 137, // en-AI + 0x1380002d: 138, // en-AS + 0x1380002e: 139, // en-AT + 0x1380002f: 140, // en-AU + 0x13800034: 141, // en-BB + 0x13800036: 142, // en-BE + 0x1380003a: 143, // en-BI + 0x1380003d: 144, // en-BM + 0x13800042: 145, // en-BS + 0x13800046: 146, // en-BW + 0x13800048: 147, // en-BZ + 0x13800049: 148, // en-CA + 0x1380004a: 149, // en-CC + 0x1380004e: 150, // en-CH + 0x13800050: 151, // en-CK + 0x13800052: 152, // en-CM + 0x1380005c: 153, // en-CX + 0x1380005d: 154, // en-CY + 0x13800060: 155, // en-DE + 0x13800061: 156, // en-DG + 0x13800063: 157, // en-DK + 0x13800064: 158, // en-DM + 0x1380006d: 159, // en-ER + 0x13800072: 160, // en-FI + 0x13800073: 161, // en-FJ + 0x13800074: 162, // en-FK + 0x13800075: 163, // en-FM + 0x1380007b: 164, // en-GB + 0x1380007c: 165, // en-GD + 0x1380007f: 166, // en-GG + 0x13800080: 167, // en-GH + 0x13800081: 168, // en-GI + 0x13800083: 169, // en-GM + 0x1380008a: 170, // en-GU + 0x1380008c: 171, // en-GY + 0x1380008d: 172, // en-HK + 0x13800096: 173, // en-IE + 0x13800097: 174, // en-IL + 0x13800098: 175, // en-IM + 0x13800099: 176, // en-IN + 0x1380009a: 177, // en-IO + 0x1380009f: 178, // en-JE + 0x138000a0: 179, // en-JM + 0x138000a4: 180, // en-KE + 0x138000a7: 181, // en-KI + 0x138000a9: 182, // en-KN + 0x138000ad: 183, // en-KY + 0x138000b1: 184, // en-LC + 0x138000b4: 185, // en-LR + 0x138000b5: 186, // en-LS + 0x138000bf: 187, // en-MG + 0x138000c0: 188, // en-MH + 0x138000c6: 189, // en-MO + 0x138000c7: 190, // en-MP + 0x138000ca: 191, // en-MS + 0x138000cb: 192, // en-MT + 0x138000cc: 193, // en-MU + 0x138000ce: 194, // en-MW + 0x138000d0: 195, // en-MY + 0x138000d2: 196, // en-NA + 0x138000d5: 197, // en-NF + 0x138000d6: 198, // en-NG + 0x138000d9: 199, // en-NL + 0x138000dd: 200, // en-NR + 0x138000df: 201, // en-NU + 0x138000e0: 202, // en-NZ + 0x138000e6: 203, // en-PG + 0x138000e7: 204, // en-PH + 0x138000e8: 205, // en-PK + 0x138000eb: 206, // en-PN + 0x138000ec: 207, // en-PR + 0x138000f0: 208, // en-PW + 0x13800107: 209, // en-RW + 0x13800109: 210, // en-SB + 0x1380010a: 211, // en-SC + 0x1380010b: 212, // en-SD + 0x1380010c: 213, // en-SE + 0x1380010d: 214, // en-SG + 0x1380010e: 215, // en-SH + 0x1380010f: 216, // en-SI + 0x13800112: 217, // en-SL + 0x13800117: 218, // en-SS + 0x1380011b: 219, // en-SX + 0x1380011d: 220, // en-SZ + 0x1380011f: 221, // en-TC + 0x13800125: 222, // en-TK + 0x13800129: 223, // en-TO + 0x1380012c: 224, // en-TT + 0x1380012d: 225, // en-TV + 0x1380012f: 226, // en-TZ + 0x13800131: 227, // en-UG + 0x13800133: 228, // en-UM + 0x13800135: 229, // en-US + 0x13800139: 230, // en-VC + 0x1380013c: 231, // en-VG + 0x1380013d: 232, // en-VI + 0x1380013f: 233, // en-VU + 0x13800142: 234, // en-WS + 0x13800161: 235, // en-ZA + 0x13800162: 236, // en-ZM + 0x13800164: 237, // en-ZW + 0x13b00000: 238, // eo + 0x13b00001: 239, // eo-001 + 0x13d00000: 240, // es + 0x13d0001f: 241, // es-419 + 0x13d0002c: 242, // es-AR + 0x13d0003f: 243, // es-BO + 0x13d00041: 244, // es-BR + 0x13d00048: 245, // es-BZ + 0x13d00051: 246, // es-CL + 0x13d00054: 247, // es-CO + 0x13d00056: 248, // es-CR + 0x13d00059: 249, // es-CU + 0x13d00065: 250, // es-DO + 0x13d00068: 251, // es-EA + 0x13d00069: 252, // es-EC + 0x13d0006e: 253, // es-ES + 0x13d00086: 254, // es-GQ + 0x13d00089: 255, // es-GT + 0x13d0008f: 256, // es-HN + 0x13d00094: 257, // es-IC + 0x13d000cf: 258, // es-MX + 0x13d000d8: 259, // es-NI + 0x13d000e2: 260, // es-PA + 0x13d000e4: 261, // es-PE + 0x13d000e7: 262, // es-PH + 0x13d000ec: 263, // es-PR + 0x13d000f1: 264, // es-PY + 0x13d0011a: 265, // es-SV + 0x13d00135: 266, // es-US + 0x13d00136: 267, // es-UY + 0x13d0013b: 268, // es-VE + 0x13f00000: 269, // et + 0x13f0006a: 270, // et-EE + 0x14400000: 271, // eu + 0x1440006e: 272, // eu-ES + 0x14500000: 273, // ewo + 0x14500052: 274, // ewo-CM + 0x14700000: 275, // fa + 0x14700024: 276, // fa-AF + 0x1470009c: 277, // fa-IR + 0x14d00000: 278, // ff + 0x14d00052: 279, // ff-CM + 0x14d00084: 280, // ff-GN + 0x14d000c9: 281, // ff-MR + 0x14d00114: 282, // ff-SN + 0x15000000: 283, // fi + 0x15000072: 284, // fi-FI + 0x15200000: 285, // fil + 0x152000e7: 286, // fil-PH + 0x15700000: 287, // fo + 0x15700063: 288, // fo-DK + 0x15700076: 289, // fo-FO + 0x15d00000: 290, // fr + 0x15d00036: 291, // fr-BE + 0x15d00037: 292, // fr-BF + 0x15d0003a: 293, // fr-BI + 0x15d0003b: 294, // fr-BJ + 0x15d0003c: 295, // fr-BL + 0x15d00049: 296, // fr-CA + 0x15d0004b: 297, // fr-CD + 0x15d0004c: 298, // fr-CF + 0x15d0004d: 299, // fr-CG + 0x15d0004e: 300, // fr-CH + 0x15d0004f: 301, // fr-CI + 0x15d00052: 302, // fr-CM + 0x15d00062: 303, // fr-DJ + 0x15d00067: 304, // fr-DZ + 0x15d00078: 305, // fr-FR + 0x15d0007a: 306, // fr-GA + 0x15d0007e: 307, // fr-GF + 0x15d00084: 308, // fr-GN + 0x15d00085: 309, // fr-GP + 0x15d00086: 310, // fr-GQ + 0x15d00091: 311, // fr-HT + 0x15d000a8: 312, // fr-KM + 0x15d000b7: 313, // fr-LU + 0x15d000ba: 314, // fr-MA + 0x15d000bb: 315, // fr-MC + 0x15d000be: 316, // fr-MF + 0x15d000bf: 317, // fr-MG + 0x15d000c3: 318, // fr-ML + 0x15d000c8: 319, // fr-MQ + 0x15d000c9: 320, // fr-MR + 0x15d000cc: 321, // fr-MU + 0x15d000d3: 322, // fr-NC + 0x15d000d4: 323, // fr-NE + 0x15d000e5: 324, // fr-PF + 0x15d000ea: 325, // fr-PM + 0x15d00102: 326, // fr-RE + 0x15d00107: 327, // fr-RW + 0x15d0010a: 328, // fr-SC + 0x15d00114: 329, // fr-SN + 0x15d0011c: 330, // fr-SY + 0x15d00120: 331, // fr-TD + 0x15d00122: 332, // fr-TG + 0x15d00128: 333, // fr-TN + 0x15d0013f: 334, // fr-VU + 0x15d00140: 335, // fr-WF + 0x15d0015f: 336, // fr-YT + 0x16800000: 337, // fur + 0x1680009e: 338, // fur-IT + 0x16c00000: 339, // fy + 0x16c000d9: 340, // fy-NL + 0x16d00000: 341, // ga + 0x16d00096: 342, // ga-IE + 0x17c00000: 343, // gd + 0x17c0007b: 344, // gd-GB + 0x18e00000: 345, // gl + 0x18e0006e: 346, // gl-ES + 0x1a100000: 347, // gsw + 0x1a10004e: 348, // gsw-CH + 0x1a100078: 349, // gsw-FR + 0x1a1000b2: 350, // gsw-LI + 0x1a200000: 351, // gu + 0x1a200099: 352, // gu-IN + 0x1a700000: 353, // guw + 0x1a900000: 354, // guz + 0x1a9000a4: 355, // guz-KE + 0x1aa00000: 356, // gv + 0x1aa00098: 357, // gv-IM + 0x1b200000: 358, // ha + 0x1b200080: 359, // ha-GH + 0x1b2000d4: 360, // ha-NE + 0x1b2000d6: 361, // ha-NG + 0x1b600000: 362, // haw + 0x1b600135: 363, // haw-US + 0x1ba00000: 364, // he + 0x1ba00097: 365, // he-IL + 0x1bc00000: 366, // hi + 0x1bc00099: 367, // hi-IN + 0x1cf00000: 368, // hr + 0x1cf00033: 369, // hr-BA + 0x1cf00090: 370, // hr-HR + 0x1d000000: 371, // hsb + 0x1d000060: 372, // hsb-DE + 0x1d300000: 373, // hu + 0x1d300092: 374, // hu-HU + 0x1d500000: 375, // hy + 0x1d500028: 376, // hy-AM + 0x1df00000: 377, // id + 0x1df00095: 378, // id-ID + 0x1e500000: 379, // ig + 0x1e5000d6: 380, // ig-NG + 0x1e800000: 381, // ii + 0x1e800053: 382, // ii-CN + 0x1f600000: 383, // is + 0x1f60009d: 384, // is-IS + 0x1f700000: 385, // it + 0x1f70004e: 386, // it-CH + 0x1f70009e: 387, // it-IT + 0x1f700113: 388, // it-SM + 0x1f700138: 389, // it-VA + 0x1f800000: 390, // iu + 0x1fe00000: 391, // ja + 0x1fe000a2: 392, // ja-JP + 0x20100000: 393, // jbo + 0x20500000: 394, // jgo + 0x20500052: 395, // jgo-CM + 0x20800000: 396, // jmc + 0x2080012f: 397, // jmc-TZ + 0x20c00000: 398, // jv + 0x20e00000: 399, // ka + 0x20e0007d: 400, // ka-GE + 0x21000000: 401, // kab + 0x21000067: 402, // kab-DZ + 0x21400000: 403, // kaj + 0x21500000: 404, // kam + 0x215000a4: 405, // kam-KE + 0x21d00000: 406, // kcg + 0x22100000: 407, // kde + 0x2210012f: 408, // kde-TZ + 0x22500000: 409, // kea + 0x2250005a: 410, // kea-CV + 0x23200000: 411, // khq + 0x232000c3: 412, // khq-ML + 0x23700000: 413, // ki + 0x237000a4: 414, // ki-KE + 0x24000000: 415, // kk + 0x240000ae: 416, // kk-KZ + 0x24200000: 417, // kkj + 0x24200052: 418, // kkj-CM + 0x24300000: 419, // kl + 0x24300082: 420, // kl-GL + 0x24400000: 421, // kln + 0x244000a4: 422, // kln-KE + 0x24800000: 423, // km + 0x248000a6: 424, // km-KH + 0x24f00000: 425, // kn + 0x24f00099: 426, // kn-IN + 0x25200000: 427, // ko + 0x252000aa: 428, // ko-KP + 0x252000ab: 429, // ko-KR + 0x25400000: 430, // kok + 0x25400099: 431, // kok-IN + 0x26800000: 432, // ks + 0x26800099: 433, // ks-IN + 0x26900000: 434, // ksb + 0x2690012f: 435, // ksb-TZ + 0x26b00000: 436, // ksf + 0x26b00052: 437, // ksf-CM + 0x26c00000: 438, // ksh + 0x26c00060: 439, // ksh-DE + 0x27200000: 440, // ku + 0x27f00000: 441, // kw + 0x27f0007b: 442, // kw-GB + 0x28800000: 443, // ky + 0x288000a5: 444, // ky-KG + 0x28f00000: 445, // lag + 0x28f0012f: 446, // lag-TZ + 0x29300000: 447, // lb + 0x293000b7: 448, // lb-LU + 0x2a100000: 449, // lg + 0x2a100131: 450, // lg-UG + 0x2ad00000: 451, // lkt + 0x2ad00135: 452, // lkt-US + 0x2b300000: 453, // ln + 0x2b30002a: 454, // ln-AO + 0x2b30004b: 455, // ln-CD + 0x2b30004c: 456, // ln-CF + 0x2b30004d: 457, // ln-CG + 0x2b600000: 458, // lo + 0x2b6000af: 459, // lo-LA + 0x2bd00000: 460, // lrc + 0x2bd0009b: 461, // lrc-IQ + 0x2bd0009c: 462, // lrc-IR + 0x2be00000: 463, // lt + 0x2be000b6: 464, // lt-LT + 0x2c000000: 465, // lu + 0x2c00004b: 466, // lu-CD + 0x2c200000: 467, // luo + 0x2c2000a4: 468, // luo-KE + 0x2c300000: 469, // luy + 0x2c3000a4: 470, // luy-KE + 0x2c500000: 471, // lv + 0x2c5000b8: 472, // lv-LV + 0x2cf00000: 473, // mas + 0x2cf000a4: 474, // mas-KE + 0x2cf0012f: 475, // mas-TZ + 0x2e700000: 476, // mer + 0x2e7000a4: 477, // mer-KE + 0x2eb00000: 478, // mfe + 0x2eb000cc: 479, // mfe-MU + 0x2ef00000: 480, // mg + 0x2ef000bf: 481, // mg-MG + 0x2f000000: 482, // mgh + 0x2f0000d1: 483, // mgh-MZ + 0x2f200000: 484, // mgo + 0x2f200052: 485, // mgo-CM + 0x2fd00000: 486, // mk + 0x2fd000c2: 487, // mk-MK + 0x30200000: 488, // ml + 0x30200099: 489, // ml-IN + 0x30900000: 490, // mn + 0x309000c5: 491, // mn-MN + 0x31900000: 492, // mr + 0x31900099: 493, // mr-IN + 0x31d00000: 494, // ms + 0x31d0003e: 495, // ms-BN + 0x31d000d0: 496, // ms-MY + 0x31d0010d: 497, // ms-SG + 0x31e00000: 498, // mt + 0x31e000cb: 499, // mt-MT + 0x32300000: 500, // mua + 0x32300052: 501, // mua-CM + 0x32f00000: 502, // my + 0x32f000c4: 503, // my-MM + 0x33800000: 504, // mzn + 0x3380009c: 505, // mzn-IR + 0x33f00000: 506, // nah + 0x34300000: 507, // naq + 0x343000d2: 508, // naq-NA + 0x34500000: 509, // nb + 0x345000da: 510, // nb-NO + 0x34500110: 511, // nb-SJ + 0x34c00000: 512, // nd + 0x34c00164: 513, // nd-ZW + 0x34e00000: 514, // nds + 0x34e00060: 515, // nds-DE + 0x34e000d9: 516, // nds-NL + 0x34f00000: 517, // ne + 0x34f00099: 518, // ne-IN + 0x34f000db: 519, // ne-NP + 0x36500000: 520, // nl + 0x36500030: 521, // nl-AW + 0x36500036: 522, // nl-BE + 0x36500040: 523, // nl-BQ + 0x3650005b: 524, // nl-CW + 0x365000d9: 525, // nl-NL + 0x36500116: 526, // nl-SR + 0x3650011b: 527, // nl-SX + 0x36600000: 528, // nmg + 0x36600052: 529, // nmg-CM + 0x36800000: 530, // nn + 0x368000da: 531, // nn-NO + 0x36a00000: 532, // nnh + 0x36a00052: 533, // nnh-CM + 0x36d00000: 534, // no + 0x37300000: 535, // nqo + 0x37400000: 536, // nr + 0x37800000: 537, // nso + 0x37e00000: 538, // nus + 0x37e00117: 539, // nus-SS + 0x38500000: 540, // ny + 0x38700000: 541, // nyn + 0x38700131: 542, // nyn-UG + 0x38e00000: 543, // om + 0x38e0006f: 544, // om-ET + 0x38e000a4: 545, // om-KE + 0x39300000: 546, // or + 0x39300099: 547, // or-IN + 0x39600000: 548, // os + 0x3960007d: 549, // os-GE + 0x39600106: 550, // os-RU + 0x39b00000: 551, // pa + 0x39b05000: 552, // pa-Arab + 0x39b050e8: 553, // pa-Arab-PK + 0x39b32000: 554, // pa-Guru + 0x39b32099: 555, // pa-Guru-IN + 0x39f00000: 556, // pap + 0x3b100000: 557, // pl + 0x3b1000e9: 558, // pl-PL + 0x3bb00000: 559, // prg + 0x3bb00001: 560, // prg-001 + 0x3bc00000: 561, // ps + 0x3bc00024: 562, // ps-AF + 0x3be00000: 563, // pt + 0x3be0002a: 564, // pt-AO + 0x3be00041: 565, // pt-BR + 0x3be0004e: 566, // pt-CH + 0x3be0005a: 567, // pt-CV + 0x3be00086: 568, // pt-GQ + 0x3be0008b: 569, // pt-GW + 0x3be000b7: 570, // pt-LU + 0x3be000c6: 571, // pt-MO + 0x3be000d1: 572, // pt-MZ + 0x3be000ee: 573, // pt-PT + 0x3be00118: 574, // pt-ST + 0x3be00126: 575, // pt-TL + 0x3c200000: 576, // qu + 0x3c20003f: 577, // qu-BO + 0x3c200069: 578, // qu-EC + 0x3c2000e4: 579, // qu-PE + 0x3d200000: 580, // rm + 0x3d20004e: 581, // rm-CH + 0x3d700000: 582, // rn + 0x3d70003a: 583, // rn-BI + 0x3da00000: 584, // ro + 0x3da000bc: 585, // ro-MD + 0x3da00104: 586, // ro-RO + 0x3dc00000: 587, // rof + 0x3dc0012f: 588, // rof-TZ + 0x3e000000: 589, // ru + 0x3e000047: 590, // ru-BY + 0x3e0000a5: 591, // ru-KG + 0x3e0000ae: 592, // ru-KZ + 0x3e0000bc: 593, // ru-MD + 0x3e000106: 594, // ru-RU + 0x3e000130: 595, // ru-UA + 0x3e300000: 596, // rw + 0x3e300107: 597, // rw-RW + 0x3e400000: 598, // rwk + 0x3e40012f: 599, // rwk-TZ + 0x3e900000: 600, // sah + 0x3e900106: 601, // sah-RU + 0x3ea00000: 602, // saq + 0x3ea000a4: 603, // saq-KE + 0x3f100000: 604, // sbp + 0x3f10012f: 605, // sbp-TZ + 0x3fa00000: 606, // sdh + 0x3fb00000: 607, // se + 0x3fb00072: 608, // se-FI + 0x3fb000da: 609, // se-NO + 0x3fb0010c: 610, // se-SE + 0x3fd00000: 611, // seh + 0x3fd000d1: 612, // seh-MZ + 0x3ff00000: 613, // ses + 0x3ff000c3: 614, // ses-ML + 0x40000000: 615, // sg + 0x4000004c: 616, // sg-CF + 0x40600000: 617, // shi + 0x40655000: 618, // shi-Latn + 0x406550ba: 619, // shi-Latn-MA + 0x406d8000: 620, // shi-Tfng + 0x406d80ba: 621, // shi-Tfng-MA + 0x40a00000: 622, // si + 0x40a000b3: 623, // si-LK + 0x41000000: 624, // sk + 0x41000111: 625, // sk-SK + 0x41400000: 626, // sl + 0x4140010f: 627, // sl-SI + 0x41a00000: 628, // sma + 0x41b00000: 629, // smi + 0x41c00000: 630, // smj + 0x41d00000: 631, // smn + 0x41d00072: 632, // smn-FI + 0x42000000: 633, // sms + 0x42100000: 634, // sn + 0x42100164: 635, // sn-ZW + 0x42700000: 636, // so + 0x42700062: 637, // so-DJ + 0x4270006f: 638, // so-ET + 0x427000a4: 639, // so-KE + 0x42700115: 640, // so-SO + 0x42f00000: 641, // sq + 0x42f00027: 642, // sq-AL + 0x42f000c2: 643, // sq-MK + 0x42f0014d: 644, // sq-XK + 0x43000000: 645, // sr + 0x4301e000: 646, // sr-Cyrl + 0x4301e033: 647, // sr-Cyrl-BA + 0x4301e0bd: 648, // sr-Cyrl-ME + 0x4301e105: 649, // sr-Cyrl-RS + 0x4301e14d: 650, // sr-Cyrl-XK + 0x43055000: 651, // sr-Latn + 0x43055033: 652, // sr-Latn-BA + 0x430550bd: 653, // sr-Latn-ME + 0x43055105: 654, // sr-Latn-RS + 0x4305514d: 655, // sr-Latn-XK + 0x43500000: 656, // ss + 0x43800000: 657, // ssy + 0x43900000: 658, // st + 0x44200000: 659, // sv + 0x44200031: 660, // sv-AX + 0x44200072: 661, // sv-FI + 0x4420010c: 662, // sv-SE + 0x44300000: 663, // sw + 0x4430004b: 664, // sw-CD + 0x443000a4: 665, // sw-KE + 0x4430012f: 666, // sw-TZ + 0x44300131: 667, // sw-UG + 0x44c00000: 668, // syr + 0x44e00000: 669, // ta + 0x44e00099: 670, // ta-IN + 0x44e000b3: 671, // ta-LK + 0x44e000d0: 672, // ta-MY + 0x44e0010d: 673, // ta-SG + 0x45f00000: 674, // te + 0x45f00099: 675, // te-IN + 0x46200000: 676, // teo + 0x462000a4: 677, // teo-KE + 0x46200131: 678, // teo-UG + 0x46900000: 679, // th + 0x46900123: 680, // th-TH + 0x46d00000: 681, // ti + 0x46d0006d: 682, // ti-ER + 0x46d0006f: 683, // ti-ET + 0x46f00000: 684, // tig + 0x47400000: 685, // tk + 0x47400127: 686, // tk-TM + 0x47e00000: 687, // tn + 0x48000000: 688, // to + 0x48000129: 689, // to-TO + 0x48800000: 690, // tr + 0x4880005d: 691, // tr-CY + 0x4880012b: 692, // tr-TR + 0x48c00000: 693, // ts + 0x4a200000: 694, // twq + 0x4a2000d4: 695, // twq-NE + 0x4a700000: 696, // tzm + 0x4a7000ba: 697, // tzm-MA + 0x4aa00000: 698, // ug + 0x4aa00053: 699, // ug-CN + 0x4ac00000: 700, // uk + 0x4ac00130: 701, // uk-UA + 0x4b200000: 702, // ur + 0x4b200099: 703, // ur-IN + 0x4b2000e8: 704, // ur-PK + 0x4ba00000: 705, // uz + 0x4ba05000: 706, // uz-Arab + 0x4ba05024: 707, // uz-Arab-AF + 0x4ba1e000: 708, // uz-Cyrl + 0x4ba1e137: 709, // uz-Cyrl-UZ + 0x4ba55000: 710, // uz-Latn + 0x4ba55137: 711, // uz-Latn-UZ + 0x4bc00000: 712, // vai + 0x4bc55000: 713, // vai-Latn + 0x4bc550b4: 714, // vai-Latn-LR + 0x4bcdf000: 715, // vai-Vaii + 0x4bcdf0b4: 716, // vai-Vaii-LR + 0x4be00000: 717, // ve + 0x4c100000: 718, // vi + 0x4c10013e: 719, // vi-VN + 0x4c700000: 720, // vo + 0x4c700001: 721, // vo-001 + 0x4ca00000: 722, // vun + 0x4ca0012f: 723, // vun-TZ + 0x4cc00000: 724, // wa + 0x4cd00000: 725, // wae + 0x4cd0004e: 726, // wae-CH + 0x4e300000: 727, // wo + 0x4f000000: 728, // xh + 0x4f900000: 729, // xog + 0x4f900131: 730, // xog-UG + 0x50700000: 731, // yav + 0x50700052: 732, // yav-CM + 0x51000000: 733, // yi + 0x51000001: 734, // yi-001 + 0x51600000: 735, // yo + 0x5160003b: 736, // yo-BJ + 0x516000d6: 737, // yo-NG + 0x51d00000: 738, // yue + 0x51d0008d: 739, // yue-HK + 0x52600000: 740, // zgh + 0x526000ba: 741, // zgh-MA + 0x52700000: 742, // zh + 0x52737000: 743, // zh-Hans + 0x52737053: 744, // zh-Hans-CN + 0x5273708d: 745, // zh-Hans-HK + 0x527370c6: 746, // zh-Hans-MO + 0x5273710d: 747, // zh-Hans-SG + 0x52738000: 748, // zh-Hant + 0x5273808d: 749, // zh-Hant-HK + 0x527380c6: 750, // zh-Hant-MO + 0x5273812e: 751, // zh-Hant-TW + 0x52c00000: 752, // zu + 0x52c00161: 753, // zu-ZA +} + +// Total table size 4592 bytes (4KiB); checksum: C25F8AFF 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 0000000..ed1011f --- /dev/null +++ b/vendor/golang.org/x/text/language/language.go @@ -0,0 +1,887 @@ +// 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 gen.go gen_common.go -output tables.go +//go:generate go run gen_index.go + +package 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 + // TODO: we will soon run out of positions for script. Idea: instead of + // storing lang, region, and script codes, store only the compact index and + // have a lookup table from this code to its expansion. This greatly speeds + // up table lookup, speed up common variant cases. + // This will also immediately free up 3 extra bytes. Also, the pVariant + // field can now be moved to the lookup table, as the compact index uniquely + // determines the offset of a possible variant. + 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 0000000..1d80ac3 --- /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/match.go b/vendor/golang.org/x/text/language/match.go new file mode 100644 index 0000000..15b74d1 --- /dev/null +++ b/vendor/golang.org/x/text/language/match.go @@ -0,0 +1,933 @@ +// 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" + +// A MatchOption configures a Matcher. +type MatchOption func(*matcher) + +// PreferSameScript will, in the absence of a match, result in the first +// preferred tag with the same script as a supported tag to match this supported +// tag. The default is currently true, but this may change in the future. +func PreferSameScript(preferSame bool) MatchOption { + return func(m *matcher) { m.preferSameScript = preferSame } +} + +// TODO(v1.0.0): consider making Matcher a concrete type, instead of interface. +// There doesn't seem to be too much need for multiple types. +// Making it a concrete type allows MatchStrings to be a method, which will +// improve its discoverability. + +// MatchStrings parses and matches the given strings until one of them matches +// the language in the Matcher. A string may be an Accept-Language header as +// handled by ParseAcceptLanguage. The default language is returned if no +// other language matched. +func MatchStrings(m Matcher, lang ...string) (tag Tag, index int) { + for _, accept := range lang { + desired, _, err := ParseAcceptLanguage(accept) + if err != nil { + continue + } + if tag, index, conf := m.Match(desired...); conf != No { + return tag, index + } + } + tag, index, _ = m.Match() + return +} + +// 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, options ...MatchOption) Matcher { + return newMatcher(t, options) +} + +func (m *matcher) Match(want ...Tag) (t Tag, index int, c Confidence) { + match, w, c := m.getBest(want...) + if match != nil { + t, index = match.tag, match.index + } else { + // TODO: this should be an option + t = m.default_.tag + if m.preferSameScript { + outer: + for _, w := range want { + script, _ := w.Script() + if script.scriptID == 0 { + // Don't do anything if there is no script, such as with + // private subtags. + continue + } + for i, h := range m.supported { + if script.scriptID == h.maxScript { + t, index = h.tag, i + break outer + } + } + } + } + // TODO: select first language tag based on script. + } + if w.region != 0 && t.region != 0 && t.region.contains(w.region) { + t, _ = Raw.Compose(t, Region{w.region}) + } + // 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: add in alternative variants to -u-va-. + // TODO: add preferred region to -u-rg-. + if e := w.Extensions(); len(e) > 0 { + t, _ = Raw.Compose(t, e) + } + 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 an 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 Exact and pin is true the result will be +// frozen to the language found thusfar, although better matches may +// still be found for the same language. +// 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: +// [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 + supported []*haveTag + index map[langID]*matchHeader + passSettings bool + preferSameScript 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 { + haveTags []*haveTag + original bool +} + +// 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 || tag.region != 0 || tag.script != 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 { + // TODO: also match cases where language is not the same. + if (langID(alt.wantLang) == l || langID(alt.haveLang) == l) && + scriptID(alt.haveScript) == s { + return scriptID(alt.wantScript) + } + } + 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) { + h.original = h.original || exact + // Don't add new exact matches. + for _, v := range h.haveTags { + if v.tag.equalsRest(n.tag) { + return + } + } + // Allow duplicate maximized tags, but create a linked list to allow quickly + // comparing the equivalents and bail out. + for i, v := range h.haveTags { + if v.maxScript == n.maxScript && + v.maxRegion == n.maxRegion && + v.tag.variantOrPrivateTagStr() == n.tag.variantOrPrivateTagStr() { + for h.haveTags[i].nextMax != 0 { + i = int(h.haveTags[i].nextMax) + } + h.haveTags[i].nextMax = uint16(len(h.haveTags)) + break + } + } + h.haveTags = append(h.haveTags, &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 +} + +func toConf(d uint8) Confidence { + if d <= 10 { + return High + } + if d < 30 { + return Low + } + return No +} + +// 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, options []MatchOption) *matcher { + m := &matcher{ + index: make(map[langID]*matchHeader), + preferSameScript: true, + } + for _, o := range options { + o(m) + } + 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.supported = append(m.supported, &pair) + } + m.default_ = m.header(supported[0].lang).haveTags[0] + // Keep these in two different loops to support the case that two equivalent + // languages are distinguished, such as iw and he. + for i, tag := range supported { + pair, max := makeHaveTag(tag, i) + if max != tag.lang { + m.header(max).addIfNew(pair, true) + } + } + + // update is used to add indexes in the map for equivalent languages. + // update will only add entries to original indexes, thus not computing any + // transitive relations. + update := func(want, have uint16, conf Confidence) { + if hh := m.index[langID(have)]; hh != nil { + if !hh.original { + return + } + hw := m.header(langID(want)) + for _, ht := range hh.haveTags { + 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 && hh.original) + } + } + } + + // Add entries for languages with mutual intelligibility as defined by CLDR's + // languageMatch data. + for _, ml := range matchLang { + update(ml.want, ml.have, toConf(ml.distance)) + if !ml.oneway { + update(ml.have, ml.want, toConf(ml.distance)) + } + } + + // 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 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) + } + update(lm.from, lm.to, conf) + } + 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 i, w := range want { + var max Tag + // Check for exact match first. + h := m.index[w.lang] + if w.lang != 0 { + if h == nil { + continue + } + // Base language is defined. + max, _ = w.canonicalize(Legacy | Deprecated | Macro) + // A region that is added through canonicalization is stronger than + // a maximized region: set it in the original (e.g. mo -> ro-MD). + if w.region != max.region { + w.region = max.region + } + // TODO: should we do the same for scripts? + // See test case: en, sr, nl ; sh ; sr + max, _ = addTags(max) + } else { + // Base language is not defined. + if h != nil { + for i := range h.haveTags { + have := h.haveTags[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 + } + } + pin := true + for _, t := range want[i+1:] { + if w.lang == t.lang { + pin = false + break + } + } + // Check for match based on maximized tag. + for i := range h.haveTags { + have := h.haveTags[i] + best.update(have, w, max.script, max.region, pin) + if best.conf == Exact { + for have.nextMax != 0 { + have = h.haveTags[have.nextMax] + best.update(have, w, max.script, max.region, pin) + } + return best.have, best.want, best.conf + } + } + } + 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 + pinnedRegion regionID + pinLanguage bool + sameRegionGroup bool + // Cached results from applying tie-breaking rules. + origLang bool + origReg bool + paradigmReg bool + regGroupDist uint8 + origScript bool +} + +// 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. +// +// If pin is true and have and tag are a strong match, it will henceforth only +// consider matches for this language. This corresponds to the nothing that most +// users have a strong preference for the first defined language. A user can +// still prefer a second language over a dialect of the preferred language by +// explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should +// be false. +func (m *bestMatch) update(have *haveTag, tag Tag, maxScript scriptID, maxRegion regionID, pin bool) { + // Bail if the maximum attainable confidence is below that of the current best match. + c := have.conf + if c < m.conf { + return + } + // Don't change the language once we already have found an exact match. + if m.pinLanguage && tag.lang != m.want.lang { + return + } + // Pin the region group if we are comparing tags for the same language. + if tag.lang == m.want.lang && m.sameRegionGroup { + _, sameGroup := regionGroupDist(m.pinnedRegion, have.maxRegion, have.maxScript, m.want.lang) + if !sameGroup { + return + } + } + if c == Exact && have.maxScript == maxScript { + // If there is another language and then another entry of this language, + // don't pin anything, otherwise pin the language. + m.pinLanguage = pin + } + if have.tag.equalsRest(tag) { + } else 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 { + if High < c { + // There is usually a small difference between languages across regions. + 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 + } + + regGroupDist, sameGroup := regionGroupDist(have.maxRegion, maxRegion, maxScript, tag.lang) + if !beaten && m.regGroupDist != regGroupDist { + if regGroupDist > m.regGroupDist { + return + } + beaten = true + } + + paradigmReg := isParadigmLocale(tag.lang, have.maxRegion) + if !beaten && m.paradigmReg != paradigmReg { + if !paradigmReg { + 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 + } + + // Update m to the newly found best match. + if beaten { + m.have = have + m.want = tag + m.conf = c + m.pinnedRegion = maxRegion + m.sameRegionGroup = sameGroup + m.origLang = origLang + m.origReg = origReg + m.paradigmReg = paradigmReg + m.origScript = origScript + m.regGroupDist = regGroupDist + } +} + +func isParadigmLocale(lang langID, r regionID) bool { + for _, e := range paradigmLocales { + if langID(e[0]) == lang && (r == regionID(e[1]) || r == regionID(e[2])) { + return true + } + } + return false +} + +// regionGroupDist computes the distance between two regions based on their +// CLDR grouping. +func regionGroupDist(a, b regionID, script scriptID, lang langID) (dist uint8, same bool) { + const defaultDistance = 4 + + aGroup := uint(regionToGroups[a]) << 1 + bGroup := uint(regionToGroups[b]) << 1 + for _, ri := range matchRegion { + if langID(ri.lang) == lang && (ri.script == 0 || scriptID(ri.script) == script) { + group := uint(1 << (ri.group &^ 0x80)) + if 0x80&ri.group == 0 { + if aGroup&bGroup&group != 0 { // Both regions are in the group. + return ri.distance, ri.distance == defaultDistance + } + } else { + if (aGroup|bGroup)&group == 0 { // Both regions are not in the group. + return ri.distance, ri.distance == defaultDistance + } + } + } + } + return defaultDistance, true +} + +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)) + } + } + // Maximize undefined regions of paradigm locales. + for i, v := range paradigmLocales { + max, _ := addTags(Tag{lang: langID(v[0])}) + if v[1] == 0 { + paradigmLocales[i][1] = uint16(max.region) + } + if v[2] == 0 { + paradigmLocales[i][2] = uint16(max.region) + } + } +} 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 0000000..fca2d30 --- /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 an 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 0000000..ec17f97 --- /dev/null +++ b/vendor/golang.org/x/text/language/tables.go @@ -0,0 +1,3675 @@ +// Code generated by running "go generate" in golang.org/x/text. 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 = "31" + +const numLanguages = 8665 + +const numScripts = 237 + +const numRegions = 357 + +type fromTo struct { + from uint16 + to uint16 +} + +const nonCanonicalUnd = 1199 +const ( + _af = 22 + _am = 39 + _ar = 58 + _az = 88 + _bg = 126 + _bn = 165 + _ca = 215 + _cs = 249 + _da = 256 + _de = 268 + _el = 309 + _en = 312 + _es = 317 + _et = 319 + _fa = 327 + _fi = 336 + _fil = 338 + _fr = 349 + _gu = 418 + _he = 442 + _hi = 444 + _hr = 463 + _hu = 467 + _hy = 469 + _id = 479 + _is = 502 + _it = 503 + _ja = 510 + _ka = 526 + _kk = 576 + _km = 584 + _kn = 591 + _ko = 594 + _ky = 648 + _lo = 694 + _lt = 702 + _lv = 709 + _mk = 765 + _ml = 770 + _mn = 777 + _mo = 782 + _mr = 793 + _ms = 797 + _mul = 804 + _my = 815 + _nb = 837 + _ne = 847 + _nl = 869 + _no = 877 + _pa = 923 + _pl = 945 + _pt = 958 + _ro = 986 + _ru = 992 + _sh = 1029 + _si = 1034 + _sk = 1040 + _sl = 1044 + _sq = 1071 + _sr = 1072 + _sv = 1090 + _sw = 1091 + _ta = 1102 + _te = 1119 + _th = 1129 + _tl = 1144 + _tn = 1150 + _tr = 1160 + _uk = 1196 + _ur = 1202 + _uz = 1210 + _vi = 1217 + _zh = 1319 + _zu = 1324 + _jbo = 513 + _ami = 1647 + _bnn = 2354 + _hak = 436 + _tlh = 14464 + _lb = 659 + _nv = 897 + _pwn = 12052 + _tao = 14185 + _tay = 14195 + _tsu = 14659 + _nn = 872 + _sfb = 13626 + _vgt = 15698 + _sgg = 13657 + _cmn = 3004 + _nan = 833 + _hsn = 465 +) + +const langPrivateStart = 0x2f6f + +const langPrivateEnd = 0x3176 + +// 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. +const lang tag.Index = "" + // Size: 5312 bytes + "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" + + "cd\x00ace\x00ach\x00ada\x00ade\x00adj\x00ady\x00adz\x00aeveaeb\x00aey" + + "\x00affragc\x00agd\x00agg\x00agm\x00ago\x00agq\x00aha\x00ahl\x00aho\x00a" + + "jg\x00akkaakk\x00ala\x00ali\x00aln\x00alt\x00ammhamm\x00amn\x00amo\x00am" + + "p\x00anrganc\x00ank\x00ann\x00any\x00aoj\x00aom\x00aoz\x00apc\x00apd\x00" + + "ape\x00apr\x00aps\x00apz\x00arraarc\x00arh\x00arn\x00aro\x00arq\x00ars" + + "\x00ary\x00arz\x00assmasa\x00ase\x00asg\x00aso\x00ast\x00ata\x00atg\x00a" + + "tj\x00auy\x00avvaavl\x00avn\x00avt\x00avu\x00awa\x00awb\x00awo\x00awx" + + "\x00ayymayb\x00azzebaakbal\x00ban\x00bap\x00bar\x00bas\x00bav\x00bax\x00" + + "bba\x00bbb\x00bbc\x00bbd\x00bbj\x00bbp\x00bbr\x00bcf\x00bch\x00bci\x00bc" + + "m\x00bcn\x00bco\x00bcq\x00bcu\x00bdd\x00beelbef\x00beh\x00bej\x00bem\x00" + + "bet\x00bew\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\x00bjt\x00bjz\x00bkc\x00bkm\x00bkq\x00bku\x00bkv\x00blt" + + "\x00bmambmh\x00bmk\x00bmq\x00bmu\x00bnenbng\x00bnm\x00bnp\x00boodboj\x00" + + "bom\x00bon\x00bpy\x00bqc\x00bqi\x00bqp\x00bqv\x00brrebra\x00brh\x00brx" + + "\x00brz\x00bsosbsj\x00bsq\x00bss\x00bst\x00bto\x00btt\x00btv\x00bua\x00b" + + "uc\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\x00chm\x00cho\x00chp\x00chr\x00cja\x00cjm\x00cjv\x00ckb\x00c" + + "kl\x00cko\x00cky\x00cla\x00cme\x00cooscop\x00cps\x00crrecrh\x00crj\x00cr" + + "k\x00crl\x00crm\x00crs\x00csescsb\x00csw\x00ctd\x00cuhucvhvcyymdaandad" + + "\x00daf\x00dag\x00dah\x00dak\x00dar\x00dav\x00dbd\x00dbq\x00dcc\x00ddn" + + "\x00deeuded\x00den\x00dga\x00dgh\x00dgi\x00dgl\x00dgr\x00dgz\x00dia\x00d" + + "je\x00dnj\x00dob\x00doi\x00dop\x00dow\x00dri\x00drs\x00dsb\x00dtm\x00dtp" + + "\x00dts\x00dty\x00dua\x00duc\x00dud\x00dug\x00dvivdva\x00dww\x00dyo\x00d" + + "yu\x00dzzodzg\x00ebu\x00eeweefi\x00egl\x00egy\x00eka\x00eky\x00elllema" + + "\x00emi\x00enngenn\x00enq\x00eopoeri\x00es\x00\x05esu\x00etstetr\x00ett" + + "\x00etu\x00etx\x00euusewo\x00ext\x00faasfaa\x00fab\x00fag\x00fai\x00fan" + + "\x00ffulffi\x00ffm\x00fiinfia\x00fil\x00fit\x00fjijflr\x00fmp\x00foaofod" + + "\x00fon\x00for\x00fpe\x00fqs\x00frrafrc\x00frp\x00frr\x00frs\x00fub\x00f" + + "ud\x00fue\x00fuf\x00fuh\x00fuq\x00fur\x00fuv\x00fuy\x00fvr\x00fyrygalega" + + "a\x00gaf\x00gag\x00gah\x00gaj\x00gam\x00gan\x00gaw\x00gay\x00gbf\x00gbm" + + "\x00gby\x00gbz\x00gcr\x00gdlagde\x00gdn\x00gdr\x00geb\x00gej\x00gel\x00g" + + "ez\x00gfk\x00ggn\x00ghs\x00gil\x00gim\x00gjk\x00gjn\x00gju\x00gkn\x00gkp" + + "\x00gllgglk\x00gmm\x00gmv\x00gnrngnd\x00gng\x00god\x00gof\x00goi\x00gom" + + "\x00gon\x00gor\x00gos\x00got\x00grb\x00grc\x00grt\x00grw\x00gsw\x00guujg" + + "ub\x00guc\x00gud\x00gur\x00guw\x00gux\x00guz\x00gvlvgvf\x00gvr\x00gvs" + + "\x00gwc\x00gwi\x00gwt\x00gyi\x00haauhag\x00hak\x00ham\x00haw\x00haz\x00h" + + "bb\x00hdy\x00heebhhy\x00hiinhia\x00hif\x00hig\x00hih\x00hil\x00hla\x00hl" + + "u\x00hmd\x00hmt\x00hnd\x00hne\x00hnj\x00hnn\x00hno\x00homohoc\x00hoj\x00" + + "hot\x00hrrvhsb\x00hsn\x00htathuunhui\x00hyyehzerianaian\x00iar\x00iba" + + "\x00ibb\x00iby\x00ica\x00ich\x00idndidd\x00idi\x00idu\x00ieleife\x00igbo" + + "igb\x00ige\x00iiiiijj\x00ikpkikk\x00ikt\x00ikw\x00ikx\x00ilo\x00imo\x00i" + + "nndinh\x00iodoiou\x00iri\x00isslittaiukuiw\x00\x03iwm\x00iws\x00izh\x00i" + + "zi\x00japnjab\x00jam\x00jbo\x00jbu\x00jen\x00jgk\x00jgo\x00ji\x00\x06jib" + + "\x00jmc\x00jml\x00jra\x00jut\x00jvavjwavkaatkaa\x00kab\x00kac\x00kad\x00" + + "kai\x00kaj\x00kam\x00kao\x00kbd\x00kbm\x00kbp\x00kbq\x00kbx\x00kby\x00kc" + + "g\x00kck\x00kcl\x00kct\x00kde\x00kdh\x00kdl\x00kdt\x00kea\x00ken\x00kez" + + "\x00kfo\x00kfr\x00kfy\x00kgonkge\x00kgf\x00kgp\x00kha\x00khb\x00khn\x00k" + + "hq\x00khs\x00kht\x00khw\x00khz\x00kiikkij\x00kiu\x00kiw\x00kjuakjd\x00kj" + + "g\x00kjs\x00kjy\x00kkazkkc\x00kkj\x00klalkln\x00klq\x00klt\x00klx\x00kmh" + + "mkmb\x00kmh\x00kmo\x00kms\x00kmu\x00kmw\x00knanknf\x00knp\x00koorkoi\x00" + + "kok\x00kol\x00kos\x00koz\x00kpe\x00kpf\x00kpo\x00kpr\x00kpx\x00kqb\x00kq" + + "f\x00kqs\x00kqy\x00kraukrc\x00kri\x00krj\x00krl\x00krs\x00kru\x00ksasksb" + + "\x00ksd\x00ksf\x00ksh\x00ksj\x00ksr\x00ktb\x00ktm\x00kto\x00kuurkub\x00k" + + "ud\x00kue\x00kuj\x00kum\x00kun\x00kup\x00kus\x00kvomkvg\x00kvr\x00kvx" + + "\x00kw\x00\x01kwj\x00kwo\x00kxa\x00kxc\x00kxm\x00kxp\x00kxw\x00kxz\x00ky" + + "irkye\x00kyx\x00kzr\x00laatlab\x00lad\x00lag\x00lah\x00laj\x00las\x00lbt" + + "zlbe\x00lbu\x00lbw\x00lcm\x00lcp\x00ldb\x00led\x00lee\x00lem\x00lep\x00l" + + "eq\x00leu\x00lez\x00lguglgg\x00liimlia\x00lid\x00lif\x00lig\x00lih\x00li" + + "j\x00lis\x00ljp\x00lki\x00lkt\x00lle\x00lln\x00lmn\x00lmo\x00lmp\x00lnin" + + "lns\x00lnu\x00loaoloj\x00lok\x00lol\x00lor\x00los\x00loz\x00lrc\x00ltitl" + + "tg\x00luublua\x00luo\x00luy\x00luz\x00lvavlwl\x00lzh\x00lzz\x00mad\x00ma" + + "f\x00mag\x00mai\x00mak\x00man\x00mas\x00maw\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\x00m" + + "gp\x00mgy\x00mhahmhi\x00mhl\x00mirimif\x00min\x00mis\x00miw\x00mkkdmki" + + "\x00mkl\x00mkp\x00mkw\x00mlalmle\x00mlp\x00mls\x00mmo\x00mmu\x00mmx\x00m" + + "nonmna\x00mnf\x00mni\x00mnw\x00moolmoa\x00moe\x00moh\x00mos\x00mox\x00mp" + + "p\x00mps\x00mpt\x00mpx\x00mql\x00mrarmrd\x00mrj\x00mro\x00mssamtltmtc" + + "\x00mtf\x00mti\x00mtr\x00mua\x00mul\x00mur\x00mus\x00mva\x00mvn\x00mvy" + + "\x00mwk\x00mwr\x00mwv\x00mxc\x00mxm\x00myyamyk\x00mym\x00myv\x00myw\x00m" + + "yx\x00myz\x00mzk\x00mzm\x00mzn\x00mzp\x00mzw\x00mzz\x00naaunac\x00naf" + + "\x00nah\x00nak\x00nan\x00nap\x00naq\x00nas\x00nbobnca\x00nce\x00ncf\x00n" + + "ch\x00nco\x00ncu\x00nddendc\x00nds\x00neepneb\x00new\x00nex\x00nfr\x00ng" + + "donga\x00ngb\x00ngl\x00nhb\x00nhe\x00nhw\x00nif\x00nii\x00nij\x00nin\x00" + + "niu\x00niy\x00niz\x00njo\x00nkg\x00nko\x00nlldnmg\x00nmz\x00nnnonnf\x00n" + + "nh\x00nnk\x00nnm\x00noornod\x00noe\x00non\x00nop\x00nou\x00nqo\x00nrblnr" + + "b\x00nsk\x00nsn\x00nso\x00nss\x00ntm\x00ntr\x00nui\x00nup\x00nus\x00nuv" + + "\x00nux\x00nvavnwb\x00nxq\x00nxr\x00nyyanym\x00nyn\x00nzi\x00occiogc\x00" + + "ojjiokr\x00okv\x00omrmong\x00onn\x00ons\x00opm\x00orrioro\x00oru\x00osss" + + "osa\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\x00psuspss\x00ptorptp\x00puu\x00pwa" + + "\x00quuequc\x00qug\x00rai\x00raj\x00rao\x00rcf\x00rej\x00rel\x00res\x00r" + + "gn\x00rhg\x00ria\x00rif\x00rjs\x00rkt\x00rmohrmf\x00rmo\x00rmt\x00rmu" + + "\x00rnunrna\x00rng\x00roonrob\x00rof\x00roo\x00rro\x00rtm\x00ruusrue\x00" + + "rug\x00rw\x00\x04rwk\x00rwo\x00ryu\x00saansaf\x00sah\x00saq\x00sas\x00sa" + + "t\x00sav\x00saz\x00sba\x00sbe\x00sbp\x00scrdsck\x00scl\x00scn\x00sco\x00" + + "scs\x00sdndsdc\x00sdh\x00semesef\x00seh\x00sei\x00ses\x00sgagsga\x00sgs" + + "\x00sgw\x00sgz\x00sh\x00\x02shi\x00shk\x00shn\x00shu\x00siinsid\x00sig" + + "\x00sil\x00sim\x00sjr\x00sklkskc\x00skr\x00sks\x00sllvsld\x00sli\x00sll" + + "\x00sly\x00smmosma\x00smi\x00smj\x00smn\x00smp\x00smq\x00sms\x00snnasnc" + + "\x00snk\x00snp\x00snx\x00sny\x00soomsok\x00soq\x00sou\x00soy\x00spd\x00s" + + "pl\x00sps\x00sqqisrrpsrb\x00srn\x00srr\x00srx\x00ssswssd\x00ssg\x00ssy" + + "\x00stotstk\x00stq\x00suunsua\x00sue\x00suk\x00sur\x00sus\x00svweswwaswb" + + "\x00swc\x00swg\x00swp\x00swv\x00sxn\x00sxw\x00syl\x00syr\x00szl\x00taamt" + + "aj\x00tal\x00tan\x00taq\x00tbc\x00tbd\x00tbf\x00tbg\x00tbo\x00tbw\x00tbz" + + "\x00tci\x00tcy\x00tdd\x00tdg\x00tdh\x00teelted\x00tem\x00teo\x00tet\x00t" + + "fi\x00tggktgc\x00tgo\x00tgu\x00thhathl\x00thq\x00thr\x00tiirtif\x00tig" + + "\x00tik\x00tim\x00tio\x00tiv\x00tkuktkl\x00tkr\x00tkt\x00tlgltlf\x00tlx" + + "\x00tly\x00tmh\x00tmy\x00tnsntnh\x00toontof\x00tog\x00toq\x00tpi\x00tpm" + + "\x00tpz\x00tqo\x00trurtru\x00trv\x00trw\x00tssotsd\x00tsf\x00tsg\x00tsj" + + "\x00tsw\x00ttatttd\x00tte\x00ttj\x00ttr\x00tts\x00ttt\x00tuh\x00tul\x00t" + + "um\x00tuq\x00tvd\x00tvl\x00tvu\x00twwitwh\x00twq\x00txg\x00tyahtya\x00ty" + + "v\x00tzm\x00ubu\x00udm\x00ugiguga\x00ukkruli\x00umb\x00und\x00unr\x00unx" + + "\x00urrduri\x00urt\x00urw\x00usa\x00utr\x00uvh\x00uvl\x00uzzbvag\x00vai" + + "\x00van\x00veenvec\x00vep\x00viievic\x00viv\x00vls\x00vmf\x00vmw\x00vool" + + "vot\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\x00woolwob\x00wos\x00wrs\x00w" + + "sk\x00wtm\x00wuu\x00wuv\x00wwa\x00xav\x00xbi\x00xcr\x00xes\x00xhhoxla" + + "\x00xlc\x00xld\x00xmf\x00xmn\x00xmr\x00xna\x00xnr\x00xog\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\x00zbl\x00zdj\x00z" + + "ea\x00zgh\x00zhhozia\x00zlm\x00zmi\x00zne\x00zuulzxx\x00zza\x00\xff\xff" + + "\xff\xff" + +const langNoIndexOffset = 1327 + +// 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, 0xd3, 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, 0x7d, 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, 0x85, 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, 0x40, 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, 0xdf, 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, 0x64, 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, + 0xe7, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80, + 0x03, 0x00, 0x00, 0x00, 0x8c, 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, 0x7f, + 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, + 0x86, 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, 0x8f, 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, 0x06, 0xc4, + // 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, 0xd2, 0xb9, 0xff, 0xfd, 0x3f, + 0x1f, 0x98, 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, 0x92, 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, 0xcc, 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, + 0xb0, 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, 0x01, 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. +const 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{ + 0x027f, 0x0405, 0x01f9, 0x03e3, 0x013d, 0x0206, +} + +// langAliasMap maps langIDs to their suggested replacements. +// Size: 656 bytes, 164 elements +var langAliasMap = [164]fromTo{ + 0: {from: 0x82, to: 0x88}, + 1: {from: 0x185, to: 0x1ac}, + 2: {from: 0x1f1, to: 0x1df}, + 3: {from: 0x1f9, to: 0x1ba}, + 4: {from: 0x206, to: 0x510}, + 5: {from: 0x20d, to: 0x20c}, + 6: {from: 0x30e, to: 0x3da}, + 7: {from: 0x345, to: 0x36d}, + 8: {from: 0x405, to: 0x430}, + 9: {from: 0x478, to: 0x152}, + 10: {from: 0x48e, to: 0x44f}, + 11: {from: 0x4a0, to: 0x21}, + 12: {from: 0x53b, to: 0x541}, + 13: {from: 0x58c, to: 0x12c}, + 14: {from: 0x62d, to: 0x1eae}, + 15: {from: 0x64e, to: 0x42f}, + 16: {from: 0x65f, to: 0x42f}, + 17: {from: 0x6ea, to: 0x3a}, + 18: {from: 0x6f5, to: 0x1d5}, + 19: {from: 0x73b, to: 0x219e}, + 20: {from: 0x7b0, to: 0x56}, + 21: {from: 0x7b6, to: 0x2998}, + 22: {from: 0x7c2, to: 0x58}, + 23: {from: 0x7e3, to: 0x144}, + 24: {from: 0x809, to: 0x5a}, + 25: {from: 0x812, to: 0x8d}, + 26: {from: 0x87b, to: 0x80d}, + 27: {from: 0x8c0, to: 0xee0}, + 28: {from: 0x9ec, to: 0x32f}, + 29: {from: 0xa33, to: 0x2c3}, + 30: {from: 0xa3a, to: 0xbf}, + 31: {from: 0xabb, to: 0x331f}, + 32: {from: 0xb35, to: 0x527}, + 33: {from: 0xb72, to: 0x2657}, + 34: {from: 0xb7b, to: 0xbc0}, + 35: {from: 0xb98, to: 0x44c}, + 36: {from: 0xbb9, to: 0x4226}, + 37: {from: 0xbbc, to: 0x527}, + 38: {from: 0xbfb, to: 0x2da4}, + 39: {from: 0xc2b, to: 0x317e}, + 40: {from: 0xcb6, to: 0xf2}, + 41: {from: 0xd05, to: 0xf9}, + 42: {from: 0xdc5, to: 0x119}, + 43: {from: 0xdd4, to: 0x32b}, + 44: {from: 0xdf5, to: 0xdf8}, + 45: {from: 0xdfb, to: 0x52e}, + 46: {from: 0xedc, to: 0x2057}, + 47: {from: 0xeeb, to: 0x2e97}, + 48: {from: 0xf36, to: 0x365}, + 49: {from: 0x10cd, to: 0x13f}, + 50: {from: 0x1101, to: 0x2ce}, + 51: {from: 0x119d, to: 0x1ea}, + 52: {from: 0x1276, to: 0x21}, + 53: {from: 0x1421, to: 0x15d}, + 54: {from: 0x146d, to: 0x14d}, + 55: {from: 0x151c, to: 0xd98}, + 56: {from: 0x1520, to: 0x38e}, + 57: {from: 0x152f, to: 0x19d}, + 58: {from: 0x157d, to: 0x20e}, + 59: {from: 0x1580, to: 0x10c}, + 60: {from: 0x15a0, to: 0x3cac}, + 61: {from: 0x1667, to: 0x199}, + 62: {from: 0x16c5, to: 0x135}, + 63: {from: 0x16fd, to: 0x29f5}, + 64: {from: 0x1715, to: 0x192}, + 65: {from: 0x1724, to: 0xf3c}, + 66: {from: 0x1777, to: 0x1521}, + 67: {from: 0x1806, to: 0x17b3}, + 68: {from: 0x1813, to: 0x18f0}, + 69: {from: 0x1887, to: 0x434}, + 70: {from: 0x1976, to: 0x1cfe}, + 71: {from: 0x1a71, to: 0x2bad}, + 72: {from: 0x1a87, to: 0x1f6}, + 73: {from: 0x1b57, to: 0x1f8}, + 74: {from: 0x1b83, to: 0x1512}, + 75: {from: 0x1d61, to: 0x2c98}, + 76: {from: 0x2035, to: 0x37ae}, + 77: {from: 0x203a, to: 0x20da}, + 78: {from: 0x2057, to: 0x309}, + 79: {from: 0x20e0, to: 0x272}, + 80: {from: 0x20eb, to: 0x261}, + 81: {from: 0x20ef, to: 0x22b}, + 82: {from: 0x20f6, to: 0x254}, + 83: {from: 0x210c, to: 0x21e8}, + 84: {from: 0x2132, to: 0x27b}, + 85: {from: 0x215d, to: 0x910}, + 86: {from: 0x2196, to: 0x120}, + 87: {from: 0x21cb, to: 0x155e}, + 88: {from: 0x21e3, to: 0x502}, + 89: {from: 0x21f1, to: 0x49d}, + 90: {from: 0x222a, to: 0x120}, + 91: {from: 0x2234, to: 0x120}, + 92: {from: 0x225f, to: 0x927}, + 93: {from: 0x2313, to: 0x3223}, + 94: {from: 0x237f, to: 0x3362}, + 95: {from: 0x246f, to: 0x2c5}, + 96: {from: 0x24e1, to: 0x2fd}, + 97: {from: 0x24ed, to: 0x2f8}, + 98: {from: 0x24f7, to: 0x31d}, + 99: {from: 0x254d, to: 0xb58}, + 100: {from: 0x25a6, to: 0xe2}, + 101: {from: 0x263b, to: 0x2ce}, + 102: {from: 0x26c6, to: 0x26b1}, + 103: {from: 0x26f6, to: 0x3c6}, + 104: {from: 0x2724, to: 0x3cac}, + 105: {from: 0x2762, to: 0x26b1}, + 106: {from: 0x2786, to: 0x4355}, + 107: {from: 0x28ec, to: 0x2834}, + 108: {from: 0x2911, to: 0x34f}, + 109: {from: 0x2983, to: 0x2da4}, + 110: {from: 0x2b17, to: 0x38b}, + 111: {from: 0x2bf9, to: 0x393}, + 112: {from: 0x2c3c, to: 0x3cac}, + 113: {from: 0x2cf9, to: 0x3bc}, + 114: {from: 0x2d10, to: 0x594}, + 115: {from: 0x2d44, to: 0x147}, + 116: {from: 0x2d45, to: 0x147}, + 117: {from: 0x2dfc, to: 0x2ef}, + 118: {from: 0x2e05, to: 0x19c9}, + 119: {from: 0x2e17, to: 0x2d92}, + 120: {from: 0x2e1e, to: 0x290}, + 121: {from: 0x2e51, to: 0x7d}, + 122: {from: 0x2e62, to: 0x227f}, + 123: {from: 0x2e9d, to: 0x2e98}, + 124: {from: 0x2eec, to: 0x2ed4}, + 125: {from: 0x3190, to: 0x3c2}, + 126: {from: 0x3363, to: 0x338b}, + 127: {from: 0x3427, to: 0x3da}, + 128: {from: 0x34eb, to: 0x18cd}, + 129: {from: 0x35c5, to: 0x2c98}, + 130: {from: 0x35e3, to: 0x410}, + 131: {from: 0x3655, to: 0x244}, + 132: {from: 0x3673, to: 0x3f2}, + 133: {from: 0x36fa, to: 0x443}, + 134: {from: 0x37bd, to: 0x120}, + 135: {from: 0x3813, to: 0x38ef}, + 136: {from: 0x3828, to: 0x2c98}, + 137: {from: 0x382c, to: 0xa9}, + 138: {from: 0x382f, to: 0x3225}, + 139: {from: 0x3869, to: 0x39a3}, + 140: {from: 0x388f, to: 0x3fbd}, + 141: {from: 0x38a2, to: 0x39d4}, + 142: {from: 0x38b1, to: 0x1fa1}, + 143: {from: 0x38b2, to: 0x2e97}, + 144: {from: 0x3959, to: 0x47c}, + 145: {from: 0x3b4b, to: 0xd8e}, + 146: {from: 0x3b75, to: 0x136}, + 147: {from: 0x3c96, to: 0x4ba}, + 148: {from: 0x3fba, to: 0xff}, + 149: {from: 0x4205, to: 0xa8e}, + 150: {from: 0x42bb, to: 0x570}, + 151: {from: 0x42f6, to: 0x3f5d}, + 152: {from: 0x4375, to: 0x258}, + 153: {from: 0x43c8, to: 0x36c8}, + 154: {from: 0x43ca, to: 0x10e}, + 155: {from: 0x44ac, to: 0x331f}, + 156: {from: 0x44e0, to: 0x510}, + 157: {from: 0x45c7, to: 0x2406}, + 158: {from: 0x45da, to: 0x26d9}, + 159: {from: 0x460d, to: 0x48ab}, + 160: {from: 0x46ab, to: 0x469d}, + 161: {from: 0x473b, to: 0x4742}, + 162: {from: 0x4913, to: 0x31d}, + 163: {from: 0x49a4, to: 0x521}, +} + +// Size: 164 bytes, 164 elements +var langAliasTypes = [164]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, 0, 1, 1, + 1, 1, 1, 0, 1, 0, 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, + // Entry 80 - BF + 0, 0, 2, 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 = 85 + _Hani = 53 + _Hans = 55 + _Hant = 56 + _Qaaa = 136 + _Qaai = 144 + _Qabx = 185 + _Zinh = 231 + _Zyyy = 236 + _Zzzz = 237 +) + +// 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. +const script tag.Index = "" + // Size: 956 bytes + "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" + + "BrahBraiBugiBuhdCakmCansCariChamCherCirtCoptCprtCyrlCyrsDevaDogrDsrtDupl" + + "EgydEgyhEgypElbaEthiGeokGeorGlagGongGonmGothGranGrekGujrGuruHanbHangHani" + + "HanoHansHantHatrHebrHiraHluwHmngHrktHungIndsItalJamoJavaJpanJurcKaliKana" + + "KharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatfLatgLatnLekeLepcLimbLina" + + "LinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedfMendMercMeroMlymModiMong" + + "MoonMrooMteiMultMymrNarbNbatNewaNkgbNkooNshuOgamOlckOrkhOryaOsgeOsmaPalm" + + "PaucPermPhagPhliPhlpPhlvPhnxPiqdPlrdPrtiQaaaQaabQaacQaadQaaeQaafQaagQaah" + + "QaaiQaajQaakQaalQaamQaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaaz" + + "QabaQabbQabcQabdQabeQabfQabgQabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabr" + + "QabsQabtQabuQabvQabwQabxRjngRoroRunrSamrSaraSarbSaurSgnwShawShrdSiddSind" + + "SinhSoraSoyoSundSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTeng" + + "TfngTglgThaaThaiTibtTirhUgarVaiiVispWaraWoleXpeoXsuxYiiiZanbZinhZmthZsye" + + "ZsymZxxxZyyyZzzz\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: 1327 bytes, 1327 elements +var suppressScript = [1327]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, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 40 - 7F + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 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, + // 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, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 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, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + // Entry 100 - 13F + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, + 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, + // Entry 140 - 17F + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 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, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x00, 0x00, + // Entry 1C0 - 1FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x55, 0x00, 0x55, 0x55, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, + 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, + // Entry 200 - 23F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 240 - 27F + 0x1e, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x4e, 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, + // Entry 280 - 2BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x55, 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, 0x55, 0x00, 0x00, 0x52, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + // Entry 2C0 - 2FF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 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, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, + // Entry 300 - 33F + 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + // Entry 340 - 37F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x75, 0x55, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 380 - 3BF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x55, 0x00, + // Entry 3C0 - 3FF + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x55, 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 400 - 43F + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 440 - 47F + 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdb, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00, + // Entry 480 - 4BF + 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 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, 0x55, 0x00, + // Entry 4C0 - 4FF + 0x00, 0x55, 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, + 0x55, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 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, 0x55, 0x00, 0x00, +} + +const ( + _001 = 1 + _419 = 31 + _BR = 65 + _CA = 73 + _ES = 110 + _GB = 123 + _MD = 188 + _PT = 238 + _UK = 306 + _US = 309 + _ZZ = 357 + _XA = 323 + _XC = 325 + _XK = 333 +) + +// 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 = 32 + +// regionTypes defines the status of a region for various standards. +// Size: 358 bytes, 358 elements +var regionTypes = [358]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, 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, + // Entry 40 - 7F + 0x06, 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, + // Entry 80 - BF + 0x06, 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, + // Entry C0 - FF + 0x06, 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, + // Entry 100 - 13F + 0x05, 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, + // Entry 140 - 17F + 0x06, 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. +const 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. +const 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{ + 0x0057, 0x0070, 0x0088, 0x00a8, 0x00aa, 0x00ad, 0x00ea, 0x0105, + 0x0121, 0x015f, 0x00dc, +} + +// Size: 80 bytes, 20 elements +var regionOldMap = [20]fromTo{ + 0: {from: 0x44, to: 0xc4}, + 1: {from: 0x58, to: 0xa7}, + 2: {from: 0x5f, to: 0x60}, + 3: {from: 0x66, to: 0x3b}, + 4: {from: 0x79, to: 0x78}, + 5: {from: 0x93, to: 0x37}, + 6: {from: 0xa3, to: 0x133}, + 7: {from: 0xc1, to: 0x133}, + 8: {from: 0xd7, to: 0x13f}, + 9: {from: 0xdc, to: 0x2b}, + 10: {from: 0xef, to: 0x133}, + 11: {from: 0xf2, to: 0xe2}, + 12: {from: 0xfc, to: 0x70}, + 13: {from: 0x103, to: 0x164}, + 14: {from: 0x12a, to: 0x126}, + 15: {from: 0x132, to: 0x7b}, + 16: {from: 0x13a, to: 0x13e}, + 17: {from: 0x141, to: 0x133}, + 18: {from: 0x15d, to: 0x15e}, + 19: {from: 0x163, to: 0x4b}, +} + +// m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are +// codes indicating collections of regions. +// Size: 716 bytes, 358 elements +var m49 = [358]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, 202, 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, + // Entry 40 - 7F + 535, 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, + // Entry 80 - BF + 288, 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, + // Entry C0 - FF + 584, 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, + // Entry 100 - 13F + 971, 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, + // Entry 140 - 17F + 876, 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, 108, 143, 181, 220, 259, 291, + 333, +} + +// fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details. +// Size: 666 bytes, 333 elements +var fromM49 = [333]uint16{ + // Entry 0 - 3F + 0x0201, 0x0402, 0x0603, 0x0824, 0x0a04, 0x1027, 0x1205, 0x142b, + 0x1606, 0x1867, 0x1a07, 0x1c08, 0x1e09, 0x202d, 0x220a, 0x240b, + 0x260c, 0x2822, 0x2a0d, 0x302a, 0x3825, 0x3a0e, 0x3c0f, 0x3e32, + 0x402c, 0x4410, 0x4611, 0x482f, 0x4e12, 0x502e, 0x5842, 0x6039, + 0x6435, 0x6628, 0x6834, 0x6a13, 0x6c14, 0x7036, 0x7215, 0x783d, + 0x7a16, 0x8043, 0x883f, 0x8c33, 0x9046, 0x9445, 0x9841, 0xa848, + 0xac9a, 0xb509, 0xb93c, 0xc03e, 0xc838, 0xd0c4, 0xd83a, 0xe047, + 0xe8a6, 0xf052, 0xf849, 0x085a, 0x10ad, 0x184c, 0x1c17, 0x1e18, + // Entry 40 - 7F + 0x20b3, 0x2219, 0x2920, 0x2c1a, 0x2e1b, 0x3051, 0x341c, 0x361d, + 0x3853, 0x3d2e, 0x445c, 0x4c4a, 0x5454, 0x5ca8, 0x5f5f, 0x644d, + 0x684b, 0x7050, 0x7856, 0x7e90, 0x8059, 0x885d, 0x941e, 0x965e, + 0x983b, 0xa063, 0xa864, 0xac65, 0xb469, 0xbd1a, 0xc486, 0xcc6f, + 0xce6f, 0xd06d, 0xd26a, 0xd476, 0xdc74, 0xde88, 0xe473, 0xec72, + 0xf031, 0xf279, 0xf478, 0xfc7e, 0x04e5, 0x0921, 0x0c62, 0x147a, + 0x187d, 0x1c83, 0x26ed, 0x2860, 0x2c5f, 0x3060, 0x4080, 0x4881, + 0x50a7, 0x5887, 0x6082, 0x687c, 0x7085, 0x788a, 0x8089, 0x8884, + // Entry 80 - BF + 0x908c, 0x9891, 0x9c8e, 0xa138, 0xa88f, 0xb08d, 0xb892, 0xc09d, + 0xc899, 0xd095, 0xd89c, 0xe09b, 0xe896, 0xf097, 0xf89e, 0x004f, + 0x08a0, 0x10a2, 0x1cae, 0x20a1, 0x28a4, 0x30aa, 0x34ab, 0x3cac, + 0x42a5, 0x44af, 0x461f, 0x4cb0, 0x54b5, 0x58b8, 0x5cb4, 0x64b9, + 0x6cb2, 0x70b6, 0x74b7, 0x7cc6, 0x84bf, 0x8cce, 0x94d0, 0x9ccd, + 0xa4c3, 0xaccb, 0xb4c8, 0xbcc9, 0xc0cc, 0xc8cf, 0xd8bb, 0xe0c5, + 0xe4bc, 0xe6bd, 0xe8ca, 0xf0ba, 0xf8d1, 0x00e1, 0x08d2, 0x10dd, + 0x18db, 0x20d9, 0x2429, 0x265b, 0x2a30, 0x2d1b, 0x2e40, 0x30de, + // Entry C0 - FF + 0x38d3, 0x493f, 0x54e0, 0x5cd8, 0x64d4, 0x6cd6, 0x74df, 0x7cd5, + 0x84da, 0x88c7, 0x8b33, 0x8e75, 0x90c0, 0x92f0, 0x94e8, 0x9ee2, + 0xace6, 0xb0f1, 0xb8e4, 0xc0e7, 0xc8eb, 0xd0e9, 0xd8ee, 0xe08b, + 0xe526, 0xecec, 0xf4f3, 0xfd02, 0x0504, 0x0706, 0x0d07, 0x183c, + 0x1d0e, 0x26a9, 0x2826, 0x2cb1, 0x2ebe, 0x34ea, 0x3d39, 0x4513, + 0x4d18, 0x5508, 0x5d14, 0x6105, 0x650a, 0x6d12, 0x7d0d, 0x7f11, + 0x813e, 0x830f, 0x8515, 0x8d61, 0x9964, 0xa15d, 0xa86e, 0xb117, + 0xb30b, 0xb86c, 0xc10b, 0xc916, 0xd110, 0xd91d, 0xe10c, 0xe84e, + // Entry 100 - 13F + 0xf11c, 0xf524, 0xf923, 0x0122, 0x0925, 0x1129, 0x192c, 0x2023, + 0x2928, 0x312b, 0x3727, 0x391f, 0x3d2d, 0x4131, 0x4930, 0x4ec2, + 0x5519, 0x646b, 0x747b, 0x7e7f, 0x809f, 0x8298, 0x852f, 0x9135, + 0xa53d, 0xac37, 0xb536, 0xb937, 0xbd3b, 0xd940, 0xe542, 0xed5e, + 0xef5e, 0xf657, 0xfd62, 0x7c20, 0x7ef4, 0x80f5, 0x82f6, 0x84f7, + 0x86f8, 0x88f9, 0x8afa, 0x8cfb, 0x8e70, 0x90fd, 0x92fe, 0x94ff, + 0x9700, 0x9901, 0x9b43, 0x9d44, 0x9f45, 0xa146, 0xa347, 0xa548, + 0xa749, 0xa94a, 0xab4b, 0xad4c, 0xaf4d, 0xb14e, 0xb34f, 0xb550, + // Entry 140 - 17F + 0xb751, 0xb952, 0xbb53, 0xbd54, 0xbf55, 0xc156, 0xc357, 0xc558, + 0xc759, 0xc95a, 0xcb5b, 0xcd5c, 0xcf65, +} + +// Size: 1615 bytes +var variantIndex = map[string]uint8{ + "1606nict": 0x0, + "1694acad": 0x1, + "1901": 0x2, + "1959acad": 0x3, + "1994": 0x4d, + "1996": 0x4, + "abl1943": 0x5, + "akuapem": 0x6, + "alalc97": 0x4f, + "aluku": 0x7, + "ao1990": 0x8, + "arevela": 0x9, + "arevmda": 0xa, + "asante": 0xb, + "baku1926": 0xc, + "balanka": 0xd, + "barla": 0xe, + "basiceng": 0xf, + "bauddha": 0x10, + "biscayan": 0x11, + "biske": 0x48, + "bohoric": 0x12, + "boont": 0x13, + "colb1945": 0x14, + "cornu": 0x15, + "dajnko": 0x16, + "ekavsk": 0x17, + "emodeng": 0x18, + "fonipa": 0x50, + "fonnapa": 0x51, + "fonupa": 0x52, + "fonxsamp": 0x53, + "hepburn": 0x19, + "heploc": 0x4e, + "hognorsk": 0x1a, + "hsistemo": 0x1b, + "ijekavsk": 0x1c, + "itihasa": 0x1d, + "jauer": 0x1e, + "jyutping": 0x1f, + "kkcor": 0x20, + "kociewie": 0x21, + "kscor": 0x22, + "laukika": 0x23, + "lipaw": 0x49, + "luna1918": 0x24, + "metelko": 0x25, + "monoton": 0x26, + "ndyuka": 0x27, + "nedis": 0x28, + "newfound": 0x29, + "njiva": 0x4a, + "nulik": 0x2a, + "osojs": 0x4b, + "oxendict": 0x2b, + "pahawh2": 0x2c, + "pahawh3": 0x2d, + "pahawh4": 0x2e, + "pamaka": 0x2f, + "petr1708": 0x30, + "pinyin": 0x31, + "polyton": 0x32, + "puter": 0x33, + "rigik": 0x34, + "rozaj": 0x35, + "rumgr": 0x36, + "scotland": 0x37, + "scouse": 0x38, + "simple": 0x54, + "solba": 0x4c, + "sotav": 0x39, + "spanglis": 0x3a, + "surmiran": 0x3b, + "sursilv": 0x3c, + "sutsilv": 0x3d, + "tarask": 0x3e, + "uccor": 0x3f, + "ucrcor": 0x40, + "ulster": 0x41, + "unifon": 0x42, + "vaidika": 0x43, + "valencia": 0x44, + "vallader": 0x45, + "wadegile": 0x46, + "xsistemo": 0x47, +} + +// variantNumSpecialized is the number of specialized variants in variants. +const variantNumSpecialized = 79 + +// nRegionGroups is the number of region groups. +const nRegionGroups = 33 + +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: 956 bytes, 239 elements +var likelyScript = [239]likelyLangRegion{ + 1: {lang: 0x14d, region: 0x84}, + 3: {lang: 0x2a0, region: 0x106}, + 4: {lang: 0x1f, region: 0x99}, + 5: {lang: 0x3a, region: 0x6b}, + 7: {lang: 0x3b, region: 0x9c}, + 8: {lang: 0x1d5, region: 0x28}, + 9: {lang: 0x13, region: 0x9c}, + 10: {lang: 0x5b, region: 0x95}, + 11: {lang: 0x60, region: 0x52}, + 12: {lang: 0xb9, region: 0xb4}, + 13: {lang: 0x63, region: 0x95}, + 14: {lang: 0xa5, region: 0x35}, + 15: {lang: 0x3e7, region: 0x99}, + 17: {lang: 0x527, region: 0x12e}, + 18: {lang: 0x3af, region: 0x99}, + 19: {lang: 0x15d, region: 0x78}, + 20: {lang: 0xc2, region: 0x95}, + 21: {lang: 0x9d, region: 0xe7}, + 22: {lang: 0xdb, region: 0x35}, + 23: {lang: 0xf2, region: 0x49}, + 24: {lang: 0x4ee, region: 0x12b}, + 25: {lang: 0xe7, region: 0x13e}, + 26: {lang: 0xe5, region: 0x135}, + 28: {lang: 0xf0, region: 0x6b}, + 29: {lang: 0x19e, region: 0x5d}, + 30: {lang: 0x3e0, region: 0x106}, + 32: {lang: 0x1bc, region: 0x99}, + 35: {lang: 0x15d, region: 0x78}, + 38: {lang: 0x132, region: 0x6b}, + 39: {lang: 0x42f, region: 0x27}, + 40: {lang: 0x27, region: 0x6f}, + 42: {lang: 0x20e, region: 0x7d}, + 43: {lang: 0xfd, region: 0x38}, + 46: {lang: 0x19c, region: 0x130}, + 47: {lang: 0x3e7, region: 0x99}, + 48: {lang: 0x135, region: 0x87}, + 49: {lang: 0x1a2, region: 0x99}, + 50: {lang: 0x39b, region: 0x99}, + 51: {lang: 0x527, region: 0x12e}, + 52: {lang: 0x252, region: 0xab}, + 53: {lang: 0x527, region: 0x53}, + 54: {lang: 0x1c9, region: 0xe7}, + 55: {lang: 0x527, region: 0x53}, + 56: {lang: 0x527, region: 0x12e}, + 57: {lang: 0x2fb, region: 0x9b}, + 58: {lang: 0x1ba, region: 0x97}, + 59: {lang: 0x1fe, region: 0xa2}, + 60: {lang: 0x1c3, region: 0x12b}, + 61: {lang: 0x1c8, region: 0xaf}, + 63: {lang: 0x1d3, region: 0x92}, + 65: {lang: 0x141, region: 0x9e}, + 66: {lang: 0x252, region: 0xab}, + 67: {lang: 0x20c, region: 0x95}, + 68: {lang: 0x1fe, region: 0xa2}, + 70: {lang: 0x134, region: 0xc4}, + 71: {lang: 0x1fe, region: 0xa2}, + 72: {lang: 0x3b9, region: 0xe8}, + 73: {lang: 0x248, region: 0xa6}, + 74: {lang: 0x3f8, region: 0x99}, + 77: {lang: 0x24f, region: 0x99}, + 78: {lang: 0x252, region: 0xab}, + 80: {lang: 0x88, region: 0x99}, + 81: {lang: 0x36e, region: 0x123}, + 82: {lang: 0x2b6, region: 0xaf}, + 87: {lang: 0x29d, region: 0x99}, + 88: {lang: 0x2a6, region: 0x99}, + 89: {lang: 0x28d, region: 0x87}, + 90: {lang: 0x19e, region: 0x87}, + 91: {lang: 0x2aa, region: 0x53}, + 93: {lang: 0x4f2, region: 0x12b}, + 94: {lang: 0x4f3, region: 0x12b}, + 95: {lang: 0x1bc, region: 0x99}, + 97: {lang: 0x335, region: 0x9c}, + 98: {lang: 0x4f5, region: 0x53}, + 99: {lang: 0xa9, region: 0x53}, + 102: {lang: 0x2e6, region: 0x112}, + 103: {lang: 0x4f6, region: 0x10b}, + 104: {lang: 0x4f6, region: 0x10b}, + 105: {lang: 0x302, region: 0x99}, + 106: {lang: 0x319, region: 0x99}, + 107: {lang: 0x309, region: 0x53}, + 109: {lang: 0x31c, region: 0x35}, + 110: {lang: 0x30c, region: 0x99}, + 111: {lang: 0x412, region: 0xe8}, + 112: {lang: 0x32f, region: 0xc4}, + 113: {lang: 0x4f7, region: 0x108}, + 114: {lang: 0x3b, region: 0xa1}, + 115: {lang: 0x351, region: 0xdb}, + 117: {lang: 0x2ce, region: 0x84}, + 119: {lang: 0x401, region: 0x96}, + 120: {lang: 0x3ec, region: 0x99}, + 121: {lang: 0x399, region: 0xc5}, + 122: {lang: 0x393, region: 0x99}, + 123: {lang: 0x397, region: 0x135}, + 124: {lang: 0x427, region: 0x115}, + 125: {lang: 0x3b, region: 0x11c}, + 126: {lang: 0xfc, region: 0xc4}, + 127: {lang: 0x27b, region: 0x106}, + 128: {lang: 0x2c7, region: 0x53}, + 129: {lang: 0x39d, region: 0x9c}, + 130: {lang: 0x39d, region: 0x53}, + 132: {lang: 0x3ab, region: 0xb0}, + 134: {lang: 0x1c4, region: 0x53}, + 135: {lang: 0x4fb, region: 0x9c}, + 186: {lang: 0x3c9, region: 0x95}, + 188: {lang: 0x370, region: 0x10c}, + 189: {lang: 0x41e, region: 0x97}, + 191: {lang: 0x4fd, region: 0x15e}, + 192: {lang: 0x3ee, region: 0x99}, + 193: {lang: 0x45, region: 0x135}, + 194: {lang: 0x138, region: 0x7b}, + 195: {lang: 0x3e7, region: 0x99}, + 196: {lang: 0x3e7, region: 0x99}, + 197: {lang: 0x3f8, region: 0x99}, + 198: {lang: 0x40a, region: 0xb3}, + 199: {lang: 0x431, region: 0x99}, + 201: {lang: 0x43c, region: 0x95}, + 202: {lang: 0x44b, region: 0x35}, + 203: {lang: 0x44c, region: 0x9b}, + 207: {lang: 0x458, region: 0xe7}, + 208: {lang: 0x119, region: 0x99}, + 209: {lang: 0x45c, region: 0x53}, + 210: {lang: 0x230, region: 0x53}, + 211: {lang: 0x44e, region: 0x99}, + 212: {lang: 0x4a3, region: 0x53}, + 213: {lang: 0x9f, region: 0x13e}, + 214: {lang: 0x45f, region: 0x99}, + 216: {lang: 0x526, region: 0xba}, + 217: {lang: 0x152, region: 0xe7}, + 218: {lang: 0x127, region: 0xcd}, + 219: {lang: 0x469, region: 0x123}, + 220: {lang: 0xa9, region: 0x53}, + 221: {lang: 0x2cc, region: 0x99}, + 222: {lang: 0x4ab, region: 0x11c}, + 223: {lang: 0x4bc, region: 0xb4}, + 225: {lang: 0x1cc, region: 0x99}, + 227: {lang: 0x3a7, region: 0x9c}, + 228: {lang: 0x22, region: 0x9b}, + 229: {lang: 0x1e8, region: 0x53}, +} + +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: 5308 bytes, 1327 elements +var likelyLang = [1327]likelyScriptRegion{ + 0: {region: 0x135, script: 0x55, flags: 0x0}, + 1: {region: 0x6f, script: 0x55, flags: 0x0}, + 2: {region: 0x165, script: 0x55, flags: 0x0}, + 3: {region: 0x165, script: 0x55, flags: 0x0}, + 4: {region: 0x165, script: 0x55, flags: 0x0}, + 5: {region: 0x7d, script: 0x1e, flags: 0x0}, + 6: {region: 0x165, script: 0x55, flags: 0x0}, + 7: {region: 0x165, script: 0x1e, flags: 0x0}, + 8: {region: 0x80, script: 0x55, flags: 0x0}, + 9: {region: 0x165, script: 0x55, flags: 0x0}, + 10: {region: 0x165, script: 0x55, flags: 0x0}, + 11: {region: 0x165, script: 0x55, flags: 0x0}, + 12: {region: 0x95, script: 0x55, flags: 0x0}, + 13: {region: 0x131, script: 0x55, flags: 0x0}, + 14: {region: 0x80, script: 0x55, flags: 0x0}, + 15: {region: 0x165, script: 0x55, flags: 0x0}, + 16: {region: 0x165, script: 0x55, flags: 0x0}, + 17: {region: 0x106, script: 0x1e, flags: 0x0}, + 18: {region: 0x165, script: 0x55, flags: 0x0}, + 19: {region: 0x9c, script: 0x9, flags: 0x0}, + 20: {region: 0x128, script: 0x5, flags: 0x0}, + 21: {region: 0x165, script: 0x55, flags: 0x0}, + 22: {region: 0x161, script: 0x55, flags: 0x0}, + 23: {region: 0x165, script: 0x55, flags: 0x0}, + 24: {region: 0x165, script: 0x55, flags: 0x0}, + 25: {region: 0x165, script: 0x55, flags: 0x0}, + 26: {region: 0x165, script: 0x55, flags: 0x0}, + 27: {region: 0x165, script: 0x55, flags: 0x0}, + 28: {region: 0x52, script: 0x55, flags: 0x0}, + 29: {region: 0x165, script: 0x55, flags: 0x0}, + 30: {region: 0x165, script: 0x55, flags: 0x0}, + 31: {region: 0x99, script: 0x4, flags: 0x0}, + 32: {region: 0x165, script: 0x55, flags: 0x0}, + 33: {region: 0x80, script: 0x55, flags: 0x0}, + 34: {region: 0x9b, script: 0xe4, flags: 0x0}, + 35: {region: 0x165, script: 0x55, flags: 0x0}, + 36: {region: 0x165, script: 0x55, flags: 0x0}, + 37: {region: 0x14d, script: 0x55, flags: 0x0}, + 38: {region: 0x106, script: 0x1e, flags: 0x0}, + 39: {region: 0x6f, script: 0x28, flags: 0x0}, + 40: {region: 0x165, script: 0x55, flags: 0x0}, + 41: {region: 0x165, script: 0x55, flags: 0x0}, + 42: {region: 0xd6, script: 0x55, flags: 0x0}, + 43: {region: 0x165, script: 0x55, flags: 0x0}, + 45: {region: 0x165, script: 0x55, flags: 0x0}, + 46: {region: 0x165, script: 0x55, flags: 0x0}, + 47: {region: 0x165, script: 0x55, flags: 0x0}, + 48: {region: 0x165, script: 0x55, flags: 0x0}, + 49: {region: 0x165, script: 0x55, flags: 0x0}, + 50: {region: 0x165, script: 0x55, flags: 0x0}, + 51: {region: 0x95, script: 0x55, flags: 0x0}, + 52: {region: 0x165, script: 0x5, flags: 0x0}, + 53: {region: 0x122, script: 0x5, flags: 0x0}, + 54: {region: 0x165, script: 0x55, flags: 0x0}, + 55: {region: 0x165, script: 0x55, flags: 0x0}, + 56: {region: 0x165, script: 0x55, flags: 0x0}, + 57: {region: 0x165, script: 0x55, flags: 0x0}, + 58: {region: 0x6b, script: 0x5, flags: 0x0}, + 59: {region: 0x0, script: 0x3, flags: 0x1}, + 60: {region: 0x165, script: 0x55, flags: 0x0}, + 61: {region: 0x51, script: 0x55, flags: 0x0}, + 62: {region: 0x3f, script: 0x55, flags: 0x0}, + 63: {region: 0x67, script: 0x5, flags: 0x0}, + 65: {region: 0xba, script: 0x5, flags: 0x0}, + 66: {region: 0x6b, script: 0x5, flags: 0x0}, + 67: {region: 0x99, script: 0xe, flags: 0x0}, + 68: {region: 0x12f, script: 0x55, flags: 0x0}, + 69: {region: 0x135, script: 0xc1, flags: 0x0}, + 70: {region: 0x165, script: 0x55, flags: 0x0}, + 71: {region: 0x165, script: 0x55, flags: 0x0}, + 72: {region: 0x6e, script: 0x55, flags: 0x0}, + 73: {region: 0x165, script: 0x55, flags: 0x0}, + 74: {region: 0x165, script: 0x55, flags: 0x0}, + 75: {region: 0x49, script: 0x55, flags: 0x0}, + 76: {region: 0x165, script: 0x55, flags: 0x0}, + 77: {region: 0x106, script: 0x1e, flags: 0x0}, + 78: {region: 0x165, script: 0x5, flags: 0x0}, + 79: {region: 0x165, script: 0x55, flags: 0x0}, + 80: {region: 0x165, script: 0x55, flags: 0x0}, + 81: {region: 0x165, script: 0x55, flags: 0x0}, + 82: {region: 0x99, script: 0x20, flags: 0x0}, + 83: {region: 0x165, script: 0x55, flags: 0x0}, + 84: {region: 0x165, script: 0x55, flags: 0x0}, + 85: {region: 0x165, script: 0x55, flags: 0x0}, + 86: {region: 0x3f, script: 0x55, flags: 0x0}, + 87: {region: 0x165, script: 0x55, flags: 0x0}, + 88: {region: 0x3, script: 0x5, flags: 0x1}, + 89: {region: 0x106, script: 0x1e, flags: 0x0}, + 90: {region: 0xe8, script: 0x5, flags: 0x0}, + 91: {region: 0x95, script: 0x55, flags: 0x0}, + 92: {region: 0xdb, script: 0x20, flags: 0x0}, + 93: {region: 0x2e, script: 0x55, flags: 0x0}, + 94: {region: 0x52, script: 0x55, flags: 0x0}, + 95: {region: 0x165, script: 0x55, flags: 0x0}, + 96: {region: 0x52, script: 0xb, flags: 0x0}, + 97: {region: 0x165, script: 0x55, flags: 0x0}, + 98: {region: 0x165, script: 0x55, flags: 0x0}, + 99: {region: 0x95, script: 0x55, flags: 0x0}, + 100: {region: 0x165, script: 0x55, flags: 0x0}, + 101: {region: 0x52, script: 0x55, flags: 0x0}, + 102: {region: 0x165, script: 0x55, flags: 0x0}, + 103: {region: 0x165, script: 0x55, flags: 0x0}, + 104: {region: 0x165, script: 0x55, flags: 0x0}, + 105: {region: 0x165, script: 0x55, flags: 0x0}, + 106: {region: 0x4f, script: 0x55, flags: 0x0}, + 107: {region: 0x165, script: 0x55, flags: 0x0}, + 108: {region: 0x165, script: 0x55, flags: 0x0}, + 109: {region: 0x165, script: 0x55, flags: 0x0}, + 110: {region: 0x165, script: 0x28, flags: 0x0}, + 111: {region: 0x165, script: 0x55, flags: 0x0}, + 112: {region: 0x165, script: 0x55, flags: 0x0}, + 113: {region: 0x47, script: 0x1e, flags: 0x0}, + 114: {region: 0x165, script: 0x55, flags: 0x0}, + 115: {region: 0x165, script: 0x55, flags: 0x0}, + 116: {region: 0x10b, script: 0x5, flags: 0x0}, + 117: {region: 0x162, script: 0x55, flags: 0x0}, + 118: {region: 0x165, script: 0x55, flags: 0x0}, + 119: {region: 0x95, script: 0x55, flags: 0x0}, + 120: {region: 0x165, script: 0x55, flags: 0x0}, + 121: {region: 0x12f, script: 0x55, flags: 0x0}, + 122: {region: 0x52, script: 0x55, flags: 0x0}, + 123: {region: 0x99, script: 0xd3, flags: 0x0}, + 124: {region: 0xe8, script: 0x5, flags: 0x0}, + 125: {region: 0x99, script: 0x20, flags: 0x0}, + 126: {region: 0x38, script: 0x1e, flags: 0x0}, + 127: {region: 0x99, script: 0x20, flags: 0x0}, + 128: {region: 0xe8, script: 0x5, flags: 0x0}, + 129: {region: 0x12b, script: 0x30, flags: 0x0}, + 131: {region: 0x99, script: 0x20, flags: 0x0}, + 132: {region: 0x165, script: 0x55, flags: 0x0}, + 133: {region: 0x99, script: 0x20, flags: 0x0}, + 134: {region: 0xe7, script: 0x55, flags: 0x0}, + 135: {region: 0x165, script: 0x55, flags: 0x0}, + 136: {region: 0x99, script: 0x20, flags: 0x0}, + 137: {region: 0x165, script: 0x55, flags: 0x0}, + 138: {region: 0x13f, script: 0x55, flags: 0x0}, + 139: {region: 0x165, script: 0x55, flags: 0x0}, + 140: {region: 0x165, script: 0x55, flags: 0x0}, + 141: {region: 0xe7, script: 0x55, flags: 0x0}, + 142: {region: 0x165, script: 0x55, flags: 0x0}, + 143: {region: 0xd6, script: 0x55, flags: 0x0}, + 144: {region: 0x165, script: 0x55, flags: 0x0}, + 145: {region: 0x165, script: 0x55, flags: 0x0}, + 146: {region: 0x165, script: 0x55, flags: 0x0}, + 147: {region: 0x165, script: 0x28, flags: 0x0}, + 148: {region: 0x99, script: 0x20, flags: 0x0}, + 149: {region: 0x95, script: 0x55, flags: 0x0}, + 150: {region: 0x165, script: 0x55, flags: 0x0}, + 151: {region: 0x165, script: 0x55, flags: 0x0}, + 152: {region: 0x114, script: 0x55, flags: 0x0}, + 153: {region: 0x165, script: 0x55, flags: 0x0}, + 154: {region: 0x165, script: 0x55, flags: 0x0}, + 155: {region: 0x52, script: 0x55, flags: 0x0}, + 156: {region: 0x165, script: 0x55, flags: 0x0}, + 157: {region: 0xe7, script: 0x55, flags: 0x0}, + 158: {region: 0x165, script: 0x55, flags: 0x0}, + 159: {region: 0x13e, script: 0xd5, flags: 0x0}, + 160: {region: 0xc3, script: 0x55, flags: 0x0}, + 161: {region: 0x165, script: 0x55, flags: 0x0}, + 162: {region: 0x165, script: 0x55, flags: 0x0}, + 163: {region: 0xc3, script: 0x55, flags: 0x0}, + 164: {region: 0x165, script: 0x55, flags: 0x0}, + 165: {region: 0x35, script: 0xe, flags: 0x0}, + 166: {region: 0x165, script: 0x55, flags: 0x0}, + 167: {region: 0x165, script: 0x55, flags: 0x0}, + 168: {region: 0x165, script: 0x55, flags: 0x0}, + 169: {region: 0x53, script: 0xdc, flags: 0x0}, + 170: {region: 0x165, script: 0x55, flags: 0x0}, + 171: {region: 0x165, script: 0x55, flags: 0x0}, + 172: {region: 0x165, script: 0x55, flags: 0x0}, + 173: {region: 0x99, script: 0xe, flags: 0x0}, + 174: {region: 0x165, script: 0x55, flags: 0x0}, + 175: {region: 0x9c, script: 0x5, flags: 0x0}, + 176: {region: 0x165, script: 0x55, flags: 0x0}, + 177: {region: 0x4f, script: 0x55, flags: 0x0}, + 178: {region: 0x78, script: 0x55, flags: 0x0}, + 179: {region: 0x99, script: 0x20, flags: 0x0}, + 180: {region: 0xe8, script: 0x5, flags: 0x0}, + 181: {region: 0x99, script: 0x20, flags: 0x0}, + 182: {region: 0x165, script: 0x55, flags: 0x0}, + 183: {region: 0x33, script: 0x55, flags: 0x0}, + 184: {region: 0x165, script: 0x55, flags: 0x0}, + 185: {region: 0xb4, script: 0xc, flags: 0x0}, + 186: {region: 0x52, script: 0x55, flags: 0x0}, + 187: {region: 0x165, script: 0x28, flags: 0x0}, + 188: {region: 0xe7, script: 0x55, flags: 0x0}, + 189: {region: 0x165, script: 0x55, flags: 0x0}, + 190: {region: 0xe8, script: 0x20, flags: 0x0}, + 191: {region: 0x106, script: 0x1e, flags: 0x0}, + 192: {region: 0x15f, script: 0x55, flags: 0x0}, + 193: {region: 0x165, script: 0x55, flags: 0x0}, + 194: {region: 0x95, script: 0x55, flags: 0x0}, + 195: {region: 0x165, script: 0x55, flags: 0x0}, + 196: {region: 0x52, script: 0x55, flags: 0x0}, + 197: {region: 0x165, script: 0x55, flags: 0x0}, + 198: {region: 0x165, script: 0x55, flags: 0x0}, + 199: {region: 0x165, script: 0x55, flags: 0x0}, + 200: {region: 0x86, script: 0x55, flags: 0x0}, + 201: {region: 0x165, script: 0x55, flags: 0x0}, + 202: {region: 0x165, script: 0x55, flags: 0x0}, + 203: {region: 0x165, script: 0x55, flags: 0x0}, + 204: {region: 0x165, script: 0x55, flags: 0x0}, + 205: {region: 0x6d, script: 0x28, flags: 0x0}, + 206: {region: 0x165, script: 0x55, flags: 0x0}, + 207: {region: 0x165, script: 0x55, flags: 0x0}, + 208: {region: 0x52, script: 0x55, flags: 0x0}, + 209: {region: 0x165, script: 0x55, flags: 0x0}, + 210: {region: 0x165, script: 0x55, flags: 0x0}, + 211: {region: 0xc3, script: 0x55, flags: 0x0}, + 212: {region: 0x165, script: 0x55, flags: 0x0}, + 213: {region: 0x165, script: 0x55, flags: 0x0}, + 214: {region: 0x165, script: 0x55, flags: 0x0}, + 215: {region: 0x6e, script: 0x55, flags: 0x0}, + 216: {region: 0x165, script: 0x55, flags: 0x0}, + 217: {region: 0x165, script: 0x55, flags: 0x0}, + 218: {region: 0xd6, script: 0x55, flags: 0x0}, + 219: {region: 0x35, script: 0x16, flags: 0x0}, + 220: {region: 0x106, script: 0x1e, flags: 0x0}, + 221: {region: 0xe7, script: 0x55, flags: 0x0}, + 222: {region: 0x165, script: 0x55, flags: 0x0}, + 223: {region: 0x131, script: 0x55, flags: 0x0}, + 224: {region: 0x8a, script: 0x55, flags: 0x0}, + 225: {region: 0x75, script: 0x55, flags: 0x0}, + 226: {region: 0x106, script: 0x1e, flags: 0x0}, + 227: {region: 0x135, script: 0x55, flags: 0x0}, + 228: {region: 0x49, script: 0x55, flags: 0x0}, + 229: {region: 0x135, script: 0x1a, flags: 0x0}, + 230: {region: 0xa6, script: 0x5, flags: 0x0}, + 231: {region: 0x13e, script: 0x19, flags: 0x0}, + 232: {region: 0x165, script: 0x55, flags: 0x0}, + 233: {region: 0x9b, script: 0x5, flags: 0x0}, + 234: {region: 0x165, script: 0x55, flags: 0x0}, + 235: {region: 0x165, script: 0x55, flags: 0x0}, + 236: {region: 0x165, script: 0x55, flags: 0x0}, + 237: {region: 0x165, script: 0x55, flags: 0x0}, + 238: {region: 0x165, script: 0x55, flags: 0x0}, + 239: {region: 0x78, script: 0x55, flags: 0x0}, + 240: {region: 0x6b, script: 0x1c, flags: 0x0}, + 241: {region: 0xe7, script: 0x55, flags: 0x0}, + 242: {region: 0x49, script: 0x17, flags: 0x0}, + 243: {region: 0x130, script: 0x1e, flags: 0x0}, + 244: {region: 0x49, script: 0x17, flags: 0x0}, + 245: {region: 0x49, script: 0x17, flags: 0x0}, + 246: {region: 0x49, script: 0x17, flags: 0x0}, + 247: {region: 0x49, script: 0x17, flags: 0x0}, + 248: {region: 0x10a, script: 0x55, flags: 0x0}, + 249: {region: 0x5e, script: 0x55, flags: 0x0}, + 250: {region: 0xe9, script: 0x55, flags: 0x0}, + 251: {region: 0x49, script: 0x17, flags: 0x0}, + 252: {region: 0xc4, script: 0x7e, flags: 0x0}, + 253: {region: 0x8, script: 0x2, flags: 0x1}, + 254: {region: 0x106, script: 0x1e, flags: 0x0}, + 255: {region: 0x7b, script: 0x55, flags: 0x0}, + 256: {region: 0x63, script: 0x55, flags: 0x0}, + 257: {region: 0x165, script: 0x55, flags: 0x0}, + 258: {region: 0x165, script: 0x55, flags: 0x0}, + 259: {region: 0x165, script: 0x55, flags: 0x0}, + 260: {region: 0x165, script: 0x55, flags: 0x0}, + 261: {region: 0x135, script: 0x55, flags: 0x0}, + 262: {region: 0x106, script: 0x1e, flags: 0x0}, + 263: {region: 0xa4, script: 0x55, flags: 0x0}, + 264: {region: 0x165, script: 0x55, flags: 0x0}, + 265: {region: 0x165, script: 0x55, flags: 0x0}, + 266: {region: 0x99, script: 0x5, flags: 0x0}, + 267: {region: 0x165, script: 0x55, flags: 0x0}, + 268: {region: 0x60, script: 0x55, flags: 0x0}, + 269: {region: 0x165, script: 0x55, flags: 0x0}, + 270: {region: 0x49, script: 0x55, flags: 0x0}, + 271: {region: 0x165, script: 0x55, flags: 0x0}, + 272: {region: 0x165, script: 0x55, flags: 0x0}, + 273: {region: 0x165, script: 0x55, flags: 0x0}, + 274: {region: 0x165, script: 0x5, flags: 0x0}, + 275: {region: 0x49, script: 0x55, flags: 0x0}, + 276: {region: 0x165, script: 0x55, flags: 0x0}, + 277: {region: 0x165, script: 0x55, flags: 0x0}, + 278: {region: 0xd4, script: 0x55, flags: 0x0}, + 279: {region: 0x4f, script: 0x55, flags: 0x0}, + 280: {region: 0x165, script: 0x55, flags: 0x0}, + 281: {region: 0x99, script: 0x5, flags: 0x0}, + 282: {region: 0x165, script: 0x55, flags: 0x0}, + 283: {region: 0x165, script: 0x55, flags: 0x0}, + 284: {region: 0x165, script: 0x55, flags: 0x0}, + 285: {region: 0x165, script: 0x28, flags: 0x0}, + 286: {region: 0x60, script: 0x55, flags: 0x0}, + 287: {region: 0xc3, script: 0x55, flags: 0x0}, + 288: {region: 0xd0, script: 0x55, flags: 0x0}, + 289: {region: 0x165, script: 0x55, flags: 0x0}, + 290: {region: 0xdb, script: 0x20, flags: 0x0}, + 291: {region: 0x52, script: 0x55, flags: 0x0}, + 292: {region: 0x165, script: 0x55, flags: 0x0}, + 293: {region: 0x165, script: 0x55, flags: 0x0}, + 294: {region: 0x165, script: 0x55, flags: 0x0}, + 295: {region: 0xcd, script: 0xda, flags: 0x0}, + 296: {region: 0x165, script: 0x55, flags: 0x0}, + 297: {region: 0x165, script: 0x55, flags: 0x0}, + 298: {region: 0x114, script: 0x55, flags: 0x0}, + 299: {region: 0x37, script: 0x55, flags: 0x0}, + 300: {region: 0x43, script: 0xdc, flags: 0x0}, + 301: {region: 0x165, script: 0x55, flags: 0x0}, + 302: {region: 0xa4, script: 0x55, flags: 0x0}, + 303: {region: 0x80, script: 0x55, flags: 0x0}, + 304: {region: 0xd6, script: 0x55, flags: 0x0}, + 305: {region: 0x9e, script: 0x55, flags: 0x0}, + 306: {region: 0x6b, script: 0x26, flags: 0x0}, + 307: {region: 0x165, script: 0x55, flags: 0x0}, + 308: {region: 0xc4, script: 0x46, flags: 0x0}, + 309: {region: 0x87, script: 0x30, flags: 0x0}, + 310: {region: 0x165, script: 0x55, flags: 0x0}, + 311: {region: 0x165, script: 0x55, flags: 0x0}, + 312: {region: 0xa, script: 0x2, flags: 0x1}, + 313: {region: 0x165, script: 0x55, flags: 0x0}, + 314: {region: 0x165, script: 0x55, flags: 0x0}, + 315: {region: 0x1, script: 0x55, flags: 0x0}, + 316: {region: 0x165, script: 0x55, flags: 0x0}, + 317: {region: 0x6e, script: 0x55, flags: 0x0}, + 318: {region: 0x135, script: 0x55, flags: 0x0}, + 319: {region: 0x6a, script: 0x55, flags: 0x0}, + 320: {region: 0x165, script: 0x55, flags: 0x0}, + 321: {region: 0x9e, script: 0x41, flags: 0x0}, + 322: {region: 0x165, script: 0x55, flags: 0x0}, + 323: {region: 0x165, script: 0x55, flags: 0x0}, + 324: {region: 0x6e, script: 0x55, flags: 0x0}, + 325: {region: 0x52, script: 0x55, flags: 0x0}, + 326: {region: 0x6e, script: 0x55, flags: 0x0}, + 327: {region: 0x9c, script: 0x5, flags: 0x0}, + 328: {region: 0x165, script: 0x55, flags: 0x0}, + 329: {region: 0x165, script: 0x55, flags: 0x0}, + 330: {region: 0x165, script: 0x55, flags: 0x0}, + 331: {region: 0x165, script: 0x55, flags: 0x0}, + 332: {region: 0x86, script: 0x55, flags: 0x0}, + 333: {region: 0xc, script: 0x2, flags: 0x1}, + 334: {region: 0x165, script: 0x55, flags: 0x0}, + 335: {region: 0xc3, script: 0x55, flags: 0x0}, + 336: {region: 0x72, script: 0x55, flags: 0x0}, + 337: {region: 0x10b, script: 0x5, flags: 0x0}, + 338: {region: 0xe7, script: 0x55, flags: 0x0}, + 339: {region: 0x10c, script: 0x55, flags: 0x0}, + 340: {region: 0x73, script: 0x55, flags: 0x0}, + 341: {region: 0x165, script: 0x55, flags: 0x0}, + 342: {region: 0x165, script: 0x55, flags: 0x0}, + 343: {region: 0x76, script: 0x55, flags: 0x0}, + 344: {region: 0x165, script: 0x55, flags: 0x0}, + 345: {region: 0x3b, script: 0x55, flags: 0x0}, + 346: {region: 0x165, script: 0x55, flags: 0x0}, + 347: {region: 0x165, script: 0x55, flags: 0x0}, + 348: {region: 0x165, script: 0x55, flags: 0x0}, + 349: {region: 0x78, script: 0x55, flags: 0x0}, + 350: {region: 0x135, script: 0x55, flags: 0x0}, + 351: {region: 0x78, script: 0x55, flags: 0x0}, + 352: {region: 0x60, script: 0x55, flags: 0x0}, + 353: {region: 0x60, script: 0x55, flags: 0x0}, + 354: {region: 0x52, script: 0x5, flags: 0x0}, + 355: {region: 0x140, script: 0x55, flags: 0x0}, + 356: {region: 0x165, script: 0x55, flags: 0x0}, + 357: {region: 0x84, script: 0x55, flags: 0x0}, + 358: {region: 0x165, script: 0x55, flags: 0x0}, + 359: {region: 0xd4, script: 0x55, flags: 0x0}, + 360: {region: 0x9e, script: 0x55, flags: 0x0}, + 361: {region: 0xd6, script: 0x55, flags: 0x0}, + 362: {region: 0x165, script: 0x55, flags: 0x0}, + 363: {region: 0x10b, script: 0x55, flags: 0x0}, + 364: {region: 0xd9, script: 0x55, flags: 0x0}, + 365: {region: 0x96, script: 0x55, flags: 0x0}, + 366: {region: 0x80, script: 0x55, flags: 0x0}, + 367: {region: 0x165, script: 0x55, flags: 0x0}, + 368: {region: 0xbc, script: 0x55, flags: 0x0}, + 369: {region: 0x165, script: 0x55, flags: 0x0}, + 370: {region: 0x165, script: 0x55, flags: 0x0}, + 371: {region: 0x165, script: 0x55, flags: 0x0}, + 372: {region: 0x53, script: 0x37, flags: 0x0}, + 373: {region: 0x165, script: 0x55, flags: 0x0}, + 374: {region: 0x95, script: 0x55, flags: 0x0}, + 375: {region: 0x165, script: 0x55, flags: 0x0}, + 376: {region: 0x99, script: 0x20, flags: 0x0}, + 377: {region: 0x165, script: 0x55, flags: 0x0}, + 378: {region: 0x9c, script: 0x5, flags: 0x0}, + 379: {region: 0x7e, script: 0x55, flags: 0x0}, + 380: {region: 0x7b, script: 0x55, flags: 0x0}, + 381: {region: 0x165, script: 0x55, flags: 0x0}, + 382: {region: 0x165, script: 0x55, flags: 0x0}, + 383: {region: 0x165, script: 0x55, flags: 0x0}, + 384: {region: 0x165, script: 0x55, flags: 0x0}, + 385: {region: 0x165, script: 0x55, flags: 0x0}, + 386: {region: 0x165, script: 0x55, flags: 0x0}, + 387: {region: 0x6f, script: 0x28, flags: 0x0}, + 388: {region: 0x165, script: 0x55, flags: 0x0}, + 389: {region: 0xdb, script: 0x20, flags: 0x0}, + 390: {region: 0x165, script: 0x55, flags: 0x0}, + 391: {region: 0xa7, script: 0x55, flags: 0x0}, + 392: {region: 0x165, script: 0x55, flags: 0x0}, + 393: {region: 0xe8, script: 0x5, flags: 0x0}, + 394: {region: 0x165, script: 0x55, flags: 0x0}, + 395: {region: 0xe8, script: 0x5, flags: 0x0}, + 396: {region: 0x165, script: 0x55, flags: 0x0}, + 397: {region: 0x165, script: 0x55, flags: 0x0}, + 398: {region: 0x6e, script: 0x55, flags: 0x0}, + 399: {region: 0x9c, script: 0x5, flags: 0x0}, + 400: {region: 0x165, script: 0x55, flags: 0x0}, + 401: {region: 0x165, script: 0x28, flags: 0x0}, + 402: {region: 0xf1, script: 0x55, flags: 0x0}, + 403: {region: 0x165, script: 0x55, flags: 0x0}, + 404: {region: 0x165, script: 0x55, flags: 0x0}, + 405: {region: 0x165, script: 0x55, flags: 0x0}, + 406: {region: 0x165, script: 0x28, flags: 0x0}, + 407: {region: 0x165, script: 0x55, flags: 0x0}, + 408: {region: 0x99, script: 0x20, flags: 0x0}, + 409: {region: 0x99, script: 0xd6, flags: 0x0}, + 410: {region: 0x95, script: 0x55, flags: 0x0}, + 411: {region: 0xd9, script: 0x55, flags: 0x0}, + 412: {region: 0x130, script: 0x2e, flags: 0x0}, + 413: {region: 0x165, script: 0x55, flags: 0x0}, + 414: {region: 0xe, script: 0x2, flags: 0x1}, + 415: {region: 0x99, script: 0xe, flags: 0x0}, + 416: {region: 0x165, script: 0x55, flags: 0x0}, + 417: {region: 0x4e, script: 0x55, flags: 0x0}, + 418: {region: 0x99, script: 0x31, flags: 0x0}, + 419: {region: 0x41, script: 0x55, flags: 0x0}, + 420: {region: 0x54, script: 0x55, flags: 0x0}, + 421: {region: 0x165, script: 0x55, flags: 0x0}, + 422: {region: 0x80, script: 0x55, flags: 0x0}, + 423: {region: 0x165, script: 0x55, flags: 0x0}, + 424: {region: 0x165, script: 0x55, flags: 0x0}, + 425: {region: 0xa4, script: 0x55, flags: 0x0}, + 426: {region: 0x98, script: 0x55, flags: 0x0}, + 427: {region: 0x165, script: 0x55, flags: 0x0}, + 428: {region: 0xdb, script: 0x20, flags: 0x0}, + 429: {region: 0x165, script: 0x55, flags: 0x0}, + 430: {region: 0x165, script: 0x5, flags: 0x0}, + 431: {region: 0x49, script: 0x55, flags: 0x0}, + 432: {region: 0x165, script: 0x5, flags: 0x0}, + 433: {region: 0x165, script: 0x55, flags: 0x0}, + 434: {region: 0x10, script: 0x3, flags: 0x1}, + 435: {region: 0x165, script: 0x55, flags: 0x0}, + 436: {region: 0x53, script: 0x37, flags: 0x0}, + 437: {region: 0x165, script: 0x55, flags: 0x0}, + 438: {region: 0x135, script: 0x55, flags: 0x0}, + 439: {region: 0x24, script: 0x5, flags: 0x0}, + 440: {region: 0x165, script: 0x55, flags: 0x0}, + 441: {region: 0x165, script: 0x28, flags: 0x0}, + 442: {region: 0x97, script: 0x3a, flags: 0x0}, + 443: {region: 0x165, script: 0x55, flags: 0x0}, + 444: {region: 0x99, script: 0x20, flags: 0x0}, + 445: {region: 0x165, script: 0x55, flags: 0x0}, + 446: {region: 0x73, script: 0x55, flags: 0x0}, + 447: {region: 0x165, script: 0x55, flags: 0x0}, + 448: {region: 0x165, script: 0x55, flags: 0x0}, + 449: {region: 0xe7, script: 0x55, flags: 0x0}, + 450: {region: 0x165, script: 0x55, flags: 0x0}, + 451: {region: 0x12b, script: 0x3c, flags: 0x0}, + 452: {region: 0x53, script: 0x86, flags: 0x0}, + 453: {region: 0x165, script: 0x55, flags: 0x0}, + 454: {region: 0xe8, script: 0x5, flags: 0x0}, + 455: {region: 0x99, script: 0x20, flags: 0x0}, + 456: {region: 0xaf, script: 0x3d, flags: 0x0}, + 457: {region: 0xe7, script: 0x55, flags: 0x0}, + 458: {region: 0xe8, script: 0x5, flags: 0x0}, + 459: {region: 0xe6, script: 0x55, flags: 0x0}, + 460: {region: 0x99, script: 0x20, flags: 0x0}, + 461: {region: 0x99, script: 0x20, flags: 0x0}, + 462: {region: 0x165, script: 0x55, flags: 0x0}, + 463: {region: 0x90, script: 0x55, flags: 0x0}, + 464: {region: 0x60, script: 0x55, flags: 0x0}, + 465: {region: 0x53, script: 0x37, flags: 0x0}, + 466: {region: 0x91, script: 0x55, flags: 0x0}, + 467: {region: 0x92, script: 0x55, flags: 0x0}, + 468: {region: 0x165, script: 0x55, flags: 0x0}, + 469: {region: 0x28, script: 0x8, flags: 0x0}, + 470: {region: 0xd2, script: 0x55, flags: 0x0}, + 471: {region: 0x78, script: 0x55, flags: 0x0}, + 472: {region: 0x165, script: 0x55, flags: 0x0}, + 473: {region: 0x165, script: 0x55, flags: 0x0}, + 474: {region: 0xd0, script: 0x55, flags: 0x0}, + 475: {region: 0xd6, script: 0x55, flags: 0x0}, + 476: {region: 0x165, script: 0x55, flags: 0x0}, + 477: {region: 0x165, script: 0x55, flags: 0x0}, + 478: {region: 0x165, script: 0x55, flags: 0x0}, + 479: {region: 0x95, script: 0x55, flags: 0x0}, + 480: {region: 0x165, script: 0x55, flags: 0x0}, + 481: {region: 0x165, script: 0x55, flags: 0x0}, + 482: {region: 0x165, script: 0x55, flags: 0x0}, + 484: {region: 0x122, script: 0x55, flags: 0x0}, + 485: {region: 0xd6, script: 0x55, flags: 0x0}, + 486: {region: 0x165, script: 0x55, flags: 0x0}, + 487: {region: 0x165, script: 0x55, flags: 0x0}, + 488: {region: 0x53, script: 0xe5, flags: 0x0}, + 489: {region: 0x165, script: 0x55, flags: 0x0}, + 490: {region: 0x135, script: 0x55, flags: 0x0}, + 491: {region: 0x165, script: 0x55, flags: 0x0}, + 492: {region: 0x49, script: 0x55, flags: 0x0}, + 493: {region: 0x165, script: 0x55, flags: 0x0}, + 494: {region: 0x165, script: 0x55, flags: 0x0}, + 495: {region: 0xe7, script: 0x55, flags: 0x0}, + 496: {region: 0x165, script: 0x55, flags: 0x0}, + 497: {region: 0x95, script: 0x55, flags: 0x0}, + 498: {region: 0x106, script: 0x1e, flags: 0x0}, + 500: {region: 0x165, script: 0x55, flags: 0x0}, + 501: {region: 0x165, script: 0x55, flags: 0x0}, + 502: {region: 0x9d, script: 0x55, flags: 0x0}, + 503: {region: 0x9e, script: 0x55, flags: 0x0}, + 504: {region: 0x49, script: 0x17, flags: 0x0}, + 505: {region: 0x97, script: 0x3a, flags: 0x0}, + 506: {region: 0x165, script: 0x55, flags: 0x0}, + 507: {region: 0x165, script: 0x55, flags: 0x0}, + 508: {region: 0x106, script: 0x55, flags: 0x0}, + 509: {region: 0x165, script: 0x55, flags: 0x0}, + 510: {region: 0xa2, script: 0x44, flags: 0x0}, + 511: {region: 0x165, script: 0x55, flags: 0x0}, + 512: {region: 0xa0, script: 0x55, flags: 0x0}, + 514: {region: 0x165, script: 0x55, flags: 0x0}, + 515: {region: 0x165, script: 0x55, flags: 0x0}, + 516: {region: 0x165, script: 0x55, flags: 0x0}, + 517: {region: 0x52, script: 0x55, flags: 0x0}, + 518: {region: 0x130, script: 0x3a, flags: 0x0}, + 519: {region: 0x165, script: 0x55, flags: 0x0}, + 520: {region: 0x12f, script: 0x55, flags: 0x0}, + 521: {region: 0xdb, script: 0x20, flags: 0x0}, + 522: {region: 0x165, script: 0x55, flags: 0x0}, + 523: {region: 0x63, script: 0x55, flags: 0x0}, + 524: {region: 0x95, script: 0x55, flags: 0x0}, + 525: {region: 0x95, script: 0x55, flags: 0x0}, + 526: {region: 0x7d, script: 0x2a, flags: 0x0}, + 527: {region: 0x137, script: 0x1e, flags: 0x0}, + 528: {region: 0x67, script: 0x55, flags: 0x0}, + 529: {region: 0xc4, script: 0x55, flags: 0x0}, + 530: {region: 0x165, script: 0x55, flags: 0x0}, + 531: {region: 0x165, script: 0x55, flags: 0x0}, + 532: {region: 0xd6, script: 0x55, flags: 0x0}, + 533: {region: 0xa4, script: 0x55, flags: 0x0}, + 534: {region: 0xc3, script: 0x55, flags: 0x0}, + 535: {region: 0x106, script: 0x1e, flags: 0x0}, + 536: {region: 0x165, script: 0x55, flags: 0x0}, + 537: {region: 0x165, script: 0x55, flags: 0x0}, + 538: {region: 0x165, script: 0x55, flags: 0x0}, + 539: {region: 0x165, script: 0x55, flags: 0x0}, + 540: {region: 0xd4, script: 0x5, flags: 0x0}, + 541: {region: 0xd6, script: 0x55, flags: 0x0}, + 542: {region: 0x164, script: 0x55, flags: 0x0}, + 543: {region: 0x165, script: 0x55, flags: 0x0}, + 544: {region: 0x165, script: 0x55, flags: 0x0}, + 545: {region: 0x12f, script: 0x55, flags: 0x0}, + 546: {region: 0x122, script: 0x5, flags: 0x0}, + 547: {region: 0x165, script: 0x55, flags: 0x0}, + 548: {region: 0x123, script: 0xdb, flags: 0x0}, + 549: {region: 0x5a, script: 0x55, flags: 0x0}, + 550: {region: 0x52, script: 0x55, flags: 0x0}, + 551: {region: 0x165, script: 0x55, flags: 0x0}, + 552: {region: 0x4f, script: 0x55, flags: 0x0}, + 553: {region: 0x99, script: 0x20, flags: 0x0}, + 554: {region: 0x99, script: 0x20, flags: 0x0}, + 555: {region: 0x4b, script: 0x55, flags: 0x0}, + 556: {region: 0x95, script: 0x55, flags: 0x0}, + 557: {region: 0x165, script: 0x55, flags: 0x0}, + 558: {region: 0x41, script: 0x55, flags: 0x0}, + 559: {region: 0x99, script: 0x55, flags: 0x0}, + 560: {region: 0x53, script: 0xd2, flags: 0x0}, + 561: {region: 0x99, script: 0x20, flags: 0x0}, + 562: {region: 0xc3, script: 0x55, flags: 0x0}, + 563: {region: 0x165, script: 0x55, flags: 0x0}, + 564: {region: 0x99, script: 0x70, flags: 0x0}, + 565: {region: 0xe8, script: 0x5, flags: 0x0}, + 566: {region: 0x165, script: 0x55, flags: 0x0}, + 567: {region: 0xa4, script: 0x55, flags: 0x0}, + 568: {region: 0x165, script: 0x55, flags: 0x0}, + 569: {region: 0x12b, script: 0x55, flags: 0x0}, + 570: {region: 0x165, script: 0x55, flags: 0x0}, + 571: {region: 0xd2, script: 0x55, flags: 0x0}, + 572: {region: 0x165, script: 0x55, flags: 0x0}, + 573: {region: 0xaf, script: 0x52, flags: 0x0}, + 574: {region: 0x165, script: 0x55, flags: 0x0}, + 575: {region: 0x165, script: 0x55, flags: 0x0}, + 576: {region: 0x13, script: 0x6, flags: 0x1}, + 577: {region: 0x165, script: 0x55, flags: 0x0}, + 578: {region: 0x52, script: 0x55, flags: 0x0}, + 579: {region: 0x82, script: 0x55, flags: 0x0}, + 580: {region: 0xa4, script: 0x55, flags: 0x0}, + 581: {region: 0x165, script: 0x55, flags: 0x0}, + 582: {region: 0x165, script: 0x55, flags: 0x0}, + 583: {region: 0x165, script: 0x55, flags: 0x0}, + 584: {region: 0xa6, script: 0x49, flags: 0x0}, + 585: {region: 0x2a, script: 0x55, flags: 0x0}, + 586: {region: 0x165, script: 0x55, flags: 0x0}, + 587: {region: 0x165, script: 0x55, flags: 0x0}, + 588: {region: 0x165, script: 0x55, flags: 0x0}, + 589: {region: 0x165, script: 0x55, flags: 0x0}, + 590: {region: 0x165, script: 0x55, flags: 0x0}, + 591: {region: 0x99, script: 0x4d, flags: 0x0}, + 592: {region: 0x114, script: 0x55, flags: 0x0}, + 593: {region: 0x165, script: 0x55, flags: 0x0}, + 594: {region: 0xab, script: 0x4e, flags: 0x0}, + 595: {region: 0x106, script: 0x1e, flags: 0x0}, + 596: {region: 0x99, script: 0x20, flags: 0x0}, + 597: {region: 0x165, script: 0x55, flags: 0x0}, + 598: {region: 0x75, script: 0x55, flags: 0x0}, + 599: {region: 0x165, script: 0x55, flags: 0x0}, + 600: {region: 0xb4, script: 0x55, flags: 0x0}, + 601: {region: 0x165, script: 0x55, flags: 0x0}, + 602: {region: 0x165, script: 0x55, flags: 0x0}, + 603: {region: 0x165, script: 0x55, flags: 0x0}, + 604: {region: 0x165, script: 0x55, flags: 0x0}, + 605: {region: 0x165, script: 0x55, flags: 0x0}, + 606: {region: 0x165, script: 0x55, flags: 0x0}, + 607: {region: 0x165, script: 0x55, flags: 0x0}, + 608: {region: 0x165, script: 0x28, flags: 0x0}, + 610: {region: 0x106, script: 0x1e, flags: 0x0}, + 611: {region: 0x112, script: 0x55, flags: 0x0}, + 612: {region: 0xe7, script: 0x55, flags: 0x0}, + 613: {region: 0x106, script: 0x55, flags: 0x0}, + 614: {region: 0x165, script: 0x55, flags: 0x0}, + 615: {region: 0x99, script: 0x20, flags: 0x0}, + 616: {region: 0x99, script: 0x5, flags: 0x0}, + 617: {region: 0x12f, script: 0x55, flags: 0x0}, + 618: {region: 0x165, script: 0x55, flags: 0x0}, + 619: {region: 0x52, script: 0x55, flags: 0x0}, + 620: {region: 0x60, script: 0x55, flags: 0x0}, + 621: {region: 0x165, script: 0x55, flags: 0x0}, + 622: {region: 0x165, script: 0x55, flags: 0x0}, + 623: {region: 0x165, script: 0x28, flags: 0x0}, + 624: {region: 0x165, script: 0x55, flags: 0x0}, + 625: {region: 0x165, script: 0x55, flags: 0x0}, + 626: {region: 0x19, script: 0x3, flags: 0x1}, + 627: {region: 0x165, script: 0x55, flags: 0x0}, + 628: {region: 0x165, script: 0x55, flags: 0x0}, + 629: {region: 0x165, script: 0x55, flags: 0x0}, + 630: {region: 0x165, script: 0x55, flags: 0x0}, + 631: {region: 0x106, script: 0x1e, flags: 0x0}, + 632: {region: 0x165, script: 0x55, flags: 0x0}, + 633: {region: 0x165, script: 0x55, flags: 0x0}, + 634: {region: 0x165, script: 0x55, flags: 0x0}, + 635: {region: 0x106, script: 0x1e, flags: 0x0}, + 636: {region: 0x165, script: 0x55, flags: 0x0}, + 637: {region: 0x95, script: 0x55, flags: 0x0}, + 638: {region: 0xe8, script: 0x5, flags: 0x0}, + 639: {region: 0x7b, script: 0x55, flags: 0x0}, + 640: {region: 0x165, script: 0x55, flags: 0x0}, + 641: {region: 0x165, script: 0x55, flags: 0x0}, + 642: {region: 0x165, script: 0x55, flags: 0x0}, + 643: {region: 0x165, script: 0x28, flags: 0x0}, + 644: {region: 0x123, script: 0xdb, flags: 0x0}, + 645: {region: 0xe8, script: 0x5, flags: 0x0}, + 646: {region: 0x165, script: 0x55, flags: 0x0}, + 647: {region: 0x165, script: 0x55, flags: 0x0}, + 648: {region: 0x1c, script: 0x5, flags: 0x1}, + 649: {region: 0x165, script: 0x55, flags: 0x0}, + 650: {region: 0x165, script: 0x55, flags: 0x0}, + 651: {region: 0x165, script: 0x55, flags: 0x0}, + 652: {region: 0x138, script: 0x55, flags: 0x0}, + 653: {region: 0x87, script: 0x59, flags: 0x0}, + 654: {region: 0x97, script: 0x3a, flags: 0x0}, + 655: {region: 0x12f, script: 0x55, flags: 0x0}, + 656: {region: 0xe8, script: 0x5, flags: 0x0}, + 657: {region: 0x131, script: 0x55, flags: 0x0}, + 658: {region: 0x165, script: 0x55, flags: 0x0}, + 659: {region: 0xb7, script: 0x55, flags: 0x0}, + 660: {region: 0x106, script: 0x1e, flags: 0x0}, + 661: {region: 0x165, script: 0x55, flags: 0x0}, + 662: {region: 0x95, script: 0x55, flags: 0x0}, + 663: {region: 0x165, script: 0x55, flags: 0x0}, + 664: {region: 0x53, script: 0xdb, flags: 0x0}, + 665: {region: 0x165, script: 0x55, flags: 0x0}, + 666: {region: 0x165, script: 0x55, flags: 0x0}, + 667: {region: 0x165, script: 0x55, flags: 0x0}, + 668: {region: 0x165, script: 0x55, flags: 0x0}, + 669: {region: 0x99, script: 0x57, flags: 0x0}, + 670: {region: 0x165, script: 0x55, flags: 0x0}, + 671: {region: 0x165, script: 0x55, flags: 0x0}, + 672: {region: 0x106, script: 0x1e, flags: 0x0}, + 673: {region: 0x131, script: 0x55, flags: 0x0}, + 674: {region: 0x165, script: 0x55, flags: 0x0}, + 675: {region: 0xd9, script: 0x55, flags: 0x0}, + 676: {region: 0x165, script: 0x55, flags: 0x0}, + 677: {region: 0x165, script: 0x55, flags: 0x0}, + 678: {region: 0x21, script: 0x2, flags: 0x1}, + 679: {region: 0x165, script: 0x55, flags: 0x0}, + 680: {region: 0x165, script: 0x55, flags: 0x0}, + 681: {region: 0x9e, script: 0x55, flags: 0x0}, + 682: {region: 0x53, script: 0x5b, flags: 0x0}, + 683: {region: 0x95, script: 0x55, flags: 0x0}, + 684: {region: 0x9c, script: 0x5, flags: 0x0}, + 685: {region: 0x135, script: 0x55, flags: 0x0}, + 686: {region: 0x165, script: 0x55, flags: 0x0}, + 687: {region: 0x165, script: 0x55, flags: 0x0}, + 688: {region: 0x99, script: 0xd6, flags: 0x0}, + 689: {region: 0x9e, script: 0x55, flags: 0x0}, + 690: {region: 0x165, script: 0x55, flags: 0x0}, + 691: {region: 0x4b, script: 0x55, flags: 0x0}, + 692: {region: 0x165, script: 0x55, flags: 0x0}, + 693: {region: 0x165, script: 0x55, flags: 0x0}, + 694: {region: 0xaf, script: 0x52, flags: 0x0}, + 695: {region: 0x165, script: 0x55, flags: 0x0}, + 696: {region: 0x165, script: 0x55, flags: 0x0}, + 697: {region: 0x4b, script: 0x55, flags: 0x0}, + 698: {region: 0x165, script: 0x55, flags: 0x0}, + 699: {region: 0x165, script: 0x55, flags: 0x0}, + 700: {region: 0x162, script: 0x55, flags: 0x0}, + 701: {region: 0x9c, script: 0x5, flags: 0x0}, + 702: {region: 0xb6, script: 0x55, flags: 0x0}, + 703: {region: 0xb8, script: 0x55, flags: 0x0}, + 704: {region: 0x4b, script: 0x55, flags: 0x0}, + 705: {region: 0x4b, script: 0x55, flags: 0x0}, + 706: {region: 0xa4, script: 0x55, flags: 0x0}, + 707: {region: 0xa4, script: 0x55, flags: 0x0}, + 708: {region: 0x9c, script: 0x5, flags: 0x0}, + 709: {region: 0xb8, script: 0x55, flags: 0x0}, + 710: {region: 0x123, script: 0xdb, flags: 0x0}, + 711: {region: 0x53, script: 0x37, flags: 0x0}, + 712: {region: 0x12b, script: 0x55, flags: 0x0}, + 713: {region: 0x95, script: 0x55, flags: 0x0}, + 714: {region: 0x52, script: 0x55, flags: 0x0}, + 715: {region: 0x99, script: 0x20, flags: 0x0}, + 716: {region: 0x99, script: 0x20, flags: 0x0}, + 717: {region: 0x95, script: 0x55, flags: 0x0}, + 718: {region: 0x23, script: 0x3, flags: 0x1}, + 719: {region: 0xa4, script: 0x55, flags: 0x0}, + 720: {region: 0x165, script: 0x55, flags: 0x0}, + 721: {region: 0xcf, script: 0x55, flags: 0x0}, + 722: {region: 0x165, script: 0x55, flags: 0x0}, + 723: {region: 0x165, script: 0x55, flags: 0x0}, + 724: {region: 0x165, script: 0x55, flags: 0x0}, + 725: {region: 0x165, script: 0x55, flags: 0x0}, + 726: {region: 0x165, script: 0x55, flags: 0x0}, + 727: {region: 0x165, script: 0x55, flags: 0x0}, + 728: {region: 0x165, script: 0x55, flags: 0x0}, + 729: {region: 0x165, script: 0x55, flags: 0x0}, + 730: {region: 0x165, script: 0x55, flags: 0x0}, + 731: {region: 0x165, script: 0x55, flags: 0x0}, + 732: {region: 0x165, script: 0x55, flags: 0x0}, + 733: {region: 0x165, script: 0x5, flags: 0x0}, + 734: {region: 0x106, script: 0x1e, flags: 0x0}, + 735: {region: 0xe7, script: 0x55, flags: 0x0}, + 736: {region: 0x165, script: 0x55, flags: 0x0}, + 737: {region: 0x95, script: 0x55, flags: 0x0}, + 738: {region: 0x165, script: 0x28, flags: 0x0}, + 739: {region: 0x165, script: 0x55, flags: 0x0}, + 740: {region: 0x165, script: 0x55, flags: 0x0}, + 741: {region: 0x165, script: 0x55, flags: 0x0}, + 742: {region: 0x112, script: 0x55, flags: 0x0}, + 743: {region: 0xa4, script: 0x55, flags: 0x0}, + 744: {region: 0x165, script: 0x55, flags: 0x0}, + 745: {region: 0x165, script: 0x55, flags: 0x0}, + 746: {region: 0x123, script: 0x5, flags: 0x0}, + 747: {region: 0xcc, script: 0x55, flags: 0x0}, + 748: {region: 0x165, script: 0x55, flags: 0x0}, + 749: {region: 0x165, script: 0x55, flags: 0x0}, + 750: {region: 0x165, script: 0x55, flags: 0x0}, + 751: {region: 0xbf, script: 0x55, flags: 0x0}, + 752: {region: 0xd1, script: 0x55, flags: 0x0}, + 753: {region: 0x165, script: 0x55, flags: 0x0}, + 754: {region: 0x52, script: 0x55, flags: 0x0}, + 755: {region: 0xdb, script: 0x20, flags: 0x0}, + 756: {region: 0x12f, script: 0x55, flags: 0x0}, + 757: {region: 0xc0, script: 0x55, flags: 0x0}, + 758: {region: 0x165, script: 0x55, flags: 0x0}, + 759: {region: 0x165, script: 0x55, flags: 0x0}, + 760: {region: 0xe0, script: 0x55, flags: 0x0}, + 761: {region: 0x165, script: 0x55, flags: 0x0}, + 762: {region: 0x95, script: 0x55, flags: 0x0}, + 763: {region: 0x9b, script: 0x39, flags: 0x0}, + 764: {region: 0x165, script: 0x55, flags: 0x0}, + 765: {region: 0xc2, script: 0x1e, flags: 0x0}, + 766: {region: 0x165, script: 0x5, flags: 0x0}, + 767: {region: 0x165, script: 0x55, flags: 0x0}, + 768: {region: 0x165, script: 0x55, flags: 0x0}, + 769: {region: 0x165, script: 0x55, flags: 0x0}, + 770: {region: 0x99, script: 0x69, flags: 0x0}, + 771: {region: 0x165, script: 0x55, flags: 0x0}, + 772: {region: 0x165, script: 0x55, flags: 0x0}, + 773: {region: 0x10b, script: 0x55, flags: 0x0}, + 774: {region: 0x165, script: 0x55, flags: 0x0}, + 775: {region: 0x165, script: 0x55, flags: 0x0}, + 776: {region: 0x165, script: 0x55, flags: 0x0}, + 777: {region: 0x26, script: 0x3, flags: 0x1}, + 778: {region: 0x165, script: 0x55, flags: 0x0}, + 779: {region: 0x165, script: 0x55, flags: 0x0}, + 780: {region: 0x99, script: 0xe, flags: 0x0}, + 781: {region: 0xc4, script: 0x70, flags: 0x0}, + 783: {region: 0x165, script: 0x55, flags: 0x0}, + 784: {region: 0x49, script: 0x55, flags: 0x0}, + 785: {region: 0x49, script: 0x55, flags: 0x0}, + 786: {region: 0x37, script: 0x55, flags: 0x0}, + 787: {region: 0x165, script: 0x55, flags: 0x0}, + 788: {region: 0x165, script: 0x55, flags: 0x0}, + 789: {region: 0x165, script: 0x55, flags: 0x0}, + 790: {region: 0x165, script: 0x55, flags: 0x0}, + 791: {region: 0x165, script: 0x55, flags: 0x0}, + 792: {region: 0x165, script: 0x55, flags: 0x0}, + 793: {region: 0x99, script: 0x20, flags: 0x0}, + 794: {region: 0xdb, script: 0x20, flags: 0x0}, + 795: {region: 0x106, script: 0x1e, flags: 0x0}, + 796: {region: 0x35, script: 0x6d, flags: 0x0}, + 797: {region: 0x29, script: 0x3, flags: 0x1}, + 798: {region: 0xcb, script: 0x55, flags: 0x0}, + 799: {region: 0x165, script: 0x55, flags: 0x0}, + 800: {region: 0x165, script: 0x55, flags: 0x0}, + 801: {region: 0x165, script: 0x55, flags: 0x0}, + 802: {region: 0x99, script: 0x20, flags: 0x0}, + 803: {region: 0x52, script: 0x55, flags: 0x0}, + 805: {region: 0x165, script: 0x55, flags: 0x0}, + 806: {region: 0x135, script: 0x55, flags: 0x0}, + 807: {region: 0x165, script: 0x55, flags: 0x0}, + 808: {region: 0x165, script: 0x55, flags: 0x0}, + 809: {region: 0xe8, script: 0x5, flags: 0x0}, + 810: {region: 0xc3, script: 0x55, flags: 0x0}, + 811: {region: 0x99, script: 0x20, flags: 0x0}, + 812: {region: 0x95, script: 0x55, flags: 0x0}, + 813: {region: 0x164, script: 0x55, flags: 0x0}, + 814: {region: 0x165, script: 0x55, flags: 0x0}, + 815: {region: 0xc4, script: 0x70, flags: 0x0}, + 816: {region: 0x165, script: 0x55, flags: 0x0}, + 817: {region: 0x165, script: 0x28, flags: 0x0}, + 818: {region: 0x106, script: 0x1e, flags: 0x0}, + 819: {region: 0x165, script: 0x55, flags: 0x0}, + 820: {region: 0x131, script: 0x55, flags: 0x0}, + 821: {region: 0x9c, script: 0x61, flags: 0x0}, + 822: {region: 0x165, script: 0x55, flags: 0x0}, + 823: {region: 0x165, script: 0x55, flags: 0x0}, + 824: {region: 0x9c, script: 0x5, flags: 0x0}, + 825: {region: 0x165, script: 0x55, flags: 0x0}, + 826: {region: 0x165, script: 0x55, flags: 0x0}, + 827: {region: 0x165, script: 0x55, flags: 0x0}, + 828: {region: 0xdd, script: 0x55, flags: 0x0}, + 829: {region: 0x165, script: 0x55, flags: 0x0}, + 830: {region: 0x165, script: 0x55, flags: 0x0}, + 832: {region: 0x165, script: 0x55, flags: 0x0}, + 833: {region: 0x53, script: 0x37, flags: 0x0}, + 834: {region: 0x9e, script: 0x55, flags: 0x0}, + 835: {region: 0xd2, script: 0x55, flags: 0x0}, + 836: {region: 0x165, script: 0x55, flags: 0x0}, + 837: {region: 0xda, script: 0x55, flags: 0x0}, + 838: {region: 0x165, script: 0x55, flags: 0x0}, + 839: {region: 0x165, script: 0x55, flags: 0x0}, + 840: {region: 0x165, script: 0x55, flags: 0x0}, + 841: {region: 0xcf, script: 0x55, flags: 0x0}, + 842: {region: 0x165, script: 0x55, flags: 0x0}, + 843: {region: 0x165, script: 0x55, flags: 0x0}, + 844: {region: 0x164, script: 0x55, flags: 0x0}, + 845: {region: 0xd1, script: 0x55, flags: 0x0}, + 846: {region: 0x60, script: 0x55, flags: 0x0}, + 847: {region: 0xdb, script: 0x20, flags: 0x0}, + 848: {region: 0x165, script: 0x55, flags: 0x0}, + 849: {region: 0xdb, script: 0x20, flags: 0x0}, + 850: {region: 0x165, script: 0x55, flags: 0x0}, + 851: {region: 0x165, script: 0x55, flags: 0x0}, + 852: {region: 0xd2, script: 0x55, flags: 0x0}, + 853: {region: 0x165, script: 0x55, flags: 0x0}, + 854: {region: 0x165, script: 0x55, flags: 0x0}, + 855: {region: 0xd1, script: 0x55, flags: 0x0}, + 856: {region: 0x165, script: 0x55, flags: 0x0}, + 857: {region: 0xcf, script: 0x55, flags: 0x0}, + 858: {region: 0xcf, script: 0x55, flags: 0x0}, + 859: {region: 0x165, script: 0x55, flags: 0x0}, + 860: {region: 0x165, script: 0x55, flags: 0x0}, + 861: {region: 0x95, script: 0x55, flags: 0x0}, + 862: {region: 0x165, script: 0x55, flags: 0x0}, + 863: {region: 0xdf, script: 0x55, flags: 0x0}, + 864: {region: 0x165, script: 0x55, flags: 0x0}, + 865: {region: 0x165, script: 0x55, flags: 0x0}, + 866: {region: 0x99, script: 0x55, flags: 0x0}, + 867: {region: 0x165, script: 0x55, flags: 0x0}, + 868: {region: 0x165, script: 0x55, flags: 0x0}, + 869: {region: 0xd9, script: 0x55, flags: 0x0}, + 870: {region: 0x52, script: 0x55, flags: 0x0}, + 871: {region: 0x165, script: 0x55, flags: 0x0}, + 872: {region: 0xda, script: 0x55, flags: 0x0}, + 873: {region: 0x165, script: 0x55, flags: 0x0}, + 874: {region: 0x52, script: 0x55, flags: 0x0}, + 875: {region: 0x165, script: 0x55, flags: 0x0}, + 876: {region: 0x165, script: 0x55, flags: 0x0}, + 877: {region: 0xda, script: 0x55, flags: 0x0}, + 878: {region: 0x123, script: 0x51, flags: 0x0}, + 879: {region: 0x99, script: 0x20, flags: 0x0}, + 880: {region: 0x10c, script: 0xbc, flags: 0x0}, + 881: {region: 0x165, script: 0x55, flags: 0x0}, + 882: {region: 0x165, script: 0x55, flags: 0x0}, + 883: {region: 0x84, script: 0x75, flags: 0x0}, + 884: {region: 0x161, script: 0x55, flags: 0x0}, + 885: {region: 0x165, script: 0x55, flags: 0x0}, + 886: {region: 0x49, script: 0x17, flags: 0x0}, + 887: {region: 0x165, script: 0x55, flags: 0x0}, + 888: {region: 0x161, script: 0x55, flags: 0x0}, + 889: {region: 0x165, script: 0x55, flags: 0x0}, + 890: {region: 0x165, script: 0x55, flags: 0x0}, + 891: {region: 0x165, script: 0x55, flags: 0x0}, + 892: {region: 0x165, script: 0x55, flags: 0x0}, + 893: {region: 0x165, script: 0x55, flags: 0x0}, + 894: {region: 0x117, script: 0x55, flags: 0x0}, + 895: {region: 0x165, script: 0x55, flags: 0x0}, + 896: {region: 0x165, script: 0x55, flags: 0x0}, + 897: {region: 0x135, script: 0x55, flags: 0x0}, + 898: {region: 0x165, script: 0x55, flags: 0x0}, + 899: {region: 0x53, script: 0x55, flags: 0x0}, + 900: {region: 0x165, script: 0x55, flags: 0x0}, + 901: {region: 0xce, script: 0x55, flags: 0x0}, + 902: {region: 0x12f, script: 0x55, flags: 0x0}, + 903: {region: 0x131, script: 0x55, flags: 0x0}, + 904: {region: 0x80, script: 0x55, flags: 0x0}, + 905: {region: 0x78, script: 0x55, flags: 0x0}, + 906: {region: 0x165, script: 0x55, flags: 0x0}, + 908: {region: 0x165, script: 0x55, flags: 0x0}, + 909: {region: 0x165, script: 0x55, flags: 0x0}, + 910: {region: 0x6f, script: 0x55, flags: 0x0}, + 911: {region: 0x165, script: 0x55, flags: 0x0}, + 912: {region: 0x165, script: 0x55, flags: 0x0}, + 913: {region: 0x165, script: 0x55, flags: 0x0}, + 914: {region: 0x165, script: 0x55, flags: 0x0}, + 915: {region: 0x99, script: 0x7a, flags: 0x0}, + 916: {region: 0x165, script: 0x55, flags: 0x0}, + 917: {region: 0x165, script: 0x5, flags: 0x0}, + 918: {region: 0x7d, script: 0x1e, flags: 0x0}, + 919: {region: 0x135, script: 0x7b, flags: 0x0}, + 920: {region: 0x165, script: 0x5, flags: 0x0}, + 921: {region: 0xc5, script: 0x79, flags: 0x0}, + 922: {region: 0x165, script: 0x55, flags: 0x0}, + 923: {region: 0x2c, script: 0x3, flags: 0x1}, + 924: {region: 0xe7, script: 0x55, flags: 0x0}, + 925: {region: 0x2f, script: 0x2, flags: 0x1}, + 926: {region: 0xe7, script: 0x55, flags: 0x0}, + 927: {region: 0x30, script: 0x55, flags: 0x0}, + 928: {region: 0xf0, script: 0x55, flags: 0x0}, + 929: {region: 0x165, script: 0x55, flags: 0x0}, + 930: {region: 0x78, script: 0x55, flags: 0x0}, + 931: {region: 0xd6, script: 0x55, flags: 0x0}, + 932: {region: 0x135, script: 0x55, flags: 0x0}, + 933: {region: 0x49, script: 0x55, flags: 0x0}, + 934: {region: 0x165, script: 0x55, flags: 0x0}, + 935: {region: 0x9c, script: 0xe3, flags: 0x0}, + 936: {region: 0x165, script: 0x55, flags: 0x0}, + 937: {region: 0x60, script: 0x55, flags: 0x0}, + 938: {region: 0x165, script: 0x5, flags: 0x0}, + 939: {region: 0xb0, script: 0x84, flags: 0x0}, + 941: {region: 0x165, script: 0x55, flags: 0x0}, + 942: {region: 0x165, script: 0x55, flags: 0x0}, + 943: {region: 0x99, script: 0x12, flags: 0x0}, + 944: {region: 0xa4, script: 0x55, flags: 0x0}, + 945: {region: 0xe9, script: 0x55, flags: 0x0}, + 946: {region: 0x165, script: 0x55, flags: 0x0}, + 947: {region: 0x9e, script: 0x55, flags: 0x0}, + 948: {region: 0x165, script: 0x55, flags: 0x0}, + 949: {region: 0x165, script: 0x55, flags: 0x0}, + 950: {region: 0x87, script: 0x30, flags: 0x0}, + 951: {region: 0x75, script: 0x55, flags: 0x0}, + 952: {region: 0x165, script: 0x55, flags: 0x0}, + 953: {region: 0xe8, script: 0x48, flags: 0x0}, + 954: {region: 0x9c, script: 0x5, flags: 0x0}, + 955: {region: 0x1, script: 0x55, flags: 0x0}, + 956: {region: 0x24, script: 0x5, flags: 0x0}, + 957: {region: 0x165, script: 0x55, flags: 0x0}, + 958: {region: 0x41, script: 0x55, flags: 0x0}, + 959: {region: 0x165, script: 0x55, flags: 0x0}, + 960: {region: 0x7a, script: 0x55, flags: 0x0}, + 961: {region: 0x165, script: 0x55, flags: 0x0}, + 962: {region: 0xe4, script: 0x55, flags: 0x0}, + 963: {region: 0x89, script: 0x55, flags: 0x0}, + 964: {region: 0x69, script: 0x55, flags: 0x0}, + 965: {region: 0x165, script: 0x55, flags: 0x0}, + 966: {region: 0x99, script: 0x20, flags: 0x0}, + 967: {region: 0x165, script: 0x55, flags: 0x0}, + 968: {region: 0x102, script: 0x55, flags: 0x0}, + 969: {region: 0x95, script: 0x55, flags: 0x0}, + 970: {region: 0x165, script: 0x55, flags: 0x0}, + 971: {region: 0x165, script: 0x55, flags: 0x0}, + 972: {region: 0x9e, script: 0x55, flags: 0x0}, + 973: {region: 0x165, script: 0x5, flags: 0x0}, + 974: {region: 0x99, script: 0x55, flags: 0x0}, + 975: {region: 0x31, script: 0x2, flags: 0x1}, + 976: {region: 0xdb, script: 0x20, flags: 0x0}, + 977: {region: 0x35, script: 0xe, flags: 0x0}, + 978: {region: 0x4e, script: 0x55, flags: 0x0}, + 979: {region: 0x72, script: 0x55, flags: 0x0}, + 980: {region: 0x4e, script: 0x55, flags: 0x0}, + 981: {region: 0x9c, script: 0x5, flags: 0x0}, + 982: {region: 0x10c, script: 0x55, flags: 0x0}, + 983: {region: 0x3a, script: 0x55, flags: 0x0}, + 984: {region: 0x165, script: 0x55, flags: 0x0}, + 985: {region: 0xd1, script: 0x55, flags: 0x0}, + 986: {region: 0x104, script: 0x55, flags: 0x0}, + 987: {region: 0x95, script: 0x55, flags: 0x0}, + 988: {region: 0x12f, script: 0x55, flags: 0x0}, + 989: {region: 0x165, script: 0x55, flags: 0x0}, + 990: {region: 0x165, script: 0x55, flags: 0x0}, + 991: {region: 0x73, script: 0x55, flags: 0x0}, + 992: {region: 0x106, script: 0x1e, flags: 0x0}, + 993: {region: 0x130, script: 0x1e, flags: 0x0}, + 994: {region: 0x109, script: 0x55, flags: 0x0}, + 995: {region: 0x107, script: 0x55, flags: 0x0}, + 996: {region: 0x12f, script: 0x55, flags: 0x0}, + 997: {region: 0x165, script: 0x55, flags: 0x0}, + 998: {region: 0xa2, script: 0x47, flags: 0x0}, + 999: {region: 0x99, script: 0x20, flags: 0x0}, + 1000: {region: 0x80, script: 0x55, flags: 0x0}, + 1001: {region: 0x106, script: 0x1e, flags: 0x0}, + 1002: {region: 0xa4, script: 0x55, flags: 0x0}, + 1003: {region: 0x95, script: 0x55, flags: 0x0}, + 1004: {region: 0x99, script: 0x55, flags: 0x0}, + 1005: {region: 0x114, script: 0x55, flags: 0x0}, + 1006: {region: 0x99, script: 0xc0, flags: 0x0}, + 1007: {region: 0x165, script: 0x55, flags: 0x0}, + 1008: {region: 0x165, script: 0x55, flags: 0x0}, + 1009: {region: 0x12f, script: 0x55, flags: 0x0}, + 1010: {region: 0x9e, script: 0x55, flags: 0x0}, + 1011: {region: 0x99, script: 0x20, flags: 0x0}, + 1012: {region: 0x165, script: 0x5, flags: 0x0}, + 1013: {region: 0x9e, script: 0x55, flags: 0x0}, + 1014: {region: 0x7b, script: 0x55, flags: 0x0}, + 1015: {region: 0x49, script: 0x55, flags: 0x0}, + 1016: {region: 0x33, script: 0x4, flags: 0x1}, + 1017: {region: 0x9e, script: 0x55, flags: 0x0}, + 1018: {region: 0x9c, script: 0x5, flags: 0x0}, + 1019: {region: 0xda, script: 0x55, flags: 0x0}, + 1020: {region: 0x4f, script: 0x55, flags: 0x0}, + 1021: {region: 0xd1, script: 0x55, flags: 0x0}, + 1022: {region: 0xcf, script: 0x55, flags: 0x0}, + 1023: {region: 0xc3, script: 0x55, flags: 0x0}, + 1024: {region: 0x4c, script: 0x55, flags: 0x0}, + 1025: {region: 0x96, script: 0x77, flags: 0x0}, + 1026: {region: 0xb6, script: 0x55, flags: 0x0}, + 1027: {region: 0x165, script: 0x28, flags: 0x0}, + 1028: {region: 0x165, script: 0x55, flags: 0x0}, + 1030: {region: 0xba, script: 0xd8, flags: 0x0}, + 1031: {region: 0x165, script: 0x55, flags: 0x0}, + 1032: {region: 0xc4, script: 0x70, flags: 0x0}, + 1033: {region: 0x165, script: 0x5, flags: 0x0}, + 1034: {region: 0xb3, script: 0xc6, flags: 0x0}, + 1035: {region: 0x6f, script: 0x55, flags: 0x0}, + 1036: {region: 0x165, script: 0x55, flags: 0x0}, + 1037: {region: 0x165, script: 0x55, flags: 0x0}, + 1038: {region: 0x165, script: 0x55, flags: 0x0}, + 1039: {region: 0x165, script: 0x55, flags: 0x0}, + 1040: {region: 0x111, script: 0x55, flags: 0x0}, + 1041: {region: 0x165, script: 0x55, flags: 0x0}, + 1042: {region: 0xe8, script: 0x5, flags: 0x0}, + 1043: {region: 0x165, script: 0x55, flags: 0x0}, + 1044: {region: 0x10f, script: 0x55, flags: 0x0}, + 1045: {region: 0x165, script: 0x55, flags: 0x0}, + 1046: {region: 0xe9, script: 0x55, flags: 0x0}, + 1047: {region: 0x165, script: 0x55, flags: 0x0}, + 1048: {region: 0x95, script: 0x55, flags: 0x0}, + 1049: {region: 0x142, script: 0x55, flags: 0x0}, + 1050: {region: 0x10c, script: 0x55, flags: 0x0}, + 1052: {region: 0x10c, script: 0x55, flags: 0x0}, + 1053: {region: 0x72, script: 0x55, flags: 0x0}, + 1054: {region: 0x97, script: 0xbd, flags: 0x0}, + 1055: {region: 0x165, script: 0x55, flags: 0x0}, + 1056: {region: 0x72, script: 0x55, flags: 0x0}, + 1057: {region: 0x164, script: 0x55, flags: 0x0}, + 1058: {region: 0x165, script: 0x55, flags: 0x0}, + 1059: {region: 0xc3, script: 0x55, flags: 0x0}, + 1060: {region: 0x165, script: 0x55, flags: 0x0}, + 1061: {region: 0x165, script: 0x55, flags: 0x0}, + 1062: {region: 0x165, script: 0x55, flags: 0x0}, + 1063: {region: 0x115, script: 0x55, flags: 0x0}, + 1064: {region: 0x165, script: 0x55, flags: 0x0}, + 1065: {region: 0x165, script: 0x55, flags: 0x0}, + 1066: {region: 0x123, script: 0xdb, flags: 0x0}, + 1067: {region: 0x165, script: 0x55, flags: 0x0}, + 1068: {region: 0x165, script: 0x55, flags: 0x0}, + 1069: {region: 0x165, script: 0x55, flags: 0x0}, + 1070: {region: 0x165, script: 0x55, flags: 0x0}, + 1071: {region: 0x27, script: 0x55, flags: 0x0}, + 1072: {region: 0x37, script: 0x5, flags: 0x1}, + 1073: {region: 0x99, script: 0xc7, flags: 0x0}, + 1074: {region: 0x116, script: 0x55, flags: 0x0}, + 1075: {region: 0x114, script: 0x55, flags: 0x0}, + 1076: {region: 0x99, script: 0x20, flags: 0x0}, + 1077: {region: 0x161, script: 0x55, flags: 0x0}, + 1078: {region: 0x165, script: 0x55, flags: 0x0}, + 1079: {region: 0x165, script: 0x55, flags: 0x0}, + 1080: {region: 0x6d, script: 0x55, flags: 0x0}, + 1081: {region: 0x161, script: 0x55, flags: 0x0}, + 1082: {region: 0x165, script: 0x55, flags: 0x0}, + 1083: {region: 0x60, script: 0x55, flags: 0x0}, + 1084: {region: 0x95, script: 0x55, flags: 0x0}, + 1085: {region: 0x165, script: 0x55, flags: 0x0}, + 1086: {region: 0x165, script: 0x55, flags: 0x0}, + 1087: {region: 0x12f, script: 0x55, flags: 0x0}, + 1088: {region: 0x165, script: 0x55, flags: 0x0}, + 1089: {region: 0x84, script: 0x55, flags: 0x0}, + 1090: {region: 0x10c, script: 0x55, flags: 0x0}, + 1091: {region: 0x12f, script: 0x55, flags: 0x0}, + 1092: {region: 0x15f, script: 0x5, flags: 0x0}, + 1093: {region: 0x4b, script: 0x55, flags: 0x0}, + 1094: {region: 0x60, script: 0x55, flags: 0x0}, + 1095: {region: 0x165, script: 0x55, flags: 0x0}, + 1096: {region: 0x99, script: 0x20, flags: 0x0}, + 1097: {region: 0x95, script: 0x55, flags: 0x0}, + 1098: {region: 0x165, script: 0x55, flags: 0x0}, + 1099: {region: 0x35, script: 0xe, flags: 0x0}, + 1100: {region: 0x9b, script: 0xcb, flags: 0x0}, + 1101: {region: 0xe9, script: 0x55, flags: 0x0}, + 1102: {region: 0x99, script: 0xd3, flags: 0x0}, + 1103: {region: 0xdb, script: 0x20, flags: 0x0}, + 1104: {region: 0x165, script: 0x55, flags: 0x0}, + 1105: {region: 0x165, script: 0x55, flags: 0x0}, + 1106: {region: 0x165, script: 0x55, flags: 0x0}, + 1107: {region: 0x165, script: 0x55, flags: 0x0}, + 1108: {region: 0x165, script: 0x55, flags: 0x0}, + 1109: {region: 0x165, script: 0x55, flags: 0x0}, + 1110: {region: 0x165, script: 0x55, flags: 0x0}, + 1111: {region: 0x165, script: 0x55, flags: 0x0}, + 1112: {region: 0xe7, script: 0x55, flags: 0x0}, + 1113: {region: 0x165, script: 0x55, flags: 0x0}, + 1114: {region: 0x165, script: 0x55, flags: 0x0}, + 1115: {region: 0x99, script: 0x4d, flags: 0x0}, + 1116: {region: 0x53, script: 0xd1, flags: 0x0}, + 1117: {region: 0xdb, script: 0x20, flags: 0x0}, + 1118: {region: 0xdb, script: 0x20, flags: 0x0}, + 1119: {region: 0x99, script: 0xd6, flags: 0x0}, + 1120: {region: 0x165, script: 0x55, flags: 0x0}, + 1121: {region: 0x112, script: 0x55, flags: 0x0}, + 1122: {region: 0x131, script: 0x55, flags: 0x0}, + 1123: {region: 0x126, script: 0x55, flags: 0x0}, + 1124: {region: 0x165, script: 0x55, flags: 0x0}, + 1125: {region: 0x3c, script: 0x3, flags: 0x1}, + 1126: {region: 0x165, script: 0x55, flags: 0x0}, + 1127: {region: 0x165, script: 0x55, flags: 0x0}, + 1128: {region: 0x165, script: 0x55, flags: 0x0}, + 1129: {region: 0x123, script: 0xdb, flags: 0x0}, + 1130: {region: 0xdb, script: 0x20, flags: 0x0}, + 1131: {region: 0xdb, script: 0x20, flags: 0x0}, + 1132: {region: 0xdb, script: 0x20, flags: 0x0}, + 1133: {region: 0x6f, script: 0x28, flags: 0x0}, + 1134: {region: 0x165, script: 0x55, flags: 0x0}, + 1135: {region: 0x6d, script: 0x28, flags: 0x0}, + 1136: {region: 0x165, script: 0x55, flags: 0x0}, + 1137: {region: 0x165, script: 0x55, flags: 0x0}, + 1138: {region: 0x165, script: 0x55, flags: 0x0}, + 1139: {region: 0xd6, script: 0x55, flags: 0x0}, + 1140: {region: 0x127, script: 0x55, flags: 0x0}, + 1141: {region: 0x125, script: 0x55, flags: 0x0}, + 1142: {region: 0x32, script: 0x55, flags: 0x0}, + 1143: {region: 0xdb, script: 0x20, flags: 0x0}, + 1144: {region: 0xe7, script: 0x55, flags: 0x0}, + 1145: {region: 0x165, script: 0x55, flags: 0x0}, + 1146: {region: 0x165, script: 0x55, flags: 0x0}, + 1147: {region: 0x32, script: 0x55, flags: 0x0}, + 1148: {region: 0xd4, script: 0x55, flags: 0x0}, + 1149: {region: 0x165, script: 0x55, flags: 0x0}, + 1150: {region: 0x161, script: 0x55, flags: 0x0}, + 1151: {region: 0x165, script: 0x55, flags: 0x0}, + 1152: {region: 0x129, script: 0x55, flags: 0x0}, + 1153: {region: 0x165, script: 0x55, flags: 0x0}, + 1154: {region: 0xce, script: 0x55, flags: 0x0}, + 1155: {region: 0x165, script: 0x55, flags: 0x0}, + 1156: {region: 0xe6, script: 0x55, flags: 0x0}, + 1157: {region: 0x165, script: 0x55, flags: 0x0}, + 1158: {region: 0x165, script: 0x55, flags: 0x0}, + 1159: {region: 0x165, script: 0x55, flags: 0x0}, + 1160: {region: 0x12b, script: 0x55, flags: 0x0}, + 1161: {region: 0x12b, script: 0x55, flags: 0x0}, + 1162: {region: 0x12e, script: 0x55, flags: 0x0}, + 1163: {region: 0x165, script: 0x5, flags: 0x0}, + 1164: {region: 0x161, script: 0x55, flags: 0x0}, + 1165: {region: 0x87, script: 0x30, flags: 0x0}, + 1166: {region: 0xdb, script: 0x20, flags: 0x0}, + 1167: {region: 0xe7, script: 0x55, flags: 0x0}, + 1168: {region: 0x43, script: 0xdc, flags: 0x0}, + 1169: {region: 0x165, script: 0x55, flags: 0x0}, + 1170: {region: 0x106, script: 0x1e, flags: 0x0}, + 1171: {region: 0x165, script: 0x55, flags: 0x0}, + 1172: {region: 0x165, script: 0x55, flags: 0x0}, + 1173: {region: 0x131, script: 0x55, flags: 0x0}, + 1174: {region: 0x165, script: 0x55, flags: 0x0}, + 1175: {region: 0x123, script: 0xdb, flags: 0x0}, + 1176: {region: 0x32, script: 0x55, flags: 0x0}, + 1177: {region: 0x165, script: 0x55, flags: 0x0}, + 1178: {region: 0x165, script: 0x55, flags: 0x0}, + 1179: {region: 0xce, script: 0x55, flags: 0x0}, + 1180: {region: 0x165, script: 0x55, flags: 0x0}, + 1181: {region: 0x165, script: 0x55, flags: 0x0}, + 1182: {region: 0x12d, script: 0x55, flags: 0x0}, + 1183: {region: 0x165, script: 0x55, flags: 0x0}, + 1185: {region: 0x165, script: 0x55, flags: 0x0}, + 1186: {region: 0xd4, script: 0x55, flags: 0x0}, + 1187: {region: 0x53, script: 0xd4, flags: 0x0}, + 1188: {region: 0xe5, script: 0x55, flags: 0x0}, + 1189: {region: 0x165, script: 0x55, flags: 0x0}, + 1190: {region: 0x106, script: 0x1e, flags: 0x0}, + 1191: {region: 0xba, script: 0x55, flags: 0x0}, + 1192: {region: 0x165, script: 0x55, flags: 0x0}, + 1193: {region: 0x106, script: 0x1e, flags: 0x0}, + 1194: {region: 0x3f, script: 0x4, flags: 0x1}, + 1195: {region: 0x11c, script: 0xde, flags: 0x0}, + 1196: {region: 0x130, script: 0x1e, flags: 0x0}, + 1197: {region: 0x75, script: 0x55, flags: 0x0}, + 1198: {region: 0x2a, script: 0x55, flags: 0x0}, + 1200: {region: 0x43, script: 0x3, flags: 0x1}, + 1201: {region: 0x99, script: 0xe, flags: 0x0}, + 1202: {region: 0xe8, script: 0x5, flags: 0x0}, + 1203: {region: 0x165, script: 0x55, flags: 0x0}, + 1204: {region: 0x165, script: 0x55, flags: 0x0}, + 1205: {region: 0x165, script: 0x55, flags: 0x0}, + 1206: {region: 0x165, script: 0x55, flags: 0x0}, + 1207: {region: 0x165, script: 0x55, flags: 0x0}, + 1208: {region: 0x165, script: 0x55, flags: 0x0}, + 1209: {region: 0x165, script: 0x55, flags: 0x0}, + 1210: {region: 0x46, script: 0x4, flags: 0x1}, + 1211: {region: 0x165, script: 0x55, flags: 0x0}, + 1212: {region: 0xb4, script: 0xdf, flags: 0x0}, + 1213: {region: 0x165, script: 0x55, flags: 0x0}, + 1214: {region: 0x161, script: 0x55, flags: 0x0}, + 1215: {region: 0x9e, script: 0x55, flags: 0x0}, + 1216: {region: 0x106, script: 0x55, flags: 0x0}, + 1217: {region: 0x13e, script: 0x55, flags: 0x0}, + 1218: {region: 0x11b, script: 0x55, flags: 0x0}, + 1219: {region: 0x165, script: 0x55, flags: 0x0}, + 1220: {region: 0x36, script: 0x55, flags: 0x0}, + 1221: {region: 0x60, script: 0x55, flags: 0x0}, + 1222: {region: 0xd1, script: 0x55, flags: 0x0}, + 1223: {region: 0x1, script: 0x55, flags: 0x0}, + 1224: {region: 0x106, script: 0x55, flags: 0x0}, + 1225: {region: 0x6a, script: 0x55, flags: 0x0}, + 1226: {region: 0x12f, script: 0x55, flags: 0x0}, + 1227: {region: 0x165, script: 0x55, flags: 0x0}, + 1228: {region: 0x36, script: 0x55, flags: 0x0}, + 1229: {region: 0x4e, script: 0x55, flags: 0x0}, + 1230: {region: 0x165, script: 0x55, flags: 0x0}, + 1231: {region: 0x6f, script: 0x28, flags: 0x0}, + 1232: {region: 0x165, script: 0x55, flags: 0x0}, + 1233: {region: 0xe7, script: 0x55, flags: 0x0}, + 1234: {region: 0x2f, script: 0x55, flags: 0x0}, + 1235: {region: 0x99, script: 0xd6, flags: 0x0}, + 1236: {region: 0x99, script: 0x20, flags: 0x0}, + 1237: {region: 0x165, script: 0x55, flags: 0x0}, + 1238: {region: 0x165, script: 0x55, flags: 0x0}, + 1239: {region: 0x165, script: 0x55, flags: 0x0}, + 1240: {region: 0x165, script: 0x55, flags: 0x0}, + 1241: {region: 0x165, script: 0x55, flags: 0x0}, + 1242: {region: 0x165, script: 0x55, flags: 0x0}, + 1243: {region: 0x165, script: 0x55, flags: 0x0}, + 1244: {region: 0x165, script: 0x55, flags: 0x0}, + 1245: {region: 0x165, script: 0x55, flags: 0x0}, + 1246: {region: 0x140, script: 0x55, flags: 0x0}, + 1247: {region: 0x165, script: 0x55, flags: 0x0}, + 1248: {region: 0x165, script: 0x55, flags: 0x0}, + 1249: {region: 0xa8, script: 0x5, flags: 0x0}, + 1250: {region: 0x165, script: 0x55, flags: 0x0}, + 1251: {region: 0x114, script: 0x55, flags: 0x0}, + 1252: {region: 0x165, script: 0x55, flags: 0x0}, + 1253: {region: 0x165, script: 0x55, flags: 0x0}, + 1254: {region: 0x165, script: 0x55, flags: 0x0}, + 1255: {region: 0x165, script: 0x55, flags: 0x0}, + 1256: {region: 0x99, script: 0x20, flags: 0x0}, + 1257: {region: 0x53, script: 0x37, flags: 0x0}, + 1258: {region: 0x165, script: 0x55, flags: 0x0}, + 1259: {region: 0x165, script: 0x55, flags: 0x0}, + 1260: {region: 0x41, script: 0x55, flags: 0x0}, + 1261: {region: 0x165, script: 0x55, flags: 0x0}, + 1262: {region: 0x12b, script: 0x18, flags: 0x0}, + 1263: {region: 0x165, script: 0x55, flags: 0x0}, + 1264: {region: 0x161, script: 0x55, flags: 0x0}, + 1265: {region: 0x165, script: 0x55, flags: 0x0}, + 1266: {region: 0x12b, script: 0x5d, flags: 0x0}, + 1267: {region: 0x12b, script: 0x5e, flags: 0x0}, + 1268: {region: 0x7d, script: 0x2a, flags: 0x0}, + 1269: {region: 0x53, script: 0x62, flags: 0x0}, + 1270: {region: 0x10b, script: 0x67, flags: 0x0}, + 1271: {region: 0x108, script: 0x71, flags: 0x0}, + 1272: {region: 0x99, script: 0x20, flags: 0x0}, + 1273: {region: 0x131, script: 0x55, flags: 0x0}, + 1274: {region: 0x165, script: 0x55, flags: 0x0}, + 1275: {region: 0x9c, script: 0x87, flags: 0x0}, + 1276: {region: 0x165, script: 0x55, flags: 0x0}, + 1277: {region: 0x15e, script: 0xbf, flags: 0x0}, + 1278: {region: 0x165, script: 0x55, flags: 0x0}, + 1279: {region: 0x165, script: 0x55, flags: 0x0}, + 1280: {region: 0xdb, script: 0x20, flags: 0x0}, + 1281: {region: 0x165, script: 0x55, flags: 0x0}, + 1282: {region: 0x165, script: 0x55, flags: 0x0}, + 1283: {region: 0xd1, script: 0x55, flags: 0x0}, + 1284: {region: 0x75, script: 0x55, flags: 0x0}, + 1285: {region: 0x165, script: 0x55, flags: 0x0}, + 1286: {region: 0x165, script: 0x55, flags: 0x0}, + 1287: {region: 0x52, script: 0x55, flags: 0x0}, + 1288: {region: 0x165, script: 0x55, flags: 0x0}, + 1289: {region: 0x165, script: 0x55, flags: 0x0}, + 1290: {region: 0x165, script: 0x55, flags: 0x0}, + 1291: {region: 0x52, script: 0x55, flags: 0x0}, + 1292: {region: 0x165, script: 0x55, flags: 0x0}, + 1293: {region: 0x165, script: 0x55, flags: 0x0}, + 1294: {region: 0x165, script: 0x55, flags: 0x0}, + 1295: {region: 0x165, script: 0x55, flags: 0x0}, + 1296: {region: 0x1, script: 0x3a, flags: 0x0}, + 1297: {region: 0x165, script: 0x55, flags: 0x0}, + 1298: {region: 0x165, script: 0x55, flags: 0x0}, + 1299: {region: 0x165, script: 0x55, flags: 0x0}, + 1300: {region: 0x165, script: 0x55, flags: 0x0}, + 1301: {region: 0x165, script: 0x55, flags: 0x0}, + 1302: {region: 0xd6, script: 0x55, flags: 0x0}, + 1303: {region: 0x165, script: 0x55, flags: 0x0}, + 1304: {region: 0x165, script: 0x55, flags: 0x0}, + 1305: {region: 0x165, script: 0x55, flags: 0x0}, + 1306: {region: 0x41, script: 0x55, flags: 0x0}, + 1307: {region: 0x165, script: 0x55, flags: 0x0}, + 1308: {region: 0xcf, script: 0x55, flags: 0x0}, + 1309: {region: 0x4a, script: 0x3, flags: 0x1}, + 1310: {region: 0x165, script: 0x55, flags: 0x0}, + 1311: {region: 0x165, script: 0x55, flags: 0x0}, + 1312: {region: 0x165, script: 0x55, flags: 0x0}, + 1313: {region: 0x53, script: 0x55, flags: 0x0}, + 1314: {region: 0x10b, script: 0x55, flags: 0x0}, + 1316: {region: 0xa8, script: 0x5, flags: 0x0}, + 1317: {region: 0xd9, script: 0x55, flags: 0x0}, + 1318: {region: 0xba, script: 0xd8, flags: 0x0}, + 1319: {region: 0x4d, script: 0x14, flags: 0x1}, + 1320: {region: 0x165, script: 0x55, flags: 0x0}, + 1321: {region: 0x122, script: 0x55, flags: 0x0}, + 1322: {region: 0xd0, script: 0x55, flags: 0x0}, + 1323: {region: 0x165, script: 0x55, flags: 0x0}, + 1324: {region: 0x161, script: 0x55, flags: 0x0}, + 1326: {region: 0x12b, script: 0x55, flags: 0x0}, +} + +// likelyLangList holds lists info associated with likelyLang. +// Size: 388 bytes, 97 elements +var likelyLangList = [97]likelyScriptRegion{ + 0: {region: 0x9c, script: 0x7, flags: 0x0}, + 1: {region: 0xa1, script: 0x72, flags: 0x2}, + 2: {region: 0x11c, script: 0x7d, flags: 0x2}, + 3: {region: 0x32, script: 0x55, flags: 0x0}, + 4: {region: 0x9b, script: 0x5, flags: 0x4}, + 5: {region: 0x9c, script: 0x5, flags: 0x4}, + 6: {region: 0x106, script: 0x1e, flags: 0x4}, + 7: {region: 0x9c, script: 0x5, flags: 0x2}, + 8: {region: 0x106, script: 0x1e, flags: 0x0}, + 9: {region: 0x38, script: 0x2b, flags: 0x2}, + 10: {region: 0x135, script: 0x55, flags: 0x0}, + 11: {region: 0x7b, script: 0xc2, flags: 0x2}, + 12: {region: 0x114, script: 0x55, flags: 0x0}, + 13: {region: 0x84, script: 0x1, flags: 0x2}, + 14: {region: 0x5d, script: 0x1d, flags: 0x0}, + 15: {region: 0x87, script: 0x5a, flags: 0x2}, + 16: {region: 0xd6, script: 0x55, flags: 0x0}, + 17: {region: 0x52, script: 0x5, flags: 0x4}, + 18: {region: 0x10b, script: 0x5, flags: 0x4}, + 19: {region: 0xae, script: 0x1e, flags: 0x0}, + 20: {region: 0x24, script: 0x5, flags: 0x4}, + 21: {region: 0x53, script: 0x5, flags: 0x4}, + 22: {region: 0x9c, script: 0x5, flags: 0x4}, + 23: {region: 0xc5, script: 0x5, flags: 0x4}, + 24: {region: 0x53, script: 0x5, flags: 0x2}, + 25: {region: 0x12b, script: 0x55, flags: 0x0}, + 26: {region: 0xb0, script: 0x5, flags: 0x4}, + 27: {region: 0x9b, script: 0x5, flags: 0x2}, + 28: {region: 0xa5, script: 0x1e, flags: 0x0}, + 29: {region: 0x53, script: 0x5, flags: 0x4}, + 30: {region: 0x12b, script: 0x55, flags: 0x4}, + 31: {region: 0x53, script: 0x5, flags: 0x2}, + 32: {region: 0x12b, script: 0x55, flags: 0x2}, + 33: {region: 0xdb, script: 0x20, flags: 0x0}, + 34: {region: 0x99, script: 0x58, flags: 0x2}, + 35: {region: 0x83, script: 0x55, flags: 0x0}, + 36: {region: 0x84, script: 0x75, flags: 0x4}, + 37: {region: 0x84, script: 0x75, flags: 0x2}, + 38: {region: 0xc5, script: 0x1e, flags: 0x0}, + 39: {region: 0x53, script: 0x6b, flags: 0x4}, + 40: {region: 0x53, script: 0x6b, flags: 0x2}, + 41: {region: 0xd0, script: 0x55, flags: 0x0}, + 42: {region: 0x4a, script: 0x5, flags: 0x4}, + 43: {region: 0x95, script: 0x5, flags: 0x4}, + 44: {region: 0x99, script: 0x32, flags: 0x0}, + 45: {region: 0xe8, script: 0x5, flags: 0x4}, + 46: {region: 0xe8, script: 0x5, flags: 0x2}, + 47: {region: 0x9c, script: 0x81, flags: 0x0}, + 48: {region: 0x53, script: 0x82, flags: 0x2}, + 49: {region: 0xba, script: 0xd8, flags: 0x0}, + 50: {region: 0xd9, script: 0x55, flags: 0x4}, + 51: {region: 0xe8, script: 0x5, flags: 0x0}, + 52: {region: 0x99, script: 0x20, flags: 0x2}, + 53: {region: 0x99, script: 0x4a, flags: 0x2}, + 54: {region: 0x99, script: 0xc5, flags: 0x2}, + 55: {region: 0x105, script: 0x1e, flags: 0x0}, + 56: {region: 0xbd, script: 0x55, flags: 0x4}, + 57: {region: 0x104, script: 0x55, flags: 0x4}, + 58: {region: 0x106, script: 0x55, flags: 0x4}, + 59: {region: 0x12b, script: 0x55, flags: 0x4}, + 60: {region: 0x124, script: 0x1e, flags: 0x0}, + 61: {region: 0xe8, script: 0x5, flags: 0x4}, + 62: {region: 0xe8, script: 0x5, flags: 0x2}, + 63: {region: 0x53, script: 0x5, flags: 0x0}, + 64: {region: 0xae, script: 0x1e, flags: 0x4}, + 65: {region: 0xc5, script: 0x1e, flags: 0x4}, + 66: {region: 0xae, script: 0x1e, flags: 0x2}, + 67: {region: 0x99, script: 0xe, flags: 0x0}, + 68: {region: 0xdb, script: 0x20, flags: 0x4}, + 69: {region: 0xdb, script: 0x20, flags: 0x2}, + 70: {region: 0x137, script: 0x55, flags: 0x0}, + 71: {region: 0x24, script: 0x5, flags: 0x4}, + 72: {region: 0x53, script: 0x1e, flags: 0x4}, + 73: {region: 0x24, script: 0x5, flags: 0x2}, + 74: {region: 0x8d, script: 0x38, flags: 0x0}, + 75: {region: 0x53, script: 0x37, flags: 0x4}, + 76: {region: 0x53, script: 0x37, flags: 0x2}, + 77: {region: 0x53, script: 0x37, flags: 0x0}, + 78: {region: 0x2f, script: 0x38, flags: 0x4}, + 79: {region: 0x3e, script: 0x38, flags: 0x4}, + 80: {region: 0x7b, script: 0x38, flags: 0x4}, + 81: {region: 0x7e, script: 0x38, flags: 0x4}, + 82: {region: 0x8d, script: 0x38, flags: 0x4}, + 83: {region: 0x95, script: 0x38, flags: 0x4}, + 84: {region: 0xc6, script: 0x38, flags: 0x4}, + 85: {region: 0xd0, script: 0x38, flags: 0x4}, + 86: {region: 0xe2, script: 0x38, flags: 0x4}, + 87: {region: 0xe5, script: 0x38, flags: 0x4}, + 88: {region: 0xe7, script: 0x38, flags: 0x4}, + 89: {region: 0x116, script: 0x38, flags: 0x4}, + 90: {region: 0x123, script: 0x38, flags: 0x4}, + 91: {region: 0x12e, script: 0x38, flags: 0x4}, + 92: {region: 0x135, script: 0x38, flags: 0x4}, + 93: {region: 0x13e, script: 0x38, flags: 0x4}, + 94: {region: 0x12e, script: 0x11, flags: 0x2}, + 95: {region: 0x12e, script: 0x33, flags: 0x2}, + 96: {region: 0x12e, script: 0x38, 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: 1432 bytes, 358 elements +var likelyRegion = [358]likelyLangScript{ + 34: {lang: 0xd7, script: 0x55, flags: 0x0}, + 35: {lang: 0x3a, script: 0x5, flags: 0x0}, + 36: {lang: 0x0, script: 0x2, flags: 0x1}, + 39: {lang: 0x2, script: 0x2, flags: 0x1}, + 40: {lang: 0x4, script: 0x2, flags: 0x1}, + 42: {lang: 0x3be, script: 0x55, flags: 0x0}, + 43: {lang: 0x0, script: 0x55, flags: 0x0}, + 44: {lang: 0x13d, script: 0x55, flags: 0x0}, + 45: {lang: 0x419, script: 0x55, flags: 0x0}, + 46: {lang: 0x10c, script: 0x55, flags: 0x0}, + 48: {lang: 0x365, script: 0x55, flags: 0x0}, + 49: {lang: 0x442, script: 0x55, flags: 0x0}, + 50: {lang: 0x58, script: 0x55, flags: 0x0}, + 51: {lang: 0x6, script: 0x2, flags: 0x1}, + 53: {lang: 0xa5, script: 0xe, flags: 0x0}, + 54: {lang: 0x365, script: 0x55, flags: 0x0}, + 55: {lang: 0x15d, script: 0x55, flags: 0x0}, + 56: {lang: 0x7e, script: 0x1e, flags: 0x0}, + 57: {lang: 0x3a, script: 0x5, flags: 0x0}, + 58: {lang: 0x3d7, script: 0x55, flags: 0x0}, + 59: {lang: 0x15d, script: 0x55, flags: 0x0}, + 60: {lang: 0x15d, script: 0x55, flags: 0x0}, + 62: {lang: 0x31d, script: 0x55, flags: 0x0}, + 63: {lang: 0x13d, script: 0x55, flags: 0x0}, + 64: {lang: 0x39f, script: 0x55, flags: 0x0}, + 65: {lang: 0x3be, script: 0x55, flags: 0x0}, + 67: {lang: 0x8, script: 0x2, flags: 0x1}, + 69: {lang: 0x0, script: 0x55, flags: 0x0}, + 71: {lang: 0x71, script: 0x1e, flags: 0x0}, + 73: {lang: 0x510, script: 0x3a, flags: 0x2}, + 74: {lang: 0x31d, script: 0x5, flags: 0x2}, + 75: {lang: 0x443, script: 0x55, flags: 0x0}, + 76: {lang: 0x15d, script: 0x55, flags: 0x0}, + 77: {lang: 0x15d, script: 0x55, flags: 0x0}, + 78: {lang: 0x10c, script: 0x55, flags: 0x0}, + 79: {lang: 0x15d, script: 0x55, flags: 0x0}, + 81: {lang: 0x13d, script: 0x55, flags: 0x0}, + 82: {lang: 0x15d, script: 0x55, flags: 0x0}, + 83: {lang: 0xa, script: 0x5, flags: 0x1}, + 84: {lang: 0x13d, script: 0x55, flags: 0x0}, + 85: {lang: 0x0, script: 0x55, flags: 0x0}, + 86: {lang: 0x13d, script: 0x55, flags: 0x0}, + 89: {lang: 0x13d, script: 0x55, flags: 0x0}, + 90: {lang: 0x3be, script: 0x55, flags: 0x0}, + 91: {lang: 0x39f, script: 0x55, flags: 0x0}, + 93: {lang: 0xf, script: 0x2, flags: 0x1}, + 94: {lang: 0xf9, script: 0x55, flags: 0x0}, + 96: {lang: 0x10c, script: 0x55, flags: 0x0}, + 98: {lang: 0x1, script: 0x55, flags: 0x0}, + 99: {lang: 0x100, script: 0x55, flags: 0x0}, + 101: {lang: 0x13d, script: 0x55, flags: 0x0}, + 103: {lang: 0x11, script: 0x2, flags: 0x1}, + 104: {lang: 0x13d, script: 0x55, flags: 0x0}, + 105: {lang: 0x13d, script: 0x55, flags: 0x0}, + 106: {lang: 0x13f, script: 0x55, flags: 0x0}, + 107: {lang: 0x3a, script: 0x5, flags: 0x0}, + 108: {lang: 0x3a, script: 0x5, flags: 0x0}, + 109: {lang: 0x46d, script: 0x28, flags: 0x0}, + 110: {lang: 0x13d, script: 0x55, flags: 0x0}, + 111: {lang: 0x13, script: 0x2, flags: 0x1}, + 113: {lang: 0x10c, script: 0x55, flags: 0x0}, + 114: {lang: 0x150, script: 0x55, flags: 0x0}, + 115: {lang: 0x1be, script: 0x20, flags: 0x2}, + 118: {lang: 0x157, script: 0x55, flags: 0x0}, + 120: {lang: 0x15d, script: 0x55, flags: 0x0}, + 122: {lang: 0x15d, script: 0x55, flags: 0x0}, + 123: {lang: 0x15, script: 0x2, flags: 0x1}, + 125: {lang: 0x17, script: 0x3, flags: 0x1}, + 126: {lang: 0x15d, script: 0x55, flags: 0x0}, + 128: {lang: 0x21, script: 0x55, flags: 0x0}, + 130: {lang: 0x243, script: 0x55, flags: 0x0}, + 132: {lang: 0x15d, script: 0x55, flags: 0x0}, + 133: {lang: 0x15d, script: 0x55, flags: 0x0}, + 134: {lang: 0x13d, script: 0x55, flags: 0x0}, + 135: {lang: 0x1a, script: 0x2, flags: 0x1}, + 136: {lang: 0x0, script: 0x55, flags: 0x0}, + 137: {lang: 0x13d, script: 0x55, flags: 0x0}, + 139: {lang: 0x3be, script: 0x55, flags: 0x0}, + 141: {lang: 0x527, script: 0x38, flags: 0x0}, + 142: {lang: 0x0, script: 0x55, flags: 0x0}, + 143: {lang: 0x13d, script: 0x55, flags: 0x0}, + 144: {lang: 0x1cf, script: 0x55, flags: 0x0}, + 145: {lang: 0x1d2, script: 0x55, flags: 0x0}, + 146: {lang: 0x1d3, script: 0x55, flags: 0x0}, + 148: {lang: 0x13d, script: 0x55, flags: 0x0}, + 149: {lang: 0x1c, script: 0x2, flags: 0x1}, + 151: {lang: 0x1ba, script: 0x3a, flags: 0x0}, + 153: {lang: 0x1e, script: 0x3, flags: 0x1}, + 155: {lang: 0x3a, script: 0x5, flags: 0x0}, + 156: {lang: 0x21, script: 0x2, flags: 0x1}, + 157: {lang: 0x1f6, script: 0x55, flags: 0x0}, + 158: {lang: 0x1f7, script: 0x55, flags: 0x0}, + 161: {lang: 0x3a, script: 0x5, flags: 0x0}, + 162: {lang: 0x1fe, script: 0x44, flags: 0x0}, + 164: {lang: 0x443, script: 0x55, flags: 0x0}, + 165: {lang: 0x288, script: 0x1e, flags: 0x0}, + 166: {lang: 0x23, script: 0x3, flags: 0x1}, + 168: {lang: 0x26, script: 0x2, flags: 0x1}, + 170: {lang: 0x252, script: 0x4e, flags: 0x0}, + 171: {lang: 0x252, script: 0x4e, flags: 0x0}, + 172: {lang: 0x3a, script: 0x5, flags: 0x0}, + 174: {lang: 0x3e0, script: 0x1e, flags: 0x0}, + 175: {lang: 0x28, script: 0x2, flags: 0x1}, + 176: {lang: 0x3a, script: 0x5, flags: 0x0}, + 178: {lang: 0x10c, script: 0x55, flags: 0x0}, + 179: {lang: 0x40a, script: 0xc6, flags: 0x0}, + 181: {lang: 0x439, script: 0x55, flags: 0x0}, + 182: {lang: 0x2be, script: 0x55, flags: 0x0}, + 183: {lang: 0x15d, script: 0x55, flags: 0x0}, + 184: {lang: 0x2c5, script: 0x55, flags: 0x0}, + 185: {lang: 0x3a, script: 0x5, flags: 0x0}, + 186: {lang: 0x2a, script: 0x2, flags: 0x1}, + 187: {lang: 0x15d, script: 0x55, flags: 0x0}, + 188: {lang: 0x2c, script: 0x2, flags: 0x1}, + 189: {lang: 0x430, script: 0x55, flags: 0x0}, + 190: {lang: 0x15d, script: 0x55, flags: 0x0}, + 191: {lang: 0x2ef, script: 0x55, flags: 0x0}, + 194: {lang: 0x2e, script: 0x2, flags: 0x1}, + 195: {lang: 0xa0, script: 0x55, flags: 0x0}, + 196: {lang: 0x30, script: 0x2, flags: 0x1}, + 197: {lang: 0x32, script: 0x2, flags: 0x1}, + 198: {lang: 0x34, script: 0x2, flags: 0x1}, + 200: {lang: 0x15d, script: 0x55, flags: 0x0}, + 201: {lang: 0x36, script: 0x2, flags: 0x1}, + 203: {lang: 0x31e, script: 0x55, flags: 0x0}, + 204: {lang: 0x38, script: 0x3, flags: 0x1}, + 205: {lang: 0x127, script: 0xda, flags: 0x0}, + 207: {lang: 0x13d, script: 0x55, flags: 0x0}, + 208: {lang: 0x31d, script: 0x55, flags: 0x0}, + 209: {lang: 0x3be, script: 0x55, flags: 0x0}, + 210: {lang: 0x16, script: 0x55, flags: 0x0}, + 211: {lang: 0x15d, script: 0x55, flags: 0x0}, + 212: {lang: 0x1b2, script: 0x55, flags: 0x0}, + 214: {lang: 0x1b2, script: 0x5, flags: 0x2}, + 216: {lang: 0x13d, script: 0x55, flags: 0x0}, + 217: {lang: 0x365, script: 0x55, flags: 0x0}, + 218: {lang: 0x345, script: 0x55, flags: 0x0}, + 219: {lang: 0x34f, script: 0x20, flags: 0x0}, + 225: {lang: 0x3a, script: 0x5, flags: 0x0}, + 226: {lang: 0x13d, script: 0x55, flags: 0x0}, + 228: {lang: 0x13d, script: 0x55, flags: 0x0}, + 229: {lang: 0x15d, script: 0x55, flags: 0x0}, + 230: {lang: 0x484, script: 0x55, flags: 0x0}, + 231: {lang: 0x152, script: 0x55, flags: 0x0}, + 232: {lang: 0x3b, script: 0x3, flags: 0x1}, + 233: {lang: 0x3b1, script: 0x55, flags: 0x0}, + 234: {lang: 0x15d, script: 0x55, flags: 0x0}, + 236: {lang: 0x13d, script: 0x55, flags: 0x0}, + 237: {lang: 0x3a, script: 0x5, flags: 0x0}, + 238: {lang: 0x3be, script: 0x55, flags: 0x0}, + 240: {lang: 0x3a0, script: 0x55, flags: 0x0}, + 241: {lang: 0x192, script: 0x55, flags: 0x0}, + 243: {lang: 0x3a, script: 0x5, flags: 0x0}, + 258: {lang: 0x15d, script: 0x55, flags: 0x0}, + 260: {lang: 0x3e, script: 0x2, flags: 0x1}, + 261: {lang: 0x430, script: 0x1e, flags: 0x0}, + 262: {lang: 0x40, script: 0x2, flags: 0x1}, + 263: {lang: 0x3e3, script: 0x55, flags: 0x0}, + 264: {lang: 0x3a, script: 0x5, flags: 0x0}, + 266: {lang: 0x15d, script: 0x55, flags: 0x0}, + 267: {lang: 0x3a, script: 0x5, flags: 0x0}, + 268: {lang: 0x42, script: 0x2, flags: 0x1}, + 271: {lang: 0x414, script: 0x55, flags: 0x0}, + 272: {lang: 0x345, script: 0x55, flags: 0x0}, + 273: {lang: 0x44, script: 0x2, flags: 0x1}, + 275: {lang: 0x1f7, script: 0x55, flags: 0x0}, + 276: {lang: 0x15d, script: 0x55, flags: 0x0}, + 277: {lang: 0x427, script: 0x55, flags: 0x0}, + 278: {lang: 0x365, script: 0x55, flags: 0x0}, + 280: {lang: 0x3be, script: 0x55, flags: 0x0}, + 282: {lang: 0x13d, script: 0x55, flags: 0x0}, + 284: {lang: 0x46, script: 0x2, flags: 0x1}, + 288: {lang: 0x15d, script: 0x55, flags: 0x0}, + 289: {lang: 0x15d, script: 0x55, flags: 0x0}, + 290: {lang: 0x48, script: 0x2, flags: 0x1}, + 291: {lang: 0x4a, script: 0x3, flags: 0x1}, + 292: {lang: 0x4d, script: 0x2, flags: 0x1}, + 293: {lang: 0x475, script: 0x55, flags: 0x0}, + 294: {lang: 0x3be, script: 0x55, flags: 0x0}, + 295: {lang: 0x474, script: 0x55, flags: 0x0}, + 296: {lang: 0x4f, script: 0x2, flags: 0x1}, + 297: {lang: 0x480, script: 0x55, flags: 0x0}, + 299: {lang: 0x51, script: 0x4, flags: 0x1}, + 301: {lang: 0x49e, script: 0x55, flags: 0x0}, + 302: {lang: 0x55, script: 0x2, flags: 0x1}, + 303: {lang: 0x443, script: 0x55, flags: 0x0}, + 304: {lang: 0x57, script: 0x3, flags: 0x1}, + 305: {lang: 0x443, script: 0x55, flags: 0x0}, + 309: {lang: 0x510, script: 0x3a, flags: 0x2}, + 310: {lang: 0x13d, script: 0x55, flags: 0x0}, + 311: {lang: 0x4ba, script: 0x55, flags: 0x0}, + 312: {lang: 0x1f7, script: 0x55, flags: 0x0}, + 315: {lang: 0x13d, script: 0x55, flags: 0x0}, + 318: {lang: 0x4c1, script: 0x55, flags: 0x0}, + 319: {lang: 0x8a, script: 0x55, flags: 0x0}, + 320: {lang: 0x15d, script: 0x55, flags: 0x0}, + 322: {lang: 0x419, script: 0x55, flags: 0x0}, + 333: {lang: 0x5a, script: 0x2, flags: 0x1}, + 350: {lang: 0x3a, script: 0x5, flags: 0x0}, + 351: {lang: 0x5c, script: 0x2, flags: 0x1}, + 356: {lang: 0x421, script: 0x55, flags: 0x0}, +} + +// likelyRegionList holds lists info associated with likelyRegion. +// Size: 376 bytes, 94 elements +var likelyRegionList = [94]likelyLangScript{ + 0: {lang: 0x147, script: 0x5, flags: 0x0}, + 1: {lang: 0x474, script: 0x55, flags: 0x0}, + 2: {lang: 0x42f, script: 0x55, flags: 0x0}, + 3: {lang: 0x2fd, script: 0x1e, flags: 0x0}, + 4: {lang: 0x1d5, script: 0x8, flags: 0x0}, + 5: {lang: 0x272, script: 0x55, flags: 0x0}, + 6: {lang: 0xb7, script: 0x55, flags: 0x0}, + 7: {lang: 0x430, script: 0x1e, flags: 0x0}, + 8: {lang: 0x12c, script: 0xdc, flags: 0x0}, + 9: {lang: 0x34f, script: 0x20, flags: 0x0}, + 10: {lang: 0x527, script: 0x37, flags: 0x0}, + 11: {lang: 0x4aa, script: 0x5, flags: 0x0}, + 12: {lang: 0x51d, script: 0x38, flags: 0x0}, + 13: {lang: 0x521, script: 0x55, flags: 0x0}, + 14: {lang: 0x298, script: 0xdb, flags: 0x0}, + 15: {lang: 0x135, script: 0x30, flags: 0x0}, + 16: {lang: 0x488, script: 0x55, flags: 0x0}, + 17: {lang: 0x3a, script: 0x5, flags: 0x0}, + 18: {lang: 0x15d, script: 0x55, flags: 0x0}, + 19: {lang: 0x27, script: 0x28, flags: 0x0}, + 20: {lang: 0x138, script: 0x55, flags: 0x0}, + 21: {lang: 0x268, script: 0x5, flags: 0x2}, + 22: {lang: 0x510, script: 0x3a, flags: 0x2}, + 23: {lang: 0x20e, script: 0x2a, flags: 0x0}, + 24: {lang: 0x5, script: 0x1e, flags: 0x0}, + 25: {lang: 0x272, script: 0x55, flags: 0x0}, + 26: {lang: 0x135, script: 0x30, flags: 0x0}, + 27: {lang: 0x2fd, script: 0x1e, flags: 0x0}, + 28: {lang: 0x1df, script: 0x55, flags: 0x0}, + 29: {lang: 0x31d, script: 0x5, flags: 0x0}, + 30: {lang: 0x1bc, script: 0x20, flags: 0x0}, + 31: {lang: 0x4b2, script: 0x5, flags: 0x0}, + 32: {lang: 0x234, script: 0x70, flags: 0x0}, + 33: {lang: 0x147, script: 0x5, flags: 0x0}, + 34: {lang: 0x474, script: 0x55, flags: 0x0}, + 35: {lang: 0x248, script: 0x49, flags: 0x0}, + 36: {lang: 0xe6, script: 0x5, flags: 0x0}, + 37: {lang: 0x224, script: 0xdb, flags: 0x0}, + 38: {lang: 0x3a, script: 0x5, flags: 0x0}, + 39: {lang: 0x15d, script: 0x55, flags: 0x0}, + 40: {lang: 0x2b6, script: 0x52, flags: 0x0}, + 41: {lang: 0x224, script: 0xdb, flags: 0x0}, + 42: {lang: 0x3a, script: 0x5, flags: 0x0}, + 43: {lang: 0x15d, script: 0x55, flags: 0x0}, + 44: {lang: 0x3da, script: 0x55, flags: 0x0}, + 45: {lang: 0x4ac, script: 0x1e, flags: 0x0}, + 46: {lang: 0x2fd, script: 0x1e, flags: 0x0}, + 47: {lang: 0x42f, script: 0x55, flags: 0x0}, + 48: {lang: 0x32f, script: 0x70, flags: 0x0}, + 49: {lang: 0x211, script: 0x55, flags: 0x0}, + 50: {lang: 0x309, script: 0x1e, flags: 0x0}, + 51: {lang: 0x240, script: 0x5, flags: 0x0}, + 52: {lang: 0x527, script: 0x38, flags: 0x0}, + 53: {lang: 0x3be, script: 0x55, flags: 0x0}, + 54: {lang: 0x3a, script: 0x5, flags: 0x0}, + 55: {lang: 0x15d, script: 0x55, flags: 0x0}, + 56: {lang: 0x2eb, script: 0x55, flags: 0x0}, + 57: {lang: 0x4b2, script: 0x5, flags: 0x0}, + 58: {lang: 0x88, script: 0x20, flags: 0x0}, + 59: {lang: 0x4b2, script: 0x5, flags: 0x0}, + 60: {lang: 0x4b2, script: 0x5, flags: 0x0}, + 61: {lang: 0xbe, script: 0x20, flags: 0x0}, + 62: {lang: 0x3da, script: 0x55, flags: 0x0}, + 63: {lang: 0x7e, script: 0x1e, flags: 0x0}, + 64: {lang: 0x3e0, script: 0x1e, flags: 0x0}, + 65: {lang: 0x265, script: 0x55, flags: 0x0}, + 66: {lang: 0x442, script: 0x55, flags: 0x0}, + 67: {lang: 0x510, script: 0x3a, flags: 0x0}, + 68: {lang: 0x410, script: 0x55, flags: 0x0}, + 69: {lang: 0x4ac, script: 0x1e, flags: 0x0}, + 70: {lang: 0x3a, script: 0x5, flags: 0x0}, + 71: {lang: 0x15d, script: 0x55, flags: 0x0}, + 72: {lang: 0x15d, script: 0x55, flags: 0x0}, + 73: {lang: 0x35, script: 0x5, flags: 0x0}, + 74: {lang: 0x469, script: 0xdb, flags: 0x0}, + 75: {lang: 0x2ea, script: 0x5, flags: 0x0}, + 76: {lang: 0x30d, script: 0x70, flags: 0x0}, + 77: {lang: 0x465, script: 0x1e, flags: 0x0}, + 78: {lang: 0x147, script: 0x5, flags: 0x0}, + 79: {lang: 0x3a, script: 0x5, flags: 0x0}, + 80: {lang: 0x15d, script: 0x55, flags: 0x0}, + 81: {lang: 0x488, script: 0x55, flags: 0x0}, + 82: {lang: 0x58, script: 0x5, flags: 0x0}, + 83: {lang: 0x217, script: 0x1e, flags: 0x0}, + 84: {lang: 0x81, script: 0x30, flags: 0x0}, + 85: {lang: 0x527, script: 0x38, flags: 0x0}, + 86: {lang: 0x48a, script: 0x55, flags: 0x0}, + 87: {lang: 0x4ac, script: 0x1e, flags: 0x0}, + 88: {lang: 0x510, script: 0x3a, flags: 0x0}, + 89: {lang: 0x3b1, script: 0x55, flags: 0x0}, + 90: {lang: 0x42f, script: 0x55, flags: 0x0}, + 91: {lang: 0x430, script: 0x1e, flags: 0x0}, + 92: {lang: 0x15d, script: 0x55, flags: 0x0}, + 93: {lang: 0x444, script: 0x5, flags: 0x0}, +} + +type likelyTag struct { + lang uint16 + region uint16 + script uint8 +} + +// Size: 198 bytes, 33 elements +var likelyRegionGroup = [33]likelyTag{ + 1: {lang: 0x138, region: 0xd6, script: 0x55}, + 2: {lang: 0x138, region: 0x135, script: 0x55}, + 3: {lang: 0x3be, region: 0x41, script: 0x55}, + 4: {lang: 0x138, region: 0x2f, script: 0x55}, + 5: {lang: 0x138, region: 0xd6, script: 0x55}, + 6: {lang: 0x13d, region: 0xcf, script: 0x55}, + 7: {lang: 0x443, region: 0x12f, script: 0x55}, + 8: {lang: 0x3a, region: 0x6b, script: 0x5}, + 9: {lang: 0x443, region: 0x4b, script: 0x55}, + 10: {lang: 0x138, region: 0x161, script: 0x55}, + 11: {lang: 0x138, region: 0x135, script: 0x55}, + 12: {lang: 0x138, region: 0x135, script: 0x55}, + 13: {lang: 0x13d, region: 0x59, script: 0x55}, + 14: {lang: 0x527, region: 0x53, script: 0x37}, + 15: {lang: 0x1bc, region: 0x99, script: 0x20}, + 16: {lang: 0x1df, region: 0x95, script: 0x55}, + 17: {lang: 0x1f7, region: 0x9e, script: 0x55}, + 18: {lang: 0x138, region: 0x2f, script: 0x55}, + 19: {lang: 0x138, region: 0xe6, script: 0x55}, + 20: {lang: 0x138, region: 0x8a, script: 0x55}, + 21: {lang: 0x419, region: 0x142, script: 0x55}, + 22: {lang: 0x527, region: 0x53, script: 0x37}, + 23: {lang: 0x4ba, region: 0x137, script: 0x55}, + 24: {lang: 0x3a, region: 0x108, script: 0x5}, + 25: {lang: 0x3e0, region: 0x106, script: 0x1e}, + 26: {lang: 0x3e0, region: 0x106, script: 0x1e}, + 27: {lang: 0x138, region: 0x7b, script: 0x55}, + 28: {lang: 0x10c, region: 0x60, script: 0x55}, + 30: {lang: 0x13d, region: 0x1f, script: 0x55}, + 31: {lang: 0x138, region: 0x9a, script: 0x55}, + 32: {lang: 0x138, region: 0x7b, script: 0x55}, +} + +// Size: 358 bytes, 358 elements +var regionToGroups = [358]uint8{ + // Entry 0 - 3F + 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, + // Entry 40 - 7F + 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x08, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, + // Entry 80 - BF + 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x00, 0x04, 0x02, 0x00, 0x04, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, + // Entry C0 - FF + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Entry 100 - 13F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x04, 0x04, 0x05, 0x00, 0x00, + // Entry 140 - 17F + 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, +} + +// Size: 18 bytes, 3 elements +var paradigmLocales = [3][3]uint16{ + 0: [3]uint16{0x138, 0x0, 0x7b}, + 1: [3]uint16{0x13d, 0x0, 0x1f}, + 2: [3]uint16{0x3be, 0x41, 0xee}, +} + +type mutualIntelligibility struct { + want uint16 + have uint16 + distance uint8 + oneway bool +} + +type scriptIntelligibility struct { + wantLang uint16 + haveLang uint16 + wantScript uint8 + haveScript uint8 + distance uint8 +} + +type regionIntelligibility struct { + lang uint16 + script uint8 + group uint8 + distance 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: 678 bytes, 113 elements +var matchLang = [113]mutualIntelligibility{ + 0: {want: 0x1cf, have: 0xb7, distance: 0x4, oneway: false}, + 1: {want: 0x405, have: 0xb7, distance: 0x4, oneway: false}, + 2: {want: 0x405, have: 0x1cf, distance: 0x4, oneway: false}, + 3: {want: 0x405, have: 0x430, distance: 0x4, oneway: false}, + 4: {want: 0x438, have: 0x1, distance: 0x4, oneway: false}, + 5: {want: 0x1a1, have: 0x10c, distance: 0x4, oneway: true}, + 6: {want: 0x293, have: 0x10c, distance: 0x4, oneway: true}, + 7: {want: 0x100, have: 0x36d, distance: 0x8, oneway: false}, + 8: {want: 0x100, have: 0x345, distance: 0x8, oneway: false}, + 9: {want: 0x5, have: 0x3e0, distance: 0xa, oneway: true}, + 10: {want: 0xd, have: 0x138, distance: 0xa, oneway: true}, + 11: {want: 0x16, have: 0x365, distance: 0xa, oneway: true}, + 12: {want: 0x21, have: 0x138, distance: 0xa, oneway: true}, + 13: {want: 0x56, have: 0x13d, distance: 0xa, oneway: true}, + 14: {want: 0x58, have: 0x3e0, distance: 0xa, oneway: true}, + 15: {want: 0x71, have: 0x3e0, distance: 0xa, oneway: true}, + 16: {want: 0x75, have: 0x138, distance: 0xa, oneway: true}, + 17: {want: 0x82, have: 0x1bc, distance: 0xa, oneway: true}, + 18: {want: 0xa5, have: 0x138, distance: 0xa, oneway: true}, + 19: {want: 0xb2, have: 0x15d, distance: 0xa, oneway: true}, + 20: {want: 0xdd, have: 0x152, distance: 0xa, oneway: true}, + 21: {want: 0xe5, have: 0x138, distance: 0xa, oneway: true}, + 22: {want: 0xe9, have: 0x3a, distance: 0xa, oneway: true}, + 23: {want: 0xef, have: 0x15d, distance: 0xa, oneway: true}, + 24: {want: 0xf8, have: 0x15d, distance: 0xa, oneway: true}, + 25: {want: 0xff, have: 0x138, distance: 0xa, oneway: true}, + 26: {want: 0x12f, have: 0x138, distance: 0xa, oneway: true}, + 27: {want: 0x13b, have: 0x138, distance: 0xa, oneway: true}, + 28: {want: 0x13f, have: 0x150, distance: 0xa, oneway: true}, + 29: {want: 0x144, have: 0x13d, distance: 0xa, oneway: true}, + 30: {want: 0x157, have: 0x100, distance: 0xa, oneway: true}, + 31: {want: 0x16c, have: 0x365, distance: 0xa, oneway: true}, + 32: {want: 0x16d, have: 0x138, distance: 0xa, oneway: true}, + 33: {want: 0x16e, have: 0x138, distance: 0xa, oneway: true}, + 34: {want: 0x17c, have: 0x138, distance: 0xa, oneway: true}, + 35: {want: 0x18e, have: 0x13d, distance: 0xa, oneway: true}, + 36: {want: 0x192, have: 0x13d, distance: 0xa, oneway: true}, + 37: {want: 0x1a2, have: 0x1bc, distance: 0xa, oneway: true}, + 38: {want: 0x1b2, have: 0x138, distance: 0xa, oneway: true}, + 39: {want: 0x1b6, have: 0x138, distance: 0xa, oneway: true}, + 40: {want: 0x1d2, have: 0x15d, distance: 0xa, oneway: true}, + 41: {want: 0x1d5, have: 0x3e0, distance: 0xa, oneway: true}, + 42: {want: 0x1d7, have: 0x138, distance: 0xa, oneway: true}, + 43: {want: 0x1e5, have: 0x138, distance: 0xa, oneway: true}, + 44: {want: 0x1f6, have: 0x138, distance: 0xa, oneway: true}, + 45: {want: 0x20c, have: 0x1df, distance: 0xa, oneway: true}, + 46: {want: 0x20e, have: 0x138, distance: 0xa, oneway: true}, + 47: {want: 0x22b, have: 0x15d, distance: 0xa, oneway: true}, + 48: {want: 0x240, have: 0x3e0, distance: 0xa, oneway: true}, + 49: {want: 0x248, have: 0x138, distance: 0xa, oneway: true}, + 50: {want: 0x24f, have: 0x138, distance: 0xa, oneway: true}, + 51: {want: 0x263, have: 0x138, distance: 0xa, oneway: true}, + 52: {want: 0x272, have: 0x488, distance: 0xa, oneway: true}, + 53: {want: 0x288, have: 0x3e0, distance: 0xa, oneway: true}, + 54: {want: 0x28c, have: 0x1f7, distance: 0xa, oneway: true}, + 55: {want: 0x2a1, have: 0x138, distance: 0xa, oneway: true}, + 56: {want: 0x2b3, have: 0x15d, distance: 0xa, oneway: true}, + 57: {want: 0x2b6, have: 0x138, distance: 0xa, oneway: true}, + 58: {want: 0x2bc, have: 0x138, distance: 0xa, oneway: true}, + 59: {want: 0x2c1, have: 0x15d, distance: 0xa, oneway: true}, + 60: {want: 0x2eb, have: 0x138, distance: 0xa, oneway: true}, + 61: {want: 0x2ef, have: 0x15d, distance: 0xa, oneway: true}, + 62: {want: 0x2f8, have: 0x138, distance: 0xa, oneway: true}, + 63: {want: 0x2fd, have: 0x7e, distance: 0xa, oneway: true}, + 64: {want: 0x302, have: 0x138, distance: 0xa, oneway: true}, + 65: {want: 0x309, have: 0x3e0, distance: 0xa, oneway: true}, + 66: {want: 0x319, have: 0x1bc, distance: 0xa, oneway: true}, + 67: {want: 0x31d, have: 0x1df, distance: 0xa, oneway: true}, + 68: {want: 0x31e, have: 0x138, distance: 0xa, oneway: true}, + 69: {want: 0x32f, have: 0x138, distance: 0xa, oneway: true}, + 70: {want: 0x34f, have: 0x138, distance: 0xa, oneway: true}, + 71: {want: 0x368, have: 0x345, distance: 0xa, oneway: false}, + 72: {want: 0x368, have: 0x36d, distance: 0xa, oneway: true}, + 73: {want: 0x378, have: 0x138, distance: 0xa, oneway: true}, + 74: {want: 0x385, have: 0x138, distance: 0xa, oneway: true}, + 75: {want: 0x387, have: 0x138, distance: 0xa, oneway: true}, + 76: {want: 0x389, have: 0x15d, distance: 0xa, oneway: true}, + 77: {want: 0x38e, have: 0x138, distance: 0xa, oneway: true}, + 78: {want: 0x393, have: 0x138, distance: 0xa, oneway: true}, + 79: {want: 0x39b, have: 0x138, distance: 0xa, oneway: true}, + 80: {want: 0x3a3, have: 0x138, distance: 0xa, oneway: true}, + 81: {want: 0x3bc, have: 0x138, distance: 0xa, oneway: true}, + 82: {want: 0x3c2, have: 0x13d, distance: 0xa, oneway: true}, + 83: {want: 0x3d2, have: 0x10c, distance: 0xa, oneway: true}, + 84: {want: 0x3d7, have: 0x138, distance: 0xa, oneway: true}, + 85: {want: 0x3e3, have: 0x15d, distance: 0xa, oneway: true}, + 86: {want: 0x3e7, have: 0x1bc, distance: 0xa, oneway: true}, + 87: {want: 0x3f8, have: 0x138, distance: 0xa, oneway: true}, + 88: {want: 0x40a, have: 0x138, distance: 0xa, oneway: true}, + 89: {want: 0x421, have: 0x138, distance: 0xa, oneway: true}, + 90: {want: 0x427, have: 0x138, distance: 0xa, oneway: true}, + 91: {want: 0x42f, have: 0x138, distance: 0xa, oneway: true}, + 92: {want: 0x439, have: 0x138, distance: 0xa, oneway: true}, + 93: {want: 0x43c, have: 0x1df, distance: 0xa, oneway: true}, + 94: {want: 0x443, have: 0x138, distance: 0xa, oneway: true}, + 95: {want: 0x44e, have: 0x138, distance: 0xa, oneway: true}, + 96: {want: 0x45f, have: 0x138, distance: 0xa, oneway: true}, + 97: {want: 0x465, have: 0x3e0, distance: 0xa, oneway: true}, + 98: {want: 0x46d, have: 0x138, distance: 0xa, oneway: true}, + 99: {want: 0x474, have: 0x3e0, distance: 0xa, oneway: true}, + 100: {want: 0x3880, have: 0x138, distance: 0xa, oneway: true}, + 101: {want: 0x47e, have: 0x138, distance: 0xa, oneway: true}, + 102: {want: 0x480, have: 0x138, distance: 0xa, oneway: true}, + 103: {want: 0x492, have: 0x3e0, distance: 0xa, oneway: true}, + 104: {want: 0x49b, have: 0x138, distance: 0xa, oneway: true}, + 105: {want: 0x4aa, have: 0x527, distance: 0xa, oneway: true}, + 106: {want: 0x4b2, have: 0x138, distance: 0xa, oneway: true}, + 107: {want: 0x4ba, have: 0x3e0, distance: 0xa, oneway: true}, + 108: {want: 0x4e3, have: 0x15d, distance: 0xa, oneway: true}, + 109: {want: 0x4f0, have: 0x138, distance: 0xa, oneway: true}, + 110: {want: 0x510, have: 0x138, distance: 0xa, oneway: true}, + 111: {want: 0x516, have: 0x138, distance: 0xa, oneway: true}, + 112: {want: 0x52c, have: 0x138, distance: 0xa, 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: 208 bytes, 26 elements +var matchScript = [26]scriptIntelligibility{ + 0: {wantLang: 0x430, haveLang: 0x430, wantScript: 0x55, haveScript: 0x1e, distance: 0x5}, + 1: {wantLang: 0x430, haveLang: 0x430, wantScript: 0x1e, haveScript: 0x55, distance: 0x5}, + 2: {wantLang: 0x58, haveLang: 0x3e0, wantScript: 0x55, haveScript: 0x1e, distance: 0xa}, + 3: {wantLang: 0xa5, haveLang: 0x138, wantScript: 0xe, haveScript: 0x55, distance: 0xa}, + 4: {wantLang: 0x1d5, haveLang: 0x3e0, wantScript: 0x8, haveScript: 0x1e, distance: 0xa}, + 5: {wantLang: 0x20e, haveLang: 0x138, wantScript: 0x2a, haveScript: 0x55, distance: 0xa}, + 6: {wantLang: 0x248, haveLang: 0x138, wantScript: 0x49, haveScript: 0x55, distance: 0xa}, + 7: {wantLang: 0x24f, haveLang: 0x138, wantScript: 0x4d, haveScript: 0x55, distance: 0xa}, + 8: {wantLang: 0x2b6, haveLang: 0x138, wantScript: 0x52, haveScript: 0x55, distance: 0xa}, + 9: {wantLang: 0x302, haveLang: 0x138, wantScript: 0x69, haveScript: 0x55, distance: 0xa}, + 10: {wantLang: 0x32f, haveLang: 0x138, wantScript: 0x70, haveScript: 0x55, distance: 0xa}, + 11: {wantLang: 0x34f, haveLang: 0x138, wantScript: 0x20, haveScript: 0x55, distance: 0xa}, + 12: {wantLang: 0x393, haveLang: 0x138, wantScript: 0x7a, haveScript: 0x55, distance: 0xa}, + 13: {wantLang: 0x39b, haveLang: 0x138, wantScript: 0x32, haveScript: 0x55, distance: 0xa}, + 14: {wantLang: 0x3bc, haveLang: 0x138, wantScript: 0x5, haveScript: 0x55, distance: 0xa}, + 15: {wantLang: 0x3f8, haveLang: 0x138, wantScript: 0x5, haveScript: 0x55, distance: 0xa}, + 16: {wantLang: 0x40a, haveLang: 0x138, wantScript: 0xc6, haveScript: 0x55, distance: 0xa}, + 17: {wantLang: 0x44e, haveLang: 0x138, wantScript: 0xd3, haveScript: 0x55, distance: 0xa}, + 18: {wantLang: 0x45f, haveLang: 0x138, wantScript: 0xd6, haveScript: 0x55, distance: 0xa}, + 19: {wantLang: 0x46d, haveLang: 0x138, wantScript: 0x28, haveScript: 0x55, distance: 0xa}, + 20: {wantLang: 0x474, haveLang: 0x3e0, wantScript: 0x55, haveScript: 0x1e, distance: 0xa}, + 21: {wantLang: 0x4b2, haveLang: 0x138, wantScript: 0x5, haveScript: 0x55, distance: 0xa}, + 22: {wantLang: 0x4ba, haveLang: 0x3e0, wantScript: 0x55, haveScript: 0x1e, distance: 0xa}, + 23: {wantLang: 0x510, haveLang: 0x138, wantScript: 0x3a, haveScript: 0x55, distance: 0xa}, + 24: {wantLang: 0x527, haveLang: 0x527, wantScript: 0x37, haveScript: 0x38, distance: 0xf}, + 25: {wantLang: 0x527, haveLang: 0x527, wantScript: 0x38, haveScript: 0x37, distance: 0x13}, +} + +// Size: 90 bytes, 15 elements +var matchRegion = [15]regionIntelligibility{ + 0: {lang: 0x3a, script: 0x0, group: 0x4, distance: 0x4}, + 1: {lang: 0x3a, script: 0x0, group: 0x84, distance: 0x4}, + 2: {lang: 0x138, script: 0x0, group: 0x1, distance: 0x4}, + 3: {lang: 0x138, script: 0x0, group: 0x81, distance: 0x4}, + 4: {lang: 0x13d, script: 0x0, group: 0x3, distance: 0x4}, + 5: {lang: 0x13d, script: 0x0, group: 0x83, distance: 0x4}, + 6: {lang: 0x3be, script: 0x0, group: 0x3, distance: 0x4}, + 7: {lang: 0x3be, script: 0x0, group: 0x83, distance: 0x4}, + 8: {lang: 0x527, script: 0x38, group: 0x2, distance: 0x4}, + 9: {lang: 0x527, script: 0x38, group: 0x82, distance: 0x4}, + 10: {lang: 0x3a, script: 0x0, group: 0x80, distance: 0x5}, + 11: {lang: 0x138, script: 0x0, group: 0x80, distance: 0x5}, + 12: {lang: 0x13d, script: 0x0, group: 0x80, distance: 0x5}, + 13: {lang: 0x3be, script: 0x0, group: 0x80, distance: 0x5}, + 14: {lang: 0x527, script: 0x38, group: 0x80, distance: 0x5}, +} + +// Size: 264 bytes, 33 elements +var regionContainment = [33]uint64{ + // Entry 0 - 1F + 0x00000001dfffffff, 0x00000000000007a2, 0x0000000000003044, 0x0000000000000008, + 0x00000000803c0010, 0x0000000000000020, 0x0000000000000040, 0x0000000000000080, + 0x0000000000000100, 0x0000000000000200, 0x0000000000000400, 0x000000004000384c, + 0x0000000000001000, 0x0000000000002000, 0x0000000000004000, 0x0000000000008000, + 0x0000000000010000, 0x0000000000020000, 0x0000000000040000, 0x0000000000080000, + 0x0000000000100000, 0x0000000000200000, 0x0000000001c1c000, 0x0000000000800000, + 0x0000000001000000, 0x000000001e020000, 0x0000000004000000, 0x0000000008000000, + 0x0000000010000000, 0x0000000020000000, 0x0000000040002048, 0x0000000080000000, + // Entry 20 - 3F + 0x0000000100000000, +} + +// 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: 358 bytes, 358 elements +var regionInclusion = [358]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, 0x1e, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x23, + 0x24, 0x26, 0x27, 0x22, 0x28, 0x29, 0x2a, 0x2b, + 0x26, 0x2c, 0x24, 0x23, 0x26, 0x25, 0x2a, 0x2d, + 0x2e, 0x24, 0x2f, 0x2d, 0x26, 0x30, 0x31, 0x28, + // Entry 40 - 7F + 0x26, 0x28, 0x26, 0x25, 0x31, 0x22, 0x32, 0x33, + 0x34, 0x30, 0x22, 0x27, 0x27, 0x27, 0x35, 0x2d, + 0x29, 0x28, 0x27, 0x36, 0x28, 0x22, 0x34, 0x23, + 0x21, 0x26, 0x2d, 0x26, 0x22, 0x37, 0x2e, 0x35, + 0x2a, 0x22, 0x2f, 0x38, 0x26, 0x26, 0x21, 0x39, + 0x39, 0x28, 0x38, 0x39, 0x39, 0x2f, 0x3a, 0x2f, + 0x20, 0x21, 0x38, 0x3b, 0x28, 0x3c, 0x2c, 0x21, + 0x2a, 0x35, 0x27, 0x38, 0x26, 0x24, 0x28, 0x2c, + // Entry 80 - BF + 0x2d, 0x23, 0x30, 0x2d, 0x2d, 0x26, 0x27, 0x3a, + 0x22, 0x34, 0x3c, 0x2d, 0x28, 0x36, 0x22, 0x34, + 0x3a, 0x26, 0x2e, 0x21, 0x39, 0x31, 0x38, 0x24, + 0x2c, 0x25, 0x22, 0x24, 0x25, 0x2c, 0x3a, 0x2c, + 0x26, 0x24, 0x36, 0x21, 0x2f, 0x3d, 0x31, 0x3c, + 0x2f, 0x26, 0x36, 0x36, 0x24, 0x26, 0x3d, 0x31, + 0x24, 0x26, 0x35, 0x25, 0x2d, 0x32, 0x38, 0x2a, + 0x38, 0x39, 0x39, 0x35, 0x33, 0x23, 0x26, 0x2f, + // Entry C0 - FF + 0x3c, 0x21, 0x23, 0x2d, 0x31, 0x36, 0x36, 0x3c, + 0x26, 0x2d, 0x26, 0x3a, 0x2f, 0x25, 0x2f, 0x34, + 0x31, 0x2f, 0x32, 0x3b, 0x2d, 0x2b, 0x2d, 0x21, + 0x34, 0x2a, 0x2c, 0x25, 0x21, 0x3c, 0x24, 0x29, + 0x2b, 0x24, 0x34, 0x21, 0x28, 0x29, 0x3b, 0x31, + 0x25, 0x2e, 0x30, 0x29, 0x26, 0x24, 0x3a, 0x21, + 0x3c, 0x28, 0x21, 0x24, 0x21, 0x21, 0x1f, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + // Entry 100 - 13F + 0x21, 0x21, 0x2f, 0x21, 0x2e, 0x23, 0x33, 0x2f, + 0x24, 0x3b, 0x2f, 0x39, 0x38, 0x31, 0x2d, 0x3a, + 0x2c, 0x2e, 0x2d, 0x23, 0x2d, 0x2f, 0x28, 0x2f, + 0x27, 0x33, 0x34, 0x26, 0x24, 0x32, 0x22, 0x26, + 0x27, 0x22, 0x2d, 0x31, 0x3d, 0x29, 0x31, 0x3d, + 0x39, 0x29, 0x31, 0x24, 0x26, 0x29, 0x36, 0x2f, + 0x33, 0x2f, 0x21, 0x22, 0x21, 0x30, 0x28, 0x3d, + 0x23, 0x26, 0x21, 0x28, 0x26, 0x26, 0x31, 0x3b, + // Entry 140 - 17F + 0x29, 0x21, 0x29, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x24, 0x2f, + 0x23, 0x32, 0x2f, 0x27, 0x2f, 0x21, +} + +// 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: 584 bytes, 73 elements +var regionInclusionBits = [73]uint64{ + // Entry 0 - 1F + 0x0000000102400813, 0x00000000000007a3, 0x0000000000003844, 0x0000000040000808, + 0x00000000803c0011, 0x0000000000000022, 0x0000000040000844, 0x0000000000000082, + 0x0000000000000102, 0x0000000000000202, 0x0000000000000402, 0x000000004000384d, + 0x0000000000001804, 0x0000000040002804, 0x0000000000404000, 0x0000000000408000, + 0x0000000000410000, 0x0000000002020000, 0x0000000000040010, 0x0000000000080010, + 0x0000000000100010, 0x0000000000200010, 0x0000000001c1c001, 0x0000000000c00000, + 0x0000000001400000, 0x000000001e020001, 0x0000000006000000, 0x000000000a000000, + 0x0000000012000000, 0x0000000020000000, 0x0000000040002848, 0x0000000080000010, + // Entry 20 - 3F + 0x0000000100000001, 0x0000000000000001, 0x0000000080000000, 0x0000000000020000, + 0x0000000001000000, 0x0000000000008000, 0x0000000000002000, 0x0000000000000200, + 0x0000000000000008, 0x0000000000200000, 0x0000000110000000, 0x0000000000040000, + 0x0000000008000000, 0x0000000000000020, 0x0000000104000000, 0x0000000000000080, + 0x0000000000001000, 0x0000000000010000, 0x0000000000000400, 0x0000000004000000, + 0x0000000000000040, 0x0000000010000000, 0x0000000000004000, 0x0000000101000000, + 0x0000000108000000, 0x0000000000000100, 0x0000000100020000, 0x0000000000080000, + 0x0000000000100000, 0x0000000000800000, 0x00000001dfffffff, 0x0000000102400fb3, + // Entry 40 - 5F + 0x00000001827c0813, 0x000000014240385f, 0x0000000103c1c813, 0x000000011e420813, + 0x0000000112000001, 0x0000000106000001, 0x0000000101400001, 0x000000010a000001, + 0x0000000102020001, +} + +// regionInclusionNext marks, for each entry in regionInclusionBits, the set of +// all groups that are reachable from the groups set in the respective entry. +// Size: 73 bytes, 73 elements +var regionInclusionNext = [73]uint8{ + // Entry 0 - 3F + 0x3e, 0x3f, 0x0b, 0x0b, 0x40, 0x01, 0x0b, 0x01, + 0x01, 0x01, 0x01, 0x41, 0x0b, 0x0b, 0x16, 0x16, + 0x16, 0x19, 0x04, 0x04, 0x04, 0x04, 0x42, 0x16, + 0x16, 0x43, 0x19, 0x19, 0x19, 0x1d, 0x0b, 0x04, + 0x00, 0x00, 0x1f, 0x11, 0x18, 0x0f, 0x0d, 0x09, + 0x03, 0x15, 0x44, 0x12, 0x1b, 0x05, 0x45, 0x07, + 0x0c, 0x10, 0x0a, 0x1a, 0x06, 0x1c, 0x0e, 0x46, + 0x47, 0x08, 0x48, 0x13, 0x14, 0x17, 0x3e, 0x3e, + // Entry 40 - 7F + 0x3e, 0x3e, 0x3e, 0x3e, 0x43, 0x43, 0x42, 0x43, + 0x43, +} + +type parentRel struct { + lang uint16 + script uint8 + maxScript uint8 + toRegion uint16 + fromRegion []uint16 +} + +// Size: 414 bytes, 5 elements +var parents = [5]parentRel{ + 0: {lang: 0x138, script: 0x0, maxScript: 0x55, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5c, 0x5d, 0x61, 0x64, 0x6d, 0x73, 0x74, 0x75, 0x7b, 0x7c, 0x7f, 0x80, 0x81, 0x83, 0x8c, 0x8d, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9f, 0xa0, 0xa4, 0xa7, 0xa9, 0xad, 0xb1, 0xb4, 0xb5, 0xbf, 0xc6, 0xca, 0xcb, 0xcc, 0xce, 0xd0, 0xd2, 0xd5, 0xd6, 0xdd, 0xdf, 0xe0, 0xe6, 0xe7, 0xe8, 0xeb, 0xf0, 0x107, 0x109, 0x10a, 0x10b, 0x10d, 0x10e, 0x112, 0x117, 0x11b, 0x11d, 0x11f, 0x125, 0x129, 0x12c, 0x12d, 0x12f, 0x131, 0x139, 0x13c, 0x13f, 0x142, 0x161, 0x162, 0x164}}, + 1: {lang: 0x138, script: 0x0, maxScript: 0x55, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x60, 0x63, 0x72, 0xd9, 0x10c, 0x10f}}, + 2: {lang: 0x13d, script: 0x0, maxScript: 0x55, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x56, 0x59, 0x65, 0x69, 0x89, 0x8f, 0xcf, 0xd8, 0xe2, 0xe4, 0xec, 0xf1, 0x11a, 0x135, 0x136, 0x13b}}, + 3: {lang: 0x3be, script: 0x0, maxScript: 0x55, toRegion: 0xee, fromRegion: []uint16{0x2a, 0x4e, 0x5a, 0x86, 0x8b, 0xb7, 0xc6, 0xd1, 0x118, 0x126}}, + 4: {lang: 0x527, script: 0x38, maxScript: 0x38, toRegion: 0x8d, fromRegion: []uint16{0xc6}}, +} + +// Total table size 27175 bytes (26KiB); checksum: 569649CD 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 0000000..de30155 --- /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 +) |