diff options
Diffstat (limited to 'libgo/go/exp')
107 files changed, 31188 insertions, 3377 deletions
diff --git a/libgo/go/exp/html/atom/atom.go b/libgo/go/exp/html/atom/atom.go new file mode 100644 index 0000000..2dbd0fb --- /dev/null +++ b/libgo/go/exp/html/atom/atom.go @@ -0,0 +1,81 @@ +// Copyright 2012 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 atom provides integer codes (also known as atoms) for a fixed set of +// frequently occurring HTML strings: tag names and attribute keys such as "p" +// and "id". +// +// Sharing an atom's name between all elements with the same tag can result in +// fewer string allocations when tokenizing and parsing HTML. Integer +// comparisons are also generally faster than string comparisons. +// +// The value of an atom's particular code is not guaranteed to stay the same +// between versions of this package. Neither is any ordering guaranteed: +// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to +// be dense. The only guarantees are that e.g. looking up "div" will yield +// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0. +// +// TODO(rsc): When this package moves out of exp we need to freeze atom values +// across releases. +package atom + +// Atom is an integer code for a string. The zero value maps to "". +type Atom uint32 + +// String returns the atom's name. +func (a Atom) String() string { + start := uint32(a >> 8) + n := uint32(a & 0xff) + if start+n > uint32(len(atomText)) { + return "" + } + return atomText[start : start+n] +} + +func (a Atom) string() string { + return atomText[a>>8 : a>>8+a&0xff] +} + +// fnv computes the FNV hash with an arbitrary starting value h. +func fnv(h uint32, s []byte) uint32 { + for i := range s { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +func match(s string, t []byte) bool { + for i, c := range t { + if s[i] != c { + return false + } + } + return true +} + +// Lookup returns the atom whose name is s. It returns zero if there is no +// such atom. The lookup is case sensitive. +func Lookup(s []byte) Atom { + if len(s) == 0 || len(s) > maxAtomLen { + return 0 + } + h := fnv(hash0, s) + if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { + return a + } + if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { + return a + } + return 0 +} + +// String returns a string whose contents are equal to s. In that sense, it is +// equivalent to string(s) but may be more efficient. +func String(s []byte) string { + if a := Lookup(s); a != 0 { + return a.String() + } + return string(s) +} diff --git a/libgo/go/exp/html/atom/atom_test.go b/libgo/go/exp/html/atom/atom_test.go new file mode 100644 index 0000000..6e33704 --- /dev/null +++ b/libgo/go/exp/html/atom/atom_test.go @@ -0,0 +1,109 @@ +// Copyright 2012 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 atom + +import ( + "sort" + "testing" +) + +func TestKnown(t *testing.T) { + for _, s := range testAtomList { + if atom := Lookup([]byte(s)); atom.String() != s { + t.Errorf("Lookup(%q) = %#x (%q)", s, uint32(atom), atom.String()) + } + } +} + +func TestHits(t *testing.T) { + for _, a := range table { + if a == 0 { + continue + } + got := Lookup([]byte(a.String())) + if got != a { + t.Errorf("Lookup(%q) = %#x, want %#x", a.String(), uint32(got), uint32(a)) + } + } +} + +func TestMisses(t *testing.T) { + testCases := []string{ + "", + "\x00", + "\xff", + "A", + "DIV", + "Div", + "dIV", + "aa", + "a\x00", + "ab", + "abb", + "abbr0", + "abbr ", + " abbr", + " a", + "acceptcharset", + "acceptCharset", + "accept_charset", + "h0", + "h1h2", + "h7", + "onClick", + "λ", + // The following string has the same hash (0xa1d7fab7) as "onmouseover". + "\x00\x00\x00\x00\x00\x50\x18\xae\x38\xd0\xb7", + } + for _, tc := range testCases { + got := Lookup([]byte(tc)) + if got != 0 { + t.Errorf("Lookup(%q): got %d, want 0", tc, got) + } + } +} + +func TestForeignObject(t *testing.T) { + const ( + afo = Foreignobject + afO = ForeignObject + sfo = "foreignobject" + sfO = "foreignObject" + ) + if got := Lookup([]byte(sfo)); got != afo { + t.Errorf("Lookup(%q): got %#v, want %#v", sfo, got, afo) + } + if got := Lookup([]byte(sfO)); got != afO { + t.Errorf("Lookup(%q): got %#v, want %#v", sfO, got, afO) + } + if got := afo.String(); got != sfo { + t.Errorf("Atom(%#v).String(): got %q, want %q", afo, got, sfo) + } + if got := afO.String(); got != sfO { + t.Errorf("Atom(%#v).String(): got %q, want %q", afO, got, sfO) + } +} + +func BenchmarkLookup(b *testing.B) { + sortedTable := make([]string, 0, len(table)) + for _, a := range table { + if a != 0 { + sortedTable = append(sortedTable, a.String()) + } + } + sort.Strings(sortedTable) + + x := make([][]byte, 1000) + for i := range x { + x[i] = []byte(sortedTable[i%len(sortedTable)]) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, s := range x { + Lookup(s) + } + } +} diff --git a/libgo/go/exp/html/atom/gen.go b/libgo/go/exp/html/atom/gen.go new file mode 100644 index 0000000..9958a71 --- /dev/null +++ b/libgo/go/exp/html/atom/gen.go @@ -0,0 +1,636 @@ +// Copyright 2012 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 program generates table.go and table_test.go. +// Invoke as +// +// go run gen.go |gofmt >table.go +// go run gen.go -test |gofmt >table_test.go + +import ( + "flag" + "fmt" + "math/rand" + "os" + "sort" + "strings" +) + +// identifier converts s to a Go exported identifier. +// It converts "div" to "Div" and "accept-charset" to "AcceptCharset". +func identifier(s string) string { + b := make([]byte, 0, len(s)) + cap := true + for _, c := range s { + if c == '-' { + cap = true + continue + } + if cap && 'a' <= c && c <= 'z' { + c -= 'a' - 'A' + } + cap = false + b = append(b, byte(c)) + } + return string(b) +} + +var test = flag.Bool("test", false, "generate table_test.go") + +func main() { + flag.Parse() + + var all []string + all = append(all, elements...) + all = append(all, attributes...) + all = append(all, eventHandlers...) + all = append(all, extra...) + sort.Strings(all) + + if *test { + fmt.Printf("// generated by go run gen.go -test; DO NOT EDIT\n\n") + fmt.Printf("package atom\n\n") + fmt.Printf("var testAtomList = []string{\n") + for _, s := range all { + fmt.Printf("\t%q,\n", s) + } + fmt.Printf("}\n") + return + } + + // uniq - lists have dups + // compute max len too + maxLen := 0 + w := 0 + for _, s := range all { + if w == 0 || all[w-1] != s { + if maxLen < len(s) { + maxLen = len(s) + } + all[w] = s + w++ + } + } + all = all[:w] + + // Find hash that minimizes table size. + var best *table + for i := 0; i < 1000000; i++ { + if best != nil && 1<<(best.k-1) < len(all) { + break + } + h := rand.Uint32() + for k := uint(0); k <= 16; k++ { + if best != nil && k >= best.k { + break + } + var t table + if t.init(h, k, all) { + best = &t + break + } + } + } + if best == nil { + fmt.Fprintf(os.Stderr, "failed to construct string table\n") + os.Exit(1) + } + + // Lay out strings, using overlaps when possible. + layout := append([]string{}, all...) + + // Remove strings that are substrings of other strings + for changed := true; changed; { + changed = false + for i, s := range layout { + if s == "" { + continue + } + for j, t := range layout { + if i != j && t != "" && strings.Contains(s, t) { + changed = true + layout[j] = "" + } + } + } + } + + // Join strings where one suffix matches another prefix. + for { + // Find best i, j, k such that layout[i][len-k:] == layout[j][:k], + // maximizing overlap length k. + besti := -1 + bestj := -1 + bestk := 0 + for i, s := range layout { + if s == "" { + continue + } + for j, t := range layout { + if i == j { + continue + } + for k := bestk + 1; k <= len(s) && k <= len(t); k++ { + if s[len(s)-k:] == t[:k] { + besti = i + bestj = j + bestk = k + } + } + } + } + if bestk > 0 { + layout[besti] += layout[bestj][bestk:] + layout[bestj] = "" + continue + } + break + } + + text := strings.Join(layout, "") + + atom := map[string]uint32{} + for _, s := range all { + off := strings.Index(text, s) + if off < 0 { + panic("lost string " + s) + } + atom[s] = uint32(off<<8 | len(s)) + } + + // Generate the Go code. + fmt.Printf("// generated by go run gen.go; DO NOT EDIT\n\n") + fmt.Printf("package atom\n\nconst (\n") + for _, s := range all { + fmt.Printf("\t%s Atom = %#x\n", identifier(s), atom[s]) + } + fmt.Printf(")\n\n") + + fmt.Printf("const hash0 = %#x\n\n", best.h0) + fmt.Printf("const maxAtomLen = %d\n\n", maxLen) + + fmt.Printf("var table = [1<<%d]Atom{\n", best.k) + for i, s := range best.tab { + if s == "" { + continue + } + fmt.Printf("\t%#x: %#x, // %s\n", i, atom[s], s) + } + fmt.Printf("}\n") + datasize := (1 << best.k) * 4 + + fmt.Printf("const atomText =\n") + textsize := len(text) + for len(text) > 60 { + fmt.Printf("\t%q +\n", text[:60]) + text = text[60:] + } + fmt.Printf("\t%q\n\n", text) + + fmt.Fprintf(os.Stderr, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize) +} + +type byLen []string + +func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) } +func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byLen) Len() int { return len(x) } + +// fnv computes the FNV hash with an arbitrary starting value h. +func fnv(h uint32, s string) uint32 { + for i := 0; i < len(s); i++ { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +// A table represents an attempt at constructing the lookup table. +// The lookup table uses cuckoo hashing, meaning that each string +// can be found in one of two positions. +type table struct { + h0 uint32 + k uint + mask uint32 + tab []string +} + +// hash returns the two hashes for s. +func (t *table) hash(s string) (h1, h2 uint32) { + h := fnv(t.h0, s) + h1 = h & t.mask + h2 = (h >> 16) & t.mask + return +} + +// init initializes the table with the given parameters. +// h0 is the initial hash value, +// k is the number of bits of hash value to use, and +// x is the list of strings to store in the table. +// init returns false if the table cannot be constructed. +func (t *table) init(h0 uint32, k uint, x []string) bool { + t.h0 = h0 + t.k = k + t.tab = make([]string, 1<<k) + t.mask = 1<<k - 1 + for _, s := range x { + if !t.insert(s) { + return false + } + } + return true +} + +// insert inserts s in the table. +func (t *table) insert(s string) bool { + h1, h2 := t.hash(s) + if t.tab[h1] == "" { + t.tab[h1] = s + return true + } + if t.tab[h2] == "" { + t.tab[h2] = s + return true + } + if t.push(h1, 0) { + t.tab[h1] = s + return true + } + if t.push(h2, 0) { + t.tab[h2] = s + return true + } + return false +} + +// push attempts to push aside the entry in slot i. +func (t *table) push(i uint32, depth int) bool { + if depth > len(t.tab) { + return false + } + s := t.tab[i] + h1, h2 := t.hash(s) + j := h1 + h2 - i + if t.tab[j] != "" && !t.push(j, depth+1) { + return false + } + t.tab[j] = s + return true +} + +// The lists of element names and attribute keys were taken from +// http://www.whatwg.org/specs/web-apps/current-work/multipage/section-index.html +// as of the "HTML Living Standard - Last Updated 30 May 2012" version. + +var elements = []string{ + "a", + "abbr", + "address", + "area", + "article", + "aside", + "audio", + "b", + "base", + "bdi", + "bdo", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "cite", + "code", + "col", + "colgroup", + "command", + "data", + "datalist", + "dd", + "del", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "i", + "iframe", + "img", + "input", + "ins", + "kbd", + "keygen", + "label", + "legend", + "li", + "link", + "map", + "mark", + "menu", + "meta", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "param", + "pre", + "progress", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "small", + "source", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "track", + "u", + "ul", + "var", + "video", + "wbr", +} + +var attributes = []string{ + "accept", + "accept-charset", + "accesskey", + "action", + "alt", + "async", + "autocomplete", + "autofocus", + "autoplay", + "border", + "challenge", + "charset", + "checked", + "cite", + "class", + "cols", + "colspan", + "command", + "content", + "contenteditable", + "contextmenu", + "controls", + "coords", + "crossorigin", + "data", + "datetime", + "default", + "defer", + "dir", + "dirname", + "disabled", + "download", + "draggable", + "dropzone", + "enctype", + "for", + "form", + "formaction", + "formenctype", + "formmethod", + "formnovalidate", + "formtarget", + "headers", + "height", + "hidden", + "high", + "href", + "hreflang", + "http-equiv", + "icon", + "id", + "inert", + "ismap", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "keytype", + "kind", + "label", + "lang", + "list", + "loop", + "low", + "manifest", + "max", + "maxlength", + "media", + "mediagroup", + "method", + "min", + "multiple", + "muted", + "name", + "novalidate", + "open", + "optimum", + "pattern", + "ping", + "placeholder", + "poster", + "preload", + "radiogroup", + "readonly", + "rel", + "required", + "reversed", + "rows", + "rowspan", + "sandbox", + "spellcheck", + "scope", + "scoped", + "seamless", + "selected", + "shape", + "size", + "sizes", + "span", + "src", + "srcdoc", + "srclang", + "start", + "step", + "style", + "tabindex", + "target", + "title", + "translate", + "type", + "typemustmatch", + "usemap", + "value", + "width", + "wrap", +} + +var eventHandlers = []string{ + "onabort", + "onafterprint", + "onbeforeprint", + "onbeforeunload", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onhashchange", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmessage", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onoffline", + "ononline", + "onpagehide", + "onpageshow", + "onpause", + "onplay", + "onplaying", + "onpopstate", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onstalled", + "onstorage", + "onsubmit", + "onsuspend", + "ontimeupdate", + "onunload", + "onvolumechange", + "onwaiting", +} + +// extra are ad-hoc values not covered by any of the lists above. +var extra = []string{ + "align", + "annotation", + "annotation-xml", + "applet", + "basefont", + "bgsound", + "big", + "blink", + "center", + "color", + "desc", + "face", + "font", + "foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive. + "foreignobject", + "frame", + "frameset", + "image", + "isindex", + "listing", + "malignmark", + "marquee", + "math", + "mglyph", + "mi", + "mn", + "mo", + "ms", + "mtext", + "nobr", + "noembed", + "noframes", + "plaintext", + "prompt", + "public", + "spacer", + "strike", + "svg", + "system", + "tt", + "xmp", +} diff --git a/libgo/go/exp/html/atom/table.go b/libgo/go/exp/html/atom/table.go new file mode 100644 index 0000000..20b8b8a --- /dev/null +++ b/libgo/go/exp/html/atom/table.go @@ -0,0 +1,694 @@ +// generated by go run gen.go; DO NOT EDIT + +package atom + +const ( + A Atom = 0x1 + Abbr Atom = 0x4 + Accept Atom = 0x2106 + AcceptCharset Atom = 0x210e + Accesskey Atom = 0x3309 + Action Atom = 0x21b06 + Address Atom = 0x5d507 + Align Atom = 0x1105 + Alt Atom = 0x4503 + Annotation Atom = 0x18d0a + AnnotationXml Atom = 0x18d0e + Applet Atom = 0x2d106 + Area Atom = 0x31804 + Article Atom = 0x39907 + Aside Atom = 0x4f05 + Async Atom = 0x9305 + Audio Atom = 0xaf05 + Autocomplete Atom = 0xd50c + Autofocus Atom = 0xe109 + Autoplay Atom = 0x10c08 + B Atom = 0x101 + Base Atom = 0x11404 + Basefont Atom = 0x11408 + Bdi Atom = 0x1a03 + Bdo Atom = 0x12503 + Bgsound Atom = 0x13807 + Big Atom = 0x14403 + Blink Atom = 0x14705 + Blockquote Atom = 0x14c0a + Body Atom = 0x2f04 + Border Atom = 0x15606 + Br Atom = 0x202 + Button Atom = 0x15c06 + Canvas Atom = 0x4b06 + Caption Atom = 0x1e007 + Center Atom = 0x2df06 + Challenge Atom = 0x23e09 + Charset Atom = 0x2807 + Checked Atom = 0x33f07 + Cite Atom = 0x9704 + Class Atom = 0x3d905 + Code Atom = 0x16f04 + Col Atom = 0x17603 + Colgroup Atom = 0x17608 + Color Atom = 0x18305 + Cols Atom = 0x18804 + Colspan Atom = 0x18807 + Command Atom = 0x19b07 + Content Atom = 0x42c07 + Contenteditable Atom = 0x42c0f + Contextmenu Atom = 0x3480b + Controls Atom = 0x1ae08 + Coords Atom = 0x1ba06 + Crossorigin Atom = 0x1c40b + Data Atom = 0x44304 + Datalist Atom = 0x44308 + Datetime Atom = 0x25b08 + Dd Atom = 0x28802 + Default Atom = 0x5207 + Defer Atom = 0x17105 + Del Atom = 0x4d603 + Desc Atom = 0x4804 + Details Atom = 0x6507 + Dfn Atom = 0x8303 + Dialog Atom = 0x1b06 + Dir Atom = 0x9d03 + Dirname Atom = 0x9d07 + Disabled Atom = 0x10008 + Div Atom = 0x10703 + Dl Atom = 0x13e02 + Download Atom = 0x40908 + Draggable Atom = 0x1a109 + Dropzone Atom = 0x3a208 + Dt Atom = 0x4e402 + Em Atom = 0x7f02 + Embed Atom = 0x7f05 + Enctype Atom = 0x23007 + Face Atom = 0x2dd04 + Fieldset Atom = 0x1d508 + Figcaption Atom = 0x1dd0a + Figure Atom = 0x1f106 + Font Atom = 0x11804 + Footer Atom = 0x5906 + For Atom = 0x1fd03 + ForeignObject Atom = 0x1fd0d + Foreignobject Atom = 0x20a0d + Form Atom = 0x21704 + Formaction Atom = 0x2170a + Formenctype Atom = 0x22c0b + Formmethod Atom = 0x2470a + Formnovalidate Atom = 0x2510e + Formtarget Atom = 0x2660a + Frame Atom = 0x8705 + Frameset Atom = 0x8708 + H1 Atom = 0x13602 + H2 Atom = 0x29602 + H3 Atom = 0x2c502 + H4 Atom = 0x30e02 + H5 Atom = 0x4e602 + H6 Atom = 0x27002 + Head Atom = 0x2fa04 + Header Atom = 0x2fa06 + Headers Atom = 0x2fa07 + Height Atom = 0x27206 + Hgroup Atom = 0x27a06 + Hidden Atom = 0x28606 + High Atom = 0x29304 + Hr Atom = 0x13102 + Href Atom = 0x29804 + Hreflang Atom = 0x29808 + Html Atom = 0x27604 + HttpEquiv Atom = 0x2a00a + I Atom = 0x601 + Icon Atom = 0x42b04 + Id Atom = 0x5102 + Iframe Atom = 0x2b406 + Image Atom = 0x2ba05 + Img Atom = 0x2bf03 + Inert Atom = 0x4c105 + Input Atom = 0x3f605 + Ins Atom = 0x1cd03 + Isindex Atom = 0x2c707 + Ismap Atom = 0x2ce05 + Itemid Atom = 0x9806 + Itemprop Atom = 0x57e08 + Itemref Atom = 0x2d707 + Itemscope Atom = 0x2e509 + Itemtype Atom = 0x2ef08 + Kbd Atom = 0x1903 + Keygen Atom = 0x3906 + Keytype Atom = 0x51207 + Kind Atom = 0xfd04 + Label Atom = 0xba05 + Lang Atom = 0x29c04 + Legend Atom = 0x1a806 + Li Atom = 0x1202 + Link Atom = 0x14804 + List Atom = 0x44704 + Listing Atom = 0x44707 + Loop Atom = 0xbe04 + Low Atom = 0x13f03 + Malignmark Atom = 0x100a + Manifest Atom = 0x5b608 + Map Atom = 0x2d003 + Mark Atom = 0x1604 + Marquee Atom = 0x5f207 + Math Atom = 0x2f704 + Max Atom = 0x30603 + Maxlength Atom = 0x30609 + Media Atom = 0xa205 + Mediagroup Atom = 0xa20a + Menu Atom = 0x34f04 + Meta Atom = 0x45604 + Meter Atom = 0x26105 + Method Atom = 0x24b06 + Mglyph Atom = 0x2c006 + Mi Atom = 0x9b02 + Min Atom = 0x31003 + Mn Atom = 0x25402 + Mo Atom = 0x47a02 + Ms Atom = 0x2e802 + Mtext Atom = 0x31305 + Multiple Atom = 0x32108 + Muted Atom = 0x32905 + Name Atom = 0xa004 + Nav Atom = 0x3e03 + Nobr Atom = 0x7404 + Noembed Atom = 0x7d07 + Noframes Atom = 0x8508 + Noscript Atom = 0x28b08 + Novalidate Atom = 0x2550a + Object Atom = 0x21106 + Ol Atom = 0xcd02 + Onabort Atom = 0x16007 + Onafterprint Atom = 0x1e50c + Onbeforeprint Atom = 0x21f0d + Onbeforeunload Atom = 0x5c90e + Onblur Atom = 0x3e206 + Oncancel Atom = 0xb308 + Oncanplay Atom = 0x12709 + Oncanplaythrough Atom = 0x12710 + Onchange Atom = 0x3b808 + Onclick Atom = 0x2ad07 + Onclose Atom = 0x32e07 + Oncontextmenu Atom = 0x3460d + Oncuechange Atom = 0x3530b + Ondblclick Atom = 0x35e0a + Ondrag Atom = 0x36806 + Ondragend Atom = 0x36809 + Ondragenter Atom = 0x3710b + Ondragleave Atom = 0x37c0b + Ondragover Atom = 0x3870a + Ondragstart Atom = 0x3910b + Ondrop Atom = 0x3a006 + Ondurationchange Atom = 0x3b010 + Onemptied Atom = 0x3a709 + Onended Atom = 0x3c007 + Onerror Atom = 0x3c707 + Onfocus Atom = 0x3ce07 + Onhashchange Atom = 0x3e80c + Oninput Atom = 0x3f407 + Oninvalid Atom = 0x3fb09 + Onkeydown Atom = 0x40409 + Onkeypress Atom = 0x4110a + Onkeyup Atom = 0x42107 + Onload Atom = 0x43b06 + Onloadeddata Atom = 0x43b0c + Onloadedmetadata Atom = 0x44e10 + Onloadstart Atom = 0x4640b + Onmessage Atom = 0x46f09 + Onmousedown Atom = 0x4780b + Onmousemove Atom = 0x4830b + Onmouseout Atom = 0x48e0a + Onmouseover Atom = 0x49b0b + Onmouseup Atom = 0x4a609 + Onmousewheel Atom = 0x4af0c + Onoffline Atom = 0x4bb09 + Ononline Atom = 0x4c608 + Onpagehide Atom = 0x4ce0a + Onpageshow Atom = 0x4d90a + Onpause Atom = 0x4e807 + Onplay Atom = 0x4f206 + Onplaying Atom = 0x4f209 + Onpopstate Atom = 0x4fb0a + Onprogress Atom = 0x5050a + Onratechange Atom = 0x5190c + Onreset Atom = 0x52507 + Onresize Atom = 0x52c08 + Onscroll Atom = 0x53a08 + Onseeked Atom = 0x54208 + Onseeking Atom = 0x54a09 + Onselect Atom = 0x55308 + Onshow Atom = 0x55d06 + Onstalled Atom = 0x56609 + Onstorage Atom = 0x56f09 + Onsubmit Atom = 0x57808 + Onsuspend Atom = 0x58809 + Ontimeupdate Atom = 0x1190c + Onunload Atom = 0x59108 + Onvolumechange Atom = 0x5990e + Onwaiting Atom = 0x5a709 + Open Atom = 0x58404 + Optgroup Atom = 0xc008 + Optimum Atom = 0x5b007 + Option Atom = 0x5c506 + Output Atom = 0x49506 + P Atom = 0xc01 + Param Atom = 0xc05 + Pattern Atom = 0x6e07 + Ping Atom = 0xab04 + Placeholder Atom = 0xc70b + Plaintext Atom = 0xf109 + Poster Atom = 0x17d06 + Pre Atom = 0x27f03 + Preload Atom = 0x27f07 + Progress Atom = 0x50708 + Prompt Atom = 0x5bf06 + Public Atom = 0x42706 + Q Atom = 0x15101 + Radiogroup Atom = 0x30a + Readonly Atom = 0x31908 + Rel Atom = 0x28003 + Required Atom = 0x1f508 + Reversed Atom = 0x5e08 + Rows Atom = 0x7704 + Rowspan Atom = 0x7707 + Rp Atom = 0x1eb02 + Rt Atom = 0x16502 + Ruby Atom = 0xd104 + S Atom = 0x2c01 + Samp Atom = 0x6b04 + Sandbox Atom = 0xe907 + Scope Atom = 0x2e905 + Scoped Atom = 0x2e906 + Script Atom = 0x28d06 + Seamless Atom = 0x33308 + Section Atom = 0x3dd07 + Select Atom = 0x55506 + Selected Atom = 0x55508 + Shape Atom = 0x1b505 + Size Atom = 0x53004 + Sizes Atom = 0x53005 + Small Atom = 0x1bf05 + Source Atom = 0x1cf06 + Spacer Atom = 0x30006 + Span Atom = 0x7a04 + Spellcheck Atom = 0x33a0a + Src Atom = 0x3d403 + Srcdoc Atom = 0x3d406 + Srclang Atom = 0x41a07 + Start Atom = 0x39705 + Step Atom = 0x5bc04 + Strike Atom = 0x50e06 + Strong Atom = 0x53406 + Style Atom = 0x5db05 + Sub Atom = 0x57a03 + Summary Atom = 0x5e007 + Sup Atom = 0x5e703 + Svg Atom = 0x5ea03 + System Atom = 0x5ed06 + Tabindex Atom = 0x45c08 + Table Atom = 0x43605 + Target Atom = 0x26a06 + Tbody Atom = 0x2e05 + Td Atom = 0x4702 + Textarea Atom = 0x31408 + Tfoot Atom = 0x5805 + Th Atom = 0x13002 + Thead Atom = 0x2f905 + Time Atom = 0x11b04 + Title Atom = 0x8e05 + Tr Atom = 0xf902 + Track Atom = 0xf905 + Translate Atom = 0x16609 + Tt Atom = 0x7002 + Type Atom = 0x23304 + Typemustmatch Atom = 0x2330d + U Atom = 0xb01 + Ul Atom = 0x5602 + Usemap Atom = 0x4ec06 + Value Atom = 0x4005 + Var Atom = 0x10903 + Video Atom = 0x2a905 + Wbr Atom = 0x14103 + Width Atom = 0x4e205 + Wrap Atom = 0x56204 + Xmp Atom = 0xef03 +) + +const hash0 = 0xc17da63e + +const maxAtomLen = 16 + +var table = [1 << 9]Atom{ + 0x1: 0x4830b, // onmousemove + 0x2: 0x5a709, // onwaiting + 0x4: 0x5bf06, // prompt + 0x7: 0x5b007, // optimum + 0x8: 0x1604, // mark + 0xa: 0x2d707, // itemref + 0xb: 0x4d90a, // onpageshow + 0xc: 0x55506, // select + 0xd: 0x1a109, // draggable + 0xe: 0x3e03, // nav + 0xf: 0x19b07, // command + 0x11: 0xb01, // u + 0x14: 0x2fa07, // headers + 0x15: 0x44308, // datalist + 0x17: 0x6b04, // samp + 0x1a: 0x40409, // onkeydown + 0x1b: 0x53a08, // onscroll + 0x1c: 0x17603, // col + 0x20: 0x57e08, // itemprop + 0x21: 0x2a00a, // http-equiv + 0x22: 0x5e703, // sup + 0x24: 0x1f508, // required + 0x2b: 0x27f07, // preload + 0x2c: 0x21f0d, // onbeforeprint + 0x2d: 0x3710b, // ondragenter + 0x2e: 0x4e402, // dt + 0x2f: 0x57808, // onsubmit + 0x30: 0x13102, // hr + 0x31: 0x3460d, // oncontextmenu + 0x33: 0x2ba05, // image + 0x34: 0x4e807, // onpause + 0x35: 0x27a06, // hgroup + 0x36: 0xab04, // ping + 0x37: 0x55308, // onselect + 0x3a: 0x10703, // div + 0x40: 0x9b02, // mi + 0x41: 0x33308, // seamless + 0x42: 0x2807, // charset + 0x43: 0x5102, // id + 0x44: 0x4fb0a, // onpopstate + 0x45: 0x4d603, // del + 0x46: 0x5f207, // marquee + 0x47: 0x3309, // accesskey + 0x49: 0x5906, // footer + 0x4a: 0x2d106, // applet + 0x4b: 0x2ce05, // ismap + 0x51: 0x34f04, // menu + 0x52: 0x2f04, // body + 0x55: 0x8708, // frameset + 0x56: 0x52507, // onreset + 0x57: 0x14705, // blink + 0x58: 0x8e05, // title + 0x59: 0x39907, // article + 0x5b: 0x13002, // th + 0x5d: 0x15101, // q + 0x5e: 0x58404, // open + 0x5f: 0x31804, // area + 0x61: 0x43b06, // onload + 0x62: 0x3f605, // input + 0x63: 0x11404, // base + 0x64: 0x18807, // colspan + 0x65: 0x51207, // keytype + 0x66: 0x13e02, // dl + 0x68: 0x1d508, // fieldset + 0x6a: 0x31003, // min + 0x6b: 0x10903, // var + 0x6f: 0x2fa06, // header + 0x70: 0x16502, // rt + 0x71: 0x17608, // colgroup + 0x72: 0x25402, // mn + 0x74: 0x16007, // onabort + 0x75: 0x3906, // keygen + 0x76: 0x4bb09, // onoffline + 0x77: 0x23e09, // challenge + 0x78: 0x2d003, // map + 0x7a: 0x30e02, // h4 + 0x7b: 0x3c707, // onerror + 0x7c: 0x30609, // maxlength + 0x7d: 0x31305, // mtext + 0x7e: 0x5805, // tfoot + 0x7f: 0x11804, // font + 0x80: 0x100a, // malignmark + 0x81: 0x45604, // meta + 0x82: 0x9305, // async + 0x83: 0x2c502, // h3 + 0x84: 0x28802, // dd + 0x85: 0x29804, // href + 0x86: 0xa20a, // mediagroup + 0x87: 0x1ba06, // coords + 0x88: 0x41a07, // srclang + 0x89: 0x35e0a, // ondblclick + 0x8a: 0x4005, // value + 0x8c: 0xb308, // oncancel + 0x8e: 0x33a0a, // spellcheck + 0x8f: 0x8705, // frame + 0x91: 0x14403, // big + 0x94: 0x21b06, // action + 0x95: 0x9d03, // dir + 0x97: 0x31908, // readonly + 0x99: 0x43605, // table + 0x9a: 0x5e007, // summary + 0x9b: 0x14103, // wbr + 0x9c: 0x30a, // radiogroup + 0x9d: 0xa004, // name + 0x9f: 0x5ed06, // system + 0xa1: 0x18305, // color + 0xa2: 0x4b06, // canvas + 0xa3: 0x27604, // html + 0xa5: 0x54a09, // onseeking + 0xac: 0x1b505, // shape + 0xad: 0x28003, // rel + 0xae: 0x12710, // oncanplaythrough + 0xaf: 0x3870a, // ondragover + 0xb1: 0x1fd0d, // foreignObject + 0xb3: 0x7704, // rows + 0xb6: 0x44707, // listing + 0xb7: 0x49506, // output + 0xb9: 0x3480b, // contextmenu + 0xbb: 0x13f03, // low + 0xbc: 0x1eb02, // rp + 0xbd: 0x58809, // onsuspend + 0xbe: 0x15c06, // button + 0xbf: 0x4804, // desc + 0xc1: 0x3dd07, // section + 0xc2: 0x5050a, // onprogress + 0xc3: 0x56f09, // onstorage + 0xc4: 0x2f704, // math + 0xc5: 0x4f206, // onplay + 0xc7: 0x5602, // ul + 0xc8: 0x6e07, // pattern + 0xc9: 0x4af0c, // onmousewheel + 0xca: 0x36809, // ondragend + 0xcb: 0xd104, // ruby + 0xcc: 0xc01, // p + 0xcd: 0x32e07, // onclose + 0xce: 0x26105, // meter + 0xcf: 0x13807, // bgsound + 0xd2: 0x27206, // height + 0xd4: 0x101, // b + 0xd5: 0x2ef08, // itemtype + 0xd8: 0x1e007, // caption + 0xd9: 0x10008, // disabled + 0xdc: 0x5ea03, // svg + 0xdd: 0x1bf05, // small + 0xde: 0x44304, // data + 0xe0: 0x4c608, // ononline + 0xe1: 0x2c006, // mglyph + 0xe3: 0x7f05, // embed + 0xe4: 0xf902, // tr + 0xe5: 0x4640b, // onloadstart + 0xe7: 0x3b010, // ondurationchange + 0xed: 0x12503, // bdo + 0xee: 0x4702, // td + 0xef: 0x4f05, // aside + 0xf0: 0x29602, // h2 + 0xf1: 0x50708, // progress + 0xf2: 0x14c0a, // blockquote + 0xf4: 0xba05, // label + 0xf5: 0x601, // i + 0xf7: 0x7707, // rowspan + 0xfb: 0x4f209, // onplaying + 0xfd: 0x2bf03, // img + 0xfe: 0xc008, // optgroup + 0xff: 0x42c07, // content + 0x101: 0x5190c, // onratechange + 0x103: 0x3e80c, // onhashchange + 0x104: 0x6507, // details + 0x106: 0x40908, // download + 0x109: 0xe907, // sandbox + 0x10b: 0x42c0f, // contenteditable + 0x10d: 0x37c0b, // ondragleave + 0x10e: 0x2106, // accept + 0x10f: 0x55508, // selected + 0x112: 0x2170a, // formaction + 0x113: 0x2df06, // center + 0x115: 0x44e10, // onloadedmetadata + 0x116: 0x14804, // link + 0x117: 0x11b04, // time + 0x118: 0x1c40b, // crossorigin + 0x119: 0x3ce07, // onfocus + 0x11a: 0x56204, // wrap + 0x11b: 0x42b04, // icon + 0x11d: 0x2a905, // video + 0x11e: 0x3d905, // class + 0x121: 0x5990e, // onvolumechange + 0x122: 0x3e206, // onblur + 0x123: 0x2e509, // itemscope + 0x124: 0x5db05, // style + 0x127: 0x42706, // public + 0x129: 0x2510e, // formnovalidate + 0x12a: 0x55d06, // onshow + 0x12c: 0x16609, // translate + 0x12d: 0x9704, // cite + 0x12e: 0x2e802, // ms + 0x12f: 0x1190c, // ontimeupdate + 0x130: 0xfd04, // kind + 0x131: 0x2660a, // formtarget + 0x135: 0x3c007, // onended + 0x136: 0x28606, // hidden + 0x137: 0x2c01, // s + 0x139: 0x2470a, // formmethod + 0x13a: 0x44704, // list + 0x13c: 0x27002, // h6 + 0x13d: 0xcd02, // ol + 0x13e: 0x3530b, // oncuechange + 0x13f: 0x20a0d, // foreignobject + 0x143: 0x5c90e, // onbeforeunload + 0x145: 0x3a709, // onemptied + 0x146: 0x17105, // defer + 0x147: 0xef03, // xmp + 0x148: 0xaf05, // audio + 0x149: 0x1903, // kbd + 0x14c: 0x46f09, // onmessage + 0x14d: 0x5c506, // option + 0x14e: 0x4503, // alt + 0x14f: 0x33f07, // checked + 0x150: 0x10c08, // autoplay + 0x152: 0x202, // br + 0x153: 0x2550a, // novalidate + 0x156: 0x7d07, // noembed + 0x159: 0x2ad07, // onclick + 0x15a: 0x4780b, // onmousedown + 0x15b: 0x3b808, // onchange + 0x15e: 0x3fb09, // oninvalid + 0x15f: 0x2e906, // scoped + 0x160: 0x1ae08, // controls + 0x161: 0x32905, // muted + 0x163: 0x4ec06, // usemap + 0x164: 0x1dd0a, // figcaption + 0x165: 0x36806, // ondrag + 0x166: 0x29304, // high + 0x168: 0x3d403, // src + 0x169: 0x17d06, // poster + 0x16b: 0x18d0e, // annotation-xml + 0x16c: 0x5bc04, // step + 0x16d: 0x4, // abbr + 0x16e: 0x1b06, // dialog + 0x170: 0x1202, // li + 0x172: 0x47a02, // mo + 0x175: 0x1fd03, // for + 0x176: 0x1cd03, // ins + 0x178: 0x53004, // size + 0x17a: 0x5207, // default + 0x17b: 0x1a03, // bdi + 0x17c: 0x4ce0a, // onpagehide + 0x17d: 0x9d07, // dirname + 0x17e: 0x23304, // type + 0x17f: 0x21704, // form + 0x180: 0x4c105, // inert + 0x181: 0x12709, // oncanplay + 0x182: 0x8303, // dfn + 0x183: 0x45c08, // tabindex + 0x186: 0x7f02, // em + 0x187: 0x29c04, // lang + 0x189: 0x3a208, // dropzone + 0x18a: 0x4110a, // onkeypress + 0x18b: 0x25b08, // datetime + 0x18c: 0x18804, // cols + 0x18d: 0x1, // a + 0x18e: 0x43b0c, // onloadeddata + 0x191: 0x15606, // border + 0x192: 0x2e05, // tbody + 0x193: 0x24b06, // method + 0x195: 0xbe04, // loop + 0x196: 0x2b406, // iframe + 0x198: 0x2fa04, // head + 0x19e: 0x5b608, // manifest + 0x19f: 0xe109, // autofocus + 0x1a0: 0x16f04, // code + 0x1a1: 0x53406, // strong + 0x1a2: 0x32108, // multiple + 0x1a3: 0xc05, // param + 0x1a6: 0x23007, // enctype + 0x1a7: 0x2dd04, // face + 0x1a8: 0xf109, // plaintext + 0x1a9: 0x13602, // h1 + 0x1aa: 0x56609, // onstalled + 0x1ad: 0x28d06, // script + 0x1ae: 0x30006, // spacer + 0x1af: 0x52c08, // onresize + 0x1b0: 0x49b0b, // onmouseover + 0x1b1: 0x59108, // onunload + 0x1b2: 0x54208, // onseeked + 0x1b4: 0x2330d, // typemustmatch + 0x1b5: 0x1f106, // figure + 0x1b6: 0x48e0a, // onmouseout + 0x1b7: 0x27f03, // pre + 0x1b8: 0x4e205, // width + 0x1bb: 0x7404, // nobr + 0x1be: 0x7002, // tt + 0x1bf: 0x1105, // align + 0x1c0: 0x3f407, // oninput + 0x1c3: 0x42107, // onkeyup + 0x1c6: 0x1e50c, // onafterprint + 0x1c7: 0x210e, // accept-charset + 0x1c8: 0x9806, // itemid + 0x1cb: 0x50e06, // strike + 0x1cc: 0x57a03, // sub + 0x1cd: 0xf905, // track + 0x1ce: 0x39705, // start + 0x1d0: 0x11408, // basefont + 0x1d6: 0x1cf06, // source + 0x1d7: 0x1a806, // legend + 0x1d8: 0x2f905, // thead + 0x1da: 0x2e905, // scope + 0x1dd: 0x21106, // object + 0x1de: 0xa205, // media + 0x1df: 0x18d0a, // annotation + 0x1e0: 0x22c0b, // formenctype + 0x1e2: 0x28b08, // noscript + 0x1e4: 0x53005, // sizes + 0x1e5: 0xd50c, // autocomplete + 0x1e6: 0x7a04, // span + 0x1e7: 0x8508, // noframes + 0x1e8: 0x26a06, // target + 0x1e9: 0x3a006, // ondrop + 0x1ea: 0x3d406, // srcdoc + 0x1ec: 0x5e08, // reversed + 0x1f0: 0x2c707, // isindex + 0x1f3: 0x29808, // hreflang + 0x1f5: 0x4e602, // h5 + 0x1f6: 0x5d507, // address + 0x1fa: 0x30603, // max + 0x1fb: 0xc70b, // placeholder + 0x1fc: 0x31408, // textarea + 0x1fe: 0x4a609, // onmouseup + 0x1ff: 0x3910b, // ondragstart +} + +const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + + "genavaluealtdescanvasidefaultfootereversedetailsampatternobr" + + "owspanoembedfnoframesetitleasyncitemidirnamediagroupingaudio" + + "ncancelabelooptgrouplaceholderubyautocompleteautofocusandbox" + + "mplaintextrackindisabledivarautoplaybasefontimeupdatebdoncan" + + "playthrough1bgsoundlowbrbigblinkblockquoteborderbuttonabortr" + + "anslatecodefercolgroupostercolorcolspannotation-xmlcommandra" + + "ggablegendcontrolshapecoordsmallcrossoriginsourcefieldsetfig" + + "captionafterprintfigurequiredforeignObjectforeignobjectforma" + + "ctionbeforeprintformenctypemustmatchallengeformmethodformnov" + + "alidatetimeterformtargeth6heightmlhgroupreloadhiddenoscripth" + + "igh2hreflanghttp-equivideonclickiframeimageimglyph3isindexis" + + "mappletitemrefacenteritemscopeditemtypematheaderspacermaxlen" + + "gth4minmtextareadonlymultiplemutedoncloseamlesspellcheckedon" + + "contextmenuoncuechangeondblclickondragendondragenterondragle" + + "aveondragoverondragstarticleondropzonemptiedondurationchange" + + "onendedonerroronfocusrcdoclassectionbluronhashchangeoninputo" + + "ninvalidonkeydownloadonkeypressrclangonkeyupublicontentedita" + + "bleonloadeddatalistingonloadedmetadatabindexonloadstartonmes" + + "sageonmousedownonmousemoveonmouseoutputonmouseoveronmouseupo" + + "nmousewheelonofflinertononlineonpagehidelonpageshowidth5onpa" + + "usemaponplayingonpopstateonprogresstrikeytypeonratechangeonr" + + "esetonresizestrongonscrollonseekedonseekingonselectedonshowr" + + "aponstalledonstorageonsubmitempropenonsuspendonunloadonvolum" + + "echangeonwaitingoptimumanifestepromptoptionbeforeunloaddress" + + "tylesummarysupsvgsystemarquee" diff --git a/libgo/go/exp/html/atom/table_test.go b/libgo/go/exp/html/atom/table_test.go new file mode 100644 index 0000000..db016a1 --- /dev/null +++ b/libgo/go/exp/html/atom/table_test.go @@ -0,0 +1,341 @@ +// generated by go run gen.go -test; DO NOT EDIT + +package atom + +var testAtomList = []string{ + "a", + "abbr", + "accept", + "accept-charset", + "accesskey", + "action", + "address", + "align", + "alt", + "annotation", + "annotation-xml", + "applet", + "area", + "article", + "aside", + "async", + "audio", + "autocomplete", + "autofocus", + "autoplay", + "b", + "base", + "basefont", + "bdi", + "bdo", + "bgsound", + "big", + "blink", + "blockquote", + "body", + "border", + "br", + "button", + "canvas", + "caption", + "center", + "challenge", + "charset", + "checked", + "cite", + "cite", + "class", + "code", + "col", + "colgroup", + "color", + "cols", + "colspan", + "command", + "command", + "content", + "contenteditable", + "contextmenu", + "controls", + "coords", + "crossorigin", + "data", + "data", + "datalist", + "datetime", + "dd", + "default", + "defer", + "del", + "desc", + "details", + "dfn", + "dialog", + "dir", + "dirname", + "disabled", + "div", + "dl", + "download", + "draggable", + "dropzone", + "dt", + "em", + "embed", + "enctype", + "face", + "fieldset", + "figcaption", + "figure", + "font", + "footer", + "for", + "foreignObject", + "foreignobject", + "form", + "form", + "formaction", + "formenctype", + "formmethod", + "formnovalidate", + "formtarget", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "headers", + "height", + "hgroup", + "hidden", + "high", + "hr", + "href", + "hreflang", + "html", + "http-equiv", + "i", + "icon", + "id", + "iframe", + "image", + "img", + "inert", + "input", + "ins", + "isindex", + "ismap", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "kbd", + "keygen", + "keytype", + "kind", + "label", + "label", + "lang", + "legend", + "li", + "link", + "list", + "listing", + "loop", + "low", + "malignmark", + "manifest", + "map", + "mark", + "marquee", + "math", + "max", + "maxlength", + "media", + "mediagroup", + "menu", + "meta", + "meter", + "method", + "mglyph", + "mi", + "min", + "mn", + "mo", + "ms", + "mtext", + "multiple", + "muted", + "name", + "nav", + "nobr", + "noembed", + "noframes", + "noscript", + "novalidate", + "object", + "ol", + "onabort", + "onafterprint", + "onbeforeprint", + "onbeforeunload", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onhashchange", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmessage", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onoffline", + "ononline", + "onpagehide", + "onpageshow", + "onpause", + "onplay", + "onplaying", + "onpopstate", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onstalled", + "onstorage", + "onsubmit", + "onsuspend", + "ontimeupdate", + "onunload", + "onvolumechange", + "onwaiting", + "open", + "optgroup", + "optimum", + "option", + "output", + "p", + "param", + "pattern", + "ping", + "placeholder", + "plaintext", + "poster", + "pre", + "preload", + "progress", + "prompt", + "public", + "q", + "radiogroup", + "readonly", + "rel", + "required", + "reversed", + "rows", + "rowspan", + "rp", + "rt", + "ruby", + "s", + "samp", + "sandbox", + "scope", + "scoped", + "script", + "seamless", + "section", + "select", + "selected", + "shape", + "size", + "sizes", + "small", + "source", + "spacer", + "span", + "span", + "spellcheck", + "src", + "srcdoc", + "srclang", + "start", + "step", + "strike", + "strong", + "style", + "style", + "sub", + "summary", + "sup", + "svg", + "system", + "tabindex", + "table", + "target", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "title", + "tr", + "track", + "translate", + "tt", + "type", + "typemustmatch", + "u", + "ul", + "usemap", + "value", + "var", + "video", + "wbr", + "width", + "wrap", + "xmp", +} diff --git a/libgo/go/exp/html/doc.go b/libgo/go/exp/html/doc.go index 56b194f..4dd4530 100644 --- a/libgo/go/exp/html/doc.go +++ b/libgo/go/exp/html/doc.go @@ -84,7 +84,7 @@ example, to process each anchor node in depth-first order: if n.Type == html.ElementNode && n.Data == "a" { // Do something with n... } - for _, c := range n.Child { + for c := n.FirstChild; c != nil; c = c.NextSibling { f(c) } } diff --git a/libgo/go/exp/html/entity.go b/libgo/go/exp/html/entity.go index bd83075..af8a007 100644 --- a/libgo/go/exp/html/entity.go +++ b/libgo/go/exp/html/entity.go @@ -75,2083 +75,2083 @@ var entity = map[string]rune{ "Copf;": '\U00002102', "Coproduct;": '\U00002210', "CounterClockwiseContourIntegral;": '\U00002233', - "Cross;": '\U00002A2F', - "Cscr;": '\U0001D49E', - "Cup;": '\U000022D3', - "CupCap;": '\U0000224D', - "DD;": '\U00002145', - "DDotrahd;": '\U00002911', - "DJcy;": '\U00000402', - "DScy;": '\U00000405', - "DZcy;": '\U0000040F', - "Dagger;": '\U00002021', - "Darr;": '\U000021A1', - "Dashv;": '\U00002AE4', - "Dcaron;": '\U0000010E', - "Dcy;": '\U00000414', - "Del;": '\U00002207', - "Delta;": '\U00000394', - "Dfr;": '\U0001D507', - "DiacriticalAcute;": '\U000000B4', - "DiacriticalDot;": '\U000002D9', - "DiacriticalDoubleAcute;": '\U000002DD', - "DiacriticalGrave;": '\U00000060', - "DiacriticalTilde;": '\U000002DC', - "Diamond;": '\U000022C4', - "DifferentialD;": '\U00002146', - "Dopf;": '\U0001D53B', - "Dot;": '\U000000A8', - "DotDot;": '\U000020DC', - "DotEqual;": '\U00002250', - "DoubleContourIntegral;": '\U0000222F', - "DoubleDot;": '\U000000A8', - "DoubleDownArrow;": '\U000021D3', - "DoubleLeftArrow;": '\U000021D0', - "DoubleLeftRightArrow;": '\U000021D4', - "DoubleLeftTee;": '\U00002AE4', - "DoubleLongLeftArrow;": '\U000027F8', - "DoubleLongLeftRightArrow;": '\U000027FA', - "DoubleLongRightArrow;": '\U000027F9', - "DoubleRightArrow;": '\U000021D2', - "DoubleRightTee;": '\U000022A8', - "DoubleUpArrow;": '\U000021D1', - "DoubleUpDownArrow;": '\U000021D5', - "DoubleVerticalBar;": '\U00002225', - "DownArrow;": '\U00002193', - "DownArrowBar;": '\U00002913', - "DownArrowUpArrow;": '\U000021F5', - "DownBreve;": '\U00000311', - "DownLeftRightVector;": '\U00002950', - "DownLeftTeeVector;": '\U0000295E', - "DownLeftVector;": '\U000021BD', - "DownLeftVectorBar;": '\U00002956', - "DownRightTeeVector;": '\U0000295F', - "DownRightVector;": '\U000021C1', - "DownRightVectorBar;": '\U00002957', - "DownTee;": '\U000022A4', - "DownTeeArrow;": '\U000021A7', - "Downarrow;": '\U000021D3', - "Dscr;": '\U0001D49F', - "Dstrok;": '\U00000110', - "ENG;": '\U0000014A', - "ETH;": '\U000000D0', - "Eacute;": '\U000000C9', - "Ecaron;": '\U0000011A', - "Ecirc;": '\U000000CA', - "Ecy;": '\U0000042D', - "Edot;": '\U00000116', - "Efr;": '\U0001D508', - "Egrave;": '\U000000C8', - "Element;": '\U00002208', - "Emacr;": '\U00000112', - "EmptySmallSquare;": '\U000025FB', - "EmptyVerySmallSquare;": '\U000025AB', - "Eogon;": '\U00000118', - "Eopf;": '\U0001D53C', - "Epsilon;": '\U00000395', - "Equal;": '\U00002A75', - "EqualTilde;": '\U00002242', - "Equilibrium;": '\U000021CC', - "Escr;": '\U00002130', - "Esim;": '\U00002A73', - "Eta;": '\U00000397', - "Euml;": '\U000000CB', - "Exists;": '\U00002203', - "ExponentialE;": '\U00002147', - "Fcy;": '\U00000424', - "Ffr;": '\U0001D509', - "FilledSmallSquare;": '\U000025FC', - "FilledVerySmallSquare;": '\U000025AA', - "Fopf;": '\U0001D53D', - "ForAll;": '\U00002200', - "Fouriertrf;": '\U00002131', - "Fscr;": '\U00002131', - "GJcy;": '\U00000403', - "GT;": '\U0000003E', - "Gamma;": '\U00000393', - "Gammad;": '\U000003DC', - "Gbreve;": '\U0000011E', - "Gcedil;": '\U00000122', - "Gcirc;": '\U0000011C', - "Gcy;": '\U00000413', - "Gdot;": '\U00000120', - "Gfr;": '\U0001D50A', - "Gg;": '\U000022D9', - "Gopf;": '\U0001D53E', - "GreaterEqual;": '\U00002265', - "GreaterEqualLess;": '\U000022DB', - "GreaterFullEqual;": '\U00002267', - "GreaterGreater;": '\U00002AA2', - "GreaterLess;": '\U00002277', - "GreaterSlantEqual;": '\U00002A7E', - "GreaterTilde;": '\U00002273', - "Gscr;": '\U0001D4A2', - "Gt;": '\U0000226B', - "HARDcy;": '\U0000042A', - "Hacek;": '\U000002C7', - "Hat;": '\U0000005E', - "Hcirc;": '\U00000124', - "Hfr;": '\U0000210C', - "HilbertSpace;": '\U0000210B', - "Hopf;": '\U0000210D', - "HorizontalLine;": '\U00002500', - "Hscr;": '\U0000210B', - "Hstrok;": '\U00000126', - "HumpDownHump;": '\U0000224E', - "HumpEqual;": '\U0000224F', - "IEcy;": '\U00000415', - "IJlig;": '\U00000132', - "IOcy;": '\U00000401', - "Iacute;": '\U000000CD', - "Icirc;": '\U000000CE', - "Icy;": '\U00000418', - "Idot;": '\U00000130', - "Ifr;": '\U00002111', - "Igrave;": '\U000000CC', - "Im;": '\U00002111', - "Imacr;": '\U0000012A', - "ImaginaryI;": '\U00002148', - "Implies;": '\U000021D2', - "Int;": '\U0000222C', - "Integral;": '\U0000222B', - "Intersection;": '\U000022C2', - "InvisibleComma;": '\U00002063', - "InvisibleTimes;": '\U00002062', - "Iogon;": '\U0000012E', - "Iopf;": '\U0001D540', - "Iota;": '\U00000399', - "Iscr;": '\U00002110', - "Itilde;": '\U00000128', - "Iukcy;": '\U00000406', - "Iuml;": '\U000000CF', - "Jcirc;": '\U00000134', - "Jcy;": '\U00000419', - "Jfr;": '\U0001D50D', - "Jopf;": '\U0001D541', - "Jscr;": '\U0001D4A5', - "Jsercy;": '\U00000408', - "Jukcy;": '\U00000404', - "KHcy;": '\U00000425', - "KJcy;": '\U0000040C', - "Kappa;": '\U0000039A', - "Kcedil;": '\U00000136', - "Kcy;": '\U0000041A', - "Kfr;": '\U0001D50E', - "Kopf;": '\U0001D542', - "Kscr;": '\U0001D4A6', - "LJcy;": '\U00000409', - "LT;": '\U0000003C', - "Lacute;": '\U00000139', - "Lambda;": '\U0000039B', - "Lang;": '\U000027EA', - "Laplacetrf;": '\U00002112', - "Larr;": '\U0000219E', - "Lcaron;": '\U0000013D', - "Lcedil;": '\U0000013B', - "Lcy;": '\U0000041B', - "LeftAngleBracket;": '\U000027E8', - "LeftArrow;": '\U00002190', - "LeftArrowBar;": '\U000021E4', - "LeftArrowRightArrow;": '\U000021C6', - "LeftCeiling;": '\U00002308', - "LeftDoubleBracket;": '\U000027E6', - "LeftDownTeeVector;": '\U00002961', - "LeftDownVector;": '\U000021C3', - "LeftDownVectorBar;": '\U00002959', - "LeftFloor;": '\U0000230A', - "LeftRightArrow;": '\U00002194', - "LeftRightVector;": '\U0000294E', - "LeftTee;": '\U000022A3', - "LeftTeeArrow;": '\U000021A4', - "LeftTeeVector;": '\U0000295A', - "LeftTriangle;": '\U000022B2', - "LeftTriangleBar;": '\U000029CF', - "LeftTriangleEqual;": '\U000022B4', - "LeftUpDownVector;": '\U00002951', - "LeftUpTeeVector;": '\U00002960', - "LeftUpVector;": '\U000021BF', - "LeftUpVectorBar;": '\U00002958', - "LeftVector;": '\U000021BC', - "LeftVectorBar;": '\U00002952', - "Leftarrow;": '\U000021D0', - "Leftrightarrow;": '\U000021D4', - "LessEqualGreater;": '\U000022DA', - "LessFullEqual;": '\U00002266', - "LessGreater;": '\U00002276', - "LessLess;": '\U00002AA1', - "LessSlantEqual;": '\U00002A7D', - "LessTilde;": '\U00002272', - "Lfr;": '\U0001D50F', - "Ll;": '\U000022D8', - "Lleftarrow;": '\U000021DA', - "Lmidot;": '\U0000013F', - "LongLeftArrow;": '\U000027F5', - "LongLeftRightArrow;": '\U000027F7', - "LongRightArrow;": '\U000027F6', - "Longleftarrow;": '\U000027F8', - "Longleftrightarrow;": '\U000027FA', - "Longrightarrow;": '\U000027F9', - "Lopf;": '\U0001D543', - "LowerLeftArrow;": '\U00002199', - "LowerRightArrow;": '\U00002198', - "Lscr;": '\U00002112', - "Lsh;": '\U000021B0', - "Lstrok;": '\U00000141', - "Lt;": '\U0000226A', - "Map;": '\U00002905', - "Mcy;": '\U0000041C', - "MediumSpace;": '\U0000205F', - "Mellintrf;": '\U00002133', - "Mfr;": '\U0001D510', - "MinusPlus;": '\U00002213', - "Mopf;": '\U0001D544', - "Mscr;": '\U00002133', - "Mu;": '\U0000039C', - "NJcy;": '\U0000040A', - "Nacute;": '\U00000143', - "Ncaron;": '\U00000147', - "Ncedil;": '\U00000145', - "Ncy;": '\U0000041D', - "NegativeMediumSpace;": '\U0000200B', - "NegativeThickSpace;": '\U0000200B', - "NegativeThinSpace;": '\U0000200B', - "NegativeVeryThinSpace;": '\U0000200B', - "NestedGreaterGreater;": '\U0000226B', - "NestedLessLess;": '\U0000226A', - "NewLine;": '\U0000000A', - "Nfr;": '\U0001D511', - "NoBreak;": '\U00002060', - "NonBreakingSpace;": '\U000000A0', - "Nopf;": '\U00002115', - "Not;": '\U00002AEC', - "NotCongruent;": '\U00002262', - "NotCupCap;": '\U0000226D', - "NotDoubleVerticalBar;": '\U00002226', - "NotElement;": '\U00002209', - "NotEqual;": '\U00002260', - "NotExists;": '\U00002204', - "NotGreater;": '\U0000226F', - "NotGreaterEqual;": '\U00002271', - "NotGreaterLess;": '\U00002279', - "NotGreaterTilde;": '\U00002275', - "NotLeftTriangle;": '\U000022EA', - "NotLeftTriangleEqual;": '\U000022EC', - "NotLess;": '\U0000226E', - "NotLessEqual;": '\U00002270', - "NotLessGreater;": '\U00002278', - "NotLessTilde;": '\U00002274', - "NotPrecedes;": '\U00002280', - "NotPrecedesSlantEqual;": '\U000022E0', - "NotReverseElement;": '\U0000220C', - "NotRightTriangle;": '\U000022EB', - "NotRightTriangleEqual;": '\U000022ED', - "NotSquareSubsetEqual;": '\U000022E2', - "NotSquareSupersetEqual;": '\U000022E3', - "NotSubsetEqual;": '\U00002288', - "NotSucceeds;": '\U00002281', - "NotSucceedsSlantEqual;": '\U000022E1', - "NotSupersetEqual;": '\U00002289', - "NotTilde;": '\U00002241', - "NotTildeEqual;": '\U00002244', - "NotTildeFullEqual;": '\U00002247', - "NotTildeTilde;": '\U00002249', - "NotVerticalBar;": '\U00002224', - "Nscr;": '\U0001D4A9', - "Ntilde;": '\U000000D1', - "Nu;": '\U0000039D', - "OElig;": '\U00000152', - "Oacute;": '\U000000D3', - "Ocirc;": '\U000000D4', - "Ocy;": '\U0000041E', - "Odblac;": '\U00000150', - "Ofr;": '\U0001D512', - "Ograve;": '\U000000D2', - "Omacr;": '\U0000014C', - "Omega;": '\U000003A9', - "Omicron;": '\U0000039F', - "Oopf;": '\U0001D546', - "OpenCurlyDoubleQuote;": '\U0000201C', - "OpenCurlyQuote;": '\U00002018', - "Or;": '\U00002A54', - "Oscr;": '\U0001D4AA', - "Oslash;": '\U000000D8', - "Otilde;": '\U000000D5', - "Otimes;": '\U00002A37', - "Ouml;": '\U000000D6', - "OverBar;": '\U0000203E', - "OverBrace;": '\U000023DE', - "OverBracket;": '\U000023B4', - "OverParenthesis;": '\U000023DC', - "PartialD;": '\U00002202', - "Pcy;": '\U0000041F', - "Pfr;": '\U0001D513', - "Phi;": '\U000003A6', - "Pi;": '\U000003A0', - "PlusMinus;": '\U000000B1', - "Poincareplane;": '\U0000210C', - "Popf;": '\U00002119', - "Pr;": '\U00002ABB', - "Precedes;": '\U0000227A', - "PrecedesEqual;": '\U00002AAF', - "PrecedesSlantEqual;": '\U0000227C', - "PrecedesTilde;": '\U0000227E', - "Prime;": '\U00002033', - "Product;": '\U0000220F', - "Proportion;": '\U00002237', - "Proportional;": '\U0000221D', - "Pscr;": '\U0001D4AB', - "Psi;": '\U000003A8', - "QUOT;": '\U00000022', - "Qfr;": '\U0001D514', - "Qopf;": '\U0000211A', - "Qscr;": '\U0001D4AC', - "RBarr;": '\U00002910', - "REG;": '\U000000AE', - "Racute;": '\U00000154', - "Rang;": '\U000027EB', - "Rarr;": '\U000021A0', - "Rarrtl;": '\U00002916', - "Rcaron;": '\U00000158', - "Rcedil;": '\U00000156', - "Rcy;": '\U00000420', - "Re;": '\U0000211C', - "ReverseElement;": '\U0000220B', - "ReverseEquilibrium;": '\U000021CB', - "ReverseUpEquilibrium;": '\U0000296F', - "Rfr;": '\U0000211C', - "Rho;": '\U000003A1', - "RightAngleBracket;": '\U000027E9', - "RightArrow;": '\U00002192', - "RightArrowBar;": '\U000021E5', - "RightArrowLeftArrow;": '\U000021C4', - "RightCeiling;": '\U00002309', - "RightDoubleBracket;": '\U000027E7', - "RightDownTeeVector;": '\U0000295D', - "RightDownVector;": '\U000021C2', - "RightDownVectorBar;": '\U00002955', - "RightFloor;": '\U0000230B', - "RightTee;": '\U000022A2', - "RightTeeArrow;": '\U000021A6', - "RightTeeVector;": '\U0000295B', - "RightTriangle;": '\U000022B3', - "RightTriangleBar;": '\U000029D0', - "RightTriangleEqual;": '\U000022B5', - "RightUpDownVector;": '\U0000294F', - "RightUpTeeVector;": '\U0000295C', - "RightUpVector;": '\U000021BE', - "RightUpVectorBar;": '\U00002954', - "RightVector;": '\U000021C0', - "RightVectorBar;": '\U00002953', - "Rightarrow;": '\U000021D2', - "Ropf;": '\U0000211D', - "RoundImplies;": '\U00002970', - "Rrightarrow;": '\U000021DB', - "Rscr;": '\U0000211B', - "Rsh;": '\U000021B1', - "RuleDelayed;": '\U000029F4', - "SHCHcy;": '\U00000429', - "SHcy;": '\U00000428', - "SOFTcy;": '\U0000042C', - "Sacute;": '\U0000015A', - "Sc;": '\U00002ABC', - "Scaron;": '\U00000160', - "Scedil;": '\U0000015E', - "Scirc;": '\U0000015C', - "Scy;": '\U00000421', - "Sfr;": '\U0001D516', - "ShortDownArrow;": '\U00002193', - "ShortLeftArrow;": '\U00002190', - "ShortRightArrow;": '\U00002192', - "ShortUpArrow;": '\U00002191', - "Sigma;": '\U000003A3', - "SmallCircle;": '\U00002218', - "Sopf;": '\U0001D54A', - "Sqrt;": '\U0000221A', - "Square;": '\U000025A1', - "SquareIntersection;": '\U00002293', - "SquareSubset;": '\U0000228F', - "SquareSubsetEqual;": '\U00002291', - "SquareSuperset;": '\U00002290', - "SquareSupersetEqual;": '\U00002292', - "SquareUnion;": '\U00002294', - "Sscr;": '\U0001D4AE', - "Star;": '\U000022C6', - "Sub;": '\U000022D0', - "Subset;": '\U000022D0', - "SubsetEqual;": '\U00002286', - "Succeeds;": '\U0000227B', - "SucceedsEqual;": '\U00002AB0', - "SucceedsSlantEqual;": '\U0000227D', - "SucceedsTilde;": '\U0000227F', - "SuchThat;": '\U0000220B', - "Sum;": '\U00002211', - "Sup;": '\U000022D1', - "Superset;": '\U00002283', - "SupersetEqual;": '\U00002287', - "Supset;": '\U000022D1', - "THORN;": '\U000000DE', - "TRADE;": '\U00002122', - "TSHcy;": '\U0000040B', - "TScy;": '\U00000426', - "Tab;": '\U00000009', - "Tau;": '\U000003A4', - "Tcaron;": '\U00000164', - "Tcedil;": '\U00000162', - "Tcy;": '\U00000422', - "Tfr;": '\U0001D517', - "Therefore;": '\U00002234', - "Theta;": '\U00000398', - "ThinSpace;": '\U00002009', - "Tilde;": '\U0000223C', - "TildeEqual;": '\U00002243', - "TildeFullEqual;": '\U00002245', - "TildeTilde;": '\U00002248', - "Topf;": '\U0001D54B', - "TripleDot;": '\U000020DB', - "Tscr;": '\U0001D4AF', - "Tstrok;": '\U00000166', - "Uacute;": '\U000000DA', - "Uarr;": '\U0000219F', - "Uarrocir;": '\U00002949', - "Ubrcy;": '\U0000040E', - "Ubreve;": '\U0000016C', - "Ucirc;": '\U000000DB', - "Ucy;": '\U00000423', - "Udblac;": '\U00000170', - "Ufr;": '\U0001D518', - "Ugrave;": '\U000000D9', - "Umacr;": '\U0000016A', - "UnderBar;": '\U0000005F', - "UnderBrace;": '\U000023DF', - "UnderBracket;": '\U000023B5', - "UnderParenthesis;": '\U000023DD', - "Union;": '\U000022C3', - "UnionPlus;": '\U0000228E', - "Uogon;": '\U00000172', - "Uopf;": '\U0001D54C', - "UpArrow;": '\U00002191', - "UpArrowBar;": '\U00002912', - "UpArrowDownArrow;": '\U000021C5', - "UpDownArrow;": '\U00002195', - "UpEquilibrium;": '\U0000296E', - "UpTee;": '\U000022A5', - "UpTeeArrow;": '\U000021A5', - "Uparrow;": '\U000021D1', - "Updownarrow;": '\U000021D5', - "UpperLeftArrow;": '\U00002196', - "UpperRightArrow;": '\U00002197', - "Upsi;": '\U000003D2', - "Upsilon;": '\U000003A5', - "Uring;": '\U0000016E', - "Uscr;": '\U0001D4B0', - "Utilde;": '\U00000168', - "Uuml;": '\U000000DC', - "VDash;": '\U000022AB', - "Vbar;": '\U00002AEB', - "Vcy;": '\U00000412', - "Vdash;": '\U000022A9', - "Vdashl;": '\U00002AE6', - "Vee;": '\U000022C1', - "Verbar;": '\U00002016', - "Vert;": '\U00002016', - "VerticalBar;": '\U00002223', - "VerticalLine;": '\U0000007C', - "VerticalSeparator;": '\U00002758', - "VerticalTilde;": '\U00002240', - "VeryThinSpace;": '\U0000200A', - "Vfr;": '\U0001D519', - "Vopf;": '\U0001D54D', - "Vscr;": '\U0001D4B1', - "Vvdash;": '\U000022AA', - "Wcirc;": '\U00000174', - "Wedge;": '\U000022C0', - "Wfr;": '\U0001D51A', - "Wopf;": '\U0001D54E', - "Wscr;": '\U0001D4B2', - "Xfr;": '\U0001D51B', - "Xi;": '\U0000039E', - "Xopf;": '\U0001D54F', - "Xscr;": '\U0001D4B3', - "YAcy;": '\U0000042F', - "YIcy;": '\U00000407', - "YUcy;": '\U0000042E', - "Yacute;": '\U000000DD', - "Ycirc;": '\U00000176', - "Ycy;": '\U0000042B', - "Yfr;": '\U0001D51C', - "Yopf;": '\U0001D550', - "Yscr;": '\U0001D4B4', - "Yuml;": '\U00000178', - "ZHcy;": '\U00000416', - "Zacute;": '\U00000179', - "Zcaron;": '\U0000017D', - "Zcy;": '\U00000417', - "Zdot;": '\U0000017B', - "ZeroWidthSpace;": '\U0000200B', - "Zeta;": '\U00000396', - "Zfr;": '\U00002128', - "Zopf;": '\U00002124', - "Zscr;": '\U0001D4B5', - "aacute;": '\U000000E1', - "abreve;": '\U00000103', - "ac;": '\U0000223E', - "acd;": '\U0000223F', - "acirc;": '\U000000E2', - "acute;": '\U000000B4', - "acy;": '\U00000430', - "aelig;": '\U000000E6', - "af;": '\U00002061', - "afr;": '\U0001D51E', - "agrave;": '\U000000E0', - "alefsym;": '\U00002135', - "aleph;": '\U00002135', - "alpha;": '\U000003B1', - "amacr;": '\U00000101', - "amalg;": '\U00002A3F', - "amp;": '\U00000026', - "and;": '\U00002227', - "andand;": '\U00002A55', - "andd;": '\U00002A5C', - "andslope;": '\U00002A58', - "andv;": '\U00002A5A', - "ang;": '\U00002220', - "ange;": '\U000029A4', - "angle;": '\U00002220', - "angmsd;": '\U00002221', - "angmsdaa;": '\U000029A8', - "angmsdab;": '\U000029A9', - "angmsdac;": '\U000029AA', - "angmsdad;": '\U000029AB', - "angmsdae;": '\U000029AC', - "angmsdaf;": '\U000029AD', - "angmsdag;": '\U000029AE', - "angmsdah;": '\U000029AF', - "angrt;": '\U0000221F', - "angrtvb;": '\U000022BE', - "angrtvbd;": '\U0000299D', - "angsph;": '\U00002222', - "angst;": '\U000000C5', - "angzarr;": '\U0000237C', - "aogon;": '\U00000105', - "aopf;": '\U0001D552', - "ap;": '\U00002248', - "apE;": '\U00002A70', - "apacir;": '\U00002A6F', - "ape;": '\U0000224A', - "apid;": '\U0000224B', - "apos;": '\U00000027', - "approx;": '\U00002248', - "approxeq;": '\U0000224A', - "aring;": '\U000000E5', - "ascr;": '\U0001D4B6', - "ast;": '\U0000002A', - "asymp;": '\U00002248', - "asympeq;": '\U0000224D', - "atilde;": '\U000000E3', - "auml;": '\U000000E4', - "awconint;": '\U00002233', - "awint;": '\U00002A11', - "bNot;": '\U00002AED', - "backcong;": '\U0000224C', - "backepsilon;": '\U000003F6', - "backprime;": '\U00002035', - "backsim;": '\U0000223D', - "backsimeq;": '\U000022CD', - "barvee;": '\U000022BD', - "barwed;": '\U00002305', - "barwedge;": '\U00002305', - "bbrk;": '\U000023B5', - "bbrktbrk;": '\U000023B6', - "bcong;": '\U0000224C', - "bcy;": '\U00000431', - "bdquo;": '\U0000201E', - "becaus;": '\U00002235', - "because;": '\U00002235', - "bemptyv;": '\U000029B0', - "bepsi;": '\U000003F6', - "bernou;": '\U0000212C', - "beta;": '\U000003B2', - "beth;": '\U00002136', - "between;": '\U0000226C', - "bfr;": '\U0001D51F', - "bigcap;": '\U000022C2', - "bigcirc;": '\U000025EF', - "bigcup;": '\U000022C3', - "bigodot;": '\U00002A00', - "bigoplus;": '\U00002A01', - "bigotimes;": '\U00002A02', - "bigsqcup;": '\U00002A06', - "bigstar;": '\U00002605', - "bigtriangledown;": '\U000025BD', - "bigtriangleup;": '\U000025B3', - "biguplus;": '\U00002A04', - "bigvee;": '\U000022C1', - "bigwedge;": '\U000022C0', - "bkarow;": '\U0000290D', - "blacklozenge;": '\U000029EB', - "blacksquare;": '\U000025AA', - "blacktriangle;": '\U000025B4', - "blacktriangledown;": '\U000025BE', - "blacktriangleleft;": '\U000025C2', - "blacktriangleright;": '\U000025B8', - "blank;": '\U00002423', - "blk12;": '\U00002592', - "blk14;": '\U00002591', - "blk34;": '\U00002593', - "block;": '\U00002588', - "bnot;": '\U00002310', - "bopf;": '\U0001D553', - "bot;": '\U000022A5', - "bottom;": '\U000022A5', - "bowtie;": '\U000022C8', - "boxDL;": '\U00002557', - "boxDR;": '\U00002554', - "boxDl;": '\U00002556', - "boxDr;": '\U00002553', - "boxH;": '\U00002550', - "boxHD;": '\U00002566', - "boxHU;": '\U00002569', - "boxHd;": '\U00002564', - "boxHu;": '\U00002567', - "boxUL;": '\U0000255D', - "boxUR;": '\U0000255A', - "boxUl;": '\U0000255C', - "boxUr;": '\U00002559', - "boxV;": '\U00002551', - "boxVH;": '\U0000256C', - "boxVL;": '\U00002563', - "boxVR;": '\U00002560', - "boxVh;": '\U0000256B', - "boxVl;": '\U00002562', - "boxVr;": '\U0000255F', - "boxbox;": '\U000029C9', - "boxdL;": '\U00002555', - "boxdR;": '\U00002552', - "boxdl;": '\U00002510', - "boxdr;": '\U0000250C', - "boxh;": '\U00002500', - "boxhD;": '\U00002565', - "boxhU;": '\U00002568', - "boxhd;": '\U0000252C', - "boxhu;": '\U00002534', - "boxminus;": '\U0000229F', - "boxplus;": '\U0000229E', - "boxtimes;": '\U000022A0', - "boxuL;": '\U0000255B', - "boxuR;": '\U00002558', - "boxul;": '\U00002518', - "boxur;": '\U00002514', - "boxv;": '\U00002502', - "boxvH;": '\U0000256A', - "boxvL;": '\U00002561', - "boxvR;": '\U0000255E', - "boxvh;": '\U0000253C', - "boxvl;": '\U00002524', - "boxvr;": '\U0000251C', - "bprime;": '\U00002035', - "breve;": '\U000002D8', - "brvbar;": '\U000000A6', - "bscr;": '\U0001D4B7', - "bsemi;": '\U0000204F', - "bsim;": '\U0000223D', - "bsime;": '\U000022CD', - "bsol;": '\U0000005C', - "bsolb;": '\U000029C5', - "bsolhsub;": '\U000027C8', - "bull;": '\U00002022', - "bullet;": '\U00002022', - "bump;": '\U0000224E', - "bumpE;": '\U00002AAE', - "bumpe;": '\U0000224F', - "bumpeq;": '\U0000224F', - "cacute;": '\U00000107', - "cap;": '\U00002229', - "capand;": '\U00002A44', - "capbrcup;": '\U00002A49', - "capcap;": '\U00002A4B', - "capcup;": '\U00002A47', - "capdot;": '\U00002A40', - "caret;": '\U00002041', - "caron;": '\U000002C7', - "ccaps;": '\U00002A4D', - "ccaron;": '\U0000010D', - "ccedil;": '\U000000E7', - "ccirc;": '\U00000109', - "ccups;": '\U00002A4C', - "ccupssm;": '\U00002A50', - "cdot;": '\U0000010B', - "cedil;": '\U000000B8', - "cemptyv;": '\U000029B2', - "cent;": '\U000000A2', - "centerdot;": '\U000000B7', - "cfr;": '\U0001D520', - "chcy;": '\U00000447', - "check;": '\U00002713', - "checkmark;": '\U00002713', - "chi;": '\U000003C7', - "cir;": '\U000025CB', - "cirE;": '\U000029C3', - "circ;": '\U000002C6', - "circeq;": '\U00002257', - "circlearrowleft;": '\U000021BA', - "circlearrowright;": '\U000021BB', - "circledR;": '\U000000AE', - "circledS;": '\U000024C8', - "circledast;": '\U0000229B', - "circledcirc;": '\U0000229A', - "circleddash;": '\U0000229D', - "cire;": '\U00002257', - "cirfnint;": '\U00002A10', - "cirmid;": '\U00002AEF', - "cirscir;": '\U000029C2', - "clubs;": '\U00002663', - "clubsuit;": '\U00002663', - "colon;": '\U0000003A', - "colone;": '\U00002254', - "coloneq;": '\U00002254', - "comma;": '\U0000002C', - "commat;": '\U00000040', - "comp;": '\U00002201', - "compfn;": '\U00002218', - "complement;": '\U00002201', - "complexes;": '\U00002102', - "cong;": '\U00002245', - "congdot;": '\U00002A6D', - "conint;": '\U0000222E', - "copf;": '\U0001D554', - "coprod;": '\U00002210', - "copy;": '\U000000A9', - "copysr;": '\U00002117', - "crarr;": '\U000021B5', - "cross;": '\U00002717', - "cscr;": '\U0001D4B8', - "csub;": '\U00002ACF', - "csube;": '\U00002AD1', - "csup;": '\U00002AD0', - "csupe;": '\U00002AD2', - "ctdot;": '\U000022EF', - "cudarrl;": '\U00002938', - "cudarrr;": '\U00002935', - "cuepr;": '\U000022DE', - "cuesc;": '\U000022DF', - "cularr;": '\U000021B6', - "cularrp;": '\U0000293D', - "cup;": '\U0000222A', - "cupbrcap;": '\U00002A48', - "cupcap;": '\U00002A46', - "cupcup;": '\U00002A4A', - "cupdot;": '\U0000228D', - "cupor;": '\U00002A45', - "curarr;": '\U000021B7', - "curarrm;": '\U0000293C', - "curlyeqprec;": '\U000022DE', - "curlyeqsucc;": '\U000022DF', - "curlyvee;": '\U000022CE', - "curlywedge;": '\U000022CF', - "curren;": '\U000000A4', - "curvearrowleft;": '\U000021B6', - "curvearrowright;": '\U000021B7', - "cuvee;": '\U000022CE', - "cuwed;": '\U000022CF', - "cwconint;": '\U00002232', - "cwint;": '\U00002231', - "cylcty;": '\U0000232D', - "dArr;": '\U000021D3', - "dHar;": '\U00002965', - "dagger;": '\U00002020', - "daleth;": '\U00002138', - "darr;": '\U00002193', - "dash;": '\U00002010', - "dashv;": '\U000022A3', - "dbkarow;": '\U0000290F', - "dblac;": '\U000002DD', - "dcaron;": '\U0000010F', - "dcy;": '\U00000434', - "dd;": '\U00002146', - "ddagger;": '\U00002021', - "ddarr;": '\U000021CA', - "ddotseq;": '\U00002A77', - "deg;": '\U000000B0', - "delta;": '\U000003B4', - "demptyv;": '\U000029B1', - "dfisht;": '\U0000297F', - "dfr;": '\U0001D521', - "dharl;": '\U000021C3', - "dharr;": '\U000021C2', - "diam;": '\U000022C4', - "diamond;": '\U000022C4', - "diamondsuit;": '\U00002666', - "diams;": '\U00002666', - "die;": '\U000000A8', - "digamma;": '\U000003DD', - "disin;": '\U000022F2', - "div;": '\U000000F7', - "divide;": '\U000000F7', - "divideontimes;": '\U000022C7', - "divonx;": '\U000022C7', - "djcy;": '\U00000452', - "dlcorn;": '\U0000231E', - "dlcrop;": '\U0000230D', - "dollar;": '\U00000024', - "dopf;": '\U0001D555', - "dot;": '\U000002D9', - "doteq;": '\U00002250', - "doteqdot;": '\U00002251', - "dotminus;": '\U00002238', - "dotplus;": '\U00002214', - "dotsquare;": '\U000022A1', - "doublebarwedge;": '\U00002306', - "downarrow;": '\U00002193', - "downdownarrows;": '\U000021CA', - "downharpoonleft;": '\U000021C3', - "downharpoonright;": '\U000021C2', - "drbkarow;": '\U00002910', - "drcorn;": '\U0000231F', - "drcrop;": '\U0000230C', - "dscr;": '\U0001D4B9', - "dscy;": '\U00000455', - "dsol;": '\U000029F6', - "dstrok;": '\U00000111', - "dtdot;": '\U000022F1', - "dtri;": '\U000025BF', - "dtrif;": '\U000025BE', - "duarr;": '\U000021F5', - "duhar;": '\U0000296F', - "dwangle;": '\U000029A6', - "dzcy;": '\U0000045F', - "dzigrarr;": '\U000027FF', - "eDDot;": '\U00002A77', - "eDot;": '\U00002251', - "eacute;": '\U000000E9', - "easter;": '\U00002A6E', - "ecaron;": '\U0000011B', - "ecir;": '\U00002256', - "ecirc;": '\U000000EA', - "ecolon;": '\U00002255', - "ecy;": '\U0000044D', - "edot;": '\U00000117', - "ee;": '\U00002147', - "efDot;": '\U00002252', - "efr;": '\U0001D522', - "eg;": '\U00002A9A', - "egrave;": '\U000000E8', - "egs;": '\U00002A96', - "egsdot;": '\U00002A98', - "el;": '\U00002A99', - "elinters;": '\U000023E7', - "ell;": '\U00002113', - "els;": '\U00002A95', - "elsdot;": '\U00002A97', - "emacr;": '\U00000113', - "empty;": '\U00002205', - "emptyset;": '\U00002205', - "emptyv;": '\U00002205', - "emsp;": '\U00002003', - "emsp13;": '\U00002004', - "emsp14;": '\U00002005', - "eng;": '\U0000014B', - "ensp;": '\U00002002', - "eogon;": '\U00000119', - "eopf;": '\U0001D556', - "epar;": '\U000022D5', - "eparsl;": '\U000029E3', - "eplus;": '\U00002A71', - "epsi;": '\U000003B5', - "epsilon;": '\U000003B5', - "epsiv;": '\U000003F5', - "eqcirc;": '\U00002256', - "eqcolon;": '\U00002255', - "eqsim;": '\U00002242', - "eqslantgtr;": '\U00002A96', - "eqslantless;": '\U00002A95', - "equals;": '\U0000003D', - "equest;": '\U0000225F', - "equiv;": '\U00002261', - "equivDD;": '\U00002A78', - "eqvparsl;": '\U000029E5', - "erDot;": '\U00002253', - "erarr;": '\U00002971', - "escr;": '\U0000212F', - "esdot;": '\U00002250', - "esim;": '\U00002242', - "eta;": '\U000003B7', - "eth;": '\U000000F0', - "euml;": '\U000000EB', - "euro;": '\U000020AC', - "excl;": '\U00000021', - "exist;": '\U00002203', - "expectation;": '\U00002130', - "exponentiale;": '\U00002147', - "fallingdotseq;": '\U00002252', - "fcy;": '\U00000444', - "female;": '\U00002640', - "ffilig;": '\U0000FB03', - "fflig;": '\U0000FB00', - "ffllig;": '\U0000FB04', - "ffr;": '\U0001D523', - "filig;": '\U0000FB01', - "flat;": '\U0000266D', - "fllig;": '\U0000FB02', - "fltns;": '\U000025B1', - "fnof;": '\U00000192', - "fopf;": '\U0001D557', - "forall;": '\U00002200', - "fork;": '\U000022D4', - "forkv;": '\U00002AD9', - "fpartint;": '\U00002A0D', - "frac12;": '\U000000BD', - "frac13;": '\U00002153', - "frac14;": '\U000000BC', - "frac15;": '\U00002155', - "frac16;": '\U00002159', - "frac18;": '\U0000215B', - "frac23;": '\U00002154', - "frac25;": '\U00002156', - "frac34;": '\U000000BE', - "frac35;": '\U00002157', - "frac38;": '\U0000215C', - "frac45;": '\U00002158', - "frac56;": '\U0000215A', - "frac58;": '\U0000215D', - "frac78;": '\U0000215E', - "frasl;": '\U00002044', - "frown;": '\U00002322', - "fscr;": '\U0001D4BB', - "gE;": '\U00002267', - "gEl;": '\U00002A8C', - "gacute;": '\U000001F5', - "gamma;": '\U000003B3', - "gammad;": '\U000003DD', - "gap;": '\U00002A86', - "gbreve;": '\U0000011F', - "gcirc;": '\U0000011D', - "gcy;": '\U00000433', - "gdot;": '\U00000121', - "ge;": '\U00002265', - "gel;": '\U000022DB', - "geq;": '\U00002265', - "geqq;": '\U00002267', - "geqslant;": '\U00002A7E', - "ges;": '\U00002A7E', - "gescc;": '\U00002AA9', - "gesdot;": '\U00002A80', - "gesdoto;": '\U00002A82', - "gesdotol;": '\U00002A84', - "gesles;": '\U00002A94', - "gfr;": '\U0001D524', - "gg;": '\U0000226B', - "ggg;": '\U000022D9', - "gimel;": '\U00002137', - "gjcy;": '\U00000453', - "gl;": '\U00002277', - "glE;": '\U00002A92', - "gla;": '\U00002AA5', - "glj;": '\U00002AA4', - "gnE;": '\U00002269', - "gnap;": '\U00002A8A', - "gnapprox;": '\U00002A8A', - "gne;": '\U00002A88', - "gneq;": '\U00002A88', - "gneqq;": '\U00002269', - "gnsim;": '\U000022E7', - "gopf;": '\U0001D558', - "grave;": '\U00000060', - "gscr;": '\U0000210A', - "gsim;": '\U00002273', - "gsime;": '\U00002A8E', - "gsiml;": '\U00002A90', - "gt;": '\U0000003E', - "gtcc;": '\U00002AA7', - "gtcir;": '\U00002A7A', - "gtdot;": '\U000022D7', - "gtlPar;": '\U00002995', - "gtquest;": '\U00002A7C', - "gtrapprox;": '\U00002A86', - "gtrarr;": '\U00002978', - "gtrdot;": '\U000022D7', - "gtreqless;": '\U000022DB', - "gtreqqless;": '\U00002A8C', - "gtrless;": '\U00002277', - "gtrsim;": '\U00002273', - "hArr;": '\U000021D4', - "hairsp;": '\U0000200A', - "half;": '\U000000BD', - "hamilt;": '\U0000210B', - "hardcy;": '\U0000044A', - "harr;": '\U00002194', - "harrcir;": '\U00002948', - "harrw;": '\U000021AD', - "hbar;": '\U0000210F', - "hcirc;": '\U00000125', - "hearts;": '\U00002665', - "heartsuit;": '\U00002665', - "hellip;": '\U00002026', - "hercon;": '\U000022B9', - "hfr;": '\U0001D525', - "hksearow;": '\U00002925', - "hkswarow;": '\U00002926', - "hoarr;": '\U000021FF', - "homtht;": '\U0000223B', - "hookleftarrow;": '\U000021A9', - "hookrightarrow;": '\U000021AA', - "hopf;": '\U0001D559', - "horbar;": '\U00002015', - "hscr;": '\U0001D4BD', - "hslash;": '\U0000210F', - "hstrok;": '\U00000127', - "hybull;": '\U00002043', - "hyphen;": '\U00002010', - "iacute;": '\U000000ED', - "ic;": '\U00002063', - "icirc;": '\U000000EE', - "icy;": '\U00000438', - "iecy;": '\U00000435', - "iexcl;": '\U000000A1', - "iff;": '\U000021D4', - "ifr;": '\U0001D526', - "igrave;": '\U000000EC', - "ii;": '\U00002148', - "iiiint;": '\U00002A0C', - "iiint;": '\U0000222D', - "iinfin;": '\U000029DC', - "iiota;": '\U00002129', - "ijlig;": '\U00000133', - "imacr;": '\U0000012B', - "image;": '\U00002111', - "imagline;": '\U00002110', - "imagpart;": '\U00002111', - "imath;": '\U00000131', - "imof;": '\U000022B7', - "imped;": '\U000001B5', - "in;": '\U00002208', - "incare;": '\U00002105', - "infin;": '\U0000221E', - "infintie;": '\U000029DD', - "inodot;": '\U00000131', - "int;": '\U0000222B', - "intcal;": '\U000022BA', - "integers;": '\U00002124', - "intercal;": '\U000022BA', - "intlarhk;": '\U00002A17', - "intprod;": '\U00002A3C', - "iocy;": '\U00000451', - "iogon;": '\U0000012F', - "iopf;": '\U0001D55A', - "iota;": '\U000003B9', - "iprod;": '\U00002A3C', - "iquest;": '\U000000BF', - "iscr;": '\U0001D4BE', - "isin;": '\U00002208', - "isinE;": '\U000022F9', - "isindot;": '\U000022F5', - "isins;": '\U000022F4', - "isinsv;": '\U000022F3', - "isinv;": '\U00002208', - "it;": '\U00002062', - "itilde;": '\U00000129', - "iukcy;": '\U00000456', - "iuml;": '\U000000EF', - "jcirc;": '\U00000135', - "jcy;": '\U00000439', - "jfr;": '\U0001D527', - "jmath;": '\U00000237', - "jopf;": '\U0001D55B', - "jscr;": '\U0001D4BF', - "jsercy;": '\U00000458', - "jukcy;": '\U00000454', - "kappa;": '\U000003BA', - "kappav;": '\U000003F0', - "kcedil;": '\U00000137', - "kcy;": '\U0000043A', - "kfr;": '\U0001D528', - "kgreen;": '\U00000138', - "khcy;": '\U00000445', - "kjcy;": '\U0000045C', - "kopf;": '\U0001D55C', - "kscr;": '\U0001D4C0', - "lAarr;": '\U000021DA', - "lArr;": '\U000021D0', - "lAtail;": '\U0000291B', - "lBarr;": '\U0000290E', - "lE;": '\U00002266', - "lEg;": '\U00002A8B', - "lHar;": '\U00002962', - "lacute;": '\U0000013A', - "laemptyv;": '\U000029B4', - "lagran;": '\U00002112', - "lambda;": '\U000003BB', - "lang;": '\U000027E8', - "langd;": '\U00002991', - "langle;": '\U000027E8', - "lap;": '\U00002A85', - "laquo;": '\U000000AB', - "larr;": '\U00002190', - "larrb;": '\U000021E4', - "larrbfs;": '\U0000291F', - "larrfs;": '\U0000291D', - "larrhk;": '\U000021A9', - "larrlp;": '\U000021AB', - "larrpl;": '\U00002939', - "larrsim;": '\U00002973', - "larrtl;": '\U000021A2', - "lat;": '\U00002AAB', - "latail;": '\U00002919', - "late;": '\U00002AAD', - "lbarr;": '\U0000290C', - "lbbrk;": '\U00002772', - "lbrace;": '\U0000007B', - "lbrack;": '\U0000005B', - "lbrke;": '\U0000298B', - "lbrksld;": '\U0000298F', - "lbrkslu;": '\U0000298D', - "lcaron;": '\U0000013E', - "lcedil;": '\U0000013C', - "lceil;": '\U00002308', - "lcub;": '\U0000007B', - "lcy;": '\U0000043B', - "ldca;": '\U00002936', - "ldquo;": '\U0000201C', - "ldquor;": '\U0000201E', - "ldrdhar;": '\U00002967', - "ldrushar;": '\U0000294B', - "ldsh;": '\U000021B2', - "le;": '\U00002264', - "leftarrow;": '\U00002190', - "leftarrowtail;": '\U000021A2', - "leftharpoondown;": '\U000021BD', - "leftharpoonup;": '\U000021BC', - "leftleftarrows;": '\U000021C7', - "leftrightarrow;": '\U00002194', - "leftrightarrows;": '\U000021C6', - "leftrightharpoons;": '\U000021CB', - "leftrightsquigarrow;": '\U000021AD', - "leftthreetimes;": '\U000022CB', - "leg;": '\U000022DA', - "leq;": '\U00002264', - "leqq;": '\U00002266', - "leqslant;": '\U00002A7D', - "les;": '\U00002A7D', - "lescc;": '\U00002AA8', - "lesdot;": '\U00002A7F', - "lesdoto;": '\U00002A81', - "lesdotor;": '\U00002A83', - "lesges;": '\U00002A93', - "lessapprox;": '\U00002A85', - "lessdot;": '\U000022D6', - "lesseqgtr;": '\U000022DA', - "lesseqqgtr;": '\U00002A8B', - "lessgtr;": '\U00002276', - "lesssim;": '\U00002272', - "lfisht;": '\U0000297C', - "lfloor;": '\U0000230A', - "lfr;": '\U0001D529', - "lg;": '\U00002276', - "lgE;": '\U00002A91', - "lhard;": '\U000021BD', - "lharu;": '\U000021BC', - "lharul;": '\U0000296A', - "lhblk;": '\U00002584', - "ljcy;": '\U00000459', - "ll;": '\U0000226A', - "llarr;": '\U000021C7', - "llcorner;": '\U0000231E', - "llhard;": '\U0000296B', - "lltri;": '\U000025FA', - "lmidot;": '\U00000140', - "lmoust;": '\U000023B0', - "lmoustache;": '\U000023B0', - "lnE;": '\U00002268', - "lnap;": '\U00002A89', - "lnapprox;": '\U00002A89', - "lne;": '\U00002A87', - "lneq;": '\U00002A87', - "lneqq;": '\U00002268', - "lnsim;": '\U000022E6', - "loang;": '\U000027EC', - "loarr;": '\U000021FD', - "lobrk;": '\U000027E6', - "longleftarrow;": '\U000027F5', - "longleftrightarrow;": '\U000027F7', - "longmapsto;": '\U000027FC', - "longrightarrow;": '\U000027F6', - "looparrowleft;": '\U000021AB', - "looparrowright;": '\U000021AC', - "lopar;": '\U00002985', - "lopf;": '\U0001D55D', - "loplus;": '\U00002A2D', - "lotimes;": '\U00002A34', - "lowast;": '\U00002217', - "lowbar;": '\U0000005F', - "loz;": '\U000025CA', - "lozenge;": '\U000025CA', - "lozf;": '\U000029EB', - "lpar;": '\U00000028', - "lparlt;": '\U00002993', - "lrarr;": '\U000021C6', - "lrcorner;": '\U0000231F', - "lrhar;": '\U000021CB', - "lrhard;": '\U0000296D', - "lrm;": '\U0000200E', - "lrtri;": '\U000022BF', - "lsaquo;": '\U00002039', - "lscr;": '\U0001D4C1', - "lsh;": '\U000021B0', - "lsim;": '\U00002272', - "lsime;": '\U00002A8D', - "lsimg;": '\U00002A8F', - "lsqb;": '\U0000005B', - "lsquo;": '\U00002018', - "lsquor;": '\U0000201A', - "lstrok;": '\U00000142', - "lt;": '\U0000003C', - "ltcc;": '\U00002AA6', - "ltcir;": '\U00002A79', - "ltdot;": '\U000022D6', - "lthree;": '\U000022CB', - "ltimes;": '\U000022C9', - "ltlarr;": '\U00002976', - "ltquest;": '\U00002A7B', - "ltrPar;": '\U00002996', - "ltri;": '\U000025C3', - "ltrie;": '\U000022B4', - "ltrif;": '\U000025C2', - "lurdshar;": '\U0000294A', - "luruhar;": '\U00002966', - "mDDot;": '\U0000223A', - "macr;": '\U000000AF', - "male;": '\U00002642', - "malt;": '\U00002720', - "maltese;": '\U00002720', - "map;": '\U000021A6', - "mapsto;": '\U000021A6', - "mapstodown;": '\U000021A7', - "mapstoleft;": '\U000021A4', - "mapstoup;": '\U000021A5', - "marker;": '\U000025AE', - "mcomma;": '\U00002A29', - "mcy;": '\U0000043C', - "mdash;": '\U00002014', - "measuredangle;": '\U00002221', - "mfr;": '\U0001D52A', - "mho;": '\U00002127', - "micro;": '\U000000B5', - "mid;": '\U00002223', - "midast;": '\U0000002A', - "midcir;": '\U00002AF0', - "middot;": '\U000000B7', - "minus;": '\U00002212', - "minusb;": '\U0000229F', - "minusd;": '\U00002238', - "minusdu;": '\U00002A2A', - "mlcp;": '\U00002ADB', - "mldr;": '\U00002026', - "mnplus;": '\U00002213', - "models;": '\U000022A7', - "mopf;": '\U0001D55E', - "mp;": '\U00002213', - "mscr;": '\U0001D4C2', - "mstpos;": '\U0000223E', - "mu;": '\U000003BC', - "multimap;": '\U000022B8', - "mumap;": '\U000022B8', - "nLeftarrow;": '\U000021CD', - "nLeftrightarrow;": '\U000021CE', - "nRightarrow;": '\U000021CF', - "nVDash;": '\U000022AF', - "nVdash;": '\U000022AE', - "nabla;": '\U00002207', - "nacute;": '\U00000144', - "nap;": '\U00002249', - "napos;": '\U00000149', - "napprox;": '\U00002249', - "natur;": '\U0000266E', - "natural;": '\U0000266E', - "naturals;": '\U00002115', - "nbsp;": '\U000000A0', - "ncap;": '\U00002A43', - "ncaron;": '\U00000148', - "ncedil;": '\U00000146', - "ncong;": '\U00002247', - "ncup;": '\U00002A42', - "ncy;": '\U0000043D', - "ndash;": '\U00002013', - "ne;": '\U00002260', - "neArr;": '\U000021D7', - "nearhk;": '\U00002924', - "nearr;": '\U00002197', - "nearrow;": '\U00002197', - "nequiv;": '\U00002262', - "nesear;": '\U00002928', - "nexist;": '\U00002204', - "nexists;": '\U00002204', - "nfr;": '\U0001D52B', - "nge;": '\U00002271', - "ngeq;": '\U00002271', - "ngsim;": '\U00002275', - "ngt;": '\U0000226F', - "ngtr;": '\U0000226F', - "nhArr;": '\U000021CE', - "nharr;": '\U000021AE', - "nhpar;": '\U00002AF2', - "ni;": '\U0000220B', - "nis;": '\U000022FC', - "nisd;": '\U000022FA', - "niv;": '\U0000220B', - "njcy;": '\U0000045A', - "nlArr;": '\U000021CD', - "nlarr;": '\U0000219A', - "nldr;": '\U00002025', - "nle;": '\U00002270', - "nleftarrow;": '\U0000219A', - "nleftrightarrow;": '\U000021AE', - "nleq;": '\U00002270', - "nless;": '\U0000226E', - "nlsim;": '\U00002274', - "nlt;": '\U0000226E', - "nltri;": '\U000022EA', - "nltrie;": '\U000022EC', - "nmid;": '\U00002224', - "nopf;": '\U0001D55F', - "not;": '\U000000AC', - "notin;": '\U00002209', - "notinva;": '\U00002209', - "notinvb;": '\U000022F7', - "notinvc;": '\U000022F6', - "notni;": '\U0000220C', - "notniva;": '\U0000220C', - "notnivb;": '\U000022FE', - "notnivc;": '\U000022FD', - "npar;": '\U00002226', - "nparallel;": '\U00002226', - "npolint;": '\U00002A14', - "npr;": '\U00002280', - "nprcue;": '\U000022E0', - "nprec;": '\U00002280', - "nrArr;": '\U000021CF', - "nrarr;": '\U0000219B', - "nrightarrow;": '\U0000219B', - "nrtri;": '\U000022EB', - "nrtrie;": '\U000022ED', - "nsc;": '\U00002281', - "nsccue;": '\U000022E1', - "nscr;": '\U0001D4C3', - "nshortmid;": '\U00002224', - "nshortparallel;": '\U00002226', - "nsim;": '\U00002241', - "nsime;": '\U00002244', - "nsimeq;": '\U00002244', - "nsmid;": '\U00002224', - "nspar;": '\U00002226', - "nsqsube;": '\U000022E2', - "nsqsupe;": '\U000022E3', - "nsub;": '\U00002284', - "nsube;": '\U00002288', - "nsubseteq;": '\U00002288', - "nsucc;": '\U00002281', - "nsup;": '\U00002285', - "nsupe;": '\U00002289', - "nsupseteq;": '\U00002289', - "ntgl;": '\U00002279', - "ntilde;": '\U000000F1', - "ntlg;": '\U00002278', - "ntriangleleft;": '\U000022EA', - "ntrianglelefteq;": '\U000022EC', - "ntriangleright;": '\U000022EB', - "ntrianglerighteq;": '\U000022ED', - "nu;": '\U000003BD', - "num;": '\U00000023', - "numero;": '\U00002116', - "numsp;": '\U00002007', - "nvDash;": '\U000022AD', - "nvHarr;": '\U00002904', - "nvdash;": '\U000022AC', - "nvinfin;": '\U000029DE', - "nvlArr;": '\U00002902', - "nvrArr;": '\U00002903', - "nwArr;": '\U000021D6', - "nwarhk;": '\U00002923', - "nwarr;": '\U00002196', - "nwarrow;": '\U00002196', - "nwnear;": '\U00002927', - "oS;": '\U000024C8', - "oacute;": '\U000000F3', - "oast;": '\U0000229B', - "ocir;": '\U0000229A', - "ocirc;": '\U000000F4', - "ocy;": '\U0000043E', - "odash;": '\U0000229D', - "odblac;": '\U00000151', - "odiv;": '\U00002A38', - "odot;": '\U00002299', - "odsold;": '\U000029BC', - "oelig;": '\U00000153', - "ofcir;": '\U000029BF', - "ofr;": '\U0001D52C', - "ogon;": '\U000002DB', - "ograve;": '\U000000F2', - "ogt;": '\U000029C1', - "ohbar;": '\U000029B5', - "ohm;": '\U000003A9', - "oint;": '\U0000222E', - "olarr;": '\U000021BA', - "olcir;": '\U000029BE', - "olcross;": '\U000029BB', - "oline;": '\U0000203E', - "olt;": '\U000029C0', - "omacr;": '\U0000014D', - "omega;": '\U000003C9', - "omicron;": '\U000003BF', - "omid;": '\U000029B6', - "ominus;": '\U00002296', - "oopf;": '\U0001D560', - "opar;": '\U000029B7', - "operp;": '\U000029B9', - "oplus;": '\U00002295', - "or;": '\U00002228', - "orarr;": '\U000021BB', - "ord;": '\U00002A5D', - "order;": '\U00002134', - "orderof;": '\U00002134', - "ordf;": '\U000000AA', - "ordm;": '\U000000BA', - "origof;": '\U000022B6', - "oror;": '\U00002A56', - "orslope;": '\U00002A57', - "orv;": '\U00002A5B', - "oscr;": '\U00002134', - "oslash;": '\U000000F8', - "osol;": '\U00002298', - "otilde;": '\U000000F5', - "otimes;": '\U00002297', - "otimesas;": '\U00002A36', - "ouml;": '\U000000F6', - "ovbar;": '\U0000233D', - "par;": '\U00002225', - "para;": '\U000000B6', - "parallel;": '\U00002225', - "parsim;": '\U00002AF3', - "parsl;": '\U00002AFD', - "part;": '\U00002202', - "pcy;": '\U0000043F', - "percnt;": '\U00000025', - "period;": '\U0000002E', - "permil;": '\U00002030', - "perp;": '\U000022A5', - "pertenk;": '\U00002031', - "pfr;": '\U0001D52D', - "phi;": '\U000003C6', - "phiv;": '\U000003D5', - "phmmat;": '\U00002133', - "phone;": '\U0000260E', - "pi;": '\U000003C0', - "pitchfork;": '\U000022D4', - "piv;": '\U000003D6', - "planck;": '\U0000210F', - "planckh;": '\U0000210E', - "plankv;": '\U0000210F', - "plus;": '\U0000002B', - "plusacir;": '\U00002A23', - "plusb;": '\U0000229E', - "pluscir;": '\U00002A22', - "plusdo;": '\U00002214', - "plusdu;": '\U00002A25', - "pluse;": '\U00002A72', - "plusmn;": '\U000000B1', - "plussim;": '\U00002A26', - "plustwo;": '\U00002A27', - "pm;": '\U000000B1', - "pointint;": '\U00002A15', - "popf;": '\U0001D561', - "pound;": '\U000000A3', - "pr;": '\U0000227A', - "prE;": '\U00002AB3', - "prap;": '\U00002AB7', - "prcue;": '\U0000227C', - "pre;": '\U00002AAF', - "prec;": '\U0000227A', - "precapprox;": '\U00002AB7', - "preccurlyeq;": '\U0000227C', - "preceq;": '\U00002AAF', - "precnapprox;": '\U00002AB9', - "precneqq;": '\U00002AB5', - "precnsim;": '\U000022E8', - "precsim;": '\U0000227E', - "prime;": '\U00002032', - "primes;": '\U00002119', - "prnE;": '\U00002AB5', - "prnap;": '\U00002AB9', - "prnsim;": '\U000022E8', - "prod;": '\U0000220F', - "profalar;": '\U0000232E', - "profline;": '\U00002312', - "profsurf;": '\U00002313', - "prop;": '\U0000221D', - "propto;": '\U0000221D', - "prsim;": '\U0000227E', - "prurel;": '\U000022B0', - "pscr;": '\U0001D4C5', - "psi;": '\U000003C8', - "puncsp;": '\U00002008', - "qfr;": '\U0001D52E', - "qint;": '\U00002A0C', - "qopf;": '\U0001D562', - "qprime;": '\U00002057', - "qscr;": '\U0001D4C6', - "quaternions;": '\U0000210D', - "quatint;": '\U00002A16', - "quest;": '\U0000003F', - "questeq;": '\U0000225F', - "quot;": '\U00000022', - "rAarr;": '\U000021DB', - "rArr;": '\U000021D2', - "rAtail;": '\U0000291C', - "rBarr;": '\U0000290F', - "rHar;": '\U00002964', - "racute;": '\U00000155', - "radic;": '\U0000221A', - "raemptyv;": '\U000029B3', - "rang;": '\U000027E9', - "rangd;": '\U00002992', - "range;": '\U000029A5', - "rangle;": '\U000027E9', - "raquo;": '\U000000BB', - "rarr;": '\U00002192', - "rarrap;": '\U00002975', - "rarrb;": '\U000021E5', - "rarrbfs;": '\U00002920', - "rarrc;": '\U00002933', - "rarrfs;": '\U0000291E', - "rarrhk;": '\U000021AA', - "rarrlp;": '\U000021AC', - "rarrpl;": '\U00002945', - "rarrsim;": '\U00002974', - "rarrtl;": '\U000021A3', - "rarrw;": '\U0000219D', - "ratail;": '\U0000291A', - "ratio;": '\U00002236', - "rationals;": '\U0000211A', - "rbarr;": '\U0000290D', - "rbbrk;": '\U00002773', - "rbrace;": '\U0000007D', - "rbrack;": '\U0000005D', - "rbrke;": '\U0000298C', - "rbrksld;": '\U0000298E', - "rbrkslu;": '\U00002990', - "rcaron;": '\U00000159', - "rcedil;": '\U00000157', - "rceil;": '\U00002309', - "rcub;": '\U0000007D', - "rcy;": '\U00000440', - "rdca;": '\U00002937', - "rdldhar;": '\U00002969', - "rdquo;": '\U0000201D', - "rdquor;": '\U0000201D', - "rdsh;": '\U000021B3', - "real;": '\U0000211C', - "realine;": '\U0000211B', - "realpart;": '\U0000211C', - "reals;": '\U0000211D', - "rect;": '\U000025AD', - "reg;": '\U000000AE', - "rfisht;": '\U0000297D', - "rfloor;": '\U0000230B', - "rfr;": '\U0001D52F', - "rhard;": '\U000021C1', - "rharu;": '\U000021C0', - "rharul;": '\U0000296C', - "rho;": '\U000003C1', - "rhov;": '\U000003F1', - "rightarrow;": '\U00002192', - "rightarrowtail;": '\U000021A3', - "rightharpoondown;": '\U000021C1', - "rightharpoonup;": '\U000021C0', - "rightleftarrows;": '\U000021C4', - "rightleftharpoons;": '\U000021CC', - "rightrightarrows;": '\U000021C9', - "rightsquigarrow;": '\U0000219D', - "rightthreetimes;": '\U000022CC', - "ring;": '\U000002DA', - "risingdotseq;": '\U00002253', - "rlarr;": '\U000021C4', - "rlhar;": '\U000021CC', - "rlm;": '\U0000200F', - "rmoust;": '\U000023B1', - "rmoustache;": '\U000023B1', - "rnmid;": '\U00002AEE', - "roang;": '\U000027ED', - "roarr;": '\U000021FE', - "robrk;": '\U000027E7', - "ropar;": '\U00002986', - "ropf;": '\U0001D563', - "roplus;": '\U00002A2E', - "rotimes;": '\U00002A35', - "rpar;": '\U00000029', - "rpargt;": '\U00002994', - "rppolint;": '\U00002A12', - "rrarr;": '\U000021C9', - "rsaquo;": '\U0000203A', - "rscr;": '\U0001D4C7', - "rsh;": '\U000021B1', - "rsqb;": '\U0000005D', - "rsquo;": '\U00002019', - "rsquor;": '\U00002019', - "rthree;": '\U000022CC', - "rtimes;": '\U000022CA', - "rtri;": '\U000025B9', - "rtrie;": '\U000022B5', - "rtrif;": '\U000025B8', - "rtriltri;": '\U000029CE', - "ruluhar;": '\U00002968', - "rx;": '\U0000211E', - "sacute;": '\U0000015B', - "sbquo;": '\U0000201A', - "sc;": '\U0000227B', - "scE;": '\U00002AB4', - "scap;": '\U00002AB8', - "scaron;": '\U00000161', - "sccue;": '\U0000227D', - "sce;": '\U00002AB0', - "scedil;": '\U0000015F', - "scirc;": '\U0000015D', - "scnE;": '\U00002AB6', - "scnap;": '\U00002ABA', - "scnsim;": '\U000022E9', - "scpolint;": '\U00002A13', - "scsim;": '\U0000227F', - "scy;": '\U00000441', - "sdot;": '\U000022C5', - "sdotb;": '\U000022A1', - "sdote;": '\U00002A66', - "seArr;": '\U000021D8', - "searhk;": '\U00002925', - "searr;": '\U00002198', - "searrow;": '\U00002198', - "sect;": '\U000000A7', - "semi;": '\U0000003B', - "seswar;": '\U00002929', - "setminus;": '\U00002216', - "setmn;": '\U00002216', - "sext;": '\U00002736', - "sfr;": '\U0001D530', - "sfrown;": '\U00002322', - "sharp;": '\U0000266F', - "shchcy;": '\U00000449', - "shcy;": '\U00000448', - "shortmid;": '\U00002223', - "shortparallel;": '\U00002225', - "shy;": '\U000000AD', - "sigma;": '\U000003C3', - "sigmaf;": '\U000003C2', - "sigmav;": '\U000003C2', - "sim;": '\U0000223C', - "simdot;": '\U00002A6A', - "sime;": '\U00002243', - "simeq;": '\U00002243', - "simg;": '\U00002A9E', - "simgE;": '\U00002AA0', - "siml;": '\U00002A9D', - "simlE;": '\U00002A9F', - "simne;": '\U00002246', - "simplus;": '\U00002A24', - "simrarr;": '\U00002972', - "slarr;": '\U00002190', - "smallsetminus;": '\U00002216', - "smashp;": '\U00002A33', - "smeparsl;": '\U000029E4', - "smid;": '\U00002223', - "smile;": '\U00002323', - "smt;": '\U00002AAA', - "smte;": '\U00002AAC', - "softcy;": '\U0000044C', - "sol;": '\U0000002F', - "solb;": '\U000029C4', - "solbar;": '\U0000233F', - "sopf;": '\U0001D564', - "spades;": '\U00002660', - "spadesuit;": '\U00002660', - "spar;": '\U00002225', - "sqcap;": '\U00002293', - "sqcup;": '\U00002294', - "sqsub;": '\U0000228F', - "sqsube;": '\U00002291', - "sqsubset;": '\U0000228F', - "sqsubseteq;": '\U00002291', - "sqsup;": '\U00002290', - "sqsupe;": '\U00002292', - "sqsupset;": '\U00002290', - "sqsupseteq;": '\U00002292', - "squ;": '\U000025A1', - "square;": '\U000025A1', - "squarf;": '\U000025AA', - "squf;": '\U000025AA', - "srarr;": '\U00002192', - "sscr;": '\U0001D4C8', - "ssetmn;": '\U00002216', - "ssmile;": '\U00002323', - "sstarf;": '\U000022C6', - "star;": '\U00002606', - "starf;": '\U00002605', - "straightepsilon;": '\U000003F5', - "straightphi;": '\U000003D5', - "strns;": '\U000000AF', - "sub;": '\U00002282', - "subE;": '\U00002AC5', - "subdot;": '\U00002ABD', - "sube;": '\U00002286', - "subedot;": '\U00002AC3', - "submult;": '\U00002AC1', - "subnE;": '\U00002ACB', - "subne;": '\U0000228A', - "subplus;": '\U00002ABF', - "subrarr;": '\U00002979', - "subset;": '\U00002282', - "subseteq;": '\U00002286', - "subseteqq;": '\U00002AC5', - "subsetneq;": '\U0000228A', - "subsetneqq;": '\U00002ACB', - "subsim;": '\U00002AC7', - "subsub;": '\U00002AD5', - "subsup;": '\U00002AD3', - "succ;": '\U0000227B', - "succapprox;": '\U00002AB8', - "succcurlyeq;": '\U0000227D', - "succeq;": '\U00002AB0', - "succnapprox;": '\U00002ABA', - "succneqq;": '\U00002AB6', - "succnsim;": '\U000022E9', - "succsim;": '\U0000227F', - "sum;": '\U00002211', - "sung;": '\U0000266A', - "sup;": '\U00002283', - "sup1;": '\U000000B9', - "sup2;": '\U000000B2', - "sup3;": '\U000000B3', - "supE;": '\U00002AC6', - "supdot;": '\U00002ABE', - "supdsub;": '\U00002AD8', - "supe;": '\U00002287', - "supedot;": '\U00002AC4', - "suphsol;": '\U000027C9', - "suphsub;": '\U00002AD7', - "suplarr;": '\U0000297B', - "supmult;": '\U00002AC2', - "supnE;": '\U00002ACC', - "supne;": '\U0000228B', - "supplus;": '\U00002AC0', - "supset;": '\U00002283', - "supseteq;": '\U00002287', - "supseteqq;": '\U00002AC6', - "supsetneq;": '\U0000228B', - "supsetneqq;": '\U00002ACC', - "supsim;": '\U00002AC8', - "supsub;": '\U00002AD4', - "supsup;": '\U00002AD6', - "swArr;": '\U000021D9', - "swarhk;": '\U00002926', - "swarr;": '\U00002199', - "swarrow;": '\U00002199', - "swnwar;": '\U0000292A', - "szlig;": '\U000000DF', - "target;": '\U00002316', - "tau;": '\U000003C4', - "tbrk;": '\U000023B4', - "tcaron;": '\U00000165', - "tcedil;": '\U00000163', - "tcy;": '\U00000442', - "tdot;": '\U000020DB', - "telrec;": '\U00002315', - "tfr;": '\U0001D531', - "there4;": '\U00002234', - "therefore;": '\U00002234', - "theta;": '\U000003B8', - "thetasym;": '\U000003D1', - "thetav;": '\U000003D1', - "thickapprox;": '\U00002248', - "thicksim;": '\U0000223C', - "thinsp;": '\U00002009', - "thkap;": '\U00002248', - "thksim;": '\U0000223C', - "thorn;": '\U000000FE', - "tilde;": '\U000002DC', - "times;": '\U000000D7', - "timesb;": '\U000022A0', - "timesbar;": '\U00002A31', - "timesd;": '\U00002A30', - "tint;": '\U0000222D', - "toea;": '\U00002928', - "top;": '\U000022A4', - "topbot;": '\U00002336', - "topcir;": '\U00002AF1', - "topf;": '\U0001D565', - "topfork;": '\U00002ADA', - "tosa;": '\U00002929', - "tprime;": '\U00002034', - "trade;": '\U00002122', - "triangle;": '\U000025B5', - "triangledown;": '\U000025BF', - "triangleleft;": '\U000025C3', - "trianglelefteq;": '\U000022B4', - "triangleq;": '\U0000225C', - "triangleright;": '\U000025B9', - "trianglerighteq;": '\U000022B5', - "tridot;": '\U000025EC', - "trie;": '\U0000225C', - "triminus;": '\U00002A3A', - "triplus;": '\U00002A39', - "trisb;": '\U000029CD', - "tritime;": '\U00002A3B', - "trpezium;": '\U000023E2', - "tscr;": '\U0001D4C9', - "tscy;": '\U00000446', - "tshcy;": '\U0000045B', - "tstrok;": '\U00000167', - "twixt;": '\U0000226C', - "twoheadleftarrow;": '\U0000219E', - "twoheadrightarrow;": '\U000021A0', - "uArr;": '\U000021D1', - "uHar;": '\U00002963', - "uacute;": '\U000000FA', - "uarr;": '\U00002191', - "ubrcy;": '\U0000045E', - "ubreve;": '\U0000016D', - "ucirc;": '\U000000FB', - "ucy;": '\U00000443', - "udarr;": '\U000021C5', - "udblac;": '\U00000171', - "udhar;": '\U0000296E', - "ufisht;": '\U0000297E', - "ufr;": '\U0001D532', - "ugrave;": '\U000000F9', - "uharl;": '\U000021BF', - "uharr;": '\U000021BE', - "uhblk;": '\U00002580', - "ulcorn;": '\U0000231C', - "ulcorner;": '\U0000231C', - "ulcrop;": '\U0000230F', - "ultri;": '\U000025F8', - "umacr;": '\U0000016B', - "uml;": '\U000000A8', - "uogon;": '\U00000173', - "uopf;": '\U0001D566', - "uparrow;": '\U00002191', - "updownarrow;": '\U00002195', - "upharpoonleft;": '\U000021BF', - "upharpoonright;": '\U000021BE', - "uplus;": '\U0000228E', - "upsi;": '\U000003C5', - "upsih;": '\U000003D2', - "upsilon;": '\U000003C5', - "upuparrows;": '\U000021C8', - "urcorn;": '\U0000231D', - "urcorner;": '\U0000231D', - "urcrop;": '\U0000230E', - "uring;": '\U0000016F', - "urtri;": '\U000025F9', - "uscr;": '\U0001D4CA', - "utdot;": '\U000022F0', - "utilde;": '\U00000169', - "utri;": '\U000025B5', - "utrif;": '\U000025B4', - "uuarr;": '\U000021C8', - "uuml;": '\U000000FC', - "uwangle;": '\U000029A7', - "vArr;": '\U000021D5', - "vBar;": '\U00002AE8', - "vBarv;": '\U00002AE9', - "vDash;": '\U000022A8', - "vangrt;": '\U0000299C', - "varepsilon;": '\U000003F5', - "varkappa;": '\U000003F0', - "varnothing;": '\U00002205', - "varphi;": '\U000003D5', - "varpi;": '\U000003D6', - "varpropto;": '\U0000221D', - "varr;": '\U00002195', - "varrho;": '\U000003F1', - "varsigma;": '\U000003C2', - "vartheta;": '\U000003D1', - "vartriangleleft;": '\U000022B2', - "vartriangleright;": '\U000022B3', - "vcy;": '\U00000432', - "vdash;": '\U000022A2', - "vee;": '\U00002228', - "veebar;": '\U000022BB', - "veeeq;": '\U0000225A', - "vellip;": '\U000022EE', - "verbar;": '\U0000007C', - "vert;": '\U0000007C', - "vfr;": '\U0001D533', - "vltri;": '\U000022B2', - "vopf;": '\U0001D567', - "vprop;": '\U0000221D', - "vrtri;": '\U000022B3', - "vscr;": '\U0001D4CB', - "vzigzag;": '\U0000299A', - "wcirc;": '\U00000175', - "wedbar;": '\U00002A5F', - "wedge;": '\U00002227', - "wedgeq;": '\U00002259', - "weierp;": '\U00002118', - "wfr;": '\U0001D534', - "wopf;": '\U0001D568', - "wp;": '\U00002118', - "wr;": '\U00002240', - "wreath;": '\U00002240', - "wscr;": '\U0001D4CC', - "xcap;": '\U000022C2', - "xcirc;": '\U000025EF', - "xcup;": '\U000022C3', - "xdtri;": '\U000025BD', - "xfr;": '\U0001D535', - "xhArr;": '\U000027FA', - "xharr;": '\U000027F7', - "xi;": '\U000003BE', - "xlArr;": '\U000027F8', - "xlarr;": '\U000027F5', - "xmap;": '\U000027FC', - "xnis;": '\U000022FB', - "xodot;": '\U00002A00', - "xopf;": '\U0001D569', - "xoplus;": '\U00002A01', - "xotime;": '\U00002A02', - "xrArr;": '\U000027F9', - "xrarr;": '\U000027F6', - "xscr;": '\U0001D4CD', - "xsqcup;": '\U00002A06', - "xuplus;": '\U00002A04', - "xutri;": '\U000025B3', - "xvee;": '\U000022C1', - "xwedge;": '\U000022C0', - "yacute;": '\U000000FD', - "yacy;": '\U0000044F', - "ycirc;": '\U00000177', - "ycy;": '\U0000044B', - "yen;": '\U000000A5', - "yfr;": '\U0001D536', - "yicy;": '\U00000457', - "yopf;": '\U0001D56A', - "yscr;": '\U0001D4CE', - "yucy;": '\U0000044E', - "yuml;": '\U000000FF', - "zacute;": '\U0000017A', - "zcaron;": '\U0000017E', - "zcy;": '\U00000437', - "zdot;": '\U0000017C', - "zeetrf;": '\U00002128', - "zeta;": '\U000003B6', - "zfr;": '\U0001D537', - "zhcy;": '\U00000436', - "zigrarr;": '\U000021DD', - "zopf;": '\U0001D56B', - "zscr;": '\U0001D4CF', - "zwj;": '\U0000200D', - "zwnj;": '\U0000200C', - "AElig": '\U000000C6', - "AMP": '\U00000026', - "Aacute": '\U000000C1', - "Acirc": '\U000000C2', - "Agrave": '\U000000C0', - "Aring": '\U000000C5', - "Atilde": '\U000000C3', - "Auml": '\U000000C4', - "COPY": '\U000000A9', - "Ccedil": '\U000000C7', - "ETH": '\U000000D0', - "Eacute": '\U000000C9', - "Ecirc": '\U000000CA', - "Egrave": '\U000000C8', - "Euml": '\U000000CB', - "GT": '\U0000003E', - "Iacute": '\U000000CD', - "Icirc": '\U000000CE', - "Igrave": '\U000000CC', - "Iuml": '\U000000CF', - "LT": '\U0000003C', - "Ntilde": '\U000000D1', - "Oacute": '\U000000D3', - "Ocirc": '\U000000D4', - "Ograve": '\U000000D2', - "Oslash": '\U000000D8', - "Otilde": '\U000000D5', - "Ouml": '\U000000D6', - "QUOT": '\U00000022', - "REG": '\U000000AE', - "THORN": '\U000000DE', - "Uacute": '\U000000DA', - "Ucirc": '\U000000DB', - "Ugrave": '\U000000D9', - "Uuml": '\U000000DC', - "Yacute": '\U000000DD', - "aacute": '\U000000E1', - "acirc": '\U000000E2', - "acute": '\U000000B4', - "aelig": '\U000000E6', - "agrave": '\U000000E0', - "amp": '\U00000026', - "aring": '\U000000E5', - "atilde": '\U000000E3', - "auml": '\U000000E4', - "brvbar": '\U000000A6', - "ccedil": '\U000000E7', - "cedil": '\U000000B8', - "cent": '\U000000A2', - "copy": '\U000000A9', - "curren": '\U000000A4', - "deg": '\U000000B0', - "divide": '\U000000F7', - "eacute": '\U000000E9', - "ecirc": '\U000000EA', - "egrave": '\U000000E8', - "eth": '\U000000F0', - "euml": '\U000000EB', - "frac12": '\U000000BD', - "frac14": '\U000000BC', - "frac34": '\U000000BE', - "gt": '\U0000003E', - "iacute": '\U000000ED', - "icirc": '\U000000EE', - "iexcl": '\U000000A1', - "igrave": '\U000000EC', - "iquest": '\U000000BF', - "iuml": '\U000000EF', - "laquo": '\U000000AB', - "lt": '\U0000003C', - "macr": '\U000000AF', - "micro": '\U000000B5', - "middot": '\U000000B7', - "nbsp": '\U000000A0', - "not": '\U000000AC', - "ntilde": '\U000000F1', - "oacute": '\U000000F3', - "ocirc": '\U000000F4', - "ograve": '\U000000F2', - "ordf": '\U000000AA', - "ordm": '\U000000BA', - "oslash": '\U000000F8', - "otilde": '\U000000F5', - "ouml": '\U000000F6', - "para": '\U000000B6', - "plusmn": '\U000000B1', - "pound": '\U000000A3', - "quot": '\U00000022', - "raquo": '\U000000BB', - "reg": '\U000000AE', - "sect": '\U000000A7', - "shy": '\U000000AD', - "sup1": '\U000000B9', - "sup2": '\U000000B2', - "sup3": '\U000000B3', - "szlig": '\U000000DF', - "thorn": '\U000000FE', - "times": '\U000000D7', - "uacute": '\U000000FA', - "ucirc": '\U000000FB', - "ugrave": '\U000000F9', - "uml": '\U000000A8', - "uuml": '\U000000FC', - "yacute": '\U000000FD', - "yen": '\U000000A5', - "yuml": '\U000000FF', + "Cross;": '\U00002A2F', + "Cscr;": '\U0001D49E', + "Cup;": '\U000022D3', + "CupCap;": '\U0000224D', + "DD;": '\U00002145', + "DDotrahd;": '\U00002911', + "DJcy;": '\U00000402', + "DScy;": '\U00000405', + "DZcy;": '\U0000040F', + "Dagger;": '\U00002021', + "Darr;": '\U000021A1', + "Dashv;": '\U00002AE4', + "Dcaron;": '\U0000010E', + "Dcy;": '\U00000414', + "Del;": '\U00002207', + "Delta;": '\U00000394', + "Dfr;": '\U0001D507', + "DiacriticalAcute;": '\U000000B4', + "DiacriticalDot;": '\U000002D9', + "DiacriticalDoubleAcute;": '\U000002DD', + "DiacriticalGrave;": '\U00000060', + "DiacriticalTilde;": '\U000002DC', + "Diamond;": '\U000022C4', + "DifferentialD;": '\U00002146', + "Dopf;": '\U0001D53B', + "Dot;": '\U000000A8', + "DotDot;": '\U000020DC', + "DotEqual;": '\U00002250', + "DoubleContourIntegral;": '\U0000222F', + "DoubleDot;": '\U000000A8', + "DoubleDownArrow;": '\U000021D3', + "DoubleLeftArrow;": '\U000021D0', + "DoubleLeftRightArrow;": '\U000021D4', + "DoubleLeftTee;": '\U00002AE4', + "DoubleLongLeftArrow;": '\U000027F8', + "DoubleLongLeftRightArrow;": '\U000027FA', + "DoubleLongRightArrow;": '\U000027F9', + "DoubleRightArrow;": '\U000021D2', + "DoubleRightTee;": '\U000022A8', + "DoubleUpArrow;": '\U000021D1', + "DoubleUpDownArrow;": '\U000021D5', + "DoubleVerticalBar;": '\U00002225', + "DownArrow;": '\U00002193', + "DownArrowBar;": '\U00002913', + "DownArrowUpArrow;": '\U000021F5', + "DownBreve;": '\U00000311', + "DownLeftRightVector;": '\U00002950', + "DownLeftTeeVector;": '\U0000295E', + "DownLeftVector;": '\U000021BD', + "DownLeftVectorBar;": '\U00002956', + "DownRightTeeVector;": '\U0000295F', + "DownRightVector;": '\U000021C1', + "DownRightVectorBar;": '\U00002957', + "DownTee;": '\U000022A4', + "DownTeeArrow;": '\U000021A7', + "Downarrow;": '\U000021D3', + "Dscr;": '\U0001D49F', + "Dstrok;": '\U00000110', + "ENG;": '\U0000014A', + "ETH;": '\U000000D0', + "Eacute;": '\U000000C9', + "Ecaron;": '\U0000011A', + "Ecirc;": '\U000000CA', + "Ecy;": '\U0000042D', + "Edot;": '\U00000116', + "Efr;": '\U0001D508', + "Egrave;": '\U000000C8', + "Element;": '\U00002208', + "Emacr;": '\U00000112', + "EmptySmallSquare;": '\U000025FB', + "EmptyVerySmallSquare;": '\U000025AB', + "Eogon;": '\U00000118', + "Eopf;": '\U0001D53C', + "Epsilon;": '\U00000395', + "Equal;": '\U00002A75', + "EqualTilde;": '\U00002242', + "Equilibrium;": '\U000021CC', + "Escr;": '\U00002130', + "Esim;": '\U00002A73', + "Eta;": '\U00000397', + "Euml;": '\U000000CB', + "Exists;": '\U00002203', + "ExponentialE;": '\U00002147', + "Fcy;": '\U00000424', + "Ffr;": '\U0001D509', + "FilledSmallSquare;": '\U000025FC', + "FilledVerySmallSquare;": '\U000025AA', + "Fopf;": '\U0001D53D', + "ForAll;": '\U00002200', + "Fouriertrf;": '\U00002131', + "Fscr;": '\U00002131', + "GJcy;": '\U00000403', + "GT;": '\U0000003E', + "Gamma;": '\U00000393', + "Gammad;": '\U000003DC', + "Gbreve;": '\U0000011E', + "Gcedil;": '\U00000122', + "Gcirc;": '\U0000011C', + "Gcy;": '\U00000413', + "Gdot;": '\U00000120', + "Gfr;": '\U0001D50A', + "Gg;": '\U000022D9', + "Gopf;": '\U0001D53E', + "GreaterEqual;": '\U00002265', + "GreaterEqualLess;": '\U000022DB', + "GreaterFullEqual;": '\U00002267', + "GreaterGreater;": '\U00002AA2', + "GreaterLess;": '\U00002277', + "GreaterSlantEqual;": '\U00002A7E', + "GreaterTilde;": '\U00002273', + "Gscr;": '\U0001D4A2', + "Gt;": '\U0000226B', + "HARDcy;": '\U0000042A', + "Hacek;": '\U000002C7', + "Hat;": '\U0000005E', + "Hcirc;": '\U00000124', + "Hfr;": '\U0000210C', + "HilbertSpace;": '\U0000210B', + "Hopf;": '\U0000210D', + "HorizontalLine;": '\U00002500', + "Hscr;": '\U0000210B', + "Hstrok;": '\U00000126', + "HumpDownHump;": '\U0000224E', + "HumpEqual;": '\U0000224F', + "IEcy;": '\U00000415', + "IJlig;": '\U00000132', + "IOcy;": '\U00000401', + "Iacute;": '\U000000CD', + "Icirc;": '\U000000CE', + "Icy;": '\U00000418', + "Idot;": '\U00000130', + "Ifr;": '\U00002111', + "Igrave;": '\U000000CC', + "Im;": '\U00002111', + "Imacr;": '\U0000012A', + "ImaginaryI;": '\U00002148', + "Implies;": '\U000021D2', + "Int;": '\U0000222C', + "Integral;": '\U0000222B', + "Intersection;": '\U000022C2', + "InvisibleComma;": '\U00002063', + "InvisibleTimes;": '\U00002062', + "Iogon;": '\U0000012E', + "Iopf;": '\U0001D540', + "Iota;": '\U00000399', + "Iscr;": '\U00002110', + "Itilde;": '\U00000128', + "Iukcy;": '\U00000406', + "Iuml;": '\U000000CF', + "Jcirc;": '\U00000134', + "Jcy;": '\U00000419', + "Jfr;": '\U0001D50D', + "Jopf;": '\U0001D541', + "Jscr;": '\U0001D4A5', + "Jsercy;": '\U00000408', + "Jukcy;": '\U00000404', + "KHcy;": '\U00000425', + "KJcy;": '\U0000040C', + "Kappa;": '\U0000039A', + "Kcedil;": '\U00000136', + "Kcy;": '\U0000041A', + "Kfr;": '\U0001D50E', + "Kopf;": '\U0001D542', + "Kscr;": '\U0001D4A6', + "LJcy;": '\U00000409', + "LT;": '\U0000003C', + "Lacute;": '\U00000139', + "Lambda;": '\U0000039B', + "Lang;": '\U000027EA', + "Laplacetrf;": '\U00002112', + "Larr;": '\U0000219E', + "Lcaron;": '\U0000013D', + "Lcedil;": '\U0000013B', + "Lcy;": '\U0000041B', + "LeftAngleBracket;": '\U000027E8', + "LeftArrow;": '\U00002190', + "LeftArrowBar;": '\U000021E4', + "LeftArrowRightArrow;": '\U000021C6', + "LeftCeiling;": '\U00002308', + "LeftDoubleBracket;": '\U000027E6', + "LeftDownTeeVector;": '\U00002961', + "LeftDownVector;": '\U000021C3', + "LeftDownVectorBar;": '\U00002959', + "LeftFloor;": '\U0000230A', + "LeftRightArrow;": '\U00002194', + "LeftRightVector;": '\U0000294E', + "LeftTee;": '\U000022A3', + "LeftTeeArrow;": '\U000021A4', + "LeftTeeVector;": '\U0000295A', + "LeftTriangle;": '\U000022B2', + "LeftTriangleBar;": '\U000029CF', + "LeftTriangleEqual;": '\U000022B4', + "LeftUpDownVector;": '\U00002951', + "LeftUpTeeVector;": '\U00002960', + "LeftUpVector;": '\U000021BF', + "LeftUpVectorBar;": '\U00002958', + "LeftVector;": '\U000021BC', + "LeftVectorBar;": '\U00002952', + "Leftarrow;": '\U000021D0', + "Leftrightarrow;": '\U000021D4', + "LessEqualGreater;": '\U000022DA', + "LessFullEqual;": '\U00002266', + "LessGreater;": '\U00002276', + "LessLess;": '\U00002AA1', + "LessSlantEqual;": '\U00002A7D', + "LessTilde;": '\U00002272', + "Lfr;": '\U0001D50F', + "Ll;": '\U000022D8', + "Lleftarrow;": '\U000021DA', + "Lmidot;": '\U0000013F', + "LongLeftArrow;": '\U000027F5', + "LongLeftRightArrow;": '\U000027F7', + "LongRightArrow;": '\U000027F6', + "Longleftarrow;": '\U000027F8', + "Longleftrightarrow;": '\U000027FA', + "Longrightarrow;": '\U000027F9', + "Lopf;": '\U0001D543', + "LowerLeftArrow;": '\U00002199', + "LowerRightArrow;": '\U00002198', + "Lscr;": '\U00002112', + "Lsh;": '\U000021B0', + "Lstrok;": '\U00000141', + "Lt;": '\U0000226A', + "Map;": '\U00002905', + "Mcy;": '\U0000041C', + "MediumSpace;": '\U0000205F', + "Mellintrf;": '\U00002133', + "Mfr;": '\U0001D510', + "MinusPlus;": '\U00002213', + "Mopf;": '\U0001D544', + "Mscr;": '\U00002133', + "Mu;": '\U0000039C', + "NJcy;": '\U0000040A', + "Nacute;": '\U00000143', + "Ncaron;": '\U00000147', + "Ncedil;": '\U00000145', + "Ncy;": '\U0000041D', + "NegativeMediumSpace;": '\U0000200B', + "NegativeThickSpace;": '\U0000200B', + "NegativeThinSpace;": '\U0000200B', + "NegativeVeryThinSpace;": '\U0000200B', + "NestedGreaterGreater;": '\U0000226B', + "NestedLessLess;": '\U0000226A', + "NewLine;": '\U0000000A', + "Nfr;": '\U0001D511', + "NoBreak;": '\U00002060', + "NonBreakingSpace;": '\U000000A0', + "Nopf;": '\U00002115', + "Not;": '\U00002AEC', + "NotCongruent;": '\U00002262', + "NotCupCap;": '\U0000226D', + "NotDoubleVerticalBar;": '\U00002226', + "NotElement;": '\U00002209', + "NotEqual;": '\U00002260', + "NotExists;": '\U00002204', + "NotGreater;": '\U0000226F', + "NotGreaterEqual;": '\U00002271', + "NotGreaterLess;": '\U00002279', + "NotGreaterTilde;": '\U00002275', + "NotLeftTriangle;": '\U000022EA', + "NotLeftTriangleEqual;": '\U000022EC', + "NotLess;": '\U0000226E', + "NotLessEqual;": '\U00002270', + "NotLessGreater;": '\U00002278', + "NotLessTilde;": '\U00002274', + "NotPrecedes;": '\U00002280', + "NotPrecedesSlantEqual;": '\U000022E0', + "NotReverseElement;": '\U0000220C', + "NotRightTriangle;": '\U000022EB', + "NotRightTriangleEqual;": '\U000022ED', + "NotSquareSubsetEqual;": '\U000022E2', + "NotSquareSupersetEqual;": '\U000022E3', + "NotSubsetEqual;": '\U00002288', + "NotSucceeds;": '\U00002281', + "NotSucceedsSlantEqual;": '\U000022E1', + "NotSupersetEqual;": '\U00002289', + "NotTilde;": '\U00002241', + "NotTildeEqual;": '\U00002244', + "NotTildeFullEqual;": '\U00002247', + "NotTildeTilde;": '\U00002249', + "NotVerticalBar;": '\U00002224', + "Nscr;": '\U0001D4A9', + "Ntilde;": '\U000000D1', + "Nu;": '\U0000039D', + "OElig;": '\U00000152', + "Oacute;": '\U000000D3', + "Ocirc;": '\U000000D4', + "Ocy;": '\U0000041E', + "Odblac;": '\U00000150', + "Ofr;": '\U0001D512', + "Ograve;": '\U000000D2', + "Omacr;": '\U0000014C', + "Omega;": '\U000003A9', + "Omicron;": '\U0000039F', + "Oopf;": '\U0001D546', + "OpenCurlyDoubleQuote;": '\U0000201C', + "OpenCurlyQuote;": '\U00002018', + "Or;": '\U00002A54', + "Oscr;": '\U0001D4AA', + "Oslash;": '\U000000D8', + "Otilde;": '\U000000D5', + "Otimes;": '\U00002A37', + "Ouml;": '\U000000D6', + "OverBar;": '\U0000203E', + "OverBrace;": '\U000023DE', + "OverBracket;": '\U000023B4', + "OverParenthesis;": '\U000023DC', + "PartialD;": '\U00002202', + "Pcy;": '\U0000041F', + "Pfr;": '\U0001D513', + "Phi;": '\U000003A6', + "Pi;": '\U000003A0', + "PlusMinus;": '\U000000B1', + "Poincareplane;": '\U0000210C', + "Popf;": '\U00002119', + "Pr;": '\U00002ABB', + "Precedes;": '\U0000227A', + "PrecedesEqual;": '\U00002AAF', + "PrecedesSlantEqual;": '\U0000227C', + "PrecedesTilde;": '\U0000227E', + "Prime;": '\U00002033', + "Product;": '\U0000220F', + "Proportion;": '\U00002237', + "Proportional;": '\U0000221D', + "Pscr;": '\U0001D4AB', + "Psi;": '\U000003A8', + "QUOT;": '\U00000022', + "Qfr;": '\U0001D514', + "Qopf;": '\U0000211A', + "Qscr;": '\U0001D4AC', + "RBarr;": '\U00002910', + "REG;": '\U000000AE', + "Racute;": '\U00000154', + "Rang;": '\U000027EB', + "Rarr;": '\U000021A0', + "Rarrtl;": '\U00002916', + "Rcaron;": '\U00000158', + "Rcedil;": '\U00000156', + "Rcy;": '\U00000420', + "Re;": '\U0000211C', + "ReverseElement;": '\U0000220B', + "ReverseEquilibrium;": '\U000021CB', + "ReverseUpEquilibrium;": '\U0000296F', + "Rfr;": '\U0000211C', + "Rho;": '\U000003A1', + "RightAngleBracket;": '\U000027E9', + "RightArrow;": '\U00002192', + "RightArrowBar;": '\U000021E5', + "RightArrowLeftArrow;": '\U000021C4', + "RightCeiling;": '\U00002309', + "RightDoubleBracket;": '\U000027E7', + "RightDownTeeVector;": '\U0000295D', + "RightDownVector;": '\U000021C2', + "RightDownVectorBar;": '\U00002955', + "RightFloor;": '\U0000230B', + "RightTee;": '\U000022A2', + "RightTeeArrow;": '\U000021A6', + "RightTeeVector;": '\U0000295B', + "RightTriangle;": '\U000022B3', + "RightTriangleBar;": '\U000029D0', + "RightTriangleEqual;": '\U000022B5', + "RightUpDownVector;": '\U0000294F', + "RightUpTeeVector;": '\U0000295C', + "RightUpVector;": '\U000021BE', + "RightUpVectorBar;": '\U00002954', + "RightVector;": '\U000021C0', + "RightVectorBar;": '\U00002953', + "Rightarrow;": '\U000021D2', + "Ropf;": '\U0000211D', + "RoundImplies;": '\U00002970', + "Rrightarrow;": '\U000021DB', + "Rscr;": '\U0000211B', + "Rsh;": '\U000021B1', + "RuleDelayed;": '\U000029F4', + "SHCHcy;": '\U00000429', + "SHcy;": '\U00000428', + "SOFTcy;": '\U0000042C', + "Sacute;": '\U0000015A', + "Sc;": '\U00002ABC', + "Scaron;": '\U00000160', + "Scedil;": '\U0000015E', + "Scirc;": '\U0000015C', + "Scy;": '\U00000421', + "Sfr;": '\U0001D516', + "ShortDownArrow;": '\U00002193', + "ShortLeftArrow;": '\U00002190', + "ShortRightArrow;": '\U00002192', + "ShortUpArrow;": '\U00002191', + "Sigma;": '\U000003A3', + "SmallCircle;": '\U00002218', + "Sopf;": '\U0001D54A', + "Sqrt;": '\U0000221A', + "Square;": '\U000025A1', + "SquareIntersection;": '\U00002293', + "SquareSubset;": '\U0000228F', + "SquareSubsetEqual;": '\U00002291', + "SquareSuperset;": '\U00002290', + "SquareSupersetEqual;": '\U00002292', + "SquareUnion;": '\U00002294', + "Sscr;": '\U0001D4AE', + "Star;": '\U000022C6', + "Sub;": '\U000022D0', + "Subset;": '\U000022D0', + "SubsetEqual;": '\U00002286', + "Succeeds;": '\U0000227B', + "SucceedsEqual;": '\U00002AB0', + "SucceedsSlantEqual;": '\U0000227D', + "SucceedsTilde;": '\U0000227F', + "SuchThat;": '\U0000220B', + "Sum;": '\U00002211', + "Sup;": '\U000022D1', + "Superset;": '\U00002283', + "SupersetEqual;": '\U00002287', + "Supset;": '\U000022D1', + "THORN;": '\U000000DE', + "TRADE;": '\U00002122', + "TSHcy;": '\U0000040B', + "TScy;": '\U00000426', + "Tab;": '\U00000009', + "Tau;": '\U000003A4', + "Tcaron;": '\U00000164', + "Tcedil;": '\U00000162', + "Tcy;": '\U00000422', + "Tfr;": '\U0001D517', + "Therefore;": '\U00002234', + "Theta;": '\U00000398', + "ThinSpace;": '\U00002009', + "Tilde;": '\U0000223C', + "TildeEqual;": '\U00002243', + "TildeFullEqual;": '\U00002245', + "TildeTilde;": '\U00002248', + "Topf;": '\U0001D54B', + "TripleDot;": '\U000020DB', + "Tscr;": '\U0001D4AF', + "Tstrok;": '\U00000166', + "Uacute;": '\U000000DA', + "Uarr;": '\U0000219F', + "Uarrocir;": '\U00002949', + "Ubrcy;": '\U0000040E', + "Ubreve;": '\U0000016C', + "Ucirc;": '\U000000DB', + "Ucy;": '\U00000423', + "Udblac;": '\U00000170', + "Ufr;": '\U0001D518', + "Ugrave;": '\U000000D9', + "Umacr;": '\U0000016A', + "UnderBar;": '\U0000005F', + "UnderBrace;": '\U000023DF', + "UnderBracket;": '\U000023B5', + "UnderParenthesis;": '\U000023DD', + "Union;": '\U000022C3', + "UnionPlus;": '\U0000228E', + "Uogon;": '\U00000172', + "Uopf;": '\U0001D54C', + "UpArrow;": '\U00002191', + "UpArrowBar;": '\U00002912', + "UpArrowDownArrow;": '\U000021C5', + "UpDownArrow;": '\U00002195', + "UpEquilibrium;": '\U0000296E', + "UpTee;": '\U000022A5', + "UpTeeArrow;": '\U000021A5', + "Uparrow;": '\U000021D1', + "Updownarrow;": '\U000021D5', + "UpperLeftArrow;": '\U00002196', + "UpperRightArrow;": '\U00002197', + "Upsi;": '\U000003D2', + "Upsilon;": '\U000003A5', + "Uring;": '\U0000016E', + "Uscr;": '\U0001D4B0', + "Utilde;": '\U00000168', + "Uuml;": '\U000000DC', + "VDash;": '\U000022AB', + "Vbar;": '\U00002AEB', + "Vcy;": '\U00000412', + "Vdash;": '\U000022A9', + "Vdashl;": '\U00002AE6', + "Vee;": '\U000022C1', + "Verbar;": '\U00002016', + "Vert;": '\U00002016', + "VerticalBar;": '\U00002223', + "VerticalLine;": '\U0000007C', + "VerticalSeparator;": '\U00002758', + "VerticalTilde;": '\U00002240', + "VeryThinSpace;": '\U0000200A', + "Vfr;": '\U0001D519', + "Vopf;": '\U0001D54D', + "Vscr;": '\U0001D4B1', + "Vvdash;": '\U000022AA', + "Wcirc;": '\U00000174', + "Wedge;": '\U000022C0', + "Wfr;": '\U0001D51A', + "Wopf;": '\U0001D54E', + "Wscr;": '\U0001D4B2', + "Xfr;": '\U0001D51B', + "Xi;": '\U0000039E', + "Xopf;": '\U0001D54F', + "Xscr;": '\U0001D4B3', + "YAcy;": '\U0000042F', + "YIcy;": '\U00000407', + "YUcy;": '\U0000042E', + "Yacute;": '\U000000DD', + "Ycirc;": '\U00000176', + "Ycy;": '\U0000042B', + "Yfr;": '\U0001D51C', + "Yopf;": '\U0001D550', + "Yscr;": '\U0001D4B4', + "Yuml;": '\U00000178', + "ZHcy;": '\U00000416', + "Zacute;": '\U00000179', + "Zcaron;": '\U0000017D', + "Zcy;": '\U00000417', + "Zdot;": '\U0000017B', + "ZeroWidthSpace;": '\U0000200B', + "Zeta;": '\U00000396', + "Zfr;": '\U00002128', + "Zopf;": '\U00002124', + "Zscr;": '\U0001D4B5', + "aacute;": '\U000000E1', + "abreve;": '\U00000103', + "ac;": '\U0000223E', + "acd;": '\U0000223F', + "acirc;": '\U000000E2', + "acute;": '\U000000B4', + "acy;": '\U00000430', + "aelig;": '\U000000E6', + "af;": '\U00002061', + "afr;": '\U0001D51E', + "agrave;": '\U000000E0', + "alefsym;": '\U00002135', + "aleph;": '\U00002135', + "alpha;": '\U000003B1', + "amacr;": '\U00000101', + "amalg;": '\U00002A3F', + "amp;": '\U00000026', + "and;": '\U00002227', + "andand;": '\U00002A55', + "andd;": '\U00002A5C', + "andslope;": '\U00002A58', + "andv;": '\U00002A5A', + "ang;": '\U00002220', + "ange;": '\U000029A4', + "angle;": '\U00002220', + "angmsd;": '\U00002221', + "angmsdaa;": '\U000029A8', + "angmsdab;": '\U000029A9', + "angmsdac;": '\U000029AA', + "angmsdad;": '\U000029AB', + "angmsdae;": '\U000029AC', + "angmsdaf;": '\U000029AD', + "angmsdag;": '\U000029AE', + "angmsdah;": '\U000029AF', + "angrt;": '\U0000221F', + "angrtvb;": '\U000022BE', + "angrtvbd;": '\U0000299D', + "angsph;": '\U00002222', + "angst;": '\U000000C5', + "angzarr;": '\U0000237C', + "aogon;": '\U00000105', + "aopf;": '\U0001D552', + "ap;": '\U00002248', + "apE;": '\U00002A70', + "apacir;": '\U00002A6F', + "ape;": '\U0000224A', + "apid;": '\U0000224B', + "apos;": '\U00000027', + "approx;": '\U00002248', + "approxeq;": '\U0000224A', + "aring;": '\U000000E5', + "ascr;": '\U0001D4B6', + "ast;": '\U0000002A', + "asymp;": '\U00002248', + "asympeq;": '\U0000224D', + "atilde;": '\U000000E3', + "auml;": '\U000000E4', + "awconint;": '\U00002233', + "awint;": '\U00002A11', + "bNot;": '\U00002AED', + "backcong;": '\U0000224C', + "backepsilon;": '\U000003F6', + "backprime;": '\U00002035', + "backsim;": '\U0000223D', + "backsimeq;": '\U000022CD', + "barvee;": '\U000022BD', + "barwed;": '\U00002305', + "barwedge;": '\U00002305', + "bbrk;": '\U000023B5', + "bbrktbrk;": '\U000023B6', + "bcong;": '\U0000224C', + "bcy;": '\U00000431', + "bdquo;": '\U0000201E', + "becaus;": '\U00002235', + "because;": '\U00002235', + "bemptyv;": '\U000029B0', + "bepsi;": '\U000003F6', + "bernou;": '\U0000212C', + "beta;": '\U000003B2', + "beth;": '\U00002136', + "between;": '\U0000226C', + "bfr;": '\U0001D51F', + "bigcap;": '\U000022C2', + "bigcirc;": '\U000025EF', + "bigcup;": '\U000022C3', + "bigodot;": '\U00002A00', + "bigoplus;": '\U00002A01', + "bigotimes;": '\U00002A02', + "bigsqcup;": '\U00002A06', + "bigstar;": '\U00002605', + "bigtriangledown;": '\U000025BD', + "bigtriangleup;": '\U000025B3', + "biguplus;": '\U00002A04', + "bigvee;": '\U000022C1', + "bigwedge;": '\U000022C0', + "bkarow;": '\U0000290D', + "blacklozenge;": '\U000029EB', + "blacksquare;": '\U000025AA', + "blacktriangle;": '\U000025B4', + "blacktriangledown;": '\U000025BE', + "blacktriangleleft;": '\U000025C2', + "blacktriangleright;": '\U000025B8', + "blank;": '\U00002423', + "blk12;": '\U00002592', + "blk14;": '\U00002591', + "blk34;": '\U00002593', + "block;": '\U00002588', + "bnot;": '\U00002310', + "bopf;": '\U0001D553', + "bot;": '\U000022A5', + "bottom;": '\U000022A5', + "bowtie;": '\U000022C8', + "boxDL;": '\U00002557', + "boxDR;": '\U00002554', + "boxDl;": '\U00002556', + "boxDr;": '\U00002553', + "boxH;": '\U00002550', + "boxHD;": '\U00002566', + "boxHU;": '\U00002569', + "boxHd;": '\U00002564', + "boxHu;": '\U00002567', + "boxUL;": '\U0000255D', + "boxUR;": '\U0000255A', + "boxUl;": '\U0000255C', + "boxUr;": '\U00002559', + "boxV;": '\U00002551', + "boxVH;": '\U0000256C', + "boxVL;": '\U00002563', + "boxVR;": '\U00002560', + "boxVh;": '\U0000256B', + "boxVl;": '\U00002562', + "boxVr;": '\U0000255F', + "boxbox;": '\U000029C9', + "boxdL;": '\U00002555', + "boxdR;": '\U00002552', + "boxdl;": '\U00002510', + "boxdr;": '\U0000250C', + "boxh;": '\U00002500', + "boxhD;": '\U00002565', + "boxhU;": '\U00002568', + "boxhd;": '\U0000252C', + "boxhu;": '\U00002534', + "boxminus;": '\U0000229F', + "boxplus;": '\U0000229E', + "boxtimes;": '\U000022A0', + "boxuL;": '\U0000255B', + "boxuR;": '\U00002558', + "boxul;": '\U00002518', + "boxur;": '\U00002514', + "boxv;": '\U00002502', + "boxvH;": '\U0000256A', + "boxvL;": '\U00002561', + "boxvR;": '\U0000255E', + "boxvh;": '\U0000253C', + "boxvl;": '\U00002524', + "boxvr;": '\U0000251C', + "bprime;": '\U00002035', + "breve;": '\U000002D8', + "brvbar;": '\U000000A6', + "bscr;": '\U0001D4B7', + "bsemi;": '\U0000204F', + "bsim;": '\U0000223D', + "bsime;": '\U000022CD', + "bsol;": '\U0000005C', + "bsolb;": '\U000029C5', + "bsolhsub;": '\U000027C8', + "bull;": '\U00002022', + "bullet;": '\U00002022', + "bump;": '\U0000224E', + "bumpE;": '\U00002AAE', + "bumpe;": '\U0000224F', + "bumpeq;": '\U0000224F', + "cacute;": '\U00000107', + "cap;": '\U00002229', + "capand;": '\U00002A44', + "capbrcup;": '\U00002A49', + "capcap;": '\U00002A4B', + "capcup;": '\U00002A47', + "capdot;": '\U00002A40', + "caret;": '\U00002041', + "caron;": '\U000002C7', + "ccaps;": '\U00002A4D', + "ccaron;": '\U0000010D', + "ccedil;": '\U000000E7', + "ccirc;": '\U00000109', + "ccups;": '\U00002A4C', + "ccupssm;": '\U00002A50', + "cdot;": '\U0000010B', + "cedil;": '\U000000B8', + "cemptyv;": '\U000029B2', + "cent;": '\U000000A2', + "centerdot;": '\U000000B7', + "cfr;": '\U0001D520', + "chcy;": '\U00000447', + "check;": '\U00002713', + "checkmark;": '\U00002713', + "chi;": '\U000003C7', + "cir;": '\U000025CB', + "cirE;": '\U000029C3', + "circ;": '\U000002C6', + "circeq;": '\U00002257', + "circlearrowleft;": '\U000021BA', + "circlearrowright;": '\U000021BB', + "circledR;": '\U000000AE', + "circledS;": '\U000024C8', + "circledast;": '\U0000229B', + "circledcirc;": '\U0000229A', + "circleddash;": '\U0000229D', + "cire;": '\U00002257', + "cirfnint;": '\U00002A10', + "cirmid;": '\U00002AEF', + "cirscir;": '\U000029C2', + "clubs;": '\U00002663', + "clubsuit;": '\U00002663', + "colon;": '\U0000003A', + "colone;": '\U00002254', + "coloneq;": '\U00002254', + "comma;": '\U0000002C', + "commat;": '\U00000040', + "comp;": '\U00002201', + "compfn;": '\U00002218', + "complement;": '\U00002201', + "complexes;": '\U00002102', + "cong;": '\U00002245', + "congdot;": '\U00002A6D', + "conint;": '\U0000222E', + "copf;": '\U0001D554', + "coprod;": '\U00002210', + "copy;": '\U000000A9', + "copysr;": '\U00002117', + "crarr;": '\U000021B5', + "cross;": '\U00002717', + "cscr;": '\U0001D4B8', + "csub;": '\U00002ACF', + "csube;": '\U00002AD1', + "csup;": '\U00002AD0', + "csupe;": '\U00002AD2', + "ctdot;": '\U000022EF', + "cudarrl;": '\U00002938', + "cudarrr;": '\U00002935', + "cuepr;": '\U000022DE', + "cuesc;": '\U000022DF', + "cularr;": '\U000021B6', + "cularrp;": '\U0000293D', + "cup;": '\U0000222A', + "cupbrcap;": '\U00002A48', + "cupcap;": '\U00002A46', + "cupcup;": '\U00002A4A', + "cupdot;": '\U0000228D', + "cupor;": '\U00002A45', + "curarr;": '\U000021B7', + "curarrm;": '\U0000293C', + "curlyeqprec;": '\U000022DE', + "curlyeqsucc;": '\U000022DF', + "curlyvee;": '\U000022CE', + "curlywedge;": '\U000022CF', + "curren;": '\U000000A4', + "curvearrowleft;": '\U000021B6', + "curvearrowright;": '\U000021B7', + "cuvee;": '\U000022CE', + "cuwed;": '\U000022CF', + "cwconint;": '\U00002232', + "cwint;": '\U00002231', + "cylcty;": '\U0000232D', + "dArr;": '\U000021D3', + "dHar;": '\U00002965', + "dagger;": '\U00002020', + "daleth;": '\U00002138', + "darr;": '\U00002193', + "dash;": '\U00002010', + "dashv;": '\U000022A3', + "dbkarow;": '\U0000290F', + "dblac;": '\U000002DD', + "dcaron;": '\U0000010F', + "dcy;": '\U00000434', + "dd;": '\U00002146', + "ddagger;": '\U00002021', + "ddarr;": '\U000021CA', + "ddotseq;": '\U00002A77', + "deg;": '\U000000B0', + "delta;": '\U000003B4', + "demptyv;": '\U000029B1', + "dfisht;": '\U0000297F', + "dfr;": '\U0001D521', + "dharl;": '\U000021C3', + "dharr;": '\U000021C2', + "diam;": '\U000022C4', + "diamond;": '\U000022C4', + "diamondsuit;": '\U00002666', + "diams;": '\U00002666', + "die;": '\U000000A8', + "digamma;": '\U000003DD', + "disin;": '\U000022F2', + "div;": '\U000000F7', + "divide;": '\U000000F7', + "divideontimes;": '\U000022C7', + "divonx;": '\U000022C7', + "djcy;": '\U00000452', + "dlcorn;": '\U0000231E', + "dlcrop;": '\U0000230D', + "dollar;": '\U00000024', + "dopf;": '\U0001D555', + "dot;": '\U000002D9', + "doteq;": '\U00002250', + "doteqdot;": '\U00002251', + "dotminus;": '\U00002238', + "dotplus;": '\U00002214', + "dotsquare;": '\U000022A1', + "doublebarwedge;": '\U00002306', + "downarrow;": '\U00002193', + "downdownarrows;": '\U000021CA', + "downharpoonleft;": '\U000021C3', + "downharpoonright;": '\U000021C2', + "drbkarow;": '\U00002910', + "drcorn;": '\U0000231F', + "drcrop;": '\U0000230C', + "dscr;": '\U0001D4B9', + "dscy;": '\U00000455', + "dsol;": '\U000029F6', + "dstrok;": '\U00000111', + "dtdot;": '\U000022F1', + "dtri;": '\U000025BF', + "dtrif;": '\U000025BE', + "duarr;": '\U000021F5', + "duhar;": '\U0000296F', + "dwangle;": '\U000029A6', + "dzcy;": '\U0000045F', + "dzigrarr;": '\U000027FF', + "eDDot;": '\U00002A77', + "eDot;": '\U00002251', + "eacute;": '\U000000E9', + "easter;": '\U00002A6E', + "ecaron;": '\U0000011B', + "ecir;": '\U00002256', + "ecirc;": '\U000000EA', + "ecolon;": '\U00002255', + "ecy;": '\U0000044D', + "edot;": '\U00000117', + "ee;": '\U00002147', + "efDot;": '\U00002252', + "efr;": '\U0001D522', + "eg;": '\U00002A9A', + "egrave;": '\U000000E8', + "egs;": '\U00002A96', + "egsdot;": '\U00002A98', + "el;": '\U00002A99', + "elinters;": '\U000023E7', + "ell;": '\U00002113', + "els;": '\U00002A95', + "elsdot;": '\U00002A97', + "emacr;": '\U00000113', + "empty;": '\U00002205', + "emptyset;": '\U00002205', + "emptyv;": '\U00002205', + "emsp;": '\U00002003', + "emsp13;": '\U00002004', + "emsp14;": '\U00002005', + "eng;": '\U0000014B', + "ensp;": '\U00002002', + "eogon;": '\U00000119', + "eopf;": '\U0001D556', + "epar;": '\U000022D5', + "eparsl;": '\U000029E3', + "eplus;": '\U00002A71', + "epsi;": '\U000003B5', + "epsilon;": '\U000003B5', + "epsiv;": '\U000003F5', + "eqcirc;": '\U00002256', + "eqcolon;": '\U00002255', + "eqsim;": '\U00002242', + "eqslantgtr;": '\U00002A96', + "eqslantless;": '\U00002A95', + "equals;": '\U0000003D', + "equest;": '\U0000225F', + "equiv;": '\U00002261', + "equivDD;": '\U00002A78', + "eqvparsl;": '\U000029E5', + "erDot;": '\U00002253', + "erarr;": '\U00002971', + "escr;": '\U0000212F', + "esdot;": '\U00002250', + "esim;": '\U00002242', + "eta;": '\U000003B7', + "eth;": '\U000000F0', + "euml;": '\U000000EB', + "euro;": '\U000020AC', + "excl;": '\U00000021', + "exist;": '\U00002203', + "expectation;": '\U00002130', + "exponentiale;": '\U00002147', + "fallingdotseq;": '\U00002252', + "fcy;": '\U00000444', + "female;": '\U00002640', + "ffilig;": '\U0000FB03', + "fflig;": '\U0000FB00', + "ffllig;": '\U0000FB04', + "ffr;": '\U0001D523', + "filig;": '\U0000FB01', + "flat;": '\U0000266D', + "fllig;": '\U0000FB02', + "fltns;": '\U000025B1', + "fnof;": '\U00000192', + "fopf;": '\U0001D557', + "forall;": '\U00002200', + "fork;": '\U000022D4', + "forkv;": '\U00002AD9', + "fpartint;": '\U00002A0D', + "frac12;": '\U000000BD', + "frac13;": '\U00002153', + "frac14;": '\U000000BC', + "frac15;": '\U00002155', + "frac16;": '\U00002159', + "frac18;": '\U0000215B', + "frac23;": '\U00002154', + "frac25;": '\U00002156', + "frac34;": '\U000000BE', + "frac35;": '\U00002157', + "frac38;": '\U0000215C', + "frac45;": '\U00002158', + "frac56;": '\U0000215A', + "frac58;": '\U0000215D', + "frac78;": '\U0000215E', + "frasl;": '\U00002044', + "frown;": '\U00002322', + "fscr;": '\U0001D4BB', + "gE;": '\U00002267', + "gEl;": '\U00002A8C', + "gacute;": '\U000001F5', + "gamma;": '\U000003B3', + "gammad;": '\U000003DD', + "gap;": '\U00002A86', + "gbreve;": '\U0000011F', + "gcirc;": '\U0000011D', + "gcy;": '\U00000433', + "gdot;": '\U00000121', + "ge;": '\U00002265', + "gel;": '\U000022DB', + "geq;": '\U00002265', + "geqq;": '\U00002267', + "geqslant;": '\U00002A7E', + "ges;": '\U00002A7E', + "gescc;": '\U00002AA9', + "gesdot;": '\U00002A80', + "gesdoto;": '\U00002A82', + "gesdotol;": '\U00002A84', + "gesles;": '\U00002A94', + "gfr;": '\U0001D524', + "gg;": '\U0000226B', + "ggg;": '\U000022D9', + "gimel;": '\U00002137', + "gjcy;": '\U00000453', + "gl;": '\U00002277', + "glE;": '\U00002A92', + "gla;": '\U00002AA5', + "glj;": '\U00002AA4', + "gnE;": '\U00002269', + "gnap;": '\U00002A8A', + "gnapprox;": '\U00002A8A', + "gne;": '\U00002A88', + "gneq;": '\U00002A88', + "gneqq;": '\U00002269', + "gnsim;": '\U000022E7', + "gopf;": '\U0001D558', + "grave;": '\U00000060', + "gscr;": '\U0000210A', + "gsim;": '\U00002273', + "gsime;": '\U00002A8E', + "gsiml;": '\U00002A90', + "gt;": '\U0000003E', + "gtcc;": '\U00002AA7', + "gtcir;": '\U00002A7A', + "gtdot;": '\U000022D7', + "gtlPar;": '\U00002995', + "gtquest;": '\U00002A7C', + "gtrapprox;": '\U00002A86', + "gtrarr;": '\U00002978', + "gtrdot;": '\U000022D7', + "gtreqless;": '\U000022DB', + "gtreqqless;": '\U00002A8C', + "gtrless;": '\U00002277', + "gtrsim;": '\U00002273', + "hArr;": '\U000021D4', + "hairsp;": '\U0000200A', + "half;": '\U000000BD', + "hamilt;": '\U0000210B', + "hardcy;": '\U0000044A', + "harr;": '\U00002194', + "harrcir;": '\U00002948', + "harrw;": '\U000021AD', + "hbar;": '\U0000210F', + "hcirc;": '\U00000125', + "hearts;": '\U00002665', + "heartsuit;": '\U00002665', + "hellip;": '\U00002026', + "hercon;": '\U000022B9', + "hfr;": '\U0001D525', + "hksearow;": '\U00002925', + "hkswarow;": '\U00002926', + "hoarr;": '\U000021FF', + "homtht;": '\U0000223B', + "hookleftarrow;": '\U000021A9', + "hookrightarrow;": '\U000021AA', + "hopf;": '\U0001D559', + "horbar;": '\U00002015', + "hscr;": '\U0001D4BD', + "hslash;": '\U0000210F', + "hstrok;": '\U00000127', + "hybull;": '\U00002043', + "hyphen;": '\U00002010', + "iacute;": '\U000000ED', + "ic;": '\U00002063', + "icirc;": '\U000000EE', + "icy;": '\U00000438', + "iecy;": '\U00000435', + "iexcl;": '\U000000A1', + "iff;": '\U000021D4', + "ifr;": '\U0001D526', + "igrave;": '\U000000EC', + "ii;": '\U00002148', + "iiiint;": '\U00002A0C', + "iiint;": '\U0000222D', + "iinfin;": '\U000029DC', + "iiota;": '\U00002129', + "ijlig;": '\U00000133', + "imacr;": '\U0000012B', + "image;": '\U00002111', + "imagline;": '\U00002110', + "imagpart;": '\U00002111', + "imath;": '\U00000131', + "imof;": '\U000022B7', + "imped;": '\U000001B5', + "in;": '\U00002208', + "incare;": '\U00002105', + "infin;": '\U0000221E', + "infintie;": '\U000029DD', + "inodot;": '\U00000131', + "int;": '\U0000222B', + "intcal;": '\U000022BA', + "integers;": '\U00002124', + "intercal;": '\U000022BA', + "intlarhk;": '\U00002A17', + "intprod;": '\U00002A3C', + "iocy;": '\U00000451', + "iogon;": '\U0000012F', + "iopf;": '\U0001D55A', + "iota;": '\U000003B9', + "iprod;": '\U00002A3C', + "iquest;": '\U000000BF', + "iscr;": '\U0001D4BE', + "isin;": '\U00002208', + "isinE;": '\U000022F9', + "isindot;": '\U000022F5', + "isins;": '\U000022F4', + "isinsv;": '\U000022F3', + "isinv;": '\U00002208', + "it;": '\U00002062', + "itilde;": '\U00000129', + "iukcy;": '\U00000456', + "iuml;": '\U000000EF', + "jcirc;": '\U00000135', + "jcy;": '\U00000439', + "jfr;": '\U0001D527', + "jmath;": '\U00000237', + "jopf;": '\U0001D55B', + "jscr;": '\U0001D4BF', + "jsercy;": '\U00000458', + "jukcy;": '\U00000454', + "kappa;": '\U000003BA', + "kappav;": '\U000003F0', + "kcedil;": '\U00000137', + "kcy;": '\U0000043A', + "kfr;": '\U0001D528', + "kgreen;": '\U00000138', + "khcy;": '\U00000445', + "kjcy;": '\U0000045C', + "kopf;": '\U0001D55C', + "kscr;": '\U0001D4C0', + "lAarr;": '\U000021DA', + "lArr;": '\U000021D0', + "lAtail;": '\U0000291B', + "lBarr;": '\U0000290E', + "lE;": '\U00002266', + "lEg;": '\U00002A8B', + "lHar;": '\U00002962', + "lacute;": '\U0000013A', + "laemptyv;": '\U000029B4', + "lagran;": '\U00002112', + "lambda;": '\U000003BB', + "lang;": '\U000027E8', + "langd;": '\U00002991', + "langle;": '\U000027E8', + "lap;": '\U00002A85', + "laquo;": '\U000000AB', + "larr;": '\U00002190', + "larrb;": '\U000021E4', + "larrbfs;": '\U0000291F', + "larrfs;": '\U0000291D', + "larrhk;": '\U000021A9', + "larrlp;": '\U000021AB', + "larrpl;": '\U00002939', + "larrsim;": '\U00002973', + "larrtl;": '\U000021A2', + "lat;": '\U00002AAB', + "latail;": '\U00002919', + "late;": '\U00002AAD', + "lbarr;": '\U0000290C', + "lbbrk;": '\U00002772', + "lbrace;": '\U0000007B', + "lbrack;": '\U0000005B', + "lbrke;": '\U0000298B', + "lbrksld;": '\U0000298F', + "lbrkslu;": '\U0000298D', + "lcaron;": '\U0000013E', + "lcedil;": '\U0000013C', + "lceil;": '\U00002308', + "lcub;": '\U0000007B', + "lcy;": '\U0000043B', + "ldca;": '\U00002936', + "ldquo;": '\U0000201C', + "ldquor;": '\U0000201E', + "ldrdhar;": '\U00002967', + "ldrushar;": '\U0000294B', + "ldsh;": '\U000021B2', + "le;": '\U00002264', + "leftarrow;": '\U00002190', + "leftarrowtail;": '\U000021A2', + "leftharpoondown;": '\U000021BD', + "leftharpoonup;": '\U000021BC', + "leftleftarrows;": '\U000021C7', + "leftrightarrow;": '\U00002194', + "leftrightarrows;": '\U000021C6', + "leftrightharpoons;": '\U000021CB', + "leftrightsquigarrow;": '\U000021AD', + "leftthreetimes;": '\U000022CB', + "leg;": '\U000022DA', + "leq;": '\U00002264', + "leqq;": '\U00002266', + "leqslant;": '\U00002A7D', + "les;": '\U00002A7D', + "lescc;": '\U00002AA8', + "lesdot;": '\U00002A7F', + "lesdoto;": '\U00002A81', + "lesdotor;": '\U00002A83', + "lesges;": '\U00002A93', + "lessapprox;": '\U00002A85', + "lessdot;": '\U000022D6', + "lesseqgtr;": '\U000022DA', + "lesseqqgtr;": '\U00002A8B', + "lessgtr;": '\U00002276', + "lesssim;": '\U00002272', + "lfisht;": '\U0000297C', + "lfloor;": '\U0000230A', + "lfr;": '\U0001D529', + "lg;": '\U00002276', + "lgE;": '\U00002A91', + "lhard;": '\U000021BD', + "lharu;": '\U000021BC', + "lharul;": '\U0000296A', + "lhblk;": '\U00002584', + "ljcy;": '\U00000459', + "ll;": '\U0000226A', + "llarr;": '\U000021C7', + "llcorner;": '\U0000231E', + "llhard;": '\U0000296B', + "lltri;": '\U000025FA', + "lmidot;": '\U00000140', + "lmoust;": '\U000023B0', + "lmoustache;": '\U000023B0', + "lnE;": '\U00002268', + "lnap;": '\U00002A89', + "lnapprox;": '\U00002A89', + "lne;": '\U00002A87', + "lneq;": '\U00002A87', + "lneqq;": '\U00002268', + "lnsim;": '\U000022E6', + "loang;": '\U000027EC', + "loarr;": '\U000021FD', + "lobrk;": '\U000027E6', + "longleftarrow;": '\U000027F5', + "longleftrightarrow;": '\U000027F7', + "longmapsto;": '\U000027FC', + "longrightarrow;": '\U000027F6', + "looparrowleft;": '\U000021AB', + "looparrowright;": '\U000021AC', + "lopar;": '\U00002985', + "lopf;": '\U0001D55D', + "loplus;": '\U00002A2D', + "lotimes;": '\U00002A34', + "lowast;": '\U00002217', + "lowbar;": '\U0000005F', + "loz;": '\U000025CA', + "lozenge;": '\U000025CA', + "lozf;": '\U000029EB', + "lpar;": '\U00000028', + "lparlt;": '\U00002993', + "lrarr;": '\U000021C6', + "lrcorner;": '\U0000231F', + "lrhar;": '\U000021CB', + "lrhard;": '\U0000296D', + "lrm;": '\U0000200E', + "lrtri;": '\U000022BF', + "lsaquo;": '\U00002039', + "lscr;": '\U0001D4C1', + "lsh;": '\U000021B0', + "lsim;": '\U00002272', + "lsime;": '\U00002A8D', + "lsimg;": '\U00002A8F', + "lsqb;": '\U0000005B', + "lsquo;": '\U00002018', + "lsquor;": '\U0000201A', + "lstrok;": '\U00000142', + "lt;": '\U0000003C', + "ltcc;": '\U00002AA6', + "ltcir;": '\U00002A79', + "ltdot;": '\U000022D6', + "lthree;": '\U000022CB', + "ltimes;": '\U000022C9', + "ltlarr;": '\U00002976', + "ltquest;": '\U00002A7B', + "ltrPar;": '\U00002996', + "ltri;": '\U000025C3', + "ltrie;": '\U000022B4', + "ltrif;": '\U000025C2', + "lurdshar;": '\U0000294A', + "luruhar;": '\U00002966', + "mDDot;": '\U0000223A', + "macr;": '\U000000AF', + "male;": '\U00002642', + "malt;": '\U00002720', + "maltese;": '\U00002720', + "map;": '\U000021A6', + "mapsto;": '\U000021A6', + "mapstodown;": '\U000021A7', + "mapstoleft;": '\U000021A4', + "mapstoup;": '\U000021A5', + "marker;": '\U000025AE', + "mcomma;": '\U00002A29', + "mcy;": '\U0000043C', + "mdash;": '\U00002014', + "measuredangle;": '\U00002221', + "mfr;": '\U0001D52A', + "mho;": '\U00002127', + "micro;": '\U000000B5', + "mid;": '\U00002223', + "midast;": '\U0000002A', + "midcir;": '\U00002AF0', + "middot;": '\U000000B7', + "minus;": '\U00002212', + "minusb;": '\U0000229F', + "minusd;": '\U00002238', + "minusdu;": '\U00002A2A', + "mlcp;": '\U00002ADB', + "mldr;": '\U00002026', + "mnplus;": '\U00002213', + "models;": '\U000022A7', + "mopf;": '\U0001D55E', + "mp;": '\U00002213', + "mscr;": '\U0001D4C2', + "mstpos;": '\U0000223E', + "mu;": '\U000003BC', + "multimap;": '\U000022B8', + "mumap;": '\U000022B8', + "nLeftarrow;": '\U000021CD', + "nLeftrightarrow;": '\U000021CE', + "nRightarrow;": '\U000021CF', + "nVDash;": '\U000022AF', + "nVdash;": '\U000022AE', + "nabla;": '\U00002207', + "nacute;": '\U00000144', + "nap;": '\U00002249', + "napos;": '\U00000149', + "napprox;": '\U00002249', + "natur;": '\U0000266E', + "natural;": '\U0000266E', + "naturals;": '\U00002115', + "nbsp;": '\U000000A0', + "ncap;": '\U00002A43', + "ncaron;": '\U00000148', + "ncedil;": '\U00000146', + "ncong;": '\U00002247', + "ncup;": '\U00002A42', + "ncy;": '\U0000043D', + "ndash;": '\U00002013', + "ne;": '\U00002260', + "neArr;": '\U000021D7', + "nearhk;": '\U00002924', + "nearr;": '\U00002197', + "nearrow;": '\U00002197', + "nequiv;": '\U00002262', + "nesear;": '\U00002928', + "nexist;": '\U00002204', + "nexists;": '\U00002204', + "nfr;": '\U0001D52B', + "nge;": '\U00002271', + "ngeq;": '\U00002271', + "ngsim;": '\U00002275', + "ngt;": '\U0000226F', + "ngtr;": '\U0000226F', + "nhArr;": '\U000021CE', + "nharr;": '\U000021AE', + "nhpar;": '\U00002AF2', + "ni;": '\U0000220B', + "nis;": '\U000022FC', + "nisd;": '\U000022FA', + "niv;": '\U0000220B', + "njcy;": '\U0000045A', + "nlArr;": '\U000021CD', + "nlarr;": '\U0000219A', + "nldr;": '\U00002025', + "nle;": '\U00002270', + "nleftarrow;": '\U0000219A', + "nleftrightarrow;": '\U000021AE', + "nleq;": '\U00002270', + "nless;": '\U0000226E', + "nlsim;": '\U00002274', + "nlt;": '\U0000226E', + "nltri;": '\U000022EA', + "nltrie;": '\U000022EC', + "nmid;": '\U00002224', + "nopf;": '\U0001D55F', + "not;": '\U000000AC', + "notin;": '\U00002209', + "notinva;": '\U00002209', + "notinvb;": '\U000022F7', + "notinvc;": '\U000022F6', + "notni;": '\U0000220C', + "notniva;": '\U0000220C', + "notnivb;": '\U000022FE', + "notnivc;": '\U000022FD', + "npar;": '\U00002226', + "nparallel;": '\U00002226', + "npolint;": '\U00002A14', + "npr;": '\U00002280', + "nprcue;": '\U000022E0', + "nprec;": '\U00002280', + "nrArr;": '\U000021CF', + "nrarr;": '\U0000219B', + "nrightarrow;": '\U0000219B', + "nrtri;": '\U000022EB', + "nrtrie;": '\U000022ED', + "nsc;": '\U00002281', + "nsccue;": '\U000022E1', + "nscr;": '\U0001D4C3', + "nshortmid;": '\U00002224', + "nshortparallel;": '\U00002226', + "nsim;": '\U00002241', + "nsime;": '\U00002244', + "nsimeq;": '\U00002244', + "nsmid;": '\U00002224', + "nspar;": '\U00002226', + "nsqsube;": '\U000022E2', + "nsqsupe;": '\U000022E3', + "nsub;": '\U00002284', + "nsube;": '\U00002288', + "nsubseteq;": '\U00002288', + "nsucc;": '\U00002281', + "nsup;": '\U00002285', + "nsupe;": '\U00002289', + "nsupseteq;": '\U00002289', + "ntgl;": '\U00002279', + "ntilde;": '\U000000F1', + "ntlg;": '\U00002278', + "ntriangleleft;": '\U000022EA', + "ntrianglelefteq;": '\U000022EC', + "ntriangleright;": '\U000022EB', + "ntrianglerighteq;": '\U000022ED', + "nu;": '\U000003BD', + "num;": '\U00000023', + "numero;": '\U00002116', + "numsp;": '\U00002007', + "nvDash;": '\U000022AD', + "nvHarr;": '\U00002904', + "nvdash;": '\U000022AC', + "nvinfin;": '\U000029DE', + "nvlArr;": '\U00002902', + "nvrArr;": '\U00002903', + "nwArr;": '\U000021D6', + "nwarhk;": '\U00002923', + "nwarr;": '\U00002196', + "nwarrow;": '\U00002196', + "nwnear;": '\U00002927', + "oS;": '\U000024C8', + "oacute;": '\U000000F3', + "oast;": '\U0000229B', + "ocir;": '\U0000229A', + "ocirc;": '\U000000F4', + "ocy;": '\U0000043E', + "odash;": '\U0000229D', + "odblac;": '\U00000151', + "odiv;": '\U00002A38', + "odot;": '\U00002299', + "odsold;": '\U000029BC', + "oelig;": '\U00000153', + "ofcir;": '\U000029BF', + "ofr;": '\U0001D52C', + "ogon;": '\U000002DB', + "ograve;": '\U000000F2', + "ogt;": '\U000029C1', + "ohbar;": '\U000029B5', + "ohm;": '\U000003A9', + "oint;": '\U0000222E', + "olarr;": '\U000021BA', + "olcir;": '\U000029BE', + "olcross;": '\U000029BB', + "oline;": '\U0000203E', + "olt;": '\U000029C0', + "omacr;": '\U0000014D', + "omega;": '\U000003C9', + "omicron;": '\U000003BF', + "omid;": '\U000029B6', + "ominus;": '\U00002296', + "oopf;": '\U0001D560', + "opar;": '\U000029B7', + "operp;": '\U000029B9', + "oplus;": '\U00002295', + "or;": '\U00002228', + "orarr;": '\U000021BB', + "ord;": '\U00002A5D', + "order;": '\U00002134', + "orderof;": '\U00002134', + "ordf;": '\U000000AA', + "ordm;": '\U000000BA', + "origof;": '\U000022B6', + "oror;": '\U00002A56', + "orslope;": '\U00002A57', + "orv;": '\U00002A5B', + "oscr;": '\U00002134', + "oslash;": '\U000000F8', + "osol;": '\U00002298', + "otilde;": '\U000000F5', + "otimes;": '\U00002297', + "otimesas;": '\U00002A36', + "ouml;": '\U000000F6', + "ovbar;": '\U0000233D', + "par;": '\U00002225', + "para;": '\U000000B6', + "parallel;": '\U00002225', + "parsim;": '\U00002AF3', + "parsl;": '\U00002AFD', + "part;": '\U00002202', + "pcy;": '\U0000043F', + "percnt;": '\U00000025', + "period;": '\U0000002E', + "permil;": '\U00002030', + "perp;": '\U000022A5', + "pertenk;": '\U00002031', + "pfr;": '\U0001D52D', + "phi;": '\U000003C6', + "phiv;": '\U000003D5', + "phmmat;": '\U00002133', + "phone;": '\U0000260E', + "pi;": '\U000003C0', + "pitchfork;": '\U000022D4', + "piv;": '\U000003D6', + "planck;": '\U0000210F', + "planckh;": '\U0000210E', + "plankv;": '\U0000210F', + "plus;": '\U0000002B', + "plusacir;": '\U00002A23', + "plusb;": '\U0000229E', + "pluscir;": '\U00002A22', + "plusdo;": '\U00002214', + "plusdu;": '\U00002A25', + "pluse;": '\U00002A72', + "plusmn;": '\U000000B1', + "plussim;": '\U00002A26', + "plustwo;": '\U00002A27', + "pm;": '\U000000B1', + "pointint;": '\U00002A15', + "popf;": '\U0001D561', + "pound;": '\U000000A3', + "pr;": '\U0000227A', + "prE;": '\U00002AB3', + "prap;": '\U00002AB7', + "prcue;": '\U0000227C', + "pre;": '\U00002AAF', + "prec;": '\U0000227A', + "precapprox;": '\U00002AB7', + "preccurlyeq;": '\U0000227C', + "preceq;": '\U00002AAF', + "precnapprox;": '\U00002AB9', + "precneqq;": '\U00002AB5', + "precnsim;": '\U000022E8', + "precsim;": '\U0000227E', + "prime;": '\U00002032', + "primes;": '\U00002119', + "prnE;": '\U00002AB5', + "prnap;": '\U00002AB9', + "prnsim;": '\U000022E8', + "prod;": '\U0000220F', + "profalar;": '\U0000232E', + "profline;": '\U00002312', + "profsurf;": '\U00002313', + "prop;": '\U0000221D', + "propto;": '\U0000221D', + "prsim;": '\U0000227E', + "prurel;": '\U000022B0', + "pscr;": '\U0001D4C5', + "psi;": '\U000003C8', + "puncsp;": '\U00002008', + "qfr;": '\U0001D52E', + "qint;": '\U00002A0C', + "qopf;": '\U0001D562', + "qprime;": '\U00002057', + "qscr;": '\U0001D4C6', + "quaternions;": '\U0000210D', + "quatint;": '\U00002A16', + "quest;": '\U0000003F', + "questeq;": '\U0000225F', + "quot;": '\U00000022', + "rAarr;": '\U000021DB', + "rArr;": '\U000021D2', + "rAtail;": '\U0000291C', + "rBarr;": '\U0000290F', + "rHar;": '\U00002964', + "racute;": '\U00000155', + "radic;": '\U0000221A', + "raemptyv;": '\U000029B3', + "rang;": '\U000027E9', + "rangd;": '\U00002992', + "range;": '\U000029A5', + "rangle;": '\U000027E9', + "raquo;": '\U000000BB', + "rarr;": '\U00002192', + "rarrap;": '\U00002975', + "rarrb;": '\U000021E5', + "rarrbfs;": '\U00002920', + "rarrc;": '\U00002933', + "rarrfs;": '\U0000291E', + "rarrhk;": '\U000021AA', + "rarrlp;": '\U000021AC', + "rarrpl;": '\U00002945', + "rarrsim;": '\U00002974', + "rarrtl;": '\U000021A3', + "rarrw;": '\U0000219D', + "ratail;": '\U0000291A', + "ratio;": '\U00002236', + "rationals;": '\U0000211A', + "rbarr;": '\U0000290D', + "rbbrk;": '\U00002773', + "rbrace;": '\U0000007D', + "rbrack;": '\U0000005D', + "rbrke;": '\U0000298C', + "rbrksld;": '\U0000298E', + "rbrkslu;": '\U00002990', + "rcaron;": '\U00000159', + "rcedil;": '\U00000157', + "rceil;": '\U00002309', + "rcub;": '\U0000007D', + "rcy;": '\U00000440', + "rdca;": '\U00002937', + "rdldhar;": '\U00002969', + "rdquo;": '\U0000201D', + "rdquor;": '\U0000201D', + "rdsh;": '\U000021B3', + "real;": '\U0000211C', + "realine;": '\U0000211B', + "realpart;": '\U0000211C', + "reals;": '\U0000211D', + "rect;": '\U000025AD', + "reg;": '\U000000AE', + "rfisht;": '\U0000297D', + "rfloor;": '\U0000230B', + "rfr;": '\U0001D52F', + "rhard;": '\U000021C1', + "rharu;": '\U000021C0', + "rharul;": '\U0000296C', + "rho;": '\U000003C1', + "rhov;": '\U000003F1', + "rightarrow;": '\U00002192', + "rightarrowtail;": '\U000021A3', + "rightharpoondown;": '\U000021C1', + "rightharpoonup;": '\U000021C0', + "rightleftarrows;": '\U000021C4', + "rightleftharpoons;": '\U000021CC', + "rightrightarrows;": '\U000021C9', + "rightsquigarrow;": '\U0000219D', + "rightthreetimes;": '\U000022CC', + "ring;": '\U000002DA', + "risingdotseq;": '\U00002253', + "rlarr;": '\U000021C4', + "rlhar;": '\U000021CC', + "rlm;": '\U0000200F', + "rmoust;": '\U000023B1', + "rmoustache;": '\U000023B1', + "rnmid;": '\U00002AEE', + "roang;": '\U000027ED', + "roarr;": '\U000021FE', + "robrk;": '\U000027E7', + "ropar;": '\U00002986', + "ropf;": '\U0001D563', + "roplus;": '\U00002A2E', + "rotimes;": '\U00002A35', + "rpar;": '\U00000029', + "rpargt;": '\U00002994', + "rppolint;": '\U00002A12', + "rrarr;": '\U000021C9', + "rsaquo;": '\U0000203A', + "rscr;": '\U0001D4C7', + "rsh;": '\U000021B1', + "rsqb;": '\U0000005D', + "rsquo;": '\U00002019', + "rsquor;": '\U00002019', + "rthree;": '\U000022CC', + "rtimes;": '\U000022CA', + "rtri;": '\U000025B9', + "rtrie;": '\U000022B5', + "rtrif;": '\U000025B8', + "rtriltri;": '\U000029CE', + "ruluhar;": '\U00002968', + "rx;": '\U0000211E', + "sacute;": '\U0000015B', + "sbquo;": '\U0000201A', + "sc;": '\U0000227B', + "scE;": '\U00002AB4', + "scap;": '\U00002AB8', + "scaron;": '\U00000161', + "sccue;": '\U0000227D', + "sce;": '\U00002AB0', + "scedil;": '\U0000015F', + "scirc;": '\U0000015D', + "scnE;": '\U00002AB6', + "scnap;": '\U00002ABA', + "scnsim;": '\U000022E9', + "scpolint;": '\U00002A13', + "scsim;": '\U0000227F', + "scy;": '\U00000441', + "sdot;": '\U000022C5', + "sdotb;": '\U000022A1', + "sdote;": '\U00002A66', + "seArr;": '\U000021D8', + "searhk;": '\U00002925', + "searr;": '\U00002198', + "searrow;": '\U00002198', + "sect;": '\U000000A7', + "semi;": '\U0000003B', + "seswar;": '\U00002929', + "setminus;": '\U00002216', + "setmn;": '\U00002216', + "sext;": '\U00002736', + "sfr;": '\U0001D530', + "sfrown;": '\U00002322', + "sharp;": '\U0000266F', + "shchcy;": '\U00000449', + "shcy;": '\U00000448', + "shortmid;": '\U00002223', + "shortparallel;": '\U00002225', + "shy;": '\U000000AD', + "sigma;": '\U000003C3', + "sigmaf;": '\U000003C2', + "sigmav;": '\U000003C2', + "sim;": '\U0000223C', + "simdot;": '\U00002A6A', + "sime;": '\U00002243', + "simeq;": '\U00002243', + "simg;": '\U00002A9E', + "simgE;": '\U00002AA0', + "siml;": '\U00002A9D', + "simlE;": '\U00002A9F', + "simne;": '\U00002246', + "simplus;": '\U00002A24', + "simrarr;": '\U00002972', + "slarr;": '\U00002190', + "smallsetminus;": '\U00002216', + "smashp;": '\U00002A33', + "smeparsl;": '\U000029E4', + "smid;": '\U00002223', + "smile;": '\U00002323', + "smt;": '\U00002AAA', + "smte;": '\U00002AAC', + "softcy;": '\U0000044C', + "sol;": '\U0000002F', + "solb;": '\U000029C4', + "solbar;": '\U0000233F', + "sopf;": '\U0001D564', + "spades;": '\U00002660', + "spadesuit;": '\U00002660', + "spar;": '\U00002225', + "sqcap;": '\U00002293', + "sqcup;": '\U00002294', + "sqsub;": '\U0000228F', + "sqsube;": '\U00002291', + "sqsubset;": '\U0000228F', + "sqsubseteq;": '\U00002291', + "sqsup;": '\U00002290', + "sqsupe;": '\U00002292', + "sqsupset;": '\U00002290', + "sqsupseteq;": '\U00002292', + "squ;": '\U000025A1', + "square;": '\U000025A1', + "squarf;": '\U000025AA', + "squf;": '\U000025AA', + "srarr;": '\U00002192', + "sscr;": '\U0001D4C8', + "ssetmn;": '\U00002216', + "ssmile;": '\U00002323', + "sstarf;": '\U000022C6', + "star;": '\U00002606', + "starf;": '\U00002605', + "straightepsilon;": '\U000003F5', + "straightphi;": '\U000003D5', + "strns;": '\U000000AF', + "sub;": '\U00002282', + "subE;": '\U00002AC5', + "subdot;": '\U00002ABD', + "sube;": '\U00002286', + "subedot;": '\U00002AC3', + "submult;": '\U00002AC1', + "subnE;": '\U00002ACB', + "subne;": '\U0000228A', + "subplus;": '\U00002ABF', + "subrarr;": '\U00002979', + "subset;": '\U00002282', + "subseteq;": '\U00002286', + "subseteqq;": '\U00002AC5', + "subsetneq;": '\U0000228A', + "subsetneqq;": '\U00002ACB', + "subsim;": '\U00002AC7', + "subsub;": '\U00002AD5', + "subsup;": '\U00002AD3', + "succ;": '\U0000227B', + "succapprox;": '\U00002AB8', + "succcurlyeq;": '\U0000227D', + "succeq;": '\U00002AB0', + "succnapprox;": '\U00002ABA', + "succneqq;": '\U00002AB6', + "succnsim;": '\U000022E9', + "succsim;": '\U0000227F', + "sum;": '\U00002211', + "sung;": '\U0000266A', + "sup;": '\U00002283', + "sup1;": '\U000000B9', + "sup2;": '\U000000B2', + "sup3;": '\U000000B3', + "supE;": '\U00002AC6', + "supdot;": '\U00002ABE', + "supdsub;": '\U00002AD8', + "supe;": '\U00002287', + "supedot;": '\U00002AC4', + "suphsol;": '\U000027C9', + "suphsub;": '\U00002AD7', + "suplarr;": '\U0000297B', + "supmult;": '\U00002AC2', + "supnE;": '\U00002ACC', + "supne;": '\U0000228B', + "supplus;": '\U00002AC0', + "supset;": '\U00002283', + "supseteq;": '\U00002287', + "supseteqq;": '\U00002AC6', + "supsetneq;": '\U0000228B', + "supsetneqq;": '\U00002ACC', + "supsim;": '\U00002AC8', + "supsub;": '\U00002AD4', + "supsup;": '\U00002AD6', + "swArr;": '\U000021D9', + "swarhk;": '\U00002926', + "swarr;": '\U00002199', + "swarrow;": '\U00002199', + "swnwar;": '\U0000292A', + "szlig;": '\U000000DF', + "target;": '\U00002316', + "tau;": '\U000003C4', + "tbrk;": '\U000023B4', + "tcaron;": '\U00000165', + "tcedil;": '\U00000163', + "tcy;": '\U00000442', + "tdot;": '\U000020DB', + "telrec;": '\U00002315', + "tfr;": '\U0001D531', + "there4;": '\U00002234', + "therefore;": '\U00002234', + "theta;": '\U000003B8', + "thetasym;": '\U000003D1', + "thetav;": '\U000003D1', + "thickapprox;": '\U00002248', + "thicksim;": '\U0000223C', + "thinsp;": '\U00002009', + "thkap;": '\U00002248', + "thksim;": '\U0000223C', + "thorn;": '\U000000FE', + "tilde;": '\U000002DC', + "times;": '\U000000D7', + "timesb;": '\U000022A0', + "timesbar;": '\U00002A31', + "timesd;": '\U00002A30', + "tint;": '\U0000222D', + "toea;": '\U00002928', + "top;": '\U000022A4', + "topbot;": '\U00002336', + "topcir;": '\U00002AF1', + "topf;": '\U0001D565', + "topfork;": '\U00002ADA', + "tosa;": '\U00002929', + "tprime;": '\U00002034', + "trade;": '\U00002122', + "triangle;": '\U000025B5', + "triangledown;": '\U000025BF', + "triangleleft;": '\U000025C3', + "trianglelefteq;": '\U000022B4', + "triangleq;": '\U0000225C', + "triangleright;": '\U000025B9', + "trianglerighteq;": '\U000022B5', + "tridot;": '\U000025EC', + "trie;": '\U0000225C', + "triminus;": '\U00002A3A', + "triplus;": '\U00002A39', + "trisb;": '\U000029CD', + "tritime;": '\U00002A3B', + "trpezium;": '\U000023E2', + "tscr;": '\U0001D4C9', + "tscy;": '\U00000446', + "tshcy;": '\U0000045B', + "tstrok;": '\U00000167', + "twixt;": '\U0000226C', + "twoheadleftarrow;": '\U0000219E', + "twoheadrightarrow;": '\U000021A0', + "uArr;": '\U000021D1', + "uHar;": '\U00002963', + "uacute;": '\U000000FA', + "uarr;": '\U00002191', + "ubrcy;": '\U0000045E', + "ubreve;": '\U0000016D', + "ucirc;": '\U000000FB', + "ucy;": '\U00000443', + "udarr;": '\U000021C5', + "udblac;": '\U00000171', + "udhar;": '\U0000296E', + "ufisht;": '\U0000297E', + "ufr;": '\U0001D532', + "ugrave;": '\U000000F9', + "uharl;": '\U000021BF', + "uharr;": '\U000021BE', + "uhblk;": '\U00002580', + "ulcorn;": '\U0000231C', + "ulcorner;": '\U0000231C', + "ulcrop;": '\U0000230F', + "ultri;": '\U000025F8', + "umacr;": '\U0000016B', + "uml;": '\U000000A8', + "uogon;": '\U00000173', + "uopf;": '\U0001D566', + "uparrow;": '\U00002191', + "updownarrow;": '\U00002195', + "upharpoonleft;": '\U000021BF', + "upharpoonright;": '\U000021BE', + "uplus;": '\U0000228E', + "upsi;": '\U000003C5', + "upsih;": '\U000003D2', + "upsilon;": '\U000003C5', + "upuparrows;": '\U000021C8', + "urcorn;": '\U0000231D', + "urcorner;": '\U0000231D', + "urcrop;": '\U0000230E', + "uring;": '\U0000016F', + "urtri;": '\U000025F9', + "uscr;": '\U0001D4CA', + "utdot;": '\U000022F0', + "utilde;": '\U00000169', + "utri;": '\U000025B5', + "utrif;": '\U000025B4', + "uuarr;": '\U000021C8', + "uuml;": '\U000000FC', + "uwangle;": '\U000029A7', + "vArr;": '\U000021D5', + "vBar;": '\U00002AE8', + "vBarv;": '\U00002AE9', + "vDash;": '\U000022A8', + "vangrt;": '\U0000299C', + "varepsilon;": '\U000003F5', + "varkappa;": '\U000003F0', + "varnothing;": '\U00002205', + "varphi;": '\U000003D5', + "varpi;": '\U000003D6', + "varpropto;": '\U0000221D', + "varr;": '\U00002195', + "varrho;": '\U000003F1', + "varsigma;": '\U000003C2', + "vartheta;": '\U000003D1', + "vartriangleleft;": '\U000022B2', + "vartriangleright;": '\U000022B3', + "vcy;": '\U00000432', + "vdash;": '\U000022A2', + "vee;": '\U00002228', + "veebar;": '\U000022BB', + "veeeq;": '\U0000225A', + "vellip;": '\U000022EE', + "verbar;": '\U0000007C', + "vert;": '\U0000007C', + "vfr;": '\U0001D533', + "vltri;": '\U000022B2', + "vopf;": '\U0001D567', + "vprop;": '\U0000221D', + "vrtri;": '\U000022B3', + "vscr;": '\U0001D4CB', + "vzigzag;": '\U0000299A', + "wcirc;": '\U00000175', + "wedbar;": '\U00002A5F', + "wedge;": '\U00002227', + "wedgeq;": '\U00002259', + "weierp;": '\U00002118', + "wfr;": '\U0001D534', + "wopf;": '\U0001D568', + "wp;": '\U00002118', + "wr;": '\U00002240', + "wreath;": '\U00002240', + "wscr;": '\U0001D4CC', + "xcap;": '\U000022C2', + "xcirc;": '\U000025EF', + "xcup;": '\U000022C3', + "xdtri;": '\U000025BD', + "xfr;": '\U0001D535', + "xhArr;": '\U000027FA', + "xharr;": '\U000027F7', + "xi;": '\U000003BE', + "xlArr;": '\U000027F8', + "xlarr;": '\U000027F5', + "xmap;": '\U000027FC', + "xnis;": '\U000022FB', + "xodot;": '\U00002A00', + "xopf;": '\U0001D569', + "xoplus;": '\U00002A01', + "xotime;": '\U00002A02', + "xrArr;": '\U000027F9', + "xrarr;": '\U000027F6', + "xscr;": '\U0001D4CD', + "xsqcup;": '\U00002A06', + "xuplus;": '\U00002A04', + "xutri;": '\U000025B3', + "xvee;": '\U000022C1', + "xwedge;": '\U000022C0', + "yacute;": '\U000000FD', + "yacy;": '\U0000044F', + "ycirc;": '\U00000177', + "ycy;": '\U0000044B', + "yen;": '\U000000A5', + "yfr;": '\U0001D536', + "yicy;": '\U00000457', + "yopf;": '\U0001D56A', + "yscr;": '\U0001D4CE', + "yucy;": '\U0000044E', + "yuml;": '\U000000FF', + "zacute;": '\U0000017A', + "zcaron;": '\U0000017E', + "zcy;": '\U00000437', + "zdot;": '\U0000017C', + "zeetrf;": '\U00002128', + "zeta;": '\U000003B6', + "zfr;": '\U0001D537', + "zhcy;": '\U00000436', + "zigrarr;": '\U000021DD', + "zopf;": '\U0001D56B', + "zscr;": '\U0001D4CF', + "zwj;": '\U0000200D', + "zwnj;": '\U0000200C', + "AElig": '\U000000C6', + "AMP": '\U00000026', + "Aacute": '\U000000C1', + "Acirc": '\U000000C2', + "Agrave": '\U000000C0', + "Aring": '\U000000C5', + "Atilde": '\U000000C3', + "Auml": '\U000000C4', + "COPY": '\U000000A9', + "Ccedil": '\U000000C7', + "ETH": '\U000000D0', + "Eacute": '\U000000C9', + "Ecirc": '\U000000CA', + "Egrave": '\U000000C8', + "Euml": '\U000000CB', + "GT": '\U0000003E', + "Iacute": '\U000000CD', + "Icirc": '\U000000CE', + "Igrave": '\U000000CC', + "Iuml": '\U000000CF', + "LT": '\U0000003C', + "Ntilde": '\U000000D1', + "Oacute": '\U000000D3', + "Ocirc": '\U000000D4', + "Ograve": '\U000000D2', + "Oslash": '\U000000D8', + "Otilde": '\U000000D5', + "Ouml": '\U000000D6', + "QUOT": '\U00000022', + "REG": '\U000000AE', + "THORN": '\U000000DE', + "Uacute": '\U000000DA', + "Ucirc": '\U000000DB', + "Ugrave": '\U000000D9', + "Uuml": '\U000000DC', + "Yacute": '\U000000DD', + "aacute": '\U000000E1', + "acirc": '\U000000E2', + "acute": '\U000000B4', + "aelig": '\U000000E6', + "agrave": '\U000000E0', + "amp": '\U00000026', + "aring": '\U000000E5', + "atilde": '\U000000E3', + "auml": '\U000000E4', + "brvbar": '\U000000A6', + "ccedil": '\U000000E7', + "cedil": '\U000000B8', + "cent": '\U000000A2', + "copy": '\U000000A9', + "curren": '\U000000A4', + "deg": '\U000000B0', + "divide": '\U000000F7', + "eacute": '\U000000E9', + "ecirc": '\U000000EA', + "egrave": '\U000000E8', + "eth": '\U000000F0', + "euml": '\U000000EB', + "frac12": '\U000000BD', + "frac14": '\U000000BC', + "frac34": '\U000000BE', + "gt": '\U0000003E', + "iacute": '\U000000ED', + "icirc": '\U000000EE', + "iexcl": '\U000000A1', + "igrave": '\U000000EC', + "iquest": '\U000000BF', + "iuml": '\U000000EF', + "laquo": '\U000000AB', + "lt": '\U0000003C', + "macr": '\U000000AF', + "micro": '\U000000B5', + "middot": '\U000000B7', + "nbsp": '\U000000A0', + "not": '\U000000AC', + "ntilde": '\U000000F1', + "oacute": '\U000000F3', + "ocirc": '\U000000F4', + "ograve": '\U000000F2', + "ordf": '\U000000AA', + "ordm": '\U000000BA', + "oslash": '\U000000F8', + "otilde": '\U000000F5', + "ouml": '\U000000F6', + "para": '\U000000B6', + "plusmn": '\U000000B1', + "pound": '\U000000A3', + "quot": '\U00000022', + "raquo": '\U000000BB', + "reg": '\U000000AE', + "sect": '\U000000A7', + "shy": '\U000000AD', + "sup1": '\U000000B9', + "sup2": '\U000000B2', + "sup3": '\U000000B3', + "szlig": '\U000000DF', + "thorn": '\U000000FE', + "times": '\U000000D7', + "uacute": '\U000000FA', + "ucirc": '\U000000FB', + "ugrave": '\U000000F9', + "uml": '\U000000A8', + "uuml": '\U000000FC', + "yacute": '\U000000FD', + "yen": '\U000000A5', + "yuml": '\U000000FF', } // HTML entities that are two unicode codepoints. diff --git a/libgo/go/exp/html/escape.go b/libgo/go/exp/html/escape.go index 8f62a8c..7827dc2 100644 --- a/libgo/go/exp/html/escape.go +++ b/libgo/go/exp/html/escape.go @@ -163,14 +163,15 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { } // unescape unescapes b's entities in-place, so that "a<b" becomes "a<b". -func unescape(b []byte) []byte { +// attribute should be true if parsing an attribute value. +func unescape(b []byte, attribute bool) []byte { for i, c := range b { if c == '&' { - dst, src := unescapeEntity(b, i, i, false) + dst, src := unescapeEntity(b, i, i, attribute) for src < len(b) { c := b[src] if c == '&' { - dst, src = unescapeEntity(b, dst, src, false) + dst, src = unescapeEntity(b, dst, src, attribute) } else { b[dst] = c dst, src = dst+1, src+1 @@ -192,7 +193,7 @@ func lower(b []byte) []byte { return b } -const escapedChars = `&'<>"` +const escapedChars = "&'<>\"\r" func escape(w writer, s string) error { i := strings.IndexAny(s, escapedChars) @@ -205,13 +206,17 @@ func escape(w writer, s string) error { case '&': esc = "&" case '\'': - esc = "'" + // "'" is shorter than "'" and apos was not in HTML until HTML5. + esc = "'" case '<': esc = "<" case '>': esc = ">" case '"': - esc = """ + // """ is shorter than """. + esc = """ + case '\r': + esc = " " default: panic("unrecognized escape character") } @@ -226,7 +231,7 @@ func escape(w writer, s string) error { } // EscapeString escapes special characters like "<" to become "<". It -// escapes only five such characters: amp, apos, lt, gt and quot. +// escapes only five such characters: <, >, &, ' and ". // UnescapeString(EscapeString(s)) == s always holds, but the converse isn't // always true. func EscapeString(s string) string { @@ -246,7 +251,7 @@ func EscapeString(s string) string { func UnescapeString(s string) string { for _, c := range s { if c == '&' { - return string(unescape([]byte(s))) + return string(unescape([]byte(s), false)) } } return s diff --git a/libgo/go/exp/html/foreign.go b/libgo/go/exp/html/foreign.go index 3ba81ce..d3b3844 100644 --- a/libgo/go/exp/html/foreign.go +++ b/libgo/go/exp/html/foreign.go @@ -8,6 +8,14 @@ import ( "strings" ) +func adjustAttributeNames(aa []Attribute, nameMap map[string]string) { + for i := range aa { + if newName, ok := nameMap[aa[i].Key]; ok { + aa[i].Key = newName + } + } +} + func adjustForeignAttributes(aa []Attribute) { for i, a := range aa { if a.Key == "" || a.Key[0] != 'x' { @@ -29,8 +37,16 @@ func htmlIntegrationPoint(n *Node) bool { } switch n.Namespace { case "math": - // TODO: annotation-xml elements whose start tags have "text/html" or - // "application/xhtml+xml" encodings. + if n.Data == "annotation-xml" { + for _, a := range n.Attr { + if a.Key == "encoding" { + val := strings.ToLower(a.Val) + if val == "text/html" || val == "application/xhtml+xml" { + return true + } + } + } + } case "svg": switch n.Data { case "desc", "foreignObject", "title": @@ -40,6 +56,17 @@ func htmlIntegrationPoint(n *Node) bool { return false } +func mathMLTextIntegrationPoint(n *Node) bool { + if n.Namespace != "math" { + return false + } + switch n.Data { + case "mi", "mo", "mn", "ms", "mtext": + return true + } + return false +} + // Section 12.2.5.5. var breakout = map[string]bool{ "b": true, @@ -55,7 +82,6 @@ var breakout = map[string]bool{ "dt": true, "em": true, "embed": true, - "font": true, "h1": true, "h2": true, "h3": true, @@ -129,4 +155,72 @@ var svgTagNameAdjustments = map[string]string{ "textpath": "textPath", } -// TODO: add look-up tables for MathML and SVG attribute adjustments. +// Section 12.2.5.1 +var mathMLAttributeAdjustments = map[string]string{ + "definitionurl": "definitionURL", +} + +var svgAttributeAdjustments = map[string]string{ + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan", +} diff --git a/libgo/go/exp/html/node.go b/libgo/go/exp/html/node.go index c105a4e..01f8c42 100644 --- a/libgo/go/exp/html/node.go +++ b/libgo/go/exp/html/node.go @@ -4,8 +4,12 @@ package html +import ( + "exp/html/atom" +) + // A NodeType is the type of a Node. -type NodeType int +type NodeType uint32 const ( ErrorNode NodeType = iota @@ -25,67 +29,115 @@ var scopeMarker = Node{Type: scopeMarkerNode} // A Node consists of a NodeType and some Data (tag name for element nodes, // content for text) and are part of a tree of Nodes. Element nodes may also // have a Namespace and contain a slice of Attributes. Data is unescaped, so -// that it looks like "a<b" rather than "a<b". +// that it looks like "a<b" rather than "a<b". For element nodes, DataAtom +// is the atom for Data, or zero if Data is not a known tag name. // // An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace. // Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and // "svg" is short for "http://www.w3.org/2000/svg". type Node struct { - Parent *Node - Child []*Node + Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node + Type NodeType + DataAtom atom.Atom Data string Namespace string Attr []Attribute } -// Add adds a node as a child of n. -// It will panic if the child's parent is not nil. -func (n *Node) Add(child *Node) { - if child.Parent != nil { - panic("html: Node.Add called for a child Node that already has a parent") +// InsertBefore inserts newChild as a child of n, immediately before oldChild +// in the sequence of n's children. oldChild may be nil, in which case newChild +// is appended to the end of n's children. +// +// It will panic if newChild already has a parent or siblings. +func (n *Node) InsertBefore(newChild, oldChild *Node) { + if newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil { + panic("html: InsertBefore called for an attached child Node") + } + var prev, next *Node + if oldChild != nil { + prev, next = oldChild.PrevSibling, oldChild + } else { + prev = n.LastChild + } + if prev != nil { + prev.NextSibling = newChild + } else { + n.FirstChild = newChild + } + if next != nil { + next.PrevSibling = newChild + } else { + n.LastChild = newChild } - child.Parent = n - n.Child = append(n.Child, child) + newChild.Parent = n + newChild.PrevSibling = prev + newChild.NextSibling = next } -// Remove removes a node as a child of n. -// It will panic if the child's parent is not n. -func (n *Node) Remove(child *Node) { - if child.Parent == n { - child.Parent = nil - for i, m := range n.Child { - if m == child { - copy(n.Child[i:], n.Child[i+1:]) - j := len(n.Child) - 1 - n.Child[j] = nil - n.Child = n.Child[:j] - return - } - } +// AppendChild adds a node c as a child of n. +// +// It will panic if c already has a parent or siblings. +func (n *Node) AppendChild(c *Node) { + if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil { + panic("html: AppendChild called for an attached child Node") + } + last := n.LastChild + if last != nil { + last.NextSibling = c + } else { + n.FirstChild = c } - panic("html: Node.Remove called for a non-child Node") + n.LastChild = c + c.Parent = n + c.PrevSibling = last +} + +// RemoveChild removes a node c that is a child of n. Afterwards, c will have +// no parent and no siblings. +// +// It will panic if c's parent is not n. +func (n *Node) RemoveChild(c *Node) { + if c.Parent != n { + panic("html: RemoveChild called for a non-child Node") + } + if n.FirstChild == c { + n.FirstChild = c.NextSibling + } + if c.NextSibling != nil { + c.NextSibling.PrevSibling = c.PrevSibling + } + if n.LastChild == c { + n.LastChild = c.PrevSibling + } + if c.PrevSibling != nil { + c.PrevSibling.NextSibling = c.NextSibling + } + c.Parent = nil + c.PrevSibling = nil + c.NextSibling = nil } // reparentChildren reparents all of src's child nodes to dst. func reparentChildren(dst, src *Node) { - for _, n := range src.Child { - if n.Parent != src { - panic("html: nodes have an inconsistent parent/child relationship") + for { + child := src.FirstChild + if child == nil { + break } - n.Parent = dst + src.RemoveChild(child) + dst.AppendChild(child) } - dst.Child = append(dst.Child, src.Child...) - src.Child = nil } // clone returns a new node with the same type, data and attributes. -// The clone has no parent and no children. +// The clone has no parent, no siblings and no children. func (n *Node) clone() *Node { m := &Node{ - Type: n.Type, - Data: n.Data, - Attr: make([]Attribute, len(n.Attr)), + Type: n.Type, + DataAtom: n.DataAtom, + Data: n.Data, + Attr: make([]Attribute, len(n.Attr)), } copy(m.Attr, n.Attr) return m @@ -139,16 +191,3 @@ func (s *nodeStack) remove(n *Node) { (*s)[j] = nil *s = (*s)[:j] } - -// TODO(nigeltao): forTag no longer used. Should it be deleted? - -// forTag returns the top-most element node with the given tag. -func (s *nodeStack) forTag(tag string) *Node { - for i := len(*s) - 1; i >= 0; i-- { - n := (*s)[i] - if n.Type == ElementNode && n.Data == tag { - return n - } - } - return nil -} diff --git a/libgo/go/exp/html/node_test.go b/libgo/go/exp/html/node_test.go new file mode 100644 index 0000000..471102f --- /dev/null +++ b/libgo/go/exp/html/node_test.go @@ -0,0 +1,146 @@ +// Copyright 2010 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 html + +import ( + "fmt" +) + +// checkTreeConsistency checks that a node and its descendants are all +// consistent in their parent/child/sibling relationships. +func checkTreeConsistency(n *Node) error { + return checkTreeConsistency1(n, 0) +} + +func checkTreeConsistency1(n *Node, depth int) error { + if depth == 1e4 { + return fmt.Errorf("html: tree looks like it contains a cycle") + } + if err := checkNodeConsistency(n); err != nil { + return err + } + for c := n.FirstChild; c != nil; c = c.NextSibling { + if err := checkTreeConsistency1(c, depth+1); err != nil { + return err + } + } + return nil +} + +// checkNodeConsistency checks that a node's parent/child/sibling relationships +// are consistent. +func checkNodeConsistency(n *Node) error { + if n == nil { + return nil + } + + nParent := 0 + for p := n.Parent; p != nil; p = p.Parent { + nParent++ + if nParent == 1e4 { + return fmt.Errorf("html: parent list looks like an infinite loop") + } + } + + nForward := 0 + for c := n.FirstChild; c != nil; c = c.NextSibling { + nForward++ + if nForward == 1e6 { + return fmt.Errorf("html: forward list of children looks like an infinite loop") + } + if c.Parent != n { + return fmt.Errorf("html: inconsistent child/parent relationship") + } + } + + nBackward := 0 + for c := n.LastChild; c != nil; c = c.PrevSibling { + nBackward++ + if nBackward == 1e6 { + return fmt.Errorf("html: backward list of children looks like an infinite loop") + } + if c.Parent != n { + return fmt.Errorf("html: inconsistent child/parent relationship") + } + } + + if n.Parent != nil { + if n.Parent == n { + return fmt.Errorf("html: inconsistent parent relationship") + } + if n.Parent == n.FirstChild { + return fmt.Errorf("html: inconsistent parent/first relationship") + } + if n.Parent == n.LastChild { + return fmt.Errorf("html: inconsistent parent/last relationship") + } + if n.Parent == n.PrevSibling { + return fmt.Errorf("html: inconsistent parent/prev relationship") + } + if n.Parent == n.NextSibling { + return fmt.Errorf("html: inconsistent parent/next relationship") + } + + parentHasNAsAChild := false + for c := n.Parent.FirstChild; c != nil; c = c.NextSibling { + if c == n { + parentHasNAsAChild = true + break + } + } + if !parentHasNAsAChild { + return fmt.Errorf("html: inconsistent parent/child relationship") + } + } + + if n.PrevSibling != nil && n.PrevSibling.NextSibling != n { + return fmt.Errorf("html: inconsistent prev/next relationship") + } + if n.NextSibling != nil && n.NextSibling.PrevSibling != n { + return fmt.Errorf("html: inconsistent next/prev relationship") + } + + if (n.FirstChild == nil) != (n.LastChild == nil) { + return fmt.Errorf("html: inconsistent first/last relationship") + } + if n.FirstChild != nil && n.FirstChild == n.LastChild { + // We have a sole child. + if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil { + return fmt.Errorf("html: inconsistent sole child's sibling relationship") + } + } + + seen := map[*Node]bool{} + + var last *Node + for c := n.FirstChild; c != nil; c = c.NextSibling { + if seen[c] { + return fmt.Errorf("html: inconsistent repeated child") + } + seen[c] = true + last = c + } + if last != n.LastChild { + return fmt.Errorf("html: inconsistent last relationship") + } + + var first *Node + for c := n.LastChild; c != nil; c = c.PrevSibling { + if !seen[c] { + return fmt.Errorf("html: inconsistent missing child") + } + delete(seen, c) + first = c + } + if first != n.FirstChild { + return fmt.Errorf("html: inconsistent first relationship") + } + + if len(seen) != 0 { + return fmt.Errorf("html: inconsistent forwards/backwards child list") + } + + return nil +} diff --git a/libgo/go/exp/html/parse.go b/libgo/go/exp/html/parse.go index 04f4ae7..cae836e 100644 --- a/libgo/go/exp/html/parse.go +++ b/libgo/go/exp/html/parse.go @@ -5,6 +5,9 @@ package html import ( + "errors" + a "exp/html/atom" + "fmt" "io" "strings" ) @@ -16,9 +19,8 @@ type parser struct { tokenizer *Tokenizer // tok is the most recently read token. tok Token - // Self-closing tags like <hr/> are re-interpreted as a two-token sequence: - // <hr> followed by </hr>. hasSelfClosingToken is true if we have just read - // the synthetic start tag and the next one due is the matching end tag. + // Self-closing tags like <hr/> are treated as start tags, except that + // hasSelfClosingToken is set while they are being processed. hasSelfClosingToken bool // doc is the document root element. doc *Node @@ -39,6 +41,8 @@ type parser struct { fosterParenting bool // quirks is whether the parser is operating in "quirks mode." quirks bool + // fragment is whether the parser is parsing an HTML fragment. + fragment bool // context is the context element when parsing an HTML fragment // (section 12.4). context *Node @@ -53,10 +57,10 @@ func (p *parser) top() *Node { // Stop tags for use in popUntil. These come from section 12.2.3.2. var ( - defaultScopeStopTags = map[string][]string{ - "": {"applet", "caption", "html", "table", "td", "th", "marquee", "object"}, - "math": {"annotation-xml", "mi", "mn", "mo", "ms", "mtext"}, - "svg": {"desc", "foreignObject", "title"}, + defaultScopeStopTags = map[string][]a.Atom{ + "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object}, + "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, + "svg": {a.Desc, a.ForeignObject, a.Title}, } ) @@ -68,6 +72,8 @@ const ( buttonScope tableScope tableRowScope + tableBodyScope + selectScope ) // popUntil pops the stack of open elements at the highest element whose tag @@ -87,7 +93,7 @@ const ( // no higher element in the stack that was also in the stop tags). For example, // popUntil(tableScope, "table") returns true and leaves: // ["html", "body", "font"] -func (p *parser) popUntil(s scope, matchTags ...string) bool { +func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { if i := p.indexOfElementInScope(s, matchTags...); i != -1 { p.oe = p.oe[:i] return true @@ -98,12 +104,12 @@ func (p *parser) popUntil(s scope, matchTags ...string) bool { // indexOfElementInScope returns the index in p.oe of the highest element whose // tag is in matchTags that is in scope. If no matching element is in scope, it // returns -1. -func (p *parser) indexOfElementInScope(s scope, matchTags ...string) int { +func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { for i := len(p.oe) - 1; i >= 0; i-- { - tag := p.oe[i].Data + tagAtom := p.oe[i].DataAtom if p.oe[i].Namespace == "" { for _, t := range matchTags { - if t == tag { + if t == tagAtom { return i } } @@ -111,15 +117,19 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...string) int { case defaultScope: // No-op. case listItemScope: - if tag == "ol" || tag == "ul" { + if tagAtom == a.Ol || tagAtom == a.Ul { return -1 } case buttonScope: - if tag == "button" { + if tagAtom == a.Button { return -1 } case tableScope: - if tag == "html" || tag == "table" { + if tagAtom == a.Html || tagAtom == a.Table { + return -1 + } + case selectScope: + if tagAtom != a.Optgroup && tagAtom != a.Option { return -1 } default: @@ -129,7 +139,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...string) int { switch s { case defaultScope, listItemScope, buttonScope: for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { - if t == tag { + if t == tagAtom { return -1 } } @@ -140,7 +150,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...string) int { // elementInScope is like popUntil, except that it doesn't modify the stack of // open elements. -func (p *parser) elementInScope(s scope, matchTags ...string) bool { +func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { return p.indexOfElementInScope(s, matchTags...) != -1 } @@ -148,15 +158,20 @@ func (p *parser) elementInScope(s scope, matchTags ...string) bool { // scope-defined element is found. func (p *parser) clearStackToContext(s scope) { for i := len(p.oe) - 1; i >= 0; i-- { - tag := p.oe[i].Data + tagAtom := p.oe[i].DataAtom switch s { case tableScope: - if tag == "html" || tag == "table" { + if tagAtom == a.Html || tagAtom == a.Table { p.oe = p.oe[:i+1] return } case tableRowScope: - if tag == "html" || tag == "tr" { + if tagAtom == a.Html || tagAtom == a.Tr { + p.oe = p.oe[:i+1] + return + } + case tableBodyScope: + if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead { p.oe = p.oe[:i+1] return } @@ -166,13 +181,38 @@ func (p *parser) clearStackToContext(s scope) { } } +// generateImpliedEndTags pops nodes off the stack of open elements as long as +// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt. +// If exceptions are specified, nodes with that name will not be popped off. +func (p *parser) generateImpliedEndTags(exceptions ...string) { + var i int +loop: + for i = len(p.oe) - 1; i >= 0; i-- { + n := p.oe[i] + if n.Type == ElementNode { + switch n.DataAtom { + case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt: + for _, except := range exceptions { + if n.Data == except { + break loop + } + } + continue + } + } + break + } + + p.oe = p.oe[:i+1] +} + // addChild adds a child node n to the top element, and pushes n onto the stack // of open elements if it is an element node. func (p *parser) addChild(n *Node) { - if p.fosterParenting { + if p.shouldFosterParent() { p.fosterParent(n) } else { - p.top().Add(n) + p.top().AppendChild(n) } if n.Type == ElementNode { @@ -180,14 +220,25 @@ func (p *parser) addChild(n *Node) { } } +// shouldFosterParent returns whether the next node to be added should be +// foster parented. +func (p *parser) shouldFosterParent() bool { + if p.fosterParenting { + switch p.top().DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: + return true + } + } + return false +} + // fosterParent adds a child node according to the foster parenting rules. // Section 12.2.5.3, "foster parenting". func (p *parser) fosterParent(n *Node) { - p.fosterParenting = false - var table, parent *Node + var table, parent, prev *Node var i int for i = len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].Data == "table" { + if p.oe[i].DataAtom == a.Table { table = p.oe[i] break } @@ -203,35 +254,37 @@ func (p *parser) fosterParent(n *Node) { parent = p.oe[i-1] } - var child *Node - for i, child = range parent.Child { - if child == table { - break - } + if table != nil { + prev = table.PrevSibling + } else { + prev = parent.LastChild } - - if i > 0 && parent.Child[i-1].Type == TextNode && n.Type == TextNode { - parent.Child[i-1].Data += n.Data + if prev != nil && prev.Type == TextNode && n.Type == TextNode { + prev.Data += n.Data return } - if i == len(parent.Child) { - parent.Add(n) - } else { - // Insert n into parent.Child at index i. - parent.Child = append(parent.Child[:i+1], parent.Child[i:]...) - parent.Child[i] = n - n.Parent = parent - } + parent.InsertBefore(n, table) } // addText adds text to the preceding node if it is a text node, or else it // calls addChild with a new text node. func (p *parser) addText(text string) { - // TODO: distinguish whitespace text from others. + if text == "" { + return + } + + if p.shouldFosterParent() { + p.fosterParent(&Node{ + Type: TextNode, + Data: text, + }) + return + } + t := p.top() - if i := len(t.Child); i > 0 && t.Child[i-1].Type == TextNode { - t.Child[i-1].Data += text + if n := t.LastChild; n != nil && n.Type == TextNode { + n.Data += text return } p.addChild(&Node{ @@ -240,20 +293,61 @@ func (p *parser) addText(text string) { }) } -// addElement calls addChild with an element node. -func (p *parser) addElement(tag string, attr []Attribute) { +// addElement adds a child element based on the current token. +func (p *parser) addElement() { p.addChild(&Node{ - Type: ElementNode, - Data: tag, - Attr: attr, + Type: ElementNode, + DataAtom: p.tok.DataAtom, + Data: p.tok.Data, + Attr: p.tok.Attr, }) } // Section 12.2.3.3. -func (p *parser) addFormattingElement(tag string, attr []Attribute) { - p.addElement(tag, attr) +func (p *parser) addFormattingElement() { + tagAtom, attr := p.tok.DataAtom, p.tok.Attr + p.addElement() + + // Implement the Noah's Ark clause, but with three per family instead of two. + identicalElements := 0 +findIdenticalElements: + for i := len(p.afe) - 1; i >= 0; i-- { + n := p.afe[i] + if n.Type == scopeMarkerNode { + break + } + if n.Type != ElementNode { + continue + } + if n.Namespace != "" { + continue + } + if n.DataAtom != tagAtom { + continue + } + if len(n.Attr) != len(attr) { + continue + } + compareAttributes: + for _, t0 := range n.Attr { + for _, t1 := range attr { + if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { + // Found a match for this attribute, continue with the next attribute. + continue compareAttributes + } + } + // If we get here, there is no attribute that matches a. + // Therefore the element is not identical to the new one. + continue findIdenticalElements + } + + identicalElements++ + if identicalElements >= 3 { + p.afe.remove(n) + } + } + p.afe = append(p.afe, p.top()) - // TODO. } // Section 12.2.3.3. @@ -295,27 +389,6 @@ func (p *parser) reconstructActiveFormattingElements() { } } -// read reads the next token. This is usually from the tokenizer, but it may -// be the synthesized end tag implied by a self-closing tag. -func (p *parser) read() error { - if p.hasSelfClosingToken { - p.hasSelfClosingToken = false - p.tok.Type = EndTagToken - p.tok.Attr = nil - return nil - } - p.tokenizer.Next() - p.tok = p.tokenizer.Token() - switch p.tok.Type { - case ErrorToken: - return p.tokenizer.Err() - case SelfClosingTagToken: - p.hasSelfClosingToken = true - p.tok.Type = StartTagToken - } - return nil -} - // Section 12.2.4. func (p *parser) acknowledgeSelfClosingTag() { p.hasSelfClosingToken = false @@ -345,28 +418,28 @@ func (p *parser) resetInsertionMode() { n = p.context } - switch n.Data { - case "select": + switch n.DataAtom { + case a.Select: p.im = inSelectIM - case "td", "th": + case a.Td, a.Th: p.im = inCellIM - case "tr": + case a.Tr: p.im = inRowIM - case "tbody", "thead", "tfoot": + case a.Tbody, a.Thead, a.Tfoot: p.im = inTableBodyIM - case "caption": + case a.Caption: p.im = inCaptionIM - case "colgroup": + case a.Colgroup: p.im = inColumnGroupIM - case "table": + case a.Table: p.im = inTableIM - case "head": + case a.Head: p.im = inBodyIM - case "body": + case a.Body: p.im = inBodyIM - case "frameset": + case a.Frameset: p.im = inFramesetIM - case "html": + case a.Html: p.im = beforeHeadIM default: continue @@ -388,14 +461,14 @@ func initialIM(p *parser) bool { return true } case CommentToken: - p.doc.Add(&Node{ + p.doc.AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) return true case DoctypeToken: n, quirks := parseDoctype(p.tok.Data) - p.doc.Add(n) + p.doc.AppendChild(n) p.quirks = quirks p.im = beforeHTMLIM return true @@ -408,6 +481,9 @@ func initialIM(p *parser) bool { // Section 12.2.5.4.2. func beforeHTMLIM(p *parser) bool { switch p.tok.Type { + case DoctypeToken: + // Ignore the token. + return true case TextToken: p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) if len(p.tok.Data) == 0 { @@ -415,65 +491,58 @@ func beforeHTMLIM(p *parser) bool { return true } case StartTagToken: - if p.tok.Data == "html" { - p.addElement(p.tok.Data, p.tok.Attr) + if p.tok.DataAtom == a.Html { + p.addElement() p.im = beforeHeadIM return true } case EndTagToken: - switch p.tok.Data { - case "head", "body", "html", "br": - // Drop down to creating an implied <html> tag. + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) + return false default: // Ignore the token. return true } case CommentToken: - p.doc.Add(&Node{ + p.doc.AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) return true } - // Create an implied <html> tag. - p.addElement("html", nil) - p.im = beforeHeadIM + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) return false } // Section 12.2.5.4.3. func beforeHeadIM(p *parser) bool { - var ( - add bool - attr []Attribute - implied bool - ) switch p.tok.Type { - case ErrorToken: - implied = true case TextToken: p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) if len(p.tok.Data) == 0 { // It was all whitespace, so ignore it. return true } - implied = true case StartTagToken: - switch p.tok.Data { - case "head": - add = true - attr = p.tok.Attr - case "html": + switch p.tok.DataAtom { + case a.Head: + p.addElement() + p.head = p.top() + p.im = inHeadIM + return true + case a.Html: return inBodyIM(p) - default: - implied = true } case EndTagToken: - switch p.tok.Data { - case "head", "body", "html", "br": - implied = true + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false default: // Ignore the token. + return true } case CommentToken: p.addChild(&Node{ @@ -481,24 +550,18 @@ func beforeHeadIM(p *parser) bool { Data: p.tok.Data, }) return true + case DoctypeToken: + // Ignore the token. + return true } - if add || implied { - p.addElement("head", attr) - p.head = p.top() - } - p.im = inHeadIM - return !implied + + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false } // Section 12.2.5.4.4. func inHeadIM(p *parser) bool { - var ( - pop bool - implied bool - ) switch p.tok.Type { - case ErrorToken: - implied = true case TextToken: s := strings.TrimLeft(p.tok.Data, whitespace) if len(s) < len(p.tok.Data) { @@ -509,32 +572,36 @@ func inHeadIM(p *parser) bool { } p.tok.Data = s } - implied = true case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: return inBodyIM(p) - case "base", "basefont", "bgsound", "command", "link", "meta": - p.addElement(p.tok.Data, p.tok.Attr) + case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: + p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() - case "script", "title", "noscript", "noframes", "style": - p.addElement(p.tok.Data, p.tok.Attr) + return true + case a.Script, a.Title, a.Noscript, a.Noframes, a.Style: + p.addElement() p.setOriginalIM() p.im = textIM return true - case "head": + case a.Head: // Ignore the token. return true - default: - implied = true } case EndTagToken: - switch p.tok.Data { - case "head": - pop = true - case "body", "html", "br": - implied = true + switch p.tok.DataAtom { + case a.Head: + n := p.oe.pop() + if n.DataAtom != a.Head { + panic("html: bad parser state: <head> element not found, in the in-head insertion mode") + } + p.im = afterHeadIM + return true + case a.Body, a.Html, a.Br: + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false default: // Ignore the token. return true @@ -545,30 +612,18 @@ func inHeadIM(p *parser) bool { Data: p.tok.Data, }) return true + case DoctypeToken: + // Ignore the token. + return true } - if pop || implied { - n := p.oe.pop() - if n.Data != "head" { - panic("html: bad parser state: <head> element not found, in the in-head insertion mode") - } - p.im = afterHeadIM - return !implied - } - return true + + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false } // Section 12.2.5.4.6. func afterHeadIM(p *parser) bool { - var ( - add bool - attr []Attribute - framesetOK bool - implied bool - ) switch p.tok.Type { - case ErrorToken: - implied = true - framesetOK = true case TextToken: s := strings.TrimLeft(p.tok.Data, whitespace) if len(s) < len(p.tok.Data) { @@ -579,36 +634,31 @@ func afterHeadIM(p *parser) bool { } p.tok.Data = s } - implied = true - framesetOK = true case StartTagToken: - switch p.tok.Data { - case "html": - // TODO. - case "body": - add = true - attr = p.tok.Attr - framesetOK = false - case "frameset": - p.addElement(p.tok.Data, p.tok.Attr) + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Body: + p.addElement() + p.framesetOK = false + p.im = inBodyIM + return true + case a.Frameset: + p.addElement() p.im = inFramesetIM return true - case "base", "basefont", "bgsound", "link", "meta", "noframes", "script", "style", "title": + case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: p.oe = append(p.oe, p.head) - defer p.oe.pop() + defer p.oe.remove(p.head) return inHeadIM(p) - case "head": + case a.Head: // Ignore the token. return true - default: - implied = true - framesetOK = true } case EndTagToken: - switch p.tok.Data { - case "body", "html", "br": - implied = true - framesetOK = true + switch p.tok.DataAtom { + case a.Body, a.Html, a.Br: + // Drop down to creating an implied <body> tag. default: // Ignore the token. return true @@ -619,13 +669,14 @@ func afterHeadIM(p *parser) bool { Data: p.tok.Data, }) return true + case DoctypeToken: + // Ignore the token. + return true } - if add || implied { - p.addElement("body", attr) - p.framesetOK = framesetOK - } - p.im = inBodyIM - return !implied + + p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) + p.framesetOK = true + return false } // copyAttributes copies attributes of src not found on dst to dst. @@ -634,13 +685,13 @@ func copyAttributes(dst *Node, src Token) { return } attr := map[string]string{} - for _, a := range dst.Attr { - attr[a.Key] = a.Val + for _, t := range dst.Attr { + attr[t.Key] = t.Val } - for _, a := range src.Attr { - if _, ok := attr[a.Key]; !ok { - dst.Attr = append(dst.Attr, a) - attr[a.Key] = a.Val + for _, t := range src.Attr { + if _, ok := attr[t.Key]; !ok { + dst.Attr = append(dst.Attr, t) + attr[t.Key] = t.Val } } } @@ -649,106 +700,85 @@ func copyAttributes(dst *Node, src Token) { func inBodyIM(p *parser) bool { switch p.tok.Type { case TextToken: - switch n := p.oe.top(); n.Data { - case "pre", "listing", "textarea": - if len(n.Child) == 0 { + d := p.tok.Data + switch n := p.oe.top(); n.DataAtom { + case a.Pre, a.Listing: + if n.FirstChild == nil { // Ignore a newline at the start of a <pre> block. - d := p.tok.Data if d != "" && d[0] == '\r' { d = d[1:] } if d != "" && d[0] == '\n' { d = d[1:] } - if d == "" { - return true - } - p.tok.Data = d } } + d = strings.Replace(d, "\x00", "", -1) + if d == "" { + return true + } p.reconstructActiveFormattingElements() - p.addText(p.tok.Data) - p.framesetOK = false + p.addText(d) + if p.framesetOK && strings.TrimLeft(d, whitespace) != "" { + // There were non-whitespace characters inserted. + p.framesetOK = false + } case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: copyAttributes(p.oe[0], p.tok) - case "address", "article", "aside", "blockquote", "center", "details", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu", "nav", "ol", "p", "section", "summary", "ul": - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) - case "h1", "h2", "h3", "h4", "h5", "h6": - p.popUntil(buttonScope, "p") - switch n := p.top(); n.Data { - case "h1", "h2", "h3", "h4", "h5", "h6": - p.oe.pop() - } - p.addElement(p.tok.Data, p.tok.Attr) - case "a": - for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- { - if n := p.afe[i]; n.Type == ElementNode && n.Data == "a" { - p.inBodyEndTagFormatting("a") - p.oe.remove(n) - p.afe.remove(n) - break + case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: + return inHeadIM(p) + case a.Body: + if len(p.oe) >= 2 { + body := p.oe[1] + if body.Type == ElementNode && body.DataAtom == a.Body { + p.framesetOK = false + copyAttributes(body, p.tok) } } - p.reconstructActiveFormattingElements() - p.addFormattingElement(p.tok.Data, p.tok.Attr) - case "b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u": - p.reconstructActiveFormattingElements() - p.addFormattingElement(p.tok.Data, p.tok.Attr) - case "nobr": - p.reconstructActiveFormattingElements() - if p.elementInScope(defaultScope, "nobr") { - p.inBodyEndTagFormatting("nobr") - p.reconstructActiveFormattingElements() + case a.Frameset: + if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body { + // Ignore the token. + return true } - p.addFormattingElement(p.tok.Data, p.tok.Attr) - case "applet", "marquee", "object": - p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) - p.afe = append(p.afe, &scopeMarker) - p.framesetOK = false - case "area", "br", "embed", "img", "input", "keygen", "wbr": - p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) - p.oe.pop() - p.acknowledgeSelfClosingTag() - p.framesetOK = false - case "table": - if !p.quirks { - p.popUntil(buttonScope, "p") + body := p.oe[1] + if body.Parent != nil { + body.Parent.RemoveChild(body) } - p.addElement(p.tok.Data, p.tok.Attr) - p.framesetOK = false - p.im = inTableIM + p.oe = p.oe[:1] + p.addElement() + p.im = inFramesetIM return true - case "hr": - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) - p.oe.pop() - p.acknowledgeSelfClosingTag() - p.framesetOK = false - case "select": - p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) + case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul: + p.popUntil(buttonScope, a.P) + p.addElement() + case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6: + p.popUntil(buttonScope, a.P) + switch n := p.top(); n.DataAtom { + case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6: + p.oe.pop() + } + p.addElement() + case a.Pre, a.Listing: + p.popUntil(buttonScope, a.P) + p.addElement() + // The newline, if any, will be dealt with by the TextToken case. p.framesetOK = false - p.im = inSelectIM - return true - case "form": + case a.Form: if p.form == nil { - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) + p.popUntil(buttonScope, a.P) + p.addElement() p.form = p.top() } - case "li": + case a.Li: p.framesetOK = false for i := len(p.oe) - 1; i >= 0; i-- { node := p.oe[i] - switch node.Data { - case "li": - p.popUntil(listItemScope, "li") - case "address", "div", "p": + switch node.DataAtom { + case a.Li: + p.oe = p.oe[:i] + case a.Address, a.Div, a.P: continue default: if !isSpecialElement(node) { @@ -757,16 +787,16 @@ func inBodyIM(p *parser) bool { } break } - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) - case "dd", "dt": + p.popUntil(buttonScope, a.P) + p.addElement() + case a.Dd, a.Dt: p.framesetOK = false for i := len(p.oe) - 1; i >= 0; i-- { node := p.oe[i] - switch node.Data { - case "dd", "dt": + switch node.DataAtom { + case a.Dd, a.Dt: p.oe = p.oe[:i] - case "address", "div", "p": + case a.Address, a.Div, a.P: continue default: if !isSpecialElement(node) { @@ -775,49 +805,81 @@ func inBodyIM(p *parser) bool { } break } - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) - case "plaintext": - p.popUntil(buttonScope, "p") - p.addElement(p.tok.Data, p.tok.Attr) - case "button": - p.popUntil(defaultScope, "button") + p.popUntil(buttonScope, a.P) + p.addElement() + case a.Plaintext: + p.popUntil(buttonScope, a.P) + p.addElement() + case a.Button: + p.popUntil(defaultScope, a.Button) p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.framesetOK = false - case "optgroup", "option": - if p.top().Data == "option" { - p.oe.pop() - } - p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) - case "body": - if len(p.oe) >= 2 { - body := p.oe[1] - if body.Type == ElementNode && body.Data == "body" { - p.framesetOK = false - copyAttributes(body, p.tok) + case a.A: + for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- { + if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A { + p.inBodyEndTagFormatting(a.A) + p.oe.remove(n) + p.afe.remove(n) + break } } - case "frameset": - if !p.framesetOK || len(p.oe) < 2 || p.oe[1].Data != "body" { - // Ignore the token. - return true + p.reconstructActiveFormattingElements() + p.addFormattingElement() + case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U: + p.reconstructActiveFormattingElements() + p.addFormattingElement() + case a.Nobr: + p.reconstructActiveFormattingElements() + if p.elementInScope(defaultScope, a.Nobr) { + p.inBodyEndTagFormatting(a.Nobr) + p.reconstructActiveFormattingElements() } - body := p.oe[1] - if body.Parent != nil { - body.Parent.Remove(body) + p.addFormattingElement() + case a.Applet, a.Marquee, a.Object: + p.reconstructActiveFormattingElements() + p.addElement() + p.afe = append(p.afe, &scopeMarker) + p.framesetOK = false + case a.Table: + if !p.quirks { + p.popUntil(buttonScope, a.P) } - p.oe = p.oe[:1] - p.addElement(p.tok.Data, p.tok.Attr) - p.im = inFramesetIM + p.addElement() + p.framesetOK = false + p.im = inTableIM return true - case "base", "basefont", "bgsound", "command", "link", "meta", "noframes", "script", "style", "title": - return inHeadIM(p) - case "image": - p.tok.Data = "img" + case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr: + p.reconstructActiveFormattingElements() + p.addElement() + p.oe.pop() + p.acknowledgeSelfClosingTag() + if p.tok.DataAtom == a.Input { + for _, t := range p.tok.Attr { + if t.Key == "type" { + if strings.ToLower(t.Val) == "hidden" { + // Skip setting framesetOK = false + return true + } + } + } + } + p.framesetOK = false + case a.Param, a.Source, a.Track: + p.addElement() + p.oe.pop() + p.acknowledgeSelfClosingTag() + case a.Hr: + p.popUntil(buttonScope, a.P) + p.addElement() + p.oe.pop() + p.acknowledgeSelfClosingTag() + p.framesetOK = false + case a.Image: + p.tok.DataAtom = a.Img + p.tok.Data = a.Img.String() return false - case "isindex": + case a.Isindex: if p.form != nil { // Ignore the token. return true @@ -825,82 +887,142 @@ func inBodyIM(p *parser) bool { action := "" prompt := "This is a searchable index. Enter search keywords: " attr := []Attribute{{Key: "name", Val: "isindex"}} - for _, a := range p.tok.Attr { - switch a.Key { + for _, t := range p.tok.Attr { + switch t.Key { case "action": - action = a.Val + action = t.Val case "name": // Ignore the attribute. case "prompt": - prompt = a.Val + prompt = t.Val default: - attr = append(attr, a) + attr = append(attr, t) } } p.acknowledgeSelfClosingTag() - p.popUntil(buttonScope, "p") - p.addElement("form", nil) - p.form = p.top() + p.popUntil(buttonScope, a.P) + p.parseImpliedToken(StartTagToken, a.Form, a.Form.String()) if action != "" { p.form.Attr = []Attribute{{Key: "action", Val: action}} } - p.addElement("hr", nil) - p.oe.pop() - p.addElement("label", nil) + p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String()) + p.parseImpliedToken(StartTagToken, a.Label, a.Label.String()) p.addText(prompt) - p.addElement("input", attr) - p.oe.pop() - p.oe.pop() - p.addElement("hr", nil) - p.oe.pop() + p.addChild(&Node{ + Type: ElementNode, + DataAtom: a.Input, + Data: a.Input.String(), + Attr: attr, + }) p.oe.pop() - p.form = nil - case "xmp": - p.popUntil(buttonScope, "p") + p.parseImpliedToken(EndTagToken, a.Label, a.Label.String()) + p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String()) + p.parseImpliedToken(EndTagToken, a.Form, a.Form.String()) + case a.Textarea: + p.addElement() + p.setOriginalIM() + p.framesetOK = false + p.im = textIM + case a.Xmp: + p.popUntil(buttonScope, a.P) + p.reconstructActiveFormattingElements() + p.framesetOK = false + p.addElement() + p.setOriginalIM() + p.im = textIM + case a.Iframe: + p.framesetOK = false + p.addElement() + p.setOriginalIM() + p.im = textIM + case a.Noembed, a.Noscript: + p.addElement() + p.setOriginalIM() + p.im = textIM + case a.Select: p.reconstructActiveFormattingElements() + p.addElement() p.framesetOK = false - p.addElement(p.tok.Data, p.tok.Attr) - case "math", "svg": + p.im = inSelectIM + return true + case a.Optgroup, a.Option: + if p.top().DataAtom == a.Option { + p.oe.pop() + } p.reconstructActiveFormattingElements() - if p.tok.Data == "math" { - // TODO: adjust MathML attributes. + p.addElement() + case a.Rp, a.Rt: + if p.elementInScope(defaultScope, a.Ruby) { + p.generateImpliedEndTags() + } + p.addElement() + case a.Math, a.Svg: + p.reconstructActiveFormattingElements() + if p.tok.DataAtom == a.Math { + adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments) } else { - // TODO: adjust SVG attributes. + adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments) } adjustForeignAttributes(p.tok.Attr) - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.top().Namespace = p.tok.Data + if p.hasSelfClosingToken { + p.oe.pop() + p.acknowledgeSelfClosingTag() + } return true - case "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr": + case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: // Ignore the token. default: - // TODO. - p.addElement(p.tok.Data, p.tok.Attr) + p.reconstructActiveFormattingElements() + p.addElement() } case EndTagToken: - switch p.tok.Data { - case "body": - // TODO: autoclose the stack of open elements. - p.im = afterBodyIM + switch p.tok.DataAtom { + case a.Body: + if p.elementInScope(defaultScope, a.Body) { + p.im = afterBodyIM + } + case a.Html: + if p.elementInScope(defaultScope, a.Body) { + p.parseImpliedToken(EndTagToken, a.Body, a.Body.String()) + return false + } return true - case "p": - if !p.elementInScope(buttonScope, "p") { - p.addElement("p", nil) - } - p.popUntil(buttonScope, "p") - case "a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u": - p.inBodyEndTagFormatting(p.tok.Data) - case "address", "article", "aside", "blockquote", "button", "center", "details", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "listing", "menu", "nav", "ol", "pre", "section", "summary", "ul": - p.popUntil(defaultScope, p.tok.Data) - case "applet", "marquee", "object": - if p.popUntil(defaultScope, p.tok.Data) { + case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul: + p.popUntil(defaultScope, p.tok.DataAtom) + case a.Form: + node := p.form + p.form = nil + i := p.indexOfElementInScope(defaultScope, a.Form) + if node == nil || i == -1 || p.oe[i] != node { + // Ignore the token. + return true + } + p.generateImpliedEndTags() + p.oe.remove(node) + case a.P: + if !p.elementInScope(buttonScope, a.P) { + p.parseImpliedToken(StartTagToken, a.P, a.P.String()) + } + p.popUntil(buttonScope, a.P) + case a.Li: + p.popUntil(listItemScope, a.Li) + case a.Dd, a.Dt: + p.popUntil(defaultScope, p.tok.DataAtom) + case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6: + p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6) + case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U: + p.inBodyEndTagFormatting(p.tok.DataAtom) + case a.Applet, a.Marquee, a.Object: + if p.popUntil(defaultScope, p.tok.DataAtom) { p.clearActiveFormattingElements() } - case "br": + case a.Br: p.tok.Type = StartTagToken return false default: - p.inBodyEndTagOther(p.tok.Data) + p.inBodyEndTagOther(p.tok.DataAtom) } case CommentToken: p.addChild(&Node{ @@ -912,7 +1034,7 @@ func inBodyIM(p *parser) bool { return true } -func (p *parser) inBodyEndTagFormatting(tag string) { +func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) { // This is the "adoption agency" algorithm, described at // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#adoptionAgency @@ -928,13 +1050,13 @@ func (p *parser) inBodyEndTagFormatting(tag string) { if p.afe[j].Type == scopeMarkerNode { break } - if p.afe[j].Data == tag { + if p.afe[j].DataAtom == tagAtom { formattingElement = p.afe[j] break } } if formattingElement == nil { - p.inBodyEndTagOther(tag) + p.inBodyEndTagOther(tagAtom) return } feIndex := p.oe.index(formattingElement) @@ -942,7 +1064,7 @@ func (p *parser) inBodyEndTagFormatting(tag string) { p.afe.remove(formattingElement) return } - if !p.elementInScope(defaultScope, tag) { + if !p.elementInScope(defaultScope, tagAtom) { // Ignore the tag. return } @@ -997,9 +1119,9 @@ func (p *parser) inBodyEndTagFormatting(tag string) { } // Step 9.9. if lastNode.Parent != nil { - lastNode.Parent.Remove(lastNode) + lastNode.Parent.RemoveChild(lastNode) } - node.Add(lastNode) + node.AppendChild(lastNode) // Step 9.10. lastNode = node } @@ -1007,20 +1129,20 @@ func (p *parser) inBodyEndTagFormatting(tag string) { // Step 10. Reparent lastNode to the common ancestor, // or for misnested table nodes, to the foster parent. if lastNode.Parent != nil { - lastNode.Parent.Remove(lastNode) + lastNode.Parent.RemoveChild(lastNode) } - switch commonAncestor.Data { - case "table", "tbody", "tfoot", "thead", "tr": + switch commonAncestor.DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: p.fosterParent(lastNode) default: - commonAncestor.Add(lastNode) + commonAncestor.AppendChild(lastNode) } // Steps 11-13. Reparent nodes from the furthest block's children // to a clone of the formatting element. clone := formattingElement.clone() reparentChildren(clone, furthestBlock) - furthestBlock.Add(clone) + furthestBlock.AppendChild(clone) // Step 14. Fix up the list of active formatting elements. if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark { @@ -1037,9 +1159,9 @@ func (p *parser) inBodyEndTagFormatting(tag string) { } // inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM. -func (p *parser) inBodyEndTagOther(tag string) { +func (p *parser) inBodyEndTagOther(tagAtom a.Atom) { for i := len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].Data == tag { + if p.oe[i].DataAtom == tagAtom { p.oe = p.oe[:i] break } @@ -1055,7 +1177,20 @@ func textIM(p *parser) bool { case ErrorToken: p.oe.pop() case TextToken: - p.addText(p.tok.Data) + d := p.tok.Data + if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil { + // Ignore a newline at the start of a <textarea> block. + if d != "" && d[0] == '\r' { + d = d[1:] + } + if d != "" && d[0] == '\n' { + d = d[1:] + } + } + if d == "" { + return true + } + p.addText(d) return true case EndTagToken: p.oe.pop() @@ -1072,66 +1207,85 @@ func inTableIM(p *parser) bool { // Stop parsing. return true case TextToken: - // TODO. + p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1) + switch p.oe.top().DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: + if strings.Trim(p.tok.Data, whitespace) == "" { + p.addText(p.tok.Data) + return true + } + } case StartTagToken: - switch p.tok.Data { - case "caption": + switch p.tok.DataAtom { + case a.Caption: p.clearStackToContext(tableScope) p.afe = append(p.afe, &scopeMarker) - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.im = inCaptionIM return true - case "tbody", "tfoot", "thead": + case a.Colgroup: p.clearStackToContext(tableScope) - p.addElement(p.tok.Data, p.tok.Attr) - p.im = inTableBodyIM + p.addElement() + p.im = inColumnGroupIM return true - case "td", "th", "tr": + case a.Col: + p.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String()) + return false + case a.Tbody, a.Tfoot, a.Thead: p.clearStackToContext(tableScope) - p.addElement("tbody", nil) + p.addElement() p.im = inTableBodyIM + return true + case a.Td, a.Th, a.Tr: + p.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String()) return false - case "table": - if p.popUntil(tableScope, "table") { + case a.Table: + if p.popUntil(tableScope, a.Table) { p.resetInsertionMode() return false } // Ignore the token. return true - case "colgroup": - p.clearStackToContext(tableScope) - p.addElement(p.tok.Data, p.tok.Attr) - p.im = inColumnGroupIM - return true - case "col": - p.clearStackToContext(tableScope) - p.addElement("colgroup", p.tok.Attr) - p.im = inColumnGroupIM - return false - case "select": + case a.Style, a.Script: + return inHeadIM(p) + case a.Input: + for _, t := range p.tok.Attr { + if t.Key == "type" && strings.ToLower(t.Val) == "hidden" { + p.addElement() + p.oe.pop() + return true + } + } + // Otherwise drop down to the default action. + case a.Form: + if p.form != nil { + // Ignore the token. + return true + } + p.addElement() + p.form = p.oe.pop() + case a.Select: p.reconstructActiveFormattingElements() - switch p.top().Data { - case "table", "tbody", "tfoot", "thead", "tr": + switch p.top().DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: p.fosterParenting = true } - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.fosterParenting = false p.framesetOK = false p.im = inSelectInTableIM return true - default: - // TODO. } case EndTagToken: - switch p.tok.Data { - case "table": - if p.popUntil(tableScope, "table") { + switch p.tok.DataAtom { + case a.Table: + if p.popUntil(tableScope, a.Table) { p.resetInsertionMode() return true } // Ignore the token. return true - case "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr": + case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: // Ignore the token. return true } @@ -1141,13 +1295,13 @@ func inTableIM(p *parser) bool { Data: p.tok.Data, }) return true + case DoctypeToken: + // Ignore the token. + return true } - switch p.top().Data { - case "table", "tbody", "tfoot", "thead", "tr": - p.fosterParenting = true - defer func() { p.fosterParenting = false }() - } + p.fosterParenting = true + defer func() { p.fosterParenting = false }() return inBodyIM(p) } @@ -1156,9 +1310,9 @@ func inTableIM(p *parser) bool { func inCaptionIM(p *parser) bool { switch p.tok.Type { case StartTagToken: - switch p.tok.Data { - case "caption", "col", "colgroup", "tbody", "td", "tfoot", "thead", "tr": - if p.popUntil(tableScope, "caption") { + switch p.tok.DataAtom { + case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr: + if p.popUntil(tableScope, a.Caption) { p.clearActiveFormattingElements() p.im = inTableIM return false @@ -1166,23 +1320,23 @@ func inCaptionIM(p *parser) bool { // Ignore the token. return true } - case "select": + case a.Select: p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.framesetOK = false p.im = inSelectInTableIM return true } case EndTagToken: - switch p.tok.Data { - case "caption": - if p.popUntil(tableScope, "caption") { + switch p.tok.DataAtom { + case a.Caption: + if p.popUntil(tableScope, a.Caption) { p.clearActiveFormattingElements() p.im = inTableIM } return true - case "table": - if p.popUntil(tableScope, "caption") { + case a.Table: + if p.popUntil(tableScope, a.Caption) { p.clearActiveFormattingElements() p.im = inTableIM return false @@ -1190,7 +1344,7 @@ func inCaptionIM(p *parser) bool { // Ignore the token. return true } - case "body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr": + case a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: // Ignore the token. return true } @@ -1201,6 +1355,16 @@ func inCaptionIM(p *parser) bool { // Section 12.2.5.4.12. func inColumnGroupIM(p *parser) bool { switch p.tok.Type { + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } case CommentToken: p.addChild(&Node{ Type: CommentNode, @@ -1211,29 +1375,29 @@ func inColumnGroupIM(p *parser) bool { // Ignore the token. return true case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: return inBodyIM(p) - case "col": - p.addElement(p.tok.Data, p.tok.Attr) + case a.Col: + p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() return true } case EndTagToken: - switch p.tok.Data { - case "colgroup": - if p.oe.top().Data != "html" { + switch p.tok.DataAtom { + case a.Colgroup: + if p.oe.top().DataAtom != a.Html { p.oe.pop() p.im = inTableIM } return true - case "col": + case a.Col: // Ignore the token. return true } } - if p.oe.top().Data != "html" { + if p.oe.top().DataAtom != a.Html { p.oe.pop() p.im = inTableIM return false @@ -1243,48 +1407,42 @@ func inColumnGroupIM(p *parser) bool { // Section 12.2.5.4.13. func inTableBodyIM(p *parser) bool { - var ( - add bool - data string - attr []Attribute - consumed bool - ) switch p.tok.Type { - case ErrorToken: - // TODO. - case TextToken: - // TODO. case StartTagToken: - switch p.tok.Data { - case "tr": - add = true - data = p.tok.Data - attr = p.tok.Attr - consumed = true - case "td", "th": - add = true - data = "tr" - consumed = false - case "caption", "col", "colgroup", "tbody", "tfoot", "thead": - if !p.popUntil(tableScope, "tbody", "thead", "tfoot") { - // Ignore the token. - return true - } - p.im = inTableIM + switch p.tok.DataAtom { + case a.Tr: + p.clearStackToContext(tableBodyScope) + p.addElement() + p.im = inRowIM + return true + case a.Td, a.Th: + p.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String()) return false - default: - // TODO. + case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead: + if p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) { + p.im = inTableIM + return false + } + // Ignore the token. + return true } case EndTagToken: - switch p.tok.Data { - case "table": - if p.popUntil(tableScope, "tbody", "thead", "tfoot") { + switch p.tok.DataAtom { + case a.Tbody, a.Tfoot, a.Thead: + if p.elementInScope(tableScope, p.tok.DataAtom) { + p.clearStackToContext(tableBodyScope) + p.oe.pop() + p.im = inTableIM + } + return true + case a.Table: + if p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) { p.im = inTableIM return false } // Ignore the token. return true - case "body", "caption", "col", "colgroup", "html", "td", "th", "tr": + case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th, a.Tr: // Ignore the token. return true } @@ -1295,117 +1453,102 @@ func inTableBodyIM(p *parser) bool { }) return true } - if add { - // TODO: clear the stack back to a table body context. - p.addElement(data, attr) - p.im = inRowIM - return consumed - } + return inTableIM(p) } // Section 12.2.5.4.14. func inRowIM(p *parser) bool { switch p.tok.Type { - case ErrorToken: - // TODO. - case TextToken: - // TODO. case StartTagToken: - switch p.tok.Data { - case "td", "th": + switch p.tok.DataAtom { + case a.Td, a.Th: p.clearStackToContext(tableRowScope) - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.afe = append(p.afe, &scopeMarker) p.im = inCellIM return true - case "caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr": - if p.popUntil(tableScope, "tr") { + case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr: + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return false } // Ignore the token. return true - default: - // TODO. } case EndTagToken: - switch p.tok.Data { - case "tr": - if p.popUntil(tableScope, "tr") { + switch p.tok.DataAtom { + case a.Tr: + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return true } // Ignore the token. return true - case "table": - if p.popUntil(tableScope, "tr") { + case a.Table: + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return false } // Ignore the token. return true - case "tbody", "tfoot", "thead": - // TODO. - case "body", "caption", "col", "colgroup", "html", "td", "th": + case a.Tbody, a.Tfoot, a.Thead: + if p.elementInScope(tableScope, p.tok.DataAtom) { + p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String()) + return false + } + // Ignore the token. + return true + case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th: // Ignore the token. return true - default: - // TODO. } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true } + return inTableIM(p) } // Section 12.2.5.4.15. func inCellIM(p *parser) bool { - var ( - closeTheCellAndReprocess bool - ) switch p.tok.Type { case StartTagToken: - switch p.tok.Data { - case "caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr": - // TODO: check for "td" or "th" in table scope. - closeTheCellAndReprocess = true - case "select": + switch p.tok.DataAtom { + case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr: + if p.popUntil(tableScope, a.Td, a.Th) { + // Close the cell and reprocess. + p.clearActiveFormattingElements() + p.im = inRowIM + return false + } + // Ignore the token. + return true + case a.Select: p.reconstructActiveFormattingElements() - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.framesetOK = false p.im = inSelectInTableIM return true } case EndTagToken: - switch p.tok.Data { - case "td", "th": - if !p.popUntil(tableScope, p.tok.Data) { + switch p.tok.DataAtom { + case a.Td, a.Th: + if !p.popUntil(tableScope, p.tok.DataAtom) { // Ignore the token. return true } p.clearActiveFormattingElements() p.im = inRowIM return true - case "body", "caption", "col", "colgroup", "html": - // TODO. - case "table", "tbody", "tfoot", "thead", "tr": - // TODO: check for matching element in table scope. - closeTheCellAndReprocess = true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - } - if closeTheCellAndReprocess { - if p.popUntil(tableScope, "td") || p.popUntil(tableScope, "th") { + case a.Body, a.Caption, a.Col, a.Colgroup, a.Html: + // Ignore the token. + return true + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: + if !p.elementInScope(tableScope, p.tok.DataAtom) { + // Ignore the token. + return true + } + // Close the cell and reprocess. + p.popUntil(tableScope, a.Td, a.Th) p.clearActiveFormattingElements() p.im = inRowIM return false @@ -1416,66 +1559,73 @@ func inCellIM(p *parser) bool { // Section 12.2.5.4.16. func inSelectIM(p *parser) bool { - endSelect := false switch p.tok.Type { case ErrorToken: - // TODO. + // Stop parsing. + return true case TextToken: - p.addText(p.tok.Data) + p.addText(strings.Replace(p.tok.Data, "\x00", "", -1)) case StartTagToken: - switch p.tok.Data { - case "html": - // TODO. - case "option": - if p.top().Data == "option" { + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Option: + if p.top().DataAtom == a.Option { p.oe.pop() } - p.addElement(p.tok.Data, p.tok.Attr) - case "optgroup": - if p.top().Data == "option" { + p.addElement() + case a.Optgroup: + if p.top().DataAtom == a.Option { p.oe.pop() } - if p.top().Data == "optgroup" { + if p.top().DataAtom == a.Optgroup { p.oe.pop() } - p.addElement(p.tok.Data, p.tok.Attr) - case "select": - endSelect = true - case "input", "keygen", "textarea": - // TODO. - case "script": - // TODO. - default: + p.addElement() + case a.Select: + p.tok.Type = EndTagToken + return false + case a.Input, a.Keygen, a.Textarea: + if p.elementInScope(selectScope, a.Select) { + p.parseImpliedToken(EndTagToken, a.Select, a.Select.String()) + return false + } + // In order to properly ignore <textarea>, we need to change the tokenizer mode. + p.tokenizer.NextIsNotRawText() // Ignore the token. + return true + case a.Script: + return inHeadIM(p) } case EndTagToken: - switch p.tok.Data { - case "option": - if p.top().Data == "option" { + switch p.tok.DataAtom { + case a.Option: + if p.top().DataAtom == a.Option { p.oe.pop() } - case "optgroup": + case a.Optgroup: i := len(p.oe) - 1 - if p.oe[i].Data == "option" { + if p.oe[i].DataAtom == a.Option { i-- } - if p.oe[i].Data == "optgroup" { + if p.oe[i].DataAtom == a.Optgroup { p.oe = p.oe[:i] } - case "select": - endSelect = true - default: - // Ignore the token. + case a.Select: + if p.popUntil(selectScope, a.Select) { + p.resetInsertionMode() + } } case CommentToken: - p.doc.Add(&Node{ + p.doc.AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) + case DoctypeToken: + // Ignore the token. + return true } - if endSelect { - p.endSelect() - } + return true } @@ -1483,10 +1633,10 @@ func inSelectIM(p *parser) bool { func inSelectInTableIM(p *parser) bool { switch p.tok.Type { case StartTagToken, EndTagToken: - switch p.tok.Data { - case "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th": - if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.Data) { - p.endSelect() + switch p.tok.DataAtom { + case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th: + if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.DataAtom) { + p.parseImpliedToken(EndTagToken, a.Select, a.Select.String()) return false } else { // Ignore the token. @@ -1497,40 +1647,35 @@ func inSelectInTableIM(p *parser) bool { return inSelectIM(p) } -func (p *parser) endSelect() { - for i := len(p.oe) - 1; i >= 0; i-- { - switch p.oe[i].Data { - case "option", "optgroup": - continue - case "select": - p.oe = p.oe[:i] - p.resetInsertionMode() - } - return - } -} - // Section 12.2.5.4.18. func afterBodyIM(p *parser) bool { switch p.tok.Type { case ErrorToken: // Stop parsing. return true + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) == 0 { + // It was all whitespace. + return inBodyIM(p) + } case StartTagToken: - if p.tok.Data == "html" { + if p.tok.DataAtom == a.Html { return inBodyIM(p) } case EndTagToken: - if p.tok.Data == "html" { - p.im = afterAfterBodyIM + if p.tok.DataAtom == a.Html { + if !p.fragment { + p.im = afterAfterBodyIM + } return true } case CommentToken: // The comment is attached to the <html> element. - if len(p.oe) < 1 || p.oe[0].Data != "html" { + if len(p.oe) < 1 || p.oe[0].DataAtom != a.Html { panic("html: bad parser state: <html> element not found, in the after-body insertion mode") } - p.oe[0].Add(&Node{ + p.oe[0].AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) @@ -1561,24 +1706,24 @@ func inFramesetIM(p *parser) bool { p.addText(s) } case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: return inBodyIM(p) - case "frameset": - p.addElement(p.tok.Data, p.tok.Attr) - case "frame": - p.addElement(p.tok.Data, p.tok.Attr) + case a.Frameset: + p.addElement() + case a.Frame: + p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() - case "noframes": + case a.Noframes: return inHeadIM(p) } case EndTagToken: - switch p.tok.Data { - case "frameset": - if p.oe.top().Data != "html" { + switch p.tok.DataAtom { + case a.Frameset: + if p.oe.top().DataAtom != a.Html { p.oe.pop() - if p.oe.top().Data != "frameset" { + if p.oe.top().DataAtom != a.Frameset { p.im = afterFramesetIM return true } @@ -1611,15 +1756,15 @@ func afterFramesetIM(p *parser) bool { p.addText(s) } case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: return inBodyIM(p) - case "noframes": + case a.Noframes: return inHeadIM(p) } case EndTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: p.im = afterAfterFramesetIM return true } @@ -1636,17 +1781,23 @@ func afterAfterBodyIM(p *parser) bool { // Stop parsing. return true case TextToken: - // TODO. + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) == 0 { + // It was all whitespace. + return inBodyIM(p) + } case StartTagToken: - if p.tok.Data == "html" { + if p.tok.DataAtom == a.Html { return inBodyIM(p) } case CommentToken: - p.doc.Add(&Node{ + p.doc.AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) return true + case DoctypeToken: + return inBodyIM(p) } p.im = inBodyIM return false @@ -1656,7 +1807,7 @@ func afterAfterBodyIM(p *parser) bool { func afterAfterFramesetIM(p *parser) bool { switch p.tok.Type { case CommentToken: - p.addChild(&Node{ + p.doc.AppendChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) @@ -1670,35 +1821,34 @@ func afterAfterFramesetIM(p *parser) bool { return -1 }, p.tok.Data) if s != "" { - p.reconstructActiveFormattingElements() - p.addText(s) + p.tok.Data = s + return inBodyIM(p) } case StartTagToken: - switch p.tok.Data { - case "html": + switch p.tok.DataAtom { + case a.Html: return inBodyIM(p) - case "noframes": + case a.Noframes: return inHeadIM(p) } + case DoctypeToken: + return inBodyIM(p) default: // Ignore the token. } return true } +const whitespaceOrNUL = whitespace + "\x00" + // Section 12.2.5.5. func parseForeignContent(p *parser) bool { switch p.tok.Type { case TextToken: - // TODO: HTML integration points. - if p.top().Namespace == "" { - inBodyIM(p) - p.resetInsertionMode() - return true - } if p.framesetOK { - p.framesetOK = strings.TrimLeft(p.tok.Data, whitespace) == "" + p.framesetOK = strings.TrimLeft(p.tok.Data, whitespaceOrNUL) == "" } + p.tok.Data = strings.Replace(p.tok.Data, "\x00", "\ufffd", -1) p.addText(p.tok.Data) case CommentToken: p.addChild(&Node{ @@ -1706,15 +1856,21 @@ func parseForeignContent(p *parser) bool { Data: p.tok.Data, }) case StartTagToken: - if htmlIntegrationPoint(p.top()) { - inBodyIM(p) - p.resetInsertionMode() - return true + b := breakout[p.tok.Data] + if p.tok.DataAtom == a.Font { + loop: + for _, attr := range p.tok.Attr { + switch attr.Key { + case "color", "face", "size": + b = true + break loop + } + } } - if breakout[p.tok.Data] { + if b { for i := len(p.oe) - 1; i >= 0; i-- { - // TODO: MathML integration points. - if p.oe[i].Namespace == "" || htmlIntegrationPoint(p.oe[i]) { + n := p.oe[i] + if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) { p.oe = p.oe[:i+1] break } @@ -1723,21 +1879,31 @@ func parseForeignContent(p *parser) bool { } switch p.top().Namespace { case "math": - // TODO: adjust MathML attributes. + adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments) case "svg": // Adjust SVG tag names. The tokenizer lower-cases tag names, but // SVG wants e.g. "foreignObject" with a capital second "O". if x := svgTagNameAdjustments[p.tok.Data]; x != "" { + p.tok.DataAtom = a.Lookup([]byte(x)) p.tok.Data = x } - // TODO: adjust SVG attributes. + adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments) default: panic("html: bad parser state: unexpected namespace") } adjustForeignAttributes(p.tok.Attr) namespace := p.top().Namespace - p.addElement(p.tok.Data, p.tok.Attr) + p.addElement() p.top().Namespace = namespace + if namespace != "" { + // Don't let the tokenizer go into raw text mode in foreign content + // (e.g. in an SVG <title> tag). + p.tokenizer.NextIsNotRawText() + } + if p.hasSelfClosingToken { + p.oe.pop() + p.acknowledgeSelfClosingTag() + } case EndTagToken: for i := len(p.oe) - 1; i >= 0; i-- { if p.oe[i].Namespace == "" { @@ -1764,34 +1930,80 @@ func (p *parser) inForeignContent() bool { if n.Namespace == "" { return false } - // TODO: MathML, HTML integration points. - // TODO: MathML's annotation-xml combining with SVG's svg. + if mathMLTextIntegrationPoint(n) { + if p.tok.Type == StartTagToken && p.tok.DataAtom != a.Mglyph && p.tok.DataAtom != a.Malignmark { + return false + } + if p.tok.Type == TextToken { + return false + } + } + if n.Namespace == "math" && n.DataAtom == a.AnnotationXml && p.tok.Type == StartTagToken && p.tok.DataAtom == a.Svg { + return false + } + if htmlIntegrationPoint(n) && (p.tok.Type == StartTagToken || p.tok.Type == TextToken) { + return false + } + if p.tok.Type == ErrorToken { + return false + } return true } -func (p *parser) parse() error { - // Iterate until EOF. Any other error will cause an early return. - consumed := true - for { - if consumed { - if err := p.read(); err != nil { - if err == io.EOF { - break - } - return err - } - } +// parseImpliedToken parses a token as though it had appeared in the parser's +// input. +func (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string) { + realToken, selfClosing := p.tok, p.hasSelfClosingToken + p.tok = Token{ + Type: t, + DataAtom: dataAtom, + Data: data, + } + p.hasSelfClosingToken = false + p.parseCurrentToken() + p.tok, p.hasSelfClosingToken = realToken, selfClosing +} + +// parseCurrentToken runs the current token through the parsing routines +// until it is consumed. +func (p *parser) parseCurrentToken() { + if p.tok.Type == SelfClosingTagToken { + p.hasSelfClosingToken = true + p.tok.Type = StartTagToken + } + + consumed := false + for !consumed { if p.inForeignContent() { consumed = parseForeignContent(p) } else { consumed = p.im(p) } } - // Loop until the final token (the ErrorToken signifying EOF) is consumed. - for { - if consumed = p.im(p); consumed { - break + + if p.hasSelfClosingToken { + // This is a parse error, but ignore it. + p.hasSelfClosingToken = false + } +} + +func (p *parser) parse() error { + // Iterate until EOF. Any other error will cause an early return. + var err error + for err != io.EOF { + // CDATA sections are allowed only in foreign content. + n := p.oe.top() + p.tokenizer.AllowCDATA(n != nil && n.Namespace != "") + // Read and parse the next token. + p.tokenizer.Next() + p.tok = p.tokenizer.Token() + if p.tok.Type == ErrorToken { + err = p.tokenizer.Err() + if err != nil && err != io.EOF { + return err + } } + p.parseCurrentToken() } return nil } @@ -1819,32 +2031,40 @@ func Parse(r io.Reader) (*Node, error) { // found. If the fragment is the InnerHTML for an existing element, pass that // element in context. func ParseFragment(r io.Reader, context *Node) ([]*Node, error) { + contextTag := "" + if context != nil { + if context.Type != ElementNode { + return nil, errors.New("html: ParseFragment of non-element Node") + } + // The next check isn't just context.DataAtom.String() == context.Data because + // it is valid to pass an element whose tag isn't a known atom. For example, + // DataAtom == 0 and Data = "tagfromthefuture" is perfectly consistent. + if context.DataAtom != a.Lookup([]byte(context.Data)) { + return nil, fmt.Errorf("html: inconsistent Node: DataAtom=%q, Data=%q", context.DataAtom, context.Data) + } + contextTag = context.DataAtom.String() + } p := &parser{ - tokenizer: NewTokenizer(r), + tokenizer: NewTokenizerFragment(r, contextTag), doc: &Node{ Type: DocumentNode, }, scripting: true, + fragment: true, context: context, } - if context != nil { - switch context.Data { - case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "title", "textarea", "xmp": - p.tokenizer.rawTag = context.Data - } - } - root := &Node{ - Type: ElementNode, - Data: "html", + Type: ElementNode, + DataAtom: a.Html, + Data: a.Html.String(), } - p.doc.Add(root) + p.doc.AppendChild(root) p.oe = nodeStack{root} p.resetInsertionMode() for n := context; n != nil; n = n.Parent { - if n.Type == ElementNode && n.Data == "form" { + if n.Type == ElementNode && n.DataAtom == a.Form { p.form = n break } @@ -1860,10 +2080,12 @@ func ParseFragment(r io.Reader, context *Node) ([]*Node, error) { parent = root } - result := parent.Child - parent.Child = nil - for _, n := range result { - n.Parent = nil + var result []*Node + for c := parent.FirstChild; c != nil; { + next := c.NextSibling + parent.RemoveChild(c) + result = append(result, c) + c = next } return result, nil } diff --git a/libgo/go/exp/html/parse_test.go b/libgo/go/exp/html/parse_test.go index f3f966c..7cf2ff4 100644 --- a/libgo/go/exp/html/parse_test.go +++ b/libgo/go/exp/html/parse_test.go @@ -8,9 +8,14 @@ import ( "bufio" "bytes" "errors" + "exp/html/atom" "fmt" "io" + "io/ioutil" "os" + "path/filepath" + "runtime" + "sort" "strings" "testing" ) @@ -37,7 +42,10 @@ func readParseTest(r *bufio.Reader) (text, want, context string, err error) { } b = append(b, line...) } - text = strings.TrimRight(string(b), "\n") + text = string(b) + if strings.HasSuffix(text, "\n") { + text = text[:len(text)-1] + } b = b[:0] // Skip the error list. @@ -70,12 +78,22 @@ func readParseTest(r *bufio.Reader) (text, want, context string, err error) { if string(line) != "#document\n" { return "", "", "", fmt.Errorf(`got %q want "#document\n"`, line) } + inQuote := false for { line, err = r.ReadSlice('\n') if err != nil && err != io.EOF { return "", "", "", err } - if len(line) == 0 || len(line) == 1 && line[0] == '\n' { + trimmed := bytes.Trim(line, "| \n") + if len(trimmed) > 0 { + if line[0] == '|' && trimmed[0] == '"' { + inQuote = true + } + if trimmed[len(trimmed)-1] == '"' && !(line[0] == '|' && len(trimmed) == 1) { + inQuote = false + } + } + if len(line) == 0 || len(line) == 1 && line[0] == '\n' && !inQuote { break } b = append(b, line...) @@ -90,6 +108,23 @@ func dumpIndent(w io.Writer, level int) { } } +type sortedAttributes []Attribute + +func (a sortedAttributes) Len() int { + return len(a) +} + +func (a sortedAttributes) Less(i, j int) bool { + if a[i].Namespace != a[j].Namespace { + return a[i].Namespace < a[j].Namespace + } + return a[i].Key < a[j].Key +} + +func (a sortedAttributes) Swap(i, j int) { + a[i], a[j] = a[j], a[i] +} + func dumpLevel(w io.Writer, n *Node, level int) error { dumpIndent(w, level) switch n.Type { @@ -103,13 +138,8 @@ func dumpLevel(w io.Writer, n *Node, level int) error { } else { fmt.Fprintf(w, "<%s>", n.Data) } - attr := n.Attr - if len(attr) == 2 && attr[0].Namespace == "xml" && attr[1].Namespace == "xlink" { - // Some of the test cases in tests10.dat change the order of adjusted - // foreign attributes, but that behavior is not in the spec, and could - // simply be an implementation detail of html5lib's python map ordering. - attr[0], attr[1] = attr[1], attr[0] - } + attr := sortedAttributes(n.Attr) + sort.Sort(attr) for _, a := range attr { io.WriteString(w, "\n") dumpIndent(w, level+1) @@ -147,7 +177,7 @@ func dumpLevel(w io.Writer, n *Node, level int) error { return errors.New("unknown node type") } io.WriteString(w, "\n") - for _, c := range n.Child { + for c := n.FirstChild; c != nil; c = c.NextSibling { if err := dumpLevel(w, c, level+1); err != nil { return err } @@ -156,106 +186,126 @@ func dumpLevel(w io.Writer, n *Node, level int) error { } func dump(n *Node) (string, error) { - if n == nil || len(n.Child) == 0 { + if n == nil || n.FirstChild == nil { return "", nil } var b bytes.Buffer - for _, child := range n.Child { - if err := dumpLevel(&b, child, 0); err != nil { + for c := n.FirstChild; c != nil; c = c.NextSibling { + if err := dumpLevel(&b, c, 0); err != nil { return "", err } } return b.String(), nil } +const testDataDir = "testdata/webkit/" + func TestParser(t *testing.T) { - testFiles := []struct { - filename string - // n is the number of test cases to run from that file. - // -1 means all test cases. - n int - }{ - // TODO(nigeltao): Process all the test cases from all the .dat files. - {"adoption01.dat", -1}, - {"doctype01.dat", -1}, - {"tests1.dat", -1}, - {"tests2.dat", -1}, - {"tests3.dat", -1}, - {"tests4.dat", -1}, - {"tests5.dat", -1}, - {"tests6.dat", -1}, - {"tests10.dat", 35}, + testFiles, err := filepath.Glob(testDataDir + "*.dat") + if err != nil { + t.Fatal(err) } for _, tf := range testFiles { - f, err := os.Open("testdata/webkit/" + tf.filename) + f, err := os.Open(tf) if err != nil { t.Fatal(err) } defer f.Close() r := bufio.NewReader(f) - for i := 0; i != tf.n; i++ { + + for i := 0; ; i++ { text, want, context, err := readParseTest(r) - if err == io.EOF && tf.n == -1 { + if err == io.EOF { break } if err != nil { t.Fatal(err) } - var doc *Node - if context == "" { - doc, err = Parse(strings.NewReader(text)) - if err != nil { - t.Fatal(err) - } - } else { - contextNode := &Node{ - Type: ElementNode, - Data: context, - } - nodes, err := ParseFragment(strings.NewReader(text), contextNode) - if err != nil { - t.Fatal(err) - } - doc = &Node{ - Type: DocumentNode, - } - for _, n := range nodes { - doc.Add(n) - } - } + err = testParseCase(text, want, context) - got, err := dump(doc) - if err != nil { - t.Fatal(err) - } - // Compare the parsed tree to the #document section. - if got != want { - t.Errorf("%s test #%d %q, got vs want:\n----\n%s----\n%s----", tf.filename, i, text, got, want) - continue - } - if renderTestBlacklist[text] || context != "" { - continue - } - // Check that rendering and re-parsing results in an identical tree. - pr, pw := io.Pipe() - go func() { - pw.CloseWithError(Render(pw, doc)) - }() - doc1, err := Parse(pr) if err != nil { - t.Fatal(err) - } - got1, err := dump(doc1) - if err != nil { - t.Fatal(err) + t.Errorf("%s test #%d %q, %s", tf, i, text, err) } - if got != got1 { - t.Errorf("%s test #%d %q, got vs got1:\n----\n%s----\n%s----", tf.filename, i, text, got, got1) - continue + } + } +} + +// testParseCase tests one test case from the test files. If the test does not +// pass, it returns an error that explains the failure. +// text is the HTML to be parsed, want is a dump of the correct parse tree, +// and context is the name of the context node, if any. +func testParseCase(text, want, context string) (err error) { + defer func() { + if x := recover(); x != nil { + switch e := x.(type) { + case error: + err = e + default: + err = fmt.Errorf("%v", e) } } + }() + + var doc *Node + if context == "" { + doc, err = Parse(strings.NewReader(text)) + if err != nil { + return err + } + } else { + contextNode := &Node{ + Type: ElementNode, + DataAtom: atom.Lookup([]byte(context)), + Data: context, + } + nodes, err := ParseFragment(strings.NewReader(text), contextNode) + if err != nil { + return err + } + doc = &Node{ + Type: DocumentNode, + } + for _, n := range nodes { + doc.AppendChild(n) + } + } + + if err := checkTreeConsistency(doc); err != nil { + return err + } + + got, err := dump(doc) + if err != nil { + return err + } + // Compare the parsed tree to the #document section. + if got != want { + return fmt.Errorf("got vs want:\n----\n%s----\n%s----", got, want) + } + + if renderTestBlacklist[text] || context != "" { + return nil } + + // Check that rendering and re-parsing results in an identical tree. + pr, pw := io.Pipe() + go func() { + pw.CloseWithError(Render(pw, doc)) + }() + doc1, err := Parse(pr) + if err != nil { + return err + } + got1, err := dump(doc1) + if err != nil { + return err + } + if got != got1 { + return fmt.Errorf("got vs got1:\n----\n%s----\n%s----", got, got1) + } + + return nil } // Some test input result in parse trees are not 'well-formed' despite @@ -266,11 +316,81 @@ var renderTestBlacklist = map[string]bool{ // The second <a> will be reparented to the first <table>'s parent. This // results in an <a> whose parent is an <a>, which is not 'well-formed'. `<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y`: true, + // The same thing with a <p>: + `<p><table></p>`: true, // More cases of <a> being reparented: `<a href="blah">aba<table><a href="foo">br<tr><td></td></tr>x</table>aoe`: true, `<a><table><a></table><p><a><div><a>`: true, `<a><table><td><a><table></table><a></tr><a></table><a>`: true, + // A similar reparenting situation involving <nobr>: + `<!DOCTYPE html><body><b><nobr>1<table><nobr></b><i><nobr>2<nobr></i>3`: true, // A <plaintext> element is reparented, putting it before a table. // A <plaintext> element can't have anything after it in HTML. - `<table><plaintext><td>`: true, + `<table><plaintext><td>`: true, + `<!doctype html><table><plaintext></plaintext>`: true, + `<!doctype html><table><tbody><plaintext></plaintext>`: true, + `<!doctype html><table><tbody><tr><plaintext></plaintext>`: true, + // A form inside a table inside a form doesn't work either. + `<!doctype html><form><table></form><form></table></form>`: true, + // A script that ends at EOF may escape its own closing tag when rendered. + `<!doctype html><script><!--<script `: true, + `<!doctype html><script><!--<script <`: true, + `<!doctype html><script><!--<script <a`: true, + `<!doctype html><script><!--<script </`: true, + `<!doctype html><script><!--<script </s`: true, + `<!doctype html><script><!--<script </script`: true, + `<!doctype html><script><!--<script </scripta`: true, + `<!doctype html><script><!--<script -`: true, + `<!doctype html><script><!--<script -a`: true, + `<!doctype html><script><!--<script -<`: true, + `<!doctype html><script><!--<script --`: true, + `<!doctype html><script><!--<script --a`: true, + `<!doctype html><script><!--<script --<`: true, + `<script><!--<script `: true, + `<script><!--<script <a`: true, + `<script><!--<script </script`: true, + `<script><!--<script </scripta`: true, + `<script><!--<script -`: true, + `<script><!--<script -a`: true, + `<script><!--<script --`: true, + `<script><!--<script --a`: true, + `<script><!--<script <`: true, + `<script><!--<script </`: true, + `<script><!--<script </s`: true, + // Reconstructing the active formatting elements results in a <plaintext> + // element that contains an <a> element. + `<!doctype html><p><a><plaintext>b`: true, +} + +func TestNodeConsistency(t *testing.T) { + // inconsistentNode is a Node whose DataAtom and Data do not agree. + inconsistentNode := &Node{ + Type: ElementNode, + DataAtom: atom.Frameset, + Data: "table", + } + _, err := ParseFragment(strings.NewReader("<p>hello</p>"), inconsistentNode) + if err == nil { + t.Errorf("got nil error, want non-nil") + } +} + +func BenchmarkParser(b *testing.B) { + buf, err := ioutil.ReadFile("testdata/go1.html") + if err != nil { + b.Fatalf("could not read testdata/go1.html: %v", err) + } + b.SetBytes(int64(len(buf))) + runtime.GC() + var ms runtime.MemStats + runtime.ReadMemStats(&ms) + mallocs := ms.Mallocs + b.ResetTimer() + for i := 0; i < b.N; i++ { + Parse(bytes.NewBuffer(buf)) + } + b.StopTimer() + runtime.ReadMemStats(&ms) + mallocs = ms.Mallocs - mallocs + b.Logf("%d iterations, %d mallocs per iteration\n", b.N, int(mallocs)/b.N) } diff --git a/libgo/go/exp/html/render.go b/libgo/go/exp/html/render.go index 07859fa..65b1004 100644 --- a/libgo/go/exp/html/render.go +++ b/libgo/go/exp/html/render.go @@ -73,7 +73,7 @@ func render1(w writer, n *Node) error { case TextNode: return escape(w, n.Data) case DocumentNode: - for _, c := range n.Child { + for c := n.FirstChild; c != nil; c = c.NextSibling { if err := render1(w, c); err != nil { return err } @@ -171,7 +171,7 @@ func render1(w writer, n *Node) error { } } if voidElements[n.Data] { - if len(n.Child) != 0 { + if n.FirstChild != nil { return fmt.Errorf("html: void element <%s> has child nodes", n.Data) } _, err := w.WriteString("/>") @@ -182,7 +182,7 @@ func render1(w writer, n *Node) error { } // Add initial newline where there is danger of a newline beging ignored. - if len(n.Child) > 0 && n.Child[0].Type == TextNode && strings.HasPrefix(n.Child[0].Data, "\n") { + if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") { switch n.Data { case "pre", "listing", "textarea": if err := w.WriteByte('\n'); err != nil { @@ -194,12 +194,15 @@ func render1(w writer, n *Node) error { // Render any child nodes. switch n.Data { case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": - for _, c := range n.Child { - if c.Type != TextNode { - return fmt.Errorf("html: raw text element <%s> has non-text child node", n.Data) - } - if _, err := w.WriteString(c.Data); err != nil { - return err + for c := n.FirstChild; c != nil; c = c.NextSibling { + if c.Type == TextNode { + if _, err := w.WriteString(c.Data); err != nil { + return err + } + } else { + if err := render1(w, c); err != nil { + return err + } } } if n.Data == "plaintext" { @@ -207,17 +210,8 @@ func render1(w writer, n *Node) error { // last element in the file, with no closing tag. return plaintextAbort } - case "textarea", "title": - for _, c := range n.Child { - if c.Type != TextNode { - return fmt.Errorf("html: RCDATA element <%s> has non-text child node", n.Data) - } - if err := render1(w, c); err != nil { - return err - } - } default: - for _, c := range n.Child { + for c := n.FirstChild; c != nil; c = c.NextSibling { if err := render1(w, c); err != nil { return err } diff --git a/libgo/go/exp/html/render_test.go b/libgo/go/exp/html/render_test.go index 0584f35..11da54b 100644 --- a/libgo/go/exp/html/render_test.go +++ b/libgo/go/exp/html/render_test.go @@ -10,99 +10,144 @@ import ( ) func TestRenderer(t *testing.T) { - n := &Node{ - Type: ElementNode, - Data: "html", - Child: []*Node{ - { - Type: ElementNode, - Data: "head", + nodes := [...]*Node{ + 0: { + Type: ElementNode, + Data: "html", + }, + 1: { + Type: ElementNode, + Data: "head", + }, + 2: { + Type: ElementNode, + Data: "body", + }, + 3: { + Type: TextNode, + Data: "0<1", + }, + 4: { + Type: ElementNode, + Data: "p", + Attr: []Attribute{ + { + Key: "id", + Val: "A", + }, + { + Key: "foo", + Val: `abc"def`, + }, }, - { - Type: ElementNode, - Data: "body", - Child: []*Node{ - { - Type: TextNode, - Data: "0<1", - }, - { - Type: ElementNode, - Data: "p", - Attr: []Attribute{ - { - Key: "id", - Val: "A", - }, - { - Key: "foo", - Val: `abc"def`, - }, - }, - Child: []*Node{ - { - Type: TextNode, - Data: "2", - }, - { - Type: ElementNode, - Data: "b", - Attr: []Attribute{ - { - Key: "empty", - Val: "", - }, - }, - Child: []*Node{ - { - Type: TextNode, - Data: "3", - }, - }, - }, - { - Type: ElementNode, - Data: "i", - Attr: []Attribute{ - { - Key: "backslash", - Val: `\`, - }, - }, - Child: []*Node{ - { - Type: TextNode, - Data: "&4", - }, - }, - }, - }, - }, - { - Type: TextNode, - Data: "5", - }, - { - Type: ElementNode, - Data: "blockquote", - }, - { - Type: ElementNode, - Data: "br", - }, - { - Type: TextNode, - Data: "6", - }, + }, + 5: { + Type: TextNode, + Data: "2", + }, + 6: { + Type: ElementNode, + Data: "b", + Attr: []Attribute{ + { + Key: "empty", + Val: "", + }, + }, + }, + 7: { + Type: TextNode, + Data: "3", + }, + 8: { + Type: ElementNode, + Data: "i", + Attr: []Attribute{ + { + Key: "backslash", + Val: `\`, }, }, }, + 9: { + Type: TextNode, + Data: "&4", + }, + 10: { + Type: TextNode, + Data: "5", + }, + 11: { + Type: ElementNode, + Data: "blockquote", + }, + 12: { + Type: ElementNode, + Data: "br", + }, + 13: { + Type: TextNode, + Data: "6", + }, } - want := `<html><head></head><body>0<1<p id="A" foo="abc"def">` + + + // Build a tree out of those nodes, based on a textual representation. + // Only the ".\t"s are significant. The trailing HTML-like text is + // just commentary. The "0:" prefixes are for easy cross-reference with + // the nodes array. + treeAsText := [...]string{ + 0: `<html>`, + 1: `. <head>`, + 2: `. <body>`, + 3: `. . "0<1"`, + 4: `. . <p id="A" foo="abc"def">`, + 5: `. . . "2"`, + 6: `. . . <b empty="">`, + 7: `. . . . "3"`, + 8: `. . . <i backslash="\">`, + 9: `. . . . "&4"`, + 10: `. . "5"`, + 11: `. . <blockquote>`, + 12: `. . <br>`, + 13: `. . "6"`, + } + if len(nodes) != len(treeAsText) { + t.Fatal("len(nodes) != len(treeAsText)") + } + var stack [8]*Node + for i, line := range treeAsText { + level := 0 + for line[0] == '.' { + // Strip a leading ".\t". + line = line[2:] + level++ + } + n := nodes[i] + if level == 0 { + if stack[0] != nil { + t.Fatal("multiple root nodes") + } + stack[0] = n + } else { + stack[level-1].AppendChild(n) + stack[level] = n + for i := level + 1; i < len(stack); i++ { + stack[i] = nil + } + } + // At each stage of tree construction, we check all nodes for consistency. + for j, m := range nodes { + if err := checkNodeConsistency(m); err != nil { + t.Fatalf("i=%d, j=%d: %v", i, j, err) + } + } + } + + want := `<html><head></head><body>0<1<p id="A" foo="abc"def">` + `2<b empty="">3</b><i backslash="\">&4</i></p>` + `5<blockquote></blockquote><br/>6</body></html>` b := new(bytes.Buffer) - if err := Render(b, n); err != nil { + if err := Render(b, nodes[0]); err != nil { t.Fatal(err) } if got := b.String(); got != want { diff --git a/libgo/go/exp/html/testdata/go1.html b/libgo/go/exp/html/testdata/go1.html new file mode 100644 index 0000000..a782cc7 --- /dev/null +++ b/libgo/go/exp/html/testdata/go1.html @@ -0,0 +1,2237 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + + <title>Go 1 Release Notes - The Go Programming Language</title> + +<link type="text/css" rel="stylesheet" href="/doc/style.css"> +<script type="text/javascript" src="/doc/godocs.js"></script> + +<link rel="search" type="application/opensearchdescription+xml" title="godoc" href="/opensearch.xml" /> + +<script type="text/javascript"> +var _gaq = _gaq || []; +_gaq.push(["_setAccount", "UA-11222381-2"]); +_gaq.push(["_trackPageview"]); +</script> +</head> +<body> + +<div id="topbar"><div class="container wide"> + +<form method="GET" action="/search"> +<div id="menu"> +<a href="/doc/">Documents</a> +<a href="/ref/">References</a> +<a href="/pkg/">Packages</a> +<a href="/project/">The Project</a> +<a href="/help/">Help</a> +<input type="text" id="search" name="q" class="inactive" value="Search"> +</div> +<div id="heading"><a href="/">The Go Programming Language</a></div> +</form> + +</div></div> + +<div id="page" class="wide"> + + + <div id="plusone"><g:plusone size="small" annotation="none"></g:plusone></div> + <h1>Go 1 Release Notes</h1> + + + + +<div id="nav"></div> + + + + +<h2 id="introduction">Introduction to Go 1</h2> + +<p> +Go version 1, Go 1 for short, defines a language and a set of core libraries +that provide a stable foundation for creating reliable products, projects, and +publications. +</p> + +<p> +The driving motivation for Go 1 is stability for its users. People should be able to +write Go programs and expect that they will continue to compile and run without +change, on a time scale of years, including in production environments such as +Google App Engine. Similarly, people should be able to write books about Go, be +able to say which version of Go the book is describing, and have that version +number still be meaningful much later. +</p> + +<p> +Code that compiles in Go 1 should, with few exceptions, continue to compile and +run throughout the lifetime of that version, even as we issue updates and bug +fixes such as Go version 1.1, 1.2, and so on. Other than critical fixes, changes +made to the language and library for subsequent releases of Go 1 may +add functionality but will not break existing Go 1 programs. +<a href="go1compat.html">The Go 1 compatibility document</a> +explains the compatibility guidelines in more detail. +</p> + +<p> +Go 1 is a representation of Go as it used today, not a wholesale rethinking of +the language. We avoided designing new features and instead focused on cleaning +up problems and inconsistencies and improving portability. There are a number +changes to the Go language and packages that we had considered for some time and +prototyped but not released primarily because they are significant and +backwards-incompatible. Go 1 was an opportunity to get them out, which is +helpful for the long term, but also means that Go 1 introduces incompatibilities +for old programs. Fortunately, the <code>go</code> <code>fix</code> tool can +automate much of the work needed to bring programs up to the Go 1 standard. +</p> + +<p> +This document outlines the major changes in Go 1 that will affect programmers +updating existing code; its reference point is the prior release, r60 (tagged as +r60.3). It also explains how to update code from r60 to run under Go 1. +</p> + +<h2 id="language">Changes to the language</h2> + +<h3 id="append">Append</h3> + +<p> +The <code>append</code> predeclared variadic function makes it easy to grow a slice +by adding elements to the end. +A common use is to add bytes to the end of a byte slice when generating output. +However, <code>append</code> did not provide a way to append a string to a <code>[]byte</code>, +which is another common case. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}} +--> greeting := []byte{} + greeting = append(greeting, []byte("hello ")...)</pre> + +<p> +By analogy with the similar property of <code>copy</code>, Go 1 +permits a string to be appended (byte-wise) directly to a byte +slice, reducing the friction between strings and byte slices. +The conversion is no longer necessary: +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/append.*world/`}} +--> greeting = append(greeting, "world"...)</pre> + +<p> +<em>Updating</em>: +This is a new feature, so existing code needs no changes. +</p> + +<h3 id="close">Close</h3> + +<p> +The <code>close</code> predeclared function provides a mechanism +for a sender to signal that no more values will be sent. +It is important to the implementation of <code>for</code> <code>range</code> +loops over channels and is helpful in other situations. +Partly by design and partly because of race conditions that can occur otherwise, +it is intended for use only by the goroutine sending on the channel, +not by the goroutine receiving data. +However, before Go 1 there was no compile-time checking that <code>close</code> +was being used correctly. +</p> + +<p> +To close this gap, at least in part, Go 1 disallows <code>close</code> on receive-only channels. +Attempting to close such a channel is a compile-time error. +</p> + +<pre> + var c chan int + var csend chan<- int = c + var crecv <-chan int = c + close(c) // legal + close(csend) // legal + close(crecv) // illegal +</pre> + +<p> +<em>Updating</em>: +Existing code that attempts to close a receive-only channel was +erroneous even before Go 1 and should be fixed. The compiler will +now reject such code. +</p> + +<h3 id="literals">Composite literals</h3> + +<p> +In Go 1, a composite literal of array, slice, or map type can elide the +type specification for the elements' initializers if they are of pointer type. +All four of the initializations in this example are legal; the last one was illegal before Go 1. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/type Date struct/` `/STOP/`}} +--> type Date struct { + month string + day int + } + <span class="comment">// Struct values, fully qualified; always legal.</span> + holiday1 := []Date{ + Date{"Feb", 14}, + Date{"Nov", 11}, + Date{"Dec", 25}, + } + <span class="comment">// Struct values, type name elided; always legal.</span> + holiday2 := []Date{ + {"Feb", 14}, + {"Nov", 11}, + {"Dec", 25}, + } + <span class="comment">// Pointers, fully qualified, always legal.</span> + holiday3 := []*Date{ + &Date{"Feb", 14}, + &Date{"Nov", 11}, + &Date{"Dec", 25}, + } + <span class="comment">// Pointers, type name elided; legal in Go 1.</span> + holiday4 := []*Date{ + {"Feb", 14}, + {"Nov", 11}, + {"Dec", 25}, + }</pre> + +<p> +<em>Updating</em>: +This change has no effect on existing code, but the command +<code>gofmt</code> <code>-s</code> applied to existing source +will, among other things, elide explicit element types wherever permitted. +</p> + + +<h3 id="init">Goroutines during init</h3> + +<p> +The old language defined that <code>go</code> statements executed during initialization created goroutines but that they did not begin to run until initialization of the entire program was complete. +This introduced clumsiness in many places and, in effect, limited the utility +of the <code>init</code> construct: +if it was possible for another package to use the library during initialization, the library +was forced to avoid goroutines. +This design was done for reasons of simplicity and safety but, +as our confidence in the language grew, it seemed unnecessary. +Running goroutines during initialization is no more complex or unsafe than running them during normal execution. +</p> + +<p> +In Go 1, code that uses goroutines can be called from +<code>init</code> routines and global initialization expressions +without introducing a deadlock. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/PackageGlobal/` `/^}/`}} +-->var PackageGlobal int + +func init() { + c := make(chan int) + go initializationFunction(c) + PackageGlobal = <-c +}</pre> + +<p> +<em>Updating</em>: +This is a new feature, so existing code needs no changes, +although it's possible that code that depends on goroutines not starting before <code>main</code> will break. +There was no such code in the standard repository. +</p> + +<h3 id="rune">The rune type</h3> + +<p> +The language spec allows the <code>int</code> type to be 32 or 64 bits wide, but current implementations set <code>int</code> to 32 bits even on 64-bit platforms. +It would be preferable to have <code>int</code> be 64 bits on 64-bit platforms. +(There are important consequences for indexing large slices.) +However, this change would waste space when processing Unicode characters with +the old language because the <code>int</code> type was also used to hold Unicode code points: each code point would waste an extra 32 bits of storage if <code>int</code> grew from 32 bits to 64. +</p> + +<p> +To make changing to 64-bit <code>int</code> feasible, +Go 1 introduces a new basic type, <code>rune</code>, to represent +individual Unicode code points. +It is an alias for <code>int32</code>, analogous to <code>byte</code> +as an alias for <code>uint8</code>. +</p> + +<p> +Character literals such as <code>'a'</code>, <code>'語'</code>, and <code>'\u0345'</code> +now have default type <code>rune</code>, +analogous to <code>1.0</code> having default type <code>float64</code>. +A variable initialized to a character constant will therefore +have type <code>rune</code> unless otherwise specified. +</p> + +<p> +Libraries have been updated to use <code>rune</code> rather than <code>int</code> +when appropriate. For instance, the functions <code>unicode.ToLower</code> and +relatives now take and return a <code>rune</code>. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}} +--> delta := 'δ' <span class="comment">// delta has type rune.</span> + var DELTA rune + DELTA = unicode.ToUpper(delta) + epsilon := unicode.ToLower(DELTA + 1) + if epsilon != 'δ'+1 { + log.Fatal("inconsistent casing for Greek") + }</pre> + +<p> +<em>Updating</em>: +Most source code will be unaffected by this because the type inference from +<code>:=</code> initializers introduces the new type silently, and it propagates +from there. +Some code may get type errors that a trivial conversion will resolve. +</p> + +<h3 id="error">The error type</h3> + +<p> +Go 1 introduces a new built-in type, <code>error</code>, which has the following definition: +</p> + +<pre> + type error interface { + Error() string + } +</pre> + +<p> +Since the consequences of this type are all in the package library, +it is discussed <a href="#errors">below</a>. +</p> + +<h3 id="delete">Deleting from maps</h3> + +<p> +In the old language, to delete the entry with key <code>k</code> from map <code>m</code>, one wrote the statement, +</p> + +<pre> + m[k] = value, false +</pre> + +<p> +This syntax was a peculiar special case, the only two-to-one assignment. +It required passing a value (usually ignored) that is evaluated but discarded, +plus a boolean that was nearly always the constant <code>false</code>. +It did the job but was odd and a point of contention. +</p> + +<p> +In Go 1, that syntax has gone; instead there is a new built-in +function, <code>delete</code>. The call +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/delete\(m, k\)/`}} +--> delete(m, k)</pre> + +<p> +will delete the map entry retrieved by the expression <code>m[k]</code>. +There is no return value. Deleting a non-existent entry is a no-op. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will convert expressions of the form <code>m[k] = value, +false</code> into <code>delete(m, k)</code> when it is clear that +the ignored value can be safely discarded from the program and +<code>false</code> refers to the predefined boolean constant. +The fix tool +will flag other uses of the syntax for inspection by the programmer. +</p> + +<h3 id="iteration">Iterating in maps</h3> + +<p> +The old language specification did not define the order of iteration for maps, +and in practice it differed across hardware platforms. +This caused tests that iterated over maps to be fragile and non-portable, with the +unpleasant property that a test might always pass on one machine but break on another. +</p> + +<p> +In Go 1, the order in which elements are visited when iterating +over a map using a <code>for</code> <code>range</code> statement +is defined to be unpredictable, even if the same loop is run multiple +times with the same map. +Code should not assume that the elements are visited in any particular order. +</p> + +<p> +This change means that code that depends on iteration order is very likely to break early and be fixed long before it becomes a problem. +Just as important, it allows the map implementation to ensure better map balancing even when programs are using range loops to select an element from a map. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/Sunday/` `/^ }/`}} +--> m := map[string]int{"Sunday": 0, "Monday": 1} + for name, value := range m { + <span class="comment">// This loop should not assume Sunday will be visited first.</span> + f(name, value) + }</pre> + +<p> +<em>Updating</em>: +This is one change where tools cannot help. Most existing code +will be unaffected, but some programs may break or misbehave; we +recommend manual checking of all range statements over maps to +verify they do not depend on iteration order. There were a few such +examples in the standard repository; they have been fixed. +Note that it was already incorrect to depend on the iteration order, which +was unspecified. This change codifies the unpredictability. +</p> + +<h3 id="multiple_assignment">Multiple assignment</h3> + +<p> +The language specification has long guaranteed that in assignments +the right-hand-side expressions are all evaluated before any left-hand-side expressions are assigned. +To guarantee predictable behavior, +Go 1 refines the specification further. +</p> + +<p> +If the left-hand side of the assignment +statement contains expressions that require evaluation, such as +function calls or array indexing operations, these will all be done +using the usual left-to-right rule before any variables are assigned +their value. Once everything is evaluated, the actual assignments +proceed in left-to-right order. +</p> + +<p> +These examples illustrate the behavior. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}} +--> sa := []int{1, 2, 3} + i := 0 + i, sa[i] = 1, 2 <span class="comment">// sets i = 1, sa[0] = 2</span> + + sb := []int{1, 2, 3} + j := 0 + sb[j], j = 2, 1 <span class="comment">// sets sb[0] = 2, j = 1</span> + + sc := []int{1, 2, 3} + sc[0], sc[0] = 1, 2 <span class="comment">// sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)</span></pre> + +<p> +<em>Updating</em>: +This is one change where tools cannot help, but breakage is unlikely. +No code in the standard repository was broken by this change, and code +that depended on the previous unspecified behavior was already incorrect. +</p> + +<h3 id="shadowing">Returns and shadowed variables</h3> + +<p> +A common mistake is to use <code>return</code> (without arguments) after an assignment to a variable that has the same name as a result variable but is not the same variable. +This situation is called <em>shadowing</em>: the result variable has been shadowed by another variable with the same name declared in an inner scope. +</p> + +<p> +In functions with named return values, +the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement. +(It isn't part of the specification, because this is one area we are still exploring; +the situation is analogous to the compilers rejecting functions that do not end with an explicit return statement.) +</p> + +<p> +This function implicitly returns a shadowed return value and will be rejected by the compiler: +</p> + +<pre> + func Bug() (i, j, k int) { + for i = 0; i < 5; i++ { + for j := 0; j < 5; j++ { // Redeclares j. + k += i*j + if k > 100 { + return // Rejected: j is shadowed here. + } + } + } + return // OK: j is not shadowed here. + } +</pre> + +<p> +<em>Updating</em>: +Code that shadows return values in this way will be rejected by the compiler and will need to be fixed by hand. +The few cases that arose in the standard repository were mostly bugs. +</p> + +<h3 id="unexported">Copying structs with unexported fields</h3> + +<p> +The old language did not allow a package to make a copy of a struct value containing unexported fields belonging to a different package. +There was, however, a required exception for a method receiver; +also, the implementations of <code>copy</code> and <code>append</code> have never honored the restriction. +</p> + +<p> +Go 1 will allow packages to copy struct values containing unexported fields from other packages. +Besides resolving the inconsistency, +this change admits a new kind of API: a package can return an opaque value without resorting to a pointer or interface. +The new implementations of <code>time.Time</code> and +<code>reflect.Value</code> are examples of types taking advantage of this new property. +</p> + +<p> +As an example, if package <code>p</code> includes the definitions, +</p> + +<pre> + type Struct struct { + Public int + secret int + } + func NewStruct(a int) Struct { // Note: not a pointer. + return Struct{a, f(a)} + } + func (s Struct) String() string { + return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret) + } +</pre> + +<p> +a package that imports <code>p</code> can assign and copy values of type +<code>p.Struct</code> at will. +Behind the scenes the unexported fields will be assigned and copied just +as if they were exported, +but the client code will never be aware of them. The code +</p> + +<pre> + import "p" + + myStruct := p.NewStruct(23) + copyOfMyStruct := myStruct + fmt.Println(myStruct, copyOfMyStruct) +</pre> + +<p> +will show that the secret field of the struct has been copied to the new value. +</p> + +<p> +<em>Updating</em>: +This is a new feature, so existing code needs no changes. +</p> + +<h3 id="equality">Equality</h3> + +<p> +Before Go 1, the language did not define equality on struct and array values. +This meant, +among other things, that structs and arrays could not be used as map keys. +On the other hand, Go did define equality on function and map values. +Function equality was problematic in the presence of closures +(when are two closures equal?) +while map equality compared pointers, not the maps' content, which was usually +not what the user would want. +</p> + +<p> +Go 1 addressed these issues. +First, structs and arrays can be compared for equality and inequality +(<code>==</code> and <code>!=</code>), +and therefore be used as map keys, +provided they are composed from elements for which equality is also defined, +using element-wise comparison. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/type Day struct/` `/Printf/`}} +--> type Day struct { + long string + short string + } + Christmas := Day{"Christmas", "XMas"} + Thanksgiving := Day{"Thanksgiving", "Turkey"} + holiday := map[Day]bool{ + Christmas: true, + Thanksgiving: true, + } + fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])</pre> + +<p> +Second, Go 1 removes the definition of equality for function values, +except for comparison with <code>nil</code>. +Finally, map equality is gone too, also except for comparison with <code>nil</code>. +</p> + +<p> +Note that equality is still undefined for slices, for which the +calculation is in general infeasible. Also note that the ordered +comparison operators (<code><</code> <code><=</code> +<code>></code> <code>>=</code>) are still undefined for +structs and arrays. + +<p> +<em>Updating</em>: +Struct and array equality is a new feature, so existing code needs no changes. +Existing code that depends on function or map equality will be +rejected by the compiler and will need to be fixed by hand. +Few programs will be affected, but the fix may require some +redesign. +</p> + +<h2 id="packages">The package hierarchy</h2> + +<p> +Go 1 addresses many deficiencies in the old standard library and +cleans up a number of packages, making them more internally consistent +and portable. +</p> + +<p> +This section describes how the packages have been rearranged in Go 1. +Some have moved, some have been renamed, some have been deleted. +New packages are described in later sections. +</p> + +<h3 id="hierarchy">The package hierarchy</h3> + +<p> +Go 1 has a rearranged package hierarchy that groups related items +into subdirectories. For instance, <code>utf8</code> and +<code>utf16</code> now occupy subdirectories of <code>unicode</code>. +Also, <a href="#subrepo">some packages</a> have moved into +subrepositories of +<a href="http://code.google.com/p/go"><code>code.google.com/p/go</code></a> +while <a href="#deleted">others</a> have been deleted outright. +</p> + +<table class="codetable" frame="border" summary="Moved packages"> +<colgroup align="left" width="60%"></colgroup> +<colgroup align="left" width="40%"></colgroup> +<tr> +<th align="left">Old path</th> +<th align="left">New path</th> +</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>asn1</td> <td>encoding/asn1</td></tr> +<tr><td>csv</td> <td>encoding/csv</td></tr> +<tr><td>gob</td> <td>encoding/gob</td></tr> +<tr><td>json</td> <td>encoding/json</td></tr> +<tr><td>xml</td> <td>encoding/xml</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>exp/template/html</td> <td>html/template</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>big</td> <td>math/big</td></tr> +<tr><td>cmath</td> <td>math/cmplx</td></tr> +<tr><td>rand</td> <td>math/rand</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>http</td> <td>net/http</td></tr> +<tr><td>http/cgi</td> <td>net/http/cgi</td></tr> +<tr><td>http/fcgi</td> <td>net/http/fcgi</td></tr> +<tr><td>http/httptest</td> <td>net/http/httptest</td></tr> +<tr><td>http/pprof</td> <td>net/http/pprof</td></tr> +<tr><td>mail</td> <td>net/mail</td></tr> +<tr><td>rpc</td> <td>net/rpc</td></tr> +<tr><td>rpc/jsonrpc</td> <td>net/rpc/jsonrpc</td></tr> +<tr><td>smtp</td> <td>net/smtp</td></tr> +<tr><td>url</td> <td>net/url</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>exec</td> <td>os/exec</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>scanner</td> <td>text/scanner</td></tr> +<tr><td>tabwriter</td> <td>text/tabwriter</td></tr> +<tr><td>template</td> <td>text/template</td></tr> +<tr><td>template/parse</td> <td>text/template/parse</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>utf8</td> <td>unicode/utf8</td></tr> +<tr><td>utf16</td> <td>unicode/utf16</td></tr> +</table> + +<p> +Note that the package names for the old <code>cmath</code> and +<code>exp/template/html</code> packages have changed to <code>cmplx</code> +and <code>template</code>. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update all imports and package renames for packages that +remain inside the standard repository. Programs that import packages +that are no longer in the standard repository will need to be edited +by hand. +</p> + +<h3 id="exp">The package tree exp</h3> + +<p> +Because they are not standardized, the packages under the <code>exp</code> directory will not be available in the +standard Go 1 release distributions, although they will be available in source code form +in <a href="http://code.google.com/p/go/">the repository</a> for +developers who wish to use them. +</p> + +<p> +Several packages have moved under <code>exp</code> at the time of Go 1's release: +</p> + +<ul> +<li><code>ebnf</code></li> +<li><code>html</code><sup>†</sup></li> +<li><code>go/types</code></li> +</ul> + +<p> +(<sup>†</sup>The <code>EscapeString</code> and <code>UnescapeString</code> types remain +in package <code>html</code>.) +</p> + +<p> +All these packages are available under the same names, with the prefix <code>exp/</code>: <code>exp/ebnf</code> etc. +</p> + +<p> +Also, the <code>utf8.String</code> type has been moved to its own package, <code>exp/utf8string</code>. +</p> + +<p> +Finally, the <code>gotype</code> command now resides in <code>exp/gotype</code>, while +<code>ebnflint</code> is now in <code>exp/ebnflint</code>. +If they are installed, they now reside in <code>$GOROOT/bin/tool</code>. +</p> + +<p> +<em>Updating</em>: +Code that uses packages in <code>exp</code> will need to be updated by hand, +or else compiled from an installation that has <code>exp</code> available. +The <code>go</code> <code>fix</code> tool or the compiler will complain about such uses. +</p> + +<h3 id="old">The package tree old</h3> + +<p> +Because they are deprecated, the packages under the <code>old</code> directory will not be available in the +standard Go 1 release distributions, although they will be available in source code form for +developers who wish to use them. +</p> + +<p> +The packages in their new locations are: +</p> + +<ul> +<li><code>old/netchan</code></li> +<li><code>old/regexp</code></li> +<li><code>old/template</code></li> +</ul> + +<p> +<em>Updating</em>: +Code that uses packages now in <code>old</code> will need to be updated by hand, +or else compiled from an installation that has <code>old</code> available. +The <code>go</code> <code>fix</code> tool will warn about such uses. +</p> + +<h3 id="deleted">Deleted packages</h3> + +<p> +Go 1 deletes several packages outright: +</p> + +<ul> +<li><code>container/vector</code></li> +<li><code>exp/datafmt</code></li> +<li><code>go/typechecker</code></li> +<li><code>try</code></li> +</ul> + +<p> +and also the command <code>gotry</code>. +</p> + +<p> +<em>Updating</em>: +Code that uses <code>container/vector</code> should be updated to use +slices directly. See +<a href="http://code.google.com/p/go-wiki/wiki/SliceTricks">the Go +Language Community Wiki</a> for some suggestions. +Code that uses the other packages (there should be almost zero) will need to be rethought. +</p> + +<h3 id="subrepo">Packages moving to subrepositories</h3> + +<p> +Go 1 has moved a number of packages into other repositories, usually sub-repositories of +<a href="http://code.google.com/p/go/">the main Go repository</a>. +This table lists the old and new import paths: + +<table class="codetable" frame="border" summary="Sub-repositories"> +<colgroup align="left" width="40%"></colgroup> +<colgroup align="left" width="60%"></colgroup> +<tr> +<th align="left">Old</th> +<th align="left">New</th> +</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>crypto/bcrypt</td> <td>code.google.com/p/go.crypto/bcrypt</tr> +<tr><td>crypto/blowfish</td> <td>code.google.com/p/go.crypto/blowfish</tr> +<tr><td>crypto/cast5</td> <td>code.google.com/p/go.crypto/cast5</tr> +<tr><td>crypto/md4</td> <td>code.google.com/p/go.crypto/md4</tr> +<tr><td>crypto/ocsp</td> <td>code.google.com/p/go.crypto/ocsp</tr> +<tr><td>crypto/openpgp</td> <td>code.google.com/p/go.crypto/openpgp</tr> +<tr><td>crypto/openpgp/armor</td> <td>code.google.com/p/go.crypto/openpgp/armor</tr> +<tr><td>crypto/openpgp/elgamal</td> <td>code.google.com/p/go.crypto/openpgp/elgamal</tr> +<tr><td>crypto/openpgp/errors</td> <td>code.google.com/p/go.crypto/openpgp/errors</tr> +<tr><td>crypto/openpgp/packet</td> <td>code.google.com/p/go.crypto/openpgp/packet</tr> +<tr><td>crypto/openpgp/s2k</td> <td>code.google.com/p/go.crypto/openpgp/s2k</tr> +<tr><td>crypto/ripemd160</td> <td>code.google.com/p/go.crypto/ripemd160</tr> +<tr><td>crypto/twofish</td> <td>code.google.com/p/go.crypto/twofish</tr> +<tr><td>crypto/xtea</td> <td>code.google.com/p/go.crypto/xtea</tr> +<tr><td>exp/ssh</td> <td>code.google.com/p/go.crypto/ssh</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>image/bmp</td> <td>code.google.com/p/go.image/bmp</tr> +<tr><td>image/tiff</td> <td>code.google.com/p/go.image/tiff</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>net/dict</td> <td>code.google.com/p/go.net/dict</tr> +<tr><td>net/websocket</td> <td>code.google.com/p/go.net/websocket</tr> +<tr><td>exp/spdy</td> <td>code.google.com/p/go.net/spdy</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>encoding/git85</td> <td>code.google.com/p/go.codereview/git85</tr> +<tr><td>patch</td> <td>code.google.com/p/go.codereview/patch</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>exp/wingui</td> <td>code.google.com/p/gowingui</tr> +</table> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update imports of these packages to use the new import paths. +Installations that depend on these packages will need to install them using +a <code>go get</code> command. +</p> + +<h2 id="major">Major changes to the library</h2> + +<p> +This section describes significant changes to the core libraries, the ones that +affect the most programs. +</p> + +<h3 id="errors">The error type and errors package</h3> + +<p> +The placement of <code>os.Error</code> in package <code>os</code> is mostly historical: errors first came up when implementing package <code>os</code>, and they seemed system-related at the time. +Since then it has become clear that errors are more fundamental than the operating system. For example, it would be nice to use <code>Errors</code> in packages that <code>os</code> depends on, like <code>syscall</code>. +Also, having <code>Error</code> in <code>os</code> introduces many dependencies on <code>os</code> that would otherwise not exist. +</p> + +<p> +Go 1 solves these problems by introducing a built-in <code>error</code> interface type and a separate <code>errors</code> package (analogous to <code>bytes</code> and <code>strings</code>) that contains utility functions. +It replaces <code>os.NewError</code> with +<a href="/pkg/errors/#New"><code>errors.New</code></a>, +giving errors a more central place in the environment. +</p> + +<p> +So the widely-used <code>String</code> method does not cause accidental satisfaction +of the <code>error</code> interface, the <code>error</code> interface uses instead +the name <code>Error</code> for that method: +</p> + +<pre> + type error interface { + Error() string + } +</pre> + +<p> +The <code>fmt</code> library automatically invokes <code>Error</code>, as it already +does for <code>String</code>, for easy printing of error values. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/START ERROR EXAMPLE/` `/END ERROR EXAMPLE/`}} +-->type SyntaxError struct { + File string + Line int + Message string +} + +func (se *SyntaxError) Error() string { + return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message) +}</pre> + +<p> +All standard packages have been updated to use the new interface; the old <code>os.Error</code> is gone. +</p> + +<p> +A new package, <a href="/pkg/errors/"><code>errors</code></a>, contains the function +</p> + +<pre> +func New(text string) error +</pre> + +<p> +to turn a string into an error. It replaces the old <code>os.NewError</code>. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/ErrSyntax/`}} +--> var ErrSyntax = errors.New("syntax error")</pre> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update almost all code affected by the change. +Code that defines error types with a <code>String</code> method will need to be updated +by hand to rename the methods to <code>Error</code>. +</p> + +<h3 id="errno">System call errors</h3> + +<p> +The old <code>syscall</code> package, which predated <code>os.Error</code> +(and just about everything else), +returned errors as <code>int</code> values. +In turn, the <code>os</code> package forwarded many of these errors, such +as <code>EINVAL</code>, but using a different set of errors on each platform. +This behavior was unpleasant and unportable. +</p> + +<p> +In Go 1, the +<a href="/pkg/syscall/"><code>syscall</code></a> +package instead returns an <code>error</code> for system call errors. +On Unix, the implementation is done by a +<a href="/pkg/syscall/#Errno"><code>syscall.Errno</code></a> type +that satisfies <code>error</code> and replaces the old <code>os.Errno</code>. +</p> + +<p> +The changes affecting <code>os.EINVAL</code> and relatives are +described <a href="#os">elsewhere</a>. + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update almost all code affected by the change. +Regardless, most code should use the <code>os</code> package +rather than <code>syscall</code> and so will be unaffected. +</p> + +<h3 id="time">Time</h3> + +<p> +Time is always a challenge to support well in a programming language. +The old Go <code>time</code> package had <code>int64</code> units, no +real type safety, +and no distinction between absolute times and durations. +</p> + +<p> +One of the most sweeping changes in the Go 1 library is therefore a +complete redesign of the +<a href="/pkg/time/"><code>time</code></a> package. +Instead of an integer number of nanoseconds as an <code>int64</code>, +and a separate <code>*time.Time</code> type to deal with human +units such as hours and years, +there are now two fundamental types: +<a href="/pkg/time/#Time"><code>time.Time</code></a> +(a value, so the <code>*</code> is gone), which represents a moment in time; +and <a href="/pkg/time/#Duration"><code>time.Duration</code></a>, +which represents an interval. +Both have nanosecond resolution. +A <code>Time</code> can represent any time into the ancient +past and remote future, while a <code>Duration</code> can +span plus or minus only about 290 years. +There are methods on these types, plus a number of helpful +predefined constant durations such as <code>time.Second</code>. +</p> + +<p> +Among the new methods are things like +<a href="/pkg/time/#Time.Add"><code>Time.Add</code></a>, +which adds a <code>Duration</code> to a <code>Time</code>, and +<a href="/pkg/time/#Time.Sub"><code>Time.Sub</code></a>, +which subtracts two <code>Times</code> to yield a <code>Duration</code>. +</p> + +<p> +The most important semantic change is that the Unix epoch (Jan 1, 1970) is now +relevant only for those functions and methods that mention Unix: +<a href="/pkg/time/#Unix"><code>time.Unix</code></a> +and the <a href="/pkg/time/#Time.Unix"><code>Unix</code></a> +and <a href="/pkg/time/#Time.UnixNano"><code>UnixNano</code></a> methods +of the <code>Time</code> type. +In particular, +<a href="/pkg/time/#Now"><code>time.Now</code></a> +returns a <code>time.Time</code> value rather than, in the old +API, an integer nanosecond count since the Unix epoch. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/sleepUntil/` `/^}/`}} +--><span class="comment">// sleepUntil sleeps until the specified time. It returns immediately if it's too late.</span> +func sleepUntil(wakeup time.Time) { + now := time.Now() <span class="comment">// A Time.</span> + if !wakeup.After(now) { + return + } + delta := wakeup.Sub(now) <span class="comment">// A Duration.</span> + fmt.Printf("Sleeping for %.3fs\n", delta.Seconds()) + time.Sleep(delta) +}</pre> + +<p> +The new types, methods, and constants have been propagated through +all the standard packages that use time, such as <code>os</code> and +its representation of file time stamps. +</p> + +<p> +<em>Updating</em>: +The <code>go</code> <code>fix</code> tool will update many uses of the old <code>time</code> package to use the new +types and methods, although it does not replace values such as <code>1e9</code> +representing nanoseconds per second. +Also, because of type changes in some of the values that arise, +some of the expressions rewritten by the fix tool may require +further hand editing; in such cases the rewrite will include +the correct function or method for the old functionality, but +may have the wrong type or require further analysis. +</p> + +<h2 id="minor">Minor changes to the library</h2> + +<p> +This section describes smaller changes, such as those to less commonly +used packages or that affect +few programs beyond the need to run <code>go</code> <code>fix</code>. +This category includes packages that are new in Go 1. +Collectively they improve portability, regularize behavior, and +make the interfaces more modern and Go-like. +</p> + +<h3 id="archive_zip">The archive/zip package</h3> + +<p> +In Go 1, <a href="/pkg/archive/zip/#Writer"><code>*zip.Writer</code></a> no +longer has a <code>Write</code> method. Its presence was a mistake. +</p> + +<p> +<em>Updating</em>: +What little code is affected will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="bufio">The bufio package</h3> + +<p> +In Go 1, <a href="/pkg/bufio/#NewReaderSize"><code>bufio.NewReaderSize</code></a> +and +<a href="/pkg/bufio/#NewWriterSize"><code>bufio.NewWriterSize</code></a> +functions no longer return an error for invalid sizes. +If the argument size is too small or invalid, it is adjusted. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update calls that assign the error to _. +Calls that aren't fixed will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="compress">The compress/flate, compress/gzip and compress/zlib packages</h3> + +<p> +In Go 1, the <code>NewWriterXxx</code> functions in +<a href="/pkg/compress/flate"><code>compress/flate</code></a>, +<a href="/pkg/compress/gzip"><code>compress/gzip</code></a> and +<a href="/pkg/compress/zlib"><code>compress/zlib</code></a> +all return <code>(*Writer, error)</code> if they take a compression level, +and <code>*Writer</code> otherwise. Package <code>gzip</code>'s +<code>Compressor</code> and <code>Decompressor</code> types have been renamed +to <code>Writer</code> and <code>Reader</code>. Package <code>flate</code>'s +<code>WrongValueError</code> type has been removed. +</p> + +<p> +<em>Updating</em> +Running <code>go</code> <code>fix</code> will update old names and calls that assign the error to _. +Calls that aren't fixed will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="crypto_aes_des">The crypto/aes and crypto/des packages</h3> + +<p> +In Go 1, the <code>Reset</code> method has been removed. Go does not guarantee +that memory is not copied and therefore this method was misleading. +</p> + +<p> +The cipher-specific types <code>*aes.Cipher</code>, <code>*des.Cipher</code>, +and <code>*des.TripleDESCipher</code> have been removed in favor of +<code>cipher.Block</code>. +</p> + +<p> +<em>Updating</em>: +Remove the calls to Reset. Replace uses of the specific cipher types with +cipher.Block. +</p> + +<h3 id="crypto_elliptic">The crypto/elliptic package</h3> + +<p> +In Go 1, <a href="/pkg/crypto/elliptic/#Curve"><code>elliptic.Curve</code></a> +has been made an interface to permit alternative implementations. The curve +parameters have been moved to the +<a href="/pkg/crypto/elliptic/#CurveParams"><code>elliptic.CurveParams</code></a> +structure. +</p> + +<p> +<em>Updating</em>: +Existing users of <code>*elliptic.Curve</code> will need to change to +simply <code>elliptic.Curve</code>. Calls to <code>Marshal</code>, +<code>Unmarshal</code> and <code>GenerateKey</code> are now functions +in <code>crypto/elliptic</code> that take an <code>elliptic.Curve</code> +as their first argument. +</p> + +<h3 id="crypto_hmac">The crypto/hmac package</h3> + +<p> +In Go 1, the hash-specific functions, such as <code>hmac.NewMD5</code>, have +been removed from <code>crypto/hmac</code>. Instead, <code>hmac.New</code> takes +a function that returns a <code>hash.Hash</code>, such as <code>md5.New</code>. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will perform the needed changes. +</p> + +<h3 id="crypto_x509">The crypto/x509 package</h3> + +<p> +In Go 1, the +<a href="/pkg/crypto/x509/#CreateCertificate"><code>CreateCertificate</code></a> +and +<a href="/pkg/crypto/x509/#CreateCRL"><code>CreateCRL</code></a> +functions in <code>crypto/x509</code> have been altered to take an +<code>interface{}</code> where they previously took a <code>*rsa.PublicKey</code> +or <code>*rsa.PrivateKey</code>. This will allow other public key algorithms +to be implemented in the future. +</p> + +<p> +<em>Updating</em>: +No changes will be needed. +</p> + +<h3 id="encoding_binary">The encoding/binary package</h3> + +<p> +In Go 1, the <code>binary.TotalSize</code> function has been replaced by +<a href="/pkg/encoding/binary/#Size"><code>Size</code></a>, +which takes an <code>interface{}</code> argument rather than +a <code>reflect.Value</code>. +</p> + +<p> +<em>Updating</em>: +What little code is affected will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="encoding_xml">The encoding/xml package</h3> + +<p> +In Go 1, the <a href="/pkg/encoding/xml/"><code>xml</code></a> package +has been brought closer in design to the other marshaling packages such +as <a href="/pkg/encoding/gob/"><code>encoding/gob</code></a>. +</p> + +<p> +The old <code>Parser</code> type is renamed +<a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> and has a new +<a href="/pkg/encoding/xml/#Decoder.Decode"><code>Decode</code></a> method. An +<a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> type was also introduced. +</p> + +<p> +The functions <a href="/pkg/encoding/xml/#Marshal"><code>Marshal</code></a> +and <a href="/pkg/encoding/xml/#Unmarshal"><code>Unmarshal</code></a> +work with <code>[]byte</code> values now. To work with streams, +use the new <a href="/pkg/encoding/xml/#Encoder"><code>Encoder</code></a> +and <a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> types. +</p> + +<p> +When marshaling or unmarshaling values, the format of supported flags in +field tags has changed to be closer to the +<a href="/pkg/encoding/json"><code>json</code></a> package +(<code>`xml:"name,flag"`</code>). The matching done between field tags, field +names, and the XML attribute and element names is now case-sensitive. +The <code>XMLName</code> field tag, if present, must also match the name +of the XML element being marshaled. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update most uses of the package except for some calls to +<code>Unmarshal</code>. Special care must be taken with field tags, +since the fix tool will not update them and if not fixed by hand they will +misbehave silently in some cases. For example, the old +<code>"attr"</code> is now written <code>",attr"</code> while plain +<code>"attr"</code> remains valid but with a different meaning. +</p> + +<h3 id="expvar">The expvar package</h3> + +<p> +In Go 1, the <code>RemoveAll</code> function has been removed. +The <code>Iter</code> function and Iter method on <code>*Map</code> have +been replaced by +<a href="/pkg/expvar/#Do"><code>Do</code></a> +and +<a href="/pkg/expvar/#Map.Do"><code>(*Map).Do</code></a>. +</p> + +<p> +<em>Updating</em>: +Most code using <code>expvar</code> will not need changing. The rare code that used +<code>Iter</code> can be updated to pass a closure to <code>Do</code> to achieve the same effect. +</p> + +<h3 id="flag">The flag package</h3> + +<p> +In Go 1, the interface <a href="/pkg/flag/#Value"><code>flag.Value</code></a> has changed slightly. +The <code>Set</code> method now returns an <code>error</code> instead of +a <code>bool</code> to indicate success or failure. +</p> + +<p> +There is also a new kind of flag, <code>Duration</code>, to support argument +values specifying time intervals. +Values for such flags must be given units, just as <code>time.Duration</code> +formats them: <code>10s</code>, <code>1h30m</code>, etc. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/timeout/`}} +-->var timeout = flag.Duration("timeout", 30*time.Second, "how long to wait for completion")</pre> + +<p> +<em>Updating</em>: +Programs that implement their own flags will need minor manual fixes to update their +<code>Set</code> methods. +The <code>Duration</code> flag is new and affects no existing code. +</p> + + +<h3 id="go">The go/* packages</h3> + +<p> +Several packages under <code>go</code> have slightly revised APIs. +</p> + +<p> +A concrete <code>Mode</code> type was introduced for configuration mode flags +in the packages +<a href="/pkg/go/scanner/"><code>go/scanner</code></a>, +<a href="/pkg/go/parser/"><code>go/parser</code></a>, +<a href="/pkg/go/printer/"><code>go/printer</code></a>, and +<a href="/pkg/go/doc/"><code>go/doc</code></a>. +</p> + +<p> +The modes <code>AllowIllegalChars</code> and <code>InsertSemis</code> have been removed +from the <a href="/pkg/go/scanner/"><code>go/scanner</code></a> package. They were mostly +useful for scanning text other then Go source files. Instead, the +<a href="/pkg/text/scanner/"><code>text/scanner</code></a> package should be used +for that purpose. +</p> + +<p> +The <a href="/pkg/go/scanner/#ErrorHandler"><code>ErrorHandler</code></a> provided +to the scanner's <a href="/pkg/go/scanner/#Scanner.Init"><code>Init</code></a> method is +now simply a function rather than an interface. The <code>ErrorVector</code> type has +been removed in favor of the (existing) <a href="/pkg/go/scanner/#ErrorList"><code>ErrorList</code></a> +type, and the <code>ErrorVector</code> methods have been migrated. Instead of embedding +an <code>ErrorVector</code> in a client of the scanner, now a client should maintain +an <code>ErrorList</code>. +</p> + +<p> +The set of parse functions provided by the <a href="/pkg/go/parser/"><code>go/parser</code></a> +package has been reduced to the primary parse function +<a href="/pkg/go/parser/#ParseFile"><code>ParseFile</code></a>, and a couple of +convenience functions <a href="/pkg/go/parser/#ParseDir"><code>ParseDir</code></a> +and <a href="/pkg/go/parser/#ParseExpr"><code>ParseExpr</code></a>. +</p> + +<p> +The <a href="/pkg/go/printer/"><code>go/printer</code></a> package supports an additional +configuration mode <a href="/pkg/go/printer/#Mode"><code>SourcePos</code></a>; +if set, the printer will emit <code>//line</code> comments such that the generated +output contains the original source code position information. The new type +<a href="/pkg/go/printer/#CommentedNode"><code>CommentedNode</code></a> can be +used to provide comments associated with an arbitrary +<a href="/pkg/go/ast/#Node"><code>ast.Node</code></a> (until now only +<a href="/pkg/go/ast/#File"><code>ast.File</code></a> carried comment information). +</p> + +<p> +The type names of the <a href="/pkg/go/doc/"><code>go/doc</code></a> package have been +streamlined by removing the <code>Doc</code> suffix: <code>PackageDoc</code> +is now <code>Package</code>, <code>ValueDoc</code> is <code>Value</code>, etc. +Also, all types now consistently have a <code>Name</code> field (or <code>Names</code>, +in the case of type <code>Value</code>) and <code>Type.Factories</code> has become +<code>Type.Funcs</code>. +Instead of calling <code>doc.NewPackageDoc(pkg, importpath)</code>, +documentation for a package is created with: +</p> + +<pre> + doc.New(pkg, importpath, mode) +</pre> + +<p> +where the new <code>mode</code> parameter specifies the operation mode: +if set to <a href="/pkg/go/doc/#AllDecls"><code>AllDecls</code></a>, all declarations +(not just exported ones) are considered. +The function <code>NewFileDoc</code> was removed, and the function +<code>CommentText</code> has become the method +<a href="/pkg/go/ast/#Text"><code>Text</code></a> of +<a href="/pkg/go/ast/#CommentGroup"><code>ast.CommentGroup</code></a>. +</p> + +<p> +In package <a href="/pkg/go/token/"><code>go/token</code></a>, the +<a href="/pkg/go/token/#FileSet"><code>token.FileSet</code></a> method <code>Files</code> +(which originally returned a channel of <code>*token.File</code>s) has been replaced +with the iterator <a href="/pkg/go/token/#FileSet.Iterate"><code>Iterate</code></a> that +accepts a function argument instead. +</p> + +<p> +In package <a href="/pkg/go/build/"><code>go/build</code></a>, the API +has been nearly completely replaced. +The package still computes Go package information +but it does not run the build: the <code>Cmd</code> and <code>Script</code> +types are gone. +(To build code, use the new +<a href="/cmd/go/"><code>go</code></a> command instead.) +The <code>DirInfo</code> type is now named +<a href="/pkg/go/build/#Package"><code>Package</code></a>. +<code>FindTree</code> and <code>ScanDir</code> are replaced by +<a href="/pkg/go/build/#Import"><code>Import</code></a> +and +<a href="/pkg/go/build/#ImportDir"><code>ImportDir</code></a>. +</p> + +<p> +<em>Updating</em>: +Code that uses packages in <code>go</code> will have to be updated by hand; the +compiler will reject incorrect uses. Templates used in conjunction with any of the +<code>go/doc</code> types may need manual fixes; the renamed fields will lead +to run-time errors. +</p> + +<h3 id="hash">The hash package</h3> + +<p> +In Go 1, the definition of <a href="/pkg/hash/#Hash"><code>hash.Hash</code></a> includes +a new method, <code>BlockSize</code>. This new method is used primarily in the +cryptographic libraries. +</p> + +<p> +The <code>Sum</code> method of the +<a href="/pkg/hash/#Hash"><code>hash.Hash</code></a> interface now takes a +<code>[]byte</code> argument, to which the hash value will be appended. +The previous behavior can be recreated by adding a <code>nil</code> argument to the call. +</p> + +<p> +<em>Updating</em>: +Existing implementations of <code>hash.Hash</code> will need to add a +<code>BlockSize</code> method. Hashes that process the input one byte at +a time can implement <code>BlockSize</code> to return 1. +Running <code>go</code> <code>fix</code> will update calls to the <code>Sum</code> methods of the various +implementations of <code>hash.Hash</code>. +</p> + +<p> +<em>Updating</em>: +Since the package's functionality is new, no updating is necessary. +</p> + +<h3 id="http">The http package</h3> + +<p> +In Go 1 the <a href="/pkg/net/http/"><code>http</code></a> package is refactored, +putting some of the utilities into a +<a href="/pkg/net/http/httputil/"><code>httputil</code></a> subdirectory. +These pieces are only rarely needed by HTTP clients. +The affected items are: +</p> + +<ul> +<li>ClientConn</li> +<li>DumpRequest</li> +<li>DumpRequestOut</li> +<li>DumpResponse</li> +<li>NewChunkedReader</li> +<li>NewChunkedWriter</li> +<li>NewClientConn</li> +<li>NewProxyClientConn</li> +<li>NewServerConn</li> +<li>NewSingleHostReverseProxy</li> +<li>ReverseProxy</li> +<li>ServerConn</li> +</ul> + +<p> +The <code>Request.RawURL</code> field has been removed; it was a +historical artifact. +</p> + +<p> +The <code>Handle</code> and <code>HandleFunc</code> +functions, and the similarly-named methods of <code>ServeMux</code>, +now panic if an attempt is made to register the same pattern twice. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update the few programs that are affected except for +uses of <code>RawURL</code>, which must be fixed by hand. +</p> + +<h3 id="image">The image package</h3> + +<p> +The <a href="/pkg/image/"><code>image</code></a> package has had a number of +minor changes, rearrangements and renamings. +</p> + +<p> +Most of the color handling code has been moved into its own package, +<a href="/pkg/image/color/"><code>image/color</code></a>. +For the elements that moved, a symmetry arises; for instance, +each pixel of an +<a href="/pkg/image/#RGBA"><code>image.RGBA</code></a> +is a +<a href="/pkg/image/color/#RGBA"><code>color.RGBA</code></a>. +</p> + +<p> +The old <code>image/ycbcr</code> package has been folded, with some +renamings, into the +<a href="/pkg/image/"><code>image</code></a> +and +<a href="/pkg/image/color/"><code>image/color</code></a> +packages. +</p> + +<p> +The old <code>image.ColorImage</code> type is still in the <code>image</code> +package but has been renamed +<a href="/pkg/image/#Uniform"><code>image.Uniform</code></a>, +while <code>image.Tiled</code> has been removed. +</p> + +<p> +This table lists the renamings. +</p> + +<table class="codetable" frame="border" summary="image renames"> +<colgroup align="left" width="50%"></colgroup> +<colgroup align="left" width="50%"></colgroup> +<tr> +<th align="left">Old</th> +<th align="left">New</th> +</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>image.Color</td> <td>color.Color</td></tr> +<tr><td>image.ColorModel</td> <td>color.Model</td></tr> +<tr><td>image.ColorModelFunc</td> <td>color.ModelFunc</td></tr> +<tr><td>image.PalettedColorModel</td> <td>color.Palette</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>image.RGBAColor</td> <td>color.RGBA</td></tr> +<tr><td>image.RGBA64Color</td> <td>color.RGBA64</td></tr> +<tr><td>image.NRGBAColor</td> <td>color.NRGBA</td></tr> +<tr><td>image.NRGBA64Color</td> <td>color.NRGBA64</td></tr> +<tr><td>image.AlphaColor</td> <td>color.Alpha</td></tr> +<tr><td>image.Alpha16Color</td> <td>color.Alpha16</td></tr> +<tr><td>image.GrayColor</td> <td>color.Gray</td></tr> +<tr><td>image.Gray16Color</td> <td>color.Gray16</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>image.RGBAColorModel</td> <td>color.RGBAModel</td></tr> +<tr><td>image.RGBA64ColorModel</td> <td>color.RGBA64Model</td></tr> +<tr><td>image.NRGBAColorModel</td> <td>color.NRGBAModel</td></tr> +<tr><td>image.NRGBA64ColorModel</td> <td>color.NRGBA64Model</td></tr> +<tr><td>image.AlphaColorModel</td> <td>color.AlphaModel</td></tr> +<tr><td>image.Alpha16ColorModel</td> <td>color.Alpha16Model</td></tr> +<tr><td>image.GrayColorModel</td> <td>color.GrayModel</td></tr> +<tr><td>image.Gray16ColorModel</td> <td>color.Gray16Model</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>ycbcr.RGBToYCbCr</td> <td>color.RGBToYCbCr</td></tr> +<tr><td>ycbcr.YCbCrToRGB</td> <td>color.YCbCrToRGB</td></tr> +<tr><td>ycbcr.YCbCrColorModel</td> <td>color.YCbCrModel</td></tr> +<tr><td>ycbcr.YCbCrColor</td> <td>color.YCbCr</td></tr> +<tr><td>ycbcr.YCbCr</td> <td>image.YCbCr</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>ycbcr.SubsampleRatio444</td> <td>image.YCbCrSubsampleRatio444</td></tr> +<tr><td>ycbcr.SubsampleRatio422</td> <td>image.YCbCrSubsampleRatio422</td></tr> +<tr><td>ycbcr.SubsampleRatio420</td> <td>image.YCbCrSubsampleRatio420</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>image.ColorImage</td> <td>image.Uniform</td></tr> +</table> + +<p> +The image package's <code>New</code> functions +(<a href="/pkg/image/#NewRGBA"><code>NewRGBA</code></a>, +<a href="/pkg/image/#NewRGBA64"><code>NewRGBA64</code></a>, etc.) +take an <a href="/pkg/image/#Rectangle"><code>image.Rectangle</code></a> as an argument +instead of four integers. +</p> + +<p> +Finally, there are new predefined <code>color.Color</code> variables +<a href="/pkg/image/color/#Black"><code>color.Black</code></a>, +<a href="/pkg/image/color/#White"><code>color.White</code></a>, +<a href="/pkg/image/color/#Opaque"><code>color.Opaque</code></a> +and +<a href="/pkg/image/color/#Transparent"><code>color.Transparent</code></a>. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update almost all code affected by the change. +</p> + +<h3 id="log_syslog">The log/syslog package</h3> + +<p> +In Go 1, the <a href="/pkg/log/syslog/#NewLogger"><code>syslog.NewLogger</code></a> +function returns an error as well as a <code>log.Logger</code>. +</p> + +<p> +<em>Updating</em>: +What little code is affected will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="mime">The mime package</h3> + +<p> +In Go 1, the <a href="/pkg/mime/#FormatMediaType"><code>FormatMediaType</code></a> function +of the <code>mime</code> package has been simplified to make it +consistent with +<a href="/pkg/mime/#ParseMediaType"><code>ParseMediaType</code></a>. +It now takes <code>"text/html"</code> rather than <code>"text"</code> and <code>"html"</code>. +</p> + +<p> +<em>Updating</em>: +What little code is affected will be caught by the compiler and must be updated by hand. +</p> + +<h3 id="net">The net package</h3> + +<p> +In Go 1, the various <code>SetTimeout</code>, +<code>SetReadTimeout</code>, and <code>SetWriteTimeout</code> methods +have been replaced with +<a href="/pkg/net/#IPConn.SetDeadline"><code>SetDeadline</code></a>, +<a href="/pkg/net/#IPConn.SetReadDeadline"><code>SetReadDeadline</code></a>, and +<a href="/pkg/net/#IPConn.SetWriteDeadline"><code>SetWriteDeadline</code></a>, +respectively. Rather than taking a timeout value in nanoseconds that +apply to any activity on the connection, the new methods set an +absolute deadline (as a <code>time.Time</code> value) after which +reads and writes will time out and no longer block. +</p> + +<p> +There are also new functions +<a href="/pkg/net/#DialTimeout"><code>net.DialTimeout</code></a> +to simplify timing out dialing a network address and +<a href="/pkg/net/#ListenMulticastUDP"><code>net.ListenMulticastUDP</code></a> +to allow multicast UDP to listen concurrently across multiple listeners. +The <code>net.ListenMulticastUDP</code> function replaces the old +<code>JoinGroup</code> and <code>LeaveGroup</code> methods. +</p> + +<p> +<em>Updating</em>: +Code that uses the old methods will fail to compile and must be updated by hand. +The semantic change makes it difficult for the fix tool to update automatically. +</p> + +<h3 id="os">The os package</h3> + +<p> +The <code>Time</code> function has been removed; callers should use +the <a href="/pkg/time/#Time"><code>Time</code></a> type from the +<code>time</code> package. +</p> + +<p> +The <code>Exec</code> function has been removed; callers should use +<code>Exec</code> from the <code>syscall</code> package, where available. +</p> + +<p> +The <code>ShellExpand</code> function has been renamed to <a +href="/pkg/os/#ExpandEnv"><code>ExpandEnv</code></a>. +</p> + +<p> +The <a href="/pkg/os/#NewFile"><code>NewFile</code></a> function +now takes a <code>uintptr</code> fd, instead of an <code>int</code>. +The <a href="/pkg/os/#File.Fd"><code>Fd</code></a> method on files now +also returns a <code>uintptr</code>. +</p> + +<p> +There are no longer error constants such as <code>EINVAL</code> +in the <code>os</code> package, since the set of values varied with +the underlying operating system. There are new portable functions like +<a href="/pkg/os/#IsPermission"><code>IsPermission</code></a> +to test common error properties, plus a few new error values +with more Go-like names, such as +<a href="/pkg/os/#ErrPermission"><code>ErrPermission</code></a> +and +<a href="/pkg/os/#ErrNoEnv"><code>ErrNoEnv</code></a>. +</p> + +<p> +The <code>Getenverror</code> function has been removed. To distinguish +between a non-existent environment variable and an empty string, +use <a href="/pkg/os/#Environ"><code>os.Environ</code></a> or +<a href="/pkg/syscall/#Getenv"><code>syscall.Getenv</code></a>. +</p> + + +<p> +The <a href="/pkg/os/#Process.Wait"><code>Process.Wait</code></a> method has +dropped its option argument and the associated constants are gone +from the package. +Also, the function <code>Wait</code> is gone; only the method of +the <code>Process</code> type persists. +</p> + +<p> +The <code>Waitmsg</code> type returned by +<a href="/pkg/os/#Process.Wait"><code>Process.Wait</code></a> +has been replaced with a more portable +<a href="/pkg/os/#ProcessState"><code>ProcessState</code></a> +type with accessor methods to recover information about the +process. +Because of changes to <code>Wait</code>, the <code>ProcessState</code> +value always describes an exited process. +Portability concerns simplified the interface in other ways, but the values returned by the +<a href="/pkg/os/#ProcessState.Sys"><code>ProcessState.Sys</code></a> and +<a href="/pkg/os/#ProcessState.SysUsage"><code>ProcessState.SysUsage</code></a> +methods can be type-asserted to underlying system-specific data structures such as +<a href="/pkg/syscall/#WaitStatus"><code>syscall.WaitStatus</code></a> and +<a href="/pkg/syscall/#Rusage"><code>syscall.Rusage</code></a> on Unix. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will drop a zero argument to <code>Process.Wait</code>. +All other changes will be caught by the compiler and must be updated by hand. +</p> + +<h4 id="os_fileinfo">The os.FileInfo type</h4> + +<p> +Go 1 redefines the <a href="/pkg/os/#FileInfo"><code>os.FileInfo</code></a> type, +changing it from a struct to an interface: +</p> + +<pre> + type FileInfo interface { + Name() string // base name of the file + Size() int64 // length in bytes + Mode() FileMode // file mode bits + ModTime() time.Time // modification time + IsDir() bool // abbreviation for Mode().IsDir() + Sys() interface{} // underlying data source (can return nil) + } +</pre> + +<p> +The file mode information has been moved into a subtype called +<a href="/pkg/os/#FileMode"><code>os.FileMode</code></a>, +a simple integer type with <code>IsDir</code>, <code>Perm</code>, and <code>String</code> +methods. +</p> + +<p> +The system-specific details of file modes and properties such as (on Unix) +i-number have been removed from <code>FileInfo</code> altogether. +Instead, each operating system's <code>os</code> package provides an +implementation of the <code>FileInfo</code> interface, which +has a <code>Sys</code> method that returns the +system-specific representation of file metadata. +For instance, to discover the i-number of a file on a Unix system, unpack +the <code>FileInfo</code> like this: +</p> + +<pre> + fi, err := os.Stat("hello.go") + if err != nil { + log.Fatal(err) + } + // Check that it's a Unix file. + unixStat, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + log.Fatal("hello.go: not a Unix file") + } + fmt.Printf("file i-number: %d\n", unixStat.Ino) +</pre> + +<p> +Assuming (which is unwise) that <code>"hello.go"</code> is a Unix file, +the i-number expression could be contracted to +</p> + +<pre> + fi.Sys().(*syscall.Stat_t).Ino +</pre> + +<p> +The vast majority of uses of <code>FileInfo</code> need only the methods +of the standard interface. +</p> + +<p> +The <code>os</code> package no longer contains wrappers for the POSIX errors +such as <code>ENOENT</code>. +For the few programs that need to verify particular error conditions, there are +now the boolean functions +<a href="/pkg/os/#IsExist"><code>IsExist</code></a>, +<a href="/pkg/os/#IsNotExist"><code>IsNotExist</code></a> +and +<a href="/pkg/os/#IsPermission"><code>IsPermission</code></a>. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/os\.Open/` `/}/`}} +--> f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) + if os.IsExist(err) { + log.Printf("%s already exists", name) + }</pre> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update code that uses the old equivalent of the current <code>os.FileInfo</code> +and <code>os.FileMode</code> API. +Code that needs system-specific file details will need to be updated by hand. +Code that uses the old POSIX error values from the <code>os</code> package +will fail to compile and will also need to be updated by hand. +</p> + +<h3 id="os_signal">The os/signal package</h3> + +<p> +The <code>os/signal</code> package in Go 1 replaces the +<code>Incoming</code> function, which returned a channel +that received all incoming signals, +with the selective <code>Notify</code> function, which asks +for delivery of specific signals on an existing channel. +</p> + +<p> +<em>Updating</em>: +Code must be updated by hand. +A literal translation of +</p> +<pre> +c := signal.Incoming() +</pre> +<p> +is +</p> +<pre> +c := make(chan os.Signal) +signal.Notify(c) // ask for all signals +</pre> +<p> +but most code should list the specific signals it wants to handle instead: +</p> +<pre> +c := make(chan os.Signal) +signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT) +</pre> + +<h3 id="path_filepath">The path/filepath package</h3> + +<p> +In Go 1, the <a href="/pkg/path/filepath/#Walk"><code>Walk</code></a> function of the +<code>path/filepath</code> package +has been changed to take a function value of type +<a href="/pkg/path/filepath/#WalkFunc"><code>WalkFunc</code></a> +instead of a <code>Visitor</code> interface value. +<code>WalkFunc</code> unifies the handling of both files and directories. +</p> + +<pre> + type WalkFunc func(path string, info os.FileInfo, err error) error +</pre> + +<p> +The <code>WalkFunc</code> function will be called even for files or directories that could not be opened; +in such cases the error argument will describe the failure. +If a directory's contents are to be skipped, +the function should return the value <a href="/pkg/path/filepath/#variables"><code>filepath.SkipDir</code></a> +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/STARTWALK/` `/ENDWALK/`}} +--> markFn := func(path string, info os.FileInfo, err error) error { + if path == "pictures" { <span class="comment">// Will skip walking of directory pictures and its contents.</span> + return filepath.SkipDir + } + if err != nil { + return err + } + log.Println(path) + return nil + } + err := filepath.Walk(".", markFn) + if err != nil { + log.Fatal(err) + }</pre> + +<p> +<em>Updating</em>: +The change simplifies most code but has subtle consequences, so affected programs +will need to be updated by hand. +The compiler will catch code using the old interface. +</p> + +<h3 id="regexp">The regexp package</h3> + +<p> +The <a href="/pkg/regexp/"><code>regexp</code></a> package has been rewritten. +It has the same interface but the specification of the regular expressions +it supports has changed from the old "egrep" form to that of +<a href="http://code.google.com/p/re2/">RE2</a>. +</p> + +<p> +<em>Updating</em>: +Code that uses the package should have its regular expressions checked by hand. +</p> + +<h3 id="runtime">The runtime package</h3> + +<p> +In Go 1, much of the API exported by package +<code>runtime</code> has been removed in favor of +functionality provided by other packages. +Code using the <code>runtime.Type</code> interface +or its specific concrete type implementations should +now use package <a href="/pkg/reflect/"><code>reflect</code></a>. +Code using <code>runtime.Semacquire</code> or <code>runtime.Semrelease</code> +should use channels or the abstractions in package <a href="/pkg/sync/"><code>sync</code></a>. +The <code>runtime.Alloc</code>, <code>runtime.Free</code>, +and <code>runtime.Lookup</code> functions, an unsafe API created for +debugging the memory allocator, have no replacement. +</p> + +<p> +Before, <code>runtime.MemStats</code> was a global variable holding +statistics about memory allocation, and calls to <code>runtime.UpdateMemStats</code> +ensured that it was up to date. +In Go 1, <code>runtime.MemStats</code> is a struct type, and code should use +<a href="/pkg/runtime/#ReadMemStats"><code>runtime.ReadMemStats</code></a> +to obtain the current statistics. +</p> + +<p> +The package adds a new function, +<a href="/pkg/runtime/#NumCPU"><code>runtime.NumCPU</code></a>, that returns the number of CPUs available +for parallel execution, as reported by the operating system kernel. +Its value can inform the setting of <code>GOMAXPROCS</code>. +The <code>runtime.Cgocalls</code> and <code>runtime.Goroutines</code> functions +have been renamed to <code>runtime.NumCgoCall</code> and <code>runtime.NumGoroutine</code>. +</p> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update code for the function renamings. +Other code will need to be updated by hand. +</p> + +<h3 id="strconv">The strconv package</h3> + +<p> +In Go 1, the +<a href="/pkg/strconv/"><code>strconv</code></a> +package has been significantly reworked to make it more Go-like and less C-like, +although <code>Atoi</code> lives on (it's similar to +<code>int(ParseInt(x, 10, 0))</code>, as does +<code>Itoa(x)</code> (<code>FormatInt(int64(x), 10)</code>). +There are also new variants of some of the functions that append to byte slices rather than +return strings, to allow control over allocation. +</p> + +<p> +This table summarizes the renamings; see the +<a href="/pkg/strconv/">package documentation</a> +for full details. +</p> + +<table class="codetable" frame="border" summary="strconv renames"> +<colgroup align="left" width="50%"></colgroup> +<colgroup align="left" width="50%"></colgroup> +<tr> +<th align="left">Old call</th> +<th align="left">New call</th> +</tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Atob(x)</td> <td>ParseBool(x)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Atof32(x)</td> <td>ParseFloat(x, 32)§</td></tr> +<tr><td>Atof64(x)</td> <td>ParseFloat(x, 64)</td></tr> +<tr><td>AtofN(x, n)</td> <td>ParseFloat(x, n)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Atoi(x)</td> <td>Atoi(x)</td></tr> +<tr><td>Atoi(x)</td> <td>ParseInt(x, 10, 0)§</td></tr> +<tr><td>Atoi64(x)</td> <td>ParseInt(x, 10, 64)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Atoui(x)</td> <td>ParseUint(x, 10, 0)§</td></tr> +<tr><td>Atoui64(x)</td> <td>ParseUint(x, 10, 64)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Btoi64(x, b)</td> <td>ParseInt(x, b, 64)</td></tr> +<tr><td>Btoui64(x, b)</td> <td>ParseUint(x, b, 64)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Btoa(x)</td> <td>FormatBool(x)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Ftoa32(x, f, p)</td> <td>FormatFloat(float64(x), f, p, 32)</td></tr> +<tr><td>Ftoa64(x, f, p)</td> <td>FormatFloat(x, f, p, 64)</td></tr> +<tr><td>FtoaN(x, f, p, n)</td> <td>FormatFloat(x, f, p, n)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Itoa(x)</td> <td>Itoa(x)</td></tr> +<tr><td>Itoa(x)</td> <td>FormatInt(int64(x), 10)</td></tr> +<tr><td>Itoa64(x)</td> <td>FormatInt(x, 10)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Itob(x, b)</td> <td>FormatInt(int64(x), b)</td></tr> +<tr><td>Itob64(x, b)</td> <td>FormatInt(x, b)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Uitoa(x)</td> <td>FormatUint(uint64(x), 10)</td></tr> +<tr><td>Uitoa64(x)</td> <td>FormatUint(x, 10)</td></tr> +<tr> +<td colspan="2"><hr></td> +</tr> +<tr><td>Uitob(x, b)</td> <td>FormatUint(uint64(x), b)</td></tr> +<tr><td>Uitob64(x, b)</td> <td>FormatUint(x, b)</td></tr> +</table> + +<p> +<em>Updating</em>: +Running <code>go</code> <code>fix</code> will update almost all code affected by the change. +<br> +§ <code>Atoi</code> persists but <code>Atoui</code> and <code>Atof32</code> do not, so +they may require +a cast that must be added by hand; the <code>go</code> <code>fix</code> tool will warn about it. +</p> + + +<h3 id="templates">The template packages</h3> + +<p> +The <code>template</code> and <code>exp/template/html</code> packages have moved to +<a href="/pkg/text/template/"><code>text/template</code></a> and +<a href="/pkg/html/template/"><code>html/template</code></a>. +More significant, the interface to these packages has been simplified. +The template language is the same, but the concept of "template set" is gone +and the functions and methods of the packages have changed accordingly, +often by elimination. +</p> + +<p> +Instead of sets, a <code>Template</code> object +may contain multiple named template definitions, +in effect constructing +name spaces for template invocation. +A template can invoke any other template associated with it, but only those +templates associated with it. +The simplest way to associate templates is to parse them together, something +made easier with the new structure of the packages. +</p> + +<p> +<em>Updating</em>: +The imports will be updated by fix tool. +Single-template uses will be otherwise be largely unaffected. +Code that uses multiple templates in concert will need to be updated by hand. +The <a href="/pkg/text/template/#examples">examples</a> in +the documentation for <code>text/template</code> can provide guidance. +</p> + +<h3 id="testing">The testing package</h3> + +<p> +The testing package has a type, <code>B</code>, passed as an argument to benchmark functions. +In Go 1, <code>B</code> has new methods, analogous to those of <code>T</code>, enabling +logging and failure reporting. +</p> + +<pre><!--{{code "/doc/progs/go1.go" `/func.*Benchmark/` `/^}/`}} +-->func BenchmarkSprintf(b *testing.B) { + <span class="comment">// Verify correctness before running benchmark.</span> + b.StopTimer() + got := fmt.Sprintf("%x", 23) + const expect = "17" + if expect != got { + b.Fatalf("expected %q; got %q", expect, got) + } + b.StartTimer() + for i := 0; i < b.N; i++ { + fmt.Sprintf("%x", 23) + } +}</pre> + +<p> +<em>Updating</em>: +Existing code is unaffected, although benchmarks that use <code>println</code> +or <code>panic</code> should be updated to use the new methods. +</p> + +<h3 id="testing_script">The testing/script package</h3> + +<p> +The testing/script package has been deleted. It was a dreg. +</p> + +<p> +<em>Updating</em>: +No code is likely to be affected. +</p> + +<h3 id="unsafe">The unsafe package</h3> + +<p> +In Go 1, the functions +<code>unsafe.Typeof</code>, <code>unsafe.Reflect</code>, +<code>unsafe.Unreflect</code>, <code>unsafe.New</code>, and +<code>unsafe.NewArray</code> have been removed; +they duplicated safer functionality provided by +package <a href="/pkg/reflect/"><code>reflect</code></a>. +</p> + +<p> +<em>Updating</em>: +Code using these functions must be rewritten to use +package <a href="/pkg/reflect/"><code>reflect</code></a>. +The changes to <a href="http://code.google.com/p/go/source/detail?r=2646dc956207">encoding/gob</a> and the <a href="http://code.google.com/p/goprotobuf/source/detail?r=5340ad310031">protocol buffer library</a> +may be helpful as examples. +</p> + +<h3 id="url">The url package</h3> + +<p> +In Go 1 several fields from the <a href="/pkg/net/url/#URL"><code>url.URL</code></a> type +were removed or replaced. +</p> + +<p> +The <a href="/pkg/net/url/#URL.String"><code>String</code></a> method now +predictably rebuilds an encoded URL string using all of <code>URL</code>'s +fields as necessary. The resulting string will also no longer have +passwords escaped. +</p> + +<p> +The <code>Raw</code> field has been removed. In most cases the <code>String</code> +method may be used in its place. +</p> + +<p> +The old <code>RawUserinfo</code> field is replaced by the <code>User</code> +field, of type <a href="/pkg/net/url/#Userinfo"><code>*net.Userinfo</code></a>. +Values of this type may be created using the new <a href="/pkg/net/url/#User"><code>net.User</code></a> +and <a href="/pkg/net/url/#UserPassword"><code>net.UserPassword</code></a> +functions. The <code>EscapeUserinfo</code> and <code>UnescapeUserinfo</code> +functions are also gone. +</p> + +<p> +The <code>RawAuthority</code> field has been removed. The same information is +available in the <code>Host</code> and <code>User</code> fields. +</p> + +<p> +The <code>RawPath</code> field and the <code>EncodedPath</code> method have +been removed. The path information in rooted URLs (with a slash following the +schema) is now available only in decoded form in the <code>Path</code> field. +Occasionally, the encoded data may be required to obtain information that +was lost in the decoding process. These cases must be handled by accessing +the data the URL was built from. +</p> + +<p> +URLs with non-rooted paths, such as <code>"mailto:dev@golang.org?subject=Hi"</code>, +are also handled differently. The <code>OpaquePath</code> boolean field has been +removed and a new <code>Opaque</code> string field introduced to hold the encoded +path for such URLs. In Go 1, the cited URL parses as: +</p> + +<pre> + URL{ + Scheme: "mailto", + Opaque: "dev@golang.org", + RawQuery: "subject=Hi", + } +</pre> + +<p> +A new <a href="/pkg/net/url/#URL.RequestURI"><code>RequestURI</code></a> method was +added to <code>URL</code>. +</p> + +<p> +The <code>ParseWithReference</code> function has been renamed to <code>ParseWithFragment</code>. +</p> + +<p> +<em>Updating</em>: +Code that uses the old fields will fail to compile and must be updated by hand. +The semantic changes make it difficult for the fix tool to update automatically. +</p> + +<h2 id="cmd_go">The go command</h2> + +<p> +Go 1 introduces the <a href="/cmd/go/">go command</a>, a tool for fetching, +building, and installing Go packages and commands. The <code>go</code> command +does away with makefiles, instead using Go source code to find dependencies and +determine build conditions. Most existing Go programs will no longer require +makefiles to be built. +</p> + +<p> +See <a href="/doc/code.html">How to Write Go Code</a> for a primer on the +<code>go</code> command and the <a href="/cmd/go/">go command documentation</a> +for the full details. +</p> + +<p> +<em>Updating</em>: +Projects that depend on the Go project's old makefile-based build +infrastructure (<code>Make.pkg</code>, <code>Make.cmd</code>, and so on) should +switch to using the <code>go</code> command for building Go code and, if +necessary, rewrite their makefiles to perform any auxiliary build tasks. +</p> + +<h2 id="cmd_cgo">The cgo command</h2> + +<p> +In Go 1, the <a href="/cmd/cgo">cgo command</a> +uses a different <code>_cgo_export.h</code> +file, which is generated for packages containing <code>//export</code> lines. +The <code>_cgo_export.h</code> file now begins with the C preamble comment, +so that exported function definitions can use types defined there. +This has the effect of compiling the preamble multiple times, so a +package using <code>//export</code> must not put function definitions +or variable initializations in the C preamble. +</p> + +<h2 id="releases">Packaged releases</h2> + +<p> +One of the most significant changes associated with Go 1 is the availability +of prepackaged, downloadable distributions. +They are available for many combinations of architecture and operating system +(including Windows) and the list will grow. +Installation details are described on the +<a href="/doc/install">Getting Started</a> page, while +the distributions themselves are listed on the +<a href="http://code.google.com/p/go/downloads/list">downloads page</a>. + + +</div> + +<div id="footer"> +Build version go1.0.1.<br> +Except as <a href="http://code.google.com/policies.html#restrictions">noted</a>, +the content of this page is licensed under the +Creative Commons Attribution 3.0 License, +and code is licensed under a <a href="/LICENSE">BSD license</a>.<br> +<a href="/doc/tos.html">Terms of Service</a> | +<a href="http://www.google.com/intl/en/privacy/privacy-policy.html">Privacy Policy</a> +</div> + +<script type="text/javascript"> +(function() { + var ga = document.createElement("script"); ga.type = "text/javascript"; ga.async = true; + ga.src = ("https:" == document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js"; + var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ga, s); +})(); +</script> +</body> +<script type="text/javascript"> + (function() { + var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; + po.src = 'https://apis.google.com/js/plusone.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); + })(); +</script> +</html> + diff --git a/libgo/go/exp/html/testdata/webkit/pending-spec-changes.dat b/libgo/go/exp/html/testdata/webkit/pending-spec-changes.dat index e00ee85..5a92084 100644 --- a/libgo/go/exp/html/testdata/webkit/pending-spec-changes.dat +++ b/libgo/go/exp/html/testdata/webkit/pending-spec-changes.dat @@ -26,3 +26,27 @@ | <svg svg> | "foo" | "bar" + +#data +<table><tr><td><svg><desc><td></desc><circle> +#errors +7: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”. +30: A table cell was implicitly closed, but there were open elements. +26: Unclosed element “desc”. +20: Unclosed element “svg”. +37: Stray end tag “desc”. +45: End of file seen and there were open elements. +45: Unclosed element “circle”. +7: Unclosed element “table”. +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| <svg desc> +| <td> +| <circle> diff --git a/libgo/go/exp/html/testdata/webkit/tables01.dat b/libgo/go/exp/html/testdata/webkit/tables01.dat index 88ef1fe..c4b47e4 100644 --- a/libgo/go/exp/html/testdata/webkit/tables01.dat +++ b/libgo/go/exp/html/testdata/webkit/tables01.dat @@ -195,3 +195,18 @@ | <td> | <button> | <td> + +#data +<table><tr><td><svg><desc><td> +#errors +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| <svg desc> +| <td> diff --git a/libgo/go/exp/html/testdata/webkit/tests16.dat b/libgo/go/exp/html/testdata/webkit/tests16.dat index 937dba9..c8ef66f 100644 --- a/libgo/go/exp/html/testdata/webkit/tests16.dat +++ b/libgo/go/exp/html/testdata/webkit/tests16.dat @@ -1076,6 +1076,28 @@ Line: 1 Col: 64 Unexpected end tag (textarea). | "</textarea>" #data +<!doctype html><textarea><</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<" + +#data +<!doctype html><textarea>a<b</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "a<b" + +#data <!doctype html><iframe><!--<iframe></iframe>--></iframe> #errors Line: 1 Col: 56 Unexpected end tag (iframe). diff --git a/libgo/go/exp/html/testdata/webkit/tests19.dat b/libgo/go/exp/html/testdata/webkit/tests19.dat index 06222f5..0d62f5a 100644 --- a/libgo/go/exp/html/testdata/webkit/tests19.dat +++ b/libgo/go/exp/html/testdata/webkit/tests19.dat @@ -173,7 +173,7 @@ | <ruby> | <div> | <span> -| <rp> +| <rp> #data <!doctype html><ruby><div><p><rp> @@ -186,7 +186,7 @@ | <ruby> | <div> | <p> -| <rp> +| <rp> #data <!doctype html><ruby><p><rt> @@ -211,7 +211,7 @@ | <ruby> | <div> | <span> -| <rt> +| <rt> #data <!doctype html><ruby><div><p><rt> @@ -224,7 +224,7 @@ | <ruby> | <div> | <p> -| <rt> +| <rt> #data <!doctype html><math/><foo> @@ -1218,3 +1218,20 @@ | <plaintext> | <a> | "b" + +#data +<!DOCTYPE html><div>a<a></div>b<p>c</p>d +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| "a" +| <a> +| <a> +| "b" +| <p> +| "c" +| "d" diff --git a/libgo/go/exp/html/testdata/webkit/tests26.dat b/libgo/go/exp/html/testdata/webkit/tests26.dat index da128e7..fae11ff 100644 --- a/libgo/go/exp/html/testdata/webkit/tests26.dat +++ b/libgo/go/exp/html/testdata/webkit/tests26.dat @@ -193,3 +193,121 @@ | <i> | <nobr> | "2" + +#data +<p><code x</code></p> + +#errors +#document +| <html> +| <head> +| <body> +| <p> +| <code> +| code="" +| x<="" +| <code> +| code="" +| x<="" +| " +" + +#data +<!DOCTYPE html><svg><foreignObject><p><i></p>a +#errors +45: End tag “p” seen, but there were open elements. +41: Unclosed element “i”. +46: End of file seen and there were open elements. +35: Unclosed element “foreignObject”. +20: Unclosed element “svg”. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| <svg foreignObject> +| <p> +| <i> +| <i> +| "a" + +#data +<!DOCTYPE html><table><tr><td><svg><foreignObject><p><i></p>a +#errors +56: End tag “p” seen, but there were open elements. +52: Unclosed element “i”. +57: End of file seen and there were open elements. +46: Unclosed element “foreignObject”. +31: Unclosed element “svg”. +22: Unclosed element “table”. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| <svg foreignObject> +| <p> +| <i> +| <i> +| "a" + +#data +<!DOCTYPE html><math><mtext><p><i></p>a +#errors +38: End tag “p” seen, but there were open elements. +34: Unclosed element “i”. +39: End of file in a foreign namespace context. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <math mtext> +| <p> +| <i> +| <i> +| "a" + +#data +<!DOCTYPE html><table><tr><td><math><mtext><p><i></p>a +#errors +53: End tag “p” seen, but there were open elements. +49: Unclosed element “i”. +54: End of file in a foreign namespace context. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <math math> +| <math mtext> +| <p> +| <i> +| <i> +| "a" + +#data +<!DOCTYPE html><body><div><!/div>a +#errors +29: Bogus comment. +34: End of file seen and there were open elements. +26: Unclosed element “div”. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <!-- /div --> +| "a" diff --git a/libgo/go/exp/html/testdata/webkit/tests_innerHTML_1.dat b/libgo/go/exp/html/testdata/webkit/tests_innerHTML_1.dat index 052fac7..6c78661 100644 --- a/libgo/go/exp/html/testdata/webkit/tests_innerHTML_1.dat +++ b/libgo/go/exp/html/testdata/webkit/tests_innerHTML_1.dat @@ -731,3 +731,11 @@ html frameset #document | <frame> + +#data +#errors +#document-fragment +html +#document +| <head> +| <body> diff --git a/libgo/go/exp/html/testdata/webkit/webkit01.dat b/libgo/go/exp/html/testdata/webkit/webkit01.dat index 4101b21..9d425e9 100644 --- a/libgo/go/exp/html/testdata/webkit/webkit01.dat +++ b/libgo/go/exp/html/testdata/webkit/webkit01.dat @@ -289,8 +289,8 @@ console.log("FOO<span>BAR</span>BAZ"); | <body> | <ruby> | <div> -| <rp> -| "xx" +| <rp> +| "xx" #data <html><body><ruby><div><rt>xx</rt></div></ruby></body></html> @@ -301,8 +301,8 @@ console.log("FOO<span>BAR</span>BAZ"); | <body> | <ruby> | <div> -| <rt> -| "xx" +| <rt> +| "xx" #data <html><frameset><!--1--><noframes>A</noframes><!--2--></frameset><!--3--><noframes>B</noframes><!--4--></html><!--5--><noframes>C</noframes><!--6--> @@ -560,7 +560,8 @@ console.log("FOO<span>BAR</span>BAZ"); | <td> | <svg svg> | <svg desc> -| <svg circle> +| <td> +| <circle> #data <svg><tfoot></mi><td> diff --git a/libgo/go/exp/html/testdata/webkit/webkit02.dat b/libgo/go/exp/html/testdata/webkit/webkit02.dat index 2218f42..905783d 100644 --- a/libgo/go/exp/html/testdata/webkit/webkit02.dat +++ b/libgo/go/exp/html/testdata/webkit/webkit02.dat @@ -102,3 +102,58 @@ | <body> | <legend> | "test" + +#data +<table><input> +#errors +#document +| <html> +| <head> +| <body> +| <input> +| <table> + +#data +<b><em><dcell><postfield><postfield><postfield><postfield><missing_glyph><missing_glyph><missing_glyph><missing_glyph><hkern><aside></b></em> +#errors +#document-fragment +div +#document +| <b> +| <em> +| <dcell> +| <postfield> +| <postfield> +| <postfield> +| <postfield> +| <missing_glyph> +| <missing_glyph> +| <missing_glyph> +| <missing_glyph> +| <hkern> +| <aside> +| <em> +| <b> + +#data +<isindex action="x"> +#errors +#document-fragment +table +#document +| <form> +| action="x" +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| <hr> + +#data +<option><XH<optgroup></optgroup> +#errors +#document-fragment +select +#document +| <option> diff --git a/libgo/go/exp/html/token.go b/libgo/go/exp/html/token.go index b5e9c2d..517bd5d 100644 --- a/libgo/go/exp/html/token.go +++ b/libgo/go/exp/html/token.go @@ -6,13 +6,14 @@ package html import ( "bytes" + "exp/html/atom" "io" "strconv" "strings" ) // A TokenType is the type of a Token. -type TokenType int +type TokenType uint32 const ( // ErrorToken means that an error occurred during tokenization. @@ -65,11 +66,13 @@ type Attribute struct { // A Token consists of a TokenType and some Data (tag name for start and end // tags, content for text, comments and doctypes). A tag Token may also contain // a slice of Attributes. Data is unescaped for all Tokens (it looks like "a<b" -// rather than "a<b"). +// rather than "a<b"). For tag Tokens, DataAtom is the atom for Data, or +// zero if Data is not a known tag name. type Token struct { - Type TokenType - Data string - Attr []Attribute + Type TokenType + DataAtom atom.Atom + Data string + Attr []Attribute } // tagString returns a string representation of a tag Token's Data and Attr. @@ -149,6 +152,57 @@ type Tokenizer struct { rawTag string // textIsRaw is whether the current text token's data is not escaped. textIsRaw bool + // convertNUL is whether NUL bytes in the current token's data should + // be converted into \ufffd replacement characters. + convertNUL bool + // allowCDATA is whether CDATA sections are allowed in the current context. + allowCDATA bool +} + +// AllowCDATA sets whether or not the tokenizer recognizes <![CDATA[foo]]> as +// the text "foo". The default value is false, which means to recognize it as +// a bogus comment "<!-- [CDATA[foo]] -->" instead. +// +// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and +// only if tokenizing foreign content, such as MathML and SVG. However, +// tracking foreign-contentness is difficult to do purely in the tokenizer, +// as opposed to the parser, due to HTML integration points: an <svg> element +// can contain a <foreignObject> that is foreign-to-SVG but not foreign-to- +// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the +// responsibility of the user of a tokenizer to call AllowCDATA as appropriate. +// In practice, if using the tokenizer without caring whether MathML or SVG +// CDATA is text or comments, such as tokenizing HTML to find all the anchor +// text, it is acceptable to ignore this responsibility. +func (z *Tokenizer) AllowCDATA(allowCDATA bool) { + z.allowCDATA = allowCDATA +} + +// NextIsNotRawText instructs the tokenizer that the next token should not be +// considered as 'raw text'. Some elements, such as script and title elements, +// normally require the next token after the opening tag to be 'raw text' that +// has no child elements. For example, tokenizing "<title>a<b>c</b>d</title>" +// yields a start tag token for "<title>", a text token for "a<b>c</b>d", and +// an end tag token for "</title>". There are no distinct start tag or end tag +// tokens for the "<b>" and "</b>". +// +// This tokenizer implementation will generally look for raw text at the right +// times. Strictly speaking, an HTML5 compliant tokenizer should not look for +// raw text if in foreign content: <title> generally needs raw text, but a +// <title> inside an <svg> does not. Another example is that a <textarea> +// generally needs raw text, but a <textarea> is not allowed as an immediate +// child of a <select>; in normal parsing, a <textarea> implies </select>, but +// one cannot close the implicit element when parsing a <select>'s InnerHTML. +// Similarly to AllowCDATA, tracking the correct moment to override raw-text- +// ness is difficult to do purely in the tokenizer, as opposed to the parser. +// For strict compliance with the HTML5 tokenization algorithm, it is the +// responsibility of the user of a tokenizer to call NextIsNotRawText as +// appropriate. In practice, like AllowCDATA, it is acceptable to ignore this +// responsibility for basic usage. +// +// Note that this 'raw text' concept is different from the one offered by the +// Tokenizer.Raw method. +func (z *Tokenizer) NextIsNotRawText() { + z.rawTag = "" } // Err returns the error associated with the most recent ErrorToken token. @@ -233,6 +287,12 @@ func (z *Tokenizer) skipWhiteSpace() { // readRawOrRCDATA reads until the next "</foo>", where "foo" is z.rawTag and // is typically something like "script" or "textarea". func (z *Tokenizer) readRawOrRCDATA() { + if z.rawTag == "script" { + z.readScript() + z.textIsRaw = true + z.rawTag = "" + return + } loop: for { c := z.readByte() @@ -249,27 +309,8 @@ loop: if c != '/' { continue loop } - for i := 0; i < len(z.rawTag); i++ { - c = z.readByte() - if z.err != nil { - break loop - } - if c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') { - continue loop - } - } - c = z.readByte() - if z.err != nil { - break loop - } - switch c { - case ' ', '\n', '\r', '\t', '\f', '/', '>': - // The 3 is 2 for the leading "</" plus 1 for the trailing character c. - z.raw.end -= 3 + len(z.rawTag) + if z.readRawEndTag() || z.err != nil { break loop - case '<': - // Step back one, to catch "</foo</foo>". - z.raw.end-- } } z.data.end = z.raw.end @@ -278,6 +319,242 @@ loop: z.rawTag = "" } +// readRawEndTag attempts to read a tag like "</foo>", where "foo" is z.rawTag. +// If it succeeds, it backs up the input position to reconsume the tag and +// returns true. Otherwise it returns false. The opening "</" has already been +// consumed. +func (z *Tokenizer) readRawEndTag() bool { + for i := 0; i < len(z.rawTag); i++ { + c := z.readByte() + if z.err != nil { + return false + } + if c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') { + z.raw.end-- + return false + } + } + c := z.readByte() + if z.err != nil { + return false + } + switch c { + case ' ', '\n', '\r', '\t', '\f', '/', '>': + // The 3 is 2 for the leading "</" plus 1 for the trailing character c. + z.raw.end -= 3 + len(z.rawTag) + return true + } + z.raw.end-- + return false +} + +// readScript reads until the next </script> tag, following the byzantine +// rules for escaping/hiding the closing tag. +func (z *Tokenizer) readScript() { + defer func() { + z.data.end = z.raw.end + }() + var c byte + +scriptData: + c = z.readByte() + if z.err != nil { + return + } + if c == '<' { + goto scriptDataLessThanSign + } + goto scriptData + +scriptDataLessThanSign: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '/': + goto scriptDataEndTagOpen + case '!': + goto scriptDataEscapeStart + } + z.raw.end-- + goto scriptData + +scriptDataEndTagOpen: + if z.readRawEndTag() || z.err != nil { + return + } + goto scriptData + +scriptDataEscapeStart: + c = z.readByte() + if z.err != nil { + return + } + if c == '-' { + goto scriptDataEscapeStartDash + } + z.raw.end-- + goto scriptData + +scriptDataEscapeStartDash: + c = z.readByte() + if z.err != nil { + return + } + if c == '-' { + goto scriptDataEscapedDashDash + } + z.raw.end-- + goto scriptData + +scriptDataEscaped: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataEscapedDash + case '<': + goto scriptDataEscapedLessThanSign + } + goto scriptDataEscaped + +scriptDataEscapedDash: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataEscapedDashDash + case '<': + goto scriptDataEscapedLessThanSign + } + goto scriptDataEscaped + +scriptDataEscapedDashDash: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataEscapedDashDash + case '<': + goto scriptDataEscapedLessThanSign + case '>': + goto scriptData + } + goto scriptDataEscaped + +scriptDataEscapedLessThanSign: + c = z.readByte() + if z.err != nil { + return + } + if c == '/' { + goto scriptDataEscapedEndTagOpen + } + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { + goto scriptDataDoubleEscapeStart + } + z.raw.end-- + goto scriptData + +scriptDataEscapedEndTagOpen: + if z.readRawEndTag() || z.err != nil { + return + } + goto scriptDataEscaped + +scriptDataDoubleEscapeStart: + z.raw.end-- + for i := 0; i < len("script"); i++ { + c = z.readByte() + if z.err != nil { + return + } + if c != "script"[i] && c != "SCRIPT"[i] { + z.raw.end-- + goto scriptDataEscaped + } + } + c = z.readByte() + if z.err != nil { + return + } + switch c { + case ' ', '\n', '\r', '\t', '\f', '/', '>': + goto scriptDataDoubleEscaped + } + z.raw.end-- + goto scriptDataEscaped + +scriptDataDoubleEscaped: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataDoubleEscapedDash + case '<': + goto scriptDataDoubleEscapedLessThanSign + } + goto scriptDataDoubleEscaped + +scriptDataDoubleEscapedDash: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataDoubleEscapedDashDash + case '<': + goto scriptDataDoubleEscapedLessThanSign + } + goto scriptDataDoubleEscaped + +scriptDataDoubleEscapedDashDash: + c = z.readByte() + if z.err != nil { + return + } + switch c { + case '-': + goto scriptDataDoubleEscapedDashDash + case '<': + goto scriptDataDoubleEscapedLessThanSign + case '>': + goto scriptData + } + goto scriptDataDoubleEscaped + +scriptDataDoubleEscapedLessThanSign: + c = z.readByte() + if z.err != nil { + return + } + if c == '/' { + goto scriptDataDoubleEscapeEnd + } + z.raw.end-- + goto scriptDataDoubleEscaped + +scriptDataDoubleEscapeEnd: + if z.readRawEndTag() { + z.raw.end += len("</script>") + goto scriptDataEscaped + } + if z.err != nil { + return + } + goto scriptDataDoubleEscaped +} + // readComment reads the next comment token starting with "<!--". The opening // "<!--" has already been consumed. func (z *Tokenizer) readComment() { @@ -341,8 +618,8 @@ func (z *Tokenizer) readUntilCloseAngle() { } // readMarkupDeclaration reads the next token starting with "<!". It might be -// a "<!--comment-->", a "<!DOCTYPE foo>", or "<!a bogus comment". The opening -// "<!" has already been consumed. +// a "<!--comment-->", a "<!DOCTYPE foo>", a "<![CDATA[section]]>" or +// "<!a bogus comment". The opening "<!" has already been consumed. func (z *Tokenizer) readMarkupDeclaration() TokenType { z.data.start = z.raw.end var c [2]byte @@ -358,27 +635,81 @@ func (z *Tokenizer) readMarkupDeclaration() TokenType { return CommentToken } z.raw.end -= 2 + if z.readDoctype() { + return DoctypeToken + } + if z.allowCDATA && z.readCDATA() { + z.convertNUL = true + return TextToken + } + // It's a bogus comment. + z.readUntilCloseAngle() + return CommentToken +} + +// readDoctype attempts to read a doctype declaration and returns true if +// successful. The opening "<!" has already been consumed. +func (z *Tokenizer) readDoctype() bool { const s = "DOCTYPE" for i := 0; i < len(s); i++ { c := z.readByte() if z.err != nil { z.data.end = z.raw.end - return CommentToken + return false } if c != s[i] && c != s[i]+('a'-'A') { // Back up to read the fragment of "DOCTYPE" again. z.raw.end = z.data.start - z.readUntilCloseAngle() - return CommentToken + return false } } if z.skipWhiteSpace(); z.err != nil { z.data.start = z.raw.end z.data.end = z.raw.end - return DoctypeToken + return true } z.readUntilCloseAngle() - return DoctypeToken + return true +} + +// readCDATA attempts to read a CDATA section and returns true if +// successful. The opening "<!" has already been consumed. +func (z *Tokenizer) readCDATA() bool { + const s = "[CDATA[" + for i := 0; i < len(s); i++ { + c := z.readByte() + if z.err != nil { + z.data.end = z.raw.end + return false + } + if c != s[i] { + // Back up to read the fragment of "[CDATA[" again. + z.raw.end = z.data.start + return false + } + } + z.data.start = z.raw.end + brackets := 0 + for { + c := z.readByte() + if z.err != nil { + z.data.end = z.raw.end + return true + } + switch c { + case ']': + brackets++ + case '>': + if brackets >= 2 { + z.data.end = z.raw.end - len("]]>") + return true + } + brackets = 0 + default: + brackets = 0 + } + } + panic("unreachable") } // startTagIn returns whether the start tag in z.buf[z.data.start:z.data.end] @@ -406,29 +737,10 @@ loop: // readStartTag reads the next start tag token. The opening "<a" has already // been consumed, where 'a' means anything in [A-Za-z]. func (z *Tokenizer) readStartTag() TokenType { - z.attr = z.attr[:0] - z.nAttrReturned = 0 - // Read the tag name and attribute key/value pairs. - z.readTagName() - if z.skipWhiteSpace(); z.err != nil { + z.readTag(true) + if z.err != nil { return ErrorToken } - for { - c := z.readByte() - if z.err != nil || c == '>' { - break - } - z.raw.end-- - z.readTagAttrKey() - z.readTagAttrVal() - // Save pendingAttr if it has a non-empty key. - if z.pendingAttr[0].start != z.pendingAttr[0].end { - z.attr = append(z.attr, z.pendingAttr) - } - if z.skipWhiteSpace(); z.err != nil { - break - } - } // Several tags flag the tokenizer's next token as raw. c, raw := z.buf[z.data.start], false if 'A' <= c && c <= 'Z' { @@ -458,16 +770,32 @@ func (z *Tokenizer) readStartTag() TokenType { return StartTagToken } -// readEndTag reads the next end tag token. The opening "</a" has already -// been consumed, where 'a' means anything in [A-Za-z]. -func (z *Tokenizer) readEndTag() { +// readTag reads the next tag token and its attributes. If saveAttr, those +// attributes are saved in z.attr, otherwise z.attr is set to an empty slice. +// The opening "<a" or "</a" has already been consumed, where 'a' means anything +// in [A-Za-z]. +func (z *Tokenizer) readTag(saveAttr bool) { z.attr = z.attr[:0] z.nAttrReturned = 0 + // Read the tag name and attribute key/value pairs. z.readTagName() + if z.skipWhiteSpace(); z.err != nil { + return + } for { c := z.readByte() if z.err != nil || c == '>' { - return + break + } + z.raw.end-- + z.readTagAttrKey() + z.readTagAttrVal() + // Save pendingAttr if saveAttr and that attribute has a non-empty key. + if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end { + z.attr = append(z.attr, z.pendingAttr) + } + if z.skipWhiteSpace(); z.err != nil { + break } } } @@ -594,16 +922,19 @@ func (z *Tokenizer) Next() TokenType { for z.err == nil { z.readByte() } + z.data.end = z.raw.end z.textIsRaw = true } else { z.readRawOrRCDATA() } if z.data.end > z.data.start { z.tt = TextToken + z.convertNUL = true return z.tt } } z.textIsRaw = false + z.convertNUL = false loop: for { @@ -662,8 +993,12 @@ loop: continue loop } if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { - z.readEndTag() - z.tt = EndTagToken + z.readTag(false) + if z.err != nil { + z.tt = ErrorToken + } else { + z.tt = EndTagToken + } return z.tt } z.raw.end-- @@ -696,6 +1031,43 @@ func (z *Tokenizer) Raw() []byte { return z.buf[z.raw.start:z.raw.end] } +// convertNewlines converts "\r" and "\r\n" in s to "\n". +// The conversion happens in place, but the resulting slice may be shorter. +func convertNewlines(s []byte) []byte { + for i, c := range s { + if c != '\r' { + continue + } + + src := i + 1 + if src >= len(s) || s[src] != '\n' { + s[i] = '\n' + continue + } + + dst := i + for src < len(s) { + if s[src] == '\r' { + if src+1 < len(s) && s[src+1] == '\n' { + src++ + } + s[dst] = '\n' + } else { + s[dst] = s[src] + } + src++ + dst++ + } + return s[:dst] + } + return s +} + +var ( + nul = []byte("\x00") + replacement = []byte("\ufffd") +) + // Text returns the unescaped text of a text, comment or doctype token. The // contents of the returned slice may change on the next call to Next. func (z *Tokenizer) Text() []byte { @@ -704,8 +1076,12 @@ func (z *Tokenizer) Text() []byte { s := z.buf[z.data.start:z.data.end] z.data.start = z.raw.end z.data.end = z.raw.end + s = convertNewlines(s) + if (z.convertNUL || z.tt == CommentToken) && bytes.Contains(s, nul) { + s = bytes.Replace(s, nul, replacement, -1) + } if !z.textIsRaw { - s = unescape(s) + s = unescape(s, false) } return s } @@ -739,7 +1115,7 @@ func (z *Tokenizer) TagAttr() (key, val []byte, moreAttr bool) { z.nAttrReturned++ key = z.buf[x[0].start:x[0].end] val = z.buf[x[1].start:x[1].end] - return lower(key), unescape(val), z.nAttrReturned < len(z.attr) + return lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr) } } return nil, nil, false @@ -752,19 +1128,18 @@ func (z *Tokenizer) Token() Token { switch z.tt { case TextToken, CommentToken, DoctypeToken: t.Data = string(z.Text()) - case StartTagToken, SelfClosingTagToken: - var attr []Attribute + case StartTagToken, SelfClosingTagToken, EndTagToken: name, moreAttr := z.TagName() for moreAttr { var key, val []byte key, val, moreAttr = z.TagAttr() - attr = append(attr, Attribute{"", string(key), string(val)}) + t.Attr = append(t.Attr, Attribute{"", atom.String(key), string(val)}) + } + if a := atom.Lookup(name); a != 0 { + t.DataAtom, t.Data = a, a.String() + } else { + t.DataAtom, t.Data = 0, string(name) } - t.Data = string(name) - t.Attr = attr - case EndTagToken: - name, _ := z.TagName() - t.Data = string(name) } return t } @@ -772,8 +1147,27 @@ func (z *Tokenizer) Token() Token { // NewTokenizer returns a new HTML Tokenizer for the given Reader. // The input is assumed to be UTF-8 encoded. func NewTokenizer(r io.Reader) *Tokenizer { - return &Tokenizer{ + return NewTokenizerFragment(r, "") +} + +// NewTokenizerFragment returns a new HTML Tokenizer for the given Reader, for +// tokenizing an exisitng element's InnerHTML fragment. contextTag is that +// element's tag, such as "div" or "iframe". +// +// For example, how the InnerHTML "a<b" is tokenized depends on whether it is +// for a <p> tag or a <script> tag. +// +// The input is assumed to be UTF-8 encoded. +func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer { + z := &Tokenizer{ r: r, buf: make([]byte, 0, 4096), } + if contextTag != "" { + switch s := strings.ToLower(contextTag); s { + case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "title", "textarea", "xmp": + z.rawTag = s + } + } + return z } diff --git a/libgo/go/exp/html/token_test.go b/libgo/go/exp/html/token_test.go index 61d7400..63a8bfc 100644 --- a/libgo/go/exp/html/token_test.go +++ b/libgo/go/exp/html/token_test.go @@ -7,6 +7,8 @@ package html import ( "bytes" "io" + "io/ioutil" + "runtime" "strings" "testing" ) @@ -126,7 +128,7 @@ var tokenTests = []tokenTest{ { "tag name eof #4", `<a x`, - `<a x="">`, + ``, }, // Some malformed tags that are missing a '>'. { @@ -142,12 +144,12 @@ var tokenTests = []tokenTest{ { "malformed tag #2", `<p id`, - `<p id="">`, + ``, }, { "malformed tag #3", `<p id=`, - `<p id="">`, + ``, }, { "malformed tag #4", @@ -157,7 +159,7 @@ var tokenTests = []tokenTest{ { "malformed tag #5", `<p id=0`, - `<p id="0">`, + ``, }, { "malformed tag #6", @@ -167,13 +169,18 @@ var tokenTests = []tokenTest{ { "malformed tag #7", `<p id="0</p>`, - `<p id="0</p>">`, + ``, }, { "malformed tag #8", `<p id="0"</p>`, `<p id="0" <="" p="">`, }, + { + "malformed tag #9", + `<p></p id`, + `<p>`, + }, // Raw text and RCDATA. { "basic raw text", @@ -203,7 +210,7 @@ var tokenTests = []tokenTest{ { "' ' completes script end tag", "<SCRIPT>a</SCRipt ", - "<script>$a$</script>", + "<script>$a", }, { "'>' completes script end tag", @@ -359,7 +366,7 @@ var tokenTests = []tokenTest{ { "tricky", "<p \t\n iD=\"a"B\" foo=\"bar\"><EM>te<&;xt</em></p>", - `<p id="a"B" foo="bar">$<em>$te<&;xt$</em>$</p>`, + `<p id="a"B" foo="bar">$<em>$te<&;xt$</em>$</p>`, }, // A nonexistent entity. Tokenizing and converting back to a string should // escape the "&" to become "&". @@ -368,14 +375,11 @@ var tokenTests = []tokenTest{ `<a b="c&noSuchEntity;d"><&alsoDoesntExist;&`, `<a b="c&noSuchEntity;d">$<&alsoDoesntExist;&`, }, - /* - // TODO: re-enable this test when it works. This input/output matches html5lib's behavior. - { - "entity without semicolon", - `¬it;∉<a b="q=z&=5¬ice=hello¬=world">`, - `¬it;∉$<a b="q=z&amp=5&notice=hello¬=world">`, - }, - */ + { + "entity without semicolon", + `¬it;∉<a b="q=z&=5¬ice=hello¬=world">`, + `¬it;∉$<a b="q=z&amp=5&notice=hello¬=world">`, + }, { "entity with digits", "½", @@ -421,7 +425,7 @@ var tokenTests = []tokenTest{ { "Double-quoted attribute value", `<input value="I'm an attribute" FOO="BAR">`, - `<input value="I'm an attribute" foo="BAR">`, + `<input value="I'm an attribute" foo="BAR">`, }, { "Attribute name characters", @@ -436,7 +440,7 @@ var tokenTests = []tokenTest{ { "Attributes with a solitary single quote", `<p id=can't><p id=won't>`, - `<p id="can't">$<p id="won't">`, + `<p id="can't">$<p id="won't">`, }, } @@ -545,10 +549,11 @@ func TestUnescapeEscape(t *testing.T) { `"<&>"`, `"<&>"`, `3&5==1 && 0<1, "0<1", a+acute=á`, + `The special characters are: <, >, &, ' and "`, } for _, s := range ss { - if s != UnescapeString(EscapeString(s)) { - t.Errorf("s != UnescapeString(EscapeString(s)), s=%q", s) + if got := UnescapeString(EscapeString(s)); got != s { + t.Errorf("got %q want %q", got, s) } } } @@ -588,3 +593,93 @@ loop: t.Errorf("TestBufAPI: want %q got %q", u, v) } } + +func TestConvertNewlines(t *testing.T) { + testCases := map[string]string{ + "Mac\rDOS\r\nUnix\n": "Mac\nDOS\nUnix\n", + "Unix\nMac\rDOS\r\n": "Unix\nMac\nDOS\n", + "DOS\r\nDOS\r\nDOS\r\n": "DOS\nDOS\nDOS\n", + "": "", + "\n": "\n", + "\n\r": "\n\n", + "\r": "\n", + "\r\n": "\n", + "\r\n\n": "\n\n", + "\r\n\r": "\n\n", + "\r\n\r\n": "\n\n", + "\r\r": "\n\n", + "\r\r\n": "\n\n", + "\r\r\n\n": "\n\n\n", + "\r\r\r\n": "\n\n\n", + "\r \n": "\n \n", + "xyz": "xyz", + } + for in, want := range testCases { + if got := string(convertNewlines([]byte(in))); got != want { + t.Errorf("input %q: got %q, want %q", in, got, want) + } + } +} + +const ( + rawLevel = iota + lowLevel + highLevel +) + +func benchmarkTokenizer(b *testing.B, level int) { + buf, err := ioutil.ReadFile("testdata/go1.html") + if err != nil { + b.Fatalf("could not read testdata/go1.html: %v", err) + } + b.SetBytes(int64(len(buf))) + runtime.GC() + var ms runtime.MemStats + runtime.ReadMemStats(&ms) + mallocs := ms.Mallocs + b.ResetTimer() + for i := 0; i < b.N; i++ { + z := NewTokenizer(bytes.NewBuffer(buf)) + for { + tt := z.Next() + if tt == ErrorToken { + if err := z.Err(); err != nil && err != io.EOF { + b.Fatalf("tokenizer error: %v", err) + } + break + } + switch level { + case rawLevel: + // Calling z.Raw just returns the raw bytes of the token. It does + // not unescape < to <, or lower-case tag names and attribute keys. + z.Raw() + case lowLevel: + // Caling z.Text, z.TagName and z.TagAttr returns []byte values + // whose contents may change on the next call to z.Next. + switch tt { + case TextToken, CommentToken, DoctypeToken: + z.Text() + case StartTagToken, SelfClosingTagToken: + _, more := z.TagName() + for more { + _, _, more = z.TagAttr() + } + case EndTagToken: + z.TagName() + } + case highLevel: + // Calling z.Token converts []byte values to strings whose validity + // extend beyond the next call to z.Next. + z.Token() + } + } + } + b.StopTimer() + runtime.ReadMemStats(&ms) + mallocs = ms.Mallocs - mallocs + b.Logf("%d iterations, %d mallocs per iteration\n", b.N, int(mallocs)/b.N) +} + +func BenchmarkRawLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, rawLevel) } +func BenchmarkLowLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, lowLevel) } +func BenchmarkHighLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, highLevel) } diff --git a/libgo/go/exp/locale/collate/build/builder.go b/libgo/go/exp/locale/collate/build/builder.go new file mode 100644 index 0000000..97d5e81 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/builder.go @@ -0,0 +1,476 @@ +// Copyright 2012 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 build + +import ( + "exp/locale/collate" + "exp/norm" + "fmt" + "io" + "log" + "sort" + "strings" + "unicode/utf8" +) + +// TODO: optimizations: +// - expandElem is currently 20K. By putting unique colElems in a separate +// table and having a byte array of indexes into this table, we can reduce +// the total size to about 7K. By also factoring out the length bytes, we +// can reduce this to about 6K. +// - trie valueBlocks are currently 100K. There are a lot of sparse blocks +// and many consecutive values with the same stride. This can be further +// compacted. +// - Compress secondary weights into 8 bits. +// - Some LDML specs specify a context element. Currently we simply concatenate +// those. Context can be implemented using the contraction trie. If Builder +// could analyze and detect when using a context makes sense, there is no +// need to expose this construct in the API. + +// A Builder builds a root collation table. The user must specify the +// collation elements for each entry. A common use will be to base the weights +// on those specified in the allkeys* file as provided by the UCA or CLDR. +type Builder struct { + index *trieBuilder + root ordering + locale []*Tailoring + t *table + err error + built bool + + minNonVar int // lowest primary recorded for a variable + varTop int // highest primary recorded for a non-variable + + // indexes used for reusing expansions and contractions + expIndex map[string]int // positions of expansions keyed by their string representation + ctHandle map[string]ctHandle // contraction handles keyed by a concatenation of the suffixes + ctElem map[string]int // contraction elements keyed by their string representation +} + +// A Tailoring builds a collation table based on another collation table. +// The table is defined by specifying tailorings to the underlying table. +// See http://unicode.org/reports/tr35/ for an overview of tailoring +// collation tables. The CLDR contains pre-defined tailorings for a variety +// of languages (See http://www.unicode.org/Public/cldr/2.0.1/core.zip.) +type Tailoring struct { + id string + builder *Builder + index *ordering + // TODO: implement. +} + +// NewBuilder returns a new Builder. +func NewBuilder() *Builder { + return &Builder{ + index: newTrieBuilder(), + root: makeRootOrdering(), + expIndex: make(map[string]int), + ctHandle: make(map[string]ctHandle), + ctElem: make(map[string]int), + } +} + +// Tailoring returns a Tailoring for the given locale. One should +// have completed all calls to Add before calling Tailoring. +func (b *Builder) Tailoring(locale string) *Tailoring { + t := &Tailoring{ + id: locale, + builder: b, + index: b.root.clone(), + } + b.locale = append(b.locale, t) + return t +} + +// Add adds an entry to the collation element table, mapping +// a slice of runes to a sequence of collation elements. +// A collation element is specified as list of weights: []int{primary, secondary, ...}. +// The entries are typically obtained from a collation element table +// as defined in http://www.unicode.org/reports/tr10/#Data_Table_Format. +// Note that the collation elements specified by colelems are only used +// as a guide. The actual weights generated by Builder may differ. +// The argument variables is a list of indices into colelems that should contain +// a value for each colelem that is a variable. (See the reference above.) +func (b *Builder) Add(runes []rune, colelems [][]int, variables []int) error { + str := string(runes) + + elems := make([][]int, len(colelems)) + for i, ce := range colelems { + elems[i] = append(elems[i], ce...) + if len(ce) == 0 { + elems[i] = append(elems[i], []int{0, 0, 0, 0}...) + break + } + if len(ce) == 1 { + elems[i] = append(elems[i], defaultSecondary) + } + if len(ce) <= 2 { + elems[i] = append(elems[i], defaultTertiary) + } + if len(ce) <= 3 { + elems[i] = append(elems[i], ce[0]) + } + } + for i, ce := range elems { + isvar := false + for _, j := range variables { + if i == j { + isvar = true + } + } + if isvar { + if ce[0] >= b.minNonVar && b.minNonVar > 0 { + return fmt.Errorf("primary value %X of variable is larger than the smallest non-variable %X", ce[0], b.minNonVar) + } + if ce[0] > b.varTop { + b.varTop = ce[0] + } + } else if ce[0] > 0 { + if ce[0] <= b.varTop { + return fmt.Errorf("primary value %X of non-variable is smaller than the highest variable %X", ce[0], b.varTop) + } + if b.minNonVar == 0 || ce[0] < b.minNonVar { + b.minNonVar = ce[0] + } + } + } + elems, err := convertLargeWeights(elems) + if err != nil { + return err + } + b.root.newEntry(str, elems) + return nil +} + +// SetAnchor sets the point after which elements passed in subsequent calls to +// Insert will be inserted. It is equivalent to the reset directive in an LDML +// specification. See Insert for an example. +// SetAnchor supports the following logical reset positions: +// <first_tertiary_ignorable/>, <last_teriary_ignorable/>, <first_primary_ignorable/>, +// and <last_non_ignorable/>. +func (t *Tailoring) SetAnchor(anchor string) error { + // TODO: implement. + return nil +} + +// SetAnchorBefore is similar to SetAnchor, except that subsequent calls to +// Insert will insert entries before the anchor. +func (t *Tailoring) SetAnchorBefore(anchor string) error { + // TODO: implement. + return nil +} + +// Insert sets the ordering of str relative to the entry set by the previous +// call to SetAnchor or Insert. The argument extend corresponds +// to the extend elements as defined in LDML. A non-empty value for extend +// will cause the collation elements corresponding to extend to be appended +// to the collation elements generated for the entry added by Insert. +// This has the same net effect as sorting str after the string anchor+extend. +// See http://www.unicode.org/reports/tr10/#Tailoring_Example for details +// on parametric tailoring and http://unicode.org/reports/tr35/#Collation_Elements +// for full details on LDML. +// +// Examples: create a tailoring for Swedish, where "ä" is ordered after "z" +// at the primary sorting level: +// t := b.Tailoring("se") +// t.SetAnchor("z") +// t.Insert(collate.Primary, "ä", "") +// Order "ü" after "ue" at the secondary sorting level: +// t.SetAnchor("ue") +// t.Insert(collate.Secondary, "ü","") +// or +// t.SetAnchor("u") +// t.Insert(collate.Secondary, "ü", "e") +// Order "q" afer "ab" at the secondary level and "Q" after "q" +// at the tertiary level: +// t.SetAnchor("ab") +// t.Insert(collate.Secondary, "q", "") +// t.Insert(collate.Tertiary, "Q", "") +// Order "b" before "a": +// t.SetAnchorBefore("a") +// t.Insert(collate.Primary, "b", "") +// Order "0" after the last primary ignorable: +// t.SetAnchor("<last_primary_ignorable/>") +// t.Insert(collate.Primary, "0", "") +func (t *Tailoring) Insert(level collate.Level, str, extend string) error { + // TODO: implement. + return nil +} + +func (b *Builder) error(e error) { + if e != nil { + b.err = e + } +} + +func (b *Builder) buildOrdering(o *ordering) { + o.sort() + simplify(o) + b.processExpansions(o) // requires simplify + b.processContractions(o) // requires simplify + + t := newNode() + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if !e.skip() { + ce, err := e.encode() + b.error(err) + t.insert(e.runes[0], ce) + } + } + o.handle = b.index.addTrie(t) +} + +func (b *Builder) build() (*table, error) { + if b.built { + return b.t, b.err + } + b.built = true + b.t = &table{ + maxContractLen: utf8.UTFMax, + variableTop: uint32(b.varTop), + } + + b.buildOrdering(&b.root) + b.t.root = b.root.handle + for _, t := range b.locale { + b.buildOrdering(t.index) + if b.err != nil { + break + } + } + i, err := b.index.generate() + b.t.index = *i + b.error(err) + return b.t, b.err +} + +// Build builds the root Collator. +func (b *Builder) Build() (*collate.Collator, error) { + t, err := b.build() + if err != nil { + return nil, err + } + return collate.Init(t), nil +} + +// Build builds a Collator for Tailoring t. +func (t *Tailoring) Build() (*collate.Collator, error) { + // TODO: implement. + return nil, nil +} + +// Print prints the tables for b and all its Tailorings as a Go file +// that can be included in the Collate package. +func (b *Builder) Print(w io.Writer) (n int, err error) { + p := func(nn int, e error) { + n += nn + if err == nil { + err = e + } + } + t, err := b.build() + if err != nil { + return 0, err + } + p(fmt.Fprintf(w, "var availableLocales = []string{")) + for _, loc := range b.locale { + p(fmt.Fprintf(w, "%q, ", loc.id)) + } + p(fmt.Fprintln(w, "}\n")) + p(fmt.Fprintln(w, "var locales = map[string]tableIndex{")) + for _, loc := range b.locale { + p(fmt.Fprintf(w, "\t%q: ", loc.id)) + p(t.fprintIndex(w, loc.index.handle)) + p(fmt.Fprintln(w, ",")) + } + p(fmt.Fprint(w, "}\n\n")) + n, _, err = t.fprint(w, "main") + return +} + +// reproducibleFromNFKD checks whether the given expansion could be generated +// from an NFKD expansion. +func reproducibleFromNFKD(e *entry, exp, nfkd [][]int) bool { + // Length must be equal. + if len(exp) != len(nfkd) { + return false + } + for i, ce := range exp { + // Primary and secondary values should be equal. + if ce[0] != nfkd[i][0] || ce[1] != nfkd[i][1] { + return false + } + // Tertiary values should be equal to maxTertiary for third element onwards. + // TODO: there seem to be a lot of cases in CLDR (e.g. ㏭ in zh.xml) that can + // simply be dropped. Try this out by dropping the following code. + if i >= 2 && ce[2] != maxTertiary { + return false + } + } + return true +} + +func simplify(o *ordering) { + // Runes that are a starter of a contraction should not be removed. + // (To date, there is only Kannada character 0CCA.) + keep := make(map[rune]bool) + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if len(e.runes) > 1 { + keep[e.runes[0]] = true + } + } + // Remove entries for which the runes normalize (using NFD) to identical values. + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + s := e.str + nfd := norm.NFD.String(s) + if len(e.runes) > 1 || keep[e.runes[0]] || nfd == s { + continue + } + if equalCEArrays(o.genColElems(nfd), e.elems) { + e.remove() + } + } + + // Tag entries for which the runes NFKD decompose to identical values. + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + s := e.str + nfkd := norm.NFKD.String(s) + if len(e.runes) > 1 || keep[e.runes[0]] || nfkd == s { + continue + } + if reproducibleFromNFKD(e, e.elems, o.genColElems(nfkd)) { + e.decompose = true + } + } +} + +// appendExpansion converts the given collation sequence to +// collation elements and adds them to the expansion table. +// It returns an index to the expansion table. +func (b *Builder) appendExpansion(e *entry) int { + t := b.t + i := len(t.expandElem) + ce := uint32(len(e.elems)) + t.expandElem = append(t.expandElem, ce) + for _, w := range e.elems { + ce, err := makeCE(w) + if err != nil { + b.error(err) + return -1 + } + t.expandElem = append(t.expandElem, ce) + } + return i +} + +// processExpansions extracts data necessary to generate +// the extraction tables. +func (b *Builder) processExpansions(o *ordering) { + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if !e.expansion() { + continue + } + key := fmt.Sprintf("%v", e.elems) + i, ok := b.expIndex[key] + if !ok { + i = b.appendExpansion(e) + b.expIndex[key] = i + } + e.expansionIndex = i + } +} + +func (b *Builder) processContractions(o *ordering) { + // Collate contractions per starter rune. + starters := []rune{} + cm := make(map[rune][]*entry) + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if e.contraction() { + if len(e.str) > b.t.maxContractLen { + b.t.maxContractLen = len(e.str) + } + r := e.runes[0] + if _, ok := cm[r]; !ok { + starters = append(starters, r) + } + cm[r] = append(cm[r], e) + } + } + // Add entries of single runes that are at a start of a contraction. + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if !e.contraction() { + r := e.runes[0] + if _, ok := cm[r]; ok { + cm[r] = append(cm[r], e) + } + } + } + // Build the tries for the contractions. + t := b.t + for _, r := range starters { + l := cm[r] + // Compute suffix strings. There are 31 different contraction suffix + // sets for 715 contractions and 82 contraction starter runes as of + // version 6.0.0. + sufx := []string{} + hasSingle := false + for _, e := range l { + if len(e.runes) > 1 { + sufx = append(sufx, string(e.runes[1:])) + } else { + hasSingle = true + } + } + if !hasSingle { + b.error(fmt.Errorf("no single entry for starter rune %U found", r)) + continue + } + // Unique the suffix set. + sort.Strings(sufx) + key := strings.Join(sufx, "\n") + handle, ok := b.ctHandle[key] + if !ok { + var err error + handle, err = t.contractTries.appendTrie(sufx) + if err != nil { + b.error(err) + } + b.ctHandle[key] = handle + } + // Bucket sort entries in index order. + es := make([]*entry, len(l)) + for _, e := range l { + var o, sn int + if len(e.runes) > 1 { + str := []byte(string(e.runes[1:])) + o, sn = t.contractTries.lookup(handle, str) + if sn != len(str) { + log.Fatalf("processContractions: unexpected length for '%X'; len=%d; want %d", e.runes, sn, len(str)) + } + } + if es[o] != nil { + log.Fatalf("Multiple contractions for position %d for rune %U", o, e.runes[0]) + } + es[o] = e + } + // Create collation elements for contractions. + elems := []uint32{} + for _, e := range es { + ce, err := e.encodeBase() + b.error(err) + elems = append(elems, ce) + } + key = fmt.Sprintf("%v", elems) + i, ok := b.ctElem[key] + if !ok { + i = len(t.contractElem) + b.ctElem[key] = i + t.contractElem = append(t.contractElem, elems...) + } + // Store info in entry for starter rune. + es[0].contractionIndex = i + es[0].contractionHandle = handle + } +} diff --git a/libgo/go/exp/locale/collate/build/builder_test.go b/libgo/go/exp/locale/collate/build/builder_test.go new file mode 100644 index 0000000..f80a2bc --- /dev/null +++ b/libgo/go/exp/locale/collate/build/builder_test.go @@ -0,0 +1,269 @@ +// Copyright 2012 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 build + +import "testing" + +// cjk returns an implicit collation element for a CJK rune. +func cjk(r rune) [][]int { + // A CJK character C is represented in the DUCET as + // [.AAAA.0020.0002.C][.BBBB.0000.0000.C] + // Where AAAA is the most significant 15 bits plus a base value. + // Any base value will work for the test, so we pick the common value of FB40. + const base = 0xFB40 + return [][]int{ + {base + int(r>>15), defaultSecondary, defaultTertiary, int(r)}, + {int(r&0x7FFF) | 0x8000, 0, 0, int(r)}, + } +} + +func pCE(p int) [][]int { + return [][]int{{p, defaultSecondary, defaultTertiary, 0}} +} + +func pqCE(p, q int) [][]int { + return [][]int{{p, defaultSecondary, defaultTertiary, q}} +} + +func ptCE(p, t int) [][]int { + return [][]int{{p, defaultSecondary, t, 0}} +} + +func sCE(s int) [][]int { + return [][]int{{0, s, defaultTertiary, 0}} +} + +func stCE(s, t int) [][]int { + return [][]int{{0, s, t, 0}} +} + +// ducetElem is used to define test data that is used to generate a table. +type ducetElem struct { + str string + ces [][]int +} + +func newBuilder(t *testing.T, ducet []ducetElem) *Builder { + b := NewBuilder() + for _, e := range ducet { + if err := b.Add([]rune(e.str), e.ces, nil); err != nil { + t.Errorf(err.Error()) + } + } + b.t = &table{} + b.root.sort() + return b +} + +type convertTest struct { + in, out [][]int + err bool +} + +var convLargeTests = []convertTest{ + {pCE(0xFB39), pCE(0xFB39), false}, + {cjk(0x2F9B2), pqCE(0x3F9B2, 0x2F9B2), false}, + {pCE(0xFB40), pCE(0), true}, + {append(pCE(0xFB40), pCE(0)[0]), pCE(0), true}, + {pCE(0xFFFE), pCE(illegalOffset), false}, + {pCE(0xFFFF), pCE(illegalOffset + 1), false}, +} + +func TestConvertLarge(t *testing.T) { + for i, tt := range convLargeTests { + e := &entry{elems: tt.in} + elems, err := convertLargeWeights(e.elems) + if tt.err { + if err == nil { + t.Errorf("%d: expected error; none found", i) + } + continue + } else if err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + } + if !equalCEArrays(elems, tt.out) { + t.Errorf("%d: conversion was %x; want %x", i, elems, tt.out) + } + } +} + +// Collation element table for simplify tests. +var simplifyTest = []ducetElem{ + {"\u0300", sCE(30)}, // grave + {"\u030C", sCE(40)}, // caron + {"A", ptCE(100, 8)}, + {"D", ptCE(104, 8)}, + {"E", ptCE(105, 8)}, + {"I", ptCE(110, 8)}, + {"z", ptCE(130, 8)}, + {"\u05F2", append(ptCE(200, 4), ptCE(200, 4)[0])}, + {"\u05B7", sCE(80)}, + {"\u00C0", append(ptCE(100, 8), sCE(30)...)}, // A with grave, can be removed + {"\u00C8", append(ptCE(105, 8), sCE(30)...)}, // E with grave + {"\uFB1F", append(ptCE(200, 4), ptCE(200, 4)[0], sCE(80)[0])}, // eliminated by NFD + {"\u00C8\u0302", ptCE(106, 8)}, // block previous from simplifying + {"\u01C5", append(ptCE(104, 9), ptCE(130, 4)[0], stCE(40, maxTertiary)[0])}, // eliminated by NFKD + // no removal: tertiary value of third element is not maxTertiary + {"\u2162", append(ptCE(110, 9), ptCE(110, 4)[0], ptCE(110, 8)[0])}, +} + +var genColTests = []ducetElem{ + {"\uFA70", pqCE(0x1FA70, 0xFA70)}, + {"A\u0300", append(ptCE(100, 8), sCE(30)...)}, + {"A\u0300\uFA70", append(ptCE(100, 8), sCE(30)[0], pqCE(0x1FA70, 0xFA70)[0])}, + {"A\u0300A\u0300", append(ptCE(100, 8), sCE(30)[0], ptCE(100, 8)[0], sCE(30)[0])}, +} + +func TestGenColElems(t *testing.T) { + b := newBuilder(t, simplifyTest[:5]) + + for i, tt := range genColTests { + res := b.root.genColElems(tt.str) + if !equalCEArrays(tt.ces, res) { + t.Errorf("%d: result %X; want %X", i, res, tt.ces) + } + } +} + +type strArray []string + +func (sa strArray) contains(s string) bool { + for _, e := range sa { + if e == s { + return true + } + } + return false +} + +var simplifyRemoved = strArray{"\u00C0", "\uFB1F"} +var simplifyMarked = strArray{"\u01C5"} + +func TestSimplify(t *testing.T) { + b := newBuilder(t, simplifyTest) + o := &b.root + simplify(o) + + for i, tt := range simplifyTest { + if simplifyRemoved.contains(tt.str) { + continue + } + e := o.find(tt.str) + if e.str != tt.str || !equalCEArrays(e.elems, tt.ces) { + t.Errorf("%d: found element %s -> %X; want %s -> %X", i, e.str, e.elems, tt.str, tt.ces) + break + } + } + var i, k int + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + gold := simplifyMarked.contains(e.str) + if gold { + k++ + } + if gold != e.decompose { + t.Errorf("%d: %s has decompose %v; want %v", i, e.str, e.decompose, gold) + } + i++ + } + if k != len(simplifyMarked) { + t.Errorf(" an entry that should be marked as decompose was deleted") + } +} + +var expandTest = []ducetElem{ + {"\u00C0", append(ptCE(100, 8), sCE(30)...)}, + {"\u00C8", append(ptCE(105, 8), sCE(30)...)}, + {"\u00C9", append(ptCE(105, 8), sCE(30)...)}, // identical expansion + {"\u05F2", append(ptCE(200, 4), ptCE(200, 4)[0], ptCE(200, 4)[0])}, +} + +func TestExpand(t *testing.T) { + const ( + totalExpansions = 3 + totalElements = 2 + 2 + 3 + totalExpansions + ) + b := newBuilder(t, expandTest) + o := &b.root + b.processExpansions(o) + + e := o.front() + for _, tt := range expandTest { + exp := b.t.expandElem[e.expansionIndex:] + if int(exp[0]) != len(tt.ces) { + t.Errorf("%U: len(expansion)==%d; want %d", []rune(tt.str)[0], exp[0], len(tt.ces)) + } + exp = exp[1:] + for j, w := range tt.ces { + if ce, _ := makeCE(w); exp[j] != ce { + t.Errorf("%U: element %d is %X; want %X", []rune(tt.str)[0], j, exp[j], ce) + } + } + e, _ = e.nextIndexed() + } + // Verify uniquing. + if len(b.t.expandElem) != totalElements { + t.Errorf("len(expandElem)==%d; want %d", len(b.t.expandElem), totalElements) + } +} + +var contractTest = []ducetElem{ + {"abc", pCE(102)}, + {"abd", pCE(103)}, + {"a", pCE(100)}, + {"ab", pCE(101)}, + {"ac", pCE(104)}, + {"bcd", pCE(202)}, + {"b", pCE(200)}, + {"bc", pCE(201)}, + {"bd", pCE(203)}, + // shares suffixes with a* + {"Ab", pCE(301)}, + {"A", pCE(300)}, + {"Ac", pCE(304)}, + {"Abc", pCE(302)}, + {"Abd", pCE(303)}, + // starter to be ignored + {"z", pCE(1000)}, +} + +func TestContract(t *testing.T) { + const ( + totalElements = 5 + 5 + 4 + ) + b := newBuilder(t, contractTest) + o := &b.root + b.processContractions(o) + + indexMap := make(map[int]bool) + handleMap := make(map[rune]*entry) + for e := o.front(); e != nil; e, _ = e.nextIndexed() { + if e.contractionHandle.n > 0 { + handleMap[e.runes[0]] = e + indexMap[e.contractionHandle.index] = true + } + } + // Verify uniquing. + if len(indexMap) != 2 { + t.Errorf("number of tries is %d; want %d", len(indexMap), 2) + } + for _, tt := range contractTest { + e, ok := handleMap[[]rune(tt.str)[0]] + if !ok { + continue + } + str := tt.str[1:] + offset, n := b.t.contractTries.lookup(e.contractionHandle, []byte(str)) + if len(str) != n { + t.Errorf("%s: bytes consumed==%d; want %d", tt.str, n, len(str)) + } + ce := b.t.contractElem[offset+e.contractionIndex] + if want, _ := makeCE(tt.ces[0]); want != ce { + t.Errorf("%s: element %X; want %X", tt.str, ce, want) + } + } + if len(b.t.contractElem) != totalElements { + t.Errorf("len(expandElem)==%d; want %d", len(b.t.contractElem), totalElements) + } +} diff --git a/libgo/go/exp/locale/collate/build/colelem.go b/libgo/go/exp/locale/collate/build/colelem.go new file mode 100644 index 0000000..343aa74 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/colelem.go @@ -0,0 +1,329 @@ +// Copyright 2012 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 build + +import ( + "exp/locale/collate" + "fmt" + "unicode" +) + +const ( + defaultSecondary = 0x20 + defaultTertiary = 0x2 + maxTertiary = 0x1F +) + +// A collation element is represented as an uint32. +// In the typical case, a rune maps to a single collation element. If a rune +// can be the start of a contraction or expands into multiple collation elements, +// then the collation element that is associated with a rune will have a special +// form to represent such m to n mappings. Such special collation elements +// have a value >= 0x80000000. + +// For normal collation elements, we assume that a collation element either has +// a primary or non-default secondary value, not both. +// Collation elements with a primary value are of the form +// 010ppppp pppppppp pppppppp ssssssss +// - p* is primary collation value +// - s* is the secondary collation value +// or +// 00pppppp pppppppp ppppppps sssttttt, where +// - p* is primary collation value +// - s* offset of secondary from default value. +// - t* is the tertiary collation value +// Collation elements with a secondary value are of the form +// 10000000 0000ssss ssssssss tttttttt, where +// - 16 BMP implicit -> weight +// - 8 bit s +// - default tertiary +const ( + maxPrimaryBits = 21 + maxSecondaryBits = 12 + maxSecondaryCompactBits = 8 + maxSecondaryDiffBits = 4 + maxTertiaryBits = 8 + maxTertiaryCompactBits = 5 + + isSecondary = 0x80000000 + isPrimary = 0x40000000 +) + +func makeCE(weights []int) (uint32, error) { + if w := weights[0]; w >= 1<<maxPrimaryBits || w < 0 { + return 0, fmt.Errorf("makeCE: primary weight out of bounds: %x >= %x", w, 1<<maxPrimaryBits) + } + if w := weights[1]; w >= 1<<maxSecondaryBits || w < 0 { + return 0, fmt.Errorf("makeCE: secondary weight out of bounds: %x >= %x", w, 1<<maxSecondaryBits) + } + if w := weights[2]; w >= 1<<maxTertiaryBits || w < 0 { + return 0, fmt.Errorf("makeCE: tertiary weight out of bounds: %x >= %x", w, 1<<maxTertiaryBits) + } + ce := uint32(0) + if weights[0] != 0 { + if weights[2] == defaultTertiary { + if weights[1] >= 1<<maxSecondaryCompactBits { + return 0, fmt.Errorf("makeCE: secondary weight with non-zero primary out of bounds: %x >= %x", weights[1], 1<<maxSecondaryCompactBits) + } + ce = uint32(weights[0]<<maxSecondaryCompactBits + weights[1]) + ce |= isPrimary + } else { + d := weights[1] - defaultSecondary + if d >= 1<<maxSecondaryDiffBits || d < 0 { + return 0, fmt.Errorf("makeCE: secondary weight diff out of bounds: %x < 0 || %x > %x", d, d, 1<<maxSecondaryDiffBits) + } + if weights[2] >= 1<<maxTertiaryCompactBits { + return 0, fmt.Errorf("makeCE: tertiary weight with non-zero primary out of bounds: %x > %x (%X)", weights[2], 1<<maxTertiaryCompactBits, weights) + } + ce = uint32(weights[0]<<maxSecondaryDiffBits + d) + ce = ce<<maxTertiaryCompactBits + uint32(weights[2]) + } + } else { + ce = uint32(weights[1]<<maxTertiaryBits + weights[2]) + ce |= isSecondary + } + return ce, nil +} + +// For contractions, collation elements are of the form +// 110bbbbb bbbbbbbb iiiiiiii iiiinnnn, where +// - n* is the size of the first node in the contraction trie. +// - i* is the index of the first node in the contraction trie. +// - b* is the offset into the contraction collation element table. +// See contract.go for details on the contraction trie. +const ( + contractID = 0xC0000000 + maxNBits = 4 + maxTrieIndexBits = 12 + maxContractOffsetBits = 13 +) + +func makeContractIndex(h ctHandle, offset int) (uint32, error) { + if h.n >= 1<<maxNBits { + return 0, fmt.Errorf("size of contraction trie node too large: %d >= %d", h.n, 1<<maxNBits) + } + if h.index >= 1<<maxTrieIndexBits { + return 0, fmt.Errorf("size of contraction trie offset too large: %d >= %d", h.index, 1<<maxTrieIndexBits) + } + if offset >= 1<<maxContractOffsetBits { + return 0, fmt.Errorf("contraction offset out of bounds: %x >= %x", offset, 1<<maxContractOffsetBits) + } + ce := uint32(contractID) + ce += uint32(offset << (maxNBits + maxTrieIndexBits)) + ce += uint32(h.index << maxNBits) + ce += uint32(h.n) + return ce, nil +} + +// For expansions, collation elements are of the form +// 11100000 00000000 bbbbbbbb bbbbbbbb, +// where b* is the index into the expansion sequence table. +const ( + expandID = 0xE0000000 + maxExpandIndexBits = 16 +) + +func makeExpandIndex(index int) (uint32, error) { + if index >= 1<<maxExpandIndexBits { + return 0, fmt.Errorf("expansion index out of bounds: %x >= %x", index, 1<<maxExpandIndexBits) + } + return expandID + uint32(index), nil +} + +// Each list of collation elements corresponding to an expansion starts with +// a header indicating the length of the sequence. +func makeExpansionHeader(n int) (uint32, error) { + return uint32(n), nil +} + +// Some runes can be expanded using NFKD decomposition. Instead of storing the full +// sequence of collation elements, we decompose the rune and lookup the collation +// elements for each rune in the decomposition and modify the tertiary weights. +// The collation element, in this case, is of the form +// 11110000 00000000 wwwwwwww vvvvvvvv, where +// - v* is the replacement tertiary weight for the first rune, +// - w* is the replacement tertiary weight for the second rune, +// Tertiary weights of subsequent runes should be replaced with maxTertiary. +// See http://www.unicode.org/reports/tr10/#Compatibility_Decompositions for more details. +const ( + decompID = 0xF0000000 +) + +func makeDecompose(t1, t2 int) (uint32, error) { + if t1 >= 256 || t1 < 0 { + return 0, fmt.Errorf("first tertiary weight out of bounds: %d >= 256", t1) + } + if t2 >= 256 || t2 < 0 { + return 0, fmt.Errorf("second tertiary weight out of bounds: %d >= 256", t2) + } + return uint32(t2<<8+t1) + decompID, nil +} + +const ( + // These constants were taken from http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf. + minUnified rune = 0x4E00 + maxUnified = 0x9FFF + minCompatibility = 0xF900 + maxCompatibility = 0xFAFF + minRare = 0x3400 + maxRare = 0x4DBF +) +const ( + commonUnifiedOffset = 0x10000 + rareUnifiedOffset = 0x20000 // largest rune in common is U+FAFF + otherOffset = 0x50000 // largest rune in rare is U+2FA1D + illegalOffset = otherOffset + int(unicode.MaxRune) + maxPrimary = illegalOffset + 1 +) + +// implicitPrimary returns the primary weight for the a rune +// for which there is no entry for the rune in the collation table. +// We take a different approach from the one specified in +// http://unicode.org/reports/tr10/#Implicit_Weights, +// but preserve the resulting relative ordering of the runes. +func implicitPrimary(r rune) int { + if unicode.Is(unicode.Ideographic, r) { + if r >= minUnified && r <= maxUnified { + // The most common case for CJK. + return int(r) + commonUnifiedOffset + } + if r >= minCompatibility && r <= maxCompatibility { + // This will typically not hit. The DUCET explicitly specifies mappings + // for all characters that do not decompose. + return int(r) + commonUnifiedOffset + } + return int(r) + rareUnifiedOffset + } + return int(r) + otherOffset +} + +// convertLargeWeights converts collation elements with large +// primaries (either double primaries or for illegal runes) +// to our own representation. +// A CJK character C is represented in the DUCET as +// [.FBxx.0020.0002.C][.BBBB.0000.0000.C] +// We will rewrite these characters to a single CE. +// We assume the CJK values start at 0x8000. +// See http://unicode.org/reports/tr10/#Implicit_Weights +func convertLargeWeights(elems [][]int) (res [][]int, err error) { + const ( + cjkPrimaryStart = 0xFB40 + rarePrimaryStart = 0xFB80 + otherPrimaryStart = 0xFBC0 + illegalPrimary = 0xFFFE + highBitsMask = 0x3F + lowBitsMask = 0x7FFF + lowBitsFlag = 0x8000 + shiftBits = 15 + ) + for i := 0; i < len(elems); i++ { + ce := elems[i] + p := ce[0] + if p < cjkPrimaryStart { + continue + } + if p > 0xFFFF { + return elems, fmt.Errorf("found primary weight %X; should be <= 0xFFFF", p) + } + if p >= illegalPrimary { + ce[0] = illegalOffset + p - illegalPrimary + } else { + if i+1 >= len(elems) { + return elems, fmt.Errorf("second part of double primary weight missing: %v", elems) + } + if elems[i+1][0]&lowBitsFlag == 0 { + return elems, fmt.Errorf("malformed second part of double primary weight: %v", elems) + } + np := ((p & highBitsMask) << shiftBits) + elems[i+1][0]&lowBitsMask + switch { + case p < rarePrimaryStart: + np += commonUnifiedOffset + case p < otherPrimaryStart: + np += rareUnifiedOffset + default: + p += otherOffset + } + ce[0] = np + for j := i + 1; j+1 < len(elems); j++ { + elems[j] = elems[j+1] + } + elems = elems[:len(elems)-1] + } + } + return elems, nil +} + +// nextWeight computes the first possible collation weights following elems +// for the given level. +func nextWeight(level collate.Level, elems [][]int) [][]int { + nce := make([][]int, len(elems)) + copy(nce, elems) + + if level != collate.Identity { + nce[0] = make([]int, len(elems[0])) + copy(nce[0], elems[0]) + nce[0][level]++ + if level < collate.Secondary { + nce[0][collate.Secondary] = defaultSecondary + } + if level < collate.Tertiary { + nce[0][collate.Tertiary] = defaultTertiary + } + } + return nce +} + +func nextVal(elems [][]int, i int, level collate.Level) (index, value int) { + for ; i < len(elems) && elems[i][level] == 0; i++ { + } + if i < len(elems) { + return i, elems[i][level] + } + return i, 0 +} + +// compareWeights returns -1 if a < b, 1 if a > b, or 0 otherwise. +// It also returns the collation level at which the difference is found. +func compareWeights(a, b [][]int) (result int, level collate.Level) { + for level := collate.Primary; level < collate.Identity; level++ { + var va, vb int + for ia, ib := 0, 0; ia < len(a) || ib < len(b); ia, ib = ia+1, ib+1 { + ia, va = nextVal(a, ia, level) + ib, vb = nextVal(b, ib, level) + if va != vb { + if va < vb { + return -1, level + } else { + return 1, level + } + } + } + } + return 0, collate.Identity +} + +func equalCE(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i := 0; i < 3; i++ { + if b[i] != a[i] { + return false + } + } + return true +} + +func equalCEArrays(a, b [][]int) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if !equalCE(a[i], b[i]) { + return false + } + } + return true +} diff --git a/libgo/go/exp/locale/collate/build/colelem_test.go b/libgo/go/exp/locale/collate/build/colelem_test.go new file mode 100644 index 0000000..28d7c89 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/colelem_test.go @@ -0,0 +1,197 @@ +// Copyright 2012 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 build + +import ( + "exp/locale/collate" + "testing" +) + +type ceTest struct { + f func(in []int) (uint32, error) + arg []int + val uint32 +} + +func normalCE(in []int) (ce uint32, err error) { + return makeCE(in) +} + +func expandCE(in []int) (ce uint32, err error) { + return makeExpandIndex(in[0]) +} + +func contractCE(in []int) (ce uint32, err error) { + return makeContractIndex(ctHandle{in[0], in[1]}, in[2]) +} + +func decompCE(in []int) (ce uint32, err error) { + return makeDecompose(in[0], in[1]) +} + +var ceTests = []ceTest{ + {normalCE, []int{0, 0, 0}, 0x80000000}, + {normalCE, []int{0, 0x28, 3}, 0x80002803}, + {normalCE, []int{100, defaultSecondary, 3}, 0x0000C803}, + // non-ignorable primary with non-default secondary + {normalCE, []int{100, 0x28, defaultTertiary}, 0x40006428}, + {normalCE, []int{100, defaultSecondary + 8, 3}, 0x0000C903}, + {normalCE, []int{100, 0, 3}, 0xFFFF}, // non-ignorable primary with non-supported secondary + {normalCE, []int{100, 1, 3}, 0xFFFF}, + {normalCE, []int{1 << maxPrimaryBits, defaultSecondary, 0}, 0xFFFF}, + {normalCE, []int{0, 1 << maxSecondaryBits, 0}, 0xFFFF}, + {normalCE, []int{100, defaultSecondary, 1 << maxTertiaryBits}, 0xFFFF}, + + {contractCE, []int{0, 0, 0}, 0xC0000000}, + {contractCE, []int{1, 1, 1}, 0xC0010011}, + {contractCE, []int{1, (1 << maxNBits) - 1, 1}, 0xC001001F}, + {contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}, 0xC001FFF1}, + {contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}, 0xDFFF0011}, + {contractCE, []int{1, (1 << maxNBits), 1}, 0xFFFF}, + {contractCE, []int{(1 << maxTrieIndexBits), 1, 1}, 0xFFFF}, + {contractCE, []int{1, (1 << maxContractOffsetBits), 1}, 0xFFFF}, + + {expandCE, []int{0}, 0xE0000000}, + {expandCE, []int{5}, 0xE0000005}, + {expandCE, []int{(1 << maxExpandIndexBits) - 1}, 0xE000FFFF}, + {expandCE, []int{1 << maxExpandIndexBits}, 0xFFFF}, + + {decompCE, []int{0, 0}, 0xF0000000}, + {decompCE, []int{1, 1}, 0xF0000101}, + {decompCE, []int{0x1F, 0x1F}, 0xF0001F1F}, + {decompCE, []int{256, 0x1F}, 0xFFFF}, + {decompCE, []int{0x1F, 256}, 0xFFFF}, +} + +func TestColElem(t *testing.T) { + for i, tt := range ceTests { + in := make([]int, len(tt.arg)) + copy(in, tt.arg) + ce, err := tt.f(in) + if tt.val == 0xFFFF { + if err == nil { + t.Errorf("%d: expected error for args %x", i, tt.arg) + } + continue + } + if err != nil { + t.Errorf("%d: unexpected error: %v", i, err.Error()) + } + if ce != tt.val { + t.Errorf("%d: colElem=%X; want %X", i, ce, tt.val) + } + } +} + +type weightsTest struct { + a, b [][]int + level collate.Level + result int +} + +var nextWeightTests = []weightsTest{ + { + a: [][]int{{100, 20, 5, 0}}, + b: [][]int{{101, defaultSecondary, defaultTertiary, 0}}, + level: collate.Primary, + }, + { + a: [][]int{{100, 20, 5, 0}}, + b: [][]int{{100, 21, defaultTertiary, 0}}, + level: collate.Secondary, + }, + { + a: [][]int{{100, 20, 5, 0}}, + b: [][]int{{100, 20, 6, 0}}, + level: collate.Tertiary, + }, + { + a: [][]int{{100, 20, 5, 0}}, + b: [][]int{{100, 20, 5, 0}}, + level: collate.Identity, + }, +} + +var extra = []int{200, 32, 8, 0} + +func TestNextWeight(t *testing.T) { + for i, tt := range nextWeightTests { + test := func(tt weightsTest, a, gold [][]int) { + res := nextWeight(tt.level, a) + if !equalCEArrays(gold, res) { + t.Errorf("%d: expected weights %d; found %d", i, tt.b, res) + } + } + test(tt, tt.a, tt.b) + test(tt, append(tt.a, extra), append(tt.b, extra)) + } +} + +var compareTests = []weightsTest{ + { + [][]int{{100, 20, 5, 0}}, + [][]int{{100, 20, 5, 0}}, + collate.Identity, + 0, + }, + { + [][]int{{100, 20, 5, 0}, extra}, + [][]int{{100, 20, 5, 1}}, + collate.Primary, + 1, + }, + { + [][]int{{100, 20, 5, 0}}, + [][]int{{101, 20, 5, 0}}, + collate.Primary, + -1, + }, + { + [][]int{{101, 20, 5, 0}}, + [][]int{{100, 20, 5, 0}}, + collate.Primary, + 1, + }, + { + [][]int{{100, 0, 0, 0}, {0, 20, 5, 0}}, + [][]int{{0, 20, 5, 0}, {100, 0, 0, 0}}, + collate.Identity, + 0, + }, + { + [][]int{{100, 20, 5, 0}}, + [][]int{{100, 21, 5, 0}}, + collate.Secondary, + -1, + }, + { + [][]int{{100, 20, 5, 0}}, + [][]int{{100, 20, 2, 0}}, + collate.Tertiary, + 1, + }, + { + [][]int{{100, 20, 5, 1}}, + [][]int{{100, 20, 5, 2}}, + collate.Quaternary, + -1, + }, +} + +func TestCompareWeights(t *testing.T) { + for i, tt := range compareTests { + test := func(tt weightsTest, a, b [][]int) { + res, level := compareWeights(a, b) + if res != tt.result { + t.Errorf("%d: expected comparisson result %d; found %d", i, tt.result, res) + } + if level != tt.level { + t.Errorf("%d: expected level %d; found %d", i, tt.level, level) + } + } + test(tt, tt.a, tt.b) + test(tt, append(tt.a, extra), append(tt.b, extra)) + } +} diff --git a/libgo/go/exp/locale/collate/build/contract.go b/libgo/go/exp/locale/collate/build/contract.go new file mode 100644 index 0000000..f7cf64a --- /dev/null +++ b/libgo/go/exp/locale/collate/build/contract.go @@ -0,0 +1,307 @@ +// Copyright 2012 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 build + +import ( + "fmt" + "io" + "reflect" + "sort" + "strings" +) + +// This file contains code for detecting contractions and generating +// the necessary tables. +// Any Unicode Collation Algorithm (UCA) table entry that has more than +// one rune one the left-hand side is called a contraction. +// See http://www.unicode.org/reports/tr10/#Contractions for more details. +// +// We define the following terms: +// initial: a rune that appears as the first rune in a contraction. +// suffix: a sequence of runes succeeding the initial rune +// in a given contraction. +// non-initial: a rune that appears in a suffix. +// +// A rune may be both a initial and a non-initial and may be so in +// many contractions. An initial may typically also appear by itself. +// In case of ambiguities, the UCA requires we match the longest +// contraction. +// +// Many contraction rules share the same set of possible suffixes. +// We store sets of suffixes in a trie that associates an index with +// each suffix in the set. This index can be used to look up a +// collation element associated with the (starter rune, suffix) pair. +// +// The trie is defined on a UTF-8 byte sequence. +// The overall trie is represented as an array of ctEntries. Each node of the trie +// is represented as a subsequence of ctEntries, where each entry corresponds to +// a possible match of a next character in the search string. An entry +// also includes the length and offset to the next sequence of entries +// to check in case of a match. + +const ( + final = 0 + noIndex = 0xFF +) + +// ctEntry associates to a matching byte an offset and/or next sequence of +// bytes to check. A ctEntry c is called final if a match means that the +// longest suffix has been found. An entry c is final if c.n == 0. +// A single final entry can match a range of characters to an offset. +// A non-final entry always matches a single byte. Note that a non-final +// entry might still resemble a completed suffix. +// Examples: +// The suffix strings "ab" and "ac" can be represented as: +// []ctEntry{ +// {'a', 1, 1, noIndex}, // 'a' by itself does not match, so i is 0xFF. +// {'b', 'c', 0, 1}, // "ab" -> 1, "ac" -> 2 +// } +// +// The suffix strings "ab", "abc", "abd", and "abcd" can be represented as: +// []ctEntry{ +// {'a', 1, 1, noIndex}, // 'a' must be followed by 'b'. +// {'b', 1, 2, 1}, // "ab" -> 1, may be followed by 'c' or 'd'. +// {'d', 'd', final, 3}, // "abd" -> 3 +// {'c', 4, 1, 2}, // "abc" -> 2, may be followed by 'd'. +// {'d', 'd', final, 4}, // "abcd" -> 4 +// } +// See genStateTests in contract_test.go for more examples. +type ctEntry struct { + l uint8 // non-final: byte value to match; final: lowest match in range. + h uint8 // non-final: relative index to next block; final: highest match in range. + n uint8 // non-final: length of next block; final: final + i uint8 // result offset. Will be noIndex if more bytes are needed to complete. +} + +// contractTrieSet holds a set of contraction tries. The tries are stored +// consecutively in the entry field. +type contractTrieSet []struct{ l, h, n, i uint8 } + +// ctHandle is used to identify a trie in the trie set, consisting in an offset +// in the array and the size of the first node. +type ctHandle struct { + index, n int +} + +// appendTrie adds a new trie for the given suffixes to the trie set and returns +// a handle to it. The handle will be invalid on error. +func (ct *contractTrieSet) appendTrie(suffixes []string) (ctHandle, error) { + es := make([]stridx, len(suffixes)) + for i, s := range suffixes { + es[i].str = s + } + sort.Sort(offsetSort(es)) + for i := range es { + es[i].index = i + 1 + } + sort.Sort(genidxSort(es)) + i := len(*ct) + n, err := ct.genStates(es) + if err != nil { + *ct = (*ct)[:i] + return ctHandle{}, err + } + return ctHandle{i, n}, nil +} + +// genStates generates ctEntries for a given suffix set and returns +// the number of entries for the first node. +func (ct *contractTrieSet) genStates(sis []stridx) (int, error) { + if len(sis) == 0 { + return 0, fmt.Errorf("genStates: list of suffices must be non-empty") + } + start := len(*ct) + // create entries for differing first bytes. + for _, si := range sis { + s := si.str + if len(s) == 0 { + continue + } + added := false + c := s[0] + if len(s) > 1 { + for j := len(*ct) - 1; j >= start; j-- { + if (*ct)[j].l == c { + added = true + break + } + } + if !added { + *ct = append(*ct, ctEntry{l: c, i: noIndex}) + } + } else { + for j := len(*ct) - 1; j >= start; j-- { + // Update the offset for longer suffixes with the same byte. + if (*ct)[j].l == c { + (*ct)[j].i = uint8(si.index) + added = true + } + // Extend range of final ctEntry, if possible. + if (*ct)[j].h+1 == c { + (*ct)[j].h = c + added = true + } + } + if !added { + *ct = append(*ct, ctEntry{l: c, h: c, n: final, i: uint8(si.index)}) + } + } + } + n := len(*ct) - start + // Append nodes for the remainder of the suffixes for each ctEntry. + sp := 0 + for i, end := start, len(*ct); i < end; i++ { + fe := (*ct)[i] + if fe.h == 0 { // uninitialized non-final + ln := len(*ct) - start - n + if ln > 0xFF { + return 0, fmt.Errorf("genStates: relative block offset too large: %d > 255", ln) + } + fe.h = uint8(ln) + // Find first non-final strings with same byte as current entry. + for ; sis[sp].str[0] != fe.l; sp++ { + } + se := sp + 1 + for ; se < len(sis) && len(sis[se].str) > 1 && sis[se].str[0] == fe.l; se++ { + } + sl := sis[sp:se] + sp = se + for i, si := range sl { + sl[i].str = si.str[1:] + } + nn, err := ct.genStates(sl) + if err != nil { + return 0, err + } + fe.n = uint8(nn) + (*ct)[i] = fe + } + } + sort.Sort(entrySort((*ct)[start : start+n])) + return n, nil +} + +// There may be both a final and non-final entry for a byte if the byte +// is implied in a range of matches in the final entry. +// We need to ensure that the non-final entry comes first in that case. +type entrySort contractTrieSet + +func (fe entrySort) Len() int { return len(fe) } +func (fe entrySort) Swap(i, j int) { fe[i], fe[j] = fe[j], fe[i] } +func (fe entrySort) Less(i, j int) bool { + return fe[i].l > fe[j].l +} + +// stridx is used for sorting suffixes and their associated offsets. +type stridx struct { + str string + index int +} + +// For computing the offsets, we first sort by size, and then by string. +// This ensures that strings that only differ in the last byte by 1 +// are sorted consecutively in increasing order such that they can +// be packed as a range in a final ctEntry. +type offsetSort []stridx + +func (si offsetSort) Len() int { return len(si) } +func (si offsetSort) Swap(i, j int) { si[i], si[j] = si[j], si[i] } +func (si offsetSort) Less(i, j int) bool { + if len(si[i].str) != len(si[j].str) { + return len(si[i].str) > len(si[j].str) + } + return si[i].str < si[j].str +} + +// For indexing, we want to ensure that strings are sorted in string order, where +// for strings with the same prefix, we put longer strings before shorter ones. +type genidxSort []stridx + +func (si genidxSort) Len() int { return len(si) } +func (si genidxSort) Swap(i, j int) { si[i], si[j] = si[j], si[i] } +func (si genidxSort) Less(i, j int) bool { + if strings.HasPrefix(si[j].str, si[i].str) { + return false + } + if strings.HasPrefix(si[i].str, si[j].str) { + return true + } + return si[i].str < si[j].str +} + +// lookup matches the longest suffix in str and returns the associated offset +// and the number of bytes consumed. +func (ct *contractTrieSet) lookup(h ctHandle, str []byte) (index, ns int) { + states := (*ct)[h.index:] + p := 0 + n := h.n + for i := 0; i < n && p < len(str); { + e := states[i] + c := str[p] + if c >= e.l { + if e.l == c { + p++ + if e.i != noIndex { + index, ns = int(e.i), p + } + if e.n != final { + // set to new state + i, states, n = 0, states[int(e.h)+n:], int(e.n) + } else { + return + } + continue + } else if e.n == final && c <= e.h { + p++ + return int(c-e.l) + int(e.i), p + } + } + i++ + } + return +} + +// print writes the contractTrieSet t as compilable Go code to w. It returns +// the total number of bytes written and the size of the resulting data structure in bytes. +func (t *contractTrieSet) print(w io.Writer, name string) (n, size int, err error) { + update3 := func(nn, sz int, e error) { + n += nn + if err == nil { + err = e + } + size += sz + } + update2 := func(nn int, e error) { update3(nn, 0, e) } + + update3(t.printArray(w, name)) + update2(fmt.Fprintf(w, "var %sContractTrieSet = ", name)) + update3(t.printStruct(w, name)) + update2(fmt.Fprintln(w)) + return +} + +func (ct contractTrieSet) printArray(w io.Writer, name string) (n, size int, err error) { + p := func(f string, a ...interface{}) { + nn, e := fmt.Fprintf(w, f, a...) + n += nn + if err == nil { + err = e + } + } + size = len(ct) * 4 + p("// %sCTEntries: %d entries, %d bytes\n", name, len(ct), size) + p("var %sCTEntries = [%d]struct{l,h,n,i uint8}{\n", name, len(ct)) + for _, fe := range ct { + p("\t{0x%X, 0x%X, %d, %d},\n", fe.l, fe.h, fe.n, fe.i) + } + p("}\n") + return +} + +func (ct contractTrieSet) printStruct(w io.Writer, name string) (n, size int, err error) { + n, err = fmt.Fprintf(w, "contractTrieSet( %sCTEntries[:] )", name) + size = int(reflect.TypeOf(ct).Size()) + return +} diff --git a/libgo/go/exp/locale/collate/build/contract_test.go b/libgo/go/exp/locale/collate/build/contract_test.go new file mode 100644 index 0000000..0fc944d --- /dev/null +++ b/libgo/go/exp/locale/collate/build/contract_test.go @@ -0,0 +1,264 @@ +// Copyright 2012 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 build + +import ( + "bytes" + "sort" + "testing" +) + +var largetosmall = []stridx{ + {"a", 5}, + {"ab", 4}, + {"abc", 3}, + {"abcd", 2}, + {"abcde", 1}, + {"abcdef", 0}, +} + +var offsetSortTests = [][]stridx{ + { + {"bcde", 1}, + {"bc", 5}, + {"ab", 4}, + {"bcd", 3}, + {"abcd", 0}, + {"abc", 2}, + }, + largetosmall, +} + +func TestOffsetSort(t *testing.T) { + for i, st := range offsetSortTests { + sort.Sort(offsetSort(st)) + for j, si := range st { + if j != si.index { + t.Errorf("%d: failed: %v", i, st) + } + } + } + for i, tt := range genStateTests { + // ensure input is well-formed + sort.Sort(offsetSort(tt.in)) + for j, si := range tt.in { + if si.index != j+1 { + t.Errorf("%dth sort failed: %v", i, tt.in) + } + } + } +} + +var genidxtest1 = []stridx{ + {"bcde", 3}, + {"bc", 6}, + {"ab", 2}, + {"bcd", 5}, + {"abcd", 0}, + {"abc", 1}, + {"bcdf", 4}, +} + +var genidxSortTests = [][]stridx{ + genidxtest1, + largetosmall, +} + +func TestGenIdxSort(t *testing.T) { + for i, st := range genidxSortTests { + sort.Sort(genidxSort(st)) + for j, si := range st { + if j != si.index { + t.Errorf("%dth sort failed %v", i, st) + break + } + } + } +} + +var entrySortTests = []contractTrieSet{ + { + {10, 0, 1, 3}, + {99, 0, 1, 0}, + {20, 50, 0, 2}, + {30, 0, 1, 1}, + }, +} + +func TestEntrySort(t *testing.T) { + for i, et := range entrySortTests { + sort.Sort(entrySort(et)) + for j, fe := range et { + if j != int(fe.i) { + t.Errorf("%dth sort failed %v", i, et) + break + } + } + } +} + +type GenStateTest struct { + in []stridx + firstBlockLen int + out contractTrieSet +} + +var genStateTests = []GenStateTest{ + {[]stridx{ + {"abc", 1}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, noIndex}, + {'b', 0, 1, noIndex}, + {'c', 'c', final, 1}, + }, + }, + {[]stridx{ + {"abc", 1}, + {"abd", 2}, + {"abe", 3}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, noIndex}, + {'b', 0, 1, noIndex}, + {'c', 'e', final, 1}, + }, + }, + {[]stridx{ + {"abc", 1}, + {"ab", 2}, + {"a", 3}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, 3}, + {'b', 0, 1, 2}, + {'c', 'c', final, 1}, + }, + }, + {[]stridx{ + {"abc", 1}, + {"abd", 2}, + {"ab", 3}, + {"ac", 4}, + {"a", 5}, + {"b", 6}, + }, + 2, + contractTrieSet{ + {'b', 'b', final, 6}, + {'a', 0, 2, 5}, + {'c', 'c', final, 4}, + {'b', 0, 1, 3}, + {'c', 'd', final, 1}, + }, + }, + {[]stridx{ + {"bcde", 2}, + {"bc", 7}, + {"ab", 6}, + {"bcd", 5}, + {"abcd", 1}, + {"abc", 4}, + {"bcdf", 3}, + }, + 2, + contractTrieSet{ + {'b', 3, 1, noIndex}, + {'a', 0, 1, noIndex}, + {'b', 0, 1, 6}, + {'c', 0, 1, 4}, + {'d', 'd', final, 1}, + {'c', 0, 1, 7}, + {'d', 0, 1, 5}, + {'e', 'f', final, 2}, + }, + }, +} + +func TestGenStates(t *testing.T) { + for i, tt := range genStateTests { + si := []stridx{} + for _, e := range tt.in { + si = append(si, e) + } + // ensure input is well-formed + sort.Sort(genidxSort(si)) + ct := contractTrieSet{} + n, _ := ct.genStates(si) + if nn := tt.firstBlockLen; nn != n { + t.Errorf("%d: block len %v; want %v", i, n, nn) + } + if lv, lw := len(ct), len(tt.out); lv != lw { + t.Errorf("%d: len %v; want %v", i, lv, lw) + continue + } + for j, fe := range tt.out { + const msg = "%d:%d: value %s=%v; want %v" + if fe.l != ct[j].l { + t.Errorf(msg, i, j, "l", ct[j].l, fe.l) + } + if fe.h != ct[j].h { + t.Errorf(msg, i, j, "h", ct[j].h, fe.h) + } + if fe.n != ct[j].n { + t.Errorf(msg, i, j, "n", ct[j].n, fe.n) + } + if fe.i != ct[j].i { + t.Errorf(msg, i, j, "i", ct[j].i, fe.i) + } + } + } +} + +func TestLookupContraction(t *testing.T) { + for i, tt := range genStateTests { + input := []string{} + for _, e := range tt.in { + input = append(input, e.str) + } + cts := contractTrieSet{} + h, _ := cts.appendTrie(input) + for j, si := range tt.in { + str := si.str + for _, s := range []string{str, str + "X"} { + msg := "%d:%d: %s(%s) %v; want %v" + idx, sn := cts.lookup(h, []byte(s)) + if idx != si.index { + t.Errorf(msg, i, j, "index", s, idx, si.index) + } + if sn != len(str) { + t.Errorf(msg, i, j, "sn", s, sn, len(str)) + } + } + } + } +} + +func TestPrintContractionTrieSet(t *testing.T) { + testdata := contractTrieSet(genStateTests[4].out) + buf := &bytes.Buffer{} + testdata.print(buf, "test") + if contractTrieOutput != buf.String() { + t.Errorf("output differs; found\n%s", buf.String()) + println(string(buf.Bytes())) + } +} + +const contractTrieOutput = `// testCTEntries: 8 entries, 32 bytes +var testCTEntries = [8]struct{l,h,n,i uint8}{ + {0x62, 0x3, 1, 255}, + {0x61, 0x0, 1, 255}, + {0x62, 0x0, 1, 6}, + {0x63, 0x0, 1, 4}, + {0x64, 0x64, 0, 1}, + {0x63, 0x0, 1, 7}, + {0x64, 0x0, 1, 5}, + {0x65, 0x66, 0, 2}, +} +var testContractTrieSet = contractTrieSet( testCTEntries[:] ) +` diff --git a/libgo/go/exp/locale/collate/build/order.go b/libgo/go/exp/locale/collate/build/order.go new file mode 100644 index 0000000..7c550d5 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/order.go @@ -0,0 +1,309 @@ +// Copyright 2012 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 build + +import ( + "exp/locale/collate" + "fmt" + "log" + "sort" + "strings" + "unicode" +) + +type logicalAnchor int + +const ( + firstAnchor logicalAnchor = -1 + noAnchor = 0 + lastAnchor = 1 +) + +// entry is used to keep track of a single entry in the collation element table +// during building. Examples of entries can be found in the Default Unicode +// Collation Element Table. +// See http://www.unicode.org/Public/UCA/6.0.0/allkeys.txt. +type entry struct { + runes []rune + elems [][]int // the collation elements for runes + str string // same as string(runes) + + // prev, next, and level are used to keep track of tailorings. + prev, next *entry + level collate.Level // next differs at this level + + decompose bool // can use NFKD decomposition to generate elems + exclude bool // do not include in table + logical logicalAnchor + + expansionIndex int // used to store index into expansion table + contractionHandle ctHandle + contractionIndex int // index into contraction elements +} + +func (e *entry) String() string { + return fmt.Sprintf("%X -> %X (ch:%x; ci:%d, ei:%d)", + e.runes, e.elems, e.contractionHandle, e.contractionIndex, e.expansionIndex) +} + +func (e *entry) skip() bool { + return e.contraction() +} + +func (e *entry) expansion() bool { + return !e.decompose && len(e.elems) > 1 +} + +func (e *entry) contraction() bool { + return len(e.runes) > 1 +} + +func (e *entry) contractionStarter() bool { + return e.contractionHandle.n != 0 +} + +// nextIndexed gets the next entry that needs to be stored in the table. +// It returns the entry and the collation level at which the next entry differs +// from the current entry. +// Entries that can be explicitly derived and logical reset positions are +// examples of entries that will not be indexed. +func (e *entry) nextIndexed() (*entry, collate.Level) { + level := e.level + for e = e.next; e != nil && e.exclude; e = e.next { + if e.level < level { + level = e.level + } + } + return e, level +} + +// remove unlinks entry e from the sorted chain and clears the collation +// elements. e may not be at the front or end of the list. This should always +// be the case, as the front and end of the list are always logical anchors, +// which may not be removed. +func (e *entry) remove() { + if e.logical != noAnchor { + log.Fatalf("may not remove anchor %q", e.str) + } + if e.prev != nil { + e.prev.next = e.next + } + if e.next != nil { + e.next.prev = e.prev + } + e.elems = nil +} + +// insertAfter inserts t after e. +func (e *entry) insertAfter(n *entry) { + if e == n { + panic("e == anchor") + } + if e == nil { + panic("unexpected nil anchor") + } + n.remove() + n.decompose = false // redo decomposition test + + n.next = e.next + n.prev = e + e.next.prev = n + e.next = n +} + +func (e *entry) encodeBase() (ce uint32, err error) { + switch { + case e.expansion(): + ce, err = makeExpandIndex(e.expansionIndex) + default: + if e.decompose { + log.Fatal("decompose should be handled elsewhere") + } + ce, err = makeCE(e.elems[0]) + } + return +} + +func (e *entry) encode() (ce uint32, err error) { + if e.skip() { + log.Fatal("cannot build colElem for entry that should be skipped") + } + switch { + case e.decompose: + t1 := e.elems[0][2] + t2 := 0 + if len(e.elems) > 1 { + t2 = e.elems[1][2] + } + ce, err = makeDecompose(t1, t2) + case e.contractionStarter(): + ce, err = makeContractIndex(e.contractionHandle, e.contractionIndex) + default: + if len(e.runes) > 1 { + log.Fatal("colElem: contractions are handled in contraction trie") + } + ce, err = e.encodeBase() + } + return +} + +// entryLess returns true if a sorts before b and false otherwise. +func entryLess(a, b *entry) bool { + if res, _ := compareWeights(a.elems, b.elems); res != 0 { + return res == -1 + } + if a.logical != noAnchor { + return a.logical == firstAnchor + } + if b.logical != noAnchor { + return b.logical == lastAnchor + } + return a.str < b.str +} + +type sortedEntries []*entry + +func (s sortedEntries) Len() int { + return len(s) +} + +func (s sortedEntries) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s sortedEntries) Less(i, j int) bool { + return entryLess(s[i], s[j]) +} + +type ordering struct { + entryMap map[string]*entry + ordered []*entry + handle *trieHandle +} + +// insert inserts e into both entryMap and ordered. +// Note that insert simply appends e to ordered. To reattain a sorted +// order, o.sort() should be called. +func (o *ordering) insert(e *entry) { + o.entryMap[e.str] = e + o.ordered = append(o.ordered, e) +} + +// newEntry creates a new entry for the given info and inserts it into +// the index. +func (o *ordering) newEntry(s string, ces [][]int) *entry { + e := &entry{ + runes: []rune(s), + elems: ces, + str: s, + } + o.insert(e) + return e +} + +// find looks up and returns the entry for the given string. +// It returns nil if str is not in the index and if an implicit value +// cannot be derived, that is, if str represents more than one rune. +func (o *ordering) find(str string) *entry { + e := o.entryMap[str] + if e == nil { + r := []rune(str) + if len(r) == 1 { + e = o.newEntry(string(r[0]), [][]int{ + { + implicitPrimary(r[0]), + defaultSecondary, + defaultTertiary, + int(r[0]), + }, + }) + e.exclude = true // do not index implicits + } + } + return e +} + +// makeRootOrdering returns a newly initialized ordering value and populates +// it with a set of logical reset points that can be used as anchors. +// The anchors first_tertiary_ignorable and __END__ will always sort at +// the beginning and end, respectively. This means that prev and next are non-nil +// for any indexed entry. +func makeRootOrdering() ordering { + const max = unicode.MaxRune + o := ordering{ + entryMap: make(map[string]*entry), + } + insert := func(typ logicalAnchor, s string, ce []int) { + // Use key format as used in UCA rules. + e := o.newEntry(fmt.Sprintf("[%s]", s), [][]int{ce}) + // Also add index entry for XML format. + o.entryMap[fmt.Sprintf("<%s/>", strings.Replace(s, " ", "_", -1))] = e + e.runes = nil + e.exclude = true + e.logical = typ + } + insert(firstAnchor, "first tertiary ignorable", []int{0, 0, 0, 0}) + insert(lastAnchor, "last tertiary ignorable", []int{0, 0, 0, max}) + insert(lastAnchor, "last primary ignorable", []int{0, defaultSecondary, defaultTertiary, max}) + insert(lastAnchor, "last non ignorable", []int{maxPrimary, defaultSecondary, defaultTertiary, max}) + insert(lastAnchor, "__END__", []int{1 << maxPrimaryBits, defaultSecondary, defaultTertiary, max}) + return o +} + +// clone copies all ordering of es into a new ordering value. +func (o *ordering) clone() *ordering { + o.sort() + oo := ordering{ + entryMap: make(map[string]*entry), + } + for _, e := range o.ordered { + ne := &entry{ + runes: e.runes, + elems: e.elems, + str: e.str, + decompose: e.decompose, + exclude: e.exclude, + logical: e.logical, + } + oo.insert(ne) + } + oo.sort() // link all ordering. + return &oo +} + +// front returns the first entry to be indexed. +// It assumes that sort() has been called. +func (o *ordering) front() *entry { + e := o.ordered[0] + if e.prev != nil { + log.Panicf("unexpected first entry: %v", e) + } + // The first entry is always a logical position, which should not be indexed. + e, _ = e.nextIndexed() + return e +} + +// sort sorts all ordering based on their collation elements and initializes +// the prev, next, and level fields accordingly. +func (o *ordering) sort() { + sort.Sort(sortedEntries(o.ordered)) + l := o.ordered + for i := 1; i < len(l); i++ { + k := i - 1 + l[k].next = l[i] + _, l[k].level = compareWeights(l[k].elems, l[i].elems) + l[i].prev = l[k] + } +} + +// genColElems generates a collation element array from the runes in str. This +// assumes that all collation elements have already been added to the Builder. +func (o *ordering) genColElems(str string) [][]int { + elems := [][]int{} + for _, r := range []rune(str) { + elems = append(elems, o.find(string(r)).elems...) + } + return elems +} diff --git a/libgo/go/exp/locale/collate/build/order_test.go b/libgo/go/exp/locale/collate/build/order_test.go new file mode 100644 index 0000000..e6fdfa3 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/order_test.go @@ -0,0 +1,197 @@ +// Copyright 2012 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 build + +import ( + "exp/locale/collate" + "strconv" + "testing" +) + +type entryTest struct { + f func(in []int) (uint32, error) + arg []int + val uint32 +} + +// makeList returns a list of entries of length n+2, with n normal +// entries plus a leading and trailing anchor. +func makeList(n int) []*entry { + es := make([]*entry, n+2) + weights := [][]int{{100, 20, 5, 0}} + for i := range es { + runes := []rune{rune(i)} + es[i] = &entry{ + runes: runes, + elems: weights, + } + weights = nextWeight(collate.Primary, weights) + } + for i := 1; i < len(es); i++ { + es[i-1].next = es[i] + es[i].prev = es[i-1] + _, es[i-1].level = compareWeights(es[i-1].elems, es[i].elems) + } + es[0].exclude = true + es[0].logical = firstAnchor + es[len(es)-1].exclude = true + es[len(es)-1].logical = lastAnchor + return es +} + +func TestNextIndexed(t *testing.T) { + const n = 5 + es := makeList(n) + for i := int64(0); i < 1<<n; i++ { + mask := strconv.FormatInt(i+(1<<n), 2) + for i, c := range mask { + es[i].exclude = c == '1' + } + e := es[0] + for i, c := range mask { + if c == '0' { + e, _ = e.nextIndexed() + if e != es[i] { + t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems) + } + } + } + if e, _ = e.nextIndexed(); e != nil { + t.Errorf("%d: expected nil entry; found %d", i, e.elems) + } + } +} + +func TestRemove(t *testing.T) { + const n = 5 + for i := int64(0); i < 1<<n; i++ { + es := makeList(n) + mask := strconv.FormatInt(i+(1<<n), 2) + for i, c := range mask { + if c == '0' { + es[i].remove() + } + } + e := es[0] + for i, c := range mask { + if c == '1' { + if e != es[i] { + t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems) + } + e, _ = e.nextIndexed() + } + } + if e != nil { + t.Errorf("%d: expected nil entry; found %d", i, e.elems) + } + } +} + +// nextPerm generates the next permutation of the array. The starting +// permutation is assumed to be a list of integers sorted in increasing order. +// It returns false if there are no more permuations left. +func nextPerm(a []int) bool { + i := len(a) - 2 + for ; i >= 0; i-- { + if a[i] < a[i+1] { + break + } + } + if i < 0 { + return false + } + for j := len(a) - 1; j >= i; j-- { + if a[j] > a[i] { + a[i], a[j] = a[j], a[i] + break + } + } + for j := i + 1; j < (len(a)+i+1)/2; j++ { + a[j], a[len(a)+i-j] = a[len(a)+i-j], a[j] + } + return true +} + +func TestInsertAfter(t *testing.T) { + const n = 5 + orig := makeList(n) + perm := make([]int, n) + for i := range perm { + perm[i] = i + 1 + } + for ok := true; ok; ok = nextPerm(perm) { + es := makeList(n) + last := es[0] + for _, i := range perm { + last.insertAfter(es[i]) + last = es[i] + } + e := es[0] + for _, i := range perm { + e, _ = e.nextIndexed() + if e.runes[0] != orig[i].runes[0] { + t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes, e.runes) + break + } + } + } +} + +type entryLessTest struct { + a, b *entry + res bool +} + +var ( + w1 = [][]int{{100, 20, 5, 5}} + w2 = [][]int{{101, 20, 5, 5}} +) + +var entryLessTests = []entryLessTest{ + {&entry{str: "a", elems: w1}, + &entry{str: "a", elems: w1}, + false, + }, + {&entry{str: "a", elems: w1}, + &entry{str: "a", elems: w2}, + true, + }, + {&entry{str: "a", elems: w1}, + &entry{str: "b", elems: w1}, + true, + }, + {&entry{str: "a", elems: w2}, + &entry{str: "a", elems: w1}, + false, + }, + {&entry{str: "c", elems: w1}, + &entry{str: "b", elems: w1}, + false, + }, + {&entry{str: "a", elems: w1, logical: firstAnchor}, + &entry{str: "a", elems: w1}, + true, + }, + {&entry{str: "a", elems: w1}, + &entry{str: "b", elems: w1, logical: firstAnchor}, + false, + }, + {&entry{str: "b", elems: w1}, + &entry{str: "a", elems: w1, logical: lastAnchor}, + true, + }, + {&entry{str: "a", elems: w1, logical: lastAnchor}, + &entry{str: "c", elems: w1}, + false, + }, +} + +func TestEntryLess(t *testing.T) { + for i, tt := range entryLessTests { + if res := entryLess(tt.a, tt.b); res != tt.res { + t.Errorf("%d: was %v; want %v", i, res, tt.res) + } + } +} diff --git a/libgo/go/exp/locale/collate/build/table.go b/libgo/go/exp/locale/collate/build/table.go new file mode 100644 index 0000000..0a290cd --- /dev/null +++ b/libgo/go/exp/locale/collate/build/table.go @@ -0,0 +1,136 @@ +// Copyright 2012 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 build + +import ( + "fmt" + "io" + "reflect" +) + +// table is an intermediate structure that roughly resembles the table in collate. +// It implements the non-exported interface collate.tableInitializer +type table struct { + index trie // main trie + root *trieHandle + + // expansion info + expandElem []uint32 + + // contraction info + contractTries contractTrieSet + contractElem []uint32 + maxContractLen int + variableTop uint32 +} + +func (t *table) TrieIndex() []uint16 { + return t.index.index +} + +func (t *table) TrieValues() []uint32 { + return t.index.values +} + +func (t *table) FirstBlockOffsets() (i, v uint16) { + return t.root.lookupStart, t.root.valueStart +} + +func (t *table) ExpandElems() []uint32 { + return t.expandElem +} + +func (t *table) ContractTries() []struct{ l, h, n, i uint8 } { + return t.contractTries +} + +func (t *table) ContractElems() []uint32 { + return t.contractElem +} + +func (t *table) MaxContractLen() int { + return t.maxContractLen +} + +func (t *table) VariableTop() uint32 { + return t.variableTop +} + +// print writes the table as Go compilable code to w. It prefixes the +// variable names with name. It returns the number of bytes written +// and the size of the resulting table. +func (t *table) fprint(w io.Writer, name string) (n, size int, err error) { + update := func(nn, sz int, e error) { + n += nn + if err == nil { + err = e + } + size += sz + } + p := func(f string, a ...interface{}) { + nn, e := fmt.Fprintf(w, f, a...) + update(nn, 0, e) + } + // Write main table. + size += int(reflect.TypeOf(*t).Size()) + p("var %sTable = table{\n", name) + update(t.index.printStruct(w, t.root, name)) + p(",\n") + p("%sExpandElem[:],\n", name) + update(t.contractTries.printStruct(w, name)) + p(",\n") + p("%sContractElem[:],\n", name) + p("%d,\n", t.maxContractLen) + p("0x%X,\n", t.variableTop) + p("}\n\n") + + // Write arrays needed for the structure. + update(printColElems(w, t.expandElem, name+"ExpandElem")) + update(printColElems(w, t.contractElem, name+"ContractElem")) + update(t.index.printArrays(w, name)) + update(t.contractTries.printArray(w, name)) + + p("// Total size of %sTable is %d bytes\n", name, size) + return +} + +func (t *table) fprintIndex(w io.Writer, h *trieHandle) (n int, err error) { + p := func(f string, a ...interface{}) { + nn, e := fmt.Fprintf(w, f, a...) + n += nn + if err == nil { + err = e + } + } + p("tableIndex{\n") + p("\t\tlookupOffset: 0x%x,\n", h.lookupStart) + p("\t\tvaluesOffset: 0x%x,\n", h.valueStart) + p("\t}") + return +} + +func printColElems(w io.Writer, a []uint32, name string) (n, sz int, err error) { + p := func(f string, a ...interface{}) { + nn, e := fmt.Fprintf(w, f, a...) + n += nn + if err == nil { + err = e + } + } + sz = len(a) * int(reflect.TypeOf(uint32(0)).Size()) + p("// %s: %d entries, %d bytes\n", name, len(a), sz) + p("var %s = [%d]uint32 {", name, len(a)) + for i, c := range a { + switch { + case i%64 == 0: + p("\n\t// Block %d, offset 0x%x\n", i/64, i) + case (i%64)%6 == 0: + p("\n\t") + } + p("0x%.8X, ", c) + } + p("\n}\n\n") + return +} diff --git a/libgo/go/exp/locale/collate/build/trie.go b/libgo/go/exp/locale/collate/build/trie.go new file mode 100644 index 0000000..d251a39 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/trie.go @@ -0,0 +1,281 @@ +// Copyright 2012 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. + +// The trie in this file is used to associate the first full character +// in a UTF-8 string to a collation element. +// All but the last byte in a UTF-8 byte sequence are +// used to look up offsets in the index table to be used for the next byte. +// The last byte is used to index into a table of collation elements. +// This file contains the code for the generation of the trie. + +package build + +import ( + "fmt" + "hash/fnv" + "io" + "reflect" +) + +const ( + blockSize = 64 + blockOffset = 2 // Substract 2 blocks to compensate for the 0x80 added to continuation bytes. +) + +type trieHandle struct { + lookupStart uint16 // offset in table for first byte + valueStart uint16 // offset in table for first byte +} + +type trie struct { + index []uint16 + values []uint32 +} + +// trieNode is the intermediate trie structure used for generating a trie. +type trieNode struct { + index []*trieNode + value []uint32 + b byte + ref uint16 +} + +func newNode() *trieNode { + return &trieNode{ + index: make([]*trieNode, 64), + value: make([]uint32, 128), // root node size is 128 instead of 64 + } +} + +func (n *trieNode) isInternal() bool { + return n.value != nil +} + +func (n *trieNode) insert(r rune, value uint32) { + const maskx = 0x3F // mask out two most-significant bits + str := string(r) + if len(str) == 1 { + n.value[str[0]] = value + return + } + for i := 0; i < len(str)-1; i++ { + b := str[i] & maskx + if n.index == nil { + n.index = make([]*trieNode, blockSize) + } + nn := n.index[b] + if nn == nil { + nn = &trieNode{} + nn.b = b + n.index[b] = nn + } + n = nn + } + if n.value == nil { + n.value = make([]uint32, blockSize) + } + b := str[len(str)-1] & maskx + n.value[b] = value +} + +type trieBuilder struct { + t *trie + + roots []*trieHandle + + lookupBlocks []*trieNode + valueBlocks []*trieNode + + lookupBlockIdx map[uint32]*trieNode + valueBlockIdx map[uint32]*trieNode +} + +func newTrieBuilder() *trieBuilder { + index := &trieBuilder{} + index.lookupBlocks = make([]*trieNode, 0) + index.valueBlocks = make([]*trieNode, 0) + index.lookupBlockIdx = make(map[uint32]*trieNode) + index.valueBlockIdx = make(map[uint32]*trieNode) + // The third nil is the default null block. The other two blocks + // are used to guarantee an offset of at least 3 for each block. + index.lookupBlocks = append(index.lookupBlocks, nil, nil, nil) + index.t = &trie{} + return index +} + +func (b *trieBuilder) computeOffsets(n *trieNode) *trieNode { + hasher := fnv.New32() + if n.index != nil { + for i, nn := range n.index { + v := uint16(0) + if nn != nil { + nn = b.computeOffsets(nn) + n.index[i] = nn + v = nn.ref + } + hasher.Write([]byte{byte(v >> 8), byte(v)}) + } + h := hasher.Sum32() + nn, ok := b.lookupBlockIdx[h] + if !ok { + n.ref = uint16(len(b.lookupBlocks)) - blockOffset + b.lookupBlocks = append(b.lookupBlocks, n) + b.lookupBlockIdx[h] = n + } else { + n = nn + } + } else { + for _, v := range n.value { + hasher.Write([]byte{byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)}) + } + h := hasher.Sum32() + nn, ok := b.valueBlockIdx[h] + if !ok { + n.ref = uint16(len(b.valueBlocks)) - blockOffset + b.valueBlocks = append(b.valueBlocks, n) + b.valueBlockIdx[h] = n + } else { + n = nn + } + } + return n +} + +func (b *trieBuilder) addStartValueBlock(n *trieNode) uint16 { + hasher := fnv.New32() + for _, v := range n.value[:2*blockSize] { + hasher.Write([]byte{byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)}) + } + h := hasher.Sum32() + nn, ok := b.valueBlockIdx[h] + if !ok { + n.ref = uint16(len(b.valueBlocks)) + b.valueBlocks = append(b.valueBlocks, n) + // Add a dummy block to accommodate the double block size. + b.valueBlocks = append(b.valueBlocks, nil) + b.valueBlockIdx[h] = n + } else { + n = nn + } + return n.ref +} + +func genValueBlock(t *trie, n *trieNode) { + if n != nil { + for _, v := range n.value { + t.values = append(t.values, v) + } + } +} + +func genLookupBlock(t *trie, n *trieNode) { + for _, nn := range n.index { + v := uint16(0) + if nn != nil { + v = nn.ref + } + t.index = append(t.index, v) + } +} + +func (b *trieBuilder) addTrie(n *trieNode) *trieHandle { + h := &trieHandle{} + b.roots = append(b.roots, h) + h.valueStart = b.addStartValueBlock(n) + if len(b.roots) == 1 { + // We insert a null block after the first start value block. + // This ensures that continuation bytes UTF-8 sequences of length + // greater than 2 will automatically hit a null block if there + // was an undefined entry. + b.valueBlocks = append(b.valueBlocks, nil) + } + n = b.computeOffsets(n) + // Offset by one extra block as the first byte starts at 0xC0 instead of 0x80. + h.lookupStart = n.ref - 1 + return h +} + +// generate generates and returns the trie for n. +func (b *trieBuilder) generate() (t *trie, err error) { + t = b.t + if len(b.valueBlocks) >= 1<<16 { + return nil, fmt.Errorf("maximum number of value blocks exceeded (%d > %d)", len(b.valueBlocks), 1<<16) + } + if len(b.lookupBlocks) >= 1<<16 { + return nil, fmt.Errorf("maximum number of lookup blocks exceeded (%d > %d)", len(b.lookupBlocks), 1<<16) + } + genValueBlock(t, b.valueBlocks[0]) + genValueBlock(t, &trieNode{value: make([]uint32, 64)}) + for i := 2; i < len(b.valueBlocks); i++ { + genValueBlock(t, b.valueBlocks[i]) + } + n := &trieNode{index: make([]*trieNode, 64)} + genLookupBlock(t, n) + genLookupBlock(t, n) + genLookupBlock(t, n) + for i := 3; i < len(b.lookupBlocks); i++ { + genLookupBlock(t, b.lookupBlocks[i]) + } + return b.t, nil +} + +func (t *trie) printArrays(w io.Writer, name string) (n, size int, err error) { + p := func(f string, a ...interface{}) { + nn, e := fmt.Fprintf(w, f, a...) + n += nn + if err == nil { + err = e + } + } + nv := len(t.values) + p("// %sValues: %d entries, %d bytes\n", name, nv, nv*4) + p("// Block 2 is the null block.\n") + p("var %sValues = [%d]uint32 {", name, nv) + var printnewline bool + for i, v := range t.values { + if i%blockSize == 0 { + p("\n\t// Block %#x, offset %#x", i/blockSize, i) + } + if i%4 == 0 { + printnewline = true + } + if v != 0 { + if printnewline { + p("\n\t") + printnewline = false + } + p("%#04x:%#08x, ", i, v) + } + } + p("\n}\n\n") + ni := len(t.index) + p("// %sLookup: %d entries, %d bytes\n", name, ni, ni*2) + p("// Block 0 is the null block.\n") + p("var %sLookup = [%d]uint16 {", name, ni) + printnewline = false + for i, v := range t.index { + if i%blockSize == 0 { + p("\n\t// Block %#x, offset %#x", i/blockSize, i) + } + if i%8 == 0 { + printnewline = true + } + if v != 0 { + if printnewline { + p("\n\t") + printnewline = false + } + p("%#03x:%#02x, ", i, v) + } + } + p("\n}\n\n") + return n, nv*4 + ni*2, err +} + +func (t *trie) printStruct(w io.Writer, handle *trieHandle, name string) (n, sz int, err error) { + const msg = "trie{ %sLookup[%d:], %sValues[%d:], %sLookup[:], %sValues[:]}" + n, err = fmt.Fprintf(w, msg, name, handle.lookupStart*blockSize, name, handle.valueStart*blockSize, name, name) + sz += int(reflect.TypeOf(trie{}).Size()) + return +} diff --git a/libgo/go/exp/locale/collate/build/trie_test.go b/libgo/go/exp/locale/collate/build/trie_test.go new file mode 100644 index 0000000..11da566 --- /dev/null +++ b/libgo/go/exp/locale/collate/build/trie_test.go @@ -0,0 +1,107 @@ +// Copyright 2012 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 build + +import ( + "bytes" + "fmt" + "testing" +) + +// We take the smallest, largest and an arbitrary value for each +// of the UTF-8 sequence lengths. +var testRunes = []rune{ + 0x01, 0x0C, 0x7F, // 1-byte sequences + 0x80, 0x100, 0x7FF, // 2-byte sequences + 0x800, 0x999, 0xFFFF, // 3-byte sequences + 0x10000, 0x10101, 0x10FFFF, // 4-byte sequences + 0x200, 0x201, 0x202, 0x210, 0x215, // five entries in one sparse block +} + +func makeTestTrie(t *testing.T) trie { + n := newNode() + for i, r := range testRunes { + n.insert(r, uint32(i)) + } + idx := newTrieBuilder() + idx.addTrie(n) + tr, err := idx.generate() + if err != nil { + t.Errorf(err.Error()) + } + return *tr +} + +func TestGenerateTrie(t *testing.T) { + testdata := makeTestTrie(t) + buf := &bytes.Buffer{} + testdata.printArrays(buf, "test") + fmt.Fprintf(buf, "var testTrie = ") + testdata.printStruct(buf, &trieHandle{19, 0}, "test") + if output != buf.String() { + t.Error("output differs") + } +} + +var output = `// testValues: 832 entries, 3328 bytes +// Block 2 is the null block. +var testValues = [832]uint32 { + // Block 0x0, offset 0x0 + 0x000c:0x00000001, + // Block 0x1, offset 0x40 + 0x007f:0x00000002, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00c0:0x00000003, + // Block 0x4, offset 0x100 + 0x0100:0x00000004, + // Block 0x5, offset 0x140 + 0x0140:0x0000000c, 0x0141:0x0000000d, 0x0142:0x0000000e, + 0x0150:0x0000000f, + 0x0155:0x00000010, + // Block 0x6, offset 0x180 + 0x01bf:0x00000005, + // Block 0x7, offset 0x1c0 + 0x01c0:0x00000006, + // Block 0x8, offset 0x200 + 0x0219:0x00000007, + // Block 0x9, offset 0x240 + 0x027f:0x00000008, + // Block 0xa, offset 0x280 + 0x0280:0x00000009, + // Block 0xb, offset 0x2c0 + 0x02c1:0x0000000a, + // Block 0xc, offset 0x300 + 0x033f:0x0000000b, +} + +// testLookup: 640 entries, 1280 bytes +// Block 0 is the null block. +var testLookup = [640]uint16 { + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0e0:0x05, 0x0e6:0x06, + // Block 0x4, offset 0x100 + 0x13f:0x07, + // Block 0x5, offset 0x140 + 0x140:0x08, 0x144:0x09, + // Block 0x6, offset 0x180 + 0x190:0x03, + // Block 0x7, offset 0x1c0 + 0x1ff:0x0a, + // Block 0x8, offset 0x200 + 0x20f:0x05, + // Block 0x9, offset 0x240 + 0x242:0x01, 0x244:0x02, + 0x248:0x03, + 0x25f:0x04, + 0x260:0x01, + 0x26f:0x02, + 0x270:0x04, 0x274:0x06, +} + +var testTrie = trie{ testLookup[1216:], testValues[0:], testLookup[:], testValues[:]}` diff --git a/libgo/go/exp/locale/collate/colelem.go b/libgo/go/exp/locale/collate/colelem.go new file mode 100644 index 0000000..4af71f0 --- /dev/null +++ b/libgo/go/exp/locale/collate/colelem.go @@ -0,0 +1,183 @@ +// Copyright 2012 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 collate + +import ( + "unicode" +) + +// weights holds the decoded weights per collation level. +type weights struct { + primary uint32 + secondary uint16 + tertiary uint8 + // TODO: compute quaternary on the fly or compress this value into 8 bits + // such that weights fit within 64bit. + quaternary uint32 +} + +const ( + defaultSecondary = 0x20 + defaultTertiary = 0x2 + maxTertiary = 0x1F + maxQuaternary = 0x1FFFFF // 21 bits. +) + +// colElem is a representation of a collation element. +// In the typical case, a rune maps to a single collation element. If a rune +// can be the start of a contraction or expands into multiple collation elements, +// then the colElem that is associated with a rune will have a special form to represent +// such m to n mappings. Such special colElems have a value >= 0x80000000. +type colElem uint32 + +const ( + maxCE colElem = 0x80FFFFFF + minContract = 0xC0000000 + maxContract = 0xDFFFFFFF + minExpand = 0xE0000000 + maxExpand = 0xEFFFFFFF + minDecomp = 0xF0000000 +) + +type ceType int + +const ( + ceNormal ceType = iota // ceNormal includes implicits (ce == 0) + ceContractionIndex // rune can be a start of a contraction + ceExpansionIndex // rune expands into a sequence of collation elements + ceDecompose // rune expands using NFKC decomposition +) + +func (ce colElem) ctype() ceType { + if ce <= maxCE { + return ceNormal + } + if ce <= maxContract { + return ceContractionIndex + } else { + if ce <= maxExpand { + return ceExpansionIndex + } + return ceDecompose + } + panic("should not reach here") + return ceType(-1) +} + +// For normal collation elements, we assume that a collation element either has +// a primary or non-default secondary value, not both. +// Collation elements with a primary value are of the form +// 010ppppp pppppppp pppppppp ssssssss +// - p* is primary collation value +// - s* is the secondary collation value +// or +// 00pppppp pppppppp ppppppps sssttttt, where +// - p* is primary collation value +// - s* offset of secondary from default value. +// - t* is the tertiary collation value +// Collation elements with a secondary value are of the form +// 10000000 0000ssss ssssssss tttttttt, where +// - 16 BMP implicit -> weight +// - 8 bit s +// - default tertiary +func splitCE(ce colElem) weights { + const primaryMask = 0x40000000 + const secondaryMask = 0x80000000 + w := weights{} + if ce&primaryMask != 0 { + w.tertiary = defaultTertiary + w.secondary = uint16(uint8(ce)) + w.primary = uint32((ce >> 8) & 0x1FFFFF) + } else if ce&secondaryMask == 0 { + w.tertiary = uint8(ce & 0x1F) + ce >>= 5 + w.secondary = defaultSecondary + uint16(ce&0xF) + ce >>= 4 + w.primary = uint32(ce) + } else { + w.tertiary = uint8(ce) + w.secondary = uint16(ce >> 8) + } + return w +} + +// For contractions, collation elements are of the form +// 110bbbbb bbbbbbbb iiiiiiii iiiinnnn, where +// - n* is the size of the first node in the contraction trie. +// - i* is the index of the first node in the contraction trie. +// - b* is the offset into the contraction collation element table. +// See contract.go for details on the contraction trie. +const ( + maxNBits = 4 + maxTrieIndexBits = 12 + maxContractOffsetBits = 13 +) + +func splitContractIndex(ce colElem) (index, n, offset int) { + n = int(ce & (1<<maxNBits - 1)) + ce >>= maxNBits + index = int(ce & (1<<maxTrieIndexBits - 1)) + ce >>= maxTrieIndexBits + offset = int(ce & (1<<maxContractOffsetBits - 1)) + return +} + +// For expansions, colElems are of the form 11100000 00000000 bbbbbbbb bbbbbbbb, +// where b* is the index into the expansion sequence table. +const maxExpandIndexBits = 16 + +func splitExpandIndex(ce colElem) (index int) { + return int(uint16(ce)) +} + +// Some runes can be expanded using NFKD decomposition. Instead of storing the full +// sequence of collation elements, we decompose the rune and lookup the collation +// elements for each rune in the decomposition and modify the tertiary weights. +// The colElem, in this case, is of the form 11110000 00000000 wwwwwwww vvvvvvvv, where +// - v* is the replacement tertiary weight for the first rune, +// - w* is the replacement tertiary weight for the second rune, +// Tertiary weights of subsequent runes should be replaced with maxTertiary. +// See http://www.unicode.org/reports/tr10/#Compatibility_Decompositions for more details. +func splitDecompose(ce colElem) (t1, t2 uint8) { + return uint8(ce), uint8(ce >> 8) +} + +const ( + // These constants were taken from http://www.unicode.org/versions/Unicode6.0.0/ch12.pdf. + minUnified rune = 0x4E00 + maxUnified = 0x9FFF + minCompatibility = 0xF900 + maxCompatibility = 0xFAFF + minRare = 0x3400 + maxRare = 0x4DBF +) +const ( + commonUnifiedOffset = 0x10000 + rareUnifiedOffset = 0x20000 // largest rune in common is U+FAFF + otherOffset = 0x50000 // largest rune in rare is U+2FA1D + illegalOffset = otherOffset + int(unicode.MaxRune) + maxPrimary = illegalOffset + 1 +) + +// implicitPrimary returns the primary weight for the a rune +// for which there is no entry for the rune in the collation table. +// We take a different approach from the one specified in +// http://unicode.org/reports/tr10/#Implicit_Weights, +// but preserve the resulting relative ordering of the runes. +func implicitPrimary(r rune) int { + if unicode.Is(unicode.Ideographic, r) { + if r >= minUnified && r <= maxUnified { + // The most common case for CJK. + return int(r) + commonUnifiedOffset + } + if r >= minCompatibility && r <= maxCompatibility { + // This will typically not hit. The DUCET explicitly specifies mappings + // for all characters that do not decompose. + return int(r) + commonUnifiedOffset + } + return int(r) + rareUnifiedOffset + } + return int(r) + otherOffset +} diff --git a/libgo/go/exp/locale/collate/colelem_test.go b/libgo/go/exp/locale/collate/colelem_test.go new file mode 100644 index 0000000..bcb4ddb --- /dev/null +++ b/libgo/go/exp/locale/collate/colelem_test.go @@ -0,0 +1,169 @@ +// Copyright 2012 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 collate + +import ( + "testing" + "unicode" +) + +type ceTest struct { + f func(inout []int) (colElem, ceType) + arg []int +} + +// The make* funcs are simplified versions of the functions in build/colelem.go +func makeCE(weights []int) colElem { + const ( + maxPrimaryBits = 21 + maxSecondaryBits = 12 + maxSecondaryCompactBits = 8 + maxSecondaryDiffBits = 4 + maxTertiaryBits = 8 + maxTertiaryCompactBits = 5 + isSecondary = 0x80000000 + isPrimary = 0x40000000 + ) + var ce colElem + if weights[0] != 0 { + if weights[2] == defaultTertiary { + ce = colElem(weights[0]<<maxSecondaryCompactBits + weights[1]) + ce |= isPrimary + } else { + d := weights[1] - defaultSecondary + ce = colElem(weights[0]<<maxSecondaryDiffBits + d) + ce = ce<<maxTertiaryCompactBits + colElem(weights[2]) + } + } else { + ce = colElem(weights[1]<<maxTertiaryBits + weights[2]) + ce |= isSecondary + } + return ce +} + +func makeContractIndex(index, n, offset int) colElem { + const ( + contractID = 0xC0000000 + maxNBits = 4 + maxTrieIndexBits = 12 + maxContractOffsetBits = 13 + ) + ce := colElem(contractID) + ce += colElem(offset << (maxNBits + maxTrieIndexBits)) + ce += colElem(index << maxNBits) + ce += colElem(n) + return ce +} + +func makeExpandIndex(index int) colElem { + const expandID = 0xE0000000 + return expandID + colElem(index) +} + +func makeDecompose(t1, t2 int) colElem { + const decompID = 0xF0000000 + return colElem(t2<<8+t1) + decompID +} + +func normalCE(inout []int) (ce colElem, t ceType) { + w := splitCE(makeCE(inout)) + inout[0] = int(w.primary) + inout[1] = int(w.secondary) + inout[2] = int(w.tertiary) + return ce, ceNormal +} + +func expandCE(inout []int) (ce colElem, t ceType) { + ce = makeExpandIndex(inout[0]) + inout[0] = splitExpandIndex(ce) + return ce, ceExpansionIndex +} + +func contractCE(inout []int) (ce colElem, t ceType) { + ce = makeContractIndex(inout[0], inout[1], inout[2]) + i, n, o := splitContractIndex(ce) + inout[0], inout[1], inout[2] = i, n, o + return ce, ceContractionIndex +} + +func decompCE(inout []int) (ce colElem, t ceType) { + ce = makeDecompose(inout[0], inout[1]) + t1, t2 := splitDecompose(ce) + inout[0], inout[1] = int(t1), int(t2) + return ce, ceDecompose +} + +const ( + maxPrimaryBits = 21 + maxSecondaryBits = 16 + maxTertiaryBits = 8 +) + +var ceTests = []ceTest{ + {normalCE, []int{0, 0, 0}}, + {normalCE, []int{0, 30, 3}}, + {normalCE, []int{100, defaultSecondary, 3}}, + + {contractCE, []int{0, 0, 0}}, + {contractCE, []int{1, 1, 1}}, + {contractCE, []int{1, (1 << maxNBits) - 1, 1}}, + {contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}}, + {contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}}, + + {expandCE, []int{0}}, + {expandCE, []int{5}}, + {expandCE, []int{(1 << maxExpandIndexBits) - 1}}, + + {decompCE, []int{0, 0}}, + {decompCE, []int{1, 1}}, + {decompCE, []int{0x1F, 0x1F}}, +} + +func TestColElem(t *testing.T) { + for i, tt := range ceTests { + inout := make([]int, len(tt.arg)) + copy(inout, tt.arg) + ce, typ := tt.f(inout) + if ce.ctype() != typ { + t.Errorf("%d: type is %d; want %d", i, ce.ctype(), typ) + } + for j, a := range tt.arg { + if inout[j] != a { + t.Errorf("%d: argument %d is %X; want %X", i, j, inout[j], a) + } + } + } +} + +type implicitTest struct { + r rune + p int +} + +var implicitTests = []implicitTest{ + {0x33FF, 0x533FF}, + {0x3400, 0x23400}, + {0x4DC0, 0x54DC0}, + {0x4DFF, 0x54DFF}, + {0x4E00, 0x14E00}, + {0x9FCB, 0x19FCB}, + {0xA000, 0x5A000}, + {0xF8FF, 0x5F8FF}, + {0xF900, 0x1F900}, + {0xFA23, 0x1FA23}, + {0xFAD9, 0x1FAD9}, + {0xFB00, 0x5FB00}, + {0x20000, 0x40000}, + {0x2B81C, 0x4B81C}, + {unicode.MaxRune, 0x15FFFF}, // maximum primary value +} + +func TestImplicit(t *testing.T) { + for _, tt := range implicitTests { + if p := implicitPrimary(tt.r); p != tt.p { + t.Errorf("%U: was %X; want %X", tt.r, p, tt.p) + } + } +} diff --git a/libgo/go/exp/locale/collate/collate.go b/libgo/go/exp/locale/collate/collate.go new file mode 100644 index 0000000..5853b71 --- /dev/null +++ b/libgo/go/exp/locale/collate/collate.go @@ -0,0 +1,363 @@ +// Copyright 2012 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 collate contains types for comparing and sorting Unicode strings +// according to a given collation order. Package locale provides a high-level +// interface to collation. Users should typically use that package instead. +package collate + +import ( + "bytes" + "exp/norm" +) + +// Level identifies the collation comparison level. +// The primary level corresponds to the basic sorting of text. +// The secondary level corresponds to accents and related linguistic elements. +// The tertiary level corresponds to casing and related concepts. +// The quaternary level is derived from the other levels by the +// various algorithms for handling variable elements. +type Level int + +const ( + Primary Level = iota + Secondary + Tertiary + Quaternary + Identity +) + +// AlternateHandling identifies the various ways in which variables are handled. +// A rune with a primary weight lower than the variable top is considered a +// variable. +// See http://www.unicode.org/reports/tr10/#Variable_Weighting for details. +type AlternateHandling int + +const ( + // AltNonIgnorable turns off special handling of variables. + AltNonIgnorable AlternateHandling = iota + + // AltBlanked sets variables and all subsequent primary ignorables to be + // ignorable at all levels. This is identical to removing all variables + // and subsequent primary ignorables from the input. + AltBlanked + + // AltShifted sets variables to be ignorable for levels one through three and + // adds a fourth level based on the values of the ignored levels. + AltShifted + + // AltShiftTrimmed is a slight variant of AltShifted that is used to + // emulate POSIX. + AltShiftTrimmed +) + +// Collator provides functionality for comparing strings for a given +// collation order. +type Collator struct { + // Strength sets the maximum level to use in comparison. + Strength Level + + // Alternate specifies an alternative handling of variables. + Alternate AlternateHandling + + // Backwards specifies the order of sorting at the secondary level. + // This option exists predominantly to support reverse sorting of accents in French. + Backwards bool + + // TODO: implement: + // With HiraganaQuaternary enabled, Hiragana codepoints will get lower values + // than all the other non-variable code points. Strength must be greater or + // equal to Quaternary for this to take effect. + HiraganaQuaternary bool + + // If CaseLevel is true, a level consisting only of case characteristics will + // be inserted in front of the tertiary level. To ignore accents but take + // cases into account, set Strength to Primary and CaseLevel to true. + CaseLevel bool + + // If Numeric is true, any sequence of decimal digits (category is Nd) is sorted + // at a primary level with its numeric value. For example, "A-21" < "A-123". + Numeric bool + + f norm.Form + + t *table +} + +// Locales returns the list of locales for which collating differs from its parent locale. +func Locales() []string { + return availableLocales +} + +// New returns a new Collator initialized for the given locale. +func New(loc string) *Collator { + // TODO: handle locale selection according to spec. + t := &mainTable + if loc != "" { + if idx, ok := locales[loc]; ok { + t = mainTable.indexedTable(idx) + } + } + return &Collator{ + Strength: Quaternary, + f: norm.NFD, + t: t, + } +} + +// SetVariableTop sets all runes with primary strength less than the primary +// strength of r to be variable and thus affected by alternate handling. +func (c *Collator) SetVariableTop(r rune) { + // TODO: implement +} + +// Buffer holds reusable buffers that can be used during collation. +// Reusing a Buffer for the various calls that accept it may avoid +// unnecessary memory allocations. +type Buffer struct { + // TODO: try various parameters and techniques, such as using + // a chan of buffers for a pool. + ba [4096]byte + wa [512]weights + key []byte + ce []weights +} + +func (b *Buffer) init() { + if b.ce == nil { + b.ce = b.wa[:0] + b.key = b.ba[:0] + } else { + b.ce = b.ce[:0] + } +} + +// ResetKeys clears the buffer used for generated keys. Calling ResetKeys +// invalidates keys previously obtained from Key or KeyFromString. +func (b *Buffer) ResetKeys() { + b.ce = b.ce[:0] + b.key = b.key[:0] +} + +// Compare returns an integer comparing the two byte slices. +// The result will be 0 if a==b, -1 if a < b, and +1 if a > b. +// Compare calls ResetKeys, thereby invalidating keys +// previously generated using Key or KeyFromString using buf. +func (c *Collator) Compare(buf *Buffer, a, b []byte) int { + // TODO: for now we simply compute keys and compare. Once we + // have good benchmarks, move to an implementation that works + // incrementally for the majority of cases. + // - Benchmark with long strings that only vary in modifiers. + buf.ResetKeys() + ka := c.Key(buf, a) + kb := c.Key(buf, b) + defer buf.ResetKeys() + return bytes.Compare(ka, kb) +} + +// CompareString returns an integer comparing the two strings. +// The result will be 0 if a==b, -1 if a < b, and +1 if a > b. +// CompareString calls ResetKeys, thereby invalidating keys +// previously generated using Key or KeyFromString using buf. +func (c *Collator) CompareString(buf *Buffer, a, b string) int { + buf.ResetKeys() + ka := c.KeyFromString(buf, a) + kb := c.KeyFromString(buf, b) + defer buf.ResetKeys() + return bytes.Compare(ka, kb) +} + +func (c *Collator) Prefix(buf *Buffer, s, prefix []byte) int { + // iterate over s, track bytes consumed. + return 0 +} + +// Key returns the collation key for str. +// Passing the buffer buf may avoid memory allocations. +// The returned slice will point to an allocation in Buffer and will remain +// valid until the next call to buf.ResetKeys(). +func (c *Collator) Key(buf *Buffer, str []byte) []byte { + // See http://www.unicode.org/reports/tr10/#Main_Algorithm for more details. + buf.init() + c.getColElems(buf, str) + return c.key(buf, buf.ce) +} + +// KeyFromString returns the collation key for str. +// Passing the buffer buf may avoid memory allocations. +// The returned slice will point to an allocation in Buffer and will retain +// valid until the next call to buf.ResetKeys(). +func (c *Collator) KeyFromString(buf *Buffer, str string) []byte { + // See http://www.unicode.org/reports/tr10/#Main_Algorithm for more details. + buf.init() + c.getColElemsString(buf, str) + return c.key(buf, buf.ce) +} + +func (c *Collator) key(buf *Buffer, w []weights) []byte { + processWeights(c.Alternate, c.t.variableTop, w) + kn := len(buf.key) + c.keyFromElems(buf, w) + return buf.key[kn:] +} + +func (c *Collator) getColElems(buf *Buffer, str []byte) { + i := c.iter() + i.src.SetInput(c.f, str) + for !i.done() { + buf.ce = i.next(buf.ce) + } +} + +func (c *Collator) getColElemsString(buf *Buffer, str string) { + i := c.iter() + i.src.SetInputString(c.f, str) + for !i.done() { + buf.ce = i.next(buf.ce) + } +} + +type iter struct { + src norm.Iter + ba [1024]byte + buf []byte + t *table + p int + minBufSize int + _done, eof bool +} + +func (c *Collator) iter() iter { + i := iter{t: c.t, minBufSize: c.t.maxContractLen} + i.buf = i.ba[:0] + return i +} + +func (i *iter) done() bool { + return i._done +} + +func (i *iter) next(ce []weights) []weights { + if !i.eof && len(i.buf)-i.p < i.minBufSize { + // replenish buffer + n := copy(i.buf, i.buf[i.p:]) + n += i.src.Next(i.buf[n:cap(i.buf)]) + i.buf = i.buf[:n] + i.p = 0 + i.eof = i.src.Done() + } + if i.p == len(i.buf) { + i._done = true + return ce + } + ce, sz := i.t.appendNext(ce, i.buf[i.p:]) + i.p += sz + return ce +} + +func appendPrimary(key []byte, p uint32) []byte { + // Convert to variable length encoding; supports up to 23 bits. + if p <= 0x7FFF { + key = append(key, uint8(p>>8), uint8(p)) + } else { + key = append(key, uint8(p>>16)|0x80, uint8(p>>8), uint8(p)) + } + return key +} + +// keyFromElems converts the weights ws to a compact sequence of bytes. +// The result will be appended to the byte buffer in buf. +func (c *Collator) keyFromElems(buf *Buffer, ws []weights) { + for _, v := range ws { + if w := v.primary; w > 0 { + buf.key = appendPrimary(buf.key, w) + } + } + if Secondary <= c.Strength { + buf.key = append(buf.key, 0, 0) + // TODO: we can use one 0 if we can guarantee that all non-zero weights are > 0xFF. + if !c.Backwards { + for _, v := range ws { + if w := v.secondary; w > 0 { + buf.key = append(buf.key, uint8(w>>8), uint8(w)) + } + } + } else { + for i := len(ws) - 1; i >= 0; i-- { + if w := ws[i].secondary; w > 0 { + buf.key = append(buf.key, uint8(w>>8), uint8(w)) + } + } + } + } else if c.CaseLevel { + buf.key = append(buf.key, 0, 0) + } + if Tertiary <= c.Strength || c.CaseLevel { + buf.key = append(buf.key, 0, 0) + for _, v := range ws { + if w := v.tertiary; w > 0 { + buf.key = append(buf.key, w) + } + } + // Derive the quaternary weights from the options and other levels. + // Note that we represent maxQuaternary as 0xFF. The first byte of the + // representation of a a primary weight is always smaller than 0xFF, + // so using this single byte value will compare correctly. + if Quaternary <= c.Strength { + if c.Alternate == AltShiftTrimmed { + lastNonFFFF := len(buf.key) + buf.key = append(buf.key, 0) + for _, v := range ws { + if w := v.quaternary; w == maxQuaternary { + buf.key = append(buf.key, 0xFF) + } else if w > 0 { + buf.key = appendPrimary(buf.key, w) + lastNonFFFF = len(buf.key) + } + } + buf.key = buf.key[:lastNonFFFF] + } else { + buf.key = append(buf.key, 0) + for _, v := range ws { + if w := v.quaternary; w == maxQuaternary { + buf.key = append(buf.key, 0xFF) + } else if w > 0 { + buf.key = appendPrimary(buf.key, w) + } + } + } + } + } +} + +func processWeights(vw AlternateHandling, top uint32, wa []weights) { + ignore := false + switch vw { + case AltShifted, AltShiftTrimmed: + for i := range wa { + if p := wa[i].primary; p <= top && p != 0 { + wa[i] = weights{quaternary: p} + ignore = true + } else if p == 0 { + if ignore { + wa[i] = weights{} + } else if wa[i].tertiary != 0 { + wa[i].quaternary = maxQuaternary + } + } else { + wa[i].quaternary = maxQuaternary + ignore = false + } + } + case AltBlanked: + for i := range wa { + if p := wa[i].primary; p <= top && (ignore || p != 0) { + wa[i] = weights{} + ignore = true + } else { + ignore = false + } + } + } +} diff --git a/libgo/go/exp/locale/collate/contract.go b/libgo/go/exp/locale/collate/contract.go new file mode 100644 index 0000000..0d9bc40 --- /dev/null +++ b/libgo/go/exp/locale/collate/contract.go @@ -0,0 +1,86 @@ +// Copyright 2012 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 collate + +import "unicode/utf8" + +// For a description of contractTrieSet, see exp/locale/collate/build/contract.go. + +type contractTrieSet []struct{ l, h, n, i uint8 } + +// ctScanner is used to match a trie to an input sequence. +// A contraction may match a non-contiguous sequence of bytes in an input string. +// For example, if there is a contraction for <a, combining_ring>, it should match +// the sequence <a, combining_cedilla, combining_ring>, as combining_cedilla does +// not block combining_ring. +// ctScanner does not automatically skip over non-blocking non-starters, but rather +// retains the state of the last match and leaves it up to the user to continue +// the match at the appropriate points. +type ctScanner struct { + states contractTrieSet + s []byte + n int + index int + pindex int + done bool +} + +func (t contractTrieSet) scanner(index, n int, b []byte) ctScanner { + return ctScanner{states: t[index:], s: b, n: n} +} + +// result returns the offset i and bytes consumed p so far. If no suffix +// matched, i and p will be 0. +func (s *ctScanner) result() (i, p int) { + return s.index, s.pindex +} + +const ( + final = 0 + noIndex = 0xFF +) + +// scan matches the longest suffix at the current location in the input +// and returns the number of bytes consumed. +func (s *ctScanner) scan(p int) int { + pr := p // the p at the rune start + str := s.s + states, n := s.states, s.n + for i := 0; i < n && p < len(str); { + e := states[i] + c := str[p] + // TODO: a significant number of contractions are of a form that + // cannot match discontiguous UTF-8 in a normalized string. We could let + // a negative value of e.n mean that we can set s.done = true and avoid + // the need for additional matches. + if c >= e.l { + if e.l == c { + p++ + if e.i != noIndex { + s.index = int(e.i) + s.pindex = p + } + if e.n != final { + i, states, n = 0, states[int(e.h)+n:], int(e.n) + if p >= len(str) || utf8.RuneStart(str[p]) { + s.states, s.n, pr = states, n, p + } + } else { + s.done = true + return p + } + continue + } else if e.n == final && c <= e.h { + p++ + s.done = true + s.index = int(c-e.l) + int(e.i) + s.pindex = p + return p + } + } + i++ + } + return pr +} diff --git a/libgo/go/exp/locale/collate/contract_test.go b/libgo/go/exp/locale/collate/contract_test.go new file mode 100644 index 0000000..f3710a1 --- /dev/null +++ b/libgo/go/exp/locale/collate/contract_test.go @@ -0,0 +1,132 @@ +// Copyright 2012 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 collate + +import ( + "testing" +) + +type lookupStrings struct { + str string + offset int + n int // bytes consumed from input +} + +type LookupTest struct { + lookup []lookupStrings + n int + tries contractTrieSet +} + +var lookupTests = []LookupTest{ + {[]lookupStrings{ + {"abc", 1, 3}, + {"a", 0, 0}, + {"b", 0, 0}, + {"c", 0, 0}, + {"d", 0, 0}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, 0xFF}, + {'b', 0, 1, 0xFF}, + {'c', 'c', 0, 1}, + }, + }, + {[]lookupStrings{ + {"abc", 1, 3}, + {"abd", 2, 3}, + {"abe", 3, 3}, + {"a", 0, 0}, + {"ab", 0, 0}, + {"d", 0, 0}, + {"f", 0, 0}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, 0xFF}, + {'b', 0, 1, 0xFF}, + {'c', 'e', 0, 1}, + }, + }, + {[]lookupStrings{ + {"abc", 1, 3}, + {"ab", 2, 2}, + {"a", 3, 1}, + {"abcd", 1, 3}, + {"abe", 2, 2}, + }, + 1, + contractTrieSet{ + {'a', 0, 1, 3}, + {'b', 0, 1, 2}, + {'c', 'c', 0, 1}, + }, + }, + {[]lookupStrings{ + {"abc", 1, 3}, + {"abd", 2, 3}, + {"ab", 3, 2}, + {"ac", 4, 2}, + {"a", 5, 1}, + {"b", 6, 1}, + {"ba", 6, 1}, + }, + 2, + contractTrieSet{ + {'b', 'b', 0, 6}, + {'a', 0, 2, 5}, + {'c', 'c', 0, 4}, + {'b', 0, 1, 3}, + {'c', 'd', 0, 1}, + }, + }, + {[]lookupStrings{ + {"bcde", 2, 4}, + {"bc", 7, 2}, + {"ab", 6, 2}, + {"bcd", 5, 3}, + {"abcd", 1, 4}, + {"abc", 4, 3}, + {"bcdf", 3, 4}, + }, + 2, + contractTrieSet{ + {'b', 3, 1, 0xFF}, + {'a', 0, 1, 0xFF}, + {'b', 0, 1, 6}, + {'c', 0, 1, 4}, + {'d', 'd', 0, 1}, + {'c', 0, 1, 7}, + {'d', 0, 1, 5}, + {'e', 'f', 0, 2}, + }, + }, +} + +func lookup(c *contractTrieSet, nnode int, s []uint8) (i, n int) { + scan := c.scanner(0, nnode, s) + scan.scan(0) + return scan.result() +} + +func TestLookupContraction(t *testing.T) { + for i, tt := range lookupTests { + cts := contractTrieSet(tt.tries) + for j, lu := range tt.lookup { + str := lu.str + for _, s := range []string{str, str + "X"} { + const msg = `%d:%d: %s of "%s" %v; want %v` + offset, n := lookup(&cts, tt.n, []byte(s)) + if offset != lu.offset { + t.Errorf(msg, i, j, "offset", s, offset, lu.offset) + } + if n != lu.n { + t.Errorf(msg, i, j, "bytes consumed", s, n, len(str)) + } + } + } + } +} diff --git a/libgo/go/exp/locale/collate/export.go b/libgo/go/exp/locale/collate/export.go new file mode 100644 index 0000000..01750dd --- /dev/null +++ b/libgo/go/exp/locale/collate/export.go @@ -0,0 +1,43 @@ +// Copyright 2012 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 collate + +import "exp/norm" + +// Init is used by type Builder in exp/locale/collate/build/ +// to create Collator instances. It is for internal use only. +func Init(data interface{}) *Collator { + init, ok := data.(tableInitializer) + if !ok { + return nil + } + t := &table{} + loff, voff := init.FirstBlockOffsets() + t.index.index = init.TrieIndex() + t.index.index0 = t.index.index[blockSize*loff:] + t.index.values = init.TrieValues() + t.index.values0 = t.index.values[blockSize*voff:] + t.expandElem = init.ExpandElems() + t.contractTries = init.ContractTries() + t.contractElem = init.ContractElems() + t.maxContractLen = init.MaxContractLen() + t.variableTop = init.VariableTop() + return &Collator{ + Strength: Quaternary, + f: norm.NFD, + t: t, + } +} + +type tableInitializer interface { + TrieIndex() []uint16 + TrieValues() []uint32 + FirstBlockOffsets() (lookup, value uint16) + ExpandElems() []uint32 + ContractTries() []struct{ l, h, n, i uint8 } + ContractElems() []uint32 + MaxContractLen() int + VariableTop() uint32 +} diff --git a/libgo/go/exp/locale/collate/export_test.go b/libgo/go/exp/locale/collate/export_test.go new file mode 100644 index 0000000..de6e907 --- /dev/null +++ b/libgo/go/exp/locale/collate/export_test.go @@ -0,0 +1,87 @@ +// Copyright 2012 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 collate + +// Export for testing. + +import ( + "fmt" +) + +type Weights struct { + Primary, Secondary, Tertiary, Quaternary int +} + +func W(ce ...int) Weights { + w := Weights{ce[0], defaultSecondary, defaultTertiary, 0} + if len(ce) > 1 { + w.Secondary = ce[1] + } + if len(ce) > 2 { + w.Tertiary = ce[2] + } + if len(ce) > 3 { + w.Quaternary = ce[3] + } + return w +} +func (w Weights) String() string { + return fmt.Sprintf("[%d.%d.%d.%d]", w.Primary, w.Secondary, w.Tertiary, w.Quaternary) +} + +type Table struct { + t *table + w []weights +} + +func GetTable(c *Collator) *Table { + return &Table{c.t, nil} +} + +func convertToWeights(ws []weights) []Weights { + out := make([]Weights, len(ws)) + for i, w := range ws { + out[i] = Weights{int(w.primary), int(w.secondary), int(w.tertiary), int(w.quaternary)} + } + return out +} + +func convertFromWeights(ws []Weights) []weights { + out := make([]weights, len(ws)) + for i, w := range ws { + out[i] = weights{uint32(w.Primary), uint16(w.Secondary), uint8(w.Tertiary), uint32(w.Quaternary)} + } + return out +} + +func (t *Table) AppendNext(s []byte) ([]Weights, int) { + w, n := t.t.appendNext(nil, s) + return convertToWeights(w), n +} + +func SetTop(c *Collator, top int) { + if c.t == nil { + c.t = &table{} + } + c.t.variableTop = uint32(top) +} + +func GetColElems(c *Collator, buf *Buffer, str []byte) []Weights { + buf.ResetKeys() + c.getColElems(buf, str) + return convertToWeights(buf.ce) +} + +func ProcessWeights(h AlternateHandling, top int, w []Weights) []Weights { + in := convertFromWeights(w) + processWeights(h, uint32(top), in) + return convertToWeights(in) +} + +func KeyFromElems(c *Collator, buf *Buffer, w []Weights) []byte { + k := len(buf.key) + c.keyFromElems(buf, convertFromWeights(w)) + return buf.key[k:] +} diff --git a/libgo/go/exp/locale/collate/maketables.go b/libgo/go/exp/locale/collate/maketables.go new file mode 100644 index 0000000..ec03f8f --- /dev/null +++ b/libgo/go/exp/locale/collate/maketables.go @@ -0,0 +1,722 @@ +// Copyright 2012 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 + +// Collation table generator. +// Data read from the web. + +package main + +import ( + "archive/zip" + "bufio" + "bytes" + "encoding/xml" + "exp/locale/collate" + "exp/locale/collate/build" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "path" + "regexp" + "sort" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +var ( + root = flag.String("root", + "http://unicode.org/Public/UCA/"+unicode.Version+"/CollationAuxiliary.zip", + `URL of the Default Unicode Collation Element Table (DUCET). This can be a zip +file containing the file allkeys_CLDR.txt or an allkeys.txt file.`) + cldr = flag.String("cldr", + "http://www.unicode.org/Public/cldr/2.0.1/core.zip", + "URL of CLDR archive.") + test = flag.Bool("test", false, + "test existing tables; can be used to compare web data with package data.") + localFiles = flag.Bool("local", false, + "data files have been copied to the current directory; for debugging only.") + short = flag.Bool("short", false, `Use "short" alternatives, when available.`) + draft = flag.Bool("draft", false, `Use draft versions, when available.`) + tags = flag.String("tags", "", "build tags to be included after +build directive") + pkg = flag.String("package", "collate", + "the name of the package in which the generated file is to be included") + + tables = flagStringSetAllowAll("tables", "collate", "collate,chars", + "comma-spearated list of tables to generate.") + exclude = flagStringSet("exclude", "zh2", "", + "comma-separated list of languages to exclude.") + include = flagStringSet("include", "", "", + "comma-separated list of languages to include. Include trumps exclude.") + types = flagStringSetAllowAll("types", "", "", + "comma-separated list of types that should be included in addition to the standard type.") +) + +// stringSet implements an ordered set based on a list. It implements flag.Value +// to allow a set to be specified as a comma-separated list. +type stringSet struct { + s []string + allowed *stringSet + dirty bool // needs compaction if true + all bool + allowAll bool +} + +func flagStringSet(name, def, allowed, usage string) *stringSet { + ss := &stringSet{} + if allowed != "" { + usage += fmt.Sprintf(" (allowed values: any of %s)", allowed) + ss.allowed = &stringSet{} + failOnError(ss.allowed.Set(allowed)) + } + ss.Set(def) + flag.Var(ss, name, usage) + return ss +} + +func flagStringSetAllowAll(name, def, allowed, usage string) *stringSet { + ss := &stringSet{allowAll: true} + if allowed == "" { + flag.Var(ss, name, usage+fmt.Sprintf(` Use "all" to select all.`)) + } else { + ss.allowed = &stringSet{} + failOnError(ss.allowed.Set(allowed)) + flag.Var(ss, name, usage+fmt.Sprintf(` (allowed values: "all" or any of %s)`, allowed)) + } + ss.Set(def) + return ss +} + +func (ss stringSet) Len() int { + return len(ss.s) +} + +func (ss stringSet) String() string { + return strings.Join(ss.s, ",") +} + +func (ss *stringSet) Set(s string) error { + if ss.allowAll && s == "all" { + ss.s = nil + ss.all = true + return nil + } + ss.s = ss.s[:0] + for _, s := range strings.Split(s, ",") { + if s := strings.TrimSpace(s); s != "" { + if ss.allowed != nil && !ss.allowed.contains(s) { + return fmt.Errorf("unsupported value %q; must be one of %s", s, ss.allowed) + } + ss.add(s) + } + } + ss.compact() + return nil +} + +func (ss *stringSet) add(s string) { + ss.s = append(ss.s, s) + ss.dirty = true +} + +func (ss *stringSet) values() []string { + ss.compact() + return ss.s +} + +func (ss *stringSet) contains(s string) bool { + if ss.all { + return true + } + for _, v := range ss.s { + if v == s { + return true + } + } + return false +} + +func (ss *stringSet) compact() { + if !ss.dirty { + 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.dirty = false +} + +func skipLang(l string) bool { + if include.Len() > 0 { + return !include.contains(l) + } + return exclude.contains(l) +} + +func skipAlt(a string) bool { + if *draft && a == "proposed" { + return false + } + if *short && a == "short" { + return false + } + return true +} + +func failOnError(e error) { + if e != nil { + log.Fatal(e) + } +} + +// openReader opens the URL or file given by url and returns it as an io.ReadCloser +// or nil on error. +func openReader(url *string) (io.ReadCloser, error) { + if *localFiles { + pwd, _ := os.Getwd() + *url = "file://" + path.Join(pwd, path.Base(*url)) + } + t := &http.Transport{} + t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) + c := &http.Client{Transport: t} + resp, err := c.Get(*url) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf(`bad GET status for "%s": %s`, *url, resp.Status) + } + return resp.Body, nil +} + +func openArchive(url *string) *zip.Reader { + f, err := openReader(url) + failOnError(err) + buffer, err := ioutil.ReadAll(f) + f.Close() + failOnError(err) + archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer))) + failOnError(err) + return archive +} + +// parseUCA parses a Default Unicode Collation Element Table of the format +// specified in http://www.unicode.org/reports/tr10/#File_Format. +// It returns the variable top. +func parseUCA(builder *build.Builder) { + var r io.ReadCloser + var err error + if strings.HasSuffix(*root, ".zip") { + for _, f := range openArchive(root).File { + if strings.HasSuffix(f.Name, "allkeys_CLDR.txt") { + r, err = f.Open() + } + } + if r == nil { + err = fmt.Errorf("file allkeys_CLDR.txt not found in archive %q", *root) + } + } else { + r, err = openReader(root) + } + failOnError(err) + defer r.Close() + input := bufio.NewReader(r) + colelem := regexp.MustCompile(`\[([.*])([0-9A-F.]+)\]`) + for i := 1; err == nil; i++ { + l, prefix, e := input.ReadLine() + err = e + line := string(l) + if prefix { + log.Fatalf("%d: buffer overflow", i) + } + if err != nil && err != io.EOF { + log.Fatalf("%d: %v", i, err) + } + if len(line) == 0 || line[0] == '#' { + continue + } + if line[0] == '@' { + // parse properties + switch { + case strings.HasPrefix(line[1:], "version "): + a := strings.Split(line[1:], " ") + if a[1] != unicode.Version { + log.Fatalf("incompatible version %s; want %s", a[1], unicode.Version) + } + case strings.HasPrefix(line[1:], "backwards "): + log.Fatalf("%d: unsupported option backwards", i) + default: + log.Printf("%d: unknown option %s", i, line[1:]) + } + } else { + // parse entries + part := strings.Split(line, " ; ") + if len(part) != 2 { + log.Fatalf("%d: production rule without ';': %v", i, line) + } + lhs := []rune{} + for _, v := range strings.Split(part[0], " ") { + if v == "" { + continue + } + lhs = append(lhs, rune(convHex(i, v))) + } + var n int + var vars []int + rhs := [][]int{} + for i, m := range colelem.FindAllStringSubmatch(part[1], -1) { + n += len(m[0]) + elem := []int{} + for _, h := range strings.Split(m[2], ".") { + elem = append(elem, convHex(i, h)) + } + if m[1] == "*" { + vars = append(vars, i) + } + rhs = append(rhs, elem) + } + if len(part[1]) < n+3 || part[1][n+1] != '#' { + log.Fatalf("%d: expected comment; found %s", i, part[1][n:]) + } + if *test { + testInput.add(string(lhs)) + } + failOnError(builder.Add(lhs, rhs, vars)) + } + } +} + +func convHex(line int, s string) int { + r, e := strconv.ParseInt(s, 16, 32) + if e != nil { + log.Fatalf("%d: %v", line, e) + } + return int(r) +} + +var testInput = stringSet{} + +// LDML holds all collation information parsed from an LDML XML file. +// The format of these files is defined in http://unicode.org/reports/tr35/. +type LDML struct { + XMLName xml.Name `xml:"ldml"` + Language Attr `xml:"identity>language"` + Territory Attr `xml:"identity>territory"` + Chars *struct { + ExemplarCharacters []AttrValue `xml:"exemplarCharacters"` + MoreInformaton string `xml:"moreInformation,omitempty"` + } `xml:"characters"` + Default Attr `xml:"collations>default"` + Collations []Collation `xml:"collations>collation"` +} + +type Attr struct { + XMLName xml.Name + Attr string `xml:"type,attr"` +} + +func (t Attr) String() string { + return t.Attr +} + +type AttrValue struct { + Type string `xml:"type,attr"` + Key string `xml:"key,attr,omitempty"` + Draft string `xml:"draft,attr,omitempty"` + Value string `xml:",innerxml"` +} + +type Collation struct { + Type string `xml:"type,attr"` + Alt string `xml:"alt,attr"` + SuppressContraction string `xml:"suppress_contractions,omitempty"` + Settings *Settings `xml:"settings"` + Optimize string `xml:"optimize"` + Rules Rules `xml:"rules"` +} + +type Optimize struct { + XMLName xml.Name `xml:"optimize"` + Data string `xml:"chardata"` +} + +type Suppression struct { + XMLName xml.Name `xml:"suppress_contractions"` + Data string `xml:"chardata"` +} + +type Settings struct { + Strength string `xml:"strenght,attr,omitempty"` + Backwards string `xml:"backwards,attr,omitempty"` + Normalization string `xml:"normalization,attr,omitempty"` + CaseLevel string `xml:"caseLevel,attr,omitempty"` + CaseFirst string `xml:"caseFirst,attr,omitempty"` + HiraganaQuarternary string `xml:"hiraganaQuartenary,attr,omitempty"` + Numeric string `xml:"numeric,attr,omitempty"` + VariableTop string `xml:"variableTop,attr,omitempty"` +} + +type Rules struct { + XMLName xml.Name `xml:"rules"` + Any []RuleElem `xml:",any"` +} + +type RuleElem struct { + XMLName xml.Name + Value string `xml:",innerxml"` + Before string `xml:"before,attr"` + Any []RuleElem `xml:",any"` // for <x> elements +} + +var charRe = regexp.MustCompile(`&#x([0-9A-F]*);`) +var tagRe = regexp.MustCompile(`<([a-z_]*) */>`) + +func (r *RuleElem) rewrite() { + // Convert hexadecimal Unicode codepoint notation to a string. + if m := charRe.FindAllStringSubmatch(r.Value, -1); m != nil { + runes := []rune{} + for _, sa := range m { + runes = append(runes, rune(convHex(-1, sa[1]))) + } + r.Value = string(runes) + } + // Strip spaces from reset positions. + if m := tagRe.FindStringSubmatch(r.Value); m != nil { + r.Value = fmt.Sprintf("<%s/>", m[1]) + } + for _, rr := range r.Any { + rr.rewrite() + } +} + +func decodeXML(f *zip.File) *LDML { + r, err := f.Open() + failOnError(err) + d := xml.NewDecoder(r) + var x LDML + err = d.Decode(&x) + failOnError(err) + return &x +} + +var mainLocales = []string{} + +// charsets holds a list of exemplar characters per category. +type charSets map[string][]string + +func (p charSets) fprint(w io.Writer) { + fmt.Fprintln(w, "[exN]string{") + for i, k := range []string{"", "contractions", "punctuation", "auxiliary", "currencySymbol", "index"} { + if set := p[k]; len(set) != 0 { + fmt.Fprintf(w, "\t\t%d: %q,\n", i, strings.Join(set, " ")) + } + } + fmt.Fprintln(w, "\t},") +} + +var localeChars = make(map[string]charSets) + +const exemplarHeader = ` +type exemplarType int +const ( + exCharacters exemplarType = iota + exContractions + exPunctuation + exAuxiliary + exCurrency + exIndex + exN +) +` + +func printExemplarCharacters(w io.Writer) { + fmt.Fprintln(w, exemplarHeader) + fmt.Fprintln(w, "var exemplarCharacters = map[string][exN]string{") + for _, loc := range mainLocales { + fmt.Fprintf(w, "\t%q: ", loc) + localeChars[loc].fprint(w) + } + fmt.Fprintln(w, "}") +} + +var mainRe = regexp.MustCompile(`.*/main/(.*)\.xml`) + +// parseMain parses XML files in the main directory of the CLDR core.zip file. +func parseMain() { + for _, f := range openArchive(cldr).File { + if m := mainRe.FindStringSubmatch(f.Name); m != nil { + locale := m[1] + x := decodeXML(f) + if skipLang(x.Language.Attr) { + continue + } + if x.Chars != nil { + for _, ec := range x.Chars.ExemplarCharacters { + if ec.Draft != "" { + continue + } + if _, ok := localeChars[locale]; !ok { + mainLocales = append(mainLocales, locale) + localeChars[locale] = make(charSets) + } + localeChars[locale][ec.Type] = parseCharacters(ec.Value) + } + } + } + } +} + +func parseCharacters(chars string) []string { + parseSingle := func(s string) (r rune, tail string, escaped bool) { + if s[0] == '\\' { + if s[1] == 'u' || s[1] == 'U' { + r, _, tail, err := strconv.UnquoteChar(s, 0) + failOnError(err) + return r, tail, false + } else if strings.HasPrefix(s[1:], "&") { + return '&', s[6:], false + } + return rune(s[1]), s[2:], true + } else if strings.HasPrefix(s, """) { + return '"', s[6:], false + } + r, sz := utf8.DecodeRuneInString(s) + return r, s[sz:], false + } + chars = strings.Trim(chars, "[ ]") + list := []string{} + var r, last, end rune + for len(chars) > 0 { + if chars[0] == '{' { // character sequence + buf := []rune{} + for chars = chars[1:]; len(chars) > 0; { + r, chars, _ = parseSingle(chars) + if r == '}' { + break + } + if r == ' ' { + log.Fatalf("space not supported in sequence %q", chars) + } + buf = append(buf, r) + } + list = append(list, string(buf)) + last = 0 + } else { // single character + escaped := false + r, chars, escaped = parseSingle(chars) + if r != ' ' { + if r == '-' && !escaped { + if last == 0 { + log.Fatal("'-' should be preceded by a character") + } + end, chars, _ = parseSingle(chars) + for ; last <= end; last++ { + list = append(list, string(last)) + } + last = 0 + } else { + list = append(list, string(r)) + last = r + } + } + } + } + return list +} + +var fileRe = regexp.MustCompile(`.*/collation/(.*)\.xml`) + +// parseCollation parses XML files in the collation directory of the CLDR core.zip file. +func parseCollation(b *build.Builder) { + for _, f := range openArchive(cldr).File { + if m := fileRe.FindStringSubmatch(f.Name); m != nil { + lang := m[1] + x := decodeXML(f) + if skipLang(x.Language.Attr) { + continue + } + def := "standard" + if x.Default.Attr != "" { + def = x.Default.Attr + } + todo := make(map[string]Collation) + for _, c := range x.Collations { + if c.Type != def && !types.contains(c.Type) { + continue + } + if c.Alt != "" && skipAlt(c.Alt) { + continue + } + for j := range c.Rules.Any { + c.Rules.Any[j].rewrite() + } + locale := lang + if c.Type != def { + locale += "_u_co_" + c.Type + } + _, exists := todo[locale] + if c.Alt != "" || !exists { + todo[locale] = c + } + } + for _, c := range x.Collations { + locale := lang + if c.Type != def { + locale += "_u_co_" + c.Type + } + if d, ok := todo[locale]; ok && d.Alt == c.Alt { + insertCollation(b, locale, &c) + } + } + } + } +} + +var lmap = map[byte]collate.Level{ + 'p': collate.Primary, + 's': collate.Secondary, + 't': collate.Tertiary, + 'i': collate.Identity, +} + +// cldrIndex is a Unicode-reserved sentinel value used. +// We ignore any rule that starts with this rune. +// See http://unicode.org/reports/tr35/#Collation_Elements for details. +const cldrIndex = 0xFDD0 + +func insertTailoring(t *build.Tailoring, r RuleElem, context, extend string) { + switch l := r.XMLName.Local; l { + case "p", "s", "t", "i": + if []rune(r.Value)[0] != cldrIndex { + str := context + r.Value + if *test { + testInput.add(str) + } + err := t.Insert(lmap[l[0]], str, extend) + failOnError(err) + } + case "pc", "sc", "tc", "ic": + level := lmap[l[0]] + for _, s := range r.Value { + str := context + string(s) + if *test { + testInput.add(str) + } + err := t.Insert(level, str, extend) + failOnError(err) + } + default: + log.Fatalf("unsupported tag: %q", l) + } +} + +func insertCollation(builder *build.Builder, locale string, c *Collation) { + t := builder.Tailoring(locale) + for _, r := range c.Rules.Any { + switch r.XMLName.Local { + case "reset": + if r.Before == "" { + failOnError(t.SetAnchor(r.Value)) + } else { + failOnError(t.SetAnchorBefore(r.Value)) + } + case "x": + var context, extend string + for _, r1 := range r.Any { + switch r1.XMLName.Local { + case "context": + context = r1.Value + case "extend": + extend = r1.Value + } + } + for _, r1 := range r.Any { + if t := r1.XMLName.Local; t == "context" || t == "extend" { + continue + } + insertTailoring(t, r1, context, extend) + } + default: + insertTailoring(t, r, "", "") + } + } +} + +func testCollator(c *collate.Collator) { + c0 := collate.New("") + + // iterator over all characters for all locales and check + // whether Key is equal. + buf := collate.Buffer{} + + // Add all common and not too uncommon runes to the test set. + for i := rune(0); i < 0x30000; i++ { + testInput.add(string(i)) + } + for i := rune(0xE0000); i < 0xF0000; i++ { + testInput.add(string(i)) + } + for _, str := range testInput.values() { + k0 := c0.KeyFromString(&buf, str) + k := c.KeyFromString(&buf, str) + if bytes.Compare(k0, k) != 0 { + failOnError(fmt.Errorf("test:%U: keys differ (%x vs %x)", []rune(str), k0, k)) + } + buf.ResetKeys() + } + fmt.Println("PASS") +} + +func main() { + flag.Parse() + b := build.NewBuilder() + if *root != "" { + parseUCA(b) + } + if *cldr != "" { + if tables.contains("chars") { + parseMain() + } + parseCollation(b) + } + + c, err := b.Build() + failOnError(err) + + if *test { + testCollator(c) + } else { + fmt.Println("// Generated by running") + fmt.Printf("// maketables -root=%s -cldr=%s\n", *root, *cldr) + fmt.Println("// DO NOT EDIT") + fmt.Println("// TODO: implement more compact representation for sparse blocks.") + if *tags != "" { + fmt.Printf("// +build %s\n", *tags) + } + fmt.Println("") + fmt.Printf("package %s\n", *pkg) + if tables.contains("collate") { + fmt.Println("") + _, err = b.Print(os.Stdout) + failOnError(err) + } + if tables.contains("chars") { + printExemplarCharacters(os.Stdout) + } + } +} diff --git a/libgo/go/exp/locale/collate/regtest.go b/libgo/go/exp/locale/collate/regtest.go new file mode 100644 index 0000000..14a447c --- /dev/null +++ b/libgo/go/exp/locale/collate/regtest.go @@ -0,0 +1,268 @@ +// Copyright 2012 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 + +import ( + "archive/zip" + "bufio" + "bytes" + "exp/locale/collate" + "exp/locale/collate/build" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "path" + "regexp" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// This regression test runs tests for the test files in CollationTest.zip +// (taken from http://www.unicode.org/Public/UCA/<unicode.Version>/). +// +// The test files have the following form: +// # header +// 0009 0021; # ('\u0009') <CHARACTER TABULATION> [| | | 0201 025E] +// 0009 003F; # ('\u0009') <CHARACTER TABULATION> [| | | 0201 0263] +// 000A 0021; # ('\u000A') <LINE FEED (LF)> [| | | 0202 025E] +// 000A 003F; # ('\u000A') <LINE FEED (LF)> [| | | 0202 0263] +// +// The part before the semicolon is the hex representation of a sequence +// of runes. After the hash mark is a comment. The strings +// represented by rune sequence are in the file in sorted order, as +// defined by the DUCET. + +var testdata = flag.String("testdata", + "http://www.unicode.org/Public/UCA/"+unicode.Version+"/CollationTest.zip", + "URL of Unicode collation tests zip file") +var ducet = flag.String("ducet", + "http://unicode.org/Public/UCA/"+unicode.Version+"/allkeys.txt", + "URL of the Default Unicode Collation Element Table (DUCET).") +var localFiles = flag.Bool("local", + false, + "data files have been copied to the current directory; for debugging only") + +type Test struct { + name string + str [][]byte + comment []string +} + +var versionRe = regexp.MustCompile(`# UCA Version: (.*)\n?$`) +var testRe = regexp.MustCompile(`^([\dA-F ]+);.*# (.*)\n?$`) + +func Error(e error) { + if e != nil { + log.Fatal(e) + } +} + +// openReader opens the url or file given by url and returns it as an io.ReadCloser +// or nil on error. +func openReader(url string) io.ReadCloser { + if *localFiles { + pwd, _ := os.Getwd() + url = "file://" + path.Join(pwd, path.Base(url)) + } + t := &http.Transport{} + t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) + c := &http.Client{Transport: t} + resp, err := c.Get(url) + Error(err) + if resp.StatusCode != 200 { + Error(fmt.Errorf(`bad GET status for "%s": %s`, url, resp.Status)) + } + return resp.Body +} + +// parseUCA parses a Default Unicode Collation Element Table of the format +// specified in http://www.unicode.org/reports/tr10/#File_Format. +// It returns the variable top. +func parseUCA(builder *build.Builder) { + r := openReader(*ducet) + defer r.Close() + input := bufio.NewReader(r) + colelem := regexp.MustCompile(`\[([.*])([0-9A-F.]+)\]`) + for i := 1; true; i++ { + l, prefix, err := input.ReadLine() + if err == io.EOF { + break + } + Error(err) + line := string(l) + if prefix { + log.Fatalf("%d: buffer overflow", i) + } + if len(line) == 0 || line[0] == '#' { + continue + } + if line[0] == '@' { + if strings.HasPrefix(line[1:], "version ") { + if v := strings.Split(line[1:], " ")[1]; v != unicode.Version { + log.Fatalf("incompatible version %s; want %s", v, unicode.Version) + } + } + } else { + // parse entries + part := strings.Split(line, " ; ") + if len(part) != 2 { + log.Fatalf("%d: production rule without ';': %v", i, line) + } + lhs := []rune{} + for _, v := range strings.Split(part[0], " ") { + if v != "" { + lhs = append(lhs, rune(convHex(i, v))) + } + } + vars := []int{} + rhs := [][]int{} + for i, m := range colelem.FindAllStringSubmatch(part[1], -1) { + if m[1] == "*" { + vars = append(vars, i) + } + elem := []int{} + for _, h := range strings.Split(m[2], ".") { + elem = append(elem, convHex(i, h)) + } + rhs = append(rhs, elem) + } + builder.Add(lhs, rhs, vars) + } + } +} + +func convHex(line int, s string) int { + r, e := strconv.ParseInt(s, 16, 32) + if e != nil { + log.Fatalf("%d: %v", line, e) + } + return int(r) +} + +func loadTestData() []Test { + f := openReader(*testdata) + buffer, err := ioutil.ReadAll(f) + f.Close() + Error(err) + archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer))) + Error(err) + tests := []Test{} + for _, f := range archive.File { + // Skip the short versions, which are simply duplicates of the long versions. + if strings.Contains(f.Name, "SHORT") || f.FileInfo().IsDir() { + continue + } + ff, err := f.Open() + Error(err) + defer ff.Close() + input := bufio.NewReader(ff) + test := Test{name: path.Base(f.Name)} + for { + line, err := input.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + log.Fatal(err) + } + if len(line) <= 1 || line[0] == '#' { + if m := versionRe.FindStringSubmatch(line); m != nil { + if m[1] != unicode.Version { + log.Printf("warning:%s: version is %s; want %s", f.Name, m[1], unicode.Version) + } + } + continue + } + m := testRe.FindStringSubmatch(line) + if m == nil || len(m) < 3 { + log.Fatalf(`Failed to parse: "%s" result: %#v`, line, m) + } + str := []byte{} + // In the regression test data (unpaired) surrogates are assigned a weight + // corresponding to their code point value. However, utf8.DecodeRune, + // which is used to compute the implicit weight, assigns FFFD to surrogates. + // We therefore skip tests with surrogates. This skips about 35 entries + // per test. + valid := true + for _, split := range strings.Split(m[1], " ") { + r, err := strconv.ParseUint(split, 16, 64) + Error(err) + valid = valid && utf8.ValidRune(rune(r)) + str = append(str, string(rune(r))...) + } + if valid { + test.str = append(test.str, str) + test.comment = append(test.comment, m[2]) + } + } + tests = append(tests, test) + } + return tests +} + +var errorCount int + +func fail(t Test, pattern string, args ...interface{}) { + format := fmt.Sprintf("error:%s:%s", t.name, pattern) + log.Printf(format, args...) + errorCount++ + if errorCount > 30 { + log.Fatal("too many errors") + } +} + +func runes(b []byte) []rune { + return []rune(string(b)) +} + +func doTest(t Test) { + bld := build.NewBuilder() + parseUCA(bld) + c, err := bld.Build() + Error(err) + c.Strength = collate.Tertiary + c.Alternate = collate.AltShifted + b := &collate.Buffer{} + if strings.Contains(t.name, "NON_IGNOR") { + c.Alternate = collate.AltNonIgnorable + } + + prev := t.str[0] + for i := 1; i < len(t.str); i++ { + s := t.str[i] + ka := c.Key(b, prev) + kb := c.Key(b, s) + if r := bytes.Compare(ka, kb); r == 1 { + fail(t, "%d: Key(%.4X) < Key(%.4X) (%X < %X) == %d; want -1 or 0", i, []rune(string(prev)), []rune(string(s)), ka, kb, r) + prev = s + continue + } + if r := c.Compare(b, prev, s); r == 1 { + fail(t, "%d: Compare(%.4X, %.4X) == %d; want -1 or 0", i, runes(prev), runes(s), r) + } + if r := c.Compare(b, s, prev); r == -1 { + fail(t, "%d: Compare(%.4X, %.4X) == %d; want 1 or 0", i, runes(s), runes(prev), r) + } + prev = s + } +} + +func main() { + flag.Parse() + for _, test := range loadTestData() { + doTest(test) + } + if errorCount == 0 { + fmt.Println("PASS") + } +} diff --git a/libgo/go/exp/locale/collate/table.go b/libgo/go/exp/locale/collate/table.go new file mode 100644 index 0000000..c25799b --- /dev/null +++ b/libgo/go/exp/locale/collate/table.go @@ -0,0 +1,150 @@ +// Copyright 2012 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 collate + +import ( + "exp/norm" + "unicode/utf8" +) + +// tableIndex holds information for constructing a table +// for a certain locale based on the main table. +type tableIndex struct { + lookupOffset uint32 + valuesOffset uint32 +} + +// table holds all collation data for a given collation ordering. +type table struct { + index trie // main trie + + // expansion info + expandElem []uint32 + + // contraction info + contractTries contractTrieSet + contractElem []uint32 + maxContractLen int + variableTop uint32 +} + +func (t *table) indexedTable(idx tableIndex) *table { + nt := *t + nt.index.index0 = t.index.index[idx.lookupOffset*blockSize:] + nt.index.values0 = t.index.values[idx.valuesOffset*blockSize:] + return &nt +} + +// appendNext appends the weights corresponding to the next rune or +// contraction in s. If a contraction is matched to a discontinuous +// sequence of runes, the weights for the interstitial runes are +// appended as well. It returns a new slice that includes the appended +// weights and the number of bytes consumed from s. +func (t *table) appendNext(w []weights, s []byte) ([]weights, int) { + v, sz := t.index.lookup(s) + ce := colElem(v) + tp := ce.ctype() + if tp == ceNormal { + w = append(w, getWeights(ce, s)) + } else if tp == ceExpansionIndex { + w = t.appendExpansion(w, ce) + } else if tp == ceContractionIndex { + n := 0 + w, n = t.matchContraction(w, ce, s[sz:]) + sz += n + } else if tp == ceDecompose { + // Decompose using NFCK and replace tertiary weights. + t1, t2 := splitDecompose(ce) + i := len(w) + nfkd := norm.NFKD.Properties(s).Decomposition() + for p := 0; len(nfkd) > 0; nfkd = nfkd[p:] { + w, p = t.appendNext(w, nfkd) + } + w[i].tertiary = t1 + if i++; i < len(w) { + w[i].tertiary = t2 + for i++; i < len(w); i++ { + w[i].tertiary = maxTertiary + } + } + } + return w, sz +} + +func getWeights(ce colElem, s []byte) weights { + if ce == 0 { // implicit + r, _ := utf8.DecodeRune(s) + return weights{ + primary: uint32(implicitPrimary(r)), + secondary: defaultSecondary, + tertiary: defaultTertiary, + } + } + return splitCE(ce) +} + +func (t *table) appendExpansion(w []weights, ce colElem) []weights { + i := splitExpandIndex(ce) + n := int(t.expandElem[i]) + i++ + for _, ce := range t.expandElem[i : i+n] { + w = append(w, splitCE(colElem(ce))) + } + return w +} + +func (t *table) matchContraction(w []weights, ce colElem, suffix []byte) ([]weights, int) { + index, n, offset := splitContractIndex(ce) + + scan := t.contractTries.scanner(index, n, suffix) + buf := [norm.MaxSegmentSize]byte{} + bufp := 0 + p := scan.scan(0) + + if !scan.done && p < len(suffix) && suffix[p] >= utf8.RuneSelf { + // By now we should have filtered most cases. + p0 := p + bufn := 0 + rune := norm.NFC.Properties(suffix[p:]) + p += rune.Size() + if prevCC := rune.TrailCCC(); prevCC != 0 { + // A gap may only occur in the last normalization segment. + // This also ensures that len(scan.s) < norm.MaxSegmentSize. + if end := norm.NFC.FirstBoundary(suffix[p:]); end != -1 { + scan.s = suffix[:p+end] + } + for p < len(suffix) && !scan.done && suffix[p] >= utf8.RuneSelf { + rune = norm.NFC.Properties(suffix[p:]) + if ccc := rune.LeadCCC(); ccc == 0 || prevCC >= ccc { + break + } + prevCC = rune.TrailCCC() + if pp := scan.scan(p); pp != p { + // Copy the interstitial runes for later processing. + bufn += copy(buf[bufn:], suffix[p0:p]) + if scan.pindex == pp { + bufp = bufn + } + p, p0 = pp, pp + } else { + p += rune.Size() + } + } + } + } + // Append weights for the matched contraction, which may be an expansion. + i, n := scan.result() + ce = colElem(t.contractElem[i+offset]) + if ce.ctype() == ceNormal { + w = append(w, splitCE(ce)) + } else { + w = t.appendExpansion(w, ce) + } + // Append weights for the runes in the segment not part of the contraction. + for b, p := buf[:bufp], 0; len(b) > 0; b = b[p:] { + w, p = t.appendNext(w, b) + } + return w, n +} diff --git a/libgo/go/exp/locale/collate/tables.go b/libgo/go/exp/locale/collate/tables.go new file mode 100644 index 0000000..1b36a65 --- /dev/null +++ b/libgo/go/exp/locale/collate/tables.go @@ -0,0 +1,7578 @@ +// Generated by running +// maketables -root=http://unicode.org/Public/UCA/6.0.0/CollationAuxiliary.zip -cldr=http://www.unicode.org/Public/cldr/2.0.1/core.zip +// DO NOT EDIT +// TODO: implement more compact representation for sparse blocks. + +package collate + +var availableLocales = []string{"af", "ar", "as", "az", "be", "bg", "bn", "ca", "cs", "cy", "da", "de", "dz", "el", "en_US_POSIX", "eo", "es", "et", "fa", "fi", "fil", "fo", "fr_CA", "gu", "ha", "haw", "he", "hi", "hr", "hu", "hy", "ig", "is", "ja", "kk", "kl", "km", "kn", "ko", "kok", "ln", "lt", "lv", "mk", "ml", "mr", "mt", "my", "nb", "nn", "nso", "om", "or", "pa", "pl", "ps", "ro", "root", "ru", "se", "si", "sk", "sl", "sq", "sr", "sv", "ta", "te", "th", "tn", "tr", "uk", "ur", "vi", "wae", "yo", "zh"} + +var locales = map[string]tableIndex{ + "af": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ar": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "as": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "az": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "be": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "bg": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "bn": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ca": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "cs": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "cy": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "da": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "de": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "dz": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "el": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "en_US_POSIX": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "eo": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "es": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "et": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "fa": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "fi": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "fil": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "fo": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "fr_CA": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "gu": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ha": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "haw": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "he": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "hi": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "hr": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "hu": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "hy": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ig": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "is": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ja": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "kk": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "kl": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "km": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "kn": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ko": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "kok": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ln": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "lt": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "lv": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "mk": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ml": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "mr": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "mt": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "my": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "nb": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "nn": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "nso": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "om": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "or": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "pa": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "pl": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ps": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ro": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "root": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ru": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "se": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "si": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "sk": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "sl": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "sq": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "sr": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "sv": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ta": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "te": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "th": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "tn": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "tr": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "uk": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "ur": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "vi": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "wae": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "yo": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, + "zh": { + lookupOffset: 0x13, + valuesOffset: 0x0, + }, +} + +var mainTable = table{ + trie{mainLookup[1216:], mainValues[0:], mainLookup[:], mainValues[:]}, + mainExpandElem[:], + contractTrieSet(mainCTEntries[:]), + mainContractElem[:], + 9, + 0x2ED, +} + +// mainExpandElem: 4642 entries, 18568 bytes +var mainExpandElem = [4642]uint32{ + // Block 0, offset 0x0 + 0x00000002, 0x8000A31A, 0x8000AD1A, 0x00000002, 0x8000A51A, 0x8000AD1A, + 0x00000002, 0x8000A718, 0x8000AD18, 0x00000002, 0x8000A71A, 0x8000AD1A, + 0x00000002, 0x8000A918, 0x8000AD18, 0x00000002, 0x8000A91A, 0x8000AD1A, + 0x00000002, 0x8000AB18, 0x8000AD18, 0x00000002, 0x8000AB1A, 0x8000AD1A, + 0x00000002, 0x8000AD1A, 0x8000BD1A, 0x00000002, 0x40139D20, 0x80014E02, + 0x00000002, 0x40139E20, 0x80014E02, 0x00000002, 0x40149A20, 0x80016502, + 0x00000002, 0x40149A20, 0x80016602, 0x00000002, 0x40149A20, 0x80016802, + 0x00000002, 0x40149A20, 0x80016A02, 0x00000002, 0x40149A20, 0x80016B02, + 0x00000002, 0x40149A20, 0x80016C02, 0x00000002, 0x40149A20, 0x80016D02, + 0x00000002, 0x40149A20, 0x80016E02, 0x00000002, 0x40149A20, 0x80016F02, + 0x00000002, 0x40149A20, 0x80017002, 0x00000002, + // Block 1, offset 0x40 + 0x40149A20, 0x80017102, 0x00000002, 0x40149A20, 0x80017102, 0x00000002, + 0x40149A20, 0x80017202, 0x00000002, 0x40149A20, 0x80017302, 0x00000002, + 0x40149A20, 0x80017402, 0x00000002, 0x40149A20, 0x80017502, 0x00000002, + 0x40149A20, 0x80017602, 0x00000002, 0x40149A20, 0x80017702, 0x00000002, + 0x40149A20, 0x80017802, 0x00000002, 0x40149A20, 0x80017902, 0x00000002, + 0x40149A20, 0x80017A02, 0x00000002, 0x40149A20, 0x80017B02, 0x00000002, + 0x40149A20, 0x80017C02, 0x00000002, 0x00293404, 0x80017C04, 0x00000002, + 0x40149A20, 0x80017D02, 0x00000002, 0x40149A20, 0x80017E02, 0x00000002, + 0x40149A20, 0x80017F02, 0x00000002, 0x40149A20, 0x80018002, 0x00000002, + 0x40149A20, 0x80018102, 0x00000002, 0x40149A20, 0x80018202, 0x00000002, + 0x40149A20, 0x80018302, 0x00000002, 0x40149A20, + // Block 2, offset 0x80 + 0x80018402, 0x00000002, 0x40149A20, 0x80018502, 0x00000002, 0x40149A20, + 0x80018602, 0x00000002, 0x40149A20, 0x80018702, 0x00000002, 0x40149A20, + 0x80018802, 0x00000002, 0x40149A20, 0x80018902, 0x00000002, 0x40149A20, + 0x80018A02, 0x00000002, 0x40149A20, 0x80018C02, 0x00000002, 0x40149A20, + 0x80019602, 0x00000002, 0x40149B20, 0x80016502, 0x00000002, 0x40149B20, + 0x80016602, 0x00000002, 0x40149B20, 0x80016702, 0x00000002, 0x40149B20, + 0x80016802, 0x00000002, 0x40149B20, 0x80016902, 0x00000002, 0x40149B20, + 0x80016A02, 0x00000002, 0x40149B20, 0x80016B02, 0x00000002, 0x40149B20, + 0x80016C02, 0x00000002, 0x40149B20, 0x80016D02, 0x00000002, 0x40149B20, + 0x80016E02, 0x00000002, 0x40149B20, 0x80016F02, 0x00000002, 0x40149B20, + 0x80017002, 0x00000002, 0x40149B20, 0x80017102, + // Block 3, offset 0xc0 + 0x00000002, 0x40149B20, 0x80017102, 0x00000002, 0x40149B20, 0x80017102, + 0x00000002, 0x40149B20, 0x80017202, 0x00000002, 0x40149B20, 0x80017302, + 0x00000002, 0x40149B20, 0x80017402, 0x00000002, 0x40149B20, 0x80017502, + 0x00000002, 0x40149B20, 0x80017602, 0x00000002, 0x40149B20, 0x80017702, + 0x00000002, 0x40149B20, 0x80017702, 0x00000002, 0x40149B20, 0x80017802, + 0x00000002, 0x40149B20, 0x80017902, 0x00000002, 0x40149B20, 0x80017A02, + 0x00000002, 0x40149B20, 0x80017B02, 0x00000002, 0x40149B20, 0x80017C02, + 0x00000002, 0x00293604, 0x80017C04, 0x00000002, 0x40149B20, 0x80017D02, + 0x00000002, 0x40149B20, 0x80017E02, 0x00000002, 0x40149B20, 0x80017F02, + 0x00000002, 0x40149B20, 0x80018002, 0x00000002, 0x40149B20, 0x80018102, + 0x00000002, 0x40149B20, 0x80018202, 0x00000002, + // Block 4, offset 0x100 + 0x40149B20, 0x80018302, 0x00000002, 0x40149B20, 0x80018402, 0x00000002, + 0x40149B20, 0x80018502, 0x00000002, 0x40149B20, 0x80018602, 0x00000002, + 0x40149B20, 0x80018702, 0x00000002, 0x40149B20, 0x80018802, 0x00000002, + 0x40149B20, 0x80018902, 0x00000002, 0x40149B20, 0x80018A02, 0x00000002, + 0x40149B20, 0x80018B02, 0x00000002, 0x40149B20, 0x80018C02, 0x00000002, + 0x40149B20, 0x80018C02, 0x00000002, 0x40149B20, 0x80018C02, 0x00000002, + 0x40149B20, 0x80018C02, 0x00000002, 0x40149B20, 0x80018E02, 0x00000002, + 0x40149B20, 0x80018F02, 0x00000002, 0x40149B20, 0x80019002, 0x00000002, + 0x40149B20, 0x80019002, 0x00000002, 0x40149B20, 0x80019002, 0x00000002, + 0x40149B20, 0x80019002, 0x00000002, 0x40149B20, 0x80019002, 0x00000002, + 0x40149B20, 0x80019002, 0x00000002, 0x40149B20, + // Block 5, offset 0x140 + 0x80019102, 0x00000002, 0x40149B20, 0x80019202, 0x00000002, 0x40149B20, + 0x80019302, 0x00000002, 0x40149B20, 0x80019402, 0x00000002, 0x40149B20, + 0x80019502, 0x00000002, 0x40149B20, 0x80019602, 0x00000002, 0x40149B20, + 0x80019702, 0x00000002, 0x40149B20, 0x80019802, 0x00000002, 0x40149B20, + 0x80019902, 0x00000002, 0x00293606, 0x00293406, 0x00000002, 0x00293606, + 0x00293406, 0x00000002, 0x00293606, 0x00293406, 0x00000002, 0x00293606, + 0x00293406, 0x00000002, 0x00293606, 0x00293406, 0x00000002, 0x00293606, + 0x00293606, 0x00000002, 0x00293606, 0x00293806, 0x00000002, 0x00293606, + 0x00293A06, 0x00000002, 0x00293606, 0x00293C06, 0x00000002, 0x00293606, + 0x00293E06, 0x00000002, 0x00293606, 0x00294006, 0x00000002, 0x00293606, + 0x00294206, 0x00000002, 0x00293606, 0x00294406, + // Block 6, offset 0x180 + 0x00000002, 0x00293606, 0x00294606, 0x00000002, 0x40149C20, 0x80016502, + 0x00000002, 0x40149C20, 0x80016602, 0x00000002, 0x40149C20, 0x80016702, + 0x00000002, 0x40149C20, 0x80016802, 0x00000002, 0x40149C20, 0x80016902, + 0x00000002, 0x40149C20, 0x80016A02, 0x00000002, 0x40149C20, 0x80016B02, + 0x00000002, 0x40149C20, 0x80016C02, 0x00000002, 0x40149C20, 0x80016D02, + 0x00000002, 0x40149C20, 0x80016E02, 0x00000002, 0x40149C20, 0x80016F02, + 0x00000002, 0x40149C20, 0x80017002, 0x00000002, 0x40149C20, 0x80017102, + 0x00000002, 0x40149C20, 0x80017102, 0x00000002, 0x40149C20, 0x80017102, + 0x00000002, 0x40149C20, 0x80017202, 0x00000002, 0x40149C20, 0x80017302, + 0x00000002, 0x40149C20, 0x80017402, 0x00000002, 0x40149C20, 0x80017502, + 0x00000002, 0x40149C20, 0x80017602, 0x00000002, + // Block 7, offset 0x1c0 + 0x40149C20, 0x80017702, 0x00000002, 0x40149C20, 0x80017802, 0x00000002, + 0x40149C20, 0x80017902, 0x00000002, 0x40149C20, 0x80017A02, 0x00000002, + 0x40149C20, 0x80017B02, 0x00000002, 0x40149C20, 0x80017C02, 0x00000002, + 0x00293804, 0x80017C04, 0x00000002, 0x40149C20, 0x80017D02, 0x00000002, + 0x40149C20, 0x80017E02, 0x00000002, 0x40149C20, 0x80017F02, 0x00000002, + 0x40149C20, 0x80018002, 0x00000002, 0x40149C20, 0x80018102, 0x00000002, + 0x40149C20, 0x80018202, 0x00000002, 0x40149C20, 0x80018302, 0x00000002, + 0x40149C20, 0x80018402, 0x00000002, 0x40149C20, 0x80018502, 0x00000002, + 0x40149C20, 0x80018602, 0x00000002, 0x40149C20, 0x80018702, 0x00000002, + 0x40149C20, 0x80018802, 0x00000002, 0x40149C20, 0x80018902, 0x00000002, + 0x40149C20, 0x80018A02, 0x00000002, 0x40149C20, + // Block 8, offset 0x200 + 0x80018B02, 0x00000002, 0x40149C20, 0x80018C02, 0x00000002, 0x40149C20, + 0x80018C02, 0x00000002, 0x40149C20, 0x80018C02, 0x00000002, 0x40149C20, + 0x80018C02, 0x00000002, 0x40149C20, 0x80018F02, 0x00000002, 0x40149C20, + 0x80019002, 0x00000002, 0x40149C20, 0x80019002, 0x00000002, 0x40149C20, + 0x80019002, 0x00000002, 0x40149C20, 0x80019002, 0x00000002, 0x40149C20, + 0x80019002, 0x00000002, 0x40149C20, 0x80019002, 0x00000002, 0x40149C20, + 0x80019002, 0x00000002, 0x40149C20, 0x80019002, 0x00000002, 0x40149C20, + 0x80019002, 0x00000002, 0x40149C20, 0x80019202, 0x00000002, 0x40149C20, + 0x80019302, 0x00000002, 0x40149C20, 0x80019402, 0x00000002, 0x40149C20, + 0x80019502, 0x00000002, 0x40149C20, 0x80019602, 0x00000002, 0x40149C20, + 0x80019702, 0x00000002, 0x40149C20, 0x80019802, + // Block 9, offset 0x240 + 0x00000002, 0x40149C20, 0x80019902, 0x00000002, 0x00293806, 0x00293406, + 0x00000002, 0x00293806, 0x00293406, 0x00000002, 0x40149D20, 0x80016502, + 0x00000002, 0x40149D20, 0x80016602, 0x00000002, 0x40149D20, 0x80016702, + 0x00000002, 0x40149D20, 0x80016802, 0x00000002, 0x40149D20, 0x80016902, + 0x00000002, 0x40149D20, 0x80016A02, 0x00000002, 0x40149D20, 0x80016B02, + 0x00000002, 0x40149D20, 0x80016C02, 0x00000002, 0x40149D20, 0x80016D02, + 0x00000002, 0x40149D20, 0x80016E02, 0x00000002, 0x40149D20, 0x80016F02, + 0x00000002, 0x40149D20, 0x80017002, 0x00000002, 0x40149D20, 0x80017102, + 0x00000002, 0x40149D20, 0x80017102, 0x00000002, 0x40149D20, 0x80017102, + 0x00000002, 0x40149D20, 0x80017202, 0x00000002, 0x40149D20, 0x80017302, + 0x00000002, 0x40149D20, 0x80017402, 0x00000002, + // Block 10, offset 0x280 + 0x40149D20, 0x80017502, 0x00000002, 0x40149D20, 0x80017602, 0x00000002, + 0x40149D20, 0x80017702, 0x00000002, 0x40149D20, 0x80017802, 0x00000002, + 0x40149D20, 0x80017902, 0x00000002, 0x40149D20, 0x80017A02, 0x00000002, + 0x40149D20, 0x80017B02, 0x00000002, 0x40149D20, 0x80017C02, 0x00000002, + 0x00293A04, 0x80017C04, 0x00000002, 0x40149D20, 0x80017D02, 0x00000002, + 0x40149D20, 0x80017E02, 0x00000002, 0x40149D20, 0x80017F02, 0x00000002, + 0x40149D20, 0x80018002, 0x00000002, 0x40149D20, 0x80018102, 0x00000002, + 0x40149D20, 0x80018202, 0x00000002, 0x40149D20, 0x80018302, 0x00000002, + 0x40149D20, 0x80018402, 0x00000002, 0x40149D20, 0x80018502, 0x00000002, + 0x40149D20, 0x80018602, 0x00000002, 0x40149D20, 0x80018702, 0x00000002, + 0x40149D20, 0x80018802, 0x00000002, 0x40149D20, + // Block 11, offset 0x2c0 + 0x80018902, 0x00000002, 0x40149D20, 0x80018A02, 0x00000002, 0x40149D20, + 0x80018B02, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019002, 0x00000002, 0x40149D20, + 0x80019002, 0x00000002, 0x40149D20, 0x80019202, 0x00000002, 0x40149D20, + 0x80019302, 0x00000002, 0x40149D20, 0x80019402, 0x00000002, 0x40149D20, + 0x80019502, 0x00000002, 0x40149D20, 0x80019602, + // Block 12, offset 0x300 + 0x00000002, 0x40149D20, 0x80019702, 0x00000002, 0x40149D20, 0x80019802, + 0x00000002, 0x40149D20, 0x80019902, 0x00000002, 0x00293A06, 0x00293406, + 0x00000002, 0x40149E20, 0x80016502, 0x00000002, 0x40149E20, 0x80016602, + 0x00000002, 0x40149E20, 0x80016702, 0x00000002, 0x40149E20, 0x80016802, + 0x00000002, 0x40149E20, 0x80016902, 0x00000002, 0x40149E20, 0x80016A02, + 0x00000002, 0x40149E20, 0x80016B02, 0x00000002, 0x40149E20, 0x80016C02, + 0x00000002, 0x40149E20, 0x80016D02, 0x00000002, 0x40149E20, 0x80016E02, + 0x00000002, 0x40149E20, 0x80016F02, 0x00000002, 0x40149E20, 0x80017002, + 0x00000002, 0x40149E20, 0x80017102, 0x00000002, 0x40149E20, 0x80017202, + 0x00000002, 0x40149E20, 0x80017302, 0x00000002, 0x40149E20, 0x80017402, + 0x00000002, 0x40149E20, 0x80017502, 0x00000002, + // Block 13, offset 0x340 + 0x40149E20, 0x80017602, 0x00000002, 0x40149E20, 0x80017702, 0x00000002, + 0x40149E20, 0x80017802, 0x00000002, 0x40149E20, 0x80017902, 0x00000002, + 0x40149E20, 0x80017A02, 0x00000002, 0x40149E20, 0x80017B02, 0x00000002, + 0x40149E20, 0x80017C02, 0x00000002, 0x00293C04, 0x80017C04, 0x00000002, + 0x40149E20, 0x80017D02, 0x00000002, 0x40149E20, 0x80017E02, 0x00000002, + 0x40149E20, 0x80017F02, 0x00000002, 0x40149E20, 0x80018002, 0x00000002, + 0x40149E20, 0x80018102, 0x00000002, 0x40149E20, 0x80018202, 0x00000002, + 0x40149E20, 0x80018302, 0x00000002, 0x40149E20, 0x80018402, 0x00000002, + 0x40149E20, 0x80018502, 0x00000002, 0x40149E20, 0x80018602, 0x00000002, + 0x40149E20, 0x80018702, 0x00000002, 0x40149E20, 0x80018802, 0x00000002, + 0x40149E20, 0x80018902, 0x00000002, 0x40149E20, + // Block 14, offset 0x380 + 0x80018A02, 0x00000002, 0x40149E20, 0x80018B02, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019002, 0x00000002, 0x40149E20, + 0x80019002, 0x00000002, 0x40149E20, 0x80019402, 0x00000002, 0x40149E20, + 0x80019502, 0x00000002, 0x40149E20, 0x80019602, 0x00000002, 0x40149E20, + 0x80019702, 0x00000002, 0x40149E20, 0x80019802, + // Block 15, offset 0x3c0 + 0x00000002, 0x40149E20, 0x80019902, 0x00000002, 0x00293C06, 0x00293406, + 0x00000002, 0x40149F20, 0x80016502, 0x00000002, 0x40149F20, 0x80016602, + 0x00000002, 0x40149F20, 0x80016702, 0x00000002, 0x40149F20, 0x80016802, + 0x00000002, 0x40149F20, 0x80016902, 0x00000002, 0x40149F20, 0x80016A02, + 0x00000002, 0x40149F20, 0x80016B02, 0x00000002, 0x40149F20, 0x80016C02, + 0x00000002, 0x40149F20, 0x80016D02, 0x00000002, 0x40149F20, 0x80016E02, + 0x00000002, 0x40149F20, 0x80016F02, 0x00000002, 0x40149F20, 0x80017002, + 0x00000002, 0x40149F20, 0x80017102, 0x00000002, 0x40149F20, 0x80017202, + 0x00000002, 0x40149F20, 0x80017302, 0x00000002, 0x40149F20, 0x80017402, + 0x00000002, 0x40149F20, 0x80017502, 0x00000002, 0x40149F20, 0x80017602, + 0x00000002, 0x40149F20, 0x80017702, 0x00000002, + // Block 16, offset 0x400 + 0x40149F20, 0x80017802, 0x00000002, 0x40149F20, 0x80017902, 0x00000002, + 0x40149F20, 0x80017A02, 0x00000002, 0x40149F20, 0x80017B02, 0x00000002, + 0x40149F20, 0x80017C02, 0x00000002, 0x00293E04, 0x80017C04, 0x00000002, + 0x40149F20, 0x80017D02, 0x00000002, 0x40149F20, 0x80017E02, 0x00000002, + 0x40149F20, 0x80017F02, 0x00000002, 0x40149F20, 0x80018002, 0x00000002, + 0x40149F20, 0x80018102, 0x00000002, 0x40149F20, 0x80018202, 0x00000002, + 0x40149F20, 0x80018302, 0x00000002, 0x40149F20, 0x80018402, 0x00000002, + 0x40149F20, 0x80018502, 0x00000002, 0x40149F20, 0x80018602, 0x00000002, + 0x40149F20, 0x80018702, 0x00000002, 0x40149F20, 0x80018802, 0x00000002, + 0x40149F20, 0x80018902, 0x00000002, 0x40149F20, 0x80018A02, 0x00000002, + 0x40149F20, 0x80018B02, 0x00000002, 0x40149F20, + // Block 17, offset 0x440 + 0x80018C02, 0x00000002, 0x40149F20, 0x80018C02, 0x00000002, 0x40149F20, + 0x80018C02, 0x00000002, 0x40149F20, 0x80018C02, 0x00000002, 0x40149F20, + 0x80018C02, 0x00000002, 0x40149F20, 0x80018E02, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019002, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019002, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019002, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019002, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019002, 0x00000002, 0x40149F20, + 0x80019002, 0x00000002, 0x40149F20, 0x80019602, 0x00000002, 0x40149F20, + 0x80019702, 0x00000002, 0x40149F20, 0x80019902, 0x00000002, 0x00293E06, + 0x00293406, 0x00000002, 0x4014A020, 0x80016502, + // Block 18, offset 0x480 + 0x00000002, 0x4014A020, 0x80016602, 0x00000002, 0x4014A020, 0x80016702, + 0x00000002, 0x4014A020, 0x80016802, 0x00000002, 0x4014A020, 0x80016902, + 0x00000002, 0x4014A020, 0x80016A02, 0x00000002, 0x4014A020, 0x80016B02, + 0x00000002, 0x4014A020, 0x80016C02, 0x00000002, 0x4014A020, 0x80016D02, + 0x00000002, 0x4014A020, 0x80016E02, 0x00000002, 0x4014A020, 0x80016F02, + 0x00000002, 0x4014A020, 0x80017002, 0x00000002, 0x4014A020, 0x80017102, + 0x00000002, 0x4014A020, 0x80017202, 0x00000002, 0x4014A020, 0x80017302, + 0x00000002, 0x4014A020, 0x80017402, 0x00000002, 0x4014A020, 0x80017502, + 0x00000002, 0x4014A020, 0x80017602, 0x00000002, 0x4014A020, 0x80017702, + 0x00000002, 0x4014A020, 0x80017802, 0x00000002, 0x4014A020, 0x80017902, + 0x00000002, 0x4014A020, 0x80017A02, 0x00000002, + // Block 19, offset 0x4c0 + 0x4014A020, 0x80017B02, 0x00000002, 0x4014A020, 0x80017C02, 0x00000002, + 0x00294004, 0x80017C04, 0x00000002, 0x4014A020, 0x80017D02, 0x00000002, + 0x4014A020, 0x80017E02, 0x00000002, 0x4014A020, 0x80017F02, 0x00000002, + 0x4014A020, 0x80018002, 0x00000002, 0x4014A020, 0x80018102, 0x00000002, + 0x4014A020, 0x80018202, 0x00000002, 0x4014A020, 0x80018302, 0x00000002, + 0x4014A020, 0x80018402, 0x00000002, 0x4014A020, 0x80018502, 0x00000002, + 0x4014A020, 0x80018602, 0x00000002, 0x4014A020, 0x80018702, 0x00000002, + 0x4014A020, 0x80018802, 0x00000002, 0x4014A020, 0x80018902, 0x00000002, + 0x4014A020, 0x80018A02, 0x00000002, 0x4014A020, 0x80018B02, 0x00000002, + 0x4014A020, 0x80018D02, 0x00000002, 0x4014A020, 0x80019002, 0x00000002, + 0x4014A020, 0x80019002, 0x00000002, 0x4014A020, + // Block 20, offset 0x500 + 0x80019002, 0x00000002, 0x4014A020, 0x80019002, 0x00000002, 0x4014A020, + 0x80019002, 0x00000002, 0x4014A020, 0x80019002, 0x00000002, 0x4014A020, + 0x80019002, 0x00000002, 0x4014A020, 0x80019602, 0x00000002, 0x4014A020, + 0x80019702, 0x00000002, 0x4014A020, 0x80019902, 0x00000002, 0x00294006, + 0x00293406, 0x00000002, 0x4014A120, 0x80016502, 0x00000002, 0x4014A120, + 0x80016602, 0x00000002, 0x4014A120, 0x80016702, 0x00000002, 0x4014A120, + 0x80016802, 0x00000002, 0x4014A120, 0x80016902, 0x00000002, 0x4014A120, + 0x80016A02, 0x00000002, 0x4014A120, 0x80016B02, 0x00000002, 0x4014A120, + 0x80016C02, 0x00000002, 0x4014A120, 0x80016D02, 0x00000002, 0x4014A120, + 0x80016E02, 0x00000002, 0x4014A120, 0x80016F02, 0x00000002, 0x4014A120, + 0x80017002, 0x00000002, 0x4014A120, 0x80017102, + // Block 21, offset 0x540 + 0x00000002, 0x4014A120, 0x80017202, 0x00000002, 0x4014A120, 0x80017302, + 0x00000002, 0x4014A120, 0x80017402, 0x00000002, 0x4014A120, 0x80017502, + 0x00000002, 0x4014A120, 0x80017602, 0x00000002, 0x4014A120, 0x80017702, + 0x00000002, 0x4014A120, 0x80017802, 0x00000002, 0x4014A120, 0x80017902, + 0x00000002, 0x4014A120, 0x80017A02, 0x00000002, 0x4014A120, 0x80017B02, + 0x00000002, 0x4014A120, 0x80017C02, 0x00000002, 0x00294204, 0x80017C04, + 0x00000002, 0x4014A120, 0x80017D02, 0x00000002, 0x4014A120, 0x80017E02, + 0x00000002, 0x4014A120, 0x80017F02, 0x00000002, 0x4014A120, 0x80018002, + 0x00000002, 0x4014A120, 0x80018102, 0x00000002, 0x4014A120, 0x80018202, + 0x00000002, 0x4014A120, 0x80018302, 0x00000002, 0x4014A120, 0x80018402, + 0x00000002, 0x4014A120, 0x80018502, 0x00000002, + // Block 22, offset 0x580 + 0x4014A120, 0x80018602, 0x00000002, 0x4014A120, 0x80018702, 0x00000002, + 0x4014A120, 0x80018802, 0x00000002, 0x4014A120, 0x80018902, 0x00000002, + 0x4014A120, 0x80018A02, 0x00000002, 0x4014A120, 0x80018B02, 0x00000002, + 0x4014A120, 0x80019002, 0x00000002, 0x4014A120, 0x80019002, 0x00000002, + 0x4014A120, 0x80019002, 0x00000002, 0x4014A120, 0x80019002, 0x00000002, + 0x4014A120, 0x80019002, 0x00000002, 0x4014A120, 0x80019002, 0x00000002, + 0x4014A120, 0x80019002, 0x00000002, 0x4014A120, 0x80019002, 0x00000002, + 0x4014A120, 0x80019602, 0x00000002, 0x4014A120, 0x80019702, 0x00000002, + 0x4014A120, 0x80019902, 0x00000002, 0x00294206, 0x00293406, 0x00000002, + 0x4014A220, 0x80016502, 0x00000002, 0x4014A220, 0x80016602, 0x00000002, + 0x4014A220, 0x80016702, 0x00000002, 0x4014A220, + // Block 23, offset 0x5c0 + 0x80016802, 0x00000002, 0x4014A220, 0x80016902, 0x00000002, 0x4014A220, + 0x80016A02, 0x00000002, 0x4014A220, 0x80016B02, 0x00000002, 0x4014A220, + 0x80016C02, 0x00000002, 0x4014A220, 0x80016D02, 0x00000002, 0x4014A220, + 0x80016E02, 0x00000002, 0x4014A220, 0x80016F02, 0x00000002, 0x4014A220, + 0x80017002, 0x00000002, 0x4014A220, 0x80017102, 0x00000002, 0x4014A220, + 0x80017202, 0x00000002, 0x4014A220, 0x80017302, 0x00000002, 0x4014A220, + 0x80017402, 0x00000002, 0x4014A220, 0x80017502, 0x00000002, 0x4014A220, + 0x80017602, 0x00000002, 0x4014A220, 0x80017702, 0x00000002, 0x4014A220, + 0x80017802, 0x00000002, 0x4014A220, 0x80017902, 0x00000002, 0x4014A220, + 0x80017A02, 0x00000002, 0x4014A220, 0x80017B02, 0x00000002, 0x4014A220, + 0x80017C02, 0x00000002, 0x00294404, 0x80017C04, + // Block 24, offset 0x600 + 0x00000002, 0x4014A220, 0x80017D02, 0x00000002, 0x4014A220, 0x80017E02, + 0x00000002, 0x4014A220, 0x80017F02, 0x00000002, 0x4014A220, 0x80018002, + 0x00000002, 0x4014A220, 0x80018102, 0x00000002, 0x4014A220, 0x80018202, + 0x00000002, 0x4014A220, 0x80018302, 0x00000002, 0x4014A220, 0x80018402, + 0x00000002, 0x4014A220, 0x80018502, 0x00000002, 0x4014A220, 0x80018602, + 0x00000002, 0x4014A220, 0x80018702, 0x00000002, 0x4014A220, 0x80018802, + 0x00000002, 0x4014A220, 0x80018902, 0x00000002, 0x4014A220, 0x80018A02, + 0x00000002, 0x4014A220, 0x80018B02, 0x00000002, 0x4014A220, 0x80019002, + 0x00000002, 0x4014A220, 0x80019002, 0x00000002, 0x4014A220, 0x80019002, + 0x00000002, 0x4014A220, 0x80019002, 0x00000002, 0x4014A220, 0x80019002, + 0x00000002, 0x4014A220, 0x80019002, 0x00000002, + // Block 25, offset 0x640 + 0x4014A220, 0x80019002, 0x00000002, 0x4014A220, 0x80019602, 0x00000002, + 0x4014A220, 0x80019702, 0x00000002, 0x4014A220, 0x80019902, 0x00000002, + 0x00294406, 0x00293406, 0x00000002, 0x4014A320, 0x80016502, 0x00000002, + 0x4014A320, 0x80016602, 0x00000002, 0x4014A320, 0x80016702, 0x00000002, + 0x4014A320, 0x80016802, 0x00000002, 0x4014A320, 0x80016902, 0x00000002, + 0x4014A320, 0x80016A02, 0x00000002, 0x4014A320, 0x80016B02, 0x00000002, + 0x4014A320, 0x80016C02, 0x00000002, 0x4014A320, 0x80016D02, 0x00000002, + 0x4014A320, 0x80016E02, 0x00000002, 0x4014A320, 0x80016F02, 0x00000002, + 0x4014A320, 0x80017002, 0x00000002, 0x4014A320, 0x80017102, 0x00000002, + 0x4014A320, 0x80017202, 0x00000002, 0x4014A320, 0x80017302, 0x00000002, + 0x4014A320, 0x80017402, 0x00000002, 0x4014A320, + // Block 26, offset 0x680 + 0x80017502, 0x00000002, 0x4014A320, 0x80017602, 0x00000002, 0x4014A320, + 0x80017702, 0x00000002, 0x4014A320, 0x80017802, 0x00000002, 0x4014A320, + 0x80017902, 0x00000002, 0x4014A320, 0x80017A02, 0x00000002, 0x4014A320, + 0x80017B02, 0x00000002, 0x4014A320, 0x80017C02, 0x00000002, 0x00294604, + 0x80017C04, 0x00000002, 0x4014A320, 0x80017D02, 0x00000002, 0x4014A320, + 0x80017E02, 0x00000002, 0x4014A320, 0x80017F02, 0x00000002, 0x4014A320, + 0x80018002, 0x00000002, 0x4014A320, 0x80018102, 0x00000002, 0x4014A320, + 0x80018202, 0x00000002, 0x4014A320, 0x80018302, 0x00000002, 0x4014A320, + 0x80018402, 0x00000002, 0x4014A320, 0x80018502, 0x00000002, 0x4014A320, + 0x80018602, 0x00000002, 0x4014A320, 0x80018702, 0x00000002, 0x4014A320, + 0x80018802, 0x00000002, 0x4014A320, 0x80018902, + // Block 27, offset 0x6c0 + 0x00000002, 0x4014A320, 0x80018A02, 0x00000002, 0x4014A320, 0x80018B02, + 0x00000002, 0x4014A320, 0x80019002, 0x00000002, 0x4014A320, 0x80019002, + 0x00000002, 0x4014A320, 0x80019002, 0x00000002, 0x4014A320, 0x80019002, + 0x00000002, 0x4014A320, 0x80019002, 0x00000002, 0x4014A320, 0x80019002, + 0x00000002, 0x4014A320, 0x80019002, 0x00000002, 0x4014A320, 0x80019002, + 0x00000002, 0x4014A320, 0x80019002, 0x00000002, 0x4014A320, 0x80019602, + 0x00000002, 0x4014A320, 0x80019702, 0x00000002, 0x4014A320, 0x80019902, + 0x00000002, 0x002B4604, 0x80015F04, 0x00000002, 0x002B4604, 0x002B4604, + 0x00000002, 0x002B460A, 0x002B460A, 0x00000002, 0x002B461D, 0x002B721D, + 0x00000003, 0x002B4604, 0x80015F04, 0x002BFE1F, 0x00000003, 0x002B4604, + 0x80015F04, 0x002BFE1F, 0x00000003, 0x002B460A, + // Block 28, offset 0x700 + 0x80015F04, 0x002BFE1F, 0x00000002, 0x002B4604, 0x002E4804, 0x00000002, + 0x002B4604, 0x002E4804, 0x00000002, 0x002B460A, 0x002E480A, 0x00000002, + 0x002B4604, 0x002FD204, 0x00000002, 0x002B460A, 0x002FD20A, 0x00000002, + 0x002B4604, 0x00302404, 0x00000002, 0x002B4604, 0x00302404, 0x00000002, + 0x002B460A, 0x0030240A, 0x00000003, 0x002B4604, 0x80015F04, 0x0030241F, + 0x00000003, 0x002B460A, 0x80015F04, 0x0030241F, 0x00000002, 0x002B4604, + 0x00306604, 0x00000002, 0x002B460A, 0x0030660A, 0x00000002, 0x002BA204, + 0x80005604, 0x00000002, 0x002BA21D, 0x002D881D, 0x00000004, 0x002BA21D, + 0x002E481D, 0x002E481F, 0x002D881F, 0x00000002, 0x4015E420, 0x80007D02, + 0x00000002, 0x002BC808, 0x80007D02, 0x00000002, 0x002BC804, 0x80015F04, + 0x00000002, 0x002BC804, 0x80015F04, 0x00000002, + // Block 29, offset 0x740 + 0x002BC80A, 0x80015F04, 0x00000002, 0x002BC804, 0x80016004, 0x00000002, + 0x002BC804, 0x80016004, 0x00000002, 0x002BC80A, 0x80016004, 0x00000002, + 0x002BC804, 0x002B7204, 0x00000002, 0x002BC804, 0x00308804, 0x00000002, + 0x002BC804, 0x0030AE04, 0x00000002, 0x002BC804, 0x0030C204, 0x00000002, + 0x002C6E04, 0x80016004, 0x00000002, 0x002C6E0A, 0x80016004, 0x00000002, + 0x002C6E04, 0x002E4004, 0x00000004, 0x002C6E1D, 0x002EE01D, 0x002BFE1F, + 0x002BFE1F, 0x00000002, 0x002C8804, 0x80006104, 0x00000002, 0x002C880A, + 0x80006104, 0x00000002, 0x002C8804, 0x80016004, 0x00000002, 0x002C880A, + 0x80016004, 0x00000002, 0x40166720, 0x80007D02, 0x00000002, 0x002CCE08, + 0x80007D02, 0x00000002, 0x002D001D, 0x002BA21D, 0x00000002, 0x002D001D, + 0x002BC81D, 0x00000002, 0x002D6404, 0x80006104, + // Block 30, offset 0x780 + 0x00000002, 0x002D640A, 0x80006104, 0x00000002, 0x4016C420, 0x80007D02, + 0x00000002, 0x002D8808, 0x80007D02, 0x00000002, 0x4016C420, 0x80015F02, + 0x00000002, 0x4016C420, 0x80015F02, 0x00000002, 0x002D8808, 0x80015F02, + 0x00000002, 0x002D8808, 0x80015F02, 0x00000002, 0x002D8804, 0x002D8804, + 0x00000002, 0x002D880A, 0x002D880A, 0x00000002, 0x002D8804, 0x002F4C04, + 0x00000002, 0x002D8804, 0x00308804, 0x00000002, 0x002E0404, 0x80006104, + 0x00000002, 0x002E040A, 0x80006104, 0x00000003, 0x002E041D, 0x002BFE1D, + 0x0030481F, 0x00000002, 0x002E041D, 0x002C881D, 0x00000002, 0x40172420, + 0x80005402, 0x00000002, 0x002E4808, 0x80005402, 0x00000003, 0x002E4804, + 0x80015F04, 0x002BFE1F, 0x00000003, 0x002E480A, 0x80015F04, 0x002BFE1F, + 0x00000002, 0x002E481D, 0x002D641D, 0x00000002, + // Block 31, offset 0x7c0 + 0x002E4804, 0x002E4804, 0x00000002, 0x002E480A, 0x002E480A, 0x00000002, + 0x002E921D, 0x002B461D, 0x00000002, 0x002EBC04, 0x002E9204, 0x00000002, + 0x002EE004, 0x80006104, 0x00000002, 0x002EE00A, 0x80006104, 0x00000002, + 0x002EE004, 0x80016004, 0x00000002, 0x002EE00A, 0x80016004, 0x00000002, + 0x002F4C04, 0x80006104, 0x00000002, 0x002F4C0A, 0x80006104, 0x00000002, + 0x002F4C04, 0x80016004, 0x00000002, 0x002F4C04, 0x80016004, 0x00000002, + 0x002F4C04, 0x80016004, 0x00000002, 0x002F4C0A, 0x80016004, 0x00000002, + 0x002F4C1D, 0x002B461D, 0x00000003, 0x002F4C1D, 0x002E481D, 0x002F4C1F, + 0x00000003, 0x002F4C04, 0x80015F04, 0x002F4C1F, 0x00000003, 0x002F4C0A, + 0x80015F04, 0x002F4C1F, 0x00000003, 0x002F4C04, 0x80016004, 0x002F921F, + 0x00000002, 0x002F9204, 0x80016004, 0x00000002, + // Block 32, offset 0x800 + 0x002F920A, 0x80016004, 0x00000002, 0x002F9204, 0x002BBC04, 0x00000003, + 0x002F9204, 0x80015F04, 0x002CCE1F, 0x00000002, 0x002F9204, 0x002F4C04, + 0x00000002, 0x002F9204, 0x002F4C04, 0x00000002, 0x002F9204, 0x002F6E04, + 0x00000002, 0x002F9204, 0x00308804, 0x00000002, 0x002F920A, 0x00308804, + 0x00000003, 0x002FD21D, 0x002E921D, 0x0002B01F, 0x00000002, 0x0030241D, + 0x002F4C1D, 0x00000002, 0x00302404, 0x00306604, 0x00000002, 0x0030240A, + 0x0030660A, 0x00000002, 0x0030481D, 0x002BA21D, 0x00000002, 0x00308804, + 0x00304804, 0x00000003, 0x0031D604, 0x0031B804, 0x0031D21F, 0x00000003, + 0x0031D60A, 0x0031B804, 0x0031D21F, 0x00000003, 0x00322604, 0x00321004, + 0x0032241F, 0x00000002, 0x0032C604, 0x80016004, 0x00000002, 0x0032C60A, + 0x80016004, 0x00000002, 0x00349E04, 0x0034B004, + // Block 33, offset 0x840 + 0x00000002, 0x0037F404, 0x0037F404, 0x00000002, 0x0037F404, 0x0037FC04, + 0x00000002, 0x0037FC04, 0x0037FC04, 0x00000002, 0x00387604, 0x80016004, + 0x00000002, 0x00388A19, 0x00388C19, 0x00000002, 0x00388A1A, 0x00388C1A, + 0x00000002, 0x00388A17, 0x0038B617, 0x00000002, 0x00388A1A, 0x0038B61A, + 0x00000002, 0x00388A17, 0x0038C217, 0x00000002, 0x00388A1A, 0x0038C21A, + 0x00000002, 0x00388A17, 0x0038C417, 0x00000002, 0x00388A19, 0x0038F419, + 0x00000002, 0x00388A19, 0x0038F619, 0x00000002, 0x00388A17, 0x00399417, + 0x00000002, 0x00388A18, 0x00399418, 0x00000002, 0x00388A19, 0x00399419, + 0x00000002, 0x00388A1A, 0x0039941A, 0x00000002, 0x00388A19, 0x00399A19, + 0x00000002, 0x00388A17, 0x0039AC17, 0x00000002, 0x00388A18, 0x0039AC18, + 0x00000002, 0x00388A19, 0x0039B619, 0x00000002, + // Block 34, offset 0x880 + 0x00388A1A, 0x0039B61A, 0x00000002, 0x00388A19, 0x0039B819, 0x00000002, + 0x00388A1A, 0x0039B81A, 0x00000002, 0x00388A19, 0x0039BE19, 0x00000002, + 0x00388A1A, 0x0039BE1A, 0x00000002, 0x00388A19, 0x0039C019, 0x00000002, + 0x00388A1A, 0x0039C01A, 0x00000002, 0x00388A19, 0x0039C219, 0x00000002, + 0x00388A1A, 0x0039C21A, 0x00000002, 0x00388A17, 0x0039D017, 0x00000002, + 0x00388A19, 0x0039D019, 0x00000002, 0x00388A19, 0x0039D019, 0x00000002, + 0x00388A1A, 0x0039D01A, 0x00000002, 0x00388A1A, 0x0039D01A, 0x00000002, + 0x00388A19, 0x0039D219, 0x00000002, 0x00388A1A, 0x0039D21A, 0x00000002, + 0x00388A17, 0x0039DA17, 0x00000002, 0x00388A19, 0x0039DA19, 0x00000002, + 0x00388A1A, 0x0039DA1A, 0x00000002, 0x00398819, 0x00387819, 0x00000002, + 0x0039881A, 0x0038781A, 0x00000002, 0x00398819, + // Block 35, offset 0x8c0 + 0x00387A19, 0x00000002, 0x0039881A, 0x00387A1A, 0x00000002, 0x00398819, + 0x00388219, 0x00000002, 0x0039881A, 0x0038821A, 0x00000002, 0x00399404, + 0x80016004, 0x00000002, 0x0039F404, 0x80016204, 0x00000002, 0x0039F604, + 0x80016004, 0x00000002, 0x0039F604, 0x80016204, 0x00000002, 0x0039FA04, + 0x80016204, 0x00000002, 0x003A0604, 0x80016004, 0x00000002, 0x003A1A04, + 0x80016004, 0x00000002, 0x003AD604, 0x80015F04, 0x00000002, 0x003AD804, + 0x80015F04, 0x00000002, 0x003ADC04, 0x80015F04, 0x00000002, 0x003FF004, + 0x00403204, 0x00000002, 0x00435C04, 0x0043CA04, 0x00000002, 0x00437804, + 0x0043CA04, 0x00000002, 0x00438204, 0x0043CA04, 0x00000002, 0x00439204, + 0x0043CA04, 0x00000002, 0x00439204, 0x0043CA04, 0x00000002, 0x00439404, + 0x0043CA04, 0x00000002, 0x0043A004, 0x0043CA04, + // Block 36, offset 0x900 + 0x00000002, 0x40239520, 0x00479E1F, 0x00000002, 0x40239520, 0x0047A01F, + 0x00000002, 0x40239520, 0x0047A21F, 0x00000002, 0x40239520, 0x0047A41F, + 0x00000002, 0x40239520, 0x0047A61F, 0x00000002, 0x40239620, 0x00479E1F, + 0x00000002, 0x40239620, 0x0047A01F, 0x00000002, 0x40239620, 0x0047A21F, + 0x00000002, 0x40239620, 0x0047A41F, 0x00000002, 0x40239620, 0x0047A61F, + 0x00000002, 0x40239720, 0x00479E1F, 0x00000002, 0x40239720, 0x0047A01F, + 0x00000002, 0x40239720, 0x0047A21F, 0x00000002, 0x40239720, 0x0047A41F, + 0x00000002, 0x40239720, 0x0047A61F, 0x00000002, 0x40239820, 0x00479E1F, + 0x00000002, 0x40239820, 0x0047A01F, 0x00000002, 0x40239820, 0x0047A21F, + 0x00000002, 0x40239820, 0x0047A41F, 0x00000002, 0x40239820, 0x0047A61F, + 0x00000002, 0x40239920, 0x00479E1F, 0x00000002, + // Block 37, offset 0x940 + 0x40239920, 0x0047A01F, 0x00000002, 0x40239920, 0x0047A21F, 0x00000002, + 0x40239920, 0x0047A41F, 0x00000002, 0x40239920, 0x0047A61F, 0x00000002, + 0x40239A20, 0x00479E1F, 0x00000002, 0x40239A20, 0x0047A01F, 0x00000002, + 0x40239A20, 0x0047A21F, 0x00000002, 0x40239A20, 0x0047A41F, 0x00000002, + 0x40239A20, 0x0047A61F, 0x00000002, 0x40239B20, 0x00479E1F, 0x00000002, + 0x40239B20, 0x0047A01F, 0x00000002, 0x40239B20, 0x0047A21F, 0x00000002, + 0x40239B20, 0x0047A41F, 0x00000002, 0x40239B20, 0x0047A61F, 0x00000002, + 0x40239C20, 0x00479E1F, 0x00000002, 0x40239C20, 0x0047A01F, 0x00000002, + 0x40239C20, 0x0047A21F, 0x00000002, 0x40239C20, 0x0047A41F, 0x00000002, + 0x40239C20, 0x0047A61F, 0x00000002, 0x40239D20, 0x00479E1F, 0x00000002, + 0x40239D20, 0x0047A01F, 0x00000002, 0x40239D20, + // Block 38, offset 0x980 + 0x0047A21F, 0x00000002, 0x40239D20, 0x0047A41F, 0x00000002, 0x40239D20, + 0x0047A61F, 0x00000002, 0x40239E20, 0x00479E1F, 0x00000002, 0x40239E20, + 0x0047A01F, 0x00000002, 0x40239E20, 0x0047A21F, 0x00000002, 0x40239E20, + 0x0047A41F, 0x00000002, 0x40239E20, 0x0047A61F, 0x00000002, 0x40239F20, + 0x00479E1F, 0x00000002, 0x40239F20, 0x0047A01F, 0x00000002, 0x40239F20, + 0x0047A21F, 0x00000002, 0x40239F20, 0x0047A41F, 0x00000002, 0x40239F20, + 0x0047A61F, 0x00000002, 0x4023A020, 0x00479E1F, 0x00000002, 0x4023A020, + 0x0047A01F, 0x00000002, 0x4023A020, 0x0047A21F, 0x00000002, 0x4023A020, + 0x0047A41F, 0x00000002, 0x4023A020, 0x0047A61F, 0x00000002, 0x4023A120, + 0x00479E1F, 0x00000002, 0x4023A120, 0x0047A01F, 0x00000002, 0x4023A120, + 0x0047A21F, 0x00000002, 0x4023A120, 0x0047A41F, + // Block 39, offset 0x9c0 + 0x00000002, 0x4023A120, 0x0047A61F, 0x00000002, 0x4023A220, 0x00479E1F, + 0x00000002, 0x4023A220, 0x0047A01F, 0x00000002, 0x4023A220, 0x0047A21F, + 0x00000002, 0x4023A220, 0x0047A41F, 0x00000002, 0x4023A220, 0x0047A61F, + 0x00000002, 0x4023A320, 0x00479E1F, 0x00000002, 0x4023A320, 0x0047A01F, + 0x00000002, 0x4023A320, 0x0047A21F, 0x00000002, 0x4023A320, 0x0047A41F, + 0x00000002, 0x4023A320, 0x0047A61F, 0x00000002, 0x4023A420, 0x00479E1F, + 0x00000002, 0x4023A420, 0x0047A01F, 0x00000002, 0x4023A420, 0x0047A21F, + 0x00000002, 0x4023A420, 0x0047A41F, 0x00000002, 0x4023A420, 0x0047A61F, + 0x00000002, 0x4023A520, 0x00479E1F, 0x00000002, 0x4023A520, 0x0047A01F, + 0x00000002, 0x4023A520, 0x0047A21F, 0x00000002, 0x4023A520, 0x0047A41F, + 0x00000002, 0x4023A520, 0x0047A61F, 0x00000002, + // Block 40, offset 0xa00 + 0x4023A620, 0x00479E1F, 0x00000002, 0x4023A620, 0x0047A01F, 0x00000002, + 0x4023A620, 0x0047A21F, 0x00000002, 0x4023A620, 0x0047A41F, 0x00000002, + 0x4023A620, 0x0047A61F, 0x00000002, 0x4023A720, 0x00479E1F, 0x00000002, + 0x4023A720, 0x0047A01F, 0x00000002, 0x4023A720, 0x0047A21F, 0x00000002, + 0x4023A720, 0x0047A41F, 0x00000002, 0x4023A720, 0x0047A61F, 0x00000002, + 0x4023A820, 0x00479E1F, 0x00000002, 0x4023A820, 0x0047A01F, 0x00000002, + 0x4023A820, 0x0047A21F, 0x00000002, 0x4023A820, 0x0047A41F, 0x00000002, + 0x4023A820, 0x0047A61F, 0x00000002, 0x4023A920, 0x00479E1F, 0x00000002, + 0x4023A920, 0x0047A01F, 0x00000002, 0x4023A920, 0x0047A21F, 0x00000002, + 0x4023A920, 0x0047A41F, 0x00000002, 0x4023A920, 0x0047A61F, 0x00000002, + 0x4023AA20, 0x00479E1F, 0x00000002, 0x4023AA20, + // Block 41, offset 0xa40 + 0x0047A01F, 0x00000002, 0x4023AA20, 0x0047A21F, 0x00000002, 0x4023AA20, + 0x0047A41F, 0x00000002, 0x4023AA20, 0x0047A61F, 0x00000002, 0x4023AB20, + 0x00479E1F, 0x00000002, 0x4023AB20, 0x0047A01F, 0x00000002, 0x4023AB20, + 0x0047A21F, 0x00000002, 0x4023AB20, 0x0047A41F, 0x00000002, 0x4023AB20, + 0x0047A61F, 0x00000002, 0x4023AC20, 0x00479E1F, 0x00000002, 0x4023AC20, + 0x0047A01F, 0x00000002, 0x4023AC20, 0x0047A21F, 0x00000002, 0x4023AC20, + 0x0047A41F, 0x00000002, 0x4023AC20, 0x0047A61F, 0x00000002, 0x4023AD20, + 0x00479E1F, 0x00000002, 0x4023AD20, 0x0047A01F, 0x00000002, 0x4023AD20, + 0x0047A21F, 0x00000002, 0x4023AD20, 0x0047A41F, 0x00000002, 0x4023AD20, + 0x0047A61F, 0x00000002, 0x4023AE20, 0x00479E1F, 0x00000002, 0x4023AE20, + 0x0047A01F, 0x00000002, 0x4023AE20, 0x0047A21F, + // Block 42, offset 0xa80 + 0x00000002, 0x4023AE20, 0x0047A41F, 0x00000002, 0x4023AE20, 0x0047A61F, + 0x00000002, 0x4023AF20, 0x00479E1F, 0x00000002, 0x4023AF20, 0x0047A01F, + 0x00000002, 0x4023AF20, 0x0047A21F, 0x00000002, 0x4023AF20, 0x0047A41F, + 0x00000002, 0x4023AF20, 0x0047A61F, 0x00000002, 0x4023B020, 0x00479E1F, + 0x00000002, 0x4023B020, 0x0047A01F, 0x00000002, 0x4023B020, 0x0047A21F, + 0x00000002, 0x4023B020, 0x0047A41F, 0x00000002, 0x4023B020, 0x0047A61F, + 0x00000002, 0x4023B120, 0x00479E1F, 0x00000002, 0x4023B120, 0x0047A01F, + 0x00000002, 0x4023B120, 0x0047A21F, 0x00000002, 0x4023B120, 0x0047A41F, + 0x00000002, 0x4023B120, 0x0047A61F, 0x00000002, 0x4023B220, 0x00479E1F, + 0x00000002, 0x4023B220, 0x0047A01F, 0x00000002, 0x4023B220, 0x0047A21F, + 0x00000002, 0x4023B220, 0x0047A41F, 0x00000002, + // Block 43, offset 0xac0 + 0x4023B220, 0x0047A61F, 0x00000002, 0x4023B320, 0x00479E1F, 0x00000002, + 0x4023B320, 0x0047A01F, 0x00000002, 0x4023B320, 0x0047A21F, 0x00000002, + 0x4023B320, 0x0047A41F, 0x00000002, 0x4023B320, 0x0047A61F, 0x00000002, + 0x4023B420, 0x00479E1F, 0x00000002, 0x4023B420, 0x0047A01F, 0x00000002, + 0x4023B420, 0x0047A21F, 0x00000002, 0x4023B420, 0x0047A41F, 0x00000002, + 0x4023B420, 0x0047A61F, 0x00000002, 0x4023B520, 0x00479E1F, 0x00000002, + 0x4023B520, 0x0047A01F, 0x00000002, 0x4023B520, 0x0047A21F, 0x00000002, + 0x4023B520, 0x0047A41F, 0x00000002, 0x4023B520, 0x0047A61F, 0x00000002, + 0x4023B620, 0x00479E1F, 0x00000002, 0x4023B620, 0x0047A01F, 0x00000002, + 0x4023B620, 0x0047A21F, 0x00000002, 0x4023B620, 0x0047A41F, 0x00000002, + 0x4023B620, 0x0047A61F, 0x00000002, 0x4023B720, + // Block 44, offset 0xb00 + 0x00479E1F, 0x00000002, 0x4023B720, 0x0047A01F, 0x00000002, 0x4023B720, + 0x0047A21F, 0x00000002, 0x4023B720, 0x0047A41F, 0x00000002, 0x4023B720, + 0x0047A61F, 0x00000002, 0x4023B820, 0x00479E1F, 0x00000002, 0x4023B820, + 0x0047A01F, 0x00000002, 0x4023B820, 0x0047A21F, 0x00000002, 0x4023B820, + 0x0047A41F, 0x00000002, 0x4023B820, 0x0047A61F, 0x00000002, 0x4023B920, + 0x00479E1F, 0x00000002, 0x4023B920, 0x0047A01F, 0x00000002, 0x4023B920, + 0x0047A21F, 0x00000002, 0x4023B920, 0x0047A41F, 0x00000002, 0x4023B920, + 0x0047A61F, 0x00000002, 0x4023BA20, 0x00479E1F, 0x00000002, 0x4023BA20, + 0x0047A01F, 0x00000002, 0x4023BA20, 0x0047A21F, 0x00000002, 0x4023BA20, + 0x0047A41F, 0x00000002, 0x4023BA20, 0x0047A61F, 0x00000002, 0x4023BB20, + 0x00479E1F, 0x00000002, 0x4023BB20, 0x0047A01F, + // Block 45, offset 0xb40 + 0x00000002, 0x4023BB20, 0x0047A21F, 0x00000002, 0x4023BB20, 0x0047A41F, + 0x00000002, 0x4023BB20, 0x0047A61F, 0x00000002, 0x4023BC20, 0x00479E1F, + 0x00000002, 0x4023BC20, 0x0047A01F, 0x00000002, 0x4023BC20, 0x0047A21F, + 0x00000002, 0x4023BC20, 0x0047A41F, 0x00000002, 0x4023BC20, 0x0047A61F, + 0x00000002, 0x4023BD20, 0x00479E1F, 0x00000002, 0x4023BD20, 0x0047A01F, + 0x00000002, 0x4023BD20, 0x0047A21F, 0x00000002, 0x4023BD20, 0x0047A41F, + 0x00000002, 0x4023BD20, 0x0047A61F, 0x00000002, 0x4023BE20, 0x00479E1F, + 0x00000002, 0x4023BE20, 0x0047A01F, 0x00000002, 0x4023BE20, 0x0047A21F, + 0x00000002, 0x4023BE20, 0x0047A41F, 0x00000002, 0x4023BE20, 0x0047A61F, + 0x00000002, 0x4023BF20, 0x00479E1F, 0x00000002, 0x4023BF20, 0x0047A01F, + 0x00000002, 0x4023BF20, 0x0047A21F, 0x00000002, + // Block 46, offset 0xb80 + 0x4023BF20, 0x0047A41F, 0x00000002, 0x4023BF20, 0x0047A61F, 0x00000002, + 0x4023C020, 0x00479E1F, 0x00000002, 0x4023C020, 0x0047A01F, 0x00000002, + 0x4023C020, 0x0047A21F, 0x00000002, 0x4023C020, 0x0047A41F, 0x00000002, + 0x4023C020, 0x0047A61F, 0x00000002, 0x4023C120, 0x00479E1F, 0x00000002, + 0x4023C120, 0x0047A01F, 0x00000002, 0x4023C120, 0x0047A21F, 0x00000002, + 0x4023C120, 0x0047A41F, 0x00000002, 0x4023C120, 0x0047A61F, 0x00000002, + 0x4023C220, 0x00479E1F, 0x00000002, 0x4023C220, 0x0047A01F, 0x00000002, + 0x4023C220, 0x0047A21F, 0x00000002, 0x4023C220, 0x0047A41F, 0x00000002, + 0x4023C220, 0x0047A61F, 0x00000002, 0x4023D520, 0x0047FC1F, 0x00000002, + 0x4023D520, 0x0047FE1F, 0x00000002, 0x4023D520, 0x0048001F, 0x00000002, + 0x4023D520, 0x0048021F, 0x00000002, 0x4023D520, + // Block 47, offset 0xbc0 + 0x0048041F, 0x00000002, 0x4023D620, 0x0047FC1F, 0x00000002, 0x4023D620, + 0x0047FE1F, 0x00000002, 0x4023D620, 0x0048001F, 0x00000002, 0x4023D620, + 0x0048021F, 0x00000002, 0x4023D620, 0x0048041F, 0x00000002, 0x4023D720, + 0x0047FC1F, 0x00000002, 0x4023D720, 0x0047FE1F, 0x00000002, 0x4023D720, + 0x0048001F, 0x00000002, 0x4023D720, 0x0048021F, 0x00000002, 0x4023D720, + 0x0048041F, 0x00000002, 0x4023D820, 0x0047FC1F, 0x00000002, 0x4023D820, + 0x0047FE1F, 0x00000002, 0x4023D820, 0x0048001F, 0x00000002, 0x4023D820, + 0x0048021F, 0x00000002, 0x4023D820, 0x0048041F, 0x00000002, 0x4023D920, + 0x0047FC1F, 0x00000002, 0x4023D920, 0x0047FE1F, 0x00000002, 0x4023D920, + 0x0048001F, 0x00000002, 0x4023D920, 0x0048021F, 0x00000002, 0x4023D920, + 0x0048041F, 0x00000002, 0x4023DA20, 0x0047FC1F, + // Block 48, offset 0xc00 + 0x00000002, 0x4023DA20, 0x0047FE1F, 0x00000002, 0x4023DA20, 0x0048001F, + 0x00000002, 0x4023DA20, 0x0048021F, 0x00000002, 0x4023DA20, 0x0048041F, + 0x00000002, 0x4023DB20, 0x0047FC1F, 0x00000002, 0x4023DB20, 0x0047FE1F, + 0x00000002, 0x4023DB20, 0x0048001F, 0x00000002, 0x4023DB20, 0x0048021F, + 0x00000002, 0x4023DB20, 0x0048041F, 0x00000002, 0x4023DC20, 0x0047FC1F, + 0x00000002, 0x4023DC20, 0x0047FE1F, 0x00000002, 0x4023DC20, 0x0048001F, + 0x00000002, 0x4023DC20, 0x0048021F, 0x00000002, 0x4023DC20, 0x0048041F, + 0x00000002, 0x4023DD20, 0x0047FC1F, 0x00000002, 0x4023DD20, 0x0047FE1F, + 0x00000002, 0x4023DD20, 0x0048001F, 0x00000002, 0x4023DD20, 0x0048021F, + 0x00000002, 0x4023DD20, 0x0048041F, 0x00000002, 0x4023DE20, 0x0047FC1F, + 0x00000002, 0x4023DE20, 0x0047FE1F, 0x00000002, + // Block 49, offset 0xc40 + 0x4023DE20, 0x0048001F, 0x00000002, 0x4023DE20, 0x0048021F, 0x00000002, + 0x4023DE20, 0x0048041F, 0x00000002, 0x4023DF20, 0x0047FC1F, 0x00000002, + 0x4023DF20, 0x0047FE1F, 0x00000002, 0x4023DF20, 0x0048001F, 0x00000002, + 0x4023DF20, 0x0048021F, 0x00000002, 0x4023DF20, 0x0048041F, 0x00000002, + 0x4023E020, 0x0047FC1F, 0x00000002, 0x4023E020, 0x0047FE1F, 0x00000002, + 0x4023E020, 0x0048001F, 0x00000002, 0x4023E020, 0x0048021F, 0x00000002, + 0x4023E020, 0x0048041F, 0x00000002, 0x4023E120, 0x0047FC1F, 0x00000002, + 0x4023E120, 0x0047FE1F, 0x00000002, 0x4023E120, 0x0048001F, 0x00000002, + 0x4023E120, 0x0048021F, 0x00000002, 0x4023E120, 0x0048041F, 0x00000002, + 0x4023E220, 0x0047FC1F, 0x00000002, 0x4023E220, 0x0047FE1F, 0x00000002, + 0x4023E220, 0x0048001F, 0x00000002, 0x4023E220, + // Block 50, offset 0xc80 + 0x0048021F, 0x00000002, 0x4023E220, 0x0048041F, 0x00000002, 0x4023E320, + 0x0047FC1F, 0x00000002, 0x4023E320, 0x0047FE1F, 0x00000002, 0x4023E320, + 0x0048001F, 0x00000002, 0x4023E320, 0x0048021F, 0x00000002, 0x4023E320, + 0x0048041F, 0x00000002, 0x4023E420, 0x0047FC1F, 0x00000002, 0x4023E420, + 0x0047FE1F, 0x00000002, 0x4023E420, 0x0048001F, 0x00000002, 0x4023E420, + 0x0048021F, 0x00000002, 0x4023E420, 0x0048041F, 0x00000002, 0x4023E520, + 0x0047FC1F, 0x00000002, 0x4023E520, 0x0047FE1F, 0x00000002, 0x4023E520, + 0x0048001F, 0x00000002, 0x4023E520, 0x0048021F, 0x00000002, 0x4023E520, + 0x0048041F, 0x00000002, 0x4023E620, 0x0047FC1F, 0x00000002, 0x4023E620, + 0x0047FE1F, 0x00000002, 0x4023E620, 0x0048001F, 0x00000002, 0x4023E620, + 0x0048021F, 0x00000002, 0x4023E620, 0x0048041F, + // Block 51, offset 0xcc0 + 0x00000002, 0x4023E720, 0x0047FC1F, 0x00000002, 0x4023E720, 0x0047FE1F, + 0x00000002, 0x4023E720, 0x0048001F, 0x00000002, 0x4023E720, 0x0048021F, + 0x00000002, 0x4023E720, 0x0048041F, 0x00000002, 0x4023E820, 0x0047FC1F, + 0x00000002, 0x4023E820, 0x0047FE1F, 0x00000002, 0x4023E820, 0x0048001F, + 0x00000002, 0x4023E820, 0x0048021F, 0x00000002, 0x4023E820, 0x0048041F, + 0x00000002, 0x4023E920, 0x0047FC1F, 0x00000002, 0x4023E920, 0x0047FE1F, + 0x00000002, 0x4023E920, 0x0048001F, 0x00000002, 0x4023E920, 0x0048021F, + 0x00000002, 0x4023E920, 0x0048041F, 0x00000002, 0x4023EA20, 0x0047FC1F, + 0x00000002, 0x4023EA20, 0x0047FE1F, 0x00000002, 0x4023EA20, 0x0048001F, + 0x00000002, 0x4023EA20, 0x0048021F, 0x00000002, 0x4023EA20, 0x0048041F, + 0x00000002, 0x4023EB20, 0x0047FC1F, 0x00000002, + // Block 52, offset 0xd00 + 0x4023EB20, 0x0047FE1F, 0x00000002, 0x4023EB20, 0x0048001F, 0x00000002, + 0x4023EB20, 0x0048021F, 0x00000002, 0x4023EB20, 0x0048041F, 0x00000002, + 0x4023EC20, 0x0047FC1F, 0x00000002, 0x4023EC20, 0x0047FE1F, 0x00000002, + 0x4023EC20, 0x0048001F, 0x00000002, 0x4023EC20, 0x0048021F, 0x00000002, + 0x4023EC20, 0x0048041F, 0x00000003, 0x0047DA04, 0x0047C204, 0x0047FC1F, + 0x00000003, 0x0047DA04, 0x0047C204, 0x0047FE1F, 0x00000003, 0x0047DA04, + 0x0047C204, 0x0048001F, 0x00000003, 0x0047DA04, 0x0047C204, 0x0048021F, + 0x00000003, 0x0047DA04, 0x0047C204, 0x0048041F, 0x00000003, 0x0047DA04, + 0x0047D004, 0x0047FC1F, 0x00000003, 0x0047DA04, 0x0047D004, 0x0047FE1F, + 0x00000003, 0x0047DA04, 0x0047D004, 0x0048001F, 0x00000003, 0x0047DA04, + 0x0047D004, 0x0048021F, 0x00000003, 0x0047DA04, + // Block 53, offset 0xd40 + 0x0047D004, 0x0048041F, 0x00000002, 0x4023ED20, 0x0047FC1F, 0x00000002, + 0x4023ED20, 0x0047FE1F, 0x00000002, 0x4023ED20, 0x0048001F, 0x00000002, + 0x4023ED20, 0x0048021F, 0x00000002, 0x4023ED20, 0x0048041F, 0x00000002, + 0x4023EE20, 0x0047FC1F, 0x00000002, 0x4023EE20, 0x0047FE1F, 0x00000002, + 0x4023EE20, 0x0048001F, 0x00000002, 0x4023EE20, 0x0048021F, 0x00000002, + 0x4023EE20, 0x0048041F, 0x00000002, 0x4023EF20, 0x0047FC1F, 0x00000002, + 0x4023EF20, 0x0047FE1F, 0x00000002, 0x4023EF20, 0x0048001F, 0x00000002, + 0x4023EF20, 0x0048021F, 0x00000002, 0x4023EF20, 0x0048041F, 0x00000002, + 0x40240320, 0x0048701F, 0x00000002, 0x40240320, 0x0048721F, 0x00000002, + 0x40240320, 0x0048781F, 0x00000002, 0x40240320, 0x00487C1F, 0x00000002, + 0x40240320, 0x00487E1F, 0x00000002, 0x40240420, + // Block 54, offset 0xd80 + 0x0048701F, 0x00000002, 0x40240420, 0x0048721F, 0x00000002, 0x40240420, + 0x0048781F, 0x00000002, 0x40240420, 0x00487C1F, 0x00000002, 0x40240420, + 0x00487E1F, 0x00000002, 0x40240520, 0x0048701F, 0x00000002, 0x40240520, + 0x0048721F, 0x00000002, 0x40240520, 0x0048781F, 0x00000002, 0x40240520, + 0x00487C1F, 0x00000002, 0x40240520, 0x00487E1F, 0x00000002, 0x40240620, + 0x0048701F, 0x00000002, 0x40240620, 0x0048721F, 0x00000002, 0x40240620, + 0x0048781F, 0x00000002, 0x40240620, 0x00487C1F, 0x00000002, 0x40240620, + 0x00487E1F, 0x00000002, 0x40240720, 0x0048701F, 0x00000002, 0x40240720, + 0x0048721F, 0x00000002, 0x40240720, 0x0048781F, 0x00000002, 0x40240720, + 0x00487C1F, 0x00000002, 0x40240720, 0x00487E1F, 0x00000002, 0x40240820, + 0x0048701F, 0x00000002, 0x40240820, 0x0048721F, + // Block 55, offset 0xdc0 + 0x00000002, 0x40240820, 0x0048781F, 0x00000002, 0x40240820, 0x00487C1F, + 0x00000002, 0x40240820, 0x00487E1F, 0x00000002, 0x40240920, 0x0048701F, + 0x00000002, 0x40240920, 0x0048721F, 0x00000002, 0x40240920, 0x0048781F, + 0x00000002, 0x40240920, 0x00487C1F, 0x00000002, 0x40240920, 0x00487E1F, + 0x00000002, 0x40240A20, 0x0048701F, 0x00000002, 0x40240A20, 0x0048721F, + 0x00000002, 0x40240A20, 0x0048781F, 0x00000002, 0x40240A20, 0x00487C1F, + 0x00000002, 0x40240A20, 0x00487E1F, 0x00000002, 0x40240B20, 0x0048701F, + 0x00000002, 0x40240B20, 0x0048721F, 0x00000002, 0x40240B20, 0x0048781F, + 0x00000002, 0x40240B20, 0x00487C1F, 0x00000002, 0x40240B20, 0x00487E1F, + 0x00000002, 0x40240C20, 0x0048701F, 0x00000002, 0x40240C20, 0x0048721F, + 0x00000002, 0x40240C20, 0x0048781F, 0x00000002, + // Block 56, offset 0xe00 + 0x40240C20, 0x00487C1F, 0x00000002, 0x40240C20, 0x00487E1F, 0x00000002, + 0x40240D20, 0x0048701F, 0x00000002, 0x40240D20, 0x0048721F, 0x00000002, + 0x40240D20, 0x0048781F, 0x00000002, 0x40240D20, 0x00487C1F, 0x00000002, + 0x40240D20, 0x00487E1F, 0x00000002, 0x40240E20, 0x0048701F, 0x00000002, + 0x40240E20, 0x0048721F, 0x00000002, 0x40240E20, 0x0048781F, 0x00000002, + 0x40240E20, 0x00487C1F, 0x00000002, 0x40240E20, 0x00487E1F, 0x00000002, + 0x40240F20, 0x0048701F, 0x00000002, 0x40240F20, 0x0048721F, 0x00000002, + 0x40240F20, 0x0048781F, 0x00000002, 0x40240F20, 0x00487C1F, 0x00000002, + 0x40240F20, 0x00487E1F, 0x00000002, 0x40241020, 0x0048701F, 0x00000002, + 0x40241020, 0x0048721F, 0x00000002, 0x40241020, 0x0048781F, 0x00000002, + 0x40241020, 0x00487C1F, 0x00000002, 0x40241020, + // Block 57, offset 0xe40 + 0x00487E1F, 0x00000002, 0x40241120, 0x0048701F, 0x00000002, 0x40241120, + 0x0048721F, 0x00000002, 0x40241120, 0x0048781F, 0x00000002, 0x40241120, + 0x00487C1F, 0x00000002, 0x40241120, 0x00487E1F, 0x00000002, 0x40241220, + 0x0048701F, 0x00000002, 0x40241220, 0x0048721F, 0x00000002, 0x40241220, + 0x0048781F, 0x00000002, 0x40241220, 0x00487C1F, 0x00000002, 0x40241220, + 0x00487E1F, 0x00000002, 0x40241320, 0x0048701F, 0x00000002, 0x40241320, + 0x0048721F, 0x00000002, 0x40241320, 0x0048781F, 0x00000002, 0x40241320, + 0x00487C1F, 0x00000002, 0x40241320, 0x00487E1F, 0x00000002, 0x40241420, + 0x0048701F, 0x00000002, 0x40241420, 0x0048721F, 0x00000002, 0x40241420, + 0x0048781F, 0x00000002, 0x40241420, 0x00487C1F, 0x00000002, 0x40241420, + 0x00487E1F, 0x00000002, 0x40241520, 0x0048701F, + // Block 58, offset 0xe80 + 0x00000002, 0x40241520, 0x0048721F, 0x00000002, 0x40241520, 0x0048781F, + 0x00000002, 0x40241520, 0x00487C1F, 0x00000002, 0x40241520, 0x00487E1F, + 0x00000002, 0x40241620, 0x0048701F, 0x00000002, 0x40241620, 0x0048721F, + 0x00000002, 0x40241620, 0x0048781F, 0x00000002, 0x40241620, 0x00487C1F, + 0x00000002, 0x40241620, 0x00487E1F, 0x00000002, 0x40241720, 0x0048701F, + 0x00000002, 0x40241720, 0x0048721F, 0x00000002, 0x40241720, 0x0048781F, + 0x00000002, 0x40241720, 0x00487C1F, 0x00000002, 0x40241720, 0x00487E1F, + 0x00000002, 0x40241820, 0x0048701F, 0x00000002, 0x40241820, 0x0048721F, + 0x00000002, 0x40241820, 0x0048781F, 0x00000002, 0x40241820, 0x00487C1F, + 0x00000002, 0x40241820, 0x00487E1F, 0x00000002, 0x40241920, 0x0048701F, + 0x00000002, 0x40241920, 0x0048721F, 0x00000002, + // Block 59, offset 0xec0 + 0x40241920, 0x0048781F, 0x00000002, 0x40241920, 0x00487C1F, 0x00000002, + 0x40241920, 0x00487E1F, 0x00000002, 0x40241A20, 0x0048701F, 0x00000002, + 0x40241A20, 0x0048721F, 0x00000002, 0x40241A20, 0x0048781F, 0x00000002, + 0x40241A20, 0x00487C1F, 0x00000002, 0x40241A20, 0x00487E1F, 0x00000002, + 0x40241B20, 0x0048701F, 0x00000002, 0x40241B20, 0x0048721F, 0x00000002, + 0x40241B20, 0x0048781F, 0x00000002, 0x40241B20, 0x00487C1F, 0x00000002, + 0x40241B20, 0x00487E1F, 0x00000002, 0x40241C20, 0x0048701F, 0x00000002, + 0x40241C20, 0x0048721F, 0x00000002, 0x40241C20, 0x0048781F, 0x00000002, + 0x40241C20, 0x00487C1F, 0x00000002, 0x40241C20, 0x00487E1F, 0x00000002, + 0x40241D20, 0x0048701F, 0x00000002, 0x40241D20, 0x0048721F, 0x00000002, + 0x40241D20, 0x0048781F, 0x00000002, 0x40241D20, + // Block 60, offset 0xf00 + 0x00487C1F, 0x00000002, 0x40241D20, 0x00487E1F, 0x00000002, 0x40241E20, + 0x0048701F, 0x00000002, 0x40241E20, 0x0048721F, 0x00000002, 0x40241E20, + 0x0048781F, 0x00000002, 0x40241E20, 0x00487C1F, 0x00000002, 0x40241E20, + 0x00487E1F, 0x00000002, 0x40241F20, 0x0048701F, 0x00000002, 0x40241F20, + 0x0048721F, 0x00000002, 0x40241F20, 0x0048781F, 0x00000002, 0x40241F20, + 0x00487C1F, 0x00000002, 0x40241F20, 0x00487E1F, 0x00000002, 0x40242020, + 0x0048701F, 0x00000002, 0x40242020, 0x0048721F, 0x00000002, 0x40242020, + 0x0048781F, 0x00000002, 0x40242020, 0x00487C1F, 0x00000002, 0x40242020, + 0x00487E1F, 0x00000002, 0x40242120, 0x0048701F, 0x00000002, 0x40242120, + 0x0048721F, 0x00000002, 0x40242120, 0x0048781F, 0x00000002, 0x40242120, + 0x00487C1F, 0x00000002, 0x40242120, 0x00487E1F, + // Block 61, offset 0xf40 + 0x00000002, 0x40242220, 0x0048701F, 0x00000002, 0x40242220, 0x0048721F, + 0x00000002, 0x40242220, 0x0048781F, 0x00000002, 0x40242220, 0x00487C1F, + 0x00000002, 0x40242220, 0x00487E1F, 0x00000002, 0x40242320, 0x0048701F, + 0x00000002, 0x40242320, 0x0048721F, 0x00000002, 0x40242320, 0x0048781F, + 0x00000002, 0x40242320, 0x00487C1F, 0x00000002, 0x40242320, 0x00487E1F, + 0x00000002, 0x40242420, 0x0048701F, 0x00000002, 0x40242420, 0x0048721F, + 0x00000002, 0x40242420, 0x0048781F, 0x00000002, 0x40242420, 0x00487C1F, + 0x00000002, 0x40242420, 0x00487E1F, 0x00000002, 0x40242520, 0x0048701F, + 0x00000002, 0x40242520, 0x0048721F, 0x00000002, 0x40242520, 0x0048781F, + 0x00000002, 0x40242520, 0x00487C1F, 0x00000002, 0x40242520, 0x00487E1F, + 0x00000002, 0x40242620, 0x0048701F, 0x00000002, + // Block 62, offset 0xf80 + 0x40242620, 0x0048721F, 0x00000002, 0x40242620, 0x0048781F, 0x00000002, + 0x40242620, 0x00487C1F, 0x00000002, 0x40242620, 0x00487E1F, 0x00000002, + 0x40242720, 0x0048701F, 0x00000002, 0x40242720, 0x0048721F, 0x00000002, + 0x40242720, 0x0048781F, 0x00000002, 0x40242720, 0x00487C1F, 0x00000002, + 0x40242720, 0x00487E1F, 0x00000002, 0x40242820, 0x0048701F, 0x00000002, + 0x40242820, 0x0048721F, 0x00000002, 0x40242820, 0x0048781F, 0x00000002, + 0x40242820, 0x00487C1F, 0x00000002, 0x40242820, 0x00487E1F, 0x00000002, + 0x40242920, 0x0048701F, 0x00000002, 0x40242920, 0x0048721F, 0x00000002, + 0x40242920, 0x0048781F, 0x00000002, 0x40242920, 0x00487C1F, 0x00000002, + 0x40242920, 0x00487E1F, 0x00000002, 0x40242A20, 0x0048701F, 0x00000002, + 0x40242A20, 0x0048721F, 0x00000002, 0x40242A20, + // Block 63, offset 0xfc0 + 0x0048781F, 0x00000002, 0x40242A20, 0x00487C1F, 0x00000002, 0x40242A20, + 0x00487E1F, 0x00000002, 0x40242B20, 0x0048701F, 0x00000002, 0x40242B20, + 0x0048721F, 0x00000002, 0x40242B20, 0x0048781F, 0x00000002, 0x40242B20, + 0x00487C1F, 0x00000002, 0x40242B20, 0x00487E1F, 0x00000002, 0x40242C20, + 0x0048701F, 0x00000002, 0x40242C20, 0x0048721F, 0x00000002, 0x40242C20, + 0x0048781F, 0x00000002, 0x40242C20, 0x00487C1F, 0x00000002, 0x40242C20, + 0x00487E1F, 0x00000002, 0x40242D20, 0x0048701F, 0x00000002, 0x40242D20, + 0x0048721F, 0x00000002, 0x40242D20, 0x0048781F, 0x00000002, 0x40242D20, + 0x00487C1F, 0x00000002, 0x40242D20, 0x00487E1F, 0x00000002, 0x40242E20, + 0x0048701F, 0x00000002, 0x40242E20, 0x0048721F, 0x00000002, 0x40242E20, + 0x0048781F, 0x00000002, 0x40242E20, 0x00487C1F, + // Block 64, offset 0x1000 + 0x00000002, 0x40242E20, 0x00487E1F, 0x00000002, 0x40242F20, 0x0048701F, + 0x00000002, 0x40242F20, 0x0048721F, 0x00000002, 0x40242F20, 0x0048781F, + 0x00000002, 0x40242F20, 0x00487C1F, 0x00000002, 0x40242F20, 0x00487E1F, + 0x00000002, 0x40243020, 0x0048701F, 0x00000002, 0x40243020, 0x0048721F, + 0x00000002, 0x40243020, 0x0048781F, 0x00000002, 0x40243020, 0x00487C1F, + 0x00000002, 0x40243020, 0x00487E1F, 0x00000002, 0x40243120, 0x0048701F, + 0x00000002, 0x40243120, 0x0048721F, 0x00000002, 0x40243120, 0x0048781F, + 0x00000002, 0x40243120, 0x00487C1F, 0x00000002, 0x40243120, 0x00487E1F, + 0x00000002, 0x40243220, 0x0048701F, 0x00000002, 0x40243220, 0x0048721F, + 0x00000002, 0x40243220, 0x0048781F, 0x00000002, 0x40243220, 0x00487C1F, + 0x00000002, 0x40243220, 0x00487E1F, 0x00000002, + // Block 65, offset 0x1040 + 0x0048EC04, 0x80016004, 0x00000002, 0x0048FC04, 0x80016004, 0x00000002, + 0x0048FE04, 0x80016004, 0x00000002, 0x00490004, 0x80016004, 0x00000002, + 0x40248020, 0x40249620, 0x00000002, 0x40248320, 0x40249620, 0x00000003, + 0x00491804, 0x00494604, 0x80012D1F, 0x00000003, 0x004CBC04, 0x004D2A04, + 0x004CBC1F, 0x00000002, 0x004E6404, 0x004E9004, 0x00000003, 0x004E6404, + 0x004E9004, 0x004EA61F, 0x00000003, 0x004F0404, 0x004F5004, 0x004F041F, + 0x00000002, 0x00589004, 0x80015F04, 0x00000002, 0x00589204, 0x80015F04, + 0x00000002, 0x00589204, 0x80016004, 0x00000002, 0x00589404, 0x80015F04, + 0x00000002, 0x00589404, 0x00589404, 0x00000002, 0x00589604, 0x80015F04, + 0x00000002, 0x00589604, 0x80016004, 0x00000002, 0x00589604, 0x80016204, + 0x00000002, 0x00589604, 0x80016304, 0x00000002, + // Block 66, offset 0x1080 + 0x00589E04, 0x80015F04, 0x00000002, 0x00589E04, 0x80016004, 0x00000002, + 0x00589E04, 0x80016204, 0x00000002, 0x00589E04, 0x80016304, 0x00000002, + 0x0058A204, 0x80015F04, 0x00000002, 0x0058A404, 0x80015F04, 0x00000002, + 0x0058A404, 0x80016004, 0x00000002, 0x0058A404, 0x80016204, 0x00000002, + 0x0058A604, 0x80015F04, 0x00000002, 0x0058A604, 0x80016004, 0x00000002, + 0x0058A804, 0x80015F04, 0x00000002, 0x0058AA04, 0x80015F04, 0x00000002, + 0x0058AC04, 0x80015F04, 0x00000002, 0x0058AC04, 0x0058BE04, 0x00000002, + 0x0058B004, 0x80015F04, 0x00000002, 0x0058B404, 0x80015F04, 0x00000002, + 0x0058B404, 0x80016004, 0x00000002, 0x0058B404, 0x80016204, 0x00000002, + 0x0058B404, 0x80016304, 0x00000002, 0x0058B404, 0x80016404, 0x00000002, + 0x0058B604, 0x80015F04, 0x00000002, 0x0058B604, + // Block 67, offset 0x10c0 + 0x80016004, 0x00000002, 0x0058B804, 0x80015F04, 0x00000002, 0x0058B804, + 0x80016004, 0x00000002, 0x0058BC04, 0x80015F04, 0x00000002, 0x0058BC04, + 0x80016004, 0x00000004, 0x0058BC04, 0x80015F04, 0x0058BC1F, 0x80015F1F, + 0x00000002, 0x0058BE04, 0x80015F04, 0x00000002, 0x0058C004, 0x80015F04, + 0x00000002, 0x0058DA04, 0x80015F04, 0x00000002, 0x0058DA04, 0x80016004, + 0x00000002, 0x0058DC04, 0x80015F04, 0x00000002, 0x0058E004, 0x80015F04, + 0x00000002, 0x0058E604, 0x80015F04, 0x00000002, 0x0058E804, 0x80015F04, + 0x00000002, 0x0058EA04, 0x80015F04, 0x00000002, 0x0058EC04, 0x80015F04, + 0x00000002, 0x0058EE04, 0x80015F04, 0x00000002, 0x0058F004, 0x80015F04, + 0x00000002, 0x0058F404, 0x80015F04, 0x00000002, 0x0058F604, 0x80015F04, + 0x00000002, 0x0058F804, 0x80015F04, 0x00000002, + // Block 68, offset 0x1100 + 0x0058FA04, 0x80015F04, 0x00000002, 0x0058FC04, 0x80015F04, 0x00000002, + 0x0058FE04, 0x80015F04, 0x00000002, 0x00590804, 0x80015F04, 0x00000002, + 0x00590A04, 0x80015F04, 0x00000002, 0x00590C04, 0x80015F04, 0x00000002, + 0x00590E04, 0x80015F04, 0x00000002, 0x00591204, 0x80015F04, 0x00000002, + 0x00591A04, 0x80015F04, 0x00000002, 0x00591C04, 0x80015F04, 0x00000002, + 0x00591E04, 0x80015F04, 0x00000002, 0x00592004, 0x80015F04, 0x00000002, + 0x00592204, 0x80015F04, 0x00000002, 0x00592A04, 0x80015F04, 0x00000002, + 0x00592C04, 0x80015F04, 0x00000002, 0x00592E04, 0x80015F04, 0x00000002, + 0x00593004, 0x80015F04, 0x00000002, 0x00594E04, 0x005B4C04, 0x00000002, + 0x00597204, 0x005B4C04, 0x00000002, 0x00599C04, 0x005B4C04, 0x00000002, + 0x0059C404, 0x005B4E04, 0x00000002, 0x0059DA04, + // Block 69, offset 0x1140 + 0x005B4C04, 0x00000002, 0x0059E604, 0x005B4E04, 0x00000002, 0x0059EA04, + 0x005B4E04, 0x00000002, 0x0059F604, 0x005B4C04, 0x00000002, 0x005A4004, + 0x005B4C04, 0x00000002, 0x005A9E04, 0x005B4C04, 0x00000002, 0x005ACC04, + 0x005B4C04, 0x00000002, 0x005AD804, 0x005B4E04, 0x00000002, 0x005AE604, + 0x005B4C04, 0x00000002, 0x00634404, 0x00637004, 0x00000002, 0x00636A04, + 0x00634604, 0x00000002, 0x00639004, 0x80016004, 0x00000002, 0x0063A204, + 0x80016004, 0x00000002, 0x0063AC04, 0x80016004, 0x00000002, 0x0063BC04, + 0x80016004, 0x00000002, 0x0063C804, 0x80016004, 0x00000002, 0x0063CA04, + 0x80016004, 0x00000002, 0x0063D204, 0x80016004, 0x00000002, 0x0063D404, + 0x80016004, 0x00000002, 0x0063D804, 0x80016004, 0x00000002, 0x0063EE04, + 0x80016004, 0x00000002, 0x0063EE16, 0x80016016, + // Block 70, offset 0x1180 + 0x00000002, 0x0063F004, 0x80016004, 0x00000002, 0x0063F004, 0x80016204, + 0x00000002, 0x00724404, 0x80015F04, 0x00000002, 0x029C6C04, 0x80015F1F, + 0x00000002, 0x029CB204, 0x80015F1F, 0x00000002, 0x02A30404, 0x80015F1F, + 0x00000002, 0x02A3C004, 0x80015F1F, 0x00000002, 0x02A40004, 0x80015F1F, + 0x00000002, 0x02A6B804, 0x80015F1F, 0x00000002, 0x02A6D204, 0x80015F1F, + 0x00000002, 0x02A70404, 0x80015F1F, 0x00000002, 0x02B81E04, 0x80015F1F, + 0x00000002, 0x02B81E04, 0x8001601F, 0x00000002, 0x02B84404, 0x80015F1F, + 0x00000002, 0x02B84604, 0x80015F1F, 0x00000002, 0x02BEA004, 0x80015F1F, + 0x00000002, 0x02BF8604, 0x80015F1F, 0x00000002, 0x02CBCA04, 0x80015F1F, + 0x00000002, 0x02CE1004, 0x80015F1F, 0x00000002, 0x02D6F404, 0x80015F1F, + 0x00000002, 0x02E45604, 0x80015F1F, 0x00000002, + // Block 71, offset 0x11c0 + 0x02E4B604, 0x80015F1F, 0x00000002, 0x02E71604, 0x80015F1F, 0x00000002, + 0x02EB1604, 0x80015F1F, 0x00000002, 0x02EDDC04, 0x80015F1F, 0x00000002, + 0x02F27404, 0x80015F1F, 0x00000002, 0x02F5F204, 0x80015F1F, 0x00000002, + 0x02FEA404, 0x80015F1F, 0x00000002, 0x02FEA604, 0x80015F1F, 0x00000002, + 0x02FEA604, 0x8001601F, 0x00000002, 0x02FF1404, 0x80015F1F, 0x00000002, + 0x02FF1404, 0x8001601F, 0x00000002, 0x0300FE04, 0x80015F1F, 0x00000002, + 0x03011204, 0x80015F1F, 0x00000002, 0x0303F804, 0x80015F1F, 0x00000002, + 0x0304F204, 0x80015F1F, 0x00000002, 0x0304F204, 0x8001601F, 0x00000002, + 0x0313A404, 0x80015F1F, 0x00000002, 0x031B6604, 0x80015F1F, 0x00000002, + 0x031F6C04, 0x80015F1F, 0x00000002, 0x031F6C04, 0x8001601F, 0x00000002, + 0x03212204, 0x80015F1F, 0x00000002, 0x032C3804, + // Block 72, offset 0x1200 + 0x80015F1F, 0x00000002, 0x032DD004, 0x80015F1F, 0x00000002, 0x0331C004, + 0x80015F1F, 0x00000002, 0x03332C04, 0x80015F1F, 0x00000002, 0x03355004, + 0x80015F1F, 0x00000002, 0x03367804, 0x80015F1F, 0x00000002, 0x033CEA04, + 0x80015F1F, 0x00000002, 0x033E9404, 0x80015F1F, 0x00000002, 0x033EA404, + 0x80015F1F, 0x00000002, 0x033F1A04, 0x80015F1F, 0x00000002, 0x033F3804, + 0x80015F1F, 0x00000002, 0x033F3804, 0x8001601F, +} + +// mainContractElem: 799 entries, 3196 bytes +var mainContractElem = [799]uint32{ + // Block 0, offset 0x0 + 0x4016C420, 0xE0000789, 0xE0000789, 0x002D8808, 0xE000078F, 0xE000078F, + 0x40194320, 0x40194720, 0x40194B20, 0x00328608, 0x00328E08, 0x00329608, + 0x40194F20, 0x40195320, 0x00329E08, 0x0032A608, 0x40196320, 0x40198320, + 0x40198320, 0x0032C608, 0x00330608, 0x00330608, 0x40198B20, 0x40198F20, + 0x00331608, 0x00331E08, 0x40199720, 0x40199C20, 0x00332E08, 0x00333808, + 0x4019A420, 0x4019AB20, 0x00334808, 0x00335608, 0x4019BC20, 0x4019D120, + 0x4019C420, 0x00337808, 0x0033A208, 0x00338808, 0x4019C820, 0x4019CD20, + 0x00339008, 0x00339A08, 0x401A2920, 0x401A2D20, 0x00345208, 0x00345A08, + 0x401A3120, 0x401A3520, 0x00346208, 0x00346A08, 0x4019DA20, 0x401A6720, + 0x401A6720, 0x0033B408, 0x0034CE08, 0x0034CE08, 0x401A6B20, 0x401A6F20, + 0x401A7320, 0x401A7720, 0x0034D608, 0x0034DE08, + // Block 1, offset 0x40 + 0x0034E608, 0x0034EE08, 0x401ABE20, 0x401AC320, 0x00357C08, 0x00358608, + 0x401AF120, 0x401AF520, 0x0035E208, 0x0035EA08, 0x401B0620, 0x401B0A20, + 0x00360C08, 0x00361408, 0x401B3C20, 0x401B4020, 0x00367808, 0x00368008, + 0x401C4620, 0x401C3C20, 0x401C3D20, 0x401C4120, 0x401CDC20, 0x401C4020, + 0x401CE920, 0x401C4520, 0x40201520, 0x40201720, 0x40201820, 0x4020D420, + 0x4020D620, 0x4020D520, 0x4020D720, 0x4020E520, 0x4020E720, 0x40210520, + 0x40210820, 0x40210A20, 0x40210620, 0x40210920, 0x40214C20, 0x40214E20, + 0x40218D20, 0x40218E20, 0x40219520, 0x40219920, 0x40219820, 0x40219620, + 0x40219720, 0x40219820, 0x40219920, 0x4021DE20, 0x4021E120, 0x4021E320, + 0x4021DF20, 0x4021E220, 0x40222C20, 0x40223020, 0x40222D20, 0x40222F20, + 0x40223120, 0x40222F20, 0x40223020, 0x4023CF20, + // Block 2, offset 0x80 + 0xE0000900, 0xE000090F, 0xE000091E, 0xE000092D, 0xE000093C, 0xE000094B, + 0xE000095A, 0xE0000969, 0xE0000978, 0xE0000987, 0xE0000996, 0xE00009A5, + 0xE00009B4, 0xE00009C3, 0xE00009D2, 0xE00009E1, 0xE00009F0, 0xE00009FF, + 0xE0000A0E, 0xE0000A1D, 0xE0000A2C, 0xE0000A3B, 0xE0000A4A, 0xE0000A59, + 0xE0000A68, 0xE0000A77, 0xE0000A86, 0xE0000A95, 0xE0000AA4, 0xE0000AB3, + 0xE0000AC2, 0xE0000AD1, 0xE0000AE0, 0xE0000AEF, 0xE0000AFE, 0xE0000B0D, + 0xE0000B1C, 0xE0000B2B, 0xE0000B3A, 0xE0000B49, 0xE0000B58, 0xE0000B67, + 0xE0000B76, 0xE0000B85, 0xE0000B94, 0xE0000BA3, 0x4023D020, 0xE0000903, + 0xE0000912, 0xE0000921, 0xE0000930, 0xE000093F, 0xE000094E, 0xE000095D, + 0xE000096C, 0xE000097B, 0xE000098A, 0xE0000999, 0xE00009A8, 0xE00009B7, + 0xE00009C6, 0xE00009D5, 0xE00009E4, 0xE00009F3, + // Block 3, offset 0xc0 + 0xE0000A02, 0xE0000A11, 0xE0000A20, 0xE0000A2F, 0xE0000A3E, 0xE0000A4D, + 0xE0000A5C, 0xE0000A6B, 0xE0000A7A, 0xE0000A89, 0xE0000A98, 0xE0000AA7, + 0xE0000AB6, 0xE0000AC5, 0xE0000AD4, 0xE0000AE3, 0xE0000AF2, 0xE0000B01, + 0xE0000B10, 0xE0000B1F, 0xE0000B2E, 0xE0000B3D, 0xE0000B4C, 0xE0000B5B, + 0xE0000B6A, 0xE0000B79, 0xE0000B88, 0xE0000B97, 0xE0000BA6, 0x4023D120, + 0xE0000906, 0xE0000915, 0xE0000924, 0xE0000933, 0xE0000942, 0xE0000951, + 0xE0000960, 0xE000096F, 0xE000097E, 0xE000098D, 0xE000099C, 0xE00009AB, + 0xE00009BA, 0xE00009C9, 0xE00009D8, 0xE00009E7, 0xE00009F6, 0xE0000A05, + 0xE0000A14, 0xE0000A23, 0xE0000A32, 0xE0000A41, 0xE0000A50, 0xE0000A5F, + 0xE0000A6E, 0xE0000A7D, 0xE0000A8C, 0xE0000A9B, 0xE0000AAA, 0xE0000AB9, + 0xE0000AC8, 0xE0000AD7, 0xE0000AE6, 0xE0000AF5, + // Block 4, offset 0x100 + 0xE0000B04, 0xE0000B13, 0xE0000B22, 0xE0000B31, 0xE0000B40, 0xE0000B4F, + 0xE0000B5E, 0xE0000B6D, 0xE0000B7C, 0xE0000B8B, 0xE0000B9A, 0xE0000BA9, + 0x4023D220, 0xE0000909, 0xE0000918, 0xE0000927, 0xE0000936, 0xE0000945, + 0xE0000954, 0xE0000963, 0xE0000972, 0xE0000981, 0xE0000990, 0xE000099F, + 0xE00009AE, 0xE00009BD, 0xE00009CC, 0xE00009DB, 0xE00009EA, 0xE00009F9, + 0xE0000A08, 0xE0000A17, 0xE0000A26, 0xE0000A35, 0xE0000A44, 0xE0000A53, + 0xE0000A62, 0xE0000A71, 0xE0000A80, 0xE0000A8F, 0xE0000A9E, 0xE0000AAD, + 0xE0000ABC, 0xE0000ACB, 0xE0000ADA, 0xE0000AE9, 0xE0000AF8, 0xE0000B07, + 0xE0000B16, 0xE0000B25, 0xE0000B34, 0xE0000B43, 0xE0000B52, 0xE0000B61, + 0xE0000B70, 0xE0000B7F, 0xE0000B8E, 0xE0000B9D, 0xE0000BAC, 0x4023D320, + 0xE000090C, 0xE000091B, 0xE000092A, 0xE0000939, + // Block 5, offset 0x140 + 0xE0000948, 0xE0000957, 0xE0000966, 0xE0000975, 0xE0000984, 0xE0000993, + 0xE00009A2, 0xE00009B1, 0xE00009C0, 0xE00009CF, 0xE00009DE, 0xE00009ED, + 0xE00009FC, 0xE0000A0B, 0xE0000A1A, 0xE0000A29, 0xE0000A38, 0xE0000A47, + 0xE0000A56, 0xE0000A65, 0xE0000A74, 0xE0000A83, 0xE0000A92, 0xE0000AA1, + 0xE0000AB0, 0xE0000ABF, 0xE0000ACE, 0xE0000ADD, 0xE0000AEC, 0xE0000AFB, + 0xE0000B0A, 0xE0000B19, 0xE0000B28, 0xE0000B37, 0xE0000B46, 0xE0000B55, + 0xE0000B64, 0xE0000B73, 0xE0000B82, 0xE0000B91, 0xE0000BA0, 0xE0000BAF, + 0x80012302, 0x4023C720, 0x4023FE20, 0xE0000BB2, 0xE0000BC1, 0xE0000BD0, + 0xE0000BDF, 0xE0000BEE, 0xE0000C0C, 0xE0000C1B, 0xE0000C2A, 0xE0000C39, + 0xE0000C48, 0xE0000C57, 0xE0000C66, 0xE0000C75, 0xE0000C84, 0xE0000C93, + 0xE0000CA2, 0xE0000CB1, 0xE0000CC0, 0xE0000CCF, + // Block 6, offset 0x180 + 0xE0000CDE, 0xE0000CED, 0xE0000CFC, 0xE0000D0B, 0xE0000BFD, 0xE0000D42, + 0xE0000D51, 0xE0000D60, 0xE0000D1A, 0xE0000D2E, 0x4023FF20, 0xE0000BB5, + 0xE0000BC4, 0xE0000BD3, 0xE0000BE2, 0xE0000BF1, 0xE0000C0F, 0xE0000C1E, + 0xE0000C2D, 0xE0000C3C, 0xE0000C4B, 0xE0000C5A, 0xE0000C69, 0xE0000C78, + 0xE0000C87, 0xE0000C96, 0xE0000CA5, 0xE0000CB4, 0xE0000CC3, 0xE0000CD2, + 0xE0000CE1, 0xE0000CF0, 0xE0000CFF, 0xE0000D0E, 0xE0000C00, 0xE0000D45, + 0xE0000D54, 0xE0000D63, 0xE0000D1E, 0xE0000D32, 0x40240020, 0xE0000BB8, + 0xE0000BC7, 0xE0000BD6, 0xE0000BE5, 0xE0000BF4, 0xE0000C12, 0xE0000C21, + 0xE0000C30, 0xE0000C3F, 0xE0000C4E, 0xE0000C5D, 0xE0000C6C, 0xE0000C7B, + 0xE0000C8A, 0xE0000C99, 0xE0000CA8, 0xE0000CB7, 0xE0000CC6, 0xE0000CD5, + 0xE0000CE4, 0xE0000CF3, 0xE0000D02, 0xE0000D11, + // Block 7, offset 0x1c0 + 0xE0000C03, 0xE0000D48, 0xE0000D57, 0xE0000D66, 0xE0000D22, 0xE0000D36, + 0x40240120, 0xE0000BBB, 0xE0000BCA, 0xE0000BD9, 0xE0000BE8, 0xE0000BF7, + 0xE0000C15, 0xE0000C24, 0xE0000C33, 0xE0000C42, 0xE0000C51, 0xE0000C60, + 0xE0000C6F, 0xE0000C7E, 0xE0000C8D, 0xE0000C9C, 0xE0000CAB, 0xE0000CBA, + 0xE0000CC9, 0xE0000CD8, 0xE0000CE7, 0xE0000CF6, 0xE0000D05, 0xE0000D14, + 0xE0000C06, 0xE0000D4B, 0xE0000D5A, 0xE0000D69, 0xE0000D26, 0xE0000D3A, + 0x40240220, 0xE0000BBE, 0xE0000BCD, 0xE0000BDC, 0xE0000BEB, 0xE0000BFA, + 0xE0000C18, 0xE0000C27, 0xE0000C36, 0xE0000C45, 0xE0000C54, 0xE0000C63, + 0xE0000C72, 0xE0000C81, 0xE0000C90, 0xE0000C9F, 0xE0000CAE, 0xE0000CBD, + 0xE0000CCC, 0xE0000CDB, 0xE0000CEA, 0xE0000CF9, 0xE0000D08, 0xE0000D17, + 0xE0000C09, 0xE0000D4E, 0xE0000D5D, 0xE0000D6C, + // Block 8, offset 0x200 + 0xE0000D2A, 0xE0000D3E, 0x80012902, 0x4023F420, 0x40243820, 0xE0000D6F, + 0xE0000D7E, 0xE0000D8D, 0xE0000D9C, 0xE0000DAB, 0xE0000DBA, 0xE0000DC9, + 0xE0000DD8, 0xE0000DE7, 0xE0000DF6, 0xE0000E05, 0xE0000E14, 0xE0000E23, + 0xE0000E32, 0xE0000E41, 0xE0000E50, 0xE0000E5F, 0xE0000E6E, 0xE0000E7D, + 0xE0000E8C, 0xE0000E9B, 0xE0000EAA, 0xE0000EB9, 0xE0000EC8, 0xE0000ED7, + 0xE0000EE6, 0xE0000EF5, 0xE0000F04, 0xE0000F13, 0xE0000F22, 0xE0000F31, + 0xE0000F40, 0xE0000F4F, 0xE0000F5E, 0xE0000F6D, 0xE0000F7C, 0xE0000F8B, + 0xE0000F9A, 0xE0000FA9, 0xE0000FB8, 0xE0000FC7, 0xE0000FD6, 0xE0000FE5, + 0xE0000FF4, 0xE0001003, 0xE0001012, 0xE0001021, 0xE0001030, 0x40243920, + 0xE0000D72, 0xE0000D81, 0xE0000D90, 0xE0000D9F, 0xE0000DAE, 0xE0000DBD, + 0xE0000DCC, 0xE0000DDB, 0xE0000DEA, 0xE0000DF9, + // Block 9, offset 0x240 + 0xE0000E08, 0xE0000E17, 0xE0000E26, 0xE0000E35, 0xE0000E44, 0xE0000E53, + 0xE0000E62, 0xE0000E71, 0xE0000E80, 0xE0000E8F, 0xE0000E9E, 0xE0000EAD, + 0xE0000EBC, 0xE0000ECB, 0xE0000EDA, 0xE0000EE9, 0xE0000EF8, 0xE0000F07, + 0xE0000F16, 0xE0000F25, 0xE0000F34, 0xE0000F43, 0xE0000F52, 0xE0000F61, + 0xE0000F70, 0xE0000F7F, 0xE0000F8E, 0xE0000F9D, 0xE0000FAC, 0xE0000FBB, + 0xE0000FCA, 0xE0000FD9, 0xE0000FE8, 0xE0000FF7, 0xE0001006, 0xE0001015, + 0xE0001024, 0xE0001033, 0x40243C20, 0xE0000D75, 0xE0000D84, 0xE0000D93, + 0xE0000DA2, 0xE0000DB1, 0xE0000DC0, 0xE0000DCF, 0xE0000DDE, 0xE0000DED, + 0xE0000DFC, 0xE0000E0B, 0xE0000E1A, 0xE0000E29, 0xE0000E38, 0xE0000E47, + 0xE0000E56, 0xE0000E65, 0xE0000E74, 0xE0000E83, 0xE0000E92, 0xE0000EA1, + 0xE0000EB0, 0xE0000EBF, 0xE0000ECE, 0xE0000EDD, + // Block 10, offset 0x280 + 0xE0000EEC, 0xE0000EFB, 0xE0000F0A, 0xE0000F19, 0xE0000F28, 0xE0000F37, + 0xE0000F46, 0xE0000F55, 0xE0000F64, 0xE0000F73, 0xE0000F82, 0xE0000F91, + 0xE0000FA0, 0xE0000FAF, 0xE0000FBE, 0xE0000FCD, 0xE0000FDC, 0xE0000FEB, + 0xE0000FFA, 0xE0001009, 0xE0001018, 0xE0001027, 0xE0001036, 0x40243E20, + 0xE0000D78, 0xE0000D87, 0xE0000D96, 0xE0000DA5, 0xE0000DB4, 0xE0000DC3, + 0xE0000DD2, 0xE0000DE1, 0xE0000DF0, 0xE0000DFF, 0xE0000E0E, 0xE0000E1D, + 0xE0000E2C, 0xE0000E3B, 0xE0000E4A, 0xE0000E59, 0xE0000E68, 0xE0000E77, + 0xE0000E86, 0xE0000E95, 0xE0000EA4, 0xE0000EB3, 0xE0000EC2, 0xE0000ED1, + 0xE0000EE0, 0xE0000EEF, 0xE0000EFE, 0xE0000F0D, 0xE0000F1C, 0xE0000F2B, + 0xE0000F3A, 0xE0000F49, 0xE0000F58, 0xE0000F67, 0xE0000F76, 0xE0000F85, + 0xE0000F94, 0xE0000FA3, 0xE0000FB2, 0xE0000FC1, + // Block 11, offset 0x2c0 + 0xE0000FD0, 0xE0000FDF, 0xE0000FEE, 0xE0000FFD, 0xE000100C, 0xE000101B, + 0xE000102A, 0xE0001039, 0x40243F20, 0xE0000D7B, 0xE0000D8A, 0xE0000D99, + 0xE0000DA8, 0xE0000DB7, 0xE0000DC6, 0xE0000DD5, 0xE0000DE4, 0xE0000DF3, + 0xE0000E02, 0xE0000E11, 0xE0000E20, 0xE0000E2F, 0xE0000E3E, 0xE0000E4D, + 0xE0000E5C, 0xE0000E6B, 0xE0000E7A, 0xE0000E89, 0xE0000E98, 0xE0000EA7, + 0xE0000EB6, 0xE0000EC5, 0xE0000ED4, 0xE0000EE3, 0xE0000EF2, 0xE0000F01, + 0xE0000F10, 0xE0000F1F, 0xE0000F2E, 0xE0000F3D, 0xE0000F4C, 0xE0000F5B, + 0xE0000F6A, 0xE0000F79, 0xE0000F88, 0xE0000F97, 0xE0000FA6, 0xE0000FB5, + 0xE0000FC4, 0xE0000FD3, 0xE0000FE2, 0xE0000FF1, 0xE0001000, 0xE000100F, + 0xE000101E, 0xE000102D, 0xE000103C, 0x40248020, 0x40249E20, 0xE000104B, + 0x40249D20, 0x40249E20, 0x40248320, 0x4024A020, + // Block 12, offset 0x300 + 0xE000104E, 0x40249F20, 0x4024A020, 0x40249620, 0x40249820, 0x40249C20, + 0x40249A20, 0x40267020, 0x40267120, 0x4027EE20, 0x4027EF20, 0x4027F020, + 0x4027F120, 0x4027F220, 0x4027F320, 0x4027F420, 0x4027F520, 0x4027F620, + 0x4027F720, 0x4027FA20, 0x4027FB20, 0x40282920, 0x40282A20, 0x40282B20, + 0x40282C20, 0x40282D20, 0x40282F20, 0x40282E20, 0x40283020, 0x40283120, + 0x40283220, +} + +// mainValues: 25408 entries, 101632 bytes +// Block 2 is the null block. +var mainValues = [25408]uint32{ + // Block 0x0, offset 0x0 + 0x0000: 0x80000000, 0x0001: 0x80000000, 0x0002: 0x80000000, 0x0003: 0x80000000, + 0x0004: 0x80000000, 0x0005: 0x80000000, 0x0006: 0x80000000, 0x0007: 0x80000000, + 0x0008: 0x80000000, 0x0009: 0x40010020, 0x000a: 0x40010120, 0x000b: 0x40010220, + 0x000c: 0x40010320, 0x000d: 0x40010420, 0x000e: 0x80000000, 0x000f: 0x80000000, + 0x0010: 0x80000000, 0x0011: 0x80000000, 0x0012: 0x80000000, 0x0013: 0x80000000, + 0x0014: 0x80000000, 0x0015: 0x80000000, 0x0016: 0x80000000, 0x0017: 0x80000000, + 0x0018: 0x80000000, 0x0019: 0x80000000, 0x001a: 0x80000000, 0x001b: 0x80000000, + 0x001c: 0x80000000, 0x001d: 0x80000000, 0x001e: 0x80000000, 0x001f: 0x80000000, + 0x0020: 0x40010920, 0x0021: 0x40015820, 0x0022: 0x4001df20, 0x0023: 0x40024620, + 0x0024: 0x4013a520, 0x0025: 0x40024720, 0x0026: 0x40024420, 0x0027: 0x4001d820, + 0x0028: 0x4001e920, 0x0029: 0x4001ea20, 0x002a: 0x40023d20, 0x002b: 0x40048520, + 0x002c: 0x40011f20, 0x002d: 0x40010e20, 0x002e: 0x40016b20, 0x002f: 0x40024220, + 0x0030: 0x40149a20, 0x0031: 0x40149b20, 0x0032: 0x40149c20, 0x0033: 0x40149d20, + 0x0034: 0x40149e20, 0x0035: 0x40149f20, 0x0036: 0x4014a020, 0x0037: 0x4014a120, + 0x0038: 0x4014a220, 0x0039: 0x4014a320, 0x003a: 0x40013220, 0x003b: 0x40012e20, + 0x003c: 0x40048920, 0x003d: 0x40048a20, 0x003e: 0x40048b20, 0x003f: 0x40015d20, + // Block 0x1, offset 0x40 + 0x0040: 0x40023c20, 0x0041: 0x002b4608, 0x0042: 0x002b7208, 0x0043: 0x002ba208, + 0x0044: 0x002bc808, 0x0045: 0x002bfe08, 0x0046: 0x002c6e08, 0x0047: 0x002c8808, + 0x0048: 0x002cce08, 0x0049: 0x002d0008, 0x004a: 0x002d3208, 0x004b: 0x002d6408, + 0x004c: 0xc0030002, 0x004d: 0x002de808, 0x004e: 0x002e0408, 0x004f: 0x002e4808, + 0x0050: 0x002e9208, 0x0051: 0x002ebc08, 0x0052: 0x002ee008, 0x0053: 0x002f4c08, + 0x0054: 0x002f9208, 0x0055: 0x002fd208, 0x0056: 0x00302408, 0x0057: 0x00304808, + 0x0058: 0x00305c08, 0x0059: 0x00306608, 0x005a: 0x00308808, 0x005b: 0x4001eb20, + 0x005c: 0x40024320, 0x005d: 0x4001ec20, 0x005e: 0x4002f120, 0x005f: 0x40010c20, + 0x0060: 0x4002ee20, 0x0061: 0x4015a320, 0x0062: 0x4015b920, 0x0063: 0x4015d120, + 0x0064: 0x4015e420, 0x0065: 0x4015ff20, 0x0066: 0x40163720, 0x0067: 0x40164420, + 0x0068: 0x40166720, 0x0069: 0x40168020, 0x006a: 0x40169920, 0x006b: 0x4016b220, + 0x006c: 0xc0000002, 0x006d: 0x4016f420, 0x006e: 0x40170220, 0x006f: 0x40172420, + 0x0070: 0x40174920, 0x0071: 0x40175e20, 0x0072: 0x40177020, 0x0073: 0x4017a620, + 0x0074: 0x4017c920, 0x0075: 0x4017e920, 0x0076: 0x40181220, 0x0077: 0x40182420, + 0x0078: 0x40182e20, 0x0079: 0x40183320, 0x007a: 0x40184420, 0x007b: 0x4001ed20, + 0x007c: 0x40048d20, 0x007d: 0x4001ee20, 0x007e: 0x40048f20, 0x007f: 0x80000000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x00c0: 0x80000000, 0x00c1: 0x80000000, 0x00c2: 0x80000000, 0x00c3: 0x80000000, + 0x00c4: 0x80000000, 0x00c5: 0x40010520, 0x00c6: 0x80000000, 0x00c7: 0x80000000, + 0x00c8: 0x80000000, 0x00c9: 0x80000000, 0x00ca: 0x80000000, 0x00cb: 0x80000000, + 0x00cc: 0x80000000, 0x00cd: 0x80000000, 0x00ce: 0x80000000, 0x00cf: 0x80000000, + 0x00d0: 0x80000000, 0x00d1: 0x80000000, 0x00d2: 0x80000000, 0x00d3: 0x80000000, + 0x00d4: 0x80000000, 0x00d5: 0x80000000, 0x00d6: 0x80000000, 0x00d7: 0x80000000, + 0x00d8: 0x80000000, 0x00d9: 0x80000000, 0x00da: 0x80000000, 0x00db: 0x80000000, + 0x00dc: 0x80000000, 0x00dd: 0x80000000, 0x00de: 0x80000000, 0x00df: 0x80000000, + 0x00e0: 0xf000001b, 0x00e1: 0x40015920, 0x00e2: 0x4013a420, 0x00e3: 0x4013a620, + 0x00e4: 0x4013a320, 0x00e5: 0x4013a720, 0x00e6: 0x40048e20, 0x00e7: 0x40031220, + 0x00e8: 0x4002f520, 0x00e9: 0x40031420, 0x00ea: 0xf0000014, 0x00eb: 0x4001e720, + 0x00ec: 0x40048c20, 0x00ed: 0x80000000, 0x00ee: 0x40031520, 0x00ef: 0x4002f220, + 0x00f0: 0x40038220, 0x00f1: 0x40048620, 0x00f2: 0xf0000014, 0x00f3: 0xf0000014, + 0x00f4: 0x4002ef20, 0x00f5: 0xf0000004, 0x00f6: 0x40031320, 0x00f7: 0x40017c20, + 0x00f8: 0x4002fa20, 0x00f9: 0xf0000014, 0x00fa: 0xf0000014, 0x00fb: 0x4001e820, + 0x00fc: 0xf0001e1e, 0x00fd: 0xf0001e1e, 0x00fe: 0xf0001e1e, 0x00ff: 0x40015e20, + // Block 0x4, offset 0x100 + 0x0106: 0xe00006fe, + 0x0110: 0xe000073f, + 0x0117: 0x40048820, + 0x0118: 0xe00007b1, + 0x011e: 0x0030ee08, 0x011f: 0xe00007f0, + 0x0126: 0xe00006f6, + 0x0130: 0xe0000739, + 0x0137: 0x40048720, + 0x0138: 0xe00007ae, + 0x013e: 0x40187720, + // Block 0x5, offset 0x140 + 0x0150: 0xe0000736, 0x0151: 0xe0000733, + 0x0166: 0xe0000774, 0x0167: 0xe0000771, + 0x0171: 0x40168420, 0x0172: 0xf0000a0a, 0x0173: 0xf0000404, + 0x0178: 0x40176c20, + 0x017f: 0xe0000792, + // Block 0x6, offset 0x180 + 0x0180: 0xe000078c, 0x0181: 0xe0000786, 0x0182: 0xe0000783, + 0x0189: 0xf0000404, 0x018a: 0x002e4008, 0x018b: 0x40172020, + 0x0192: 0xe00007b8, 0x0193: 0xe00007b4, + 0x01a6: 0x002f9c08, 0x01a7: 0x4017ce20, + 0x01bf: 0xe00007dd, + // Block 0x7, offset 0x1c0 + 0x01c0: 0x4015c120, 0x01c1: 0x002b9208, 0x01c2: 0x002b9a08, 0x01c3: 0x4015cd20, + 0x01c4: 0x00312a08, 0x01c5: 0x40189520, 0x01c6: 0x002e6008, 0x01c7: 0x002bb408, + 0x01c8: 0x4015da20, 0x01c9: 0x002bd808, 0x01ca: 0x002be008, 0x01cb: 0x002bea08, + 0x01cc: 0x4015f520, 0x01cd: 0xe0000828, 0x01ce: 0x002c1408, 0x01cf: 0x002c1e08, + 0x01d0: 0x002c2808, 0x01d1: 0x002c7c08, 0x01d2: 0x40163e20, 0x01d3: 0x002caa08, + 0x01d4: 0x002cbe08, 0x01d5: 0x40166f20, 0x01d6: 0x002d2808, 0x01d7: 0x002d1c08, + 0x01d8: 0x002d7008, 0x01d9: 0x4016b820, 0x01da: 0x4016cf20, 0x01db: 0x4016ec20, + 0x01dc: 0x00300608, 0x01dd: 0x002e1a08, 0x01de: 0x40171120, 0x01df: 0x002e7608, + 0x01e2: 0x002cc608, 0x01e3: 0x40166320, + 0x01e4: 0x002ea408, 0x01e5: 0x40175220, 0x01e6: 0x002ee808, 0x01e7: 0x00311a08, + 0x01e8: 0x40188d20, 0x01e9: 0x002f6e08, 0x01ea: 0x4017bc20, 0x01eb: 0x4017d420, + 0x01ec: 0x002fb008, 0x01ed: 0x4017d820, 0x01ee: 0x002fb808, + 0x01f1: 0x00301a08, 0x01f2: 0x00303208, 0x01f3: 0x00307e08, + 0x01f4: 0x40183f20, 0x01f5: 0x00309208, 0x01f6: 0x40184920, 0x01f7: 0x0030c208, + 0x01f8: 0x0030cc08, 0x01f9: 0x40186620, 0x01fa: 0x40186b20, 0x01fb: 0x40188620, + 0x01fc: 0x00312208, 0x01fd: 0x40189120, 0x01fe: 0xe0000809, 0x01ff: 0x40187d20, + // Block 0x8, offset 0x200 + 0x0200: 0x4018bc20, 0x0201: 0x4018c020, 0x0202: 0x4018c420, 0x0203: 0x4018c820, + 0x0204: 0xf0000a0a, 0x0205: 0xf000040a, 0x0206: 0xf0000404, 0x0207: 0xf0000a0a, + 0x0208: 0xf000040a, 0x0209: 0xf0000404, 0x020a: 0xf0000a0a, 0x020b: 0xf000040a, + 0x020c: 0xf0000404, + 0x021d: 0x40160a20, + 0x0224: 0x002ca008, 0x0225: 0x40165020, + 0x0231: 0xf0000a0a, 0x0232: 0xf000040a, 0x0233: 0xf0000404, + 0x0236: 0x002cde08, 0x0237: 0x0030fa08, + // Block 0x9, offset 0x240 + 0x025c: 0x0030e608, 0x025d: 0x40187320, + 0x0260: 0x002e2208, 0x0261: 0x4015f920, 0x0262: 0x002e8808, 0x0263: 0x40174420, + 0x0264: 0x00309e08, 0x0265: 0x40184f20, + 0x0274: 0x4016e220, 0x0275: 0x40171b20, 0x0276: 0x4017e020, 0x0277: 0x40169d20, + 0x0278: 0xe000074b, 0x0279: 0xe00007c8, 0x027a: 0x002b5008, 0x027b: 0x002bac08, + 0x027c: 0x4015d620, 0x027d: 0x002d9e08, 0x027e: 0x002fa408, 0x027f: 0x4017b120, + // Block 0xa, offset 0x280 + 0x0280: 0x40185b20, 0x0281: 0x00313a08, 0x0282: 0x40189d20, 0x0283: 0x002b8208, + 0x0284: 0x002fe208, 0x0285: 0x00304008, 0x0286: 0x002c0808, 0x0287: 0x40160420, + 0x0288: 0x002d4408, 0x0289: 0x4016a220, 0x028a: 0x002ed008, 0x028b: 0x40176820, + 0x028c: 0x002ef408, 0x028d: 0x40177a20, 0x028e: 0x00307608, 0x028f: 0x40183b20, + 0x0290: 0x4015ac20, 0x0291: 0x4015b020, 0x0292: 0x4015b520, 0x0293: 0x4015c920, + 0x0294: 0x40173020, 0x0295: 0x4015de20, 0x0296: 0x4015ec20, 0x0297: 0x4015f020, + 0x0298: 0x40161920, 0x0299: 0x40160f20, 0x029a: 0x40161d20, 0x029b: 0x40161420, + 0x029c: 0x40162120, 0x029d: 0x40162720, 0x029e: 0x40162b20, 0x029f: 0x4016aa20, + 0x02a0: 0x40165520, 0x02a1: 0x40164820, 0x02a2: 0x40164c20, 0x02a3: 0x40165f20, + 0x02a4: 0x40163320, 0x02a5: 0x4017f720, 0x02a6: 0x40167320, 0x02a7: 0x40167a20, + 0x02a8: 0x40168e20, 0x02a9: 0x40169420, 0x02aa: 0x40168820, 0x02ab: 0x4016d420, + 0x02ac: 0x4016d820, 0x02ad: 0x4016dd20, 0x02ae: 0x4016e720, 0x02af: 0x40180320, + 0x02b0: 0x40180920, 0x02b1: 0x4016fb20, 0x02b2: 0x40170d20, 0x02b3: 0x40171720, + 0x02b4: 0x40170620, 0x02b5: 0x40173b20, 0x02b6: 0x40172a20, 0x02b7: 0x40174020, + 0x02b8: 0x40175920, 0x02b9: 0x40177f20, 0x02ba: 0x40178420, 0x02bb: 0x40178920, + 0x02bc: 0x40178e20, 0x02bd: 0x40179220, 0x02be: 0x40179620, 0x02bf: 0x40179b20, + // Block 0xb, offset 0x2c0 + 0x02c0: 0x40177420, 0x02c1: 0x40179f20, 0x02c2: 0x4017ad20, 0x02c3: 0x4017b720, + 0x02c4: 0x4016ae20, 0x02c5: 0x4017c020, 0x02c6: 0x4017c520, 0x02c7: 0x4017e520, + 0x02c8: 0x4017dc20, 0x02c9: 0x4017f120, 0x02ca: 0x40180d20, 0x02cb: 0x40181920, + 0x02cc: 0x40182020, 0x02cd: 0x40182a20, 0x02ce: 0x4016f020, 0x02cf: 0x40183720, + 0x02d0: 0x40185320, 0x02d1: 0x40185720, 0x02d2: 0x40186120, 0x02d3: 0x40186f20, + 0x02d4: 0x40189920, 0x02d5: 0x4018a720, 0x02d6: 0x4018b820, 0x02d7: 0x4018cc20, + 0x02d8: 0x4018d020, 0x02d9: 0x4015bd20, 0x02da: 0x40162f20, 0x02db: 0x40165920, + 0x02dc: 0x40166b20, 0x02dd: 0x4016a620, 0x02de: 0x4016c020, 0x02df: 0x4016c820, + 0x02e0: 0x40176420, 0x02e1: 0x4018b020, 0x02e2: 0x4018b420, 0x02e3: 0xe000074e, + 0x02e4: 0xe0000754, 0x02e5: 0xe0000751, 0x02e6: 0xe000080c, 0x02e7: 0xe000080f, + 0x02e8: 0xe0000802, 0x02e9: 0xe000075d, 0x02ea: 0xe000079b, 0x02eb: 0xe000079e, + 0x02ec: 0x4018d420, 0x02ed: 0x4018d820, 0x02ee: 0x4017fb20, 0x02ef: 0x4017ff20, + 0x02f0: 0xf0000014, 0x02f1: 0xf0000014, 0x02f2: 0xf0000014, 0x02f3: 0xf0000014, + 0x02f4: 0xf0000014, 0x02f5: 0xf0000014, 0x02f6: 0xf0000014, 0x02f7: 0xf0000014, + 0x02f8: 0xf0000014, 0x02f9: 0x40032020, 0x02fa: 0x40032220, 0x02fb: 0x40167e20, + 0x02fc: 0x4018a220, 0x02fd: 0x40167f20, 0x02fe: 0x4018a420, 0x02ff: 0x4018ab20, + // Block 0xc, offset 0x300 + 0x0300: 0x4018a120, 0x0301: 0x4018ac20, 0x0302: 0x40032320, 0x0303: 0x40032420, + 0x0304: 0x40032520, 0x0305: 0x40032620, 0x0306: 0x40032720, 0x0307: 0x40032820, + 0x0308: 0x40032920, 0x0309: 0x40032a20, 0x030a: 0x40032b20, 0x030b: 0x40032c20, + 0x030c: 0x40032d20, 0x030d: 0x40032e20, 0x030e: 0x40032f20, 0x030f: 0x40033020, + 0x0310: 0x40139220, 0x0311: 0x40139320, 0x0312: 0x40033120, 0x0313: 0x40033220, + 0x0314: 0x40033320, 0x0315: 0x40033420, 0x0316: 0x40033520, 0x0317: 0x40033620, + 0x0318: 0x4002f320, 0x0319: 0x4002f420, 0x031a: 0x4002f620, 0x031b: 0x4002fb20, + 0x031c: 0x4002f020, 0x031d: 0x4002f720, 0x031e: 0x40033720, 0x031f: 0x40033820, + 0x0320: 0xf0000014, 0x0321: 0xf0000014, 0x0322: 0xf0000014, 0x0323: 0xf0000014, + 0x0324: 0xf0000014, 0x0325: 0x40033920, 0x0326: 0x40033a20, 0x0327: 0x40033b20, + 0x0328: 0x40033c20, 0x0329: 0x40033d20, 0x032a: 0x40033e20, 0x032b: 0x40033f20, + 0x032c: 0x40034020, 0x032d: 0x40034120, 0x032e: 0x4018a320, 0x032f: 0x40034220, + 0x0330: 0x40034320, 0x0331: 0x40034420, 0x0332: 0x40034520, 0x0333: 0x40034620, + 0x0334: 0x40034720, 0x0335: 0x40034820, 0x0336: 0x40034920, 0x0337: 0x40034a20, + 0x0338: 0x40034b20, 0x0339: 0x40034c20, 0x033a: 0x40034d20, 0x033b: 0x40034e20, + 0x033c: 0x40034f20, 0x033d: 0x40035020, 0x033e: 0x40035120, 0x033f: 0x40035220, + // Block 0xd, offset 0x340 + 0x0340: 0x80003502, 0x0341: 0x80003202, 0x0342: 0x80003c02, 0x0343: 0x80004e02, + 0x0344: 0x80005b02, 0x0345: 0x80006302, 0x0346: 0x80003702, 0x0347: 0x80005202, + 0x0348: 0x80004702, 0x0349: 0x80006402, 0x034a: 0x80004302, 0x034b: 0x80004d02, + 0x034c: 0x80004102, 0x034d: 0x80005f02, 0x034e: 0x80005f02, 0x034f: 0x80006502, + 0x0350: 0x80006602, 0x0351: 0x80006702, 0x0352: 0x80005f02, 0x0353: 0x80002202, + 0x0354: 0x80002a02, 0x0355: 0x80005f02, 0x0356: 0x80006002, 0x0357: 0x80006002, + 0x0358: 0x80006002, 0x0359: 0x80006002, 0x035a: 0x80005f02, 0x035b: 0x80006802, + 0x035c: 0x80006002, 0x035d: 0x80006002, 0x035e: 0x80006002, 0x035f: 0x80006002, + 0x0360: 0x80006002, 0x0361: 0x80006e02, 0x0362: 0x80006f02, 0x0363: 0x80007002, + 0x0364: 0x80007502, 0x0365: 0x80007602, 0x0366: 0x80007702, 0x0367: 0x80005602, + 0x0368: 0x80005902, 0x0369: 0x80006002, 0x036a: 0x80006002, 0x036b: 0x80006002, + 0x036c: 0x80006002, 0x036d: 0x80007802, 0x036e: 0x80007902, 0x036f: 0x80006002, + 0x0370: 0x80007a02, 0x0371: 0x80007b02, 0x0372: 0x80002102, 0x0373: 0x80006002, + 0x0374: 0x80007c02, 0x0375: 0x80007d02, 0x0376: 0x80006102, 0x0377: 0x80006102, + 0x0378: 0x80005402, 0x0379: 0x80007e02, 0x037a: 0x80006002, 0x037b: 0x80006002, + 0x037c: 0x80006002, 0x037d: 0x80005f02, 0x037e: 0x80005f02, 0x037f: 0x80005f02, + // Block 0xe, offset 0x380 + 0x0382: 0x80004502, + 0x0385: 0x80007f02, 0x0386: 0x80005f02, 0x0387: 0x80006002, + 0x0388: 0x80006002, 0x0389: 0x80006002, 0x038a: 0x80005f02, 0x038b: 0x80005f02, + 0x038c: 0x80005f02, 0x038d: 0x80006002, 0x038e: 0x80006002, 0x038f: 0x80000000, + 0x0390: 0x80005f02, 0x0391: 0x80005f02, 0x0392: 0x80005f02, 0x0393: 0x80006002, + 0x0394: 0x80006002, 0x0395: 0x80006002, 0x0396: 0x80006002, 0x0397: 0x80005f02, + 0x0398: 0x80008002, 0x0399: 0x80006002, 0x039a: 0x80006002, 0x039b: 0x80005f02, + 0x039c: 0x80006002, 0x039d: 0x80005f02, 0x039e: 0x80005f02, 0x039f: 0x80006002, + 0x03a0: 0x80008102, 0x03a1: 0x80008202, 0x03a2: 0x80006002, 0x03a3: 0x002b4604, + 0x03a4: 0x002bfe04, 0x03a5: 0x002d0004, 0x03a6: 0x002e4804, 0x03a7: 0x002fd204, + 0x03a8: 0x002ba204, 0x03a9: 0x002bc804, 0x03aa: 0x002cce04, 0x03ab: 0x002de804, + 0x03ac: 0x002ee004, 0x03ad: 0x002f9204, 0x03ae: 0x00302404, 0x03af: 0x00305c04, + 0x03b0: 0x0031cc08, 0x03b1: 0x4018e620, 0x03b2: 0x00320c08, 0x03b3: 0x40190620, + 0x03b5: 0x40032120, 0x03b6: 0x0031c608, 0x03b7: 0x4018e320, + 0x03ba: 0x0031d204, 0x03bb: 0x4018fc20, + 0x03bc: 0x4018fb20, 0x03bd: 0x4018fd20, + // Block 0xf, offset 0x3c0 + 0x03c4: 0x4002ef20, + 0x03d1: 0x0031b808, 0x03d2: 0x0031ba08, 0x03d3: 0x0031bc08, + 0x03d4: 0x0031c008, 0x03d5: 0x0031c208, 0x03d6: 0x0031ca08, 0x03d7: 0x0031ce08, + 0x03d8: 0x0031d008, 0x03d9: 0x0031d208, 0x03da: 0x0031d608, 0x03db: 0x0031d808, + 0x03dc: 0x0031dc08, 0x03dd: 0x0031de08, 0x03de: 0x0031e008, 0x03df: 0x0031e208, + 0x03e0: 0x0031e408, 0x03e1: 0x0031ee08, 0x03e3: 0x0031f408, + 0x03e4: 0x0031fc08, 0x03e5: 0x0031fe08, 0x03e6: 0x00320008, 0x03e7: 0x00320208, + 0x03e8: 0x00320408, 0x03e9: 0x00320808, + 0x03f1: 0x4018dc20, 0x03f2: 0x4018dd20, 0x03f3: 0x4018de20, + 0x03f4: 0x4018e020, 0x03f5: 0x4018e120, 0x03f6: 0x4018e520, 0x03f7: 0x4018e720, + 0x03f8: 0x4018e820, 0x03f9: 0x4018e920, 0x03fa: 0x4018eb20, 0x03fb: 0x4018ec20, + 0x03fc: 0x4018ee20, 0x03fd: 0x4018ef20, 0x03fe: 0x4018f020, 0x03ff: 0x4018f120, + // Block 0x10, offset 0x400 + 0x0400: 0x4018f220, 0x0401: 0x4018f720, 0x0402: 0x0031f419, 0x0403: 0x4018fa20, + 0x0404: 0x4018fe20, 0x0405: 0x4018ff20, 0x0406: 0x40190020, 0x0407: 0x40190120, + 0x0408: 0x40190220, 0x0409: 0x40190420, + 0x040f: 0xe000082f, + 0x0410: 0xf0000004, 0x0411: 0xf0000004, 0x0412: 0xf000000a, + 0x0415: 0xf0000004, 0x0416: 0xf0000004, 0x0417: 0xe000082b, + 0x0418: 0x0031ec08, 0x0419: 0x4018f620, 0x041a: 0x0031c808, 0x041b: 0x4018e420, + 0x041c: 0x0031c408, 0x041d: 0x4018e220, 0x041e: 0x0031ea08, 0x041f: 0x4018f520, + 0x0420: 0x00320a08, 0x0421: 0x40190520, 0x0422: 0x00324e08, 0x0423: 0x40192720, + 0x0424: 0x00325808, 0x0425: 0x40192c20, 0x0426: 0x00325a08, 0x0427: 0x40192d20, + 0x0428: 0x00325e08, 0x0429: 0x40192f20, 0x042a: 0x00326c08, 0x042b: 0x40193620, + 0x042c: 0x00327208, 0x042d: 0x40193920, 0x042e: 0x00327a08, 0x042f: 0x40193d20, + 0x0430: 0xf0000004, 0x0431: 0xf0000004, 0x0432: 0xf0000004, 0x0433: 0x4018ea20, + 0x0434: 0xf000000a, 0x0435: 0xf0000004, 0x0436: 0x40048020, 0x0437: 0x00320e08, + 0x0438: 0x40190720, 0x0439: 0xf000000a, 0x043a: 0x0031e808, 0x043b: 0x4018f420, + 0x043c: 0x4018f920, 0x043d: 0x0031f808, 0x043e: 0x0031f608, 0x043f: 0x0031fa08, + // Block 0x11, offset 0x440 + 0x0442: 0x0032fa08, 0x0443: 0x00330608, + 0x0444: 0x00332608, 0x0445: 0x00336008, 0x0446: 0xc02a0071, 0x0447: 0x00339a08, + 0x0448: 0x0033aa08, 0x0449: 0x0033fe08, 0x044a: 0x00344808, 0x044b: 0x0034c608, + 0x044c: 0x0034ce08, 0x044e: 0x0034de08, 0x044f: 0x0035b808, + 0x0450: 0xc0090041, 0x0451: 0x0032b608, 0x0452: 0x0032be08, 0x0453: 0xc0130092, + 0x0454: 0x0032ee08, 0x0455: 0xc01800d1, 0x0456: 0xc01c0071, 0x0457: 0xc0200071, + 0x0458: 0xc0250041, 0x0459: 0x0033a208, 0x045a: 0xc0370092, 0x045b: 0x0033e808, + 0x045c: 0x00340c08, 0x045d: 0x00341e08, 0x045e: 0xc02e0071, 0x045f: 0x00347208, + 0x0460: 0x00348c08, 0x0461: 0x00349e08, 0x0462: 0x0034b008, 0x0463: 0xc03e00f1, + 0x0464: 0x00351008, 0x0465: 0x00351808, 0x0466: 0x00356608, 0x0467: 0xc0440071, + 0x0468: 0x0035c008, 0x0469: 0x0035ca08, 0x046a: 0x0035d808, 0x046b: 0xc0480071, + 0x046c: 0x0035f208, 0x046d: 0xc04c0071, 0x046e: 0x00361c08, 0x046f: 0x00362808, + 0x0470: 0xc0060041, 0x0471: 0x40195b20, 0x0472: 0x40195f20, 0x0473: 0xc0100092, + 0x0474: 0x40197720, 0x0475: 0xc01600d1, 0x0476: 0xc01a0071, 0x0477: 0xc01e0071, + 0x0478: 0xc0220041, 0x0479: 0x4019d120, 0x047a: 0xc0340092, 0x047b: 0x4019f420, + 0x047c: 0x401a0620, 0x047d: 0x401a0f20, 0x047e: 0xc02c0071, 0x047f: 0x401a3920, + // Block 0x12, offset 0x480 + 0x0480: 0x401a4620, 0x0481: 0x401a4f20, 0x0482: 0x401a5820, 0x0483: 0xc03a00f1, + 0x0484: 0x401a8820, 0x0485: 0x401a8c20, 0x0486: 0x401ab320, 0x0487: 0xc0420071, + 0x0488: 0x401ae020, 0x0489: 0x401ae520, 0x048a: 0x401aec20, 0x048b: 0xc0460071, + 0x048c: 0x401af920, 0x048d: 0xc04a0071, 0x048e: 0x401b0e20, 0x048f: 0x401b1420, + 0x0492: 0x40197d20, 0x0493: 0x40198320, + 0x0494: 0x40199320, 0x0495: 0x4019b020, 0x0496: 0xc0280071, 0x0497: 0x4019cd20, + 0x0498: 0x4019d520, 0x0499: 0x4019ff20, 0x049a: 0x401a2420, 0x049b: 0x401a6320, + 0x049c: 0x401a6720, 0x049e: 0x401a6f20, 0x049f: 0x401adc20, + 0x04a0: 0x00354408, 0x04a1: 0x401aa220, 0x04a2: 0x00360208, 0x04a3: 0x401b0120, + 0x04a4: 0x00363208, 0x04a5: 0x401b1920, 0x04a6: 0x00363a08, 0x04a7: 0x401b1d20, + 0x04a8: 0x00364e08, 0x04a9: 0x401b2720, 0x04aa: 0x00364408, 0x04ab: 0x401b2220, + 0x04ac: 0x00365808, 0x04ad: 0x401b2c20, 0x04ae: 0x00366008, 0x04af: 0x401b3020, + 0x04b0: 0x00366808, 0x04b1: 0x401b3420, 0x04b2: 0x00367008, 0x04b3: 0x401b3820, + 0x04b4: 0xc0500131, 0x04b5: 0xc04e0131, 0x04b6: 0x00368008, 0x04b7: 0x401b4020, + 0x04b8: 0x00350808, 0x04b9: 0x401a8420, 0x04ba: 0x00355e08, 0x04bb: 0x401aaf20, + 0x04bc: 0x00355608, 0x04bd: 0x401aab20, 0x04be: 0x00354c08, 0x04bf: 0x401aa620, + // Block 0x13, offset 0x4c0 + 0x04c0: 0x00348408, 0x04c1: 0x401a4220, 0x04c2: 0x40038320, 0x04c3: 0x80008302, + 0x04c4: 0x80005f02, 0x04c5: 0x80002a02, 0x04c6: 0x80002202, 0x04c7: 0x80005f02, + 0x04c8: 0x80000000, 0x04c9: 0x80000000, 0x04ca: 0x00338008, 0x04cb: 0x4019c020, + 0x04cc: 0x0035fa08, 0x04cd: 0x401afd20, 0x04ce: 0x00349408, 0x04cf: 0x401a4a20, + 0x04d0: 0xe000083a, 0x04d1: 0xe0000837, 0x04d2: 0x0032ce08, 0x04d3: 0x40196720, + 0x04d4: 0x0032de08, 0x04d5: 0x40196f20, 0x04d6: 0x00334008, 0x04d7: 0x4019a020, + 0x04d8: 0x00330e08, 0x04d9: 0x40198720, 0x04da: 0x0033bc08, 0x04db: 0x4019de20, + 0x04dc: 0x0033dc08, 0x04dd: 0x4019ee20, 0x04de: 0x0033d408, 0x04df: 0x4019ea20, + 0x04e0: 0x0033cc08, 0x04e1: 0x4019e620, 0x04e2: 0x00342e08, 0x04e3: 0x401a1720, + 0x04e4: 0x00344008, 0x04e5: 0x401a2020, 0x04e6: 0x00347c08, 0x04e7: 0x401a3e20, + 0x04e8: 0x00368a08, 0x04e9: 0x401b4520, 0x04ea: 0x0034a808, 0x04eb: 0x401a5420, + 0x04ec: 0x0034bc08, 0x04ed: 0x401a5e20, 0x04ee: 0x0034f608, 0x04ef: 0x401a7b20, + 0x04f0: 0x0034fe08, 0x04f1: 0x401a7f20, 0x04f2: 0x00353008, 0x04f3: 0x401a9820, + 0x04f4: 0x00357208, 0x04f5: 0x401ab920, 0x04f6: 0x00358e08, 0x04f7: 0x401ac720, + 0x04f8: 0x00359e08, 0x04f9: 0x401acf20, 0x04fa: 0x00353808, 0x04fb: 0x401a9c20, + 0x04fc: 0x0035a808, 0x04fd: 0x401ad420, 0x04fe: 0x0035b008, 0x04ff: 0x401ad820, + // Block 0x14, offset 0x500 + 0x0500: 0x00369408, 0x0503: 0x0033c408, + 0x0504: 0x4019e220, 0x0505: 0x0033f208, 0x0506: 0x4019f920, 0x0507: 0x00343608, + 0x0508: 0x401a1b20, 0x0509: 0x00342608, 0x050a: 0x401a1320, 0x050b: 0x00359608, + 0x050c: 0x401acb20, 0x050d: 0x00341408, 0x050e: 0x401a0a20, 0x050f: 0x401b4a20, + 0x0510: 0x00328e08, 0x0511: 0x40194720, 0x0512: 0x00329608, 0x0513: 0x40194b20, + 0x0514: 0x0032ae08, 0x0515: 0x40195720, 0x0516: 0x00331e08, 0x0517: 0x40198f20, + 0x0518: 0xc00e0071, 0x0519: 0xc00c0071, 0x051a: 0x0032a608, 0x051b: 0x40195320, + 0x051c: 0x00333808, 0x051d: 0x40199c20, 0x051e: 0x00335608, 0x051f: 0x4019ab20, + 0x0520: 0x00336a08, 0x0521: 0x4019b520, + 0x0524: 0x00338808, 0x0525: 0x4019c420, 0x0526: 0x00345a08, 0x0527: 0x401a2d20, + 0x0528: 0xc0320071, 0x0529: 0xc0300071, 0x052a: 0x00346a08, 0x052b: 0x401a3520, + 0x052c: 0x00361408, 0x052d: 0x401b0a20, + 0x0530: 0x0034e608, 0x0531: 0x401a7320, 0x0532: 0x0034ee08, 0x0533: 0x401a7720, + 0x0534: 0x00358608, 0x0535: 0x401ac320, 0x0536: 0x0032e608, 0x0537: 0x40197320, + 0x0538: 0x0035ea08, 0x0539: 0x401af520, 0x053a: 0x0032d608, 0x053b: 0x40196b20, + 0x053c: 0x00352008, 0x053d: 0x401a9020, 0x053e: 0x00352808, 0x053f: 0x401a9420, + // Block 0x15, offset 0x540 + 0x0540: 0x0032f608, 0x0541: 0x40197b20, 0x0542: 0x00330408, 0x0543: 0x40198220, + 0x0544: 0x00335208, 0x0545: 0x4019a920, 0x0546: 0x00337408, 0x0547: 0x4019ba20, + 0x0548: 0x00340808, 0x0549: 0x401a0420, 0x054a: 0x00345008, 0x054b: 0x401a2820, + 0x054c: 0x0034a608, 0x054d: 0x401a5320, 0x054e: 0x0034ba08, 0x054f: 0x401a5d20, + 0x0550: 0x00335408, 0x0551: 0x4019aa20, 0x0552: 0x0033fa08, 0x0553: 0x4019fd20, + 0x0554: 0x00340a08, 0x0555: 0x401a0520, 0x0556: 0x00349c08, 0x0557: 0x401a4e20, + 0x0558: 0x00363008, 0x0559: 0x401b1820, 0x055a: 0x0033e608, 0x055b: 0x4019f320, + 0x055c: 0x00369208, 0x055d: 0x401b4920, 0x055e: 0x0033e408, 0x055f: 0x4019f220, + 0x0560: 0x0033fc08, 0x0561: 0x4019fe20, 0x0562: 0x00343e08, 0x0563: 0x401a1f20, + 0x0564: 0x00347a08, 0x0565: 0x401a3d20, 0x0566: 0x00354008, 0x0567: 0x401aa020, + 0x0571: 0x00379c08, 0x0572: 0x00379e08, 0x0573: 0x0037a008, + 0x0574: 0x0037a208, 0x0575: 0x0037a408, 0x0576: 0x0037a608, 0x0577: 0x0037a808, + 0x0578: 0x0037aa08, 0x0579: 0x0037ac08, 0x057a: 0x0037ae08, 0x057b: 0x0037b008, + 0x057c: 0x0037b208, 0x057d: 0x0037b408, 0x057e: 0x0037b608, 0x057f: 0x0037b808, + // Block 0x16, offset 0x580 + 0x0580: 0x0037ba08, 0x0581: 0x0037bc08, 0x0582: 0x0037be08, 0x0583: 0x0037c008, + 0x0584: 0x0037c208, 0x0585: 0x0037c408, 0x0586: 0x0037c608, 0x0587: 0x0037c808, + 0x0588: 0x0037ca08, 0x0589: 0x0037cc08, 0x058a: 0x0037ce08, 0x058b: 0x0037d008, + 0x058c: 0x0037d208, 0x058d: 0x0037d408, 0x058e: 0x0037d608, 0x058f: 0x0037d808, + 0x0590: 0x0037da08, 0x0591: 0x0037dc08, 0x0592: 0x0037de08, 0x0593: 0x0037e008, + 0x0594: 0x0037e208, 0x0595: 0x0037e408, 0x0596: 0x0037e608, + 0x0599: 0x401bf420, 0x059a: 0x40027520, 0x059b: 0x40027620, + 0x059c: 0x40015a20, 0x059d: 0x40012020, 0x059e: 0x40016020, 0x059f: 0x40027720, + 0x05a1: 0x401bce20, 0x05a2: 0x401bcf20, 0x05a3: 0x401bd020, + 0x05a4: 0x401bd120, 0x05a5: 0x401bd220, 0x05a6: 0x401bd320, 0x05a7: 0x401bd420, + 0x05a8: 0x401bd520, 0x05a9: 0x401bd620, 0x05aa: 0x401bd720, 0x05ab: 0x401bd820, + 0x05ac: 0x401bd920, 0x05ad: 0x401bda20, 0x05ae: 0x401bdb20, 0x05af: 0x401bdc20, + 0x05b0: 0x401bdd20, 0x05b1: 0x401bde20, 0x05b2: 0x401bdf20, 0x05b3: 0x401be020, + 0x05b4: 0x401be120, 0x05b5: 0x401be220, 0x05b6: 0x401be320, 0x05b7: 0x401be420, + 0x05b8: 0x401be520, 0x05b9: 0x401be620, 0x05ba: 0x401be720, 0x05bb: 0x401be820, + 0x05bc: 0x401be920, 0x05bd: 0x401bea20, 0x05be: 0x401beb20, 0x05bf: 0x401bec20, + // Block 0x17, offset 0x5c0 + 0x05c0: 0x401bed20, 0x05c1: 0x401bee20, 0x05c2: 0x401bef20, 0x05c3: 0x401bf020, + 0x05c4: 0x401bf120, 0x05c5: 0x401bf220, 0x05c6: 0x401bf320, 0x05c7: 0xf0000404, + 0x05c9: 0x40013320, 0x05ca: 0x40010f20, + 0x05d1: 0x80000000, 0x05d2: 0x80000000, 0x05d3: 0x80000000, + 0x05d4: 0x80000000, 0x05d5: 0x80000000, 0x05d6: 0x80000000, 0x05d7: 0x80000000, + 0x05d8: 0x80000000, 0x05d9: 0x80000000, 0x05da: 0x80000000, 0x05db: 0x80000000, + 0x05dc: 0x80000000, 0x05dd: 0x80000000, 0x05de: 0x80000000, 0x05df: 0x80000000, + 0x05e0: 0x80000000, 0x05e1: 0x80000000, 0x05e2: 0x80000000, 0x05e3: 0x80000000, + 0x05e4: 0x80000000, 0x05e5: 0x80000000, 0x05e6: 0x80000000, 0x05e7: 0x80000000, + 0x05e8: 0x80000000, 0x05e9: 0x80000000, 0x05ea: 0x80000000, 0x05eb: 0x80000000, + 0x05ec: 0x80000000, 0x05ed: 0x80000000, 0x05ee: 0x80000000, 0x05ef: 0x80000000, + 0x05f0: 0x80008502, 0x05f1: 0x80008602, 0x05f2: 0x80008702, 0x05f3: 0x80008802, + 0x05f4: 0x80008902, 0x05f5: 0x80008a02, 0x05f6: 0x80008b02, 0x05f7: 0x80008c02, + 0x05f8: 0x80008d02, 0x05f9: 0x80008e02, 0x05fa: 0x80008e02, 0x05fb: 0x80008f02, + 0x05fc: 0x80009202, 0x05fd: 0x80000000, 0x05fe: 0x40027820, 0x05ff: 0x80009502, + // Block 0x18, offset 0x600 + 0x0600: 0x40027920, 0x0601: 0x80009102, 0x0602: 0x80009002, 0x0603: 0x40027a20, + 0x0604: 0x80000000, 0x0605: 0x80000000, 0x0606: 0x40027b20, 0x0607: 0x80008d02, + 0x0610: 0x401bf520, 0x0611: 0x401bf620, 0x0612: 0x401bf720, 0x0613: 0x401bf820, + 0x0614: 0x401bf920, 0x0615: 0x401bfa20, 0x0616: 0x401bfb20, 0x0617: 0x401bfc20, + 0x0618: 0x401bfd20, 0x0619: 0x401bfe20, 0x061a: 0x0037fe19, 0x061b: 0x401bff20, + 0x061c: 0x401c0020, 0x061d: 0x00380219, 0x061e: 0x401c0120, 0x061f: 0x00380419, + 0x0620: 0x401c0220, 0x0621: 0x401c0320, 0x0622: 0x401c0420, 0x0623: 0x00380a19, + 0x0624: 0x401c0520, 0x0625: 0x00380c19, 0x0626: 0x401c0620, 0x0627: 0x401c0720, + 0x0628: 0x401c0820, 0x0629: 0x401c0920, 0x062a: 0x401c0a20, + 0x0630: 0xe0000840, 0x0631: 0xe0000843, 0x0632: 0xe0000846, 0x0633: 0x40027c20, + 0x0634: 0x40027d20, + // Block 0x19, offset 0x640 + 0x0640: 0x80000000, 0x0641: 0x80000000, 0x0642: 0x80000000, 0x0643: 0x80000000, + 0x0646: 0x40049a20, 0x0647: 0x40049c20, + 0x0648: 0x40038420, 0x0649: 0x40024a20, 0x064a: 0x40024c20, 0x064b: 0x4013a820, + 0x064c: 0x40012120, 0x064d: 0x40012220, 0x064e: 0x40038520, 0x064f: 0x40038620, + 0x0650: 0x80000000, 0x0651: 0x80000000, 0x0652: 0x80000000, 0x0653: 0x80000000, + 0x0654: 0x80000000, 0x0655: 0x80000000, 0x0656: 0x80000000, 0x0657: 0x80000000, + 0x0658: 0x80000000, 0x0659: 0x80000000, 0x065a: 0x80000000, 0x065b: 0x40012f20, + 0x065e: 0x40013420, 0x065f: 0x40016120, + 0x0660: 0x401cf220, 0x0661: 0x401c3b20, 0x0662: 0x401c3c20, 0x0663: 0x401c3d20, + 0x0664: 0x401c4020, 0x0665: 0x401c4120, 0x0666: 0x401c4520, 0x0667: 0xc0520151, + 0x0668: 0x401c4820, 0x0669: 0x401c5320, 0x066a: 0x401c5420, 0x066b: 0x401c5520, + 0x066c: 0x401c5b20, 0x066d: 0x401c6120, 0x066e: 0x401c6220, 0x066f: 0x401c6c20, + 0x0670: 0x401c6d20, 0x0671: 0x401c7a20, 0x0672: 0x401c7b20, 0x0673: 0x401c8a20, + 0x0674: 0x401c8b20, 0x0675: 0x401c9520, 0x0676: 0x401c9620, 0x0677: 0x401c9a20, + 0x0678: 0x401c9b20, 0x0679: 0x401c9d20, 0x067a: 0x401c9e20, 0x067b: 0x401cc020, + 0x067c: 0x401cc120, 0x067d: 0x401cef20, 0x067e: 0x401cf020, 0x067f: 0x401cf120, + // Block 0x1a, offset 0x680 + 0x0680: 0x80000000, 0x0681: 0x401ca420, 0x0682: 0x401cae20, 0x0683: 0x401cb120, + 0x0684: 0x401cc420, 0x0685: 0x401cca20, 0x0686: 0x401ccd20, 0x0687: 0x401cd620, + 0x0688: 0xc0560171, 0x0689: 0x401ce820, 0x068a: 0xc0580171, 0x068b: 0x8000a202, + 0x068c: 0x8000a302, 0x068d: 0x8000a502, 0x068e: 0x8000a702, 0x068f: 0x8000a902, + 0x0690: 0x8000ab02, 0x0691: 0x8000ad02, 0x0692: 0x8000af02, 0x0693: 0x8000b002, + 0x0694: 0x8000b102, 0x0695: 0x8000b202, 0x0696: 0x8000b402, 0x0697: 0x8000b502, + 0x0698: 0x8000b602, 0x0699: 0x8000b702, 0x069a: 0x8000b802, 0x069b: 0x8000b902, + 0x069c: 0x8000ba02, 0x069d: 0x8000bb02, 0x069e: 0x8000bc02, 0x069f: 0x8000b302, + 0x06a0: 0xe0000021, 0x06a1: 0xe0000099, 0x06a2: 0xe0000183, 0x06a3: 0xe0000249, + 0x06a4: 0xe000030c, 0x06a5: 0xe00003c6, 0x06a6: 0xe000047d, 0x06a7: 0xe0000519, + 0x06a8: 0xe00005b5, 0x06a9: 0xe000064e, 0x06aa: 0x40024820, 0x06ab: 0x40012320, + 0x06ac: 0x40012420, 0x06ad: 0x40024020, 0x06ae: 0x401c4720, 0x06af: 0x401cad20, + 0x06b0: 0x8000bd02, 0x06b1: 0x401c3f20, 0x06b2: 0x401c3e20, 0x06b3: 0x401c4220, + 0x06b4: 0x00387604, 0x06b5: 0xf0000404, 0x06b6: 0xf0000404, 0x06b7: 0xf0000404, + 0x06b8: 0xf0000404, 0x06b9: 0x401c5620, 0x06ba: 0x401c5720, 0x06bb: 0x401c4920, + 0x06bc: 0x401c5820, 0x06bd: 0x401c5920, 0x06be: 0x401c4a20, 0x06bf: 0x401c5a20, + // Block 0x1b, offset 0x6c0 + 0x06c0: 0x401c4b20, 0x06c1: 0x401c6320, 0x06c2: 0x401c6420, 0x06c3: 0x401c5c20, + 0x06c4: 0x401c5d20, 0x06c5: 0x401c6520, 0x06c6: 0x401c5e20, 0x06c7: 0x401c6020, + 0x06c8: 0x401c6e20, 0x06c9: 0x401c6f20, 0x06ca: 0x401c7020, 0x06cb: 0x401c7120, + 0x06cc: 0x401c7220, 0x06cd: 0x401c7320, 0x06ce: 0x401c7420, 0x06cf: 0x401c7520, + 0x06d0: 0x401c7620, 0x06d1: 0x401c7c20, 0x06d2: 0x401c7d20, 0x06d3: 0x401c7e20, + 0x06d4: 0x401c7f20, 0x06d5: 0x401c8020, 0x06d6: 0x401c8120, 0x06d7: 0x401c8220, + 0x06d8: 0x401c8320, 0x06d9: 0x401c8420, 0x06da: 0x401c8c20, 0x06db: 0x401c8d20, + 0x06dc: 0x401c8e20, 0x06dd: 0x401c9720, 0x06de: 0x401c9820, 0x06df: 0x401c9c20, + 0x06e0: 0x401c9f20, 0x06e1: 0x401ca520, 0x06e2: 0x401ca620, 0x06e3: 0x401ca720, + 0x06e4: 0x401ca820, 0x06e5: 0x401ca920, 0x06e6: 0x401caa20, 0x06e7: 0x401caf20, + 0x06e8: 0x401cb020, 0x06e9: 0x401cb220, 0x06ea: 0x401cb320, 0x06eb: 0x401cb420, + 0x06ec: 0x401cb520, 0x06ed: 0x401cb720, 0x06ee: 0x401cb820, 0x06ef: 0x401cb920, + 0x06f0: 0x401cba20, 0x06f1: 0x401cbb20, 0x06f2: 0x401cbc20, 0x06f3: 0x401cbd20, + 0x06f4: 0x401cbe20, 0x06f5: 0x401cc520, 0x06f6: 0x401cc620, 0x06f7: 0x401cc720, + 0x06f8: 0x401cc820, 0x06f9: 0x401cd220, 0x06fa: 0x401cce20, 0x06fb: 0x401ccf20, + 0x06fc: 0x401cd020, 0x06fd: 0x401cd120, 0x06fe: 0x401cd720, 0x06ff: 0x401c5f20, + // Block 0x1c, offset 0x700 + 0x0701: 0x401cd820, 0x0703: 0x401cd920, + 0x0704: 0x401cdd20, 0x0705: 0x401cde20, 0x0706: 0x401cdf20, 0x0707: 0x401ce020, + 0x0708: 0x401ce120, 0x0709: 0x401ce220, 0x070a: 0x401ce320, 0x070b: 0x401ce420, + 0x070c: 0x401cea20, 0x070d: 0x401ceb20, 0x070e: 0x401cec20, 0x070f: 0x401ce520, + 0x0710: 0x401ced20, 0x0711: 0x401cee20, 0x0712: 0x401cf620, + 0x0714: 0x40016d20, 0x0715: 0x401cdb20, 0x0716: 0x80000000, 0x0717: 0x80000000, + 0x0718: 0x80000000, 0x0719: 0x80000000, 0x071a: 0x80000000, 0x071b: 0x80000000, + 0x071c: 0x80000000, 0x071d: 0x80000000, 0x071e: 0x40038720, 0x071f: 0x80000000, + 0x0720: 0x80000000, 0x0721: 0x80000000, 0x0722: 0x80000000, 0x0723: 0x80000000, + 0x0724: 0x80000000, 0x0725: 0x0039b804, 0x0726: 0x0039d204, 0x0727: 0x80000000, + 0x0728: 0x80000000, 0x0729: 0x40038820, 0x072a: 0x80000000, 0x072b: 0x80000000, + 0x072c: 0x80000000, 0x072d: 0x80000000, 0x072e: 0x401c7720, 0x072f: 0x401c8520, + 0x0730: 0xe0000024, 0x0731: 0xe000009c, 0x0732: 0xe0000186, 0x0733: 0xe000024c, + 0x0734: 0xe000030f, 0x0735: 0xe00003c9, 0x0736: 0xe0000480, 0x0737: 0xe000051c, + 0x0738: 0xe00005b8, 0x0739: 0xe0000651, 0x073a: 0x401c8f20, 0x073b: 0x401c9920, + 0x073c: 0x401ca020, 0x073d: 0xe0000849, 0x073e: 0xe00008ca, 0x073f: 0x401cda20, + // Block 0x1d, offset 0x740 + 0x0740: 0x4001a120, 0x0741: 0x40016e20, 0x0742: 0x40016f20, 0x0743: 0x40013520, + 0x0744: 0x40013620, 0x0745: 0x40013720, 0x0746: 0x40013820, 0x0747: 0x40013920, + 0x0748: 0x40013a20, 0x0749: 0x40016220, 0x074a: 0x40027e20, 0x074b: 0x40027f20, + 0x074c: 0x40028020, 0x074d: 0x40028120, 0x074f: 0x80000000, + 0x0750: 0x401cf920, 0x0751: 0x8000be02, 0x0752: 0x401cfa20, 0x0753: 0x401cfb20, + 0x0754: 0xe00008d0, 0x0755: 0x401cfd20, 0x0756: 0x401cfc20, 0x0757: 0x401cfe20, + 0x0758: 0x401cff20, 0x0759: 0x401d0020, 0x075a: 0x401d0220, 0x075b: 0x401d0320, + 0x075c: 0xe00008d9, 0x075d: 0x401d0420, 0x075e: 0x401d0520, 0x075f: 0x401d0620, + 0x0760: 0x401d0820, 0x0761: 0x401d0920, 0x0762: 0x401d0a20, 0x0763: 0x401d0b20, + 0x0764: 0x003a1619, 0x0765: 0x401d0c20, 0x0766: 0x401d0d20, 0x0767: 0xe00008dc, + 0x0768: 0x401d0f20, 0x0769: 0x401d1020, 0x076a: 0x401d1120, 0x076b: 0x401d1220, + 0x076c: 0x401d1320, 0x076d: 0xe00008cd, 0x076e: 0xe00008d3, 0x076f: 0xe00008d6, + 0x0770: 0x8000bf02, 0x0771: 0x8000c002, 0x0772: 0x8000c102, 0x0773: 0x8000c202, + 0x0774: 0x8000c302, 0x0775: 0x8000c402, 0x0776: 0x8000c502, 0x0777: 0x8000c602, + 0x0778: 0x8000c702, 0x0779: 0x8000c802, 0x077a: 0x8000c902, 0x077b: 0x8000ca02, + 0x077c: 0x8000cb02, 0x077d: 0x8000cc02, 0x077e: 0x8000cd02, 0x077f: 0x8000ce02, + // Block 0x1e, offset 0x780 + 0x0780: 0x80000000, 0x0781: 0x80005f02, 0x0782: 0x80006002, 0x0783: 0x80000000, + 0x0784: 0x80000000, 0x0785: 0x80005f02, 0x0786: 0x80006002, 0x0787: 0x80000000, + 0x0788: 0x80000000, 0x0789: 0x80000000, 0x078a: 0x80000000, + 0x078d: 0x401d0120, 0x078e: 0x401d0720, 0x078f: 0x401d0e20, + 0x0790: 0x401c4c20, 0x0791: 0x401c4d20, 0x0792: 0x401c4e20, 0x0793: 0x401c4f20, + 0x0794: 0x401c5020, 0x0795: 0x401c5120, 0x0796: 0x401c5220, 0x0797: 0x401c6620, + 0x0798: 0x401c6720, 0x0799: 0x401c7820, 0x079a: 0x401c7920, 0x079b: 0x401c8620, + 0x079c: 0x401c9020, 0x079d: 0x401ca120, 0x079e: 0x401ca220, 0x079f: 0x401ca320, + 0x07a0: 0x401cab20, 0x07a1: 0x401cac20, 0x07a2: 0x401cbf20, 0x07a3: 0x401cc220, + 0x07a4: 0x401cc320, 0x07a5: 0x401ccb20, 0x07a6: 0x401ccc20, 0x07a7: 0x401cd320, + 0x07a8: 0x401cd420, 0x07a9: 0x401cd520, 0x07aa: 0x401cc920, 0x07ab: 0x401c8720, + 0x07ac: 0x401c8820, 0x07ad: 0x401c9120, 0x07ae: 0x401c6820, 0x07af: 0x401c6920, + 0x07b0: 0x401c9220, 0x07b1: 0x401c8920, 0x07b2: 0x401c6a20, 0x07b3: 0x401c4320, + 0x07b4: 0x401c4420, 0x07b5: 0x401cf320, 0x07b6: 0x401cf420, 0x07b7: 0x401cf520, + 0x07b8: 0x401ce620, 0x07b9: 0x401ce720, 0x07ba: 0x401cf720, 0x07bb: 0x401cf820, + 0x07bc: 0x401c6b20, 0x07bd: 0x401c9320, 0x07be: 0x401c9420, 0x07bf: 0x401cb620, + // Block 0x1f, offset 0x7c0 + 0x07c0: 0x401d2d20, 0x07c1: 0x401d3020, 0x07c2: 0x401d3120, 0x07c3: 0x401d3220, + 0x07c4: 0x401d3420, 0x07c5: 0x401d3520, 0x07c6: 0x401d3620, 0x07c7: 0x401d3720, + 0x07c8: 0x401d3a20, 0x07c9: 0x401d3c20, 0x07ca: 0x401d3d20, 0x07cb: 0x401d3e20, + 0x07cc: 0x401d4020, 0x07cd: 0x401d4420, 0x07ce: 0x401d4520, 0x07cf: 0x401d4720, + 0x07d0: 0x401d4820, 0x07d1: 0x401d4c20, 0x07d2: 0x401d4d20, 0x07d3: 0x401d4e20, + 0x07d4: 0x401d4f20, 0x07d5: 0x401d5020, 0x07d6: 0x401d5120, 0x07d7: 0x401d5220, + 0x07d8: 0x401d4120, 0x07d9: 0x401d2e20, 0x07da: 0x401d2f20, 0x07db: 0x401d3f20, + 0x07dc: 0x401d3320, 0x07dd: 0x401d4920, 0x07de: 0x401d4a20, 0x07df: 0x401d4b20, + 0x07e0: 0x401d4220, 0x07e1: 0x401d4320, 0x07e2: 0x401d3820, 0x07e3: 0x401d3920, + 0x07e4: 0x401d4620, 0x07e5: 0x401d3b20, 0x07e6: 0x401d5420, 0x07e7: 0x401d5520, + 0x07e8: 0x401d5620, 0x07e9: 0x401d5720, 0x07ea: 0x401d5820, 0x07eb: 0x401d5920, + 0x07ec: 0x401d5a20, 0x07ed: 0x401d5b20, 0x07ee: 0x401d5c20, 0x07ef: 0x401d5d20, + 0x07f0: 0x401d5e20, 0x07f1: 0x401d5320, + // Block 0x20, offset 0x800 + 0x0800: 0xe0000027, 0x0801: 0xe00000a2, 0x0802: 0xe000018c, 0x0803: 0xe0000252, + 0x0804: 0xe0000315, 0x0805: 0xe00003cf, 0x0806: 0xe0000486, 0x0807: 0xe0000522, + 0x0808: 0xe00005be, 0x0809: 0xe0000657, 0x080a: 0x401d5f20, 0x080b: 0x401d6020, + 0x080c: 0x401d6120, 0x080d: 0x401d6220, 0x080e: 0x401d6320, 0x080f: 0x401d6420, + 0x0810: 0x401d6520, 0x0811: 0x401d6620, 0x0812: 0x401d6720, 0x0813: 0x401d6820, + 0x0814: 0x401d6920, 0x0815: 0x401d6a20, 0x0816: 0x401d6b20, 0x0817: 0x401d6c20, + 0x0818: 0x401d6d20, 0x0819: 0x401d6e20, 0x081a: 0x401d6f20, 0x081b: 0x401d7020, + 0x081c: 0x401d7120, 0x081d: 0x401d7220, 0x081e: 0x401d7320, 0x081f: 0x401d7420, + 0x0820: 0x401d7520, 0x0821: 0x401d7620, 0x0822: 0x401d7720, 0x0823: 0x401d7820, + 0x0824: 0x401d7920, 0x0825: 0x401d7a20, 0x0826: 0x401d7b20, 0x0827: 0x401d7c20, + 0x0828: 0xe00008df, 0x0829: 0xe00008e2, 0x082a: 0xe00008e5, 0x082b: 0x8000cf02, + 0x082c: 0x8000d002, 0x082d: 0x8000d102, 0x082e: 0x8000d202, 0x082f: 0x8000d302, + 0x0830: 0x8000d402, 0x0831: 0x8000d502, 0x0832: 0x8000d602, 0x0833: 0x8000d702, + 0x0834: 0x401d7d20, 0x0835: 0x401d7e20, 0x0836: 0x40038a20, 0x0837: 0x4001a220, + 0x0838: 0x40012520, 0x0839: 0x40015b20, 0x083a: 0x80000000, + // Block 0x21, offset 0x840 + 0x0840: 0x401c2120, 0x0841: 0x401c2220, 0x0842: 0x401c2320, 0x0843: 0x401c2420, + 0x0844: 0x401c2520, 0x0845: 0x401c2620, 0x0846: 0x401c2720, 0x0847: 0x401c2820, + 0x0848: 0x401c2920, 0x0849: 0x401c2a20, 0x084a: 0x401c2b20, 0x084b: 0x401c2c20, + 0x084c: 0x401c2d20, 0x084d: 0x401c2e20, 0x084e: 0x401c2f20, 0x084f: 0x401c3020, + 0x0850: 0x401c3120, 0x0851: 0x401c3220, 0x0852: 0x401c3320, 0x0853: 0x401c3420, + 0x0854: 0x401c3520, 0x0855: 0x401c3620, 0x0856: 0x401c3720, 0x0857: 0x401c3820, + 0x0858: 0x80009f02, 0x0859: 0x8000a002, 0x085a: 0x401c3920, 0x085b: 0x401c3a20, + 0x085c: 0x80009702, 0x085d: 0x80009702, 0x085e: 0x80009802, 0x085f: 0x80009802, + 0x0860: 0x80009802, 0x0861: 0x80009902, 0x0862: 0x80009902, 0x0863: 0x80009902, + 0x0864: 0x80009a02, 0x0865: 0x80009a02, 0x0866: 0x80009b02, 0x0867: 0x80009b02, + 0x0868: 0x80009c02, 0x0869: 0x80009c02, 0x086a: 0x80009c02, 0x086b: 0x80009d02, + 0x086c: 0x80009e02, 0x086d: 0x8000a102, + 0x0870: 0x40013b20, 0x0871: 0x40013c20, 0x0872: 0x40013d20, 0x0873: 0x40013e20, + 0x0874: 0x40013f20, 0x0875: 0x40014020, 0x0876: 0x40014120, 0x0877: 0x40014220, + 0x0878: 0x40014320, 0x0879: 0x40014420, 0x087a: 0x40014520, 0x087b: 0x40014620, + 0x087c: 0x40014720, 0x087d: 0x40014820, 0x087e: 0x40014920, + // Block 0x22, offset 0x880 + 0x0880: 0x401d1420, 0x0881: 0x401d1520, 0x0882: 0x401d1620, 0x0883: 0x401d1720, + 0x0884: 0x401d1820, 0x0885: 0x401d1920, 0x0886: 0x401d1a20, 0x0887: 0x401d1b20, + 0x0888: 0x401d1c20, 0x0889: 0x401d1d20, 0x088a: 0x401d1e20, 0x088b: 0x401d1f20, + 0x088c: 0x401d2020, 0x088d: 0x401d2120, 0x088e: 0x401d2220, 0x088f: 0x401d2320, + 0x0890: 0x401d2420, 0x0891: 0x401d2520, 0x0892: 0x401d2620, 0x0893: 0x401d2720, + 0x0894: 0x401d2820, 0x0895: 0x401d2920, 0x0896: 0x401d2a20, 0x0897: 0x401d2b20, + 0x0898: 0x401d2c20, 0x0899: 0x80006002, 0x089a: 0x80006002, 0x089b: 0x80006002, + 0x089e: 0x40028220, + // Block 0x23, offset 0x8c0 + 0x08c0: 0x8000de02, 0x08c1: 0x8000de02, 0x08c2: 0x8000df02, 0x08c3: 0x8000e002, + 0x08c4: 0x401f7d20, 0x08c5: 0x401f7e20, 0x08c6: 0x401f7f20, 0x08c7: 0x401f8520, + 0x08c8: 0x401f8620, 0x08c9: 0x401f8720, 0x08ca: 0x401f8820, 0x08cb: 0x401f8920, + 0x08cc: 0x401f8b20, 0x08cd: 0x401f8d20, 0x08ce: 0x401f8e20, 0x08cf: 0x401f8f20, + 0x08d0: 0x401f9020, 0x08d1: 0x401f9120, 0x08d2: 0x401f9220, 0x08d3: 0x401f9320, + 0x08d4: 0x401f9420, 0x08d5: 0x401f9520, 0x08d6: 0x401f9620, 0x08d7: 0x401f9720, + 0x08d8: 0x401f9920, 0x08d9: 0x401f9a20, 0x08da: 0x401f9b20, 0x08db: 0x401f9c20, + 0x08dc: 0x401f9d20, 0x08dd: 0x401fa020, 0x08de: 0x401fa120, 0x08df: 0x401fa220, + 0x08e0: 0x401fa320, 0x08e1: 0x401fa420, 0x08e2: 0x401fa620, 0x08e3: 0x401fa720, + 0x08e4: 0x401fa820, 0x08e5: 0x401fa920, 0x08e6: 0x401faa20, 0x08e7: 0x401fab20, + 0x08e8: 0x401fac20, 0x08ea: 0x401fad20, 0x08eb: 0x401fae20, + 0x08ec: 0x401faf20, 0x08ed: 0x401fb120, 0x08ee: 0x401fb220, 0x08ef: 0x401fb320, + 0x08f0: 0x401fb520, 0x08f2: 0x401fb620, 0x08f3: 0x401fb720, + 0x08f5: 0x401fb820, 0x08f6: 0x401fb920, 0x08f7: 0x401fba20, + 0x08f8: 0x401fbb20, 0x08f9: 0x401fbc20, 0x08fa: 0x401fc320, 0x08fb: 0x401fc420, + 0x08fc: 0x8000dd02, 0x08fd: 0x401fbd20, 0x08fe: 0x401fc220, 0x08ff: 0x401fc820, + // Block 0x24, offset 0x900 + 0x0900: 0x401fc920, 0x0901: 0x401fca20, 0x0902: 0x401fcb20, 0x0903: 0x401fcc20, + 0x0904: 0x401fcd20, 0x0905: 0x401fd020, 0x0906: 0x401fd220, 0x0907: 0x401fd320, + 0x0908: 0x401fd520, 0x0909: 0x401fd620, 0x090a: 0x401fd720, 0x090b: 0x401fd820, + 0x090c: 0x401fd920, 0x090d: 0x401fda20, 0x090e: 0x401fd420, 0x090f: 0x401fc520, + 0x0910: 0x401f7b20, 0x0911: 0x80000000, 0x0912: 0x80000000, 0x0913: 0x80003502, + 0x0914: 0x80003202, 0x0915: 0x401fd120, 0x0916: 0x401fc620, 0x0917: 0x401fc720, + 0x0920: 0x401f8a20, 0x0921: 0x401f8c20, 0x0922: 0x401fce20, 0x0923: 0x401fcf20, + 0x0924: 0x40017e20, 0x0925: 0x40017f20, 0x0926: 0xe000002d, 0x0927: 0xe00000ab, + 0x0928: 0xe0000195, 0x0929: 0xe000025b, 0x092a: 0xe000031e, 0x092b: 0xe00003d8, + 0x092c: 0xe000048f, 0x092d: 0xe000052b, 0x092e: 0xe00005c7, 0x092f: 0xe0000660, + 0x0930: 0x40028420, 0x0931: 0x40139420, 0x0932: 0x401f7c20, 0x0933: 0x401f8020, + 0x0934: 0x401f8120, 0x0935: 0x401f8220, 0x0936: 0x401f8320, 0x0937: 0x401f8420, + 0x0939: 0x401f9e20, 0x093a: 0x401fb420, 0x093b: 0x401f9820, + 0x093c: 0x401f9f20, 0x093d: 0x401fbe20, 0x093e: 0x401fa520, 0x093f: 0x401fb020, + // Block 0x25, offset 0x940 + 0x0941: 0x8000e202, 0x0942: 0x8000e302, 0x0943: 0x8000e402, + 0x0945: 0x401fdb20, 0x0946: 0x401fdc20, 0x0947: 0x401fdd20, + 0x0948: 0x401fde20, 0x0949: 0x401fdf20, 0x094a: 0x401fe020, 0x094b: 0x401fe120, + 0x094c: 0x401fe320, 0x094f: 0x401fe520, + 0x0950: 0x401fe620, 0x0953: 0x401fe720, + 0x0954: 0x401fe820, 0x0955: 0x401fe920, 0x0956: 0x401fea20, 0x0957: 0x401feb20, + 0x0958: 0x401fec20, 0x0959: 0x401fed20, 0x095a: 0x401fee20, 0x095b: 0x401fef20, + 0x095c: 0x401ff020, 0x095d: 0x401ff120, 0x095e: 0x401ff220, 0x095f: 0x401ff320, + 0x0960: 0x401ff420, 0x0961: 0x401ff520, 0x0962: 0x401ff620, 0x0963: 0x401ff720, + 0x0964: 0x401ff820, 0x0965: 0x401ff920, 0x0966: 0x401ffa20, 0x0967: 0x401ffb20, + 0x0968: 0x401ffc20, 0x096a: 0x401ffd20, 0x096b: 0x401ffe20, + 0x096c: 0x401fff20, 0x096d: 0x40200020, 0x096e: 0x40200120, 0x096f: 0x40200220, + 0x0970: 0x40200320, 0x0972: 0x40200520, + 0x0976: 0x40200720, 0x0977: 0x40200820, + 0x0978: 0x40200920, 0x0979: 0x40200a20, + 0x097c: 0x8000e102, 0x097d: 0x40200b20, 0x097e: 0x40200c20, 0x097f: 0x40200d20, + // Block 0x26, offset 0x980 + 0x0980: 0x40200e20, 0x0981: 0x40200f20, 0x0982: 0x40201020, 0x0983: 0x40201120, + 0x0984: 0x40201220, 0x0987: 0xc05a0191, + 0x0988: 0x40201620, 0x098b: 0x40201720, + 0x098c: 0x40201820, 0x098d: 0x40201920, 0x098e: 0xe00008e8, + 0x0997: 0x40201a20, + 0x09a0: 0x401fe220, 0x09a1: 0x401fe420, 0x09a2: 0x40201320, 0x09a3: 0x40201420, + 0x09a6: 0xe0000030, 0x09a7: 0xe00000ae, + 0x09a8: 0xe0000198, 0x09a9: 0xe000025e, 0x09aa: 0xe0000321, 0x09ab: 0xe00003db, + 0x09ac: 0xe0000492, 0x09ad: 0xe000052e, 0x09ae: 0xe00005ca, 0x09af: 0xe0000663, + 0x09b0: 0x40200420, 0x09b1: 0x40200620, 0x09b2: 0x4013a920, 0x09b3: 0x4013aa20, + 0x09b4: 0x4013cc20, 0x09b5: 0x4013cd20, 0x09b6: 0x4013ce20, 0x09b7: 0x4013cf20, + 0x09b8: 0x4013d020, 0x09b9: 0x4013d120, 0x09ba: 0x40038b20, 0x09bb: 0x4013ab20, + // Block 0x27, offset 0x9c0 + 0x09c1: 0x8000e602, 0x09c2: 0x8000e702, 0x09c3: 0x8000e802, + 0x09c5: 0x40202020, 0x09c6: 0x40202120, 0x09c7: 0x40202520, + 0x09c8: 0x40202620, 0x09c9: 0x40201d20, 0x09ca: 0x40201e20, + 0x09cf: 0x40202720, + 0x09d0: 0x40202220, 0x09d3: 0x40201f20, + 0x09d4: 0x40202320, 0x09d5: 0x40202b20, 0x09d6: 0x40202c20, 0x09d7: 0x40202d20, + 0x09d8: 0x40202e20, 0x09d9: 0x40202f20, 0x09da: 0x40203020, 0x09db: 0x40203120, + 0x09dc: 0x40203220, 0x09dd: 0x40203320, 0x09de: 0x40203420, 0x09df: 0x40203520, + 0x09e0: 0x40203620, 0x09e1: 0x40203720, 0x09e2: 0x40203820, 0x09e3: 0x40203920, + 0x09e4: 0x40203a20, 0x09e5: 0x40203b20, 0x09e6: 0x40203c20, 0x09e7: 0x40203d20, + 0x09e8: 0x40203e20, 0x09ea: 0x40203f20, 0x09eb: 0x40204020, + 0x09ec: 0x40204120, 0x09ed: 0x40204220, 0x09ee: 0x40204320, 0x09ef: 0x40204420, + 0x09f0: 0x40204620, 0x09f2: 0x40204720, + 0x09f5: 0x40204820, + 0x09f8: 0x40202820, 0x09f9: 0x40202920, + 0x09fc: 0x8000e502, 0x09fe: 0x40204a20, 0x09ff: 0x40204b20, + // Block 0x28, offset 0xa00 + 0x0a00: 0x40204c20, 0x0a01: 0x40204d20, 0x0a02: 0x40204e20, + 0x0a07: 0x40204f20, + 0x0a08: 0x40205020, 0x0a0b: 0x40205120, + 0x0a0c: 0x40205220, 0x0a0d: 0x40205320, + 0x0a11: 0x40202a20, + 0x0a1c: 0x40204920, + 0x0a26: 0xe0000033, 0x0a27: 0xe00000b1, + 0x0a28: 0xe000019b, 0x0a29: 0xe0000261, 0x0a2a: 0xe0000324, 0x0a2b: 0xe00003de, + 0x0a2c: 0xe0000495, 0x0a2d: 0xe0000531, 0x0a2e: 0xe00005cd, 0x0a2f: 0xe0000666, + 0x0a30: 0x8000e902, 0x0a31: 0x8000ea02, 0x0a32: 0x40202420, 0x0a33: 0x40201c20, + 0x0a34: 0x40201b20, 0x0a35: 0x40204520, + // Block 0x29, offset 0xa40 + 0x0a41: 0x8000ec02, 0x0a42: 0x8000ed02, 0x0a43: 0x8000ee02, + 0x0a45: 0x40205520, 0x0a46: 0x40205620, 0x0a47: 0x40205720, + 0x0a48: 0x40205820, 0x0a49: 0x40205920, 0x0a4a: 0x40205a20, 0x0a4b: 0x40205b20, + 0x0a4c: 0x40205d20, 0x0a4d: 0x40205f20, 0x0a4f: 0x40206020, + 0x0a50: 0x40206120, 0x0a51: 0x40206220, 0x0a53: 0x40206320, + 0x0a54: 0x40206420, 0x0a55: 0x40206520, 0x0a56: 0x40206620, 0x0a57: 0x40206720, + 0x0a58: 0x40206820, 0x0a59: 0x40206920, 0x0a5a: 0x40206a20, 0x0a5b: 0x40206b20, + 0x0a5c: 0x40206c20, 0x0a5d: 0x40206d20, 0x0a5e: 0x40206e20, 0x0a5f: 0x40206f20, + 0x0a60: 0x40207020, 0x0a61: 0x40207120, 0x0a62: 0x40207220, 0x0a63: 0x40207320, + 0x0a64: 0x40207420, 0x0a65: 0x40207520, 0x0a66: 0x40207620, 0x0a67: 0x40207720, + 0x0a68: 0x40207820, 0x0a6a: 0x40207920, 0x0a6b: 0x40207a20, + 0x0a6c: 0x40207b20, 0x0a6d: 0x40207c20, 0x0a6e: 0x40207d20, 0x0a6f: 0x40207e20, + 0x0a70: 0x40207f20, 0x0a72: 0x40208020, 0x0a73: 0x40208620, + 0x0a75: 0x40208120, 0x0a76: 0x40208220, 0x0a77: 0x40208320, + 0x0a78: 0x40208420, 0x0a79: 0x40208520, + 0x0a7c: 0x8000eb02, 0x0a7d: 0x40208720, 0x0a7e: 0x40208820, 0x0a7f: 0x40208920, + // Block 0x2a, offset 0xa80 + 0x0a80: 0x40208a20, 0x0a81: 0x40208b20, 0x0a82: 0x40208c20, 0x0a83: 0x40208d20, + 0x0a84: 0x40208e20, 0x0a85: 0x40209120, 0x0a87: 0x40209220, + 0x0a88: 0x40209320, 0x0a89: 0x40209420, 0x0a8b: 0x40209520, + 0x0a8c: 0x40209620, 0x0a8d: 0x40209720, + 0x0a90: 0x40205420, + 0x0aa0: 0x40205c20, 0x0aa1: 0x40205e20, 0x0aa2: 0x40208f20, 0x0aa3: 0x40209020, + 0x0aa6: 0xe0000036, 0x0aa7: 0xe00000b4, + 0x0aa8: 0xe000019e, 0x0aa9: 0xe0000264, 0x0aaa: 0xe0000327, 0x0aab: 0xe00003e1, + 0x0aac: 0xe0000498, 0x0aad: 0xe0000534, 0x0aae: 0xe00005d0, 0x0aaf: 0xe0000669, + 0x0ab1: 0x4013ac20, + // Block 0x2b, offset 0xac0 + 0x0ac1: 0x8000f002, 0x0ac2: 0x8000f102, 0x0ac3: 0x8000f202, + 0x0ac5: 0x40209820, 0x0ac6: 0x40209920, 0x0ac7: 0x40209a20, + 0x0ac8: 0x40209b20, 0x0ac9: 0x40209c20, 0x0aca: 0x40209d20, 0x0acb: 0x40209e20, + 0x0acc: 0x4020a020, 0x0acf: 0x4020a220, + 0x0ad0: 0x4020a320, 0x0ad3: 0x4020a420, + 0x0ad4: 0x4020a520, 0x0ad5: 0x4020a620, 0x0ad6: 0x4020a720, 0x0ad7: 0x4020a820, + 0x0ad8: 0x4020a920, 0x0ad9: 0x4020aa20, 0x0ada: 0x4020ab20, 0x0adb: 0x4020ac20, + 0x0adc: 0x4020ad20, 0x0add: 0x4020ae20, 0x0ade: 0x4020af20, 0x0adf: 0x4020b020, + 0x0ae0: 0x4020b120, 0x0ae1: 0x4020b220, 0x0ae2: 0x4020b320, 0x0ae3: 0x4020b420, + 0x0ae4: 0x4020b520, 0x0ae5: 0x4020b620, 0x0ae6: 0x4020b720, 0x0ae7: 0x4020b820, + 0x0ae8: 0x4020b920, 0x0aea: 0x4020ba20, 0x0aeb: 0x4020bb20, + 0x0aec: 0x4020bc20, 0x0aed: 0x4020bd20, 0x0aee: 0x4020be20, 0x0aef: 0x4020bf20, + 0x0af0: 0x4020c120, 0x0af2: 0x4020c220, 0x0af3: 0x4020c320, + 0x0af5: 0x4020c420, 0x0af6: 0x4020c620, 0x0af7: 0x4020c720, + 0x0af8: 0x4020c820, 0x0af9: 0x4020c920, + 0x0afc: 0x8000ef02, 0x0afd: 0x4020ca20, 0x0afe: 0x4020cb20, 0x0aff: 0x4020cc20, + // Block 0x2c, offset 0xb00 + 0x0b00: 0x4020cd20, 0x0b01: 0x4020ce20, 0x0b02: 0x4020cf20, 0x0b03: 0x4020d020, + 0x0b04: 0x4020d120, 0x0b07: 0xc05d01e1, + 0x0b08: 0x4020d520, 0x0b0b: 0x4020d620, + 0x0b0c: 0x4020d720, 0x0b0d: 0x4020d820, + 0x0b16: 0x4020d920, 0x0b17: 0x4020da20, + 0x0b1f: 0x4020c020, + 0x0b20: 0x40209f20, 0x0b21: 0x4020a120, 0x0b22: 0x4020d220, 0x0b23: 0x4020d320, + 0x0b26: 0xe0000039, 0x0b27: 0xe00000b7, + 0x0b28: 0xe00001a1, 0x0b29: 0xe0000267, 0x0b2a: 0xe000032a, 0x0b2b: 0xe00003e4, + 0x0b2c: 0xe000049b, 0x0b2d: 0xe0000537, 0x0b2e: 0xe00005d3, 0x0b2f: 0xe000066c, + 0x0b30: 0x40038c20, 0x0b31: 0x4020c520, 0x0b32: 0x4013d220, 0x0b33: 0x4013d320, + 0x0b34: 0x4013d420, 0x0b35: 0x4013d520, 0x0b36: 0x4013d620, 0x0b37: 0x4013d720, + // Block 0x2d, offset 0xb40 + 0x0b42: 0x8000f302, 0x0b43: 0x4020e820, + 0x0b45: 0x4020dc20, 0x0b46: 0x4020dd20, 0x0b47: 0x4020de20, + 0x0b48: 0x4020df20, 0x0b49: 0x4020e020, 0x0b4a: 0x4020e120, + 0x0b4e: 0x4020e220, 0x0b4f: 0x4020e320, + 0x0b50: 0x4020e420, 0x0b52: 0xc0610231, 0x0b53: 0x4020e620, + 0x0b54: 0x4020e720, 0x0b55: 0x4020e920, + 0x0b59: 0x4020ea20, 0x0b5a: 0x4020eb20, + 0x0b5c: 0x4020fb20, 0x0b5e: 0x4020ec20, 0x0b5f: 0x4020ed20, + 0x0b63: 0x4020ee20, + 0x0b64: 0x4020ef20, + 0x0b68: 0x4020f020, 0x0b69: 0x4020fa20, 0x0b6a: 0x4020f120, + 0x0b6e: 0x4020f220, 0x0b6f: 0x4020f320, + 0x0b70: 0x4020f420, 0x0b71: 0x4020f920, 0x0b72: 0x4020f520, 0x0b73: 0x4020f820, + 0x0b74: 0x4020f720, 0x0b75: 0x4020f620, 0x0b76: 0x4020fc20, 0x0b77: 0x4020fd20, + 0x0b78: 0x4020fe20, 0x0b79: 0x4020ff20, + 0x0b7e: 0x40210020, 0x0b7f: 0x40210120, + // Block 0x2e, offset 0xb80 + 0x0b80: 0x40210220, 0x0b81: 0x40210320, 0x0b82: 0x40210420, + 0x0b86: 0xc0630261, 0x0b87: 0xc06602b1, + 0x0b88: 0x40210720, 0x0b8a: 0x40210820, 0x0b8b: 0x40210920, + 0x0b8c: 0x40210a20, 0x0b8d: 0x40210b20, + 0x0b90: 0x4020db20, + 0x0b97: 0x40210c20, + 0x0ba6: 0xe000003c, 0x0ba7: 0xe00000ba, + 0x0ba8: 0xe00001a4, 0x0ba9: 0xe000026a, 0x0baa: 0xe000032d, 0x0bab: 0xe00003e7, + 0x0bac: 0xe000049e, 0x0bad: 0xe000053a, 0x0bae: 0xe00005d6, 0x0baf: 0xe000066f, + 0x0bb0: 0x4013de20, 0x0bb1: 0x4013df20, 0x0bb2: 0x4013e020, 0x0bb3: 0x40038d20, + 0x0bb4: 0x40038e20, 0x0bb5: 0x40038f20, 0x0bb6: 0x40039020, 0x0bb7: 0x40039120, + 0x0bb8: 0x40039220, 0x0bb9: 0x4013ae20, 0x0bba: 0x40039320, + // Block 0x2f, offset 0xbc0 + 0x0bc1: 0x8000f402, 0x0bc2: 0x8000f502, 0x0bc3: 0x8000f602, + 0x0bc5: 0x40210d20, 0x0bc6: 0x40210e20, 0x0bc7: 0x40210f20, + 0x0bc8: 0x40211020, 0x0bc9: 0x40211120, 0x0bca: 0x40211220, 0x0bcb: 0x40211320, + 0x0bcc: 0x40211520, 0x0bce: 0x40211720, 0x0bcf: 0x40211820, + 0x0bd0: 0x40211920, 0x0bd2: 0x40211a20, 0x0bd3: 0x40211b20, + 0x0bd4: 0x40211c20, 0x0bd5: 0x40211d20, 0x0bd6: 0x40211e20, 0x0bd7: 0x40211f20, + 0x0bd8: 0x40212020, 0x0bd9: 0x40212120, 0x0bda: 0x40212220, 0x0bdb: 0x40212420, + 0x0bdc: 0x40212520, 0x0bdd: 0x40212720, 0x0bde: 0x40212820, 0x0bdf: 0x40212920, + 0x0be0: 0x40212a20, 0x0be1: 0x40212b20, 0x0be2: 0x40212c20, 0x0be3: 0x40212d20, + 0x0be4: 0x40212e20, 0x0be5: 0x40212f20, 0x0be6: 0x40213020, 0x0be7: 0x40213120, + 0x0be8: 0x40213220, 0x0bea: 0x40213320, 0x0beb: 0x40213420, + 0x0bec: 0x40213520, 0x0bed: 0x40213620, 0x0bee: 0x40213720, 0x0bef: 0x40213820, + 0x0bf0: 0x40213920, 0x0bf1: 0x40213a20, 0x0bf2: 0x40213b20, 0x0bf3: 0x40214120, + 0x0bf5: 0x40213c20, 0x0bf6: 0x40213d20, 0x0bf7: 0x40213e20, + 0x0bf8: 0x40213f20, 0x0bf9: 0x40214020, + 0x0bfd: 0x40214220, 0x0bfe: 0x40214320, 0x0bff: 0x40214420, + // Block 0x30, offset 0xc00 + 0x0c00: 0x40214520, 0x0c01: 0x40214620, 0x0c02: 0x40214720, 0x0c03: 0x40214820, + 0x0c04: 0x40214920, 0x0c06: 0xc06802e1, 0x0c07: 0x40214d20, + 0x0c08: 0x40214e20, 0x0c0a: 0x40214f20, 0x0c0b: 0x40215020, + 0x0c0c: 0x40215120, 0x0c0d: 0x40215220, + 0x0c15: 0x40215320, 0x0c16: 0x40215420, + 0x0c18: 0x40212320, 0x0c19: 0x40212620, + 0x0c20: 0x40211420, 0x0c21: 0x40211620, 0x0c22: 0x40214a20, 0x0c23: 0x40214b20, + 0x0c26: 0xe000003f, 0x0c27: 0xe00000bd, + 0x0c28: 0xe00001a7, 0x0c29: 0xe000026d, 0x0c2a: 0xe0000330, 0x0c2b: 0xe00003ea, + 0x0c2c: 0xe00004a1, 0x0c2d: 0xe000053d, 0x0c2e: 0xe00005d9, 0x0c2f: 0xe0000672, + 0x0c38: 0xe0000042, 0x0c39: 0xe00000c0, 0x0c3a: 0xe00001aa, 0x0c3b: 0xe0000270, + 0x0c3c: 0xe00000c3, 0x0c3d: 0xe00001ad, 0x0c3e: 0xe0000273, 0x0c3f: 0x40039420, + // Block 0x31, offset 0xc40 + 0x0c42: 0x8000f802, 0x0c43: 0x8000f902, + 0x0c45: 0x40215520, 0x0c46: 0x40215620, 0x0c47: 0x40215720, + 0x0c48: 0x40215820, 0x0c49: 0x40215920, 0x0c4a: 0x40215a20, 0x0c4b: 0x40215b20, + 0x0c4c: 0x40215d20, 0x0c4e: 0x40215f20, 0x0c4f: 0x40216020, + 0x0c50: 0x40216120, 0x0c52: 0x40216220, 0x0c53: 0x40216320, + 0x0c54: 0x40216420, 0x0c55: 0x40216520, 0x0c56: 0x40216620, 0x0c57: 0x40216720, + 0x0c58: 0x40216820, 0x0c59: 0x40216920, 0x0c5a: 0x40216a20, 0x0c5b: 0x40216b20, + 0x0c5c: 0x40216c20, 0x0c5d: 0x40216d20, 0x0c5e: 0x40216e20, 0x0c5f: 0x40216f20, + 0x0c60: 0x40217020, 0x0c61: 0x40217120, 0x0c62: 0x40217220, 0x0c63: 0x40217320, + 0x0c64: 0x40217420, 0x0c65: 0x40217520, 0x0c66: 0x40217620, 0x0c67: 0x40217720, + 0x0c68: 0x40217820, 0x0c6a: 0x40217920, 0x0c6b: 0x40217a20, + 0x0c6c: 0x40217b20, 0x0c6d: 0x40217c20, 0x0c6e: 0x40217d20, 0x0c6f: 0x40217e20, + 0x0c70: 0x40217f20, 0x0c71: 0x40218020, 0x0c72: 0x40218120, 0x0c73: 0x40218720, + 0x0c75: 0x40218220, 0x0c76: 0x40218320, 0x0c77: 0x40218420, + 0x0c78: 0x40218520, 0x0c79: 0x40218620, + 0x0c7c: 0x8000f702, 0x0c7d: 0x40218920, 0x0c7e: 0x40218c20, 0x0c7f: 0xc06a0311, + // Block 0x32, offset 0xc80 + 0x0c80: 0x40218e20, 0x0c81: 0x40218f20, 0x0c82: 0x40219020, 0x0c83: 0x40219120, + 0x0c84: 0x40219220, 0x0c86: 0xc06c0341, 0x0c87: 0x40219620, + 0x0c88: 0x40219720, 0x0c8a: 0xc0710311, 0x0c8b: 0x40219920, + 0x0c8c: 0x40219a20, 0x0c8d: 0x40219b20, + 0x0c95: 0x40219c20, 0x0c96: 0x40219d20, + 0x0c9e: 0x40218820, + 0x0ca0: 0x40215c20, 0x0ca1: 0x40215e20, 0x0ca2: 0x40219320, 0x0ca3: 0x40219420, + 0x0ca6: 0xe0000045, 0x0ca7: 0xe00000c6, + 0x0ca8: 0xe00001b0, 0x0ca9: 0xe0000276, 0x0caa: 0xe0000333, 0x0cab: 0xe00003ed, + 0x0cac: 0xe00004a4, 0x0cad: 0xe0000540, 0x0cae: 0xe00005dc, 0x0caf: 0xe0000675, + 0x0cb1: 0x40218a20, 0x0cb2: 0x40218b20, + // Block 0x33, offset 0xcc0 + 0x0cc2: 0x8000fa02, 0x0cc3: 0x8000fb02, + 0x0cc5: 0x40219e20, 0x0cc6: 0x40219f20, 0x0cc7: 0x4021a020, + 0x0cc8: 0x4021a120, 0x0cc9: 0x4021a220, 0x0cca: 0x4021a320, 0x0ccb: 0x4021a420, + 0x0ccc: 0x4021a620, 0x0cce: 0x4021a820, 0x0ccf: 0x4021a920, + 0x0cd0: 0x4021aa20, 0x0cd2: 0x4021ab20, 0x0cd3: 0x4021ac20, + 0x0cd4: 0x4021ad20, 0x0cd5: 0x4021ae20, 0x0cd6: 0x4021af20, 0x0cd7: 0x4021b020, + 0x0cd8: 0x4021b120, 0x0cd9: 0x4021b220, 0x0cda: 0x4021b320, 0x0cdb: 0x4021b420, + 0x0cdc: 0x4021b520, 0x0cdd: 0x4021b620, 0x0cde: 0x4021b720, 0x0cdf: 0x4021b820, + 0x0ce0: 0x4021b920, 0x0ce1: 0x4021ba20, 0x0ce2: 0x4021bb20, 0x0ce3: 0x4021bc20, + 0x0ce4: 0x4021bd20, 0x0ce5: 0x4021be20, 0x0ce6: 0x4021bf20, 0x0ce7: 0x4021c020, + 0x0ce8: 0x4021c120, 0x0ce9: 0x4021c220, 0x0cea: 0x4021c320, 0x0ceb: 0x4021c420, + 0x0cec: 0x4021c520, 0x0ced: 0x4021c620, 0x0cee: 0x4021c720, 0x0cef: 0x4021c820, + 0x0cf0: 0x4021c920, 0x0cf1: 0x4021d220, 0x0cf2: 0x4021ca20, 0x0cf3: 0x4021d020, + 0x0cf4: 0x4021d120, 0x0cf5: 0x4021cb20, 0x0cf6: 0x4021cc20, 0x0cf7: 0x4021cd20, + 0x0cf8: 0x4021ce20, 0x0cf9: 0x4021cf20, 0x0cfa: 0x4021d320, + 0x0cfd: 0x4021d420, 0x0cfe: 0x4021d520, 0x0cff: 0x4021d620, + // Block 0x34, offset 0xd00 + 0x0d00: 0x4021d720, 0x0d01: 0x4021d820, 0x0d02: 0x4021d920, 0x0d03: 0x4021da20, + 0x0d04: 0x4021db20, 0x0d06: 0xc07303b1, 0x0d07: 0xc0760401, + 0x0d08: 0x4021e020, 0x0d0a: 0x4021e120, 0x0d0b: 0x4021e220, + 0x0d0c: 0x4021e320, 0x0d0d: 0x4021e520, 0x0d0e: 0xe00008f4, + 0x0d17: 0x4021e420, + 0x0d20: 0x4021a520, 0x0d21: 0x4021a720, 0x0d22: 0x4021dc20, 0x0d23: 0x4021dd20, + 0x0d26: 0xe0000048, 0x0d27: 0xe00000c9, + 0x0d28: 0xe00001b3, 0x0d29: 0xe0000279, 0x0d2a: 0xe0000336, 0x0d2b: 0xe00003f0, + 0x0d2c: 0xe00004a7, 0x0d2d: 0xe0000543, 0x0d2e: 0xe00005df, 0x0d2f: 0xe0000678, + 0x0d30: 0x4013e120, 0x0d31: 0x4013e220, 0x0d32: 0x4013e320, 0x0d33: 0x4013e420, + 0x0d34: 0x4013e520, 0x0d35: 0x4013e620, + 0x0d39: 0x40039520, 0x0d3a: 0xe00008ee, 0x0d3b: 0xe00008f1, + 0x0d3c: 0xe00008f7, 0x0d3d: 0xe00008fa, 0x0d3e: 0xe00008fd, 0x0d3f: 0xe00008eb, + // Block 0x35, offset 0xd40 + 0x0d42: 0x8000fc02, 0x0d43: 0x8000fd02, + 0x0d45: 0x4021e620, 0x0d46: 0x4021e720, 0x0d47: 0x4021e820, + 0x0d48: 0x4021e920, 0x0d49: 0x4021ea20, 0x0d4a: 0x4021eb20, 0x0d4b: 0x4021ec20, + 0x0d4c: 0x4021ed20, 0x0d4d: 0x4021ee20, 0x0d4e: 0x4021ef20, 0x0d4f: 0x4021f020, + 0x0d50: 0x4021f120, 0x0d51: 0x4021f220, 0x0d52: 0x4021f320, 0x0d53: 0x4021f420, + 0x0d54: 0x4021f520, 0x0d55: 0x4021f620, 0x0d56: 0x4021f720, + 0x0d5a: 0x4021f820, 0x0d5b: 0x4021f920, + 0x0d5c: 0x4021fa20, 0x0d5d: 0x4021fb20, 0x0d5e: 0x4021fc20, 0x0d5f: 0x4021fd20, + 0x0d60: 0x4021fe20, 0x0d61: 0x4021ff20, 0x0d62: 0x40220020, 0x0d63: 0x40220120, + 0x0d64: 0x40220220, 0x0d65: 0x40220320, 0x0d66: 0x40220420, 0x0d67: 0x40220520, + 0x0d68: 0x40220620, 0x0d69: 0x40220720, 0x0d6a: 0x40220820, 0x0d6b: 0x40220920, + 0x0d6c: 0x40220a20, 0x0d6d: 0x40220b20, 0x0d6e: 0x40220c20, 0x0d6f: 0x40220d20, + 0x0d70: 0x40220e20, 0x0d71: 0x40220f20, 0x0d73: 0x40221020, + 0x0d74: 0x40221120, 0x0d75: 0x40221220, 0x0d76: 0x40221320, 0x0d77: 0x40221420, + 0x0d78: 0x40221520, 0x0d79: 0x40221620, 0x0d7a: 0x40221720, 0x0d7b: 0x40221820, + 0x0d7d: 0x40221920, + // Block 0x36, offset 0xd80 + 0x0d80: 0x40221a20, 0x0d81: 0x40221b20, 0x0d82: 0x40221c20, 0x0d83: 0x40221d20, + 0x0d84: 0x40221e20, 0x0d85: 0x40221f20, 0x0d86: 0x40222020, + 0x0d8a: 0x40223220, + 0x0d8f: 0x40222120, + 0x0d90: 0x40222220, 0x0d91: 0x40222320, 0x0d92: 0x40222420, 0x0d93: 0x40222520, + 0x0d94: 0x40222620, 0x0d96: 0x40222720, + 0x0d98: 0x40222820, 0x0d99: 0xc0780431, 0x0d9a: 0x40222d20, 0x0d9b: 0x40222e20, + 0x0d9c: 0xc07d04b1, 0x0d9d: 0x40223020, 0x0d9e: 0x40223120, 0x0d9f: 0x40222a20, + 0x0db2: 0x40222920, 0x0db3: 0x40222b20, + 0x0db4: 0x40028820, + // Block 0x37, offset 0xdc0 + 0x0dc1: 0x40239520, 0x0dc2: 0x40239620, 0x0dc3: 0x40239720, + 0x0dc4: 0x40239820, 0x0dc5: 0x40239920, 0x0dc6: 0x40239a20, 0x0dc7: 0x40239b20, + 0x0dc8: 0x40239c20, 0x0dc9: 0x40239d20, 0x0dca: 0x40239e20, 0x0dcb: 0x40239f20, + 0x0dcc: 0x4023a020, 0x0dcd: 0x4023a120, 0x0dce: 0x4023a220, 0x0dcf: 0x4023a320, + 0x0dd0: 0x4023a420, 0x0dd1: 0x4023a520, 0x0dd2: 0x4023a620, 0x0dd3: 0x4023a720, + 0x0dd4: 0x4023a820, 0x0dd5: 0x4023a920, 0x0dd6: 0x4023aa20, 0x0dd7: 0x4023ab20, + 0x0dd8: 0x4023ac20, 0x0dd9: 0x4023ad20, 0x0dda: 0x4023ae20, 0x0ddb: 0x4023af20, + 0x0ddc: 0x4023b020, 0x0ddd: 0x4023b120, 0x0dde: 0x4023b220, 0x0ddf: 0x4023b320, + 0x0de0: 0x4023b420, 0x0de1: 0x4023b520, 0x0de2: 0x4023b620, 0x0de3: 0x4023b720, + 0x0de4: 0x4023b820, 0x0de5: 0x4023b920, 0x0de6: 0x4023ba20, 0x0de7: 0x4023bb20, + 0x0de8: 0x4023bc20, 0x0de9: 0x4023bd20, 0x0dea: 0x4023be20, 0x0deb: 0x4023bf20, + 0x0dec: 0x4023c020, 0x0ded: 0x4023c120, 0x0dee: 0x4023c220, 0x0def: 0x4023c320, + 0x0df0: 0x4023c420, 0x0df1: 0x4023c520, 0x0df2: 0x4023c620, 0x0df3: 0x4023c720, + 0x0df4: 0x4023c820, 0x0df5: 0x4023c920, 0x0df6: 0x4023ca20, 0x0df7: 0x4023cb20, + 0x0df8: 0x4023cc20, 0x0df9: 0x4023cd20, 0x0dfa: 0x4023ce20, + 0x0dff: 0x4013af20, + // Block 0x38, offset 0xe00 + 0x0e00: 0xc07f04e1, 0x0e01: 0xc0ae04e1, 0x0e02: 0xc0dd04e1, 0x0e03: 0xc10c04e1, + 0x0e04: 0xc13b04e1, 0x0e05: 0x4023d420, 0x0e06: 0x40139520, 0x0e07: 0x80011d02, + 0x0e08: 0x80011e02, 0x0e09: 0x80011f02, 0x0e0a: 0x80012002, 0x0e0b: 0x80012102, + 0x0e0c: 0x80012202, 0x0e0d: 0xc16a0511, 0x0e0e: 0x80011c02, 0x0e0f: 0x4002d120, + 0x0e10: 0xe000005d, 0x0e11: 0xe00000e1, 0x0e12: 0xe00001c8, 0x0e13: 0xe000028e, + 0x0e14: 0xe000034b, 0x0e15: 0xe0000405, 0x0e16: 0xe00004bc, 0x0e17: 0xe0000558, + 0x0e18: 0xe00005f4, 0x0e19: 0xe000068d, 0x0e1a: 0x40028920, 0x0e1b: 0x40028a20, + // Block 0x39, offset 0xe40 + 0x0e41: 0x4023d520, 0x0e42: 0x4023d620, + 0x0e44: 0x4023d720, 0x0e47: 0x4023d820, + 0x0e48: 0x4023d920, 0x0e4a: 0x4023db20, + 0x0e4d: 0x4023dc20, + 0x0e54: 0x4023dd20, 0x0e55: 0x4023de20, 0x0e56: 0x4023df20, 0x0e57: 0x4023e020, + 0x0e59: 0x4023e120, 0x0e5a: 0x4023e220, 0x0e5b: 0x4023e320, + 0x0e5c: 0x4023e420, 0x0e5d: 0x4023e520, 0x0e5e: 0x4023e620, 0x0e5f: 0x4023e720, + 0x0e61: 0x4023e820, 0x0e62: 0x4023e920, 0x0e63: 0x4023ea20, + 0x0e65: 0x4023eb20, 0x0e67: 0x4023ec20, + 0x0e6a: 0x4023da20, 0x0e6b: 0x4023ed20, + 0x0e6d: 0x4023ee20, 0x0e6e: 0x4023ef20, 0x0e6f: 0x4023f020, + 0x0e70: 0x4023f120, 0x0e71: 0x4023f220, 0x0e72: 0x4023f320, 0x0e73: 0x4023f420, + 0x0e74: 0x4023f520, 0x0e75: 0x4023f620, 0x0e76: 0x4023f720, 0x0e77: 0x4023f820, + 0x0e78: 0x4023f920, 0x0e79: 0x4023fa20, 0x0e7b: 0x4023fb20, + 0x0e7c: 0x4023fc20, 0x0e7d: 0x4023fd20, + // Block 0x3a, offset 0xe80 + 0x0e80: 0xc16c0541, 0x0e81: 0xc18a0541, 0x0e82: 0xc1a80541, 0x0e83: 0xc1c60541, + 0x0e84: 0xc1e40541, 0x0e86: 0x40139620, + 0x0e88: 0x80012402, 0x0e89: 0x80012502, 0x0e8a: 0x80012602, 0x0e8b: 0x80012702, + 0x0e8c: 0x80012802, 0x0e8d: 0xc2020641, + 0x0e90: 0xe0000060, 0x0e91: 0xe00000e4, 0x0e92: 0xe00001cb, 0x0e93: 0xe0000291, + 0x0e94: 0xe000034e, 0x0e95: 0xe0000408, 0x0e96: 0xe00004bf, 0x0e97: 0xe000055b, + 0x0e98: 0xe00005f7, 0x0e99: 0xe0000690, + 0x0e9c: 0xf0000404, 0x0e9d: 0xf0000404, + // Block 0x3b, offset 0xec0 + 0x0ec0: 0xe0001051, 0x0ec1: 0x40039d20, 0x0ec2: 0x40039e20, 0x0ec3: 0x40039f20, + 0x0ec4: 0x40028d20, 0x0ec5: 0x40028e20, 0x0ec6: 0x40028f20, 0x0ec7: 0x40029020, + 0x0ec8: 0x40029120, 0x0ec9: 0x40029220, 0x0eca: 0x40029320, 0x0ecb: 0x40029620, + 0x0ecc: 0xf000001b, 0x0ecd: 0x40029720, 0x0ece: 0x40029820, 0x0ecf: 0x40029920, + 0x0ed0: 0x40029a20, 0x0ed1: 0x40029b20, 0x0ed2: 0x40029c20, 0x0ed3: 0x4003a020, + 0x0ed4: 0x40030f20, 0x0ed5: 0x4003a120, 0x0ed6: 0x4003a220, 0x0ed7: 0x4003a320, + 0x0ed8: 0x80000000, 0x0ed9: 0x80000000, 0x0eda: 0x4003a420, 0x0edb: 0x4003a520, + 0x0edc: 0x4003a620, 0x0edd: 0x4003a720, 0x0ede: 0x4003a820, 0x0edf: 0x4003a920, + 0x0ee0: 0xe0000063, 0x0ee1: 0xe00000e7, 0x0ee2: 0xe00001ce, 0x0ee3: 0xe0000294, + 0x0ee4: 0xe0000351, 0x0ee5: 0xe000040b, 0x0ee6: 0xe00004c2, 0x0ee7: 0xe000055e, + 0x0ee8: 0xe00005fa, 0x0ee9: 0xe0000693, 0x0eea: 0xe00000ea, 0x0eeb: 0xe00001d1, + 0x0eec: 0xe0000297, 0x0eed: 0xe0000354, 0x0eee: 0xe000040e, 0x0eef: 0xe00004c5, + 0x0ef0: 0xe0000561, 0x0ef1: 0xe00005fd, 0x0ef2: 0xe0000696, 0x0ef3: 0xe0000066, + 0x0ef4: 0x4003aa20, 0x0ef5: 0x80000000, 0x0ef6: 0x4003ab20, 0x0ef7: 0x80000000, + 0x0ef8: 0x4003ac20, 0x0ef9: 0x80012c02, 0x0efa: 0x4001ef20, 0x0efb: 0x4001f020, + 0x0efc: 0x4001f120, 0x0efd: 0x4001f220, 0x0efe: 0x4003ad20, 0x0eff: 0x4003ae20, + // Block 0x3c, offset 0xf00 + 0x0f00: 0x40244620, 0x0f01: 0x40244920, 0x0f02: 0x40244b20, + 0x0f04: 0x40244d20, 0x0f05: 0x40244f20, 0x0f06: 0x40245120, 0x0f07: 0x40245320, + 0x0f09: 0x40245520, 0x0f0a: 0x40245720, 0x0f0b: 0x40245920, + 0x0f0c: 0x40245b20, 0x0f0e: 0x40245d20, 0x0f0f: 0x40245f20, + 0x0f10: 0x40246120, 0x0f11: 0x40246320, 0x0f13: 0x40246520, + 0x0f14: 0x40246720, 0x0f15: 0x40246920, 0x0f16: 0x40246b20, + 0x0f18: 0x40246d20, 0x0f19: 0x40246f20, 0x0f1a: 0x40247120, 0x0f1b: 0x40247320, + 0x0f1d: 0x40247520, 0x0f1e: 0x40247720, 0x0f1f: 0x40247920, + 0x0f20: 0x40247b20, 0x0f21: 0x40247d20, 0x0f22: 0x40247f20, 0x0f23: 0x40248220, + 0x0f24: 0x40248420, 0x0f25: 0x40248620, 0x0f26: 0x40248820, 0x0f27: 0x40248a20, + 0x0f28: 0x40248c20, 0x0f2a: 0xe0001045, 0x0f2b: 0x40244820, + 0x0f2c: 0x40248120, + 0x0f31: 0xc3030721, 0x0f32: 0x40249720, 0x0f33: 0x40249820, + 0x0f34: 0x40249b20, 0x0f35: 0x40249c20, 0x0f36: 0x40249d20, 0x0f37: 0x40249e20, + 0x0f38: 0x40249f20, 0x0f39: 0x4024a020, 0x0f3a: 0x4024a120, 0x0f3b: 0x4024a220, + 0x0f3c: 0x4024a320, 0x0f3d: 0x4024a420, 0x0f3e: 0x80012d02, 0x0f3f: 0x80012e02, + // Block 0x3d, offset 0xf40 + 0x0f40: 0x40249920, 0x0f41: 0x40249a20, 0x0f42: 0x80000000, 0x0f43: 0x80000000, + 0x0f44: 0x4024a520, 0x0f45: 0x40029d20, 0x0f46: 0x80000000, 0x0f47: 0x80000000, + 0x0f48: 0x40248e20, 0x0f49: 0x40249020, 0x0f4a: 0x40249420, 0x0f4b: 0x40249520, + 0x0f4c: 0x40249220, 0x0f4d: 0x40248f20, 0x0f4e: 0x40249120, 0x0f4f: 0x40249320, + 0x0f50: 0x40244720, 0x0f51: 0x40244a20, 0x0f52: 0x40244c20, + 0x0f54: 0x40244e20, 0x0f55: 0x40245020, 0x0f56: 0x40245220, 0x0f57: 0x40245420, + 0x0f59: 0x40245620, 0x0f5a: 0x40245820, 0x0f5b: 0x40245a20, + 0x0f5c: 0x40245c20, 0x0f5e: 0x40245e20, 0x0f5f: 0x40246020, + 0x0f60: 0x40246220, 0x0f61: 0x40246420, 0x0f63: 0x40246620, + 0x0f64: 0x40246820, 0x0f65: 0x40246a20, 0x0f66: 0x40246c20, + 0x0f68: 0x40246e20, 0x0f69: 0x40247020, 0x0f6a: 0x40247220, 0x0f6b: 0x40247420, + 0x0f6d: 0x40247620, 0x0f6e: 0x40247820, 0x0f6f: 0x40247a20, + 0x0f70: 0x40247c20, 0x0f71: 0x40247e20, 0x0f72: 0xc2f906a1, 0x0f73: 0xc2fe06a1, + 0x0f74: 0x40248520, 0x0f75: 0x40248720, 0x0f76: 0x40248920, 0x0f77: 0x40248b20, + 0x0f78: 0x40248d20, 0x0f7a: 0xe000103f, 0x0f7b: 0xe0001042, + 0x0f7c: 0xe0001048, 0x0f7e: 0x4003af20, 0x0f7f: 0x4003b020, + // Block 0x3e, offset 0xf80 + 0x0f80: 0x4003b120, 0x0f81: 0x4003b220, 0x0f82: 0x4003b320, 0x0f83: 0x4003b420, + 0x0f84: 0x4003b520, 0x0f85: 0x4003b620, 0x0f86: 0x80000000, 0x0f87: 0x4003b720, + 0x0f88: 0x4003b820, 0x0f89: 0x4003b920, 0x0f8a: 0x4003ba20, 0x0f8b: 0x4003bb20, + 0x0f8c: 0x4003bc20, 0x0f8e: 0x4003bd20, 0x0f8f: 0x4003be20, + 0x0f90: 0x40029420, 0x0f91: 0x40029520, 0x0f92: 0x40029e20, 0x0f93: 0x40029f20, + 0x0f94: 0x4002a020, 0x0f95: 0x4003bf20, 0x0f96: 0x4003c020, 0x0f97: 0x4003c120, + 0x0f98: 0x4003c220, 0x0f99: 0x4002a120, 0x0f9a: 0x4002a220, + // Block 0x3f, offset 0xfc0 + 0x0fc0: 0x40261520, 0x0fc1: 0x40261720, 0x0fc2: 0x40261920, 0x0fc3: 0x40261c20, + 0x0fc4: 0x40261d20, 0x0fc5: 0x40261f20, 0x0fc6: 0x40262220, 0x0fc7: 0x40262420, + 0x0fc8: 0x40262820, 0x0fc9: 0x40262c20, 0x0fca: 0x40262f20, 0x0fcb: 0x40263020, + 0x0fcc: 0x40263220, 0x0fcd: 0x40263420, 0x0fce: 0x40263620, 0x0fcf: 0x40263820, + 0x0fd0: 0x40263a20, 0x0fd1: 0x40263b20, 0x0fd2: 0x40263c20, 0x0fd3: 0x40263e20, + 0x0fd4: 0x40264020, 0x0fd5: 0x40264420, 0x0fd6: 0x40264520, 0x0fd7: 0x40264a20, + 0x0fd8: 0x40264c20, 0x0fd9: 0x40264d20, 0x0fda: 0x40264f20, 0x0fdb: 0x40265120, + 0x0fdc: 0x40265520, 0x0fdd: 0x40265720, 0x0fde: 0x40265e20, 0x0fdf: 0x40266020, + 0x0fe0: 0x40266620, 0x0fe1: 0x40266c20, 0x0fe2: 0x40266d20, 0x0fe3: 0x40266e20, + 0x0fe4: 0x40266f20, 0x0fe5: 0xc3070781, 0x0fe6: 0x40267120, 0x0fe7: 0x40267620, + 0x0fe8: 0x40267720, 0x0fe9: 0x40267820, 0x0fea: 0x40267920, 0x0feb: 0x004cf404, + 0x0fec: 0x40267a20, 0x0fed: 0x40267e20, 0x0fee: 0x40268020, 0x0fef: 0x40268220, + 0x0ff0: 0x40268520, 0x0ff1: 0x40268a20, 0x0ff2: 0x40268e20, 0x0ff3: 0x40268120, + 0x0ff4: 0x40269020, 0x0ff5: 0x40268c20, 0x0ff6: 0x80013302, 0x0ff7: 0x80013402, + 0x0ff8: 0x80013502, 0x0ff9: 0x40269520, 0x0ffa: 0x40269620, 0x0ffb: 0x40265020, + 0x0ffc: 0x40265420, 0x0ffd: 0x40265820, 0x0ffe: 0x40266320, 0x0fff: 0xe0001055, + // Block 0x40, offset 0x1000 + 0x1000: 0xe000006f, 0x1001: 0xe00000f3, 0x1002: 0xe00001da, 0x1003: 0xe00002a0, + 0x1004: 0xe000035d, 0x1005: 0xe0000417, 0x1006: 0xe00004ce, 0x1007: 0xe000056a, + 0x1008: 0xe0000606, 0x1009: 0xe000069f, 0x100a: 0x40018920, 0x100b: 0x40018a20, + 0x100c: 0x4002a620, 0x100d: 0x4002a720, 0x100e: 0x4002a820, 0x100f: 0x4002a920, + 0x1010: 0x40265b20, 0x1011: 0x40265c20, 0x1012: 0x40267220, 0x1013: 0x40267320, + 0x1014: 0x40267420, 0x1015: 0x40267520, 0x1016: 0x40268620, 0x1017: 0x40268720, + 0x1018: 0x40268820, 0x1019: 0x40268920, 0x101a: 0x40261e20, 0x101b: 0x40262920, + 0x101c: 0x40266720, 0x101d: 0x40266820, 0x101e: 0x40264320, 0x101f: 0x40264e20, + 0x1020: 0x40265620, 0x1021: 0x40262b20, 0x1022: 0x40269120, 0x1023: 0x40269720, + 0x1024: 0x40269820, 0x1025: 0x40265d20, 0x1026: 0x40266b20, 0x1027: 0x40269220, + 0x1028: 0x40269320, 0x1029: 0x40269920, 0x102a: 0x40269a20, 0x102b: 0x40269b20, + 0x102c: 0x40269c20, 0x102d: 0x40269d20, 0x102e: 0x40263920, 0x102f: 0x40266920, + 0x1030: 0x40266a20, 0x1031: 0x40267f20, 0x1032: 0x40267c20, 0x1033: 0x40268320, + 0x1034: 0x40268420, 0x1035: 0x40261620, 0x1036: 0x40261820, 0x1037: 0x40261a20, + 0x1038: 0x40262020, 0x1039: 0x40262620, 0x103a: 0x40262d20, 0x103b: 0x40263d20, + 0x103c: 0x40264120, 0x103d: 0x40264620, 0x103e: 0x40264720, 0x103f: 0x40264b20, + // Block 0x41, offset 0x1040 + 0x1040: 0x40265a20, 0x1041: 0x40266120, 0x1042: 0x40265920, 0x1043: 0x40267b20, + 0x1044: 0x40268b20, 0x1045: 0x40268d20, 0x1046: 0x40269420, 0x1047: 0x40269e20, + 0x1048: 0x4026a020, 0x1049: 0x4026a220, 0x104a: 0x4026a320, 0x104b: 0x40269f20, + 0x104c: 0x4026a120, 0x104d: 0x80013602, 0x104e: 0x40264920, 0x104f: 0x4026a420, + 0x1050: 0xe0000072, 0x1051: 0xe00000f6, 0x1052: 0xe00001dd, 0x1053: 0xe00002a3, + 0x1054: 0xe0000360, 0x1055: 0xe000041a, 0x1056: 0xe00004d1, 0x1057: 0xe000056d, + 0x1058: 0xe0000609, 0x1059: 0xe00006a2, 0x105a: 0x4026a520, 0x105b: 0x4026a620, + 0x105c: 0x40267d20, 0x105d: 0x40268f20, 0x105e: 0x40031a20, 0x105f: 0x40031b20, + 0x1060: 0x0036fc08, 0x1061: 0x00370008, 0x1062: 0x00370408, 0x1063: 0x00370808, + 0x1064: 0x00370c08, 0x1065: 0x00371008, 0x1066: 0x00371408, 0x1067: 0x00371c08, + 0x1068: 0x00372008, 0x1069: 0x00372408, 0x106a: 0x00372808, 0x106b: 0x00372c08, + 0x106c: 0x00373008, 0x106d: 0x00373808, 0x106e: 0x00373c08, 0x106f: 0x00374008, + 0x1070: 0x00374408, 0x1071: 0x00374808, 0x1072: 0x00374c08, 0x1073: 0x00375408, + 0x1074: 0x00375808, 0x1075: 0x00375c08, 0x1076: 0x00376008, 0x1077: 0x00376408, + 0x1078: 0x00376808, 0x1079: 0x00376c08, 0x107a: 0x00377008, 0x107b: 0x00377408, + 0x107c: 0x00377808, 0x107d: 0x00377c08, 0x107e: 0x00378008, 0x107f: 0x00378808, + // Block 0x42, offset 0x1080 + 0x1080: 0x00378c08, 0x1081: 0x00371808, 0x1082: 0x00373408, 0x1083: 0x00375008, + 0x1084: 0x00378408, 0x1085: 0x00379008, + 0x1090: 0x401b7d20, 0x1091: 0x401b7f20, 0x1092: 0x401b8120, 0x1093: 0x401b8320, + 0x1094: 0x401b8520, 0x1095: 0x401b8720, 0x1096: 0x401b8920, 0x1097: 0x401b8d20, + 0x1098: 0x401b8f20, 0x1099: 0x401b9120, 0x109a: 0x401b9320, 0x109b: 0x401b9520, + 0x109c: 0x401b9720, 0x109d: 0x401b9b20, 0x109e: 0x401b9d20, 0x109f: 0x401b9f20, + 0x10a0: 0x401ba120, 0x10a1: 0x401ba320, 0x10a2: 0x401ba520, 0x10a3: 0x401ba920, + 0x10a4: 0x401bab20, 0x10a5: 0x401bad20, 0x10a6: 0x401baf20, 0x10a7: 0x401bb120, + 0x10a8: 0x401bb320, 0x10a9: 0x401bb520, 0x10aa: 0x401bb720, 0x10ab: 0x401bb920, + 0x10ac: 0x401bbb20, 0x10ad: 0x401bbd20, 0x10ae: 0x401bbf20, 0x10af: 0x401bc320, + 0x10b0: 0x401bc520, 0x10b1: 0x401b8b20, 0x10b2: 0x401b9920, 0x10b3: 0x401ba720, + 0x10b4: 0x401bc120, 0x10b5: 0x401bc720, 0x10b6: 0x401bc920, 0x10b7: 0x401bca20, + 0x10b8: 0x401bcb20, 0x10b9: 0x401bcc20, 0x10ba: 0x401bcd20, 0x10bb: 0x4001a320, + 0x10bc: 0xf0000014, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x40303120, 0x10c1: 0x40303220, 0x10c2: 0x40303320, 0x10c3: 0x40303420, + 0x10c4: 0x40303520, 0x10c5: 0x40303620, 0x10c6: 0x40303720, 0x10c7: 0x40303820, + 0x10c8: 0x40303920, 0x10c9: 0x40303a20, 0x10ca: 0x40303b20, 0x10cb: 0x40303c20, + 0x10cc: 0x40303d20, 0x10cd: 0x40303e20, 0x10ce: 0x40303f20, 0x10cf: 0x40304020, + 0x10d0: 0x40304120, 0x10d1: 0x40304220, 0x10d2: 0x40304320, 0x10d3: 0x40304420, + 0x10d4: 0x40304520, 0x10d5: 0x40304620, 0x10d6: 0x40304720, 0x10d7: 0x40304820, + 0x10d8: 0x40304920, 0x10d9: 0x40304a20, 0x10da: 0x40304b20, 0x10db: 0x40304c20, + 0x10dc: 0x40304d20, 0x10dd: 0x40304e20, 0x10de: 0x40304f20, 0x10df: 0x40305020, + 0x10e0: 0x40305120, 0x10e1: 0x40305220, 0x10e2: 0x40305320, 0x10e3: 0x40305420, + 0x10e4: 0x40305520, 0x10e5: 0x40305620, 0x10e6: 0x40305720, 0x10e7: 0x40305820, + 0x10e8: 0x40305920, 0x10e9: 0x40305a20, 0x10ea: 0x40305b20, 0x10eb: 0x40305c20, + 0x10ec: 0x40305d20, 0x10ed: 0x40305e20, 0x10ee: 0x40305f20, 0x10ef: 0x40306020, + 0x10f0: 0x40306120, 0x10f1: 0x40306220, 0x10f2: 0x40306320, 0x10f3: 0x40306420, + 0x10f4: 0x40306520, 0x10f5: 0x40306620, 0x10f6: 0x40306720, 0x10f7: 0x40306820, + 0x10f8: 0x40306920, 0x10f9: 0x40306a20, 0x10fa: 0x40306b20, 0x10fb: 0x40306c20, + 0x10fc: 0x40306d20, 0x10fd: 0x40306e20, 0x10fe: 0x40306f20, 0x10ff: 0x40307020, + // Block 0x44, offset 0x1100 + 0x1100: 0x40307120, 0x1101: 0x40307220, 0x1102: 0x40307320, 0x1103: 0x40307420, + 0x1104: 0x40307520, 0x1105: 0x40307620, 0x1106: 0x40307720, 0x1107: 0x40307820, + 0x1108: 0x40307920, 0x1109: 0x40307a20, 0x110a: 0x40307b20, 0x110b: 0x40307c20, + 0x110c: 0x40307d20, 0x110d: 0x40307e20, 0x110e: 0x40307f20, 0x110f: 0x40308020, + 0x1110: 0x40308120, 0x1111: 0x40308220, 0x1112: 0x40308320, 0x1113: 0x40308420, + 0x1114: 0x40308520, 0x1115: 0x40308620, 0x1116: 0x40308720, 0x1117: 0x40308820, + 0x1118: 0x40308920, 0x1119: 0x40308a20, 0x111a: 0x40308b20, 0x111b: 0x40308c20, + 0x111c: 0x40308d20, 0x111d: 0x40308e20, 0x111e: 0x40308f20, 0x111f: 0x4030ad20, + 0x1120: 0x4030ae20, 0x1121: 0x4030af20, 0x1122: 0x4030b020, 0x1123: 0x4030b120, + 0x1124: 0x4030b220, 0x1125: 0x4030b320, 0x1126: 0x4030b420, 0x1127: 0x4030b520, + 0x1128: 0x4030b620, 0x1129: 0x4030b720, 0x112a: 0x4030b820, 0x112b: 0x4030b920, + 0x112c: 0x4030ba20, 0x112d: 0x4030bb20, 0x112e: 0x4030bc20, 0x112f: 0x4030bd20, + 0x1130: 0x4030be20, 0x1131: 0x4030bf20, 0x1132: 0x4030c020, 0x1133: 0x4030c120, + 0x1134: 0x4030c220, 0x1135: 0x4030c320, 0x1136: 0x4030c420, 0x1137: 0x4030c520, + 0x1138: 0x4030c620, 0x1139: 0x4030c720, 0x113a: 0x4030c820, 0x113b: 0x4030c920, + 0x113c: 0x4030ca20, 0x113d: 0x4030cb20, 0x113e: 0x4030cc20, 0x113f: 0x4030cd20, + // Block 0x45, offset 0x1140 + 0x1140: 0x4030ce20, 0x1141: 0x4030cf20, 0x1142: 0x4030d020, 0x1143: 0x4030d120, + 0x1144: 0x4030d220, 0x1145: 0x4030d320, 0x1146: 0x4030d420, 0x1147: 0x4030d520, + 0x1148: 0x4030d620, 0x1149: 0x4030d720, 0x114a: 0x4030d820, 0x114b: 0x4030d920, + 0x114c: 0x4030da20, 0x114d: 0x4030db20, 0x114e: 0x4030dc20, 0x114f: 0x4030dd20, + 0x1150: 0x4030de20, 0x1151: 0x4030df20, 0x1152: 0x4030e020, 0x1153: 0x4030e120, + 0x1154: 0x4030e220, 0x1155: 0x4030e320, 0x1156: 0x4030e420, 0x1157: 0x4030e520, + 0x1158: 0x4030e620, 0x1159: 0x4030e720, 0x115a: 0x4030e820, 0x115b: 0x4030e920, + 0x115c: 0x4030ea20, 0x115d: 0x4030eb20, 0x115e: 0x4030ec20, 0x115f: 0x4030ed20, + 0x1160: 0x4030ee20, 0x1161: 0x4030ef20, 0x1162: 0x4030f020, 0x1163: 0x4030f120, + 0x1164: 0x4030f220, 0x1165: 0x4030f320, 0x1166: 0x4030f420, 0x1167: 0x4030f520, + 0x1168: 0x40310d20, 0x1169: 0x40310e20, 0x116a: 0x40310f20, 0x116b: 0x40311020, + 0x116c: 0x40311120, 0x116d: 0x40311220, 0x116e: 0x40311320, 0x116f: 0x40311420, + 0x1170: 0x40311520, 0x1171: 0x40311620, 0x1172: 0x40311720, 0x1173: 0x40311820, + 0x1174: 0x40311920, 0x1175: 0x40311a20, 0x1176: 0x40311b20, 0x1177: 0x40311c20, + 0x1178: 0x40311d20, 0x1179: 0x40311e20, 0x117a: 0x40311f20, 0x117b: 0x40312020, + 0x117c: 0x40312120, 0x117d: 0x40312220, 0x117e: 0x40312320, 0x117f: 0x40312420, + // Block 0x46, offset 0x1180 + 0x1180: 0x40312520, 0x1181: 0x40312620, 0x1182: 0x40312720, 0x1183: 0x40312820, + 0x1184: 0x40312920, 0x1185: 0x40312a20, 0x1186: 0x40312b20, 0x1187: 0x40312c20, + 0x1188: 0x40312d20, 0x1189: 0x40312e20, 0x118a: 0x40312f20, 0x118b: 0x40313020, + 0x118c: 0x40313120, 0x118d: 0x40313220, 0x118e: 0x40313320, 0x118f: 0x40313420, + 0x1190: 0x40313520, 0x1191: 0x40313620, 0x1192: 0x40313720, 0x1193: 0x40313820, + 0x1194: 0x40313920, 0x1195: 0x40313a20, 0x1196: 0x40313b20, 0x1197: 0x40313c20, + 0x1198: 0x40313d20, 0x1199: 0x40313e20, 0x119a: 0x40313f20, 0x119b: 0x40314020, + 0x119c: 0x40314120, 0x119d: 0x40314220, 0x119e: 0x40314320, 0x119f: 0x40314420, + 0x11a0: 0x40314520, 0x11a1: 0x40314620, 0x11a2: 0x40314720, 0x11a3: 0x40314820, + 0x11a4: 0x40314920, 0x11a5: 0x40314a20, 0x11a6: 0x40314b20, 0x11a7: 0x40314c20, + 0x11a8: 0x40314d20, 0x11a9: 0x40314e20, 0x11aa: 0x40314f20, 0x11ab: 0x40315020, + 0x11ac: 0x40315120, 0x11ad: 0x40315220, 0x11ae: 0x40315320, 0x11af: 0x40315420, + 0x11b0: 0x40315520, 0x11b1: 0x40315620, 0x11b2: 0x40315720, 0x11b3: 0x40315820, + 0x11b4: 0x40315920, 0x11b5: 0x40315a20, 0x11b6: 0x40315b20, 0x11b7: 0x40315c20, + 0x11b8: 0x40315d20, 0x11b9: 0x40315e20, 0x11ba: 0x40315f20, 0x11bb: 0x40316020, + 0x11bc: 0x40316120, 0x11bd: 0x40316220, 0x11be: 0x40316320, 0x11bf: 0x40316420, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x401db620, 0x11c1: 0x401db720, 0x11c2: 0x401db820, 0x11c3: 0x401db920, + 0x11c4: 0x401dba20, 0x11c5: 0x401dbb20, 0x11c6: 0x401dbc20, 0x11c7: 0x401dbd20, + 0x11c8: 0x401dbe20, 0x11c9: 0x401dbf20, 0x11ca: 0x401dc020, 0x11cb: 0x401dc120, + 0x11cc: 0x401dc220, 0x11cd: 0x401dc320, 0x11ce: 0x401dc420, 0x11cf: 0x401dc520, + 0x11d0: 0x401dc720, 0x11d1: 0x401dc820, 0x11d2: 0x401dc920, 0x11d3: 0x401dca20, + 0x11d4: 0x401dcb20, 0x11d5: 0x401dcc20, 0x11d6: 0x401dcd20, 0x11d7: 0x401dce20, + 0x11d8: 0x401dcf20, 0x11d9: 0x401dd020, 0x11da: 0x401dd120, 0x11db: 0x401dd220, + 0x11dc: 0x401dd320, 0x11dd: 0x401dd420, 0x11de: 0x401dd520, 0x11df: 0x401dd620, + 0x11e0: 0x401ddc20, 0x11e1: 0x401ddd20, 0x11e2: 0x401dde20, 0x11e3: 0x401ddf20, + 0x11e4: 0x401de020, 0x11e5: 0x401de120, 0x11e6: 0x401de220, 0x11e7: 0x401de320, + 0x11e8: 0x401de420, 0x11e9: 0x401de520, 0x11ea: 0x401de620, 0x11eb: 0x401de720, + 0x11ec: 0x401de820, 0x11ed: 0x401de920, 0x11ee: 0x401dea20, 0x11ef: 0x401deb20, + 0x11f0: 0x401ded20, 0x11f1: 0x401dee20, 0x11f2: 0x401def20, 0x11f3: 0x401df020, + 0x11f4: 0x401df120, 0x11f5: 0x401df220, 0x11f6: 0x401df320, 0x11f7: 0x401df420, + 0x11f8: 0x401dfc20, 0x11f9: 0x401dfd20, 0x11fa: 0x401dfe20, 0x11fb: 0x401dff20, + 0x11fc: 0x401e0020, 0x11fd: 0x401e0120, 0x11fe: 0x401e0220, 0x11ff: 0x401e0320, + // Block 0x48, offset 0x1200 + 0x1200: 0x401e0520, 0x1201: 0x401e0620, 0x1202: 0x401e0720, 0x1203: 0x401e0820, + 0x1204: 0x401e0920, 0x1205: 0x401e0a20, 0x1206: 0x401e0b20, 0x1207: 0x401e0c20, + 0x1208: 0x401e0d20, 0x120a: 0x401e0e20, 0x120b: 0x401e0f20, + 0x120c: 0x401e1020, 0x120d: 0x401e1120, + 0x1210: 0x401e1220, 0x1211: 0x401e1320, 0x1212: 0x401e1420, 0x1213: 0x401e1520, + 0x1214: 0x401e1620, 0x1215: 0x401e1720, 0x1216: 0x401e1820, + 0x1218: 0x401e1920, 0x121a: 0x401e1a20, 0x121b: 0x401e1b20, + 0x121c: 0x401e1c20, 0x121d: 0x401e1d20, + 0x1220: 0x401e1e20, 0x1221: 0x401e1f20, 0x1222: 0x401e2020, 0x1223: 0x401e2120, + 0x1224: 0x401e2220, 0x1225: 0x401e2320, 0x1226: 0x401e2420, 0x1227: 0x401e2520, + 0x1228: 0x401e2b20, 0x1229: 0x401e2c20, 0x122a: 0x401e2d20, 0x122b: 0x401e2e20, + 0x122c: 0x401e2f20, 0x122d: 0x401e3020, 0x122e: 0x401e3120, 0x122f: 0x401e3220, + 0x1230: 0x401e3320, 0x1231: 0x401e3420, 0x1232: 0x401e3520, 0x1233: 0x401e3620, + 0x1234: 0x401e3720, 0x1235: 0x401e3820, 0x1236: 0x401e3920, 0x1237: 0x401e3a20, + 0x1238: 0x401e3c20, 0x1239: 0x401e3d20, 0x123a: 0x401e3e20, 0x123b: 0x401e3f20, + 0x123c: 0x401e4020, 0x123d: 0x401e4120, 0x123e: 0x401e4220, 0x123f: 0x401e4320, + // Block 0x49, offset 0x1240 + 0x1240: 0x401e4520, 0x1241: 0x401e4620, 0x1242: 0x401e4720, 0x1243: 0x401e4820, + 0x1244: 0x401e4920, 0x1245: 0x401e4a20, 0x1246: 0x401e4b20, 0x1247: 0x401e4c20, + 0x1248: 0x401e4d20, 0x124a: 0x401e4e20, 0x124b: 0x401e4f20, + 0x124c: 0x401e5020, 0x124d: 0x401e5120, + 0x1250: 0x401e5220, 0x1251: 0x401e5320, 0x1252: 0x401e5420, 0x1253: 0x401e5520, + 0x1254: 0x401e5620, 0x1255: 0x401e5720, 0x1256: 0x401e5820, 0x1257: 0x401e5920, + 0x1258: 0x401e5b20, 0x1259: 0x401e5c20, 0x125a: 0x401e5d20, 0x125b: 0x401e5e20, + 0x125c: 0x401e5f20, 0x125d: 0x401e6020, 0x125e: 0x401e6120, 0x125f: 0x401e6220, + 0x1260: 0x401e6420, 0x1261: 0x401e6520, 0x1262: 0x401e6620, 0x1263: 0x401e6720, + 0x1264: 0x401e6820, 0x1265: 0x401e6920, 0x1266: 0x401e6a20, 0x1267: 0x401e6b20, + 0x1268: 0x401e6d20, 0x1269: 0x401e6e20, 0x126a: 0x401e6f20, 0x126b: 0x401e7020, + 0x126c: 0x401e7120, 0x126d: 0x401e7220, 0x126e: 0x401e7320, 0x126f: 0x401e7420, + 0x1270: 0x401e7520, 0x1272: 0x401e7620, 0x1273: 0x401e7720, + 0x1274: 0x401e7820, 0x1275: 0x401e7920, + 0x1278: 0x401e7a20, 0x1279: 0x401e7b20, 0x127a: 0x401e7c20, 0x127b: 0x401e7d20, + 0x127c: 0x401e7e20, 0x127d: 0x401e7f20, 0x127e: 0x401e8020, + // Block 0x4a, offset 0x1280 + 0x1280: 0x401e8120, 0x1282: 0x401e8220, 0x1283: 0x401e8320, + 0x1284: 0x401e8420, 0x1285: 0x401e8520, + 0x1288: 0x401e8620, 0x1289: 0x401e8720, 0x128a: 0x401e8820, 0x128b: 0x401e8920, + 0x128c: 0x401e8a20, 0x128d: 0x401e8b20, 0x128e: 0x401e8c20, 0x128f: 0x401e8d20, + 0x1290: 0x401e8e20, 0x1291: 0x401e8f20, 0x1292: 0x401e9020, 0x1293: 0x401e9120, + 0x1294: 0x401e9220, 0x1295: 0x401e9320, 0x1296: 0x401e9420, + 0x1298: 0x401e9520, 0x1299: 0x401e9620, 0x129a: 0x401e9720, 0x129b: 0x401e9820, + 0x129c: 0x401e9920, 0x129d: 0x401e9a20, 0x129e: 0x401e9b20, 0x129f: 0x401e9c20, + 0x12a0: 0x401ea420, 0x12a1: 0x401ea520, 0x12a2: 0x401ea620, 0x12a3: 0x401ea720, + 0x12a4: 0x401ea820, 0x12a5: 0x401ea920, 0x12a6: 0x401eaa20, 0x12a7: 0x401eab20, + 0x12a8: 0x401eac20, 0x12a9: 0x401ead20, 0x12aa: 0x401eae20, 0x12ab: 0x401eaf20, + 0x12ac: 0x401eb020, 0x12ad: 0x401eb120, 0x12ae: 0x401eb220, 0x12af: 0x401eb320, + 0x12b0: 0x401eb420, 0x12b1: 0x401eb520, 0x12b2: 0x401eb620, 0x12b3: 0x401eb720, + 0x12b4: 0x401eb820, 0x12b5: 0x401eb920, 0x12b6: 0x401eba20, 0x12b7: 0x401ebb20, + 0x12b8: 0x401ec320, 0x12b9: 0x401ec420, 0x12ba: 0x401ec520, 0x12bb: 0x401ec620, + 0x12bc: 0x401ec720, 0x12bd: 0x401ec820, 0x12be: 0x401ec920, 0x12bf: 0x401eca20, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x401ecc20, 0x12c1: 0x401ecd20, 0x12c2: 0x401ece20, 0x12c3: 0x401ecf20, + 0x12c4: 0x401ed020, 0x12c5: 0x401ed120, 0x12c6: 0x401ed220, 0x12c7: 0x401ed320, + 0x12c8: 0x401ed520, 0x12c9: 0x401ed620, 0x12ca: 0x401ed720, 0x12cb: 0x401ed820, + 0x12cc: 0x401ed920, 0x12cd: 0x401eda20, 0x12ce: 0x401edb20, 0x12cf: 0x401edc20, + 0x12d0: 0x401edd20, 0x12d2: 0x401ede20, 0x12d3: 0x401edf20, + 0x12d4: 0x401ee020, 0x12d5: 0x401ee120, + 0x12d8: 0x401ee220, 0x12d9: 0x401ee320, 0x12da: 0x401ee420, 0x12db: 0x401ee520, + 0x12dc: 0x401ee620, 0x12dd: 0x401ee720, 0x12de: 0x401ee820, 0x12df: 0x401ee920, + 0x12e0: 0x401eee20, 0x12e1: 0x401eef20, 0x12e2: 0x401ef020, 0x12e3: 0x401ef120, + 0x12e4: 0x401ef220, 0x12e5: 0x401ef320, 0x12e6: 0x401ef420, 0x12e7: 0x401ef520, + 0x12e8: 0x401ef720, 0x12e9: 0x401ef820, 0x12ea: 0x401ef920, 0x12eb: 0x401efa20, + 0x12ec: 0x401efb20, 0x12ed: 0x401efc20, 0x12ee: 0x401efd20, 0x12ef: 0x401efe20, + 0x12f0: 0x401f0720, 0x12f1: 0x401f0820, 0x12f2: 0x401f0920, 0x12f3: 0x401f0a20, + 0x12f4: 0x401f0b20, 0x12f5: 0x401f0c20, 0x12f6: 0x401f0d20, 0x12f7: 0x401f0e20, + 0x12f8: 0x401f1020, 0x12f9: 0x401f1120, 0x12fa: 0x401f1220, 0x12fb: 0x401f1320, + 0x12fc: 0x401f1420, 0x12fd: 0x401f1520, 0x12fe: 0x401f1620, 0x12ff: 0x401f1720, + // Block 0x4c, offset 0x1300 + 0x1300: 0x401f1f20, 0x1301: 0x401f2020, 0x1302: 0x401f2120, 0x1303: 0x401f2220, + 0x1304: 0x401f2320, 0x1305: 0x401f2420, 0x1306: 0x401f2520, 0x1307: 0x401f2620, + 0x1308: 0x401f2720, 0x1309: 0x401f2820, 0x130a: 0x401f2920, 0x130b: 0x401f2a20, + 0x130c: 0x401f2b20, 0x130d: 0x401f2c20, 0x130e: 0x401f2d20, 0x130f: 0x401f2e20, + 0x1310: 0x401f3320, 0x1311: 0x401f3420, 0x1312: 0x401f3520, 0x1313: 0x401f3620, + 0x1314: 0x401f3720, 0x1315: 0x401f3820, 0x1316: 0x401f3920, 0x1317: 0x401f3a20, + 0x1318: 0x401f4020, 0x1319: 0x401f4120, 0x131a: 0x401f4220, + 0x131d: 0x8000da02, 0x131e: 0x8000d902, 0x131f: 0x8000d802, + 0x1320: 0x40031020, 0x1321: 0x40014a20, 0x1322: 0x40017020, 0x1323: 0x40014b20, + 0x1324: 0x40014c20, 0x1325: 0x40014d20, 0x1326: 0x40014e20, 0x1327: 0x40016320, + 0x1328: 0x4001a420, 0x1329: 0xe00000a5, 0x132a: 0xe000018f, 0x132b: 0xe0000255, + 0x132c: 0xe0000318, 0x132d: 0xe00003d2, 0x132e: 0xe0000489, 0x132f: 0xe0000525, + 0x1330: 0xe00005c1, 0x1331: 0xe000065a, 0x1332: 0x4013e720, 0x1333: 0x4013e820, + 0x1334: 0x4013e920, 0x1335: 0x4013ea20, 0x1336: 0x4013eb20, 0x1337: 0x4013ec20, + 0x1338: 0x4013ed20, 0x1339: 0x4013ee20, 0x133a: 0x4013ef20, 0x133b: 0x4013f020, + 0x133c: 0x4013f120, + // Block 0x4d, offset 0x1340 + 0x1340: 0x401dd720, 0x1341: 0x401dd820, 0x1342: 0x401dd920, 0x1343: 0x401dda20, + 0x1344: 0x401e2620, 0x1345: 0x401e2720, 0x1346: 0x401e2820, 0x1347: 0x401e2920, + 0x1348: 0x401f2f20, 0x1349: 0x401f3020, 0x134a: 0x401f3120, 0x134b: 0x401f3220, + 0x134c: 0x401f3b20, 0x134d: 0x401f3c20, 0x134e: 0x401f3d20, 0x134f: 0x401f3e20, + 0x1350: 0x40035320, 0x1351: 0x40035420, 0x1352: 0x40035520, 0x1353: 0x40035620, + 0x1354: 0x40035720, 0x1355: 0x40035820, 0x1356: 0x40035920, 0x1357: 0x40035a20, + 0x1358: 0x40035b20, 0x1359: 0x40035c20, + 0x1360: 0x40291620, 0x1361: 0x40291720, 0x1362: 0x40291820, 0x1363: 0x40291920, + 0x1364: 0x40291a20, 0x1365: 0x40291b20, 0x1366: 0x40291c20, 0x1367: 0x40291d20, + 0x1368: 0x40291e20, 0x1369: 0x40291f20, 0x136a: 0x40292020, 0x136b: 0x40292120, + 0x136c: 0x40292220, 0x136d: 0x40292320, 0x136e: 0x40292420, 0x136f: 0x40292520, + 0x1370: 0x40292620, 0x1371: 0x40292720, 0x1372: 0x40292820, 0x1373: 0x40292920, + 0x1374: 0x40292a20, 0x1375: 0x40292b20, 0x1376: 0x40292c20, 0x1377: 0x40292d20, + 0x1378: 0x40292e20, 0x1379: 0x40292f20, 0x137a: 0x40293020, 0x137b: 0x40293120, + 0x137c: 0x40293220, 0x137d: 0x40293320, 0x137e: 0x40293420, 0x137f: 0x40293520, + // Block 0x4e, offset 0x1380 + 0x1380: 0x40293620, 0x1381: 0x40293720, 0x1382: 0x40293820, 0x1383: 0x40293920, + 0x1384: 0x40293a20, 0x1385: 0x40293b20, 0x1386: 0x40293c20, 0x1387: 0x40293d20, + 0x1388: 0x40293e20, 0x1389: 0x40293f20, 0x138a: 0x40294020, 0x138b: 0x40294120, + 0x138c: 0x40294220, 0x138d: 0x40294320, 0x138e: 0x40294420, 0x138f: 0x40294520, + 0x1390: 0x40294620, 0x1391: 0x40294720, 0x1392: 0x40294820, 0x1393: 0x40294920, + 0x1394: 0x40294a20, 0x1395: 0x40294b20, 0x1396: 0x40294c20, 0x1397: 0x40294d20, + 0x1398: 0x40294e20, 0x1399: 0x40294f20, 0x139a: 0x40295020, 0x139b: 0x40295120, + 0x139c: 0x40295220, 0x139d: 0x40295320, 0x139e: 0x40295420, 0x139f: 0x40295520, + 0x13a0: 0x40295620, 0x13a1: 0x40295720, 0x13a2: 0x40295820, 0x13a3: 0x40295920, + 0x13a4: 0x40295a20, 0x13a5: 0x40295b20, 0x13a6: 0x40295c20, 0x13a7: 0x40295d20, + 0x13a8: 0x40295e20, 0x13a9: 0x40295f20, 0x13aa: 0x40296020, 0x13ab: 0x40296120, + 0x13ac: 0x40296220, 0x13ad: 0x40296320, 0x13ae: 0x40296420, 0x13af: 0x40296520, + 0x13b0: 0x40296620, 0x13b1: 0x40296720, 0x13b2: 0x40296820, 0x13b3: 0x40296920, + 0x13b4: 0x40296a20, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x40011020, 0x13c1: 0x40296b20, 0x13c2: 0x40296c20, 0x13c3: 0x40296d20, + 0x13c4: 0x40296e20, 0x13c5: 0x40296f20, 0x13c6: 0x40297020, 0x13c7: 0x40297120, + 0x13c8: 0x40297220, 0x13c9: 0x40297320, 0x13ca: 0x40297420, 0x13cb: 0x40297520, + 0x13cc: 0x40297620, 0x13cd: 0x40297720, 0x13ce: 0x40297820, 0x13cf: 0x40297920, + 0x13d0: 0x40297a20, 0x13d1: 0x40297b20, 0x13d2: 0x40297c20, 0x13d3: 0x40297d20, + 0x13d4: 0x40297e20, 0x13d5: 0x40297f20, 0x13d6: 0x40298020, 0x13d7: 0x40298120, + 0x13d8: 0x40298220, 0x13d9: 0x40298320, 0x13da: 0x40298420, 0x13db: 0x40298520, + 0x13dc: 0x40298620, 0x13dd: 0x40298720, 0x13de: 0x40298820, 0x13df: 0x40298920, + 0x13e0: 0x40298a20, 0x13e1: 0x40298b20, 0x13e2: 0x40298c20, 0x13e3: 0x40298d20, + 0x13e4: 0x40298e20, 0x13e5: 0x40298f20, 0x13e6: 0x40299020, 0x13e7: 0x40299120, + 0x13e8: 0x40299220, 0x13e9: 0x40299320, 0x13ea: 0x40299420, 0x13eb: 0x40299520, + 0x13ec: 0x40299620, 0x13ed: 0x40299720, 0x13ee: 0x40299820, 0x13ef: 0x40299920, + 0x13f0: 0x40299a20, 0x13f1: 0x40299b20, 0x13f2: 0x40299c20, 0x13f3: 0x40299d20, + 0x13f4: 0x40299e20, 0x13f5: 0x40299f20, 0x13f6: 0x4029a020, 0x13f7: 0x4029a120, + 0x13f8: 0x4029a220, 0x13f9: 0x4029a320, 0x13fa: 0x4029a420, 0x13fb: 0x4029a520, + 0x13fc: 0x4029a620, 0x13fd: 0x4029a720, 0x13fe: 0x4029a820, 0x13ff: 0x4029a920, + // Block 0x50, offset 0x1400 + 0x1400: 0x4029aa20, 0x1401: 0x4029ab20, 0x1402: 0x4029ac20, 0x1403: 0x4029ad20, + 0x1404: 0x4029ae20, 0x1405: 0x4029af20, 0x1406: 0x4029b020, 0x1407: 0x4029b120, + 0x1408: 0x4029b220, 0x1409: 0x4029b320, 0x140a: 0x4029b420, 0x140b: 0x4029b520, + 0x140c: 0x4029b620, 0x140d: 0x4029b720, 0x140e: 0x4029b820, 0x140f: 0x4029b920, + 0x1410: 0x4029ba20, 0x1411: 0x4029bb20, 0x1412: 0x4029bc20, 0x1413: 0x4029bd20, + 0x1414: 0x4029be20, 0x1415: 0x4029bf20, 0x1416: 0x4029c020, 0x1417: 0x4029c120, + 0x1418: 0x4029c220, 0x1419: 0x4029c320, 0x141a: 0x4029c420, 0x141b: 0x4029c520, + 0x141c: 0x4029c620, 0x141d: 0x4029c720, 0x141e: 0x4029c820, 0x141f: 0x4029c920, + 0x1420: 0x4029ca20, 0x1421: 0x4029cb20, 0x1422: 0x4029cc20, 0x1423: 0x4029cd20, + 0x1424: 0x4029ce20, 0x1425: 0x4029cf20, 0x1426: 0x4029d020, 0x1427: 0x4029d120, + 0x1428: 0x4029d220, 0x1429: 0x4029d320, 0x142a: 0x4029d420, 0x142b: 0x4029d520, + 0x142c: 0x4029d620, 0x142d: 0x4029d720, 0x142e: 0x4029d820, 0x142f: 0x4029d920, + 0x1430: 0x4029da20, 0x1431: 0x4029db20, 0x1432: 0x4029dc20, 0x1433: 0x4029dd20, + 0x1434: 0x4029de20, 0x1435: 0x4029df20, 0x1436: 0x4029e020, 0x1437: 0x4029e120, + 0x1438: 0x4029e220, 0x1439: 0x4029e320, 0x143a: 0x4029e420, 0x143b: 0x4029e520, + 0x143c: 0x4029e620, 0x143d: 0x4029e720, 0x143e: 0x4029e820, 0x143f: 0x4029e920, + // Block 0x51, offset 0x1440 + 0x1440: 0x4029ea20, 0x1441: 0x4029eb20, 0x1442: 0x4029ec20, 0x1443: 0x4029ed20, + 0x1444: 0x4029ee20, 0x1445: 0x4029ef20, 0x1446: 0x4029f020, 0x1447: 0x4029f120, + 0x1448: 0x4029f220, 0x1449: 0x4029f320, 0x144a: 0x4029f420, 0x144b: 0x4029f520, + 0x144c: 0x4029f620, 0x144d: 0x4029f720, 0x144e: 0x4029f820, 0x144f: 0x4029f920, + 0x1450: 0x4029fa20, 0x1451: 0x4029fb20, 0x1452: 0x4029fc20, 0x1453: 0x4029fd20, + 0x1454: 0x4029fe20, 0x1455: 0x4029ff20, 0x1456: 0x402a0020, 0x1457: 0x402a0120, + 0x1458: 0x402a0220, 0x1459: 0x402a0320, 0x145a: 0x402a0420, 0x145b: 0x402a0520, + 0x145c: 0x402a0620, 0x145d: 0x402a0720, 0x145e: 0x402a0820, 0x145f: 0x402a0920, + 0x1460: 0x402a0a20, 0x1461: 0x402a0b20, 0x1462: 0x402a0c20, 0x1463: 0x402a0d20, + 0x1464: 0x402a0e20, 0x1465: 0x402a0f20, 0x1466: 0x402a1020, 0x1467: 0x402a1120, + 0x1468: 0x402a1220, 0x1469: 0x402a1320, 0x146a: 0x402a1420, 0x146b: 0x402a1520, + 0x146c: 0x402a1620, 0x146d: 0x402a1720, 0x146e: 0x402a1820, 0x146f: 0x402a1920, + 0x1470: 0x402a1a20, 0x1471: 0x402a1b20, 0x1472: 0x402a1c20, 0x1473: 0x402a1d20, + 0x1474: 0x402a1e20, 0x1475: 0x402a1f20, 0x1476: 0x402a2020, 0x1477: 0x402a2120, + 0x1478: 0x402a2220, 0x1479: 0x402a2320, 0x147a: 0x402a2420, 0x147b: 0x402a2520, + 0x147c: 0x402a2620, 0x147d: 0x402a2720, 0x147e: 0x402a2820, 0x147f: 0x402a2920, + // Block 0x52, offset 0x1480 + 0x1480: 0x402a2a20, 0x1481: 0x402a2b20, 0x1482: 0x402a2c20, 0x1483: 0x402a2d20, + 0x1484: 0x402a2e20, 0x1485: 0x402a2f20, 0x1486: 0x402a3020, 0x1487: 0x402a3120, + 0x1488: 0x402a3220, 0x1489: 0x402a3320, 0x148a: 0x402a3420, 0x148b: 0x402a3520, + 0x148c: 0x402a3620, 0x148d: 0x402a3720, 0x148e: 0x402a3820, 0x148f: 0x402a3920, + 0x1490: 0x402a3a20, 0x1491: 0x402a3b20, 0x1492: 0x402a3c20, 0x1493: 0x402a3d20, + 0x1494: 0x402a3e20, 0x1495: 0x402a3f20, 0x1496: 0x402a4020, 0x1497: 0x402a4120, + 0x1498: 0x402a4220, 0x1499: 0x402a4320, 0x149a: 0x402a4420, 0x149b: 0x402a4520, + 0x149c: 0x402a4620, 0x149d: 0x402a4720, 0x149e: 0x402a4820, 0x149f: 0x402a4920, + 0x14a0: 0x402a4a20, 0x14a1: 0x402a4b20, 0x14a2: 0x402a4c20, 0x14a3: 0x402a4d20, + 0x14a4: 0x402a4e20, 0x14a5: 0x402a4f20, 0x14a6: 0x402a5020, 0x14a7: 0x402a5120, + 0x14a8: 0x402a5220, 0x14a9: 0x402a5320, 0x14aa: 0x402a5420, 0x14ab: 0x402a5520, + 0x14ac: 0x402a5620, 0x14ad: 0x402a5720, 0x14ae: 0x402a5820, 0x14af: 0x402a5920, + 0x14b0: 0x402a5a20, 0x14b1: 0x402a5b20, 0x14b2: 0x402a5c20, 0x14b3: 0x402a5d20, + 0x14b4: 0x402a5e20, 0x14b5: 0x402a5f20, 0x14b6: 0x402a6020, 0x14b7: 0x402a6120, + 0x14b8: 0x402a6220, 0x14b9: 0x402a6320, 0x14ba: 0x402a6420, 0x14bb: 0x402a6520, + 0x14bc: 0x402a6620, 0x14bd: 0x402a6720, 0x14be: 0x402a6820, 0x14bf: 0x402a6920, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x402a6a20, 0x14c1: 0x402a6b20, 0x14c2: 0x402a6c20, 0x14c3: 0x402a6d20, + 0x14c4: 0x402a6e20, 0x14c5: 0x402a6f20, 0x14c6: 0x402a7020, 0x14c7: 0x402a7120, + 0x14c8: 0x402a7220, 0x14c9: 0x402a7320, 0x14ca: 0x402a7420, 0x14cb: 0x402a7520, + 0x14cc: 0x402a7620, 0x14cd: 0x402a7720, 0x14ce: 0x402a7820, 0x14cf: 0x402a7920, + 0x14d0: 0x402a7a20, 0x14d1: 0x402a7b20, 0x14d2: 0x402a7c20, 0x14d3: 0x402a7d20, + 0x14d4: 0x402a7e20, 0x14d5: 0x402a7f20, 0x14d6: 0x402a8020, 0x14d7: 0x402a8120, + 0x14d8: 0x402a8220, 0x14d9: 0x402a8320, 0x14da: 0x402a8420, 0x14db: 0x402a8520, + 0x14dc: 0x402a8620, 0x14dd: 0x402a8720, 0x14de: 0x402a8820, 0x14df: 0x402a8920, + 0x14e0: 0x402a8a20, 0x14e1: 0x402a8b20, 0x14e2: 0x402a8c20, 0x14e3: 0x402a8d20, + 0x14e4: 0x402a8e20, 0x14e5: 0x402a8f20, 0x14e6: 0x402a9020, 0x14e7: 0x402a9120, + 0x14e8: 0x402a9220, 0x14e9: 0x402a9320, 0x14ea: 0x402a9420, 0x14eb: 0x402a9520, + 0x14ec: 0x402a9620, 0x14ed: 0x402a9720, 0x14ee: 0x402a9820, 0x14ef: 0x402a9920, + 0x14f0: 0x402a9a20, 0x14f1: 0x402a9b20, 0x14f2: 0x402a9c20, 0x14f3: 0x402a9d20, + 0x14f4: 0x402a9e20, 0x14f5: 0x402a9f20, 0x14f6: 0x402aa020, 0x14f7: 0x402aa120, + 0x14f8: 0x402aa220, 0x14f9: 0x402aa320, 0x14fa: 0x402aa420, 0x14fb: 0x402aa520, + 0x14fc: 0x402aa620, 0x14fd: 0x402aa720, 0x14fe: 0x402aa820, 0x14ff: 0x402aa920, + // Block 0x54, offset 0x1500 + 0x1500: 0x402aaa20, 0x1501: 0x402aab20, 0x1502: 0x402aac20, 0x1503: 0x402aad20, + 0x1504: 0x402aae20, 0x1505: 0x402aaf20, 0x1506: 0x402ab020, 0x1507: 0x402ab120, + 0x1508: 0x402ab220, 0x1509: 0x402ab320, 0x150a: 0x402ab420, 0x150b: 0x402ab520, + 0x150c: 0x402ab620, 0x150d: 0x402ab720, 0x150e: 0x402ab820, 0x150f: 0x402ab920, + 0x1510: 0x402aba20, 0x1511: 0x402abb20, 0x1512: 0x402abc20, 0x1513: 0x402abd20, + 0x1514: 0x402abe20, 0x1515: 0x402abf20, 0x1516: 0x402ac020, 0x1517: 0x402ac120, + 0x1518: 0x402ac220, 0x1519: 0x402ac320, 0x151a: 0x402ac420, 0x151b: 0x402ac520, + 0x151c: 0x402ac620, 0x151d: 0x402ac720, 0x151e: 0x402ac820, 0x151f: 0x402ac920, + 0x1520: 0x402aca20, 0x1521: 0x402acb20, 0x1522: 0x402acc20, 0x1523: 0x402acd20, + 0x1524: 0x402ace20, 0x1525: 0x402acf20, 0x1526: 0x402ad020, 0x1527: 0x402ad120, + 0x1528: 0x402ad220, 0x1529: 0x402ad320, 0x152a: 0x402ad420, 0x152b: 0x402ad520, + 0x152c: 0x402ad620, 0x152d: 0x402ad720, 0x152e: 0x402ad820, 0x152f: 0x402ad920, + 0x1530: 0x402ada20, 0x1531: 0x402adb20, 0x1532: 0x402adc20, 0x1533: 0x402add20, + 0x1534: 0x402ade20, 0x1535: 0x402adf20, 0x1536: 0x402ae020, 0x1537: 0x402ae120, + 0x1538: 0x402ae220, 0x1539: 0x402ae320, 0x153a: 0x402ae420, 0x153b: 0x402ae520, + 0x153c: 0x402b1820, 0x153d: 0x402ae620, 0x153e: 0x402ae820, 0x153f: 0x402ae920, + // Block 0x55, offset 0x1540 + 0x1540: 0x402aea20, 0x1541: 0x402aeb20, 0x1542: 0x402aec20, 0x1543: 0x402aed20, + 0x1544: 0x402aee20, 0x1545: 0x402aef20, 0x1546: 0x402af020, 0x1547: 0x402af120, + 0x1548: 0x402af220, 0x1549: 0x402af320, 0x154a: 0x402af420, 0x154b: 0x402af520, + 0x154c: 0x402af620, 0x154d: 0x402af720, 0x154e: 0x402af920, 0x154f: 0x402afa20, + 0x1550: 0x402afb20, 0x1551: 0x402afc20, 0x1552: 0x402afd20, 0x1553: 0x402afe20, + 0x1554: 0x402aff20, 0x1555: 0x402b0020, 0x1556: 0x402b0720, 0x1557: 0x402b0820, + 0x1558: 0x402b0920, 0x1559: 0x402b0a20, 0x155a: 0x402b0b20, 0x155b: 0x402b0c20, + 0x155c: 0x402b0d20, 0x155d: 0x402b0e20, 0x155e: 0x402b0f20, 0x155f: 0x402b1020, + 0x1560: 0x402b1120, 0x1561: 0x402b1220, 0x1562: 0x402b1320, 0x1563: 0x402b1420, + 0x1564: 0x402b1520, 0x1565: 0x402b1620, 0x1566: 0x402b1720, 0x1567: 0x402b1920, + 0x1568: 0x402b1a20, 0x1569: 0x402b1b20, 0x156a: 0x402b1c20, 0x156b: 0x402b1d20, + 0x156c: 0x402b1e20, 0x156d: 0x402b1f20, 0x156e: 0x402b2020, 0x156f: 0x402b2120, + 0x1570: 0x402b2220, 0x1571: 0x402b2320, 0x1572: 0x402b2420, 0x1573: 0x402b2520, + 0x1574: 0x402b2620, 0x1575: 0x402b2720, 0x1576: 0x402b2820, 0x1577: 0x402b2920, + 0x1578: 0x402b2a20, 0x1579: 0x402b2b20, 0x157a: 0x402b2c20, 0x157b: 0x402b2d20, + 0x157c: 0x402b2e20, 0x157d: 0x402b2f20, 0x157e: 0x402b3020, 0x157f: 0x402b3120, + // Block 0x56, offset 0x1580 + 0x1580: 0x402b3220, 0x1581: 0x402b3320, 0x1582: 0x402b3420, 0x1583: 0x402b3520, + 0x1584: 0x402b3620, 0x1585: 0x402b3720, 0x1586: 0x402b3820, 0x1587: 0x402b3920, + 0x1588: 0x402b3a20, 0x1589: 0x402b3b20, 0x158a: 0x402b3c20, 0x158b: 0x402b3d20, + 0x158c: 0x402b3e20, 0x158d: 0x402b3f20, 0x158e: 0x402b4020, 0x158f: 0x402b4120, + 0x1590: 0x402b4220, 0x1591: 0x402b4320, 0x1592: 0x402b4420, 0x1593: 0x402b4520, + 0x1594: 0x402b4620, 0x1595: 0x402b4720, 0x1596: 0x402b4820, 0x1597: 0x402b4920, + 0x1598: 0x402b4a20, 0x1599: 0x402b4b20, 0x159a: 0x402b4c20, 0x159b: 0x402b4d20, + 0x159c: 0x402b4e20, 0x159d: 0x402b4f20, 0x159e: 0x402b5020, 0x159f: 0x402b5120, + 0x15a0: 0x402b5220, 0x15a1: 0x402b5320, 0x15a2: 0x402b5420, 0x15a3: 0x402b5520, + 0x15a4: 0x402b5620, 0x15a5: 0x402b5720, 0x15a6: 0x402b5820, 0x15a7: 0x402b5920, + 0x15a8: 0x402b5a20, 0x15a9: 0x402b5b20, 0x15aa: 0x402b5c20, 0x15ab: 0x402b5d20, + 0x15ac: 0x402b5e20, 0x15ad: 0x402b5f20, 0x15ae: 0x402b6020, 0x15af: 0x402b6120, + 0x15b0: 0x402b6220, 0x15b1: 0x402b6320, 0x15b2: 0x402b6420, 0x15b3: 0x402b6520, + 0x15b4: 0x402b6620, 0x15b5: 0x402b6720, 0x15b6: 0x402b6820, 0x15b7: 0x402b6920, + 0x15b8: 0x402b6a20, 0x15b9: 0x402b6b20, 0x15ba: 0x402b6c20, 0x15bb: 0x402b6d20, + 0x15bc: 0x402b6e20, 0x15bd: 0x402b6f20, 0x15be: 0x402b7020, 0x15bf: 0x402b7120, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x402b7220, 0x15c1: 0x402b7320, 0x15c2: 0x402b7420, 0x15c3: 0x402b7520, + 0x15c4: 0x402b7620, 0x15c5: 0x402b7720, 0x15c6: 0x402b7820, 0x15c7: 0x402b7920, + 0x15c8: 0x402b7a20, 0x15c9: 0x402b7b20, 0x15ca: 0x402b7c20, 0x15cb: 0x402b7d20, + 0x15cc: 0x402b7e20, 0x15cd: 0x402b7f20, 0x15ce: 0x402b8020, 0x15cf: 0x402b8120, + 0x15d0: 0x402b8220, 0x15d1: 0x402b8320, 0x15d2: 0x402b8420, 0x15d3: 0x402b8520, + 0x15d4: 0x402b8620, 0x15d5: 0x402b8720, 0x15d6: 0x402b8820, 0x15d7: 0x402b8920, + 0x15d8: 0x402b8a20, 0x15d9: 0x402b8b20, 0x15da: 0x402b8c20, 0x15db: 0x402b8d20, + 0x15dc: 0x402b8e20, 0x15dd: 0x402b8f20, 0x15de: 0x402b9020, 0x15df: 0x402b9120, + 0x15e0: 0x402b9220, 0x15e1: 0x402b9320, 0x15e2: 0x402b9420, 0x15e3: 0x402b9520, + 0x15e4: 0x402b9620, 0x15e5: 0x402b9720, 0x15e6: 0x402b9820, 0x15e7: 0x402b9920, + 0x15e8: 0x402b9a20, 0x15e9: 0x402b9b20, 0x15ea: 0x402b9c20, 0x15eb: 0x402b9d20, + 0x15ec: 0x402b9e20, 0x15ed: 0x402b9f20, 0x15ee: 0x402ba020, 0x15ef: 0x402ba120, + 0x15f0: 0x402ba220, 0x15f1: 0x402ba320, 0x15f2: 0x402ba420, 0x15f3: 0x402ba520, + 0x15f4: 0x402ba620, 0x15f5: 0x402ba720, 0x15f6: 0x402ba820, 0x15f7: 0x402ba920, + 0x15f8: 0x402baa20, 0x15f9: 0x402bab20, 0x15fa: 0x402bac20, 0x15fb: 0x402bad20, + 0x15fc: 0x402bae20, 0x15fd: 0x402baf20, 0x15fe: 0x402bb020, 0x15ff: 0x402bb120, + // Block 0x58, offset 0x1600 + 0x1600: 0x402bb220, 0x1601: 0x402bb320, 0x1602: 0x402bb420, 0x1603: 0x402bb520, + 0x1604: 0x402bb620, 0x1605: 0x402bb720, 0x1606: 0x402bb820, 0x1607: 0x402bb920, + 0x1608: 0x402bba20, 0x1609: 0x402bbb20, 0x160a: 0x402bbc20, 0x160b: 0x402bbd20, + 0x160c: 0x402bbe20, 0x160d: 0x402bbf20, 0x160e: 0x402bc020, 0x160f: 0x402bc120, + 0x1610: 0x402bc220, 0x1611: 0x402bc320, 0x1612: 0x402bc420, 0x1613: 0x402bc520, + 0x1614: 0x402bc620, 0x1615: 0x402bc720, 0x1616: 0x402bc820, 0x1617: 0x402bc920, + 0x1618: 0x402bca20, 0x1619: 0x402bcb20, 0x161a: 0x402bcc20, 0x161b: 0x402bcd20, + 0x161c: 0x402bce20, 0x161d: 0x402bcf20, 0x161e: 0x402bd020, 0x161f: 0x402bd120, + 0x1620: 0x402bd220, 0x1621: 0x402bd320, 0x1622: 0x402bd420, 0x1623: 0x402bd520, + 0x1624: 0x402bd620, 0x1625: 0x402bd720, 0x1626: 0x402bd820, 0x1627: 0x402bd920, + 0x1628: 0x402bda20, 0x1629: 0x402bdb20, 0x162a: 0x402bdc20, 0x162b: 0x402bdd20, + 0x162c: 0x402bde20, 0x162d: 0x4002b620, 0x162e: 0x40017320, 0x162f: 0x402ae720, + 0x1630: 0x402af820, 0x1631: 0x402b0120, 0x1632: 0x402b0220, 0x1633: 0x402b0320, + 0x1634: 0x402b0420, 0x1635: 0x402b0520, 0x1636: 0x402b0620, 0x1637: 0x402bdf20, + 0x1638: 0x402be020, 0x1639: 0x402be120, 0x163a: 0x402be220, 0x163b: 0x402be320, + 0x163c: 0x402be420, 0x163d: 0x402be520, 0x163e: 0x402be620, 0x163f: 0x402be720, + // Block 0x59, offset 0x1640 + 0x1640: 0x40010a20, 0x1641: 0x402c2e20, 0x1642: 0x402c2f20, 0x1643: 0x402c3020, + 0x1644: 0x402c3120, 0x1645: 0x402c3220, 0x1646: 0x402c3320, 0x1647: 0x402c3420, + 0x1648: 0x402c3520, 0x1649: 0x402c3620, 0x164a: 0x402c3720, 0x164b: 0x402c3820, + 0x164c: 0x402c3920, 0x164d: 0x402c3a20, 0x164e: 0x402c3b20, 0x164f: 0x402c3c20, + 0x1650: 0x402c3d20, 0x1651: 0x402c3e20, 0x1652: 0x402c3f20, 0x1653: 0x402c4020, + 0x1654: 0x402c4120, 0x1655: 0x402c4220, 0x1656: 0x402c4320, 0x1657: 0x402c4420, + 0x1658: 0x402c4520, 0x1659: 0x402c4620, 0x165a: 0x402c4720, 0x165b: 0x4001f320, + 0x165c: 0x4001f420, + 0x1660: 0x402c4820, 0x1661: 0xe0001064, 0x1662: 0x402c4920, 0x1663: 0x402c6520, + 0x1664: 0xe0001067, 0x1665: 0xe000106a, 0x1666: 0x402c4a20, 0x1667: 0xe000106d, + 0x1668: 0x402c4b20, 0x1669: 0xe0001073, 0x166a: 0x402c6320, 0x166b: 0x402c6420, + 0x166c: 0xe0001076, 0x166d: 0xe0001079, 0x166e: 0xe000107c, 0x166f: 0x402c4c20, + 0x1670: 0x402c4d20, 0x1671: 0x402c4e20, 0x1672: 0x402c4f20, 0x1673: 0xe000107f, + 0x1674: 0xe0001082, 0x1675: 0xe0001085, 0x1676: 0xe0001088, 0x1677: 0x402c5020, + 0x1678: 0x402c6820, 0x1679: 0x402c5120, 0x167a: 0x402c5220, 0x167b: 0xe000108e, + 0x167c: 0xe0001091, 0x167d: 0xe0001094, 0x167e: 0x402c5320, 0x167f: 0xe0001097, + // Block 0x5a, offset 0x1680 + 0x1680: 0xe000109a, 0x1681: 0x402c5420, 0x1682: 0xe000109d, 0x1683: 0x402c5520, + 0x1684: 0xe00010a0, 0x1685: 0x402c5620, 0x1686: 0xe00010a3, 0x1687: 0x402c5720, + 0x1688: 0x402c5820, 0x1689: 0x402c5920, 0x168a: 0x402c5a20, 0x168b: 0xe00010ac, + 0x168c: 0xe00010b2, 0x168d: 0xe00010b5, 0x168e: 0xe00010b8, 0x168f: 0x402c5b20, + 0x1690: 0xe00010bb, 0x1691: 0xe00010be, 0x1692: 0x402c5c20, 0x1693: 0xe00010c1, + 0x1694: 0xe00010c4, 0x1695: 0xe00010a9, 0x1696: 0x402c5d20, 0x1697: 0x402c5e20, + 0x1698: 0xe00010c7, 0x1699: 0xe00010ca, 0x169a: 0x402c5f20, 0x169b: 0xe00010d2, + 0x169c: 0x402c6020, 0x169d: 0xe00010d5, 0x169e: 0x402c6120, 0x169f: 0x402c6220, + 0x16a0: 0x402c6620, 0x16a1: 0x402c6a20, 0x16a2: 0x402c6b20, 0x16a3: 0x402c6720, + 0x16a4: 0x402c6920, 0x16a5: 0x402c6c20, 0x16a6: 0x402c6d20, 0x16a7: 0xe00010d8, + 0x16a8: 0xe00010db, 0x16a9: 0xe000108b, 0x16aa: 0xe00010af, 0x16ab: 0x40015420, + 0x16ac: 0x40015520, 0x16ad: 0x40015620, 0x16ae: 0xe00010a6, 0x16af: 0xe00010cd, + 0x16b0: 0xe0001070, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x40254620, 0x16c1: 0x40254720, 0x16c2: 0x40254820, 0x16c3: 0x40254920, + 0x16c4: 0x40254a20, 0x16c5: 0x40254b20, 0x16c6: 0x40254c20, 0x16c7: 0x40254d20, + 0x16c8: 0x40254e20, 0x16c9: 0x40254f20, 0x16ca: 0x40255020, 0x16cb: 0x40255120, + 0x16cc: 0x40255220, 0x16ce: 0x40255320, 0x16cf: 0x40255420, + 0x16d0: 0x40255520, 0x16d1: 0x40255620, 0x16d2: 0x40255720, 0x16d3: 0x40255820, + 0x16d4: 0x40255920, + 0x16e0: 0x40255a20, 0x16e1: 0x40255b20, 0x16e2: 0x40255c20, 0x16e3: 0x40255d20, + 0x16e4: 0x40255e20, 0x16e5: 0x40255f20, 0x16e6: 0x40256020, 0x16e7: 0x40256120, + 0x16e8: 0x40256220, 0x16e9: 0x40256320, 0x16ea: 0x40256420, 0x16eb: 0x40256520, + 0x16ec: 0x40256620, 0x16ed: 0x40256720, 0x16ee: 0x40256820, 0x16ef: 0x40256920, + 0x16f0: 0x40256a20, 0x16f1: 0x40256b20, 0x16f2: 0x40256c20, 0x16f3: 0x40256d20, + 0x16f4: 0x40256e20, 0x16f5: 0x40018620, 0x16f6: 0x40018720, + // Block 0x5c, offset 0x1700 + 0x1700: 0x40256f20, 0x1701: 0x40257020, 0x1702: 0x40257120, 0x1703: 0x40257220, + 0x1704: 0x40257320, 0x1705: 0x40257420, 0x1706: 0x40257520, 0x1707: 0x40257620, + 0x1708: 0x40257720, 0x1709: 0x40257820, 0x170a: 0x40257920, 0x170b: 0x40257a20, + 0x170c: 0x40257b20, 0x170d: 0x40257c20, 0x170e: 0x40257d20, 0x170f: 0x40257e20, + 0x1710: 0x40257f20, 0x1711: 0x40258020, 0x1712: 0x40258120, 0x1713: 0x40258220, + 0x1720: 0x40258320, 0x1721: 0x40258420, 0x1722: 0x40258520, 0x1723: 0x40258620, + 0x1724: 0x40258720, 0x1725: 0x40258820, 0x1726: 0x40258920, 0x1727: 0x40258a20, + 0x1728: 0x40258b20, 0x1729: 0x40258c20, 0x172a: 0x40258d20, 0x172b: 0x40258e20, + 0x172c: 0x40258f20, 0x172e: 0x40259020, 0x172f: 0x40259120, + 0x1730: 0x40259220, 0x1732: 0x40259320, 0x1733: 0x40259420, + // Block 0x5d, offset 0x1740 + 0x1740: 0x4026ab20, 0x1741: 0x4026ac20, 0x1742: 0x4026ad20, 0x1743: 0x4026ae20, + 0x1744: 0x4026af20, 0x1745: 0x4026b020, 0x1746: 0x4026b120, 0x1747: 0x4026b220, + 0x1748: 0x4026b320, 0x1749: 0x4026b420, 0x174a: 0x4026b520, 0x174b: 0x4026b620, + 0x174c: 0x4026b720, 0x174d: 0x4026b820, 0x174e: 0x4026b920, 0x174f: 0x4026ba20, + 0x1750: 0x4026bb20, 0x1751: 0x4026bc20, 0x1752: 0x4026bd20, 0x1753: 0x4026be20, + 0x1754: 0x4026bf20, 0x1755: 0x4026c020, 0x1756: 0x4026c120, 0x1757: 0x4026c220, + 0x1758: 0x4026c320, 0x1759: 0x4026c420, 0x175a: 0x4026c520, 0x175b: 0x4026c620, + 0x175c: 0x4026c720, 0x175d: 0x4026c820, 0x175e: 0x4026c920, 0x175f: 0x4026ca20, + 0x1760: 0x4026cb20, 0x1761: 0x4026cc20, 0x1762: 0x4026cd20, 0x1763: 0x4026cf20, + 0x1764: 0x4026d020, 0x1765: 0x4026d120, 0x1766: 0x4026d220, 0x1767: 0x4026d320, + 0x1768: 0x4026d420, 0x1769: 0x4026d520, 0x176a: 0x4026d620, 0x176b: 0x4026d720, + 0x176c: 0x4026d820, 0x176d: 0x4026d920, 0x176e: 0x4026da20, 0x176f: 0x4026db20, + 0x1770: 0x4026dc20, 0x1771: 0x4026dd20, 0x1772: 0x4026de20, 0x1773: 0x4026df20, + 0x1774: 0x4026e020, 0x1775: 0x4026e120, 0x1776: 0x4026e220, 0x1777: 0x4026e320, + 0x1778: 0x4026e420, 0x1779: 0x4026e520, 0x177a: 0x4026e620, 0x177b: 0x4026e720, + 0x177c: 0x4026e820, 0x177d: 0x4026e920, 0x177e: 0x4026ea20, 0x177f: 0x4026eb20, + // Block 0x5e, offset 0x1780 + 0x1780: 0x4026ec20, 0x1781: 0x4026ed20, 0x1782: 0x4026ee20, 0x1783: 0x4026ef20, + 0x1784: 0x4026f020, 0x1785: 0x4026f120, 0x1786: 0x80013702, 0x1787: 0x80013802, + 0x1788: 0x80013902, 0x1789: 0x80013a02, 0x178a: 0x80013b02, 0x178b: 0x80005f02, + 0x178c: 0x80005f02, 0x178d: 0x80005f02, 0x178e: 0x80005f02, 0x178f: 0x80005f02, + 0x1790: 0x80005f02, 0x1791: 0x80005f02, 0x1792: 0x4026f220, 0x1793: 0x80000000, + 0x1794: 0x40018b20, 0x1795: 0x40018c20, 0x1796: 0x40015120, 0x1797: 0x40031f20, + 0x1798: 0x4002aa20, 0x1799: 0x4002ab20, 0x179a: 0x4002ac20, 0x179b: 0x4013b020, + 0x179c: 0x4026ce20, 0x179d: 0x80005f02, + 0x17a0: 0xe0000075, 0x17a1: 0xe00000f9, 0x17a2: 0xe00001e0, 0x17a3: 0xe00002a6, + 0x17a4: 0xe0000363, 0x17a5: 0xe000041d, 0x17a6: 0xe00004d4, 0x17a7: 0xe0000570, + 0x17a8: 0xe000060c, 0x17a9: 0xe00006a5, + 0x17b0: 0xe0000078, 0x17b1: 0xe00000fc, 0x17b2: 0xe00001e3, 0x17b3: 0xe00002a9, + 0x17b4: 0xe0000366, 0x17b5: 0xe0000420, 0x17b6: 0xe00004d7, 0x17b7: 0xe0000573, + 0x17b8: 0xe000060f, 0x17b9: 0xe00006a8, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x40028320, 0x17c1: 0x40016c20, 0x17c2: 0x40012620, 0x17c3: 0x40017120, + 0x17c4: 0x40014f20, 0x17c5: 0x40015020, 0x17c6: 0x40011220, 0x17c7: 0x40011320, + 0x17c8: 0x40012720, 0x17c9: 0x40017220, 0x17ca: 0x80000000, 0x17cb: 0x80000000, + 0x17cc: 0x80000000, 0x17cd: 0x80000000, 0x17ce: 0x40010620, + 0x17d0: 0xe0000087, 0x17d1: 0xe000010b, 0x17d2: 0xe00001f2, 0x17d3: 0xe00002b8, + 0x17d4: 0xe0000375, 0x17d5: 0xe000042f, 0x17d6: 0xe00004e6, 0x17d7: 0xe0000582, + 0x17d8: 0xe000061e, 0x17d9: 0xe00006b7, + 0x17e0: 0x40287720, 0x17e1: 0x40287920, 0x17e2: 0x40287c20, 0x17e3: 0x40288220, + 0x17e4: 0x40288420, 0x17e5: 0x40288720, 0x17e6: 0x40288920, 0x17e7: 0x40288c20, + 0x17e8: 0x40288d20, 0x17e9: 0x40288e20, 0x17ea: 0x40289320, 0x17eb: 0x40289520, + 0x17ec: 0x40289820, 0x17ed: 0x40289a20, 0x17ee: 0x40289f20, 0x17ef: 0x4028a120, + 0x17f0: 0x4028a220, 0x17f1: 0x4028a320, 0x17f2: 0x4028aa20, 0x17f3: 0x4028ad20, + 0x17f4: 0x4028b020, 0x17f5: 0x4028b520, 0x17f6: 0x4028b920, 0x17f7: 0x4028bc20, + 0x17f8: 0x4028be20, 0x17f9: 0x4028c020, 0x17fa: 0x4028c320, 0x17fb: 0x4028c820, + 0x17fc: 0x4028c920, 0x17fd: 0x4028cc20, 0x17fe: 0x4028d020, 0x17ff: 0x4028d320, + // Block 0x60, offset 0x1800 + 0x1800: 0x4028d420, 0x1801: 0x4028d520, 0x1802: 0x4028d620, 0x1803: 0x40287620, + 0x1804: 0x40287a20, 0x1805: 0x40287d20, 0x1806: 0x40288320, 0x1807: 0x40288520, + 0x1808: 0x40288820, 0x1809: 0x40288a20, 0x180a: 0x40288f20, 0x180b: 0x40289420, + 0x180c: 0x40289620, 0x180d: 0x40289920, 0x180e: 0x40289b20, 0x180f: 0x4028a020, + 0x1810: 0x4028ab20, 0x1811: 0x4028ae20, 0x1812: 0x4028b120, 0x1813: 0x4028b620, + 0x1814: 0x4028ca20, 0x1815: 0x4028ba20, 0x1816: 0x4028bf20, 0x1817: 0x4028c420, + 0x1818: 0x4028ce20, 0x1819: 0x4028d120, 0x181a: 0x4028d720, 0x181b: 0x4028d820, + 0x181c: 0x4028b320, 0x181d: 0x40287b20, 0x181e: 0x40287e20, 0x181f: 0x40288120, + 0x1820: 0x40288b20, 0x1821: 0x40288620, 0x1822: 0x40289020, 0x1823: 0x4028c520, + 0x1824: 0x40289c20, 0x1825: 0x40289e20, 0x1826: 0x40289720, 0x1827: 0x4028a420, + 0x1828: 0x4028ac20, 0x1829: 0x4028af20, 0x182a: 0x4028b720, 0x182b: 0x4028c120, + 0x182c: 0x4028cf20, 0x182d: 0x4028d220, 0x182e: 0x4028cb20, 0x182f: 0x4028cd20, + 0x1830: 0x4028d920, 0x1831: 0x4028b220, 0x1832: 0x4028bb20, 0x1833: 0x40287f20, + 0x1834: 0x4028c620, 0x1835: 0x4028bd20, 0x1836: 0x4028c220, 0x1837: 0x4028b820, + // Block 0x61, offset 0x1840 + 0x1840: 0x40286f20, 0x1841: 0x40287020, 0x1842: 0x40287120, 0x1843: 0x40287220, + 0x1844: 0x40287320, 0x1845: 0x40287420, 0x1846: 0x40287520, 0x1847: 0x40287820, + 0x1848: 0x40288020, 0x1849: 0x4028c720, 0x184a: 0x40289120, 0x184b: 0x4028b420, + 0x184c: 0x4028da20, 0x184d: 0x4028dc20, 0x184e: 0x4028dd20, 0x184f: 0x4028df20, + 0x1850: 0x4028e020, 0x1851: 0x4028e320, 0x1852: 0x4028e520, 0x1853: 0x4028e620, + 0x1854: 0x4028e820, 0x1855: 0x4028ea20, 0x1856: 0x4028ec20, 0x1857: 0x4028ed20, + 0x1858: 0x4028e120, 0x1859: 0x4028eb20, 0x185a: 0x40289d20, 0x185b: 0x40289220, + 0x185c: 0x4028a520, 0x185d: 0x4028a620, 0x185e: 0x4028db20, 0x185f: 0x4028de20, + 0x1860: 0x4028e220, 0x1861: 0x4028e420, 0x1862: 0x4028a720, 0x1863: 0x4028e920, + 0x1864: 0x4028a820, 0x1865: 0x4028a920, 0x1866: 0x4028ee20, 0x1867: 0x4028ef20, + 0x1868: 0x4028e720, 0x1869: 0x4028f120, 0x186a: 0x4028f020, + 0x1870: 0x402be820, 0x1871: 0x402be920, 0x1872: 0x402bea20, 0x1873: 0x402beb20, + 0x1874: 0x402bec20, 0x1875: 0x402bed20, 0x1876: 0x402bee20, 0x1877: 0x402bef20, + 0x1878: 0x402bf020, 0x1879: 0x402bf120, 0x187a: 0x402bf220, 0x187b: 0x402bf320, + 0x187c: 0x402bf420, 0x187d: 0x402bf520, 0x187e: 0x402bf620, 0x187f: 0x402bf720, + // Block 0x62, offset 0x1880 + 0x1880: 0x402bf820, 0x1881: 0x402bf920, 0x1882: 0x402bfa20, 0x1883: 0x402bfb20, + 0x1884: 0x402bfc20, 0x1885: 0x402bfd20, 0x1886: 0x402bfe20, 0x1887: 0x402bff20, + 0x1888: 0x402c0020, 0x1889: 0x402c0120, 0x188a: 0x402c0220, 0x188b: 0x402c0320, + 0x188c: 0x402c0420, 0x188d: 0x402c0520, 0x188e: 0x402c0620, 0x188f: 0x402c0720, + 0x1890: 0x402c0820, 0x1891: 0x402c0920, 0x1892: 0x402c0a20, 0x1893: 0x402c0b20, + 0x1894: 0x402c0c20, 0x1895: 0x402c0d20, 0x1896: 0x402c0e20, 0x1897: 0x402c0f20, + 0x1898: 0x402c1020, 0x1899: 0x402c1120, 0x189a: 0x402c1220, 0x189b: 0x402c1320, + 0x189c: 0x402c1420, 0x189d: 0x402c1520, 0x189e: 0x402c1620, 0x189f: 0x402c1720, + 0x18a0: 0x402c1820, 0x18a1: 0x402c1920, 0x18a2: 0x402c1a20, 0x18a3: 0x402c1b20, + 0x18a4: 0x402c1c20, 0x18a5: 0x402c1d20, 0x18a6: 0x402c1e20, 0x18a7: 0x402c1f20, + 0x18a8: 0x402c2020, 0x18a9: 0x402c2120, 0x18aa: 0x402c2220, 0x18ab: 0x402c2320, + 0x18ac: 0x402c2420, 0x18ad: 0x402c2520, 0x18ae: 0x402c2620, 0x18af: 0x402c2720, + 0x18b0: 0x402c2820, 0x18b1: 0x402c2920, 0x18b2: 0x402c2a20, 0x18b3: 0x402c2b20, + 0x18b4: 0x402c2c20, 0x18b5: 0x402c2d20, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x40251420, 0x18c1: 0x40251520, 0x18c2: 0x40251620, 0x18c3: 0x40251720, + 0x18c4: 0x40251820, 0x18c5: 0x40251920, 0x18c6: 0x40251a20, 0x18c7: 0x40251b20, + 0x18c8: 0x40251c20, 0x18c9: 0x40251d20, 0x18ca: 0x40251e20, 0x18cb: 0x40251f20, + 0x18cc: 0x40252020, 0x18cd: 0x40252120, 0x18ce: 0x40252220, 0x18cf: 0x40252320, + 0x18d0: 0x40252420, 0x18d1: 0x40252520, 0x18d2: 0x40252620, 0x18d3: 0x40252720, + 0x18d4: 0x40252820, 0x18d5: 0x40252920, 0x18d6: 0x40252a20, 0x18d7: 0x40252b20, + 0x18d8: 0x40252c20, 0x18d9: 0x40252d20, 0x18da: 0x40252e20, 0x18db: 0x40252f20, + 0x18dc: 0x40253020, + 0x18e0: 0x40253120, 0x18e1: 0x40253220, 0x18e2: 0x40253320, 0x18e3: 0x40253420, + 0x18e4: 0x40253520, 0x18e5: 0x40253620, 0x18e6: 0x40253720, 0x18e7: 0x40253820, + 0x18e8: 0x40253920, 0x18e9: 0x40253a20, 0x18ea: 0x40253b20, 0x18eb: 0x40253c20, + 0x18f0: 0x40253d20, 0x18f1: 0x40253e20, 0x18f2: 0x40253f20, 0x18f3: 0x40254020, + 0x18f4: 0x40254120, 0x18f5: 0x40254220, 0x18f6: 0x40254320, 0x18f7: 0x40254420, + 0x18f8: 0x40254520, 0x18f9: 0x80014502, 0x18fa: 0x80014602, 0x18fb: 0x80014702, + // Block 0x64, offset 0x1900 + 0x1900: 0x40031920, + 0x1904: 0x40015c20, 0x1905: 0x40016420, 0x1906: 0xe0000051, 0x1907: 0xe00000d2, + 0x1908: 0xe00001bc, 0x1909: 0xe0000282, 0x190a: 0xe000033f, 0x190b: 0xe00003f9, + 0x190c: 0xe00004b0, 0x190d: 0xe000054c, 0x190e: 0xe00005e8, 0x190f: 0xe0000681, + 0x1910: 0x4026f320, 0x1911: 0x4026f420, 0x1912: 0x4026f520, 0x1913: 0x4026f620, + 0x1914: 0x4026f720, 0x1915: 0x4026f820, 0x1916: 0x4026f920, 0x1917: 0x4026fa20, + 0x1918: 0x4026fb20, 0x1919: 0x4026fc20, 0x191a: 0x4026fd20, 0x191b: 0x4026fe20, + 0x191c: 0x4026ff20, 0x191d: 0x40270020, 0x191e: 0x40270120, 0x191f: 0x40270220, + 0x1920: 0x40270320, 0x1921: 0x40270420, 0x1922: 0x40270520, 0x1923: 0x40270620, + 0x1924: 0x40270720, 0x1925: 0x40270820, 0x1926: 0x40270920, 0x1927: 0x40270a20, + 0x1928: 0x40270b20, 0x1929: 0x40270c20, 0x192a: 0x40270d20, 0x192b: 0x40270e20, + 0x192c: 0x40270f20, 0x192d: 0x40271020, + 0x1930: 0x40271120, 0x1931: 0x40271220, 0x1932: 0x40271320, 0x1933: 0x40271420, + 0x1934: 0x40271520, + // Block 0x65, offset 0x1940 + 0x1940: 0x40271620, 0x1941: 0x40271720, 0x1942: 0x40271820, 0x1943: 0x40271920, + 0x1944: 0x40271a20, 0x1945: 0x40271b20, 0x1946: 0x40271c20, 0x1947: 0x40271d20, + 0x1948: 0x40271e20, 0x1949: 0x40271f20, 0x194a: 0x40272020, 0x194b: 0x40272120, + 0x194c: 0x40272220, 0x194d: 0x40272320, 0x194e: 0x40272420, 0x194f: 0x40272520, + 0x1950: 0x40272620, 0x1951: 0x40272720, 0x1952: 0x40272820, 0x1953: 0x40272920, + 0x1954: 0x40272a20, 0x1955: 0x40272b20, 0x1956: 0x40272c20, 0x1957: 0x40272d20, + 0x1958: 0x40272e20, 0x1959: 0x40272f20, 0x195a: 0x40273020, 0x195b: 0x40273120, + 0x195c: 0x40273220, 0x195d: 0x40273320, 0x195e: 0x40273420, 0x195f: 0x40273520, + 0x1960: 0x40273620, 0x1961: 0x40273720, 0x1962: 0x40273820, 0x1963: 0x40273920, + 0x1964: 0x40273a20, 0x1965: 0x40273b20, 0x1966: 0x40273c20, 0x1967: 0x40273d20, + 0x1968: 0x40273e20, 0x1969: 0x40273f20, 0x196a: 0x40274020, 0x196b: 0x40274120, + 0x1970: 0x40274220, 0x1971: 0x40274320, 0x1972: 0x40274420, 0x1973: 0x40274520, + 0x1974: 0x40274620, 0x1975: 0x40274720, 0x1976: 0x40274820, 0x1977: 0x40274920, + 0x1978: 0x40274a20, 0x1979: 0x40274b20, 0x197a: 0x40274c20, 0x197b: 0x40274d20, + 0x197c: 0x40274e20, 0x197d: 0x40274f20, 0x197e: 0x40275020, 0x197f: 0x40275120, + // Block 0x66, offset 0x1980 + 0x1980: 0x40275220, 0x1981: 0x40275320, 0x1982: 0x40275420, 0x1983: 0x40275520, + 0x1984: 0x40275620, 0x1985: 0x40275720, 0x1986: 0x40275820, 0x1987: 0x40275920, + 0x1988: 0x40275a20, 0x1989: 0x40275b20, + 0x1990: 0xe0000054, 0x1991: 0xe00000d5, 0x1992: 0xe00001bf, 0x1993: 0xe0000285, + 0x1994: 0xe0000342, 0x1995: 0xe00003fc, 0x1996: 0xe00004b3, 0x1997: 0xe000054f, + 0x1998: 0xe00005eb, 0x1999: 0xe0000684, 0x199a: 0xe00000d8, + 0x199e: 0xe0001059, 0x199f: 0xe000105c, + 0x19a0: 0x4003c320, 0x19a1: 0x4003c420, 0x19a2: 0x4003c520, 0x19a3: 0x4003c620, + 0x19a4: 0x4003c720, 0x19a5: 0x4003c820, 0x19a6: 0x4003c920, 0x19a7: 0x4003ca20, + 0x19a8: 0x4003cb20, 0x19a9: 0x4003cc20, 0x19aa: 0x4003cd20, 0x19ab: 0x4003ce20, + 0x19ac: 0x4003cf20, 0x19ad: 0x4003d020, 0x19ae: 0x4003d120, 0x19af: 0x4003d220, + 0x19b0: 0x4003d320, 0x19b1: 0x4003d420, 0x19b2: 0x4003d520, 0x19b3: 0x4003d620, + 0x19b4: 0x4003d720, 0x19b5: 0x4003d820, 0x19b6: 0x4003d920, 0x19b7: 0x4003da20, + 0x19b8: 0x4003db20, 0x19b9: 0x4003dc20, 0x19ba: 0x4003dd20, 0x19bb: 0x4003de20, + 0x19bc: 0x4003df20, 0x19bd: 0x4003e020, 0x19be: 0x4003e120, 0x19bf: 0x4003e220, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x40259520, 0x19c1: 0x40259620, 0x19c2: 0x40259720, 0x19c3: 0x40259820, + 0x19c4: 0x40259920, 0x19c5: 0x40259a20, 0x19c6: 0x40259b20, 0x19c7: 0x40259c20, + 0x19c8: 0x40259d20, 0x19c9: 0x40259e20, 0x19ca: 0x40259f20, 0x19cb: 0x4025a020, + 0x19cc: 0x4025a120, 0x19cd: 0x4025a220, 0x19ce: 0x4025a320, 0x19cf: 0x4025a420, + 0x19d0: 0x4025a520, 0x19d1: 0x4025a620, 0x19d2: 0x4025a720, 0x19d3: 0x4025a820, + 0x19d4: 0x4025a920, 0x19d5: 0x4025aa20, 0x19d6: 0x4025ab20, 0x19d7: 0x4025ac20, + 0x19d8: 0x4025ad20, 0x19d9: 0x4025ae20, 0x19da: 0x4025af20, 0x19db: 0x4025b020, + 0x19de: 0x4001a520, 0x19df: 0x4001a620, + 0x19e0: 0x40275c20, 0x19e1: 0x40275d20, 0x19e2: 0x40275e20, 0x19e3: 0x40275f20, + 0x19e4: 0x40276020, 0x19e5: 0x40276120, 0x19e6: 0x40276220, 0x19e7: 0x40276320, + 0x19e8: 0x40276420, 0x19e9: 0x40276520, 0x19ea: 0x40276620, 0x19eb: 0x40276720, + 0x19ec: 0x40276820, 0x19ed: 0x40276920, 0x19ee: 0x40276a20, 0x19ef: 0x40276b20, + 0x19f0: 0x40276c20, 0x19f1: 0x40276d20, 0x19f2: 0x40276e20, 0x19f3: 0x40276f20, + 0x19f4: 0x40277020, 0x19f5: 0x40277120, 0x19f6: 0x40277220, 0x19f7: 0x40277320, + 0x19f8: 0x40277420, 0x19f9: 0x40277520, 0x19fa: 0x40277620, 0x19fb: 0x40277720, + 0x19fc: 0x40277820, 0x19fd: 0x40277920, 0x19fe: 0x40277a20, 0x19ff: 0x40277b20, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x40277c20, 0x1a01: 0x40277d20, 0x1a02: 0x40277e20, 0x1a03: 0x40277f20, + 0x1a04: 0x40278020, 0x1a05: 0x40278120, 0x1a06: 0x40278220, 0x1a07: 0x40278320, + 0x1a08: 0x40278420, 0x1a09: 0x40278520, 0x1a0a: 0x40278620, 0x1a0b: 0x40278720, + 0x1a0c: 0x40278820, 0x1a0d: 0x40279120, 0x1a0e: 0x40279220, 0x1a0f: 0x40279320, + 0x1a10: 0x40279420, 0x1a11: 0x40279520, 0x1a12: 0x40279620, 0x1a13: 0x40278920, + 0x1a14: 0xe0001060, 0x1a15: 0x40278b20, 0x1a16: 0x40278c20, 0x1a17: 0x40278d20, + 0x1a18: 0x004ec404, 0x1a19: 0x004ec404, 0x1a1a: 0x004eee04, 0x1a1b: 0x004eee04, + 0x1a1c: 0x40278e20, 0x1a1d: 0x40278f20, 0x1a1e: 0x40279020, + 0x1a20: 0x4027a820, 0x1a21: 0x40279720, 0x1a22: 0x40279920, 0x1a23: 0x40279a20, + 0x1a24: 0x004f3404, 0x1a25: 0x40279b20, 0x1a26: 0x40279c20, 0x1a27: 0x40279d20, + 0x1a28: 0x40279e20, 0x1a29: 0x40279f20, 0x1a2a: 0x4027a020, 0x1a2b: 0x40278a20, + 0x1a2c: 0x40279820, 0x1a2d: 0x4027a720, 0x1a2e: 0x4027a120, 0x1a2f: 0x4027a220, + 0x1a30: 0x4027a420, 0x1a31: 0x4027a520, 0x1a32: 0x4027a620, 0x1a33: 0x4027a320, + 0x1a34: 0x80013c02, 0x1a35: 0x80013d02, 0x1a36: 0x80013e02, 0x1a37: 0x80013f02, + 0x1a38: 0x80014002, 0x1a39: 0x80014102, 0x1a3a: 0x80014202, 0x1a3b: 0x80014302, + 0x1a3c: 0x80014402, 0x1a3f: 0x80000000, + // Block 0x69, offset 0x1a40 + 0x1a40: 0xe0000057, 0x1a41: 0xe00000db, 0x1a42: 0xe00001c2, 0x1a43: 0xe0000288, + 0x1a44: 0xe0000345, 0x1a45: 0xe00003ff, 0x1a46: 0xe00004b6, 0x1a47: 0xe0000552, + 0x1a48: 0xe00005ee, 0x1a49: 0xe0000687, + 0x1a50: 0xe000005a, 0x1a51: 0xe00000de, 0x1a52: 0xe00001c5, 0x1a53: 0xe000028b, + 0x1a54: 0xe0000348, 0x1a55: 0xe0000402, 0x1a56: 0xe00004b9, 0x1a57: 0xe0000555, + 0x1a58: 0xe00005f1, 0x1a59: 0xe000068a, + 0x1a60: 0x4002ad20, 0x1a61: 0x4002ae20, 0x1a62: 0x4002af20, 0x1a63: 0x4002b020, + 0x1a64: 0x4002b120, 0x1a65: 0x4002b220, 0x1a66: 0x4002b320, 0x1a67: 0x40139720, + 0x1a68: 0x40018d20, 0x1a69: 0x40018e20, 0x1a6a: 0x40018f20, 0x1a6b: 0x40019020, + 0x1a6c: 0x4002b420, 0x1a6d: 0x4002b520, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x8000ff02, 0x1a81: 0x80010002, 0x1a82: 0x80010102, 0x1a83: 0x80010202, + 0x1a84: 0x80010302, 0x1a85: 0xc30907b1, 0x1a86: 0x4027ef20, 0x1a87: 0xc30b07b1, + 0x1a88: 0x4027f120, 0x1a89: 0xc30d07b1, 0x1a8a: 0x4027f320, 0x1a8b: 0xc30f07b1, + 0x1a8c: 0x4027f520, 0x1a8d: 0xc31107b1, 0x1a8e: 0x4027f720, 0x1a8f: 0x4027f820, + 0x1a90: 0x4027f920, 0x1a91: 0xc31307b1, 0x1a92: 0x4027fb20, 0x1a93: 0x4027fc20, + 0x1a94: 0x4027ff20, 0x1a95: 0x40280020, 0x1a96: 0x40280120, 0x1a97: 0x40280220, + 0x1a98: 0x40280320, 0x1a99: 0x40280420, 0x1a9a: 0x40280520, 0x1a9b: 0x40280620, + 0x1a9c: 0x40280720, 0x1a9d: 0x40280820, 0x1a9e: 0x40280920, 0x1a9f: 0x40280a20, + 0x1aa0: 0x40280b20, 0x1aa1: 0x40280c20, 0x1aa2: 0x40280d20, 0x1aa3: 0x40280f20, + 0x1aa4: 0x40281020, 0x1aa5: 0x40281120, 0x1aa6: 0x40281220, 0x1aa7: 0x40281320, + 0x1aa8: 0x40281520, 0x1aa9: 0x40281620, 0x1aaa: 0x40281720, 0x1aab: 0x40281820, + 0x1aac: 0x40281920, 0x1aad: 0x40281a20, 0x1aae: 0x40281b20, 0x1aaf: 0x40281c20, + 0x1ab0: 0x40281e20, 0x1ab1: 0x40281f20, 0x1ab2: 0x40282020, 0x1ab3: 0x40282320, + 0x1ab4: 0x8000fe02, 0x1ab5: 0x40282420, 0x1ab6: 0x40282520, 0x1ab7: 0x40282620, + 0x1ab8: 0x40282720, 0x1ab9: 0x40282820, 0x1aba: 0xc31507b1, 0x1abb: 0x40282a20, + 0x1abc: 0xc31707b1, 0x1abd: 0x40282c20, 0x1abe: 0xc31907b1, 0x1abf: 0xc31b07b1, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x40282f20, 0x1ac1: 0x40283020, 0x1ac2: 0xc31d07b1, 0x1ac3: 0x40283220, + 0x1ac4: 0x40283320, 0x1ac5: 0x4027fd20, 0x1ac6: 0x4027fe20, 0x1ac7: 0x40280e20, + 0x1ac8: 0x40281420, 0x1ac9: 0x40281d20, 0x1aca: 0x40282120, 0x1acb: 0x40282220, + 0x1ad0: 0xe000007e, 0x1ad1: 0xe0000102, 0x1ad2: 0xe00001e9, 0x1ad3: 0xe00002af, + 0x1ad4: 0xe000036c, 0x1ad5: 0xe0000426, 0x1ad6: 0xe00004dd, 0x1ad7: 0xe0000579, + 0x1ad8: 0xe0000615, 0x1ad9: 0xe00006ae, 0x1ada: 0x4001a720, 0x1adb: 0x4001a820, + 0x1adc: 0x40017420, 0x1add: 0x40015220, 0x1ade: 0x40019120, 0x1adf: 0x40019220, + 0x1ae0: 0x40011120, 0x1ae1: 0x4003e320, 0x1ae2: 0x4003e420, 0x1ae3: 0x4003e520, + 0x1ae4: 0x4003e620, 0x1ae5: 0x4003e720, 0x1ae6: 0x4003e820, 0x1ae7: 0x4003e920, + 0x1ae8: 0x4003ea20, 0x1ae9: 0x4003eb20, 0x1aea: 0x4003ec20, 0x1aeb: 0x80000000, + 0x1aec: 0x80000000, 0x1aed: 0x80000000, 0x1aee: 0x80000000, 0x1aef: 0x80000000, + 0x1af0: 0x80000000, 0x1af1: 0x80000000, 0x1af2: 0x80000000, 0x1af3: 0x80000000, + 0x1af4: 0x4003ed20, 0x1af5: 0x4003ee20, 0x1af6: 0x4003ef20, 0x1af7: 0x4003f020, + 0x1af8: 0x4003f120, 0x1af9: 0x4003f220, 0x1afa: 0x4003f320, 0x1afb: 0x4003f420, + 0x1afc: 0x4003f520, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x80010902, 0x1b01: 0x80010a02, 0x1b02: 0x80010b02, 0x1b03: 0x4022fd20, + 0x1b04: 0x4022fe20, 0x1b05: 0x4022ff20, 0x1b06: 0x40230020, 0x1b07: 0x40230120, + 0x1b08: 0x40230220, 0x1b09: 0x40230320, 0x1b0a: 0x40230420, 0x1b0b: 0x40230620, + 0x1b0c: 0x40230720, 0x1b0d: 0x40230820, 0x1b0e: 0x40230920, 0x1b0f: 0x40230a20, + 0x1b10: 0x40230b20, 0x1b11: 0x40230c20, 0x1b12: 0x40230d20, 0x1b13: 0x40230e20, + 0x1b14: 0x40230f20, 0x1b15: 0x40231020, 0x1b16: 0x40231120, 0x1b17: 0x40231220, + 0x1b18: 0x40231320, 0x1b19: 0x40231420, 0x1b1a: 0x40231520, 0x1b1b: 0x40231720, + 0x1b1c: 0x40231920, 0x1b1d: 0x40231b20, 0x1b1e: 0x40231c20, 0x1b1f: 0x40231d20, + 0x1b20: 0x40231f20, 0x1b21: 0x40231620, 0x1b22: 0x40231820, 0x1b23: 0x40231a20, + 0x1b24: 0x40232020, 0x1b25: 0x40232120, 0x1b26: 0x40232220, 0x1b27: 0x40232320, + 0x1b28: 0x40232420, 0x1b29: 0x40232520, 0x1b2a: 0x40232620, + 0x1b2e: 0x40230520, 0x1b2f: 0x40231e20, + 0x1b30: 0xe0000084, 0x1b31: 0xe0000108, 0x1b32: 0xe00001ef, 0x1b33: 0xe00002b5, + 0x1b34: 0xe0000372, 0x1b35: 0xe000042c, 0x1b36: 0xe00004e3, 0x1b37: 0xe000057f, + 0x1b38: 0xe000061b, 0x1b39: 0xe00006b4, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x4025b120, 0x1b41: 0x004b6204, 0x1b42: 0x4025b220, 0x1b43: 0x004b6404, + 0x1b44: 0x004b6404, 0x1b45: 0x4025b320, 0x1b46: 0x004b6604, 0x1b47: 0x4025b420, + 0x1b48: 0x004b6804, 0x1b49: 0x4025b520, 0x1b4a: 0x004b6a04, 0x1b4b: 0x4025b620, + 0x1b4c: 0x004b6c04, 0x1b4d: 0x004b6c04, 0x1b4e: 0x4025b720, 0x1b4f: 0x004b6e04, + 0x1b50: 0x4025b820, 0x1b51: 0x4025b920, 0x1b52: 0x4025ba20, 0x1b53: 0x004b7404, + 0x1b54: 0x4025bb20, 0x1b55: 0x004b7604, 0x1b56: 0x4025bc20, 0x1b57: 0x004b7804, + 0x1b58: 0x4025bd20, 0x1b59: 0x004b7a04, 0x1b5a: 0x004b7a04, 0x1b5b: 0x4025be20, + 0x1b5c: 0x004b7c04, 0x1b5d: 0x4025bf20, 0x1b5e: 0x4025c020, 0x1b5f: 0x004b8004, + 0x1b60: 0x4025c120, 0x1b61: 0x4025c220, 0x1b62: 0x4025c320, 0x1b63: 0x4025c420, + 0x1b64: 0x4025c520, 0x1b65: 0x4025c620, 0x1b66: 0x80005f02, 0x1b67: 0x4025c720, + 0x1b68: 0x004b8e04, 0x1b69: 0x4025c820, 0x1b6a: 0x4025c920, 0x1b6b: 0x004b9204, + 0x1b6c: 0x4025ca20, 0x1b6d: 0x004b9404, 0x1b6e: 0x4025cb20, 0x1b6f: 0x004b9604, + 0x1b70: 0x4025cc20, 0x1b71: 0x4025cd20, 0x1b72: 0x4025ce20, 0x1b73: 0x4025cf20, + 0x1b7c: 0x4002ba20, 0x1b7d: 0x4002bb20, 0x1b7e: 0x4002bc20, 0x1b7f: 0x4002bd20, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x4024a620, 0x1b81: 0x4024a720, 0x1b82: 0x4024a820, 0x1b83: 0x4024a920, + 0x1b84: 0x4024aa20, 0x1b85: 0x4024ab20, 0x1b86: 0x4024ac20, 0x1b87: 0x4024ad20, + 0x1b88: 0x4024ae20, 0x1b89: 0x4024af20, 0x1b8a: 0x4024b320, 0x1b8b: 0x4024b420, + 0x1b8c: 0x4024b520, 0x1b8d: 0x4024b620, 0x1b8e: 0x4024b720, 0x1b8f: 0x4024b820, + 0x1b90: 0x4024b920, 0x1b91: 0x4024ba20, 0x1b92: 0x4024bb20, 0x1b93: 0x4024bc20, + 0x1b94: 0x4024bd20, 0x1b95: 0x4024be20, 0x1b96: 0x4024bf20, 0x1b97: 0x4024c020, + 0x1b98: 0x4024c120, 0x1b99: 0x4024c220, 0x1b9a: 0x4024c320, 0x1b9b: 0x4024c520, + 0x1b9c: 0x4024c720, 0x1b9d: 0x4024c820, 0x1b9e: 0x4024c920, 0x1b9f: 0x4024ca20, + 0x1ba0: 0x4024cb20, 0x1ba1: 0x4024cc20, 0x1ba2: 0x4024cd20, 0x1ba3: 0x4024ce20, + 0x1ba4: 0x4024c420, 0x1ba5: 0x4024c620, 0x1ba6: 0x4024d020, 0x1ba7: 0x4024d120, + 0x1ba8: 0x4024d220, 0x1ba9: 0x4024d320, 0x1baa: 0x4024d420, 0x1bab: 0x4024d520, + 0x1bac: 0x4024d620, 0x1bad: 0x4024d720, 0x1bae: 0x4024d820, 0x1baf: 0x4024d920, + 0x1bb0: 0x4024da20, 0x1bb1: 0x4024db20, 0x1bb2: 0x4024dc20, 0x1bb3: 0x4024dd20, + 0x1bb4: 0x4024de20, 0x1bb5: 0x4024df20, 0x1bb6: 0x4024cf20, 0x1bb7: 0x80012f02, + 0x1bbb: 0x40018220, + 0x1bbc: 0x40018320, 0x1bbd: 0x4002a320, 0x1bbe: 0x4002a420, 0x1bbf: 0x4002a520, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0xe0000069, 0x1bc1: 0xe00000ed, 0x1bc2: 0xe00001d4, 0x1bc3: 0xe000029a, + 0x1bc4: 0xe0000357, 0x1bc5: 0xe0000411, 0x1bc6: 0xe00004c8, 0x1bc7: 0xe0000564, + 0x1bc8: 0xe0000600, 0x1bc9: 0xe0000699, + 0x1bcd: 0x4024b020, 0x1bce: 0x4024b120, 0x1bcf: 0x4024b220, + 0x1bd0: 0xe000008a, 0x1bd1: 0xe000010e, 0x1bd2: 0xe00001f5, 0x1bd3: 0xe00002bb, + 0x1bd4: 0xe0000378, 0x1bd5: 0xe0000432, 0x1bd6: 0xe00004e9, 0x1bd7: 0xe0000585, + 0x1bd8: 0xe0000621, 0x1bd9: 0xe00006ba, 0x1bda: 0x4028f220, 0x1bdb: 0x4028f320, + 0x1bdc: 0x4028f420, 0x1bdd: 0x4028f520, 0x1bde: 0x4028f620, 0x1bdf: 0x4028f720, + 0x1be0: 0x4028f820, 0x1be1: 0x4028f920, 0x1be2: 0x4028fa20, 0x1be3: 0x4028fb20, + 0x1be4: 0x4028fc20, 0x1be5: 0x4028fd20, 0x1be6: 0x4028fe20, 0x1be7: 0x4028ff20, + 0x1be8: 0x40290020, 0x1be9: 0x40290120, 0x1bea: 0x40290220, 0x1beb: 0x40290320, + 0x1bec: 0x40290420, 0x1bed: 0x40290520, 0x1bee: 0x40290620, 0x1bef: 0x40290720, + 0x1bf0: 0x40290820, 0x1bf1: 0x40290920, 0x1bf2: 0x40290a20, 0x1bf3: 0x40290b20, + 0x1bf4: 0x40290c20, 0x1bf5: 0x40290d20, 0x1bf6: 0x40290e20, 0x1bf7: 0x40290f20, + 0x1bf8: 0x40291020, 0x1bf9: 0x40291120, 0x1bfa: 0x40291220, 0x1bfb: 0x40291320, + 0x1bfc: 0x40291420, 0x1bfd: 0x40291520, 0x1bfe: 0x40019f20, 0x1bff: 0x4001a020, + // Block 0x70, offset 0x1c00 + 0x1c10: 0x80000000, 0x1c11: 0x80000000, 0x1c12: 0x80000000, 0x1c13: 0x80000000, + 0x1c14: 0x80000000, 0x1c15: 0x80000000, 0x1c16: 0x80000000, 0x1c17: 0x80000000, + 0x1c18: 0x80000000, 0x1c19: 0x80000000, 0x1c1a: 0x80000000, 0x1c1b: 0x80000000, + 0x1c1c: 0x80000000, 0x1c1d: 0x80000000, 0x1c1e: 0x80000000, 0x1c1f: 0x80000000, + 0x1c20: 0x80000000, 0x1c21: 0x80000000, 0x1c22: 0x80000000, 0x1c23: 0x80000000, + 0x1c24: 0x80000000, 0x1c25: 0x80000000, 0x1c26: 0x80000000, 0x1c27: 0x80000000, + 0x1c28: 0x80000000, 0x1c29: 0x401fbf20, 0x1c2a: 0x003f7e04, 0x1c2b: 0x003f7e04, + 0x1c2c: 0x003f7e04, 0x1c2d: 0x8000df02, 0x1c2e: 0x003f7e04, 0x1c2f: 0x003f7e04, + 0x1c30: 0x003f7e04, 0x1c31: 0x003f7e04, 0x1c32: 0x8000e002, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x4015a720, 0x1c41: 0x4015aa20, 0x1c42: 0x4015ab20, 0x1c43: 0x4015c620, + 0x1c44: 0x4015d520, 0x1c45: 0x4015e820, 0x1c46: 0x4015e920, 0x1c47: 0x40160320, + 0x1c48: 0x40162620, 0x1c49: 0x40168d20, 0x1c4a: 0x4016a120, 0x1c4b: 0x4016b620, + 0x1c4c: 0x4016cd20, 0x1c4d: 0x4016f820, 0x1c4e: 0x40170b20, 0x1c4f: 0x40172820, + 0x1c50: 0x40173420, 0x1c51: 0x40172920, 0x1c52: 0x40173520, 0x1c53: 0x40172f20, + 0x1c54: 0x40172e20, 0x1c55: 0x40174820, 0x1c56: 0x40173820, 0x1c57: 0x40173920, + 0x1c58: 0x40174d20, 0x1c59: 0x40177920, 0x1c5a: 0x40178320, 0x1c5b: 0x4017cd20, + 0x1c5c: 0x4017ed20, 0x1c5d: 0x4017ee20, 0x1c5e: 0x4017ef20, 0x1c5f: 0x40180820, + 0x1c60: 0x40181620, 0x1c61: 0x40182820, 0x1c62: 0x40184820, 0x1c63: 0x40186520, + 0x1c64: 0x4018ad20, 0x1c65: 0x4018ae20, 0x1c66: 0x4018df20, 0x1c67: 0x4018ed20, + 0x1c68: 0x4018f320, 0x1c69: 0x4018f820, 0x1c6a: 0x40190320, 0x1c6b: 0x4019f820, + 0x1c6c: 0xf000001d, 0x1c6d: 0xf0001414, 0x1c6e: 0xf000001d, 0x1c6f: 0x4015c520, + 0x1c70: 0xf000001d, 0x1c71: 0xf000001d, 0x1c72: 0xf000001d, 0x1c73: 0xf000001d, + 0x1c74: 0xf000001d, 0x1c75: 0xf000001d, 0x1c76: 0xf000001d, 0x1c77: 0xf000001d, + 0x1c78: 0xf000001d, 0x1c79: 0xf000001d, 0x1c7a: 0xf000001d, 0x1c7b: 0x40170a20, + 0x1c7c: 0xf000001d, 0x1c7d: 0xf000001d, 0x1c7e: 0xf000001d, 0x1c7f: 0xf000001d, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xf000001d, 0x1c81: 0xf000001d, 0x1c82: 0xf000001d, 0x1c83: 0xf0000014, + 0x1c84: 0xf0000014, 0x1c85: 0xf0000014, 0x1c86: 0xf0000014, 0x1c87: 0xf0000014, + 0x1c88: 0xf0000014, 0x1c89: 0xf0000014, 0x1c8a: 0xf0000014, 0x1c8b: 0xf0000014, + 0x1c8c: 0x002c4c14, 0x1c8d: 0xf0000014, 0x1c8e: 0x002d1a14, 0x1c8f: 0xf0000014, + 0x1c90: 0xf0000014, 0x1c91: 0xf0000014, 0x1c92: 0xf0000014, 0x1c93: 0xf0000014, + 0x1c94: 0xf0000014, 0x1c95: 0xf0000014, 0x1c96: 0xf0000014, 0x1c97: 0xf0000014, + 0x1c98: 0xf0000014, 0x1c99: 0xf0000014, 0x1c9a: 0xf0000014, 0x1c9b: 0xf0000014, + 0x1c9c: 0xf0000014, 0x1c9d: 0xf0000014, 0x1c9e: 0xf0000014, 0x1c9f: 0xf0000014, + 0x1ca0: 0xf0000014, 0x1ca1: 0xf0000014, 0x1ca2: 0xf0000015, 0x1ca3: 0xf0000015, + 0x1ca4: 0xf0000015, 0x1ca5: 0xf0000015, 0x1ca6: 0xf0000015, 0x1ca7: 0xf0000015, + 0x1ca8: 0xf0000015, 0x1ca9: 0xf0000015, 0x1caa: 0xf0000015, 0x1cab: 0x4017f020, + 0x1cac: 0x4015c720, 0x1cad: 0x4015ea20, 0x1cae: 0x40163c20, 0x1caf: 0x4016f920, + 0x1cb0: 0x40170c20, 0x1cb1: 0x40175020, 0x1cb2: 0x40177e20, 0x1cb3: 0x40179a20, + 0x1cb4: 0x4017ab20, 0x1cb5: 0x4017d320, 0x1cb6: 0x40184d20, 0x1cb7: 0x40165d20, + 0x1cb8: 0xf0000014, 0x1cb9: 0xe000076b, 0x1cba: 0xe0000805, 0x1cbb: 0x40169220, + 0x1cbc: 0x40169820, 0x1cbd: 0x40174e20, 0x1cbe: 0x4017f520, 0x1cbf: 0x40181120, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x4015c820, 0x1cc1: 0x4015eb20, 0x1cc2: 0x40163d20, 0x1cc3: 0x40165420, + 0x1cc4: 0x4016b720, 0x1cc5: 0x4016dc20, 0x1cc6: 0x4016fa20, 0x1cc7: 0x40171620, + 0x1cc8: 0x40175120, 0x1cc9: 0x40178820, 0x1cca: 0x4017ac20, 0x1ccb: 0x4017bb20, + 0x1ccc: 0x40181820, 0x1ccd: 0x40183220, 0x1cce: 0x40184e20, 0x1ccf: 0x4015a920, + 0x1cd0: 0x4015b420, 0x1cd1: 0x4015f420, 0x1cd2: 0x40160820, 0x1cd3: 0x40161820, + 0x1cd4: 0x40162520, 0x1cd5: 0x40161320, 0x1cd6: 0x40169320, 0x1cd7: 0x40173620, + 0x1cd8: 0x4017c420, 0x1cd9: 0x4017f620, 0x1cda: 0x40186a20, 0x1cdb: 0xf0000014, + 0x1cdc: 0xf0000014, 0x1cdd: 0xf0000014, 0x1cde: 0xf0001414, 0x1cdf: 0xf0000014, + 0x1ce0: 0xf0000014, 0x1ce1: 0xf0000014, 0x1ce2: 0xf0000014, 0x1ce3: 0xf0000014, + 0x1ce4: 0xf0000014, 0x1ce5: 0xf0000014, 0x1ce6: 0xf0000014, 0x1ce7: 0xf0000014, + 0x1ce8: 0xf0000014, 0x1ce9: 0xf0000014, 0x1cea: 0xf0000014, 0x1ceb: 0xf0000014, + 0x1cec: 0xf0000014, 0x1ced: 0xf0000014, 0x1cee: 0xf0000014, 0x1cef: 0xf0000014, + 0x1cf0: 0xf0000014, 0x1cf1: 0xf0000014, 0x1cf2: 0xf0000014, 0x1cf3: 0xf0000014, + 0x1cf4: 0xf0000014, 0x1cf5: 0xf0000014, 0x1cf6: 0xf0000014, 0x1cf7: 0xf0000014, + 0x1cf8: 0xf0000014, 0x1cf9: 0xf0000014, 0x1cfa: 0xf0000014, 0x1cfb: 0xf0000014, + 0x1cfc: 0xf0000014, 0x1cfd: 0xf0000014, 0x1cfe: 0xf0000014, 0x1cff: 0xf0000014, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x80005f02, 0x1d01: 0x80005f02, 0x1d02: 0x80006002, 0x1d03: 0x80005f02, + 0x1d04: 0x80005f02, 0x1d05: 0x80005f02, 0x1d06: 0x80005f02, 0x1d07: 0x80005f02, + 0x1d08: 0x80005f02, 0x1d09: 0x80005f02, 0x1d0a: 0x002ee004, 0x1d0b: 0x80005f02, + 0x1d0c: 0x80005f02, 0x1d0d: 0x80005f02, 0x1d0e: 0x80005f02, 0x1d0f: 0x80006002, + 0x1d10: 0x80006002, 0x1d11: 0x80005f02, 0x1d12: 0x00310804, 0x1d13: 0xe00006ea, + 0x1d14: 0xe00006fa, 0x1d15: 0xe0000702, 0x1d16: 0xe0000711, 0x1d17: 0xe0000728, + 0x1d18: 0xe0000742, 0x1d19: 0xe000073c, 0x1d1a: 0x002c8804, 0x1d1b: 0x002c9804, + 0x1d1c: 0x002d6404, 0x1d1d: 0x002d8804, 0x1d1e: 0x002d9004, 0x1d1f: 0x002df004, + 0x1d20: 0x002e0404, 0x1d21: 0x002e0c04, 0x1d22: 0x002ee804, 0x1d23: 0x002ef004, + 0x1d24: 0x002f4c04, 0x1d25: 0xe00007e0, 0x1d26: 0x00308804, + 0x1d3c: 0x80006002, 0x1d3d: 0x80006002, 0x1d3e: 0x80005f02, 0x1d3f: 0x80006002, + // Block 0x75, offset 0x1d40 + 0x1d5a: 0xf0000404, + 0x1d5c: 0x4017b520, 0x1d5d: 0x4017b620, 0x1d5e: 0xe00007f4, 0x1d5f: 0x4015fe20, + // Block 0x76, offset 0x1d80 + 0x1dba: 0xe0000798, 0x1dbb: 0xe0000795, + 0x1dbc: 0x00303e08, 0x1dbd: 0x40181f20, 0x1dbe: 0x00308608, 0x1dbf: 0x40184320, + // Block 0x77, offset 0x1dc0 + 0x1dfd: 0x4002f820, 0x1dff: 0x4002f820, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x4002fc20, + 0x1e3e: 0x4002f920, + // Block 0x79, offset 0x1e40 + 0x1e42: 0xf0000004, 0x1e43: 0xf0000004, + 0x1e44: 0xf0000004, 0x1e45: 0xf0000004, 0x1e46: 0xf0000004, 0x1e47: 0xf000001b, + 0x1e48: 0xf0000004, 0x1e49: 0xf0000004, 0x1e4a: 0xf0000004, 0x1e4b: 0x80000000, + 0x1e4c: 0x80000000, 0x1e4d: 0x80000000, 0x1e4e: 0x80000000, 0x1e4f: 0x80000000, + 0x1e50: 0x40011420, 0x1e51: 0xf000001b, 0x1e52: 0x40011520, 0x1e53: 0x40011620, + 0x1e54: 0x40011720, 0x1e55: 0x40011820, 0x1e56: 0x4002d220, 0x1e57: 0x40010d20, + 0x1e58: 0x4001d920, 0x1e59: 0x4001da20, 0x1e5a: 0x4001db20, 0x1e5b: 0x4001dc20, + 0x1e5c: 0x4001e020, 0x1e5d: 0x4001e120, 0x1e5e: 0x4001e220, 0x1e5f: 0x4001e320, + 0x1e60: 0x40024d20, 0x1e61: 0x40024e20, 0x1e62: 0x40024f20, 0x1e63: 0x40025020, + 0x1e64: 0xf0000004, 0x1e65: 0xf0000404, 0x1e66: 0xf0000404, 0x1e67: 0x40025120, + 0x1e68: 0x40010720, 0x1e69: 0x40010820, 0x1e6a: 0x80000000, 0x1e6b: 0x80000000, + 0x1e6c: 0x80000000, 0x1e6d: 0x80000000, 0x1e6e: 0x80000000, 0x1e6f: 0xf000001b, + 0x1e70: 0x40024920, 0x1e71: 0x40024b20, 0x1e72: 0x40025520, 0x1e73: 0xf0000404, + 0x1e74: 0xf0000404, 0x1e75: 0x40025620, 0x1e76: 0xf0000404, 0x1e77: 0xf0000404, + 0x1e78: 0x40025920, 0x1e79: 0x4001dd20, 0x1e7a: 0x4001de20, 0x1e7b: 0x40025a20, + 0x1e7c: 0xf0000404, 0x1e7d: 0x40016920, 0x1e7e: 0x40010b20, 0x1e7f: 0x40025b20, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x40025d20, 0x1e81: 0x40025f20, 0x1e82: 0x40026020, 0x1e83: 0x40025220, + 0x1e84: 0x40031620, 0x1e85: 0x4001f520, 0x1e86: 0x4001f620, 0x1e87: 0xf0000404, + 0x1e88: 0xf0000404, 0x1e89: 0xf0000404, 0x1e8a: 0x40024520, 0x1e8b: 0x40023b20, + 0x1e8c: 0x40025320, 0x1e8d: 0x40025420, 0x1e8e: 0x40023e20, 0x1e8f: 0x40013020, + 0x1e90: 0x40025e20, 0x1e91: 0x40023f20, 0x1e92: 0x40031820, 0x1e93: 0x40011920, + 0x1e94: 0x40025c20, 0x1e95: 0x4001be20, 0x1e96: 0x4001bf20, 0x1e97: 0xf0000404, + 0x1e98: 0x4001c020, 0x1e99: 0x4001c120, 0x1e9a: 0x4001c220, 0x1e9b: 0x4001c320, + 0x1e9c: 0x4001c420, 0x1e9d: 0x4001c520, 0x1e9e: 0x4001c620, 0x1e9f: 0xf0000004, + 0x1ea0: 0x80000000, 0x1ea1: 0x80000000, 0x1ea2: 0x80000000, 0x1ea3: 0x80000000, + 0x1ea4: 0x80000000, + 0x1eaa: 0x80000000, 0x1eab: 0x80000000, + 0x1eac: 0x80000000, 0x1ead: 0x80000000, 0x1eae: 0x80000000, 0x1eaf: 0x80000000, + 0x1eb0: 0xf0000014, 0x1eb1: 0xf0000014, + 0x1eb4: 0xf0000014, 0x1eb5: 0xf0000014, 0x1eb6: 0xf0000014, 0x1eb7: 0xf0000014, + 0x1eb8: 0xf0000014, 0x1eb9: 0xf0000014, 0x1eba: 0xf0000014, 0x1ebb: 0xf0000014, + 0x1ebc: 0xf0000014, 0x1ebd: 0xf0000014, 0x1ebe: 0xf0000014, 0x1ebf: 0xf0000014, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xf0000015, 0x1ec1: 0xf0000015, 0x1ec2: 0xf0000015, 0x1ec3: 0xf0000015, + 0x1ec4: 0xf0000015, 0x1ec5: 0xf0000015, 0x1ec6: 0xf0000015, 0x1ec7: 0xf0000015, + 0x1ec8: 0xf0000015, 0x1ec9: 0xf0000015, 0x1eca: 0xf0000015, 0x1ecb: 0xf0000015, + 0x1ecc: 0xf0000015, 0x1ecd: 0xf0000015, 0x1ece: 0xf0000015, + 0x1ed0: 0xf0000015, 0x1ed1: 0xf0000015, 0x1ed2: 0xf0000015, 0x1ed3: 0xf0000015, + 0x1ed4: 0xf0000015, 0x1ed5: 0xf0000015, 0x1ed6: 0xf0000015, 0x1ed7: 0xf0000015, + 0x1ed8: 0xf0000015, 0x1ed9: 0xf0000015, 0x1eda: 0xf0000015, 0x1edb: 0xf0000015, + 0x1edc: 0xf0000015, + 0x1ee0: 0x4013b120, 0x1ee1: 0x4013b220, 0x1ee2: 0x4013b320, 0x1ee3: 0x4013b420, + 0x1ee4: 0x4013b520, 0x1ee5: 0x4013b620, 0x1ee6: 0x4013b720, 0x1ee7: 0x4013b820, + 0x1ee8: 0x4013ca20, 0x1ee9: 0x4013b920, 0x1eea: 0x4013ba20, 0x1eeb: 0x4013bb20, + 0x1eec: 0x4013bc20, 0x1eed: 0x4013bd20, 0x1eee: 0x4013be20, 0x1eef: 0x4013bf20, + 0x1ef0: 0x4013c020, 0x1ef1: 0x4013c120, 0x1ef2: 0x4013c220, 0x1ef3: 0x4013c320, + 0x1ef4: 0x4013c420, 0x1ef5: 0x4013c520, 0x1ef6: 0x4013c620, 0x1ef7: 0x4013c720, + 0x1ef8: 0x4013c820, 0x1ef9: 0x4013c920, + // Block 0x7c, offset 0x1f00 + 0x1f10: 0x80015002, 0x1f11: 0x80015102, 0x1f12: 0x80015202, 0x1f13: 0x80015202, + 0x1f14: 0x80015302, 0x1f15: 0x80015402, 0x1f16: 0x80015502, 0x1f17: 0x80015602, + 0x1f18: 0x80006102, 0x1f19: 0x80006102, 0x1f1a: 0x80006102, 0x1f1b: 0x80015702, + 0x1f1c: 0x80015802, 0x1f1d: 0x80006202, 0x1f1e: 0x80006202, 0x1f1f: 0x80006202, + 0x1f20: 0x80006202, 0x1f21: 0x80015902, 0x1f22: 0x80006202, 0x1f23: 0x80006202, + 0x1f24: 0x80006202, 0x1f25: 0x80006102, 0x1f26: 0x80015a02, 0x1f27: 0x80015b02, + 0x1f28: 0x80015c02, 0x1f29: 0x80015d02, 0x1f2a: 0x80006102, 0x1f2b: 0x80006102, + 0x1f2c: 0x80006002, 0x1f2d: 0x80006002, 0x1f2e: 0x80006002, 0x1f2f: 0x80006002, + 0x1f30: 0x80005f02, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf0000404, 0x1f41: 0xf0000404, 0x1f42: 0xf000000b, 0x1f43: 0xf0000a04, + 0x1f44: 0x4003f620, 0x1f45: 0xf0000404, 0x1f46: 0xf0000404, 0x1f47: 0xf000000a, + 0x1f48: 0x4003f720, 0x1f49: 0xf0000a04, 0x1f4a: 0xf0000005, 0x1f4b: 0xf000000b, + 0x1f4c: 0xf000000b, 0x1f4d: 0xf000000b, 0x1f4e: 0xf0000005, 0x1f4f: 0xf0000202, + 0x1f50: 0xf000000b, 0x1f51: 0xf000000b, 0x1f52: 0xf000000b, 0x1f53: 0xf0000005, + 0x1f54: 0x4003f820, 0x1f55: 0xf000000b, 0x1f56: 0xf000040a, 0x1f57: 0x4003f920, + 0x1f58: 0x4003fa20, 0x1f59: 0xf000000b, 0x1f5a: 0xf000000b, 0x1f5b: 0xf000000b, + 0x1f5c: 0xf000000b, 0x1f5d: 0xf000000b, 0x1f5e: 0x4003fb20, 0x1f5f: 0x4003fc20, + 0x1f60: 0xf0001414, 0x1f61: 0xf0000a0a, 0x1f62: 0xf0001414, 0x1f63: 0x4003fd20, + 0x1f64: 0xf000000b, 0x1f65: 0x4003fe20, 0x1f67: 0x4003ff20, + 0x1f68: 0xf000000b, 0x1f69: 0x40040020, + 0x1f6c: 0xf000000b, 0x1f6d: 0xf000000b, 0x1f6e: 0x40040120, 0x1f6f: 0xf0000005, + 0x1f70: 0xf000000b, 0x1f71: 0xf000000b, 0x1f72: 0x002c8408, 0x1f73: 0xf000000b, + 0x1f74: 0xf0000005, 0x1f75: 0xf0000004, 0x1f76: 0xf0000004, 0x1f77: 0xf0000004, + 0x1f78: 0xf0000004, 0x1f79: 0xf0000005, 0x1f7a: 0x40040220, 0x1f7b: 0xf0000a0a, + 0x1f7c: 0xf0000005, 0x1f7d: 0xf0000005, 0x1f7e: 0xf000000b, 0x1f7f: 0xf000000b, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xf0000005, 0x1f81: 0x40040320, 0x1f82: 0x40040420, 0x1f83: 0x40040520, + 0x1f84: 0x40040620, 0x1f85: 0xf000000b, 0x1f86: 0xf0000005, 0x1f87: 0xf0000005, + 0x1f88: 0xf0000005, 0x1f89: 0xf0000005, 0x1f8a: 0x40040720, 0x1f8b: 0x40031720, + 0x1f8c: 0x40040820, 0x1f8d: 0x40040920, 0x1f8e: 0x40164220, 0x1f8f: 0x40040a20, + 0x1f90: 0xf0001e1e, 0x1f91: 0xf0001e1e, 0x1f92: 0xf0001e1e, 0x1f93: 0xf0001e1e, + 0x1f94: 0xf0001e1e, 0x1f95: 0xf0001e1e, 0x1f96: 0xf0001e1e, 0x1f97: 0xf0001e1e, + 0x1f98: 0xf0001e1e, 0x1f99: 0xf0001e1e, 0x1f9a: 0xf0001e1e, 0x1f9b: 0xf0001e1e, + 0x1f9c: 0xf0001e1e, 0x1f9d: 0xf0001e1e, 0x1f9e: 0xf0001e1e, 0x1f9f: 0xf0001e1e, + 0x1fa0: 0xf000000a, 0x1fa1: 0xf0000a0a, 0x1fa2: 0xf0000a0a, 0x1fa3: 0xf0000a0a, + 0x1fa4: 0xf000000a, 0x1fa5: 0xf0000a0a, 0x1fa6: 0xf0000a0a, 0x1fa7: 0xf0000a0a, + 0x1fa8: 0xf0000a0a, 0x1fa9: 0xf000000a, 0x1faa: 0xf0000a0a, 0x1fab: 0xf0000a0a, + 0x1fac: 0xf000000a, 0x1fad: 0xf000000a, 0x1fae: 0xf000000a, 0x1faf: 0xf000000a, + 0x1fb0: 0xf0000004, 0x1fb1: 0xf0000404, 0x1fb2: 0xf0000404, 0x1fb3: 0xf0000404, + 0x1fb4: 0xf0000004, 0x1fb5: 0xf0000404, 0x1fb6: 0xf0000404, 0x1fb7: 0xf0000404, + 0x1fb8: 0xf0000404, 0x1fb9: 0xf0000004, 0x1fba: 0xf0000404, 0x1fbb: 0xf0000404, + 0x1fbc: 0xf0000004, 0x1fbd: 0xf0000004, 0x1fbe: 0xf0000004, 0x1fbf: 0xf0000004, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x4013f220, 0x1fc1: 0x4013f320, 0x1fc2: 0x4013f420, 0x1fc3: 0x002bc408, + 0x1fc4: 0x4015e220, 0x1fc5: 0xe00004f5, 0x1fc6: 0x4013f520, 0x1fc7: 0x4013f620, + 0x1fc8: 0x4013f720, 0x1fc9: 0xf0001e1e, + 0x1fd0: 0x40040b20, 0x1fd1: 0x40040d20, 0x1fd2: 0x40040c20, 0x1fd3: 0x40040e20, + 0x1fd4: 0x40040f20, 0x1fd5: 0x40041020, 0x1fd6: 0x40041120, 0x1fd7: 0x40041220, + 0x1fd8: 0x40041320, 0x1fd9: 0x40041420, + 0x1fdc: 0x40041520, 0x1fdd: 0x40041620, 0x1fde: 0x40041720, 0x1fdf: 0x40041820, + 0x1fe0: 0x40041920, 0x1fe1: 0x40041a20, 0x1fe2: 0x40041b20, 0x1fe3: 0x40041c20, + 0x1fe4: 0x40041d20, 0x1fe5: 0x40041e20, 0x1fe6: 0x40041f20, 0x1fe7: 0x40042020, + 0x1fe8: 0x40042120, 0x1fe9: 0x40042220, 0x1fea: 0x40042320, 0x1feb: 0x40042420, + 0x1fec: 0x40042520, 0x1fed: 0x40042620, 0x1fef: 0x40042720, + 0x1ff0: 0x40042820, 0x1ff1: 0x40042920, 0x1ff2: 0x40042a20, 0x1ff3: 0x40042b20, + 0x1ff4: 0x40042c20, 0x1ff5: 0x40042d20, 0x1ff6: 0x40042e20, 0x1ff7: 0x40042f20, + 0x1ff8: 0x40043020, 0x1ff9: 0x40043120, 0x1ffa: 0x40043220, 0x1ffb: 0x40043320, + 0x1ffc: 0x40043420, 0x1ffd: 0x40043520, 0x1ffe: 0x40043620, 0x1fff: 0x40043720, + // Block 0x80, offset 0x2000 + 0x2000: 0x40043820, 0x2001: 0x40043920, 0x2002: 0x40043a20, 0x2003: 0x40043b20, + 0x2004: 0x40043c20, 0x2005: 0x40043d20, 0x2006: 0x40043e20, 0x2007: 0x40043f20, + 0x2008: 0x40044020, 0x2009: 0x40044120, 0x200a: 0x40044220, 0x200b: 0x40044320, + 0x200c: 0x40044420, + 0x2010: 0x40044520, 0x2011: 0x40044620, 0x2012: 0x40044720, 0x2013: 0x40044820, + 0x2014: 0x40044920, 0x2015: 0x40044a20, 0x2016: 0x40044b20, 0x2017: 0x40044c20, + 0x2018: 0x40044d20, 0x2019: 0x40044e20, 0x201a: 0x40044f20, 0x201b: 0x40045020, + 0x201c: 0x40045120, 0x201d: 0x40045220, 0x201e: 0x40045320, 0x201f: 0x40045420, + 0x2020: 0x40045520, 0x2021: 0x40045620, 0x2022: 0x40045720, 0x2023: 0x40045820, + 0x2024: 0x40045920, 0x2025: 0x40045a20, 0x2026: 0x40045b20, 0x2027: 0x40045c20, + 0x2028: 0x40045d20, 0x2029: 0x40045e20, 0x202a: 0x40045f20, 0x202b: 0x40046020, + 0x202c: 0x40046120, 0x202d: 0x40046220, 0x202e: 0x40046320, 0x202f: 0x40046420, + 0x2030: 0x40046520, 0x2031: 0x40046620, 0x2032: 0x40046720, 0x2033: 0x40046820, + 0x2034: 0x40046920, 0x2035: 0x40046a20, 0x2036: 0x40046b20, 0x2037: 0x40046c20, + 0x2038: 0x40046d20, 0x2039: 0x40046e20, 0x203a: 0x40046f20, 0x203b: 0x40047020, + 0x203c: 0x40047120, 0x203d: 0x40047220, 0x203e: 0x40047320, 0x203f: 0x40047420, + // Block 0x81, offset 0x2040 + 0x2040: 0x40047520, 0x2041: 0x40047620, 0x2042: 0x40047720, 0x2043: 0x40047820, + 0x2045: 0x40047920, 0x2046: 0x40047a20, 0x2047: 0x40047b20, + 0x2048: 0x40047c20, 0x204a: 0x40047d20, 0x204b: 0x40047e20, + 0x204d: 0x40047f20, 0x204e: 0x40048120, 0x204f: 0x40048220, + 0x2050: 0x40048320, 0x2051: 0x40048420, 0x2052: 0x40049020, 0x2053: 0x40049120, + 0x2054: 0x40049220, 0x2055: 0x40049320, 0x2056: 0x40049420, 0x2057: 0x40049520, + 0x2058: 0x40049620, 0x2059: 0x40049720, 0x205a: 0x40049820, 0x205b: 0x40049920, + 0x205c: 0x40049b20, 0x205d: 0x40049d20, 0x205e: 0x40049e20, 0x205f: 0x40049f20, + 0x2060: 0x4004a020, 0x2061: 0x4004a120, 0x2062: 0x4004a220, 0x2063: 0x4004a320, + 0x2065: 0x4004a420, 0x2067: 0x4004a520, + 0x2068: 0x4004a620, 0x2069: 0x4004a720, 0x206a: 0x4004a820, 0x206b: 0x4004a920, + 0x206c: 0xf0000404, 0x206d: 0xf0000404, 0x206e: 0x4004aa20, 0x206f: 0xf0000404, + 0x2070: 0xf0000404, 0x2071: 0x4004ab20, 0x2072: 0x4004ac20, 0x2073: 0x4004ad20, + 0x2074: 0x4004ae20, 0x2075: 0x4004af20, 0x2076: 0x4004b020, 0x2077: 0x4004b120, + 0x2078: 0x4004b220, 0x2079: 0x4004b320, 0x207a: 0x4004b420, 0x207b: 0x4004b520, + 0x207c: 0x4004b620, 0x207d: 0x4004b720, 0x207e: 0x4004b820, 0x207f: 0x4004b920, + // Block 0x82, offset 0x2080 + 0x2080: 0x4004ba20, 0x2082: 0x4004bb20, 0x2083: 0x4004bc20, + 0x2085: 0x4004bd20, 0x2086: 0x4004be20, + 0x2088: 0x4004bf20, 0x208a: 0x4004c020, 0x208b: 0x4004c120, + 0x208c: 0x4004c220, 0x208d: 0x4004c320, 0x208e: 0x4004c420, 0x208f: 0x4004c520, + 0x2090: 0x4004c620, 0x2091: 0x4004c720, 0x2092: 0x4004c820, 0x2093: 0x4004c920, + 0x2094: 0x4004ca20, 0x2095: 0x4004cb20, 0x2096: 0x4004cc20, 0x2097: 0x4004cd20, + 0x2098: 0x4004ce20, 0x2099: 0x4004cf20, 0x209a: 0x4004d020, 0x209b: 0x4004d120, + 0x209c: 0x4004d220, 0x209d: 0x4004d320, 0x209e: 0x4004d420, 0x209f: 0x4004d520, + 0x20a1: 0x4004d620, 0x20a3: 0x4004d720, + 0x20a4: 0x4004d820, 0x20a5: 0x4004d920, 0x20a6: 0x4004da20, 0x20a7: 0x4004db20, + 0x20a8: 0x4004dc20, 0x20a9: 0x4004dd20, 0x20aa: 0x4004de20, 0x20ab: 0x4004df20, + 0x20ac: 0x4004e020, + 0x20b2: 0x4004e120, 0x20b3: 0x4004e220, + 0x20b6: 0x4004e320, 0x20b7: 0x4004e420, + 0x20ba: 0x4004e520, 0x20bb: 0x4004e620, + 0x20bc: 0x4004e720, 0x20bd: 0x4004e820, 0x20be: 0x4004e920, 0x20bf: 0x4004ea20, + // Block 0x83, offset 0x20c0 + 0x20c2: 0x4004eb20, 0x20c3: 0x4004ec20, + 0x20c6: 0x4004ed20, 0x20c7: 0x4004ee20, + 0x20ca: 0x4004ef20, 0x20cb: 0x4004f020, + 0x20cc: 0x4004f120, 0x20cd: 0x4004f220, 0x20ce: 0x4004f320, 0x20cf: 0x4004f420, + 0x20d0: 0x4004f520, 0x20d1: 0x4004f620, 0x20d2: 0x4004f720, 0x20d3: 0x4004f820, + 0x20d4: 0x4004f920, 0x20d5: 0x4004fa20, 0x20d6: 0x4004fb20, 0x20d7: 0x4004fc20, + 0x20d8: 0x4004fd20, 0x20d9: 0x4004fe20, 0x20da: 0x4004ff20, 0x20db: 0x40050020, + 0x20dc: 0x40050120, 0x20dd: 0x40050220, 0x20de: 0x40050320, 0x20df: 0x40050420, + 0x20e0: 0x40050520, 0x20e1: 0x40050620, 0x20e2: 0x40050720, 0x20e3: 0x40050820, + 0x20e4: 0x40050920, 0x20e5: 0x40050a20, 0x20e6: 0x40050b20, 0x20e7: 0x40050c20, + 0x20e8: 0x40050d20, 0x20e9: 0x40050e20, 0x20ea: 0x40050f20, 0x20eb: 0x40051020, + 0x20f0: 0x40051120, 0x20f1: 0x40051220, 0x20f2: 0x40051320, 0x20f3: 0x40051420, + 0x20f4: 0x40051520, 0x20f5: 0x40051620, 0x20f6: 0x40051720, 0x20f7: 0x40051820, + 0x20f8: 0x40051920, 0x20f9: 0x40051a20, 0x20fa: 0x40051b20, 0x20fb: 0x40051c20, + 0x20fc: 0x40051d20, 0x20fd: 0x40051e20, 0x20fe: 0x40051f20, 0x20ff: 0x40052020, + // Block 0x84, offset 0x2100 + 0x2100: 0x40052120, 0x2101: 0x40052220, 0x2102: 0x40052320, 0x2103: 0x40052420, + 0x2104: 0x40052520, 0x2105: 0x40052620, 0x2106: 0x40052720, 0x2107: 0x40052820, + 0x2108: 0x40052920, 0x2109: 0x40052a20, 0x210a: 0x40052b20, 0x210b: 0x40052c20, + 0x210c: 0x40052d20, 0x210d: 0x40052e20, 0x210e: 0x40052f20, 0x210f: 0x40053020, + 0x2110: 0x40053120, 0x2111: 0x40053220, 0x2112: 0x40053320, 0x2113: 0x40053420, + 0x2114: 0x40053520, 0x2115: 0x40053620, 0x2116: 0x40053720, 0x2117: 0x40053820, + 0x2118: 0x40053920, 0x2119: 0x40053a20, 0x211a: 0x40053b20, 0x211b: 0x40053c20, + 0x211c: 0x40053d20, 0x211d: 0x40053e20, 0x211e: 0x40053f20, 0x211f: 0x40054020, + 0x2124: 0x40054120, 0x2125: 0x40054220, 0x2126: 0x40054320, 0x2127: 0x40054420, + 0x2128: 0x40054520, 0x2129: 0x40054620, + 0x212e: 0x40054720, 0x212f: 0x40054820, + 0x2130: 0x40054920, 0x2131: 0x40054a20, 0x2132: 0x40054b20, 0x2133: 0x40054c20, + 0x2134: 0x40054d20, 0x2135: 0x40054e20, 0x2136: 0x40054f20, 0x2137: 0x40055020, + 0x2138: 0x40055120, 0x2139: 0x40055220, 0x213a: 0x40055320, 0x213b: 0x40055420, + 0x213c: 0x40055520, 0x213d: 0x40055620, 0x213e: 0x40055720, 0x213f: 0x40055820, + // Block 0x85, offset 0x2140 + 0x2140: 0x40055920, 0x2141: 0x40055a20, 0x2142: 0x40055b20, 0x2143: 0x40055c20, + 0x2144: 0x40055d20, 0x2145: 0x40055e20, 0x2146: 0x40055f20, 0x2147: 0x40056020, + 0x2148: 0x40056120, 0x2149: 0x40056220, 0x214a: 0x40056320, 0x214b: 0x40056420, + 0x214c: 0x40056520, 0x214d: 0x40056620, 0x214e: 0x40056720, 0x214f: 0x40056820, + 0x2150: 0x40056920, 0x2151: 0x40056a20, 0x2152: 0x40056b20, 0x2153: 0x40056c20, + 0x2154: 0x40056d20, 0x2155: 0x40056e20, 0x2156: 0x40056f20, 0x2157: 0x40057020, + 0x2158: 0x40057120, 0x2159: 0x40057220, 0x215a: 0x40057320, 0x215b: 0x40057420, + 0x215c: 0x40057520, 0x215d: 0x40057620, 0x215e: 0x40057720, 0x215f: 0x40057820, + 0x2160: 0x40057920, 0x2161: 0x40057a20, 0x2162: 0x40057b20, 0x2163: 0x40057c20, + 0x2164: 0x40057d20, 0x2165: 0x40057e20, 0x2166: 0x40057f20, 0x2167: 0x40058020, + 0x2168: 0x40058120, 0x216b: 0x40058220, + 0x216c: 0x40058320, 0x216d: 0x40058420, 0x216e: 0x40058520, 0x216f: 0x40058620, + 0x2170: 0x40058720, 0x2171: 0x40058820, 0x2172: 0x40058920, 0x2173: 0x40058a20, + 0x2174: 0x40058b20, 0x2175: 0x40058c20, 0x2176: 0x40058d20, 0x2177: 0x40058e20, + 0x2178: 0x40058f20, 0x2179: 0x40059020, 0x217a: 0x40059120, 0x217b: 0x40059220, + 0x217c: 0x40059320, 0x217d: 0x40059420, 0x217e: 0x40059520, 0x217f: 0x40059620, + // Block 0x86, offset 0x2180 + 0x2180: 0x40059720, 0x2181: 0x40059820, 0x2182: 0x40059920, 0x2183: 0x40059a20, + 0x2184: 0x40059b20, 0x2185: 0x40059c20, 0x2186: 0x40059d20, 0x2187: 0x40059e20, + 0x2188: 0x40059f20, 0x2189: 0x4005a020, 0x218a: 0x4005a120, 0x218b: 0x4005a220, + 0x218c: 0x4005a320, 0x218d: 0x4005a420, 0x218e: 0x4005a520, 0x218f: 0x4005a620, + 0x2190: 0x4005a720, 0x2191: 0x4005a820, 0x2192: 0x4005a920, 0x2193: 0x4005aa20, + 0x2194: 0x4005ab20, 0x2195: 0x4005ac20, 0x2196: 0x4005ad20, 0x2197: 0x4005ae20, + 0x2198: 0x4005af20, 0x2199: 0x4005b020, 0x219a: 0x4005b120, 0x219b: 0x4005b220, + 0x219c: 0x4005b320, 0x219d: 0x4005b420, 0x219e: 0x4005b520, 0x219f: 0x4005b620, + 0x21a0: 0x4005b720, 0x21a1: 0x4005b820, 0x21a2: 0x4005b920, 0x21a3: 0x4005ba20, + 0x21a4: 0x4005bb20, 0x21a5: 0x4005bc20, 0x21a6: 0x4005bd20, 0x21a7: 0x4005be20, + 0x21a8: 0x4005bf20, 0x21a9: 0x4005c020, 0x21aa: 0x4005c120, 0x21ab: 0x4005c220, + 0x21ac: 0x4005c320, 0x21ad: 0x4005c420, 0x21ae: 0x4005c520, 0x21af: 0x4005c620, + 0x21b0: 0x4005c720, 0x21b1: 0x4005c820, 0x21b2: 0x4005c920, 0x21b3: 0x4005ca20, + 0x21b4: 0x4005cb20, 0x21b5: 0x4005cc20, 0x21b6: 0x4005cd20, 0x21b7: 0x4005ce20, + 0x21b8: 0x4005cf20, 0x21b9: 0x4005d020, 0x21ba: 0x4005d120, 0x21bb: 0x4005d220, + 0x21bc: 0x4005d320, 0x21bd: 0x4005d420, 0x21be: 0x4005d520, 0x21bf: 0x4005d620, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x4005d720, 0x21c1: 0x4005d820, 0x21c2: 0x4005d920, 0x21c3: 0x4005da20, + 0x21c4: 0x4005db20, 0x21c5: 0x4005dc20, 0x21c6: 0x4005dd20, 0x21c7: 0x4005de20, + 0x21c8: 0x4005df20, 0x21c9: 0x4005e020, 0x21ca: 0x4005e120, 0x21cb: 0x4005e220, + 0x21cc: 0x4005e320, 0x21cd: 0x4005e420, 0x21ce: 0x4005e520, 0x21cf: 0x4005e620, + 0x21d0: 0x4005e720, 0x21d1: 0x4005e820, 0x21d2: 0x4005e920, 0x21d3: 0x4005ea20, + 0x21d4: 0x4005eb20, 0x21d5: 0x4005ec20, 0x21d6: 0x4005ed20, 0x21d7: 0x4005ee20, + 0x21d8: 0x4005ef20, 0x21d9: 0x4005f020, 0x21da: 0x4005f120, 0x21db: 0x4005f220, + 0x21dc: 0x4005f320, 0x21dd: 0x4005f420, 0x21de: 0x4005f520, 0x21df: 0x4005f620, + 0x21e0: 0x4005f720, 0x21e1: 0x4005f820, 0x21e2: 0x4005f920, 0x21e3: 0x4005fa20, + 0x21e4: 0x4005fb20, 0x21e5: 0x4005fc20, 0x21e6: 0x4005fd20, 0x21e7: 0x4005fe20, + 0x21e8: 0x4005ff20, 0x21e9: 0x40060020, 0x21ea: 0x40060120, 0x21eb: 0x40060220, + 0x21ec: 0x40060320, 0x21ed: 0x40060420, 0x21ee: 0x40060520, 0x21ef: 0x40060620, + 0x21f0: 0x40060720, 0x21f1: 0x40060820, 0x21f2: 0x40060920, 0x21f3: 0x40060a20, + 0x21f4: 0x40060b20, 0x21f5: 0x40060c20, 0x21f6: 0x40060d20, 0x21f7: 0x40060e20, + 0x21f8: 0x40060f20, 0x21f9: 0x40061020, 0x21fa: 0x40061120, 0x21fb: 0x40061220, + 0x21fc: 0x40061320, 0x21fd: 0x40061420, 0x21fe: 0x40061520, 0x21ff: 0x40061620, + // Block 0x88, offset 0x2200 + 0x2200: 0x40061720, 0x2201: 0x40061820, 0x2202: 0x40061920, 0x2203: 0x40061a20, + 0x2204: 0x40061b20, 0x2205: 0x40061c20, 0x2206: 0x40061d20, 0x2207: 0x40061e20, + 0x2208: 0x40061f20, 0x2209: 0x40062020, 0x220a: 0x40062120, 0x220b: 0x40062220, + 0x220c: 0x40062320, 0x220d: 0x40062420, 0x220e: 0x40062520, 0x220f: 0x40062620, + 0x2210: 0x40062720, 0x2211: 0x40062820, 0x2212: 0x40062920, 0x2213: 0x40062a20, + 0x2214: 0x40062b20, 0x2215: 0x40062c20, 0x2216: 0x40062d20, 0x2217: 0x40062e20, + 0x2218: 0x40062f20, 0x2219: 0x40063020, 0x221a: 0x40063120, 0x221b: 0x40063220, + 0x221c: 0x40063320, 0x221d: 0x40063420, 0x221e: 0x40063520, 0x221f: 0x40063620, + 0x2220: 0x40063720, 0x2221: 0x40063820, 0x2222: 0x40063920, 0x2223: 0x40063a20, + 0x2224: 0x40063b20, 0x2225: 0x40063c20, 0x2226: 0x40063d20, 0x2227: 0x40063e20, + 0x2228: 0x40063f20, 0x2229: 0x40064020, 0x222a: 0x40064120, 0x222b: 0x40064220, + 0x222c: 0x40064320, 0x222d: 0x40064420, 0x222e: 0x40064520, 0x222f: 0x40064620, + 0x2230: 0x40064720, 0x2231: 0x40064820, 0x2232: 0x40064920, 0x2233: 0x40064a20, + // Block 0x89, offset 0x2240 + 0x2240: 0x40064b20, 0x2241: 0x40064c20, 0x2242: 0x40064d20, 0x2243: 0x40064e20, + 0x2244: 0x40064f20, 0x2245: 0x40065020, 0x2246: 0x40065120, 0x2247: 0x40065220, + 0x2248: 0x40065320, 0x2249: 0x40065420, 0x224a: 0x40065520, 0x224b: 0x40065620, + 0x224c: 0x40065720, 0x224d: 0x40065820, 0x224e: 0x40065920, 0x224f: 0x40065a20, + 0x2250: 0x40065b20, 0x2251: 0x40065c20, 0x2252: 0x40065d20, 0x2253: 0x40065e20, + 0x2254: 0x40065f20, 0x2255: 0x40066020, 0x2256: 0x40066120, 0x2257: 0x40066220, + 0x2258: 0x40066320, 0x2259: 0x40066420, 0x225a: 0x40066520, 0x225b: 0x40066620, + 0x225c: 0x40066720, 0x225d: 0x40066820, 0x225e: 0x40066920, 0x225f: 0x40066a20, + 0x2260: 0x40066b20, 0x2261: 0x40066c20, 0x2262: 0x40066d20, 0x2263: 0x40066e20, + 0x2264: 0x40066f20, 0x2265: 0x40067020, 0x2266: 0x40067120, + // Block 0x8a, offset 0x2280 + 0x2280: 0x40067220, 0x2281: 0x40067320, 0x2282: 0x40067420, 0x2283: 0x40067520, + 0x2284: 0x40067620, 0x2285: 0x40067720, 0x2286: 0x40067820, 0x2287: 0x40067920, + 0x2288: 0x40067a20, 0x2289: 0x40067b20, 0x228a: 0x40067c20, + 0x22a0: 0xf0000006, 0x22a1: 0xf0000006, 0x22a2: 0xf0000006, 0x22a3: 0xf0000006, + 0x22a4: 0xf0000006, 0x22a5: 0xf0000006, 0x22a6: 0xf0000006, 0x22a7: 0xf0000006, + 0x22a8: 0xf0000006, 0x22a9: 0xf0000606, 0x22aa: 0xf0000606, 0x22ab: 0xf0000606, + 0x22ac: 0xf0000606, 0x22ad: 0xf0000606, 0x22ae: 0xf0000606, 0x22af: 0xf0000606, + 0x22b0: 0xf0000606, 0x22b1: 0xf0000606, 0x22b2: 0xf0000606, 0x22b3: 0xf0000606, + 0x22b4: 0xf0000404, 0x22b5: 0xf0000404, 0x22b6: 0xf0000404, 0x22b7: 0xf0000404, + 0x22b8: 0xf0000404, 0x22b9: 0xf0000404, 0x22ba: 0xf0000404, 0x22bb: 0xf0000404, + 0x22bc: 0xf0000404, 0x22bd: 0xf0000404, 0x22be: 0xf0000404, 0x22bf: 0xf0000404, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0xf0000404, 0x22c1: 0xf0000404, 0x22c2: 0xf0000404, 0x22c3: 0xf0000404, + 0x22c4: 0xf0000404, 0x22c5: 0xf0000404, 0x22c6: 0xf0000404, 0x22c7: 0xf0000404, + 0x22c8: 0xf0000404, 0x22c9: 0xf0000404, 0x22ca: 0xf0000404, 0x22cb: 0xf0000404, + 0x22cc: 0xf0000404, 0x22cd: 0xf0000404, 0x22ce: 0xf0000404, 0x22cf: 0xf0000404, + 0x22d0: 0xf0000404, 0x22d1: 0xf0000404, 0x22d2: 0xf0000404, 0x22d3: 0xf0000404, + 0x22d4: 0xf0000404, 0x22d5: 0xf0000404, 0x22d6: 0xf0000404, 0x22d7: 0xf0000404, + 0x22d8: 0xf0000404, 0x22d9: 0xf0000404, 0x22da: 0xf0000404, 0x22db: 0xf0000404, + 0x22dc: 0xf0000404, 0x22dd: 0xf0000404, 0x22de: 0xf0000404, 0x22df: 0xf0000404, + 0x22e0: 0xf0000404, 0x22e1: 0xf0000404, 0x22e2: 0xf0000404, 0x22e3: 0xf0000404, + 0x22e4: 0xf0000404, 0x22e5: 0xf0000404, 0x22e6: 0xf0000404, 0x22e7: 0xf0000404, + 0x22e8: 0xf0000404, 0x22e9: 0xf0000404, 0x22ea: 0xf0000404, 0x22eb: 0xf0000404, + 0x22ec: 0xf0000404, 0x22ed: 0xf0000404, 0x22ee: 0xf0000404, 0x22ef: 0xf0000404, + 0x22f0: 0xf0000404, 0x22f1: 0xf0000404, 0x22f2: 0xf0000404, 0x22f3: 0xf0000404, + 0x22f4: 0xf0000404, 0x22f5: 0xf0000404, 0x22f6: 0xf000000c, 0x22f7: 0xf000000c, + 0x22f8: 0xf000000c, 0x22f9: 0xf000000c, 0x22fa: 0xf000000c, 0x22fb: 0xf000000c, + 0x22fc: 0xf000000c, 0x22fd: 0xf000000c, 0x22fe: 0xf000000c, 0x22ff: 0xf000000c, + // Block 0x8c, offset 0x2300 + 0x2300: 0xf000000c, 0x2301: 0xf000000c, 0x2302: 0xf000000c, 0x2303: 0xf000000c, + 0x2304: 0xf000000c, 0x2305: 0xf000000c, 0x2306: 0xf000000c, 0x2307: 0xf000000c, + 0x2308: 0xf000000c, 0x2309: 0xf000000c, 0x230a: 0xf000000c, 0x230b: 0xf000000c, + 0x230c: 0xf000000c, 0x230d: 0xf000000c, 0x230e: 0xf000000c, 0x230f: 0xf000000c, + 0x2310: 0xf0000006, 0x2311: 0xf0000006, 0x2312: 0xf0000006, 0x2313: 0xf0000006, + 0x2314: 0xf0000006, 0x2315: 0xf0000006, 0x2316: 0xf0000006, 0x2317: 0xf0000006, + 0x2318: 0xf0000006, 0x2319: 0xf0000006, 0x231a: 0xf0000006, 0x231b: 0xf0000006, + 0x231c: 0xf0000006, 0x231d: 0xf0000006, 0x231e: 0xf0000006, 0x231f: 0xf0000006, + 0x2320: 0xf0000006, 0x2321: 0xf0000006, 0x2322: 0xf0000006, 0x2323: 0xf0000006, + 0x2324: 0xf0000006, 0x2325: 0xf0000006, 0x2326: 0xf0000006, 0x2327: 0xf0000006, + 0x2328: 0xf0000006, 0x2329: 0xf0000006, 0x232a: 0xf0000006, 0x232b: 0xe0000168, + 0x232c: 0xe000016b, 0x232d: 0xe000016e, 0x232e: 0xe0000171, 0x232f: 0xe0000174, + 0x2330: 0xe0000177, 0x2331: 0xe000017a, 0x2332: 0xe000017d, 0x2333: 0xe0000180, + 0x2334: 0xe0000243, 0x2335: 0x00293606, 0x2336: 0x00293806, 0x2337: 0x00293a06, + 0x2338: 0x00293c06, 0x2339: 0x00293e06, 0x233a: 0x00294006, 0x233b: 0x00294206, + 0x233c: 0x00294406, 0x233d: 0x00294606, 0x233e: 0xe0000159, 0x233f: 0x00293406, + // Block 0x8d, offset 0x2340 + 0x2340: 0x40067d20, 0x2341: 0x40067e20, 0x2342: 0x40067f20, 0x2343: 0x40068020, + 0x2344: 0x40068120, 0x2345: 0x40068220, 0x2346: 0x40068320, 0x2347: 0x40068420, + 0x2348: 0x40068520, 0x2349: 0x40068620, 0x234a: 0x40068720, 0x234b: 0x40068820, + 0x234c: 0x40068920, 0x234d: 0x40068a20, 0x234e: 0x40068b20, 0x234f: 0x40068c20, + 0x2350: 0x40068d20, 0x2351: 0x40068e20, 0x2352: 0x40068f20, 0x2353: 0x40069020, + 0x2354: 0x40069120, 0x2355: 0x40069220, 0x2356: 0x40069320, 0x2357: 0x40069420, + 0x2358: 0x40069520, 0x2359: 0x40069620, 0x235a: 0x40069720, 0x235b: 0x40069820, + 0x235c: 0x40069920, 0x235d: 0x40069a20, 0x235e: 0x40069b20, 0x235f: 0x40069c20, + 0x2360: 0x40069d20, 0x2361: 0x40069e20, 0x2362: 0x40069f20, 0x2363: 0x4006a020, + 0x2364: 0x4006a120, 0x2365: 0x4006a220, 0x2366: 0x4006a320, 0x2367: 0x4006a420, + 0x2368: 0x4006a520, 0x2369: 0x4006a620, 0x236a: 0x4006a720, 0x236b: 0x4006a820, + 0x236c: 0x4006a920, 0x236d: 0x4006aa20, 0x236e: 0x4006ab20, 0x236f: 0x4006ac20, + 0x2370: 0x4006ad20, 0x2371: 0x4006ae20, 0x2372: 0x4006af20, 0x2373: 0x4006b020, + 0x2374: 0x4006b120, 0x2375: 0x4006b220, 0x2376: 0x4006b320, 0x2377: 0x4006b420, + 0x2378: 0x4006b520, 0x2379: 0x4006b620, 0x237a: 0x4006b720, 0x237b: 0x4006b820, + 0x237c: 0x4006b920, 0x237d: 0x4006ba20, 0x237e: 0x4006bb20, 0x237f: 0x4006bc20, + // Block 0x8e, offset 0x2380 + 0x2380: 0x4006bd20, 0x2381: 0x4006be20, 0x2382: 0x4006bf20, 0x2383: 0x4006c020, + 0x2384: 0x4006c120, 0x2385: 0x4006c220, 0x2386: 0x4006c320, 0x2387: 0x4006c420, + 0x2388: 0x4006c520, 0x2389: 0x4006c620, 0x238a: 0x4006c720, 0x238b: 0x4006c820, + 0x238c: 0x4006c920, 0x238d: 0x4006ca20, 0x238e: 0x4006cb20, 0x238f: 0x4006cc20, + 0x2390: 0x4006cd20, 0x2391: 0x4006ce20, 0x2392: 0x4006cf20, 0x2393: 0x4006d020, + 0x2394: 0x4006d120, 0x2395: 0x4006d220, 0x2396: 0x4006d320, 0x2397: 0x4006d420, + 0x2398: 0x4006d520, 0x2399: 0x4006d620, 0x239a: 0x4006d720, 0x239b: 0x4006d820, + 0x239c: 0x4006d920, 0x239d: 0x4006da20, 0x239e: 0x4006db20, 0x239f: 0x4006dc20, + 0x23a0: 0x4006dd20, 0x23a1: 0x4006de20, 0x23a2: 0x4006df20, 0x23a3: 0x4006e020, + 0x23a4: 0x4006e120, 0x23a5: 0x4006e220, 0x23a6: 0x4006e320, 0x23a7: 0x4006e420, + 0x23a8: 0x4006e520, 0x23a9: 0x4006e620, 0x23aa: 0x4006e720, 0x23ab: 0x4006e820, + 0x23ac: 0x4006e920, 0x23ad: 0x4006ea20, 0x23ae: 0x4006eb20, 0x23af: 0x4006ec20, + 0x23b0: 0x4006ed20, 0x23b1: 0x4006ee20, 0x23b2: 0x4006ef20, 0x23b3: 0x4006f020, + 0x23b4: 0x4006f120, 0x23b5: 0x4006f220, 0x23b6: 0x4006f320, 0x23b7: 0x4006f420, + 0x23b8: 0x4006f520, 0x23b9: 0x4006f620, 0x23ba: 0x4006f720, 0x23bb: 0x4006f820, + 0x23bc: 0x4006f920, 0x23bd: 0x4006fa20, 0x23be: 0x4006fb20, 0x23bf: 0x4006fc20, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x4006fd20, 0x23c1: 0x4006fe20, 0x23c2: 0x4006ff20, 0x23c3: 0x40070020, + 0x23c4: 0x40070120, 0x23c5: 0x40070220, 0x23c6: 0x40070320, 0x23c7: 0x40070420, + 0x23c8: 0x40070520, 0x23c9: 0x40070620, 0x23ca: 0x40070720, 0x23cb: 0x40070820, + 0x23cc: 0x40070920, 0x23cd: 0x40070a20, 0x23ce: 0x40070b20, 0x23cf: 0x40070c20, + 0x23d0: 0x40070d20, 0x23d1: 0x40070e20, 0x23d2: 0x40070f20, 0x23d3: 0x40071020, + 0x23d4: 0x40071120, 0x23d5: 0x40071220, 0x23d6: 0x40071320, 0x23d7: 0x40071420, + 0x23d8: 0x40071520, 0x23d9: 0x40071620, 0x23da: 0x40071720, 0x23db: 0x40071820, + 0x23dc: 0x40071920, 0x23dd: 0x40071a20, 0x23de: 0x40071b20, 0x23df: 0x40071c20, + 0x23e0: 0x40071d20, 0x23e1: 0x40071e20, 0x23e2: 0x40071f20, 0x23e3: 0x40072020, + 0x23e4: 0x40072120, 0x23e5: 0x40072220, 0x23e6: 0x40072320, 0x23e7: 0x40072420, + 0x23e8: 0x40072520, 0x23e9: 0x40072620, 0x23ea: 0x40072720, 0x23eb: 0x40072820, + 0x23ec: 0x40072920, 0x23ed: 0x40072a20, 0x23ee: 0x40072b20, 0x23ef: 0x40072c20, + 0x23f0: 0x40072d20, 0x23f1: 0x40072e20, 0x23f2: 0x40072f20, 0x23f3: 0x40073020, + 0x23f4: 0x40073120, 0x23f5: 0x40073220, 0x23f6: 0x40073320, 0x23f7: 0x40073420, + 0x23f8: 0x40073520, 0x23f9: 0x40073620, 0x23fa: 0x40073720, 0x23fb: 0x40073820, + 0x23fc: 0x40073920, 0x23fd: 0x40073a20, 0x23fe: 0x40073b20, 0x23ff: 0x40073c20, + // Block 0x90, offset 0x2400 + 0x2400: 0x40073d20, 0x2401: 0x40073e20, 0x2402: 0x40073f20, 0x2403: 0x40074020, + 0x2404: 0x40074120, 0x2405: 0x40074220, 0x2406: 0x40074320, 0x2407: 0x40074420, + 0x2408: 0x40074520, 0x2409: 0x40074620, 0x240a: 0x40074720, 0x240b: 0x40074820, + 0x240c: 0x40074920, 0x240d: 0x40074a20, 0x240e: 0x40074b20, 0x240f: 0x40074c20, + 0x2410: 0x40074d20, 0x2411: 0x40074e20, 0x2412: 0x40074f20, 0x2413: 0x40075020, + 0x2414: 0x40075120, 0x2415: 0x40075220, 0x2416: 0x40075320, 0x2417: 0x40075420, + 0x2418: 0x40075520, 0x2419: 0x40075620, 0x241a: 0x40075720, 0x241b: 0x40075820, + 0x241c: 0x40075920, 0x241d: 0x40075a20, 0x241e: 0x40075b20, 0x241f: 0x40075c20, + 0x2420: 0x40075d20, 0x2421: 0x40075e20, 0x2422: 0x40075f20, 0x2423: 0x40076020, + 0x2424: 0x40076120, 0x2425: 0x40076220, 0x2426: 0x40076320, 0x2427: 0x40076420, + 0x2428: 0x40076520, 0x2429: 0x40076620, 0x242a: 0x40076720, 0x242b: 0x40076820, + 0x242c: 0x40076920, 0x242d: 0x40076a20, 0x242e: 0x40076b20, 0x242f: 0x40076c20, + 0x2430: 0x40076d20, 0x2431: 0x40076e20, 0x2432: 0x40076f20, 0x2433: 0x40077020, + 0x2434: 0x40077120, 0x2435: 0x40077220, 0x2436: 0x40077320, 0x2437: 0x40077420, + 0x2438: 0x40077520, 0x2439: 0x40077620, 0x243a: 0x40077720, 0x243b: 0x40077820, + 0x243c: 0x40077920, 0x243d: 0x40077a20, 0x243e: 0x40077b20, 0x243f: 0x40077c20, + // Block 0x91, offset 0x2440 + 0x2440: 0x40077d20, 0x2441: 0x40077e20, 0x2442: 0x40077f20, 0x2443: 0x40078020, + 0x2444: 0x40078120, 0x2445: 0x40078220, 0x2446: 0x40078320, 0x2447: 0x40078420, + 0x2448: 0x40078520, 0x2449: 0x40078620, 0x244a: 0x40078720, 0x244b: 0x40078820, + 0x244c: 0x40078920, 0x244d: 0x40078a20, 0x244e: 0x40078b20, 0x244f: 0x40078c20, + 0x2450: 0x40078d20, 0x2451: 0x40078e20, 0x2452: 0x40078f20, 0x2453: 0x40079020, + 0x2454: 0x40079120, 0x2455: 0x40079220, 0x2456: 0x40079320, 0x2457: 0x40079420, + 0x2458: 0x40079520, 0x2459: 0x40079620, 0x245a: 0x40079720, 0x245b: 0x40079820, + 0x245c: 0x40079920, 0x245d: 0x40079a20, 0x245e: 0x40079b20, 0x245f: 0x40079c20, + 0x2460: 0x40079d20, 0x2461: 0x40079e20, 0x2462: 0x40079f20, 0x2463: 0x4007a020, + 0x2464: 0x4007a120, 0x2465: 0x4007a220, 0x2466: 0x4007a320, 0x2467: 0x4007a420, + 0x2468: 0x4007a520, 0x2469: 0x4007a620, 0x246a: 0x4007a720, 0x246b: 0x4007a820, + 0x246c: 0x4007a920, 0x246d: 0x4007aa20, 0x246e: 0x4007ab20, 0x246f: 0x4007ac20, + 0x2470: 0x400c7320, 0x2471: 0x400c7420, 0x2472: 0x400c7520, 0x2473: 0x400c7620, + 0x2474: 0x400c7720, 0x2475: 0x400c7820, 0x2476: 0x400c7920, 0x2477: 0x400c7a20, + 0x2478: 0x4007ad20, 0x2479: 0x4007ae20, 0x247a: 0x4007af20, 0x247b: 0x4007b020, + 0x247c: 0x4007b120, 0x247d: 0x4007b220, 0x247e: 0x4007b320, 0x247f: 0x4007b420, + // Block 0x92, offset 0x2480 + 0x2480: 0x4007b520, 0x2481: 0x4007b620, 0x2482: 0x4007b720, 0x2483: 0x4007b820, + 0x2484: 0x4007b920, 0x2485: 0x4007ba20, 0x2486: 0x4007bb20, 0x2487: 0x4007bc20, + 0x2488: 0x4007bd20, 0x2489: 0x4007be20, 0x248a: 0x4007bf20, 0x248b: 0x4007c020, + 0x248c: 0x4007c120, 0x248d: 0x4007c220, 0x248e: 0x4007c320, 0x248f: 0x4007c420, + 0x2490: 0x4007c520, 0x2491: 0x4007c620, 0x2492: 0x4007c720, 0x2493: 0x4007c820, + 0x2494: 0x4007c920, 0x2495: 0x4007ca20, 0x2496: 0x4007cb20, 0x2497: 0x4007cc20, + 0x2498: 0x4007cd20, 0x2499: 0x4007ce20, 0x249a: 0x4007cf20, 0x249b: 0x4007d020, + 0x249c: 0x4007d120, 0x249d: 0x4007d220, 0x249e: 0x4007d320, 0x249f: 0x4007d420, + 0x24a0: 0x4007d520, 0x24a1: 0x4007d620, 0x24a2: 0x4007d720, 0x24a3: 0x4007d820, + 0x24a4: 0x4007d920, 0x24a5: 0x4007da20, 0x24a6: 0x4007db20, 0x24a7: 0x4007dc20, + 0x24a8: 0x4007dd20, 0x24a9: 0x4007de20, 0x24aa: 0x4007df20, 0x24ab: 0x4007e020, + 0x24ac: 0x4007e120, 0x24ad: 0x400eb920, 0x24ae: 0x400eba20, 0x24af: 0x400ebb20, + 0x24b0: 0x4007e220, 0x24b1: 0x4007e320, 0x24b2: 0x4007e420, 0x24b3: 0x4007e520, + 0x24b4: 0x4007e620, 0x24b5: 0x4007e720, 0x24b6: 0x4007e820, 0x24b7: 0x4007e920, + 0x24b8: 0x4007ea20, 0x24b9: 0x4007eb20, 0x24ba: 0x4007ec20, 0x24bb: 0x4007ed20, + 0x24bc: 0x4007ee20, 0x24bd: 0x4007ef20, 0x24be: 0x4007f020, 0x24bf: 0x4007f120, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x4007f220, 0x24c1: 0x4007f320, 0x24c2: 0x4007f420, 0x24c3: 0x4007f520, + 0x24c4: 0x4007f620, 0x24c5: 0x4007f720, 0x24c6: 0x4007f820, 0x24c7: 0x4007f920, + 0x24c8: 0x4007fa20, 0x24c9: 0x4007fb20, 0x24ca: 0x400c6d20, 0x24cb: 0x400c6e20, + 0x24cc: 0x400c6f20, 0x24cd: 0x400c7020, 0x24ce: 0x400c7120, 0x24cf: 0x400c7220, + 0x24d0: 0x4007fc20, 0x24d1: 0x4007fd20, 0x24d2: 0x4007fe20, 0x24d3: 0x4007ff20, + 0x24d4: 0x40080020, 0x24d5: 0x40080120, 0x24d6: 0x40080220, 0x24d7: 0x40080320, + 0x24d8: 0x40080420, 0x24d9: 0x40080520, 0x24da: 0x40080620, 0x24db: 0x40080720, + 0x24dc: 0x40080820, 0x24dd: 0x40080920, 0x24de: 0x40080a20, 0x24df: 0x40080b20, + 0x24e0: 0x40080c20, 0x24e1: 0x40080d20, 0x24e2: 0x40080e20, 0x24e3: 0x40080f20, + 0x24e4: 0x40081020, 0x24e5: 0x40081120, 0x24e6: 0x40081220, 0x24e7: 0x40081320, + 0x24e8: 0x40081420, 0x24e9: 0x40081520, 0x24ea: 0x40081620, 0x24eb: 0x40081720, + 0x24ec: 0x40081820, 0x24ed: 0x40081920, 0x24ee: 0x40081a20, 0x24ef: 0x40081b20, + 0x24f0: 0x40081c20, 0x24f1: 0x40081d20, 0x24f2: 0x40081e20, 0x24f3: 0x40081f20, + 0x24f4: 0x40082020, 0x24f5: 0x40082120, 0x24f6: 0x40082220, 0x24f7: 0x40082320, + 0x24f8: 0x40082420, 0x24f9: 0x40082520, 0x24fa: 0x40082620, 0x24fb: 0x40082720, + 0x24fc: 0x40082820, 0x24fd: 0x40082920, 0x24fe: 0x40082a20, 0x24ff: 0x40082b20, + // Block 0x94, offset 0x2500 + 0x2500: 0x40082c20, 0x2501: 0x40082d20, 0x2502: 0x40082e20, 0x2503: 0x40082f20, + 0x2504: 0x40083020, 0x2505: 0x40083120, 0x2506: 0x40083220, 0x2507: 0x40083320, + 0x2508: 0x40083420, 0x2509: 0x40083520, 0x250a: 0x40083620, 0x250b: 0x40083720, + 0x250c: 0x40083820, 0x250d: 0x40083920, 0x250e: 0x40083a20, 0x250f: 0x40083b20, + 0x2510: 0x40083c20, 0x2511: 0x40083d20, 0x2512: 0x40083e20, 0x2513: 0x40083f20, + 0x2514: 0x40084020, 0x2515: 0x40084120, 0x2516: 0x40084220, 0x2517: 0x40084320, + 0x2518: 0x40084420, 0x2519: 0x40084520, 0x251a: 0x40084620, 0x251b: 0x40084720, + 0x251c: 0x40084820, 0x251d: 0x40084920, 0x251e: 0x40084a20, 0x251f: 0x40084b20, + 0x2520: 0x40084c20, 0x2521: 0x40084d20, 0x2522: 0x40084e20, 0x2523: 0x40084f20, + 0x2524: 0x40085020, 0x2525: 0x40085120, 0x2526: 0x40085220, 0x2527: 0x40085320, + 0x2528: 0x40085420, 0x2529: 0x40085520, 0x252a: 0x40085620, 0x252b: 0x40085720, + 0x252c: 0x40085820, 0x252d: 0x40085920, 0x252e: 0x40085a20, 0x252f: 0x40085b20, + 0x2530: 0x40085c20, 0x2531: 0x40085d20, 0x2532: 0x40085e20, 0x2533: 0x40085f20, + 0x2534: 0x40086020, 0x2535: 0x40086120, 0x2536: 0x40086220, 0x2537: 0x40086320, + 0x2538: 0x40086420, 0x2539: 0x40086520, 0x253a: 0x40086620, 0x253b: 0x40086720, + 0x253c: 0x40086820, 0x253d: 0x40086920, 0x253e: 0x40086a20, 0x253f: 0x40086b20, + // Block 0x95, offset 0x2540 + 0x2541: 0x40086c20, 0x2542: 0x40086d20, 0x2543: 0x40086e20, + 0x2544: 0x40086f20, 0x2545: 0x40087020, 0x2546: 0x40087120, 0x2547: 0x40087220, + 0x2548: 0x40087320, 0x2549: 0x40087420, 0x254a: 0x40087520, 0x254b: 0x40087620, + 0x254c: 0x40087720, 0x254d: 0x40087820, 0x254e: 0x40087920, 0x254f: 0x40087a20, + 0x2550: 0x40087b20, 0x2551: 0x40087c20, 0x2552: 0x40087d20, 0x2553: 0x40087e20, + 0x2554: 0x40087f20, 0x2555: 0x40088020, 0x2556: 0x40088120, 0x2557: 0x40088220, + 0x2558: 0x40088320, 0x2559: 0x40088420, 0x255a: 0x40088520, 0x255b: 0x40088620, + 0x255c: 0x40088720, 0x255d: 0x40088820, 0x255e: 0x40088920, 0x255f: 0x40088a20, + 0x2560: 0x40088b20, 0x2561: 0x40088c20, 0x2562: 0x40088d20, 0x2563: 0x40088e20, + 0x2564: 0x40088f20, 0x2565: 0x40089020, 0x2566: 0x40089120, 0x2567: 0x40089220, + 0x2568: 0x40089320, 0x2569: 0x40089420, 0x256a: 0x40089520, 0x256b: 0x40089620, + 0x256c: 0x40089720, 0x256d: 0x40089820, 0x256e: 0x40089920, 0x256f: 0x40089a20, + 0x2570: 0x40089b20, 0x2571: 0x40089c20, 0x2572: 0x40089d20, 0x2573: 0x40089e20, + 0x2574: 0x40089f20, 0x2575: 0x4008a020, 0x2576: 0x4008a120, 0x2577: 0x4008a220, + 0x2578: 0x4008a320, 0x2579: 0x4008a420, 0x257a: 0x4008a520, 0x257b: 0x4008a620, + 0x257c: 0x4008a720, 0x257d: 0x4008a820, 0x257e: 0x4008a920, 0x257f: 0x4008aa20, + // Block 0x96, offset 0x2580 + 0x2580: 0x4008ab20, 0x2581: 0x4008ac20, 0x2582: 0x4008ad20, 0x2583: 0x4008ae20, + 0x2584: 0x4008af20, 0x2585: 0x4008b020, 0x2586: 0x4008b120, 0x2587: 0x4008b220, + 0x2588: 0x4008b320, 0x2589: 0x4008b420, 0x258a: 0x4008b520, 0x258b: 0x4008b620, + 0x258c: 0x4008b720, 0x258d: 0x4008b820, 0x258e: 0x4008b920, 0x258f: 0x4008ba20, + 0x2590: 0x4008bb20, 0x2591: 0x4008bc20, 0x2592: 0x4008bd20, 0x2593: 0x4008be20, + 0x2594: 0x4008bf20, 0x2595: 0x4008c020, 0x2596: 0x4008c120, 0x2597: 0x4008c220, + 0x2598: 0x4008c320, 0x2599: 0x4008c420, 0x259a: 0x4008c520, 0x259b: 0x4008c620, + 0x259c: 0x4008c720, 0x259d: 0x4008c820, 0x259e: 0x4008c920, 0x259f: 0x4008ca20, + 0x25a0: 0x4008cb20, 0x25a1: 0x4008cc20, 0x25a2: 0x4008cd20, 0x25a3: 0x4008ce20, + 0x25a4: 0x4008cf20, 0x25a5: 0x4008d020, 0x25a6: 0x4008d120, 0x25a7: 0x4008d220, + 0x25a8: 0x4002d320, 0x25a9: 0x4002d420, 0x25aa: 0x4002d520, 0x25ab: 0x4002d620, + 0x25ac: 0x4002d720, 0x25ad: 0x4002d820, 0x25ae: 0x4002d920, 0x25af: 0x4002da20, + 0x25b0: 0x4002db20, 0x25b1: 0x4002dc20, 0x25b2: 0x4002dd20, 0x25b3: 0x4002de20, + 0x25b4: 0x4002df20, 0x25b5: 0x4002e020, 0x25b6: 0x00293606, 0x25b7: 0x00293806, + 0x25b8: 0x00293a06, 0x25b9: 0x00293c06, 0x25ba: 0x00293e06, 0x25bb: 0x00294006, + 0x25bc: 0x00294206, 0x25bd: 0x00294406, 0x25be: 0x00294606, 0x25bf: 0xe000015c, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00293606, 0x25c1: 0x00293806, 0x25c2: 0x00293a06, 0x25c3: 0x00293c06, + 0x25c4: 0x00293e06, 0x25c5: 0x00294006, 0x25c6: 0x00294206, 0x25c7: 0x00294406, + 0x25c8: 0x00294606, 0x25c9: 0xe000015f, 0x25ca: 0x00293606, 0x25cb: 0x00293806, + 0x25cc: 0x00293a06, 0x25cd: 0x00293c06, 0x25ce: 0x00293e06, 0x25cf: 0x00294006, + 0x25d0: 0x00294206, 0x25d1: 0x00294406, 0x25d2: 0x00294606, 0x25d3: 0xe0000162, + 0x25d4: 0x4008d320, 0x25d5: 0x4008d420, 0x25d6: 0x4008d520, 0x25d7: 0x4008d620, + 0x25d8: 0x4008d720, 0x25d9: 0x4008d820, 0x25da: 0x4008d920, 0x25db: 0x4008da20, + 0x25dc: 0x4008db20, 0x25dd: 0x4008dc20, 0x25de: 0x4008dd20, 0x25df: 0x4008de20, + 0x25e0: 0x4008df20, 0x25e1: 0x4008e020, 0x25e2: 0x4008e120, 0x25e3: 0x4008e220, + 0x25e4: 0x4008e320, 0x25e5: 0x4008e420, 0x25e6: 0x4008e520, 0x25e7: 0x4008e620, + 0x25e8: 0x4008e720, 0x25e9: 0x4008e820, 0x25ea: 0x4008e920, 0x25eb: 0x4008ea20, + 0x25ec: 0x4008eb20, 0x25ed: 0x4008ec20, 0x25ee: 0x4008ed20, 0x25ef: 0x4008ee20, + 0x25f0: 0x4008ef20, 0x25f1: 0x4008f020, 0x25f2: 0x4008f120, 0x25f3: 0x4008f220, + 0x25f4: 0x4008f320, 0x25f5: 0x4008f420, 0x25f6: 0x4008f520, 0x25f7: 0x4008f620, + 0x25f8: 0x4008f720, 0x25f9: 0x4008f820, 0x25fa: 0x4008f920, 0x25fb: 0x4008fa20, + 0x25fc: 0x4008fb20, 0x25fd: 0x4008fc20, 0x25fe: 0x4008fd20, 0x25ff: 0x4008fe20, + // Block 0x98, offset 0x2600 + 0x2600: 0x4008ff20, 0x2601: 0x40090020, 0x2602: 0x40090120, 0x2603: 0x40090220, + 0x2604: 0x40090320, 0x2605: 0x4002e120, 0x2606: 0x4002e220, 0x2607: 0x40090420, + 0x2608: 0x40090520, 0x2609: 0x40090620, 0x260a: 0x40090720, + 0x260c: 0x40090820, 0x260e: 0x40090920, 0x260f: 0x40090a20, + 0x2610: 0x40090b20, 0x2611: 0x40090c20, 0x2612: 0x40090d20, 0x2613: 0x40090e20, + 0x2614: 0x40090f20, 0x2615: 0x40091020, 0x2616: 0x40091120, 0x2617: 0x40091220, + 0x2618: 0x40091320, 0x2619: 0x40091420, 0x261a: 0x40091520, 0x261b: 0x40091620, + 0x261c: 0x40091720, 0x261d: 0x40091820, 0x261e: 0x40091920, 0x261f: 0x40091a20, + 0x2620: 0x40091b20, 0x2621: 0x40091c20, 0x2622: 0x40091d20, 0x2623: 0x40091e20, + 0x2624: 0x40091f20, 0x2625: 0x40092020, 0x2626: 0x4002e320, 0x2627: 0x4002e420, + 0x2628: 0x4002e520, 0x2629: 0x4002e620, 0x262a: 0x4002e720, 0x262b: 0x4002e820, + 0x262c: 0x40020f20, 0x262d: 0x40021020, 0x262e: 0x40021120, 0x262f: 0x40021220, + 0x2630: 0x40092120, 0x2631: 0x40092220, 0x2632: 0x40092320, 0x2633: 0x40092420, + 0x2634: 0x40092520, 0x2635: 0x40092620, 0x2636: 0x40092720, 0x2637: 0x40092820, + 0x2638: 0x40092920, 0x2639: 0x40092a20, 0x263a: 0x40092b20, 0x263b: 0x40092c20, + 0x263c: 0x40092d20, 0x263d: 0x40092e20, 0x263e: 0x40092f20, 0x263f: 0x40093020, + // Block 0x99, offset 0x2640 + 0x2640: 0x400b6d20, 0x2641: 0x400b6e20, 0x2642: 0x400b6f20, 0x2643: 0x400b7020, + 0x2644: 0x400b7120, 0x2645: 0x400b7220, 0x2646: 0x400b7320, 0x2647: 0x400b7420, + 0x2648: 0x400b7520, 0x2649: 0x400b7620, 0x264a: 0x400b7720, 0x264b: 0x400b7820, + 0x264c: 0x400b7920, 0x264d: 0x400b7a20, 0x264e: 0x400b7b20, 0x264f: 0x400b7c20, + 0x2650: 0x400b7d20, 0x2651: 0x400b7e20, 0x2652: 0x400b7f20, 0x2653: 0x400b8020, + 0x2654: 0x400b8120, 0x2655: 0x400b8220, 0x2656: 0x400b8320, 0x2657: 0x400b8420, + 0x2658: 0x400b8520, 0x2659: 0x400b8620, 0x265a: 0x400b8720, 0x265b: 0x400b8820, + 0x265c: 0x400b8920, 0x265d: 0x400b8a20, 0x265e: 0x400b8b20, 0x265f: 0x400b8c20, + 0x2660: 0x400b8d20, 0x2661: 0x400b8e20, 0x2662: 0x400b8f20, 0x2663: 0x400b9020, + 0x2664: 0x400b9120, 0x2665: 0x400b9220, 0x2666: 0x400b9320, 0x2667: 0x400b9420, + 0x2668: 0x400b9520, 0x2669: 0x400b9620, 0x266a: 0x400b9720, 0x266b: 0x400b9820, + 0x266c: 0x400b9920, 0x266d: 0x400b9a20, 0x266e: 0x400b9b20, 0x266f: 0x400b9c20, + 0x2670: 0x400b9d20, 0x2671: 0x400b9e20, 0x2672: 0x400b9f20, 0x2673: 0x400ba020, + 0x2674: 0x400ba120, 0x2675: 0x400ba220, 0x2676: 0x400ba320, 0x2677: 0x400ba420, + 0x2678: 0x400ba520, 0x2679: 0x400ba620, 0x267a: 0x400ba720, 0x267b: 0x400ba820, + 0x267c: 0x400ba920, 0x267d: 0x400baa20, 0x267e: 0x400bab20, 0x267f: 0x400bac20, + // Block 0x9a, offset 0x2680 + 0x2680: 0x400bad20, 0x2681: 0x400bae20, 0x2682: 0x400baf20, 0x2683: 0x400bb020, + 0x2684: 0x400bb120, 0x2685: 0x400bb220, 0x2686: 0x400bb320, 0x2687: 0x400bb420, + 0x2688: 0x400bb520, 0x2689: 0x400bb620, 0x268a: 0x400bb720, 0x268b: 0x400bb820, + 0x268c: 0x400bb920, 0x268d: 0x400bba20, 0x268e: 0x400bbb20, 0x268f: 0x400bbc20, + 0x2690: 0x400bbd20, 0x2691: 0x400bbe20, 0x2692: 0x400bbf20, 0x2693: 0x400bc020, + 0x2694: 0x400bc120, 0x2695: 0x400bc220, 0x2696: 0x400bc320, 0x2697: 0x400bc420, + 0x2698: 0x400bc520, 0x2699: 0x400bc620, 0x269a: 0x400bc720, 0x269b: 0x400bc820, + 0x269c: 0x400bc920, 0x269d: 0x400bca20, 0x269e: 0x400bcb20, 0x269f: 0x400bcc20, + 0x26a0: 0x400bcd20, 0x26a1: 0x400bce20, 0x26a2: 0x400bcf20, 0x26a3: 0x400bd020, + 0x26a4: 0x400bd120, 0x26a5: 0x400bd220, 0x26a6: 0x400bd320, 0x26a7: 0x400bd420, + 0x26a8: 0x400bd520, 0x26a9: 0x400bd620, 0x26aa: 0x400bd720, 0x26ab: 0x400bd820, + 0x26ac: 0x400bd920, 0x26ad: 0x400bda20, 0x26ae: 0x400bdb20, 0x26af: 0x400bdc20, + 0x26b0: 0x400bdd20, 0x26b1: 0x400bde20, 0x26b2: 0x400bdf20, 0x26b3: 0x400be020, + 0x26b4: 0x400be120, 0x26b5: 0x400be220, 0x26b6: 0x400be320, 0x26b7: 0x400be420, + 0x26b8: 0x400be520, 0x26b9: 0x400be620, 0x26ba: 0x400be720, 0x26bb: 0x400be820, + 0x26bc: 0x400be920, 0x26bd: 0x400bea20, 0x26be: 0x400beb20, 0x26bf: 0x400bec20, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x400bed20, 0x26c1: 0x400bee20, 0x26c2: 0x400bef20, 0x26c3: 0x400bf020, + 0x26c4: 0x400bf120, 0x26c5: 0x400bf220, 0x26c6: 0x400bf320, 0x26c7: 0x400bf420, + 0x26c8: 0x400bf520, 0x26c9: 0x400bf620, 0x26ca: 0x400bf720, 0x26cb: 0x400bf820, + 0x26cc: 0x400bf920, 0x26cd: 0x400bfa20, 0x26ce: 0x400bfb20, 0x26cf: 0x400bfc20, + 0x26d0: 0x400bfd20, 0x26d1: 0x400bfe20, 0x26d2: 0x400bff20, 0x26d3: 0x400c0020, + 0x26d4: 0x400c0120, 0x26d5: 0x400c0220, 0x26d6: 0x400c0320, 0x26d7: 0x400c0420, + 0x26d8: 0x400c0520, 0x26d9: 0x400c0620, 0x26da: 0x400c0720, 0x26db: 0x400c0820, + 0x26dc: 0x400c0920, 0x26dd: 0x400c0a20, 0x26de: 0x400c0b20, 0x26df: 0x400c0c20, + 0x26e0: 0x400c0d20, 0x26e1: 0x400c0e20, 0x26e2: 0x400c0f20, 0x26e3: 0x400c1020, + 0x26e4: 0x400c1120, 0x26e5: 0x400c1220, 0x26e6: 0x400c1320, 0x26e7: 0x400c1420, + 0x26e8: 0x400c1520, 0x26e9: 0x400c1620, 0x26ea: 0x400c1720, 0x26eb: 0x400c1820, + 0x26ec: 0x400c1920, 0x26ed: 0x400c1a20, 0x26ee: 0x400c1b20, 0x26ef: 0x400c1c20, + 0x26f0: 0x400c1d20, 0x26f1: 0x400c1e20, 0x26f2: 0x400c1f20, 0x26f3: 0x400c2020, + 0x26f4: 0x400c2120, 0x26f5: 0x400c2220, 0x26f6: 0x400c2320, 0x26f7: 0x400c2420, + 0x26f8: 0x400c2520, 0x26f9: 0x400c2620, 0x26fa: 0x400c2720, 0x26fb: 0x400c2820, + 0x26fc: 0x400c2920, 0x26fd: 0x400c2a20, 0x26fe: 0x400c2b20, 0x26ff: 0x400c2c20, + // Block 0x9c, offset 0x2700 + 0x2700: 0x400c2d20, 0x2701: 0x400c2e20, 0x2702: 0x400c2f20, 0x2703: 0x400c3020, + 0x2704: 0x400c3120, 0x2705: 0x400c3220, 0x2706: 0x400c3320, 0x2707: 0x400c3420, + 0x2708: 0x400c3520, 0x2709: 0x400c3620, 0x270a: 0x400c3720, 0x270b: 0x400c3820, + 0x270c: 0x400c3920, 0x270d: 0x400c3a20, 0x270e: 0x400c3b20, 0x270f: 0x400c3c20, + 0x2710: 0x400c3d20, 0x2711: 0x400c3e20, 0x2712: 0x400c3f20, 0x2713: 0x400c4020, + 0x2714: 0x400c4120, 0x2715: 0x400c4220, 0x2716: 0x400c4320, 0x2717: 0x400c4420, + 0x2718: 0x400c4520, 0x2719: 0x400c4620, 0x271a: 0x400c4720, 0x271b: 0x400c4820, + 0x271c: 0x400c4920, 0x271d: 0x400c4a20, 0x271e: 0x400c4b20, 0x271f: 0x400c4c20, + 0x2720: 0x400c4d20, 0x2721: 0x400c4e20, 0x2722: 0x400c4f20, 0x2723: 0x400c5020, + 0x2724: 0x400c5120, 0x2725: 0x400c5220, 0x2726: 0x400c5320, 0x2727: 0x400c5420, + 0x2728: 0x400c5520, 0x2729: 0x400c5620, 0x272a: 0x400c5720, 0x272b: 0x400c5820, + 0x272c: 0x400c5920, 0x272d: 0x400c5a20, 0x272e: 0x400c5b20, 0x272f: 0x400c5c20, + 0x2730: 0x400c5d20, 0x2731: 0x400c5e20, 0x2732: 0x400c5f20, 0x2733: 0x400c6020, + 0x2734: 0x400c6120, 0x2735: 0x400c6220, 0x2736: 0x400c6320, 0x2737: 0x400c6420, + 0x2738: 0x400c6520, 0x2739: 0x400c6620, 0x273a: 0x400c6720, 0x273b: 0x400c6820, + 0x273c: 0x400c6920, 0x273d: 0x400c6a20, 0x273e: 0x400c6b20, 0x273f: 0x400c6c20, + // Block 0x9d, offset 0x2740 + 0x2740: 0x40093120, 0x2741: 0x40093220, 0x2742: 0x40093320, 0x2743: 0x40093420, + 0x2744: 0x40093520, 0x2745: 0x40093620, 0x2746: 0x40093720, 0x2747: 0x40093820, + 0x2748: 0x40093920, 0x2749: 0x40093a20, 0x274a: 0x40093b20, 0x274b: 0x40093c20, + 0x274c: 0x40093d20, 0x274d: 0x40093e20, 0x274e: 0x40093f20, 0x274f: 0x40094020, + 0x2750: 0x40094120, 0x2751: 0x40094220, 0x2752: 0x40094320, 0x2753: 0x40094420, + 0x2754: 0x40094520, 0x2755: 0x40094620, 0x2756: 0x40094720, 0x2757: 0x40094820, + 0x2758: 0x40094920, 0x2759: 0x40094a20, 0x275a: 0x40094b20, 0x275b: 0x40094c20, + 0x275c: 0x40094d20, 0x275d: 0x40094e20, 0x275e: 0x40094f20, 0x275f: 0x40095020, + 0x2760: 0x40095120, 0x2761: 0x40095220, 0x2762: 0x40095320, 0x2763: 0x40095420, + 0x2764: 0x40095520, 0x2765: 0x40095620, 0x2766: 0x40095720, 0x2767: 0x40095820, + 0x2768: 0x40095920, 0x2769: 0x40095a20, 0x276a: 0x40095b20, 0x276b: 0x40095c20, + 0x276c: 0x40095d20, 0x276d: 0x40095e20, 0x276e: 0x40095f20, 0x276f: 0x40096020, + 0x2770: 0x40096120, 0x2771: 0x40096220, 0x2772: 0x40096320, 0x2773: 0x40096420, + 0x2774: 0x40096520, 0x2775: 0x40096620, 0x2776: 0x40096720, 0x2777: 0x40096820, + 0x2778: 0x40096920, 0x2779: 0x40096a20, 0x277a: 0x40096b20, 0x277b: 0x40096c20, + 0x277c: 0x40096d20, 0x277d: 0x40096e20, 0x277e: 0x40096f20, 0x277f: 0x40097020, + // Block 0x9e, offset 0x2780 + 0x2780: 0x40097120, 0x2781: 0x40097220, 0x2782: 0x40097320, 0x2783: 0x40097420, + 0x2784: 0x40097520, 0x2785: 0x40097620, 0x2786: 0x40097720, 0x2787: 0x40097820, + 0x2788: 0x40097920, 0x2789: 0x40097a20, 0x278a: 0x40097b20, 0x278b: 0x40097c20, + 0x278c: 0x40097d20, 0x278d: 0x40097e20, 0x278e: 0x40097f20, 0x278f: 0x40098020, + 0x2790: 0x40098120, 0x2791: 0x40098220, 0x2792: 0x40098320, 0x2793: 0x40098420, + 0x2794: 0x40098520, 0x2795: 0x40098620, 0x2796: 0x40098720, 0x2797: 0x40098820, + 0x2798: 0x40098920, 0x2799: 0x40098a20, 0x279a: 0x40098b20, 0x279b: 0x40098c20, + 0x279c: 0x40098d20, 0x279d: 0x40098e20, 0x279e: 0x40098f20, 0x279f: 0x40099020, + 0x27a0: 0x40099120, 0x27a1: 0x40099220, 0x27a2: 0x40099320, 0x27a3: 0x40099420, + 0x27a4: 0x40099520, 0x27a5: 0x40099620, 0x27a6: 0x40099720, 0x27a7: 0x40099820, + 0x27a8: 0x40099920, 0x27a9: 0x40099a20, 0x27aa: 0x40099b20, 0x27ab: 0x40099c20, + 0x27ac: 0x40099d20, 0x27ad: 0x40099e20, 0x27ae: 0x40099f20, 0x27af: 0x4009a020, + 0x27b0: 0x4009a120, 0x27b1: 0x4009a220, 0x27b2: 0x4009a320, 0x27b3: 0x4009a420, + 0x27b4: 0x4009a520, 0x27b5: 0x4009a620, 0x27b6: 0x4009a720, 0x27b7: 0x4009a820, + 0x27b8: 0x4009a920, 0x27b9: 0x4009aa20, 0x27ba: 0x4009ab20, 0x27bb: 0x4009ac20, + 0x27bc: 0x4009ad20, 0x27bd: 0x4009ae20, 0x27be: 0x4009af20, 0x27bf: 0x4009b020, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x4009b120, 0x27c1: 0x4009b220, 0x27c2: 0x4009b320, 0x27c3: 0x4001f920, + 0x27c4: 0x4001fa20, 0x27c5: 0x4001fb20, 0x27c6: 0x4001fc20, 0x27c7: 0x4001fd20, + 0x27c8: 0x4001fe20, 0x27c9: 0x4001ff20, 0x27ca: 0x40020020, 0x27cb: 0x40020120, + 0x27cc: 0x40020220, 0x27cd: 0x40020320, 0x27ce: 0x40020420, 0x27cf: 0x40020520, + 0x27d0: 0x40020620, 0x27d1: 0x40020720, 0x27d2: 0x40020820, 0x27d3: 0x40020920, + 0x27d4: 0x40020a20, 0x27d5: 0x40020b20, 0x27d6: 0x40020c20, 0x27d7: 0x40020d20, + 0x27d8: 0x40020e20, 0x27d9: 0x4009b420, 0x27da: 0x4009b520, 0x27db: 0x4009b620, + 0x27dc: 0x4009b720, 0x27dd: 0x4009b820, 0x27de: 0x4009b920, 0x27df: 0x4009ba20, + 0x27e0: 0x4009bb20, 0x27e1: 0x4009bc20, 0x27e2: 0x4009bd20, 0x27e3: 0x4009be20, + 0x27e4: 0x4009bf20, 0x27e5: 0x4009c020, 0x27e6: 0x4009c120, 0x27e7: 0x4009c220, + 0x27e8: 0x4009c320, 0x27e9: 0x4009c420, 0x27ea: 0x4009c520, 0x27eb: 0x4009c620, + 0x27ec: 0x4009c720, 0x27ed: 0x4009c820, 0x27ee: 0x4009c920, 0x27ef: 0x4009ca20, + 0x27f0: 0x4009cb20, 0x27f1: 0x4009cc20, 0x27f2: 0x4009cd20, 0x27f3: 0x4009ce20, + 0x27f4: 0x4009cf20, 0x27f5: 0x4009d020, 0x27f6: 0x4009d120, 0x27f7: 0x4009d220, + 0x27f8: 0x4009d320, 0x27f9: 0x4009d420, 0x27fa: 0x4009d520, 0x27fb: 0x4009d620, + 0x27fc: 0x4009d720, 0x27fd: 0x4009d820, 0x27fe: 0x4009d920, 0x27ff: 0x4009da20, + // Block 0xa0, offset 0x2800 + 0x2800: 0x4009db20, 0x2801: 0x4009dc20, 0x2802: 0x4009dd20, 0x2803: 0x4009de20, + 0x2804: 0x4009df20, 0x2805: 0x4009e020, 0x2806: 0x4009e120, 0x2807: 0x4009e220, + 0x2808: 0x4009e320, 0x2809: 0x4009e420, 0x280a: 0x4009e520, 0x280b: 0x4009e620, + 0x280c: 0x4009e720, 0x280d: 0x4009e820, 0x280e: 0x4009e920, 0x280f: 0x4009ea20, + 0x2810: 0x4009eb20, 0x2811: 0x4009ec20, 0x2812: 0x4009ed20, 0x2813: 0x4009ee20, + 0x2814: 0x4009ef20, 0x2815: 0x4009f020, 0x2816: 0x4009f120, 0x2817: 0x4009f220, + 0x2818: 0x4002e920, 0x2819: 0x4002ea20, 0x281a: 0x4002eb20, 0x281b: 0x4002ec20, + 0x281c: 0x4009f320, 0x281d: 0x4009f420, 0x281e: 0x4009f520, 0x281f: 0x4009f620, + 0x2820: 0x4009f720, 0x2821: 0x4009f820, 0x2822: 0x4009f920, 0x2823: 0x4009fa20, + 0x2824: 0x4009fb20, 0x2825: 0x4009fc20, 0x2826: 0x4009fd20, 0x2827: 0x4009fe20, + 0x2828: 0x4009ff20, 0x2829: 0x400a0020, 0x282a: 0x400a0120, 0x282b: 0x400a0220, + 0x282c: 0x400a0320, 0x282d: 0x400a0420, 0x282e: 0x400a0520, 0x282f: 0x400a0620, + 0x2830: 0x400a0720, 0x2831: 0x400a0820, 0x2832: 0x400a0920, 0x2833: 0x400a0a20, + 0x2834: 0x400a0b20, 0x2835: 0x400a0c20, 0x2836: 0x400a0d20, 0x2837: 0x400a0e20, + 0x2838: 0x400a0f20, 0x2839: 0x400a1020, 0x283a: 0x400a1120, 0x283b: 0x400a1220, + 0x283c: 0x4001f720, 0x283d: 0x4001f820, 0x283e: 0x400a1320, 0x283f: 0x400a1420, + // Block 0xa1, offset 0x2840 + 0x2840: 0x400a1520, 0x2841: 0x400a1620, 0x2842: 0x400a1720, 0x2843: 0x400a1820, + 0x2844: 0x400a1920, 0x2845: 0x400a1a20, 0x2846: 0x400a1b20, 0x2847: 0x400a1c20, + 0x2848: 0x400a1d20, 0x2849: 0x400a1e20, 0x284a: 0x400a1f20, 0x284b: 0x400a2020, + 0x284c: 0xf0000404, 0x284d: 0x400a2120, 0x284e: 0x400a2220, 0x284f: 0x400a2320, + 0x2850: 0x400a2420, 0x2851: 0x400a2520, 0x2852: 0x400a2620, 0x2853: 0x400a2720, + 0x2854: 0x400a2820, 0x2855: 0x400a2920, 0x2856: 0x400a2a20, 0x2857: 0x400a2b20, + 0x2858: 0x400a2c20, 0x2859: 0x400a2d20, 0x285a: 0x400a2e20, 0x285b: 0x400a2f20, + 0x285c: 0x400a3020, 0x285d: 0x400a3120, 0x285e: 0x400a3220, 0x285f: 0x400a3320, + 0x2860: 0x400a3420, 0x2861: 0x400a3520, 0x2862: 0x400a3620, 0x2863: 0x400a3720, + 0x2864: 0x400a3820, 0x2865: 0x400a3920, 0x2866: 0x400a3a20, 0x2867: 0x400a3b20, + 0x2868: 0x400a3c20, 0x2869: 0x400a3d20, 0x286a: 0x400a3e20, 0x286b: 0x400a3f20, + 0x286c: 0x400a4020, 0x286d: 0x400a4120, 0x286e: 0x400a4220, 0x286f: 0x400a4320, + 0x2870: 0x400a4420, 0x2871: 0x400a4520, 0x2872: 0x400a4620, 0x2873: 0x400a4720, + 0x2874: 0x400a4820, 0x2875: 0x400a4920, 0x2876: 0x400a4a20, 0x2877: 0x400a4b20, + 0x2878: 0x400a4c20, 0x2879: 0x400a4d20, 0x287a: 0x400a4e20, 0x287b: 0x400a4f20, + 0x287c: 0x400a5020, 0x287d: 0x400a5120, 0x287e: 0x400a5220, 0x287f: 0x400a5320, + // Block 0xa2, offset 0x2880 + 0x2880: 0x400a5420, 0x2881: 0x400a5520, 0x2882: 0x400a5620, 0x2883: 0x400a5720, + 0x2884: 0x400a5820, 0x2885: 0x400a5920, 0x2886: 0x400a5a20, 0x2887: 0x400a5b20, + 0x2888: 0x400a5c20, 0x2889: 0x400a5d20, 0x288a: 0x400a5e20, 0x288b: 0x400a5f20, + 0x288c: 0x400a6020, 0x288d: 0x400a6120, 0x288e: 0x400a6220, 0x288f: 0x400a6320, + 0x2890: 0x400a6420, 0x2891: 0x400a6520, 0x2892: 0x400a6620, 0x2893: 0x400a6720, + 0x2894: 0x400a6820, 0x2895: 0x400a6920, 0x2896: 0x400a6a20, 0x2897: 0x400a6b20, + 0x2898: 0x400a6c20, 0x2899: 0x400a6d20, 0x289a: 0x400a6e20, 0x289b: 0x400a6f20, + 0x289c: 0x400a7020, 0x289d: 0x400a7120, 0x289e: 0x400a7220, 0x289f: 0x400a7320, + 0x28a0: 0x400a7420, 0x28a1: 0x400a7520, 0x28a2: 0x400a7620, 0x28a3: 0x400a7720, + 0x28a4: 0x400a7820, 0x28a5: 0x400a7920, 0x28a6: 0x400a7a20, 0x28a7: 0x400a7b20, + 0x28a8: 0x400a7c20, 0x28a9: 0x400a7d20, 0x28aa: 0x400a7e20, 0x28ab: 0x400a7f20, + 0x28ac: 0x400a8020, 0x28ad: 0x400a8120, 0x28ae: 0x400a8220, 0x28af: 0x400a8320, + 0x28b0: 0x400a8420, 0x28b1: 0x400a8520, 0x28b2: 0x400a8620, 0x28b3: 0x400a8720, + 0x28b4: 0xf0000404, 0x28b5: 0xf0000404, 0x28b6: 0xf0000404, 0x28b7: 0x400a8820, + 0x28b8: 0x400a8920, 0x28b9: 0x400a8a20, 0x28ba: 0x400a8b20, 0x28bb: 0x400a8c20, + 0x28bc: 0x400a8d20, 0x28bd: 0x400a8e20, 0x28be: 0x400a8f20, 0x28bf: 0x400a9020, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x400a9120, 0x28c1: 0x400a9220, 0x28c2: 0x400a9320, 0x28c3: 0x400a9420, + 0x28c4: 0x400a9520, 0x28c5: 0x400a9620, 0x28c6: 0x400a9720, 0x28c7: 0x400a9820, + 0x28c8: 0x400a9920, 0x28c9: 0x400a9a20, 0x28ca: 0x400a9b20, 0x28cb: 0x400a9c20, + 0x28cc: 0x400a9d20, 0x28cd: 0x400a9e20, 0x28ce: 0x400a9f20, 0x28cf: 0x400aa020, + 0x28d0: 0x400aa120, 0x28d1: 0x400aa220, 0x28d2: 0x400aa320, 0x28d3: 0x400aa420, + 0x28d4: 0x400aa520, 0x28d5: 0x400aa620, 0x28d6: 0x400aa720, 0x28d7: 0x400aa820, + 0x28d8: 0x400aa920, 0x28d9: 0x400aaa20, 0x28da: 0x400aab20, 0x28db: 0x400aac20, + 0x28dc: 0x400aad20, 0x28dd: 0x400aae20, 0x28de: 0x400aaf20, 0x28df: 0x400ab020, + 0x28e0: 0x400ab120, 0x28e1: 0x400ab220, 0x28e2: 0x400ab320, 0x28e3: 0x400ab420, + 0x28e4: 0x400ab520, 0x28e5: 0x400ab620, 0x28e6: 0x400ab720, 0x28e7: 0x400ab820, + 0x28e8: 0x400ab920, 0x28e9: 0x400aba20, 0x28ea: 0x400abb20, 0x28eb: 0x400abc20, + 0x28ec: 0x400abd20, 0x28ed: 0x400abe20, 0x28ee: 0x400abf20, 0x28ef: 0x400ac020, + 0x28f0: 0x400ac120, 0x28f1: 0x400ac220, 0x28f2: 0x400ac320, 0x28f3: 0x400ac420, + 0x28f4: 0x400ac520, 0x28f5: 0x400ac620, 0x28f6: 0x400ac720, 0x28f7: 0x400ac820, + 0x28f8: 0x400ac920, 0x28f9: 0x400aca20, 0x28fa: 0x400acb20, 0x28fb: 0x400acc20, + 0x28fc: 0x400acd20, 0x28fd: 0x400ace20, 0x28fe: 0x400acf20, 0x28ff: 0x400ad020, + // Block 0xa4, offset 0x2900 + 0x2900: 0x400ad120, 0x2901: 0x400ad220, 0x2902: 0x400ad320, 0x2903: 0x400ad420, + 0x2904: 0x400ad520, 0x2905: 0x400ad620, 0x2906: 0x400ad720, 0x2907: 0x400ad820, + 0x2908: 0x400ad920, 0x2909: 0x400ada20, 0x290a: 0x400adb20, 0x290b: 0x400adc20, + 0x290c: 0x400add20, 0x290d: 0x400ade20, 0x290e: 0x400adf20, 0x290f: 0x400ae020, + 0x2910: 0x400ae120, 0x2911: 0x400ae220, 0x2912: 0x400ae320, 0x2913: 0x400ae420, + 0x2914: 0x400ae520, 0x2915: 0x400ae620, 0x2916: 0x400ae720, 0x2917: 0x400ae820, + 0x2918: 0x400ae920, 0x2919: 0x400aea20, 0x291a: 0x400aeb20, 0x291b: 0x400aec20, + 0x291d: 0x400aed20, 0x291e: 0x400aee20, 0x291f: 0x400aef20, + 0x2920: 0x400af020, 0x2921: 0x400af120, 0x2922: 0x400af220, 0x2923: 0x400af320, + 0x2924: 0x400af420, 0x2925: 0x400af520, 0x2926: 0x400af620, 0x2927: 0x400af720, + 0x2928: 0x400af820, 0x2929: 0x400af920, 0x292a: 0x400afa20, 0x292b: 0x400afb20, + 0x292c: 0x400afc20, 0x292d: 0x400afd20, 0x292e: 0x400afe20, 0x292f: 0x400aff20, + 0x2930: 0x400b0020, 0x2931: 0x400b0120, 0x2932: 0x400b0220, 0x2933: 0x400b0320, + 0x2934: 0x400b0420, 0x2935: 0x400b0520, 0x2936: 0x400b0620, 0x2937: 0x400b0720, + 0x2938: 0x400b0820, 0x2939: 0x400b0920, 0x293a: 0x400b0a20, 0x293b: 0x400b0b20, + 0x293c: 0x400b0c20, 0x293d: 0x400b0d20, 0x293e: 0x400b0e20, 0x293f: 0x400b0f20, + // Block 0xa5, offset 0x2940 + 0x2940: 0x400b1020, 0x2941: 0x400b1120, 0x2942: 0x400b1220, 0x2943: 0x400b1320, + 0x2944: 0x400b1420, 0x2945: 0x400b1520, 0x2946: 0x400b1620, 0x2947: 0x400b1720, + 0x2948: 0x400b1820, 0x2949: 0x400b1920, 0x294a: 0x400b1a20, 0x294b: 0x400b1b20, + 0x294c: 0x400b1c20, 0x294d: 0x400b1d20, 0x294e: 0x400b1e20, 0x294f: 0x400b1f20, + 0x2950: 0x400b2020, 0x2951: 0x400b2120, 0x2952: 0x400b2220, 0x2953: 0x400b2320, + 0x2954: 0x400b2420, 0x2955: 0x400b2520, 0x2956: 0x400b2620, 0x2957: 0x400b2720, + 0x2958: 0x400b2820, 0x2959: 0x400b2920, 0x295a: 0x400b2a20, 0x295b: 0x400b2b20, + 0x295c: 0x400b2c20, 0x295d: 0x400b2d20, 0x295e: 0x400b2e20, 0x295f: 0x400b2f20, + 0x2960: 0x400b3020, 0x2961: 0x400b3120, 0x2962: 0x400b3220, 0x2963: 0x400b3320, + 0x2964: 0x400b3420, 0x2965: 0x400b3520, 0x2966: 0x400b3620, 0x2967: 0x400b3720, + 0x2968: 0x400b3820, 0x2969: 0x400b3920, 0x296a: 0x400b3a20, 0x296b: 0x400b3b20, + 0x296c: 0x400b3c20, 0x296d: 0x400b3d20, 0x296e: 0x400b3e20, 0x296f: 0x400b3f20, + 0x2970: 0x400b4020, 0x2971: 0x400b4120, 0x2972: 0x400b4220, 0x2973: 0x400b4320, + 0x2974: 0x400b4420, 0x2975: 0x400b4520, 0x2976: 0x400b4620, 0x2977: 0x400b4720, + 0x2978: 0x400b4820, 0x2979: 0x400b4920, 0x297a: 0x400b4a20, 0x297b: 0x400b4b20, + 0x297c: 0x400b4c20, 0x297d: 0x400b4d20, 0x297e: 0x400b4e20, 0x297f: 0x400b4f20, + // Block 0xa6, offset 0x2980 + 0x2980: 0x400b5020, 0x2981: 0x400b5120, 0x2982: 0x400b5220, 0x2983: 0x400b5320, + 0x2984: 0x400b5420, 0x2985: 0x400b5520, 0x2986: 0x400b5620, 0x2987: 0x400b5720, + 0x2988: 0x400b5820, 0x2989: 0x400b5920, 0x298a: 0x400b5a20, 0x298b: 0x400b5b20, + 0x298c: 0x400b5c20, + 0x2990: 0x400b5d20, 0x2991: 0x400b5e20, 0x2992: 0x400b5f20, 0x2993: 0x400b6020, + 0x2994: 0x400b6120, 0x2995: 0x400b6220, 0x2996: 0x400b6320, 0x2997: 0x400b6420, + 0x2998: 0x400b6520, 0x2999: 0x400b6620, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00369c08, 0x29c1: 0x00369e08, 0x29c2: 0x0036a008, 0x29c3: 0x0036a208, + 0x29c4: 0x0036a408, 0x29c5: 0x0036a608, 0x29c6: 0x0036a808, 0x29c7: 0x0036aa08, + 0x29c8: 0x0036ac08, 0x29c9: 0x0036ae08, 0x29ca: 0x0036b008, 0x29cb: 0x0036b208, + 0x29cc: 0x0036b408, 0x29cd: 0x0036b608, 0x29ce: 0x0036b808, 0x29cf: 0x0036ba08, + 0x29d0: 0x0036bc08, 0x29d1: 0x0036be08, 0x29d2: 0x0036c008, 0x29d3: 0x0036c208, + 0x29d4: 0x0036c408, 0x29d5: 0x0036c608, 0x29d6: 0x0036c808, 0x29d7: 0x0036ca08, + 0x29d8: 0x0036cc08, 0x29d9: 0x0036ce08, 0x29da: 0x0036d008, 0x29db: 0x0036d208, + 0x29dc: 0x0036d408, 0x29dd: 0x0036d608, 0x29de: 0x0036d808, 0x29df: 0x0036da08, + 0x29e0: 0x0036dc08, 0x29e1: 0x0036de08, 0x29e2: 0x0036e008, 0x29e3: 0x0036e208, + 0x29e4: 0x0036e408, 0x29e5: 0x0036e608, 0x29e6: 0x0036e808, 0x29e7: 0x0036ea08, + 0x29e8: 0x0036ec08, 0x29e9: 0x0036ee08, 0x29ea: 0x0036f008, 0x29eb: 0x0036f208, + 0x29ec: 0x0036f408, 0x29ed: 0x0036f608, 0x29ee: 0x0036f808, + 0x29f0: 0x401b4e20, 0x29f1: 0x401b4f20, 0x29f2: 0x401b5020, 0x29f3: 0x401b5120, + 0x29f4: 0x401b5220, 0x29f5: 0x401b5320, 0x29f6: 0x401b5420, 0x29f7: 0x401b5520, + 0x29f8: 0x401b5620, 0x29f9: 0x401b5720, 0x29fa: 0x401b5820, 0x29fb: 0x401b5920, + 0x29fc: 0x401b5a20, 0x29fd: 0x401b5b20, 0x29fe: 0x401b5c20, 0x29ff: 0x401b5d20, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x401b5e20, 0x2a01: 0x401b5f20, 0x2a02: 0x401b6020, 0x2a03: 0x401b6120, + 0x2a04: 0x401b6220, 0x2a05: 0x401b6320, 0x2a06: 0x401b6420, 0x2a07: 0x401b6520, + 0x2a08: 0x401b6620, 0x2a09: 0x401b6720, 0x2a0a: 0x401b6820, 0x2a0b: 0x401b6920, + 0x2a0c: 0x401b6a20, 0x2a0d: 0x401b6b20, 0x2a0e: 0x401b6c20, 0x2a0f: 0x401b6d20, + 0x2a10: 0x401b6e20, 0x2a11: 0x401b6f20, 0x2a12: 0x401b7020, 0x2a13: 0x401b7120, + 0x2a14: 0x401b7220, 0x2a15: 0x401b7320, 0x2a16: 0x401b7420, 0x2a17: 0x401b7520, + 0x2a18: 0x401b7620, 0x2a19: 0x401b7720, 0x2a1a: 0x401b7820, 0x2a1b: 0x401b7920, + 0x2a1c: 0x401b7a20, 0x2a1d: 0x401b7b20, 0x2a1e: 0x401b7c20, + 0x2a20: 0x002da608, 0x2a21: 0x4016d320, 0x2a22: 0x002da808, 0x2a23: 0x002e9c08, + 0x2a24: 0x002f2408, 0x2a25: 0x4015a820, 0x2a26: 0x4017d220, 0x2a27: 0x002cee08, + 0x2a28: 0x40167720, 0x2a29: 0x002d7808, 0x2a2a: 0x4016bc20, 0x2a2b: 0x0030be08, + 0x2a2c: 0x40185f20, 0x2a2d: 0x002b6008, 0x2a2e: 0x002df608, 0x2a2f: 0x002b5808, + 0x2a30: 0x002b6a08, 0x2a31: 0x40181d20, 0x2a32: 0x00305208, 0x2a33: 0x40182920, + 0x2a34: 0x40181e20, 0x2a35: 0x002cf008, 0x2a36: 0x40167820, 0x2a37: 0x40175d20, + 0x2a38: 0x40160920, 0x2a39: 0x40178d20, 0x2a3a: 0x40173a20, 0x2a3b: 0x40160e20, + 0x2a3c: 0xf0000015, 0x2a3d: 0xf000001d, 0x2a3e: 0x002f6208, 0x2a3f: 0x0030b608, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x00321008, 0x2a41: 0x40190820, 0x2a42: 0x00321208, 0x2a43: 0x40190920, + 0x2a44: 0x00321408, 0x2a45: 0x40190a20, 0x2a46: 0x00321608, 0x2a47: 0x40190b20, + 0x2a48: 0x00321808, 0x2a49: 0x40190c20, 0x2a4a: 0x00321c08, 0x2a4b: 0x40190e20, + 0x2a4c: 0x00321e08, 0x2a4d: 0x40190f20, 0x2a4e: 0x00322008, 0x2a4f: 0x40191020, + 0x2a50: 0x00322208, 0x2a51: 0x40191120, 0x2a52: 0x00322408, 0x2a53: 0x40191220, + 0x2a54: 0x00322608, 0x2a55: 0x40191320, 0x2a56: 0x00322a08, 0x2a57: 0x40191520, + 0x2a58: 0x00322c08, 0x2a59: 0x40191620, 0x2a5a: 0x00322e08, 0x2a5b: 0x40191720, + 0x2a5c: 0x00323408, 0x2a5d: 0x40191a20, 0x2a5e: 0x00323608, 0x2a5f: 0x40191b20, + 0x2a60: 0x00323808, 0x2a61: 0x40191c20, 0x2a62: 0x00323a08, 0x2a63: 0x40191d20, + 0x2a64: 0x00323c08, 0x2a65: 0x40191e20, 0x2a66: 0x00323e08, 0x2a67: 0x40191f20, + 0x2a68: 0x00324008, 0x2a69: 0x40192020, 0x2a6a: 0x00324208, 0x2a6b: 0x40192120, + 0x2a6c: 0x00324408, 0x2a6d: 0x40192220, 0x2a6e: 0x00324608, 0x2a6f: 0x40192320, + 0x2a70: 0x00324808, 0x2a71: 0x40192420, 0x2a72: 0x00327c08, 0x2a73: 0x40193e20, + 0x2a74: 0x00327e08, 0x2a75: 0x40193f20, 0x2a76: 0x00321a08, 0x2a77: 0x40190d20, + 0x2a78: 0x00322808, 0x2a79: 0x40191420, 0x2a7a: 0x00323008, 0x2a7b: 0x40191820, + 0x2a7c: 0x00323208, 0x2a7d: 0x40191920, 0x2a7e: 0x00324a08, 0x2a7f: 0x40192520, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x00324c08, 0x2a81: 0x40192620, 0x2a82: 0x00325208, 0x2a83: 0x40192920, + 0x2a84: 0x00325408, 0x2a85: 0x40192a20, 0x2a86: 0x00325608, 0x2a87: 0x40192b20, + 0x2a88: 0x00325c08, 0x2a89: 0x40192e20, 0x2a8a: 0x00326008, 0x2a8b: 0x40193020, + 0x2a8c: 0x00326208, 0x2a8d: 0x40193120, 0x2a8e: 0x00326408, 0x2a8f: 0x40193220, + 0x2a90: 0x00326608, 0x2a91: 0x40193320, 0x2a92: 0x00326808, 0x2a93: 0x40193420, + 0x2a94: 0x00326a08, 0x2a95: 0x40193520, 0x2a96: 0x00327008, 0x2a97: 0x40193820, + 0x2a98: 0x00327408, 0x2a99: 0x40193a20, 0x2a9a: 0x00327608, 0x2a9b: 0x40193b20, + 0x2a9c: 0x00327808, 0x2a9d: 0x40193c20, 0x2a9e: 0x00328008, 0x2a9f: 0x40194020, + 0x2aa0: 0x00328208, 0x2aa1: 0x40194120, 0x2aa2: 0x00328408, 0x2aa3: 0x40194220, + 0x2aa4: 0xe0000833, 0x2aa5: 0x400b6720, 0x2aa6: 0x400b6820, 0x2aa7: 0x400b6920, + 0x2aa8: 0x400b6a20, 0x2aa9: 0x400b6b20, 0x2aaa: 0x400b6c20, 0x2aab: 0x00325008, + 0x2aac: 0x40192820, 0x2aad: 0x00326e08, 0x2aae: 0x40193720, 0x2aaf: 0x80005f02, + 0x2ab0: 0x80002a02, 0x2ab1: 0x80002202, + 0x2ab9: 0x40017520, 0x2aba: 0x40016520, 0x2abb: 0x40016620, + 0x2abc: 0x4001cb20, 0x2abd: 0x40140e20, 0x2abe: 0x40017620, 0x2abf: 0x4001cc20, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x401b7e20, 0x2ac1: 0x401b8020, 0x2ac2: 0x401b8220, 0x2ac3: 0x401b8420, + 0x2ac4: 0x401b8620, 0x2ac5: 0x401b8820, 0x2ac6: 0x401b8a20, 0x2ac7: 0x401b8e20, + 0x2ac8: 0x401b9020, 0x2ac9: 0x401b9220, 0x2aca: 0x401b9420, 0x2acb: 0x401b9620, + 0x2acc: 0x401b9820, 0x2acd: 0x401b9c20, 0x2ace: 0x401b9e20, 0x2acf: 0x401ba020, + 0x2ad0: 0x401ba220, 0x2ad1: 0x401ba420, 0x2ad2: 0x401ba620, 0x2ad3: 0x401baa20, + 0x2ad4: 0x401bac20, 0x2ad5: 0x401bae20, 0x2ad6: 0x401bb020, 0x2ad7: 0x401bb220, + 0x2ad8: 0x401bb420, 0x2ad9: 0x401bb620, 0x2ada: 0x401bb820, 0x2adb: 0x401bba20, + 0x2adc: 0x401bbc20, 0x2add: 0x401bbe20, 0x2ade: 0x401bc020, 0x2adf: 0x401bc420, + 0x2ae0: 0x401bc620, 0x2ae1: 0x401b8c20, 0x2ae2: 0x401b9a20, 0x2ae3: 0x401ba820, + 0x2ae4: 0x401bc220, 0x2ae5: 0x401bc820, + 0x2af0: 0x401d7f20, 0x2af1: 0x401d8020, 0x2af2: 0x401d8120, 0x2af3: 0x401d8220, + 0x2af4: 0x401d8320, 0x2af5: 0x401d8420, 0x2af6: 0x401d8520, 0x2af7: 0x401d8620, + 0x2af8: 0x401d8720, 0x2af9: 0x401d8820, 0x2afa: 0x401d8920, 0x2afb: 0x401d8a20, + 0x2afc: 0x401d8b20, 0x2afd: 0x401d8c20, 0x2afe: 0x401d8d20, 0x2aff: 0x401d8e20, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x401d8f20, 0x2b01: 0x401d9020, 0x2b02: 0x401d9120, 0x2b03: 0x401d9220, + 0x2b04: 0x401d9320, 0x2b05: 0x401d9420, 0x2b06: 0x401d9520, 0x2b07: 0x401d9620, + 0x2b08: 0x401d9720, 0x2b09: 0x401d9820, 0x2b0a: 0x401d9920, 0x2b0b: 0x401d9a20, + 0x2b0c: 0x401d9b20, 0x2b0d: 0x401d9c20, 0x2b0e: 0x401d9d20, 0x2b0f: 0x401d9e20, + 0x2b10: 0x401d9f20, 0x2b11: 0x401da020, 0x2b12: 0x401da120, 0x2b13: 0x401da220, + 0x2b14: 0x401da320, 0x2b15: 0x401da420, 0x2b16: 0x401da520, 0x2b17: 0x401da620, + 0x2b18: 0x401da720, 0x2b19: 0x401da820, 0x2b1a: 0x401da920, 0x2b1b: 0x401daa20, + 0x2b1c: 0x401dab20, 0x2b1d: 0x401dac20, 0x2b1e: 0x401dad20, 0x2b1f: 0x401dae20, + 0x2b20: 0x401daf20, 0x2b21: 0x401db020, 0x2b22: 0x401db120, 0x2b23: 0x401db220, + 0x2b24: 0x401db320, 0x2b25: 0x401db420, + 0x2b2f: 0x401db520, + 0x2b30: 0x4002b720, + 0x2b3f: 0x80000000, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x401dc620, 0x2b41: 0x401ddb20, 0x2b42: 0x401dec20, 0x2b43: 0x401df520, + 0x2b44: 0x401e0420, 0x2b45: 0x401e2a20, 0x2b46: 0x401e3b20, 0x2b47: 0x401e4420, + 0x2b48: 0x401e5a20, 0x2b49: 0x401e6320, 0x2b4a: 0x401e6c20, 0x2b4b: 0x401e9d20, + 0x2b4c: 0x401ebc20, 0x2b4d: 0x401ecb20, 0x2b4e: 0x401ed420, 0x2b4f: 0x401ef620, + 0x2b50: 0x401eff20, 0x2b51: 0x401f0f20, 0x2b52: 0x401f3f20, 0x2b53: 0x401eea20, + 0x2b54: 0x401eeb20, 0x2b55: 0x401eec20, 0x2b56: 0x401eed20, + 0x2b60: 0x401f4320, 0x2b61: 0x401f4420, 0x2b62: 0x401f4520, 0x2b63: 0x401f4620, + 0x2b64: 0x401f4720, 0x2b65: 0x401f4820, 0x2b66: 0x401f4920, + 0x2b68: 0x401f4a20, 0x2b69: 0x401f4b20, 0x2b6a: 0x401f4c20, 0x2b6b: 0x401f4d20, + 0x2b6c: 0x401f4e20, 0x2b6d: 0x401f4f20, 0x2b6e: 0x401f5020, + 0x2b70: 0x401f5120, 0x2b71: 0x401f5220, 0x2b72: 0x401f5320, 0x2b73: 0x401f5420, + 0x2b74: 0x401f5520, 0x2b75: 0x401f5620, 0x2b76: 0x401f5720, + 0x2b78: 0x401f5820, 0x2b79: 0x401f5920, 0x2b7a: 0x401f5a20, 0x2b7b: 0x401f5b20, + 0x2b7c: 0x401f5c20, 0x2b7d: 0x401f5d20, 0x2b7e: 0x401f5e20, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x401f5f20, 0x2b81: 0x401f6020, 0x2b82: 0x401f6120, 0x2b83: 0x401f6220, + 0x2b84: 0x401f6320, 0x2b85: 0x401f6420, 0x2b86: 0x401f6520, + 0x2b88: 0x401f6620, 0x2b89: 0x401f6720, 0x2b8a: 0x401f6820, 0x2b8b: 0x401f6920, + 0x2b8c: 0x401f6a20, 0x2b8d: 0x401f6b20, 0x2b8e: 0x401f6c20, + 0x2b90: 0x401f6d20, 0x2b91: 0x401f6e20, 0x2b92: 0x401f6f20, 0x2b93: 0x401f7020, + 0x2b94: 0x401f7120, 0x2b95: 0x401f7220, 0x2b96: 0x401f7320, + 0x2b98: 0x401f7420, 0x2b99: 0x401f7520, 0x2b9a: 0x401f7620, 0x2b9b: 0x401f7720, + 0x2b9c: 0x401f7820, 0x2b9d: 0x401f7920, 0x2b9e: 0x401f7a20, + 0x2ba0: 0x0032b604, 0x2ba1: 0x0032be04, 0x2ba2: 0x0032c604, 0x2ba3: 0x0032ee04, + 0x2ba4: 0x00332e04, 0x2ba5: 0x00334804, 0x2ba6: 0x0033b404, 0x2ba7: 0x0033e804, + 0x2ba8: 0x00340c04, 0x2ba9: 0x00341e04, 0x2baa: 0x00345204, 0x2bab: 0x00347204, + 0x2bac: 0x00348c04, 0x2bad: 0x00349e04, 0x2bae: 0x0034b004, 0x2baf: 0x00351804, + 0x2bb0: 0x00356604, 0x2bb1: 0x00357c04, 0x2bb2: 0x0035c004, 0x2bb3: 0x0035ca04, + 0x2bb4: 0x00367004, 0x2bb5: 0xe000083d, 0x2bb6: 0x00328604, 0x2bb7: 0x00331604, + 0x2bb8: 0x0033b204, 0x2bb9: 0x00350604, 0x2bba: 0x00360204, 0x2bbb: 0x00361c04, + 0x2bbc: 0x00362604, 0x2bbd: 0x00363a04, 0x2bbe: 0x00364404, 0x2bbf: 0x00365804, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x40026120, 0x2bc1: 0x40026220, 0x2bc2: 0x40021320, 0x2bc3: 0x40021420, + 0x2bc4: 0x40021520, 0x2bc5: 0x40021620, 0x2bc6: 0x40026320, 0x2bc7: 0x40026420, + 0x2bc8: 0x40026520, 0x2bc9: 0x40021720, 0x2bca: 0x40021820, 0x2bcb: 0x40026620, + 0x2bcc: 0x40021920, 0x2bcd: 0x40021a20, 0x2bce: 0x40026720, 0x2bcf: 0x40026820, + 0x2bd0: 0x40026920, 0x2bd1: 0x40026a20, 0x2bd2: 0x40026b20, 0x2bd3: 0x40026c20, + 0x2bd4: 0x40026d20, 0x2bd5: 0x40026e20, 0x2bd6: 0x40026f20, 0x2bd7: 0x40011a20, + 0x2bd8: 0x40016a20, 0x2bd9: 0x4001cd20, 0x2bda: 0x40027020, 0x2bdb: 0x40027120, + 0x2bdc: 0x40021b20, 0x2bdd: 0x40021c20, 0x2bde: 0x40027220, 0x2bdf: 0x40027320, + 0x2be0: 0x40021d20, 0x2be1: 0x40021e20, 0x2be2: 0x40021f20, 0x2be3: 0x40022020, + 0x2be4: 0x40022120, 0x2be5: 0x40022220, 0x2be6: 0x40022320, 0x2be7: 0x40022420, + 0x2be8: 0x40022520, 0x2be9: 0x40022620, 0x2bea: 0x4001c720, 0x2beb: 0x4001c820, + 0x2bec: 0x4001c920, 0x2bed: 0x4001ca20, 0x2bee: 0x40015f20, 0x2bef: 0x401aea20, + 0x2bf0: 0x40017720, 0x2bf1: 0x40017d20, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0xe0001189, 0x2c01: 0xe000119e, 0x2c02: 0x029cb604, 0x2c03: 0x029cb404, + 0x2c04: 0xe000118c, 0x2c05: 0x029d7604, 0x2c06: 0xe000118f, 0x2c07: 0xe0001192, + 0x2c08: 0xe0001195, 0x2c09: 0x02a40404, 0x2c0a: 0xe0001198, 0x2c0b: 0xe000119b, + 0x2c0c: 0xe00011a1, 0x2c0d: 0xe00011a4, 0x2c0e: 0xe00011a7, 0x2c0f: 0x02b84604, + 0x2c10: 0x02b84404, 0x2c11: 0xe00011aa, 0x2c12: 0x02bbe604, 0x2c13: 0x02bcf404, + 0x2c14: 0x02bea204, 0x2c15: 0xe00011ad, 0x2c16: 0x02bf8804, 0x2c17: 0xe00011b0, + 0x2c18: 0x02c49804, 0x2c19: 0x02ca6a04, 0x2c1b: 0x02cbc204, + 0x2c1c: 0xe00011b3, 0x2c1d: 0xe00011b6, 0x2c1e: 0xe00011b9, 0x2c1f: 0xf0000004, + 0x2c20: 0x02d82204, 0x2c21: 0x02d86a04, 0x2c22: 0x02d87404, 0x2c23: 0x02e0d804, + 0x2c24: 0x02e45604, 0x2c25: 0xe00011bc, 0x2c26: 0x029c5804, 0x2c27: 0xe00011bf, + 0x2c28: 0x02e55a04, 0x2c29: 0xe00011c2, 0x2c2a: 0xe00011c5, 0x2c2b: 0xe00011c8, + 0x2c2c: 0xe00011cb, 0x2c2d: 0x02f27604, 0x2c2e: 0xe00011ce, 0x2c2f: 0x02f9f204, + 0x2c30: 0x02fd3e04, 0x2c31: 0x02fea604, 0x2c32: 0x02fea404, 0x2c33: 0xe00011d4, + 0x2c34: 0xe00011d7, 0x2c35: 0xe00011d1, 0x2c36: 0xe00011da, 0x2c37: 0xe00011dd, + 0x2c38: 0x02ff1604, 0x2c39: 0x03000404, 0x2c3a: 0x03010004, 0x2c3b: 0xe00011e0, + 0x2c3c: 0xe00011e3, 0x2c3d: 0xe00011e6, 0x2c3e: 0x0304f204, 0x2c3f: 0xe00011e9, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0xe00011ec, 0x2c41: 0x030c9c04, 0x2c42: 0x0310c804, 0x2c43: 0x03130004, + 0x2c44: 0x0312fe04, 0x2c45: 0x03138204, 0x2c46: 0x0313a404, 0x2c47: 0xe00011ef, + 0x2c48: 0x03174004, 0x2c49: 0x031a3a04, 0x2c4a: 0xe00011f2, 0x2c4b: 0x031ecc04, + 0x2c4c: 0x031f6c04, 0x2c4d: 0xe00011f5, 0x2c4e: 0xe00011f8, 0x2c4f: 0xe00011fb, + 0x2c50: 0x03290a04, 0x2c51: 0x032aee04, 0x2c52: 0x032af004, 0x2c53: 0x032afe04, + 0x2c54: 0x032bd004, 0x2c55: 0xe00011fe, 0x2c56: 0x032c3a04, 0x2c57: 0xe0001201, + 0x2c58: 0x032ea404, 0x2c59: 0x032fcc04, 0x2c5a: 0x0330ea04, 0x2c5b: 0x03319c04, + 0x2c5c: 0x0331bc04, 0x2c5d: 0x0331be04, 0x2c5e: 0xe0001204, 0x2c5f: 0x0331c004, + 0x2c60: 0x0332c604, 0x2c61: 0xe0001207, 0x2c62: 0x0334d804, 0x2c63: 0xe000120a, + 0x2c64: 0xe000120d, 0x2c65: 0x0338f804, 0x2c66: 0x033c3e04, 0x2c67: 0xe0001210, + 0x2c68: 0x033d4c04, 0x2c69: 0x033d8804, 0x2c6a: 0x033dfc04, 0x2c6b: 0xe0001213, + 0x2c6c: 0x033ea004, 0x2c6d: 0xe0001216, 0x2c6e: 0x033efe04, 0x2c6f: 0xe0001219, + 0x2c70: 0x033f3204, 0x2c71: 0xe000121c, 0x2c72: 0xe000121f, 0x2c73: 0xf0000004, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0xf0000004, 0x2c81: 0xf0000004, 0x2c82: 0xf0000004, 0x2c83: 0xf0000004, + 0x2c84: 0xf0000004, 0x2c85: 0xf0000004, 0x2c86: 0xf0000004, 0x2c87: 0xf0000004, + 0x2c88: 0xf0000004, 0x2c89: 0xf0000004, 0x2c8a: 0xf0000004, 0x2c8b: 0xf0000004, + 0x2c8c: 0xf0000004, 0x2c8d: 0xf0000004, 0x2c8e: 0xf0000004, 0x2c8f: 0xf0000004, + 0x2c90: 0xf0000004, 0x2c91: 0xf0000004, 0x2c92: 0xf0000004, 0x2c93: 0xf0000004, + 0x2c94: 0xf0000004, 0x2c95: 0xf0000004, 0x2c96: 0xf0000004, 0x2c97: 0xf0000004, + 0x2c98: 0xf0000004, 0x2c99: 0xf0000004, 0x2c9a: 0xf0000004, 0x2c9b: 0xf0000004, + 0x2c9c: 0xf0000004, 0x2c9d: 0xf0000004, 0x2c9e: 0xf0000004, 0x2c9f: 0xf0000004, + 0x2ca0: 0xf0000004, 0x2ca1: 0xf0000004, 0x2ca2: 0xf0000004, 0x2ca3: 0xf0000004, + 0x2ca4: 0xf0000004, 0x2ca5: 0xf0000004, 0x2ca6: 0xf0000004, 0x2ca7: 0xf0000004, + 0x2ca8: 0xf0000004, 0x2ca9: 0xf0000004, 0x2caa: 0xf0000004, 0x2cab: 0xf0000004, + 0x2cac: 0xf0000004, 0x2cad: 0xf0000004, 0x2cae: 0xf0000004, 0x2caf: 0xf0000004, + 0x2cb0: 0xf0000004, 0x2cb1: 0xf0000004, 0x2cb2: 0xf0000004, 0x2cb3: 0xf0000004, + 0x2cb4: 0xf0000004, 0x2cb5: 0xf0000004, 0x2cb6: 0xf0000004, 0x2cb7: 0xf0000004, + 0x2cb8: 0xf0000004, 0x2cb9: 0xf0000004, 0x2cba: 0xf0000004, 0x2cbb: 0xf0000004, + 0x2cbc: 0xf0000004, 0x2cbd: 0xf0000004, 0x2cbe: 0xf0000004, 0x2cbf: 0xf0000004, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0xf0000004, 0x2cc1: 0xf0000004, 0x2cc2: 0xf0000004, 0x2cc3: 0xf0000004, + 0x2cc4: 0xf0000004, 0x2cc5: 0xf0000004, 0x2cc6: 0xf0000004, 0x2cc7: 0xf0000004, + 0x2cc8: 0xf0000004, 0x2cc9: 0xf0000004, 0x2cca: 0xf0000004, 0x2ccb: 0xf0000004, + 0x2ccc: 0xf0000004, 0x2ccd: 0xf0000004, 0x2cce: 0xf0000004, 0x2ccf: 0xf0000004, + 0x2cd0: 0xf0000004, 0x2cd1: 0xf0000004, 0x2cd2: 0xf0000004, 0x2cd3: 0xf0000004, + 0x2cd4: 0xf0000004, 0x2cd5: 0xf0000004, + 0x2cf0: 0x40135620, 0x2cf1: 0x40135720, 0x2cf2: 0x40135820, 0x2cf3: 0x40135920, + 0x2cf4: 0x40135a20, 0x2cf5: 0x40135b20, 0x2cf6: 0x40135c20, 0x2cf7: 0x40135d20, + 0x2cf8: 0x40135e20, 0x2cf9: 0x40135f20, 0x2cfa: 0x40136020, 0x2cfb: 0x40136120, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0xf0000003, 0x2d01: 0x40012b20, 0x2d02: 0x40017b20, 0x2d03: 0x40025720, + 0x2d04: 0x40138620, 0x2d05: 0x40139b20, 0x2d06: 0xe0001159, 0x2d07: 0xe0000090, + 0x2d08: 0x40022720, 0x2d09: 0x40022820, 0x2d0a: 0x40022920, 0x2d0b: 0x40022a20, + 0x2d0c: 0x40022b20, 0x2d0d: 0x40022c20, 0x2d0e: 0x40022d20, 0x2d0f: 0x40022e20, + 0x2d10: 0x40022f20, 0x2d11: 0x40023020, 0x2d12: 0x40138720, 0x2d13: 0x40138820, + 0x2d14: 0x40023120, 0x2d15: 0x40023220, 0x2d16: 0x40023320, 0x2d17: 0x40023420, + 0x2d18: 0x40023520, 0x2d19: 0x40023620, 0x2d1a: 0x40023720, 0x2d1b: 0x40023820, + 0x2d1c: 0x40011b20, 0x2d1d: 0x4001e420, 0x2d1e: 0x4001e520, 0x2d1f: 0x4001e620, + 0x2d20: 0x40138920, 0x2d21: 0xe0000114, 0x2d22: 0xe00001fb, 0x2d23: 0xe00002c1, + 0x2d24: 0xe000037e, 0x2d25: 0xe0000438, 0x2d26: 0xe00004ef, 0x2d27: 0xe000058b, + 0x2d28: 0xe0000627, 0x2d29: 0xe00006c0, 0x2d2a: 0x80014802, 0x2d2b: 0x80014902, + 0x2d2c: 0x80014a02, 0x2d2d: 0x80014b02, 0x2d2e: 0x80014c02, 0x2d2f: 0x80014d02, + 0x2d30: 0x40011c20, 0x2d31: 0x40139d20, 0x2d32: 0xe000001b, 0x2d33: 0x40139e20, + 0x2d34: 0xe000001e, 0x2d35: 0x40139f20, 0x2d36: 0xf0000004, 0x2d37: 0x40138a20, + 0x2d38: 0xf0000004, 0x2d39: 0xf0000004, 0x2d3a: 0xf0000004, 0x2d3b: 0x40139c20, + 0x2d3c: 0xe000115c, 0x2d3d: 0x40025820, 0x2d3e: 0x40138b20, 0x2d3f: 0x40138c20, + // Block 0xb5, offset 0x2d40 + 0x2d41: 0x00632c0d, 0x2d42: 0x00632c0e, 0x2d43: 0x00632e0d, + 0x2d44: 0x00632e0e, 0x2d45: 0x0063300d, 0x2d46: 0x0063300e, 0x2d47: 0x0063340d, + 0x2d48: 0x0063340e, 0x2d49: 0x0063360d, 0x2d4a: 0x0063360e, 0x2d4b: 0x0063380e, + 0x2d4d: 0x00633a0e, 0x2d4f: 0x00633c0e, + 0x2d51: 0x00633e0e, 0x2d53: 0x0063400e, + 0x2d55: 0x0063420e, 0x2d57: 0x0063440e, + 0x2d59: 0x0063460e, 0x2d5b: 0x0063480e, + 0x2d5d: 0x00634a0e, 0x2d5f: 0x00634c0e, + 0x2d61: 0x00634e0e, 0x2d63: 0x0063500d, + 0x2d64: 0x0063500e, 0x2d66: 0x0063520e, + 0x2d68: 0x0063540e, 0x2d6a: 0x0063560e, 0x2d6b: 0x0063580e, + 0x2d6c: 0x00635a0e, 0x2d6d: 0x00635c0e, 0x2d6e: 0x00635e0e, 0x2d6f: 0x0063600e, + 0x2d72: 0x0063620e, + 0x2d75: 0x0063640e, + 0x2d78: 0x0063660e, 0x2d7b: 0x0063680e, + 0x2d7e: 0x00636a0e, 0x2d7f: 0x00636c0e, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x00636e0e, 0x2d81: 0x0063700e, 0x2d82: 0x0063720e, 0x2d83: 0x0063740d, + 0x2d84: 0x0063740e, 0x2d85: 0x0063760d, 0x2d86: 0x0063760e, 0x2d87: 0x00637a0d, + 0x2d88: 0x00637a0e, 0x2d89: 0x00637c0e, 0x2d8a: 0x00637e0e, 0x2d8b: 0x0063800e, + 0x2d8c: 0x0063820e, 0x2d8d: 0x0063840e, 0x2d8e: 0x0063860d, 0x2d8f: 0x0063860e, + 0x2d90: 0x0063880e, 0x2d91: 0x00638a0e, 0x2d92: 0x00638c0e, 0x2d93: 0x00638e0e, + 0x2d95: 0x0063380d, 0x2d96: 0x00633e0d, + 0x2d99: 0x80014e02, 0x2d9a: 0x80014f02, 0x2d9b: 0x40030d20, + 0x2d9c: 0x40030e20, 0x2d9d: 0x4013a020, 0x2d9f: 0xf0001616, + 0x2da0: 0x40011d20, 0x2da1: 0x00632c0f, 0x2da2: 0x00632c11, 0x2da3: 0x00632e0f, + 0x2da4: 0x00632e11, 0x2da5: 0x0063300f, 0x2da6: 0x00633011, 0x2da7: 0x0063340f, + 0x2da8: 0x00633411, 0x2da9: 0x0063360f, 0x2daa: 0x00633611, 0x2dab: 0x00633811, + 0x2dad: 0x00633a11, 0x2daf: 0x00633c11, + 0x2db1: 0x00633e11, 0x2db3: 0x00634011, + 0x2db5: 0x00634211, 0x2db7: 0x00634411, + 0x2db9: 0x00634611, 0x2dbb: 0x00634811, + 0x2dbd: 0x00634a11, 0x2dbf: 0x00634c11, + // Block 0xb7, offset 0x2dc0 + 0x2dc1: 0x00634e11, 0x2dc3: 0x0063500f, + 0x2dc4: 0x00635011, 0x2dc6: 0x00635211, + 0x2dc8: 0x00635411, 0x2dca: 0x00635611, 0x2dcb: 0x00635811, + 0x2dcc: 0x00635a11, 0x2dcd: 0x00635c11, 0x2dce: 0x00635e11, 0x2dcf: 0x00636011, + 0x2dd2: 0x00636211, + 0x2dd5: 0x00636411, + 0x2dd8: 0x00636611, 0x2ddb: 0x00636811, + 0x2dde: 0x00636a11, 0x2ddf: 0x00636c11, + 0x2de0: 0x00636e11, 0x2de1: 0x00637011, 0x2de2: 0x00637211, 0x2de3: 0x0063740f, + 0x2de4: 0x00637411, 0x2de5: 0x0063760f, 0x2de6: 0x00637611, 0x2de7: 0x00637a0f, + 0x2de8: 0x00637a11, 0x2de9: 0x00637c11, 0x2dea: 0x00637e11, 0x2deb: 0x00638011, + 0x2dec: 0x00638211, 0x2ded: 0x00638411, 0x2dee: 0x0063860f, 0x2def: 0x00638611, + 0x2df0: 0x00638811, 0x2df1: 0x00638a11, 0x2df2: 0x00638c11, 0x2df3: 0x00638e11, + 0x2df5: 0x0063380f, 0x2df6: 0x00633e0f, + 0x2dfb: 0x40011e20, + 0x2dfc: 0x4013a120, 0x2dfd: 0x4013a220, 0x2dff: 0xf0001616, + // Block 0xb8, offset 0x2e00 + 0x2e05: 0x4031c820, 0x2e06: 0x4031c920, 0x2e07: 0x4031ca20, + 0x2e08: 0x4031cb20, 0x2e09: 0x4031cd20, 0x2e0a: 0x4031ce20, 0x2e0b: 0x4031cf20, + 0x2e0c: 0x4031d020, 0x2e0d: 0x4031d120, 0x2e0e: 0x4031d220, 0x2e0f: 0x4031d520, + 0x2e10: 0x4031d620, 0x2e11: 0x4031d720, 0x2e12: 0x4031d820, 0x2e13: 0x4031da20, + 0x2e14: 0x4031db20, 0x2e15: 0x4031dc20, 0x2e16: 0x4031dd20, 0x2e17: 0x4031de20, + 0x2e18: 0x4031df20, 0x2e19: 0x4031e020, 0x2e1a: 0x4031e420, 0x2e1b: 0x4031e520, + 0x2e1c: 0x4031e720, 0x2e1d: 0x4031e820, 0x2e1e: 0x4031ea20, 0x2e1f: 0x4031eb20, + 0x2e20: 0x4031ec20, 0x2e21: 0x4031ed20, 0x2e22: 0x4031ee20, 0x2e23: 0x4031ef20, + 0x2e24: 0x4031f020, 0x2e25: 0x4031f220, 0x2e26: 0x4031f620, 0x2e27: 0x4031f720, + 0x2e28: 0x4031f820, 0x2e29: 0x4031f920, 0x2e2a: 0x4031cc20, 0x2e2b: 0x4031d320, + 0x2e2c: 0x4031d920, 0x2e2d: 0x4031fa20, + 0x2e31: 0xf0000004, 0x2e32: 0xf0000004, 0x2e33: 0xf0000004, + 0x2e34: 0xf0000004, 0x2e35: 0xf0000004, 0x2e36: 0xf0000004, 0x2e37: 0xf0000004, + 0x2e38: 0xf0000004, 0x2e39: 0xf0000004, 0x2e3a: 0xf0000004, 0x2e3b: 0xf0000004, + 0x2e3c: 0xf0000004, 0x2e3d: 0xf0000004, 0x2e3e: 0xf0000004, 0x2e3f: 0xf0000004, + // Block 0xb9, offset 0x2e40 + 0x2e40: 0xf0000004, 0x2e41: 0xf0000004, 0x2e42: 0xf0000004, 0x2e43: 0xf0000004, + 0x2e44: 0xf0000004, 0x2e45: 0xf0000004, 0x2e46: 0xf0000004, 0x2e47: 0xf0000004, + 0x2e48: 0xf0000004, 0x2e49: 0xf0000004, 0x2e4a: 0xf0000004, 0x2e4b: 0xf0000004, + 0x2e4c: 0xf0000004, 0x2e4d: 0xf0000004, 0x2e4e: 0xf0000004, + 0x2e50: 0x40138d20, 0x2e51: 0x40138e20, 0x2e52: 0xf0000014, 0x2e53: 0xf0000014, + 0x2e54: 0xf0000014, 0x2e55: 0xf0000014, 0x2e56: 0xf0000014, 0x2e57: 0xf0000014, + 0x2e58: 0xf0000014, 0x2e59: 0xf0000014, 0x2e5a: 0xf0000014, 0x2e5b: 0xf0000014, + 0x2e5c: 0xf0000014, 0x2e5d: 0xf0000014, 0x2e5e: 0xf0000014, 0x2e5f: 0xf0000014, + 0x2e60: 0xe000115f, 0x2e61: 0xe0001168, 0x2e62: 0xe0001165, 0x2e63: 0xe0001162, + 0x2e64: 0x4031e920, 0x2e65: 0xe0001171, 0x2e66: 0x4031e620, 0x2e67: 0xe000116e, + 0x2e68: 0xe0001183, 0x2e69: 0xe000116b, 0x2e6a: 0xe000117a, 0x2e6b: 0xe0001180, + 0x2e6c: 0x4031f520, 0x2e6d: 0x4031d420, 0x2e6e: 0xe0001174, 0x2e6f: 0xe0001177, + 0x2e70: 0x4031f320, 0x2e71: 0x4031f420, 0x2e72: 0x4031f120, 0x2e73: 0xe000117d, + 0x2e74: 0x00639219, 0x2e75: 0x00639c19, 0x2e76: 0x0063a419, 0x2e77: 0x0063aa19, + 0x2e78: 0x4031e120, 0x2e79: 0x4031e220, 0x2e7a: 0x4031e320, + // Block 0xba, offset 0x2e80 + 0x2e80: 0x40136220, 0x2e81: 0x40136320, 0x2e82: 0x40136420, 0x2e83: 0x40136520, + 0x2e84: 0x40136620, 0x2e85: 0x40136720, 0x2e86: 0x40136820, 0x2e87: 0x40136920, + 0x2e88: 0x40136a20, 0x2e89: 0x40136b20, 0x2e8a: 0x40136c20, 0x2e8b: 0x40136d20, + 0x2e8c: 0x40136e20, 0x2e8d: 0x40136f20, 0x2e8e: 0x40137020, 0x2e8f: 0x40137120, + 0x2e90: 0x40137220, 0x2e91: 0x40137320, 0x2e92: 0x40137420, 0x2e93: 0x40137520, + 0x2e94: 0x40137620, 0x2e95: 0x40137720, 0x2e96: 0x40137820, 0x2e97: 0x40137920, + 0x2e98: 0x40137a20, 0x2e99: 0x40137b20, 0x2e9a: 0x40137c20, 0x2e9b: 0x40137d20, + 0x2e9c: 0x40137e20, 0x2e9d: 0x40137f20, 0x2e9e: 0x40138020, 0x2e9f: 0x40138120, + 0x2ea0: 0x40138220, 0x2ea1: 0x40138320, 0x2ea2: 0x40138420, 0x2ea3: 0x40138520, + 0x2eb0: 0x00633c0f, 0x2eb1: 0x0063440f, 0x2eb2: 0x0063460f, 0x2eb3: 0x0063540f, + 0x2eb4: 0x00635a0f, 0x2eb5: 0x0063600f, 0x2eb6: 0x0063620f, 0x2eb7: 0x0063640f, + 0x2eb8: 0x0063660f, 0x2eb9: 0x0063680f, 0x2eba: 0x00636e0f, 0x2ebb: 0x00637c0f, + 0x2ebc: 0x00637e0f, 0x2ebd: 0x0063800f, 0x2ebe: 0x0063820f, 0x2ebf: 0x0063840f, + // Block 0xbb, offset 0x2ec0 + 0x2ec0: 0xf0000404, 0x2ec1: 0xf0000404, 0x2ec2: 0xf0000404, 0x2ec3: 0xf0000404, + 0x2ec4: 0xf0000404, 0x2ec5: 0xf0000404, 0x2ec6: 0xf0000404, 0x2ec7: 0xf0000404, + 0x2ec8: 0xf0000404, 0x2ec9: 0xf0000404, 0x2eca: 0xf0000404, 0x2ecb: 0xf0000404, + 0x2ecc: 0xf0000404, 0x2ecd: 0xf0000404, 0x2ece: 0xf0000404, 0x2ecf: 0xf0000404, + 0x2ed0: 0xf0000404, 0x2ed1: 0xf0000404, 0x2ed2: 0xf0000404, 0x2ed3: 0xf0000404, + 0x2ed4: 0xf0000404, 0x2ed5: 0xf0000404, 0x2ed6: 0xf0000404, 0x2ed7: 0xf0000404, + 0x2ed8: 0xf0000404, 0x2ed9: 0xf0000404, 0x2eda: 0xf0000404, 0x2edb: 0xf0000404, + 0x2edc: 0xf0000404, 0x2edd: 0xf0000404, 0x2ede: 0xf0000404, + 0x2ee0: 0xf0000404, 0x2ee1: 0xf0000404, 0x2ee2: 0xf0000404, 0x2ee3: 0xf0000404, + 0x2ee4: 0xf0000404, 0x2ee5: 0xf0000404, 0x2ee6: 0xf0000404, 0x2ee7: 0xf0000404, + 0x2ee8: 0xf0000404, 0x2ee9: 0xf0000404, 0x2eea: 0xf0000404, 0x2eeb: 0xf0000404, + 0x2eec: 0xf0000404, 0x2eed: 0xf0000404, 0x2eee: 0xf0000404, 0x2eef: 0xf0000404, + 0x2ef0: 0xf0000404, 0x2ef1: 0xf0000404, 0x2ef2: 0xf0000404, 0x2ef3: 0xf0000404, + 0x2ef4: 0xf0000404, 0x2ef5: 0xf0000404, 0x2ef6: 0xf0000404, 0x2ef7: 0xf0000404, + 0x2ef8: 0xf0000404, 0x2ef9: 0xf0000404, 0x2efa: 0xf0000404, 0x2efb: 0xf0000404, + 0x2efc: 0xf0000404, 0x2efd: 0xf0000404, 0x2efe: 0xf0000404, 0x2eff: 0xf0000404, + // Block 0xbc, offset 0x2f00 + 0x2f00: 0xf0000404, 0x2f01: 0xf0000404, 0x2f02: 0xf0000404, 0x2f03: 0xf0000404, + 0x2f04: 0xf0000006, 0x2f05: 0xf0000006, 0x2f06: 0xf0000006, 0x2f07: 0xf0000006, + 0x2f08: 0xe0000165, 0x2f09: 0xe0000246, 0x2f0a: 0xe0000309, 0x2f0b: 0xe00003c3, + 0x2f0c: 0xe000047a, 0x2f0d: 0xe0000516, 0x2f0e: 0xe00005b2, 0x2f0f: 0xe000064b, + 0x2f10: 0xf0001d1d, 0x2f11: 0xf0000606, 0x2f12: 0xf0000606, 0x2f13: 0xf0000606, + 0x2f14: 0xf0000606, 0x2f15: 0xf0000606, 0x2f16: 0xf0000606, 0x2f17: 0xf0000606, + 0x2f18: 0xf0000606, 0x2f19: 0xf0000606, 0x2f1a: 0xf0000606, 0x2f1b: 0xf0000606, + 0x2f1c: 0xf0000606, 0x2f1d: 0xf0000606, 0x2f1e: 0xf0000606, 0x2f1f: 0xf0000606, + 0x2f20: 0xf0000006, 0x2f21: 0xf0000006, 0x2f22: 0xf0000006, 0x2f23: 0xf0000006, + 0x2f24: 0xf0000006, 0x2f25: 0xf0000006, 0x2f26: 0xf0000006, 0x2f27: 0xf0000006, + 0x2f28: 0xf0000006, 0x2f29: 0xf0000006, 0x2f2a: 0xf0000006, 0x2f2b: 0xf0000006, + 0x2f2c: 0xf0000006, 0x2f2d: 0xf0000006, 0x2f2e: 0xf0000606, 0x2f2f: 0xf0000606, + 0x2f30: 0xf0000606, 0x2f31: 0xf0000606, 0x2f32: 0xf0000606, 0x2f33: 0xf0000606, + 0x2f34: 0xf0000606, 0x2f35: 0xf0000606, 0x2f36: 0xf0000606, 0x2f37: 0xf0000606, + 0x2f38: 0xf0000606, 0x2f39: 0xf0000606, 0x2f3a: 0xf0000606, 0x2f3b: 0xf0000606, + 0x2f3c: 0xf0000606, 0x2f3d: 0xf0000606, 0x2f3e: 0xf0000606, 0x2f3f: 0x40138f20, + // Block 0xbd, offset 0x2f40 + 0x2f40: 0xf0000006, 0x2f41: 0xf0000006, 0x2f42: 0xf0000006, 0x2f43: 0xf0000006, + 0x2f44: 0xf0000006, 0x2f45: 0xf0000006, 0x2f46: 0xf0000006, 0x2f47: 0xf0000006, + 0x2f48: 0xf0000006, 0x2f49: 0xf0000006, 0x2f4a: 0xf0000006, 0x2f4b: 0xf0000006, + 0x2f4c: 0xf0000006, 0x2f4d: 0xf0000006, 0x2f4e: 0xf0000006, 0x2f4f: 0xf0000006, + 0x2f50: 0xf0000006, 0x2f51: 0xf0000006, 0x2f52: 0xf0000006, 0x2f53: 0xf0000006, + 0x2f54: 0xf0000006, 0x2f55: 0xf0000006, 0x2f56: 0xf0000006, 0x2f57: 0xf0000006, + 0x2f58: 0xf0000006, 0x2f59: 0xf0000006, 0x2f5a: 0xf0000006, 0x2f5b: 0xf0000006, + 0x2f5c: 0xf0000006, 0x2f5d: 0xf0000006, 0x2f5e: 0xf0000006, 0x2f5f: 0xf0000006, + 0x2f60: 0xf0000006, 0x2f61: 0xf0000006, 0x2f62: 0xf0000006, 0x2f63: 0xf0000006, + 0x2f64: 0xf0000006, 0x2f65: 0xf0000006, 0x2f66: 0xf0000006, 0x2f67: 0xf0000006, + 0x2f68: 0xf0000006, 0x2f69: 0xf0000006, 0x2f6a: 0xf0000006, 0x2f6b: 0xf0000006, + 0x2f6c: 0xf0000006, 0x2f6d: 0xf0000006, 0x2f6e: 0xf0000006, 0x2f6f: 0xf0000006, + 0x2f70: 0xf0000006, 0x2f71: 0xf0000606, 0x2f72: 0xf0000606, 0x2f73: 0xf0000606, + 0x2f74: 0xf0000606, 0x2f75: 0xf0000606, 0x2f76: 0xf0000606, 0x2f77: 0xf0000606, + 0x2f78: 0xf0000606, 0x2f79: 0xf0000606, 0x2f7a: 0xf0000606, 0x2f7b: 0xf0000606, + 0x2f7c: 0xf0000606, 0x2f7d: 0xf0000606, 0x2f7e: 0xf0000606, 0x2f7f: 0xf0000606, + // Block 0xbe, offset 0x2f80 + 0x2f80: 0xf0000404, 0x2f81: 0xf0000404, 0x2f82: 0xf0000404, 0x2f83: 0xf0000404, + 0x2f84: 0xf0000404, 0x2f85: 0xf0000404, 0x2f86: 0xf0000404, 0x2f87: 0xf0000404, + 0x2f88: 0xf0000404, 0x2f89: 0xf0000404, 0x2f8a: 0xf0000404, 0x2f8b: 0xf0000404, + 0x2f8c: 0xf0001c1d, 0x2f8d: 0xf0001c1c, 0x2f8e: 0xf0001d1c, 0x2f8f: 0xf0001d1d, + 0x2f90: 0xf0000013, 0x2f91: 0xf0000013, 0x2f92: 0xf0000013, 0x2f93: 0xf0000013, + 0x2f94: 0xf0000013, 0x2f95: 0xf0000013, 0x2f96: 0xf0000013, 0x2f97: 0xf0000013, + 0x2f98: 0xf0000013, 0x2f99: 0xf0000013, 0x2f9a: 0xf0000013, 0x2f9b: 0xf0000013, + 0x2f9c: 0xf0000013, 0x2f9d: 0xf0000013, 0x2f9e: 0xf0000013, 0x2f9f: 0xf0000013, + 0x2fa0: 0xf0000013, 0x2fa1: 0xf0000013, 0x2fa2: 0xf0000013, 0x2fa3: 0xf0000013, + 0x2fa4: 0xf0000013, 0x2fa5: 0xf0000013, 0x2fa6: 0xf0000013, 0x2fa7: 0xf0000013, + 0x2fa8: 0xf0000013, 0x2fa9: 0xf0000013, 0x2faa: 0xf0000013, 0x2fab: 0xf0000013, + 0x2fac: 0xf0000013, 0x2fad: 0xf0000013, 0x2fae: 0xf0000013, 0x2faf: 0xf0000013, + 0x2fb0: 0xf0000013, 0x2fb1: 0xf0000013, 0x2fb2: 0xf0000013, 0x2fb3: 0xf0000013, + 0x2fb4: 0xf0000013, 0x2fb5: 0xf0000013, 0x2fb6: 0xf0000013, 0x2fb7: 0xf0000013, + 0x2fb8: 0xf0000013, 0x2fb9: 0xf0000013, 0x2fba: 0xf0000013, 0x2fbb: 0xf0000013, + 0x2fbc: 0xf0000013, 0x2fbd: 0xf0000013, 0x2fbe: 0xf0000013, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0xf0001c1c, 0x2fc1: 0xf0001c1c, 0x2fc2: 0xf0001c1c, 0x2fc3: 0xf0001c1c, + 0x2fc4: 0xf0001c1c, 0x2fc5: 0xf0001c1c, 0x2fc6: 0xf0001c1c, 0x2fc7: 0xf0001c1c, + 0x2fc8: 0xf0001c1c, 0x2fc9: 0xf0001c1c, 0x2fca: 0xf0001c1c, 0x2fcb: 0xf0001c1c, + 0x2fcc: 0xf0001c1c, 0x2fcd: 0xf0001c1c, 0x2fce: 0xf0001c1c, 0x2fcf: 0xf0001c1c, + 0x2fd0: 0xf0001c1c, 0x2fd1: 0xf0001c1c, 0x2fd2: 0xf0001c1c, 0x2fd3: 0xf0001c1c, + 0x2fd4: 0xf0001c1c, 0x2fd5: 0xf0001c1c, 0x2fd6: 0xf0001c1c, 0x2fd7: 0xf0001c1c, + 0x2fd8: 0xf0001c1c, 0x2fd9: 0xf0001c1c, 0x2fda: 0xf0001c1c, 0x2fdb: 0xf0001c1c, + 0x2fdc: 0xf0001c1c, 0x2fdd: 0xf0001c1c, 0x2fde: 0xf0001c1c, 0x2fdf: 0xf0001c1c, + 0x2fe0: 0xf0001c1c, 0x2fe1: 0xf0001c1c, 0x2fe2: 0xf0001c1c, 0x2fe3: 0xf0001c1c, + 0x2fe4: 0xf0001c1c, 0x2fe5: 0xf0001c1c, 0x2fe6: 0xf0001c1c, 0x2fe7: 0xf0001c1c, + 0x2fe8: 0xf0001c1c, 0x2fe9: 0xf0001c1c, 0x2fea: 0xf0001c1c, 0x2feb: 0xf0001c1c, + 0x2fec: 0xf0001c1c, 0x2fed: 0xf0001c1c, 0x2fee: 0xf0001c1c, 0x2fef: 0xf0001c1c, + 0x2ff0: 0xf0001c1c, 0x2ff1: 0xf0001c1c, 0x2ff2: 0xf0001c1c, 0x2ff3: 0xf0001c1c, + 0x2ff4: 0xf0001c1c, 0x2ff5: 0xf0001c1c, 0x2ff6: 0xf0001c1c, 0x2ff7: 0xf0001c1c, + 0x2ff8: 0xf0001c1c, 0x2ff9: 0xf0001c1c, 0x2ffa: 0xf0001c1c, 0x2ffb: 0xf0001c1c, + 0x2ffc: 0xf0001c1c, 0x2ffd: 0xf0001c1c, 0x2ffe: 0xf0001c1c, 0x2fff: 0xf0001c1c, + // Block 0xc0, offset 0x3000 + 0x3000: 0xf0001c1c, 0x3001: 0xf0001c1c, 0x3002: 0xf0001c1c, 0x3003: 0xf0001c1c, + 0x3004: 0xf0001c1c, 0x3005: 0xf0001c1c, 0x3006: 0xf0001c1c, 0x3007: 0xf0001c1c, + 0x3008: 0xf0001c1c, 0x3009: 0xf0001c1c, 0x300a: 0xf0001c1c, 0x300b: 0xf0001c1c, + 0x300c: 0xf0001c1c, 0x300d: 0xf0001c1c, 0x300e: 0xf0001c1c, 0x300f: 0xf0001c1c, + 0x3010: 0xf0001c1c, 0x3011: 0xf0001c1c, 0x3012: 0xf0001c1c, 0x3013: 0xf0001c1c, + 0x3014: 0xf0001c1c, 0x3015: 0xf0001c1c, 0x3016: 0xf0001c1c, 0x3017: 0xf0001c1c, + 0x3018: 0xf0000404, 0x3019: 0xf0000404, 0x301a: 0xf0000404, 0x301b: 0xf0000404, + 0x301c: 0xf0000404, 0x301d: 0xf0000404, 0x301e: 0xf0000404, 0x301f: 0xf0000404, + 0x3020: 0xf0000404, 0x3021: 0xf0000404, 0x3022: 0xf0000404, 0x3023: 0xf0000404, + 0x3024: 0xf0000404, 0x3025: 0xf0000404, 0x3026: 0xf0000404, 0x3027: 0xf0000404, + 0x3028: 0xf0000404, 0x3029: 0xf0000404, 0x302a: 0xf0000404, 0x302b: 0xf0000404, + 0x302c: 0xf0000404, 0x302d: 0xf0000404, 0x302e: 0xf0000404, 0x302f: 0xf0000404, + 0x3030: 0xf0000404, 0x3031: 0xf0001d1c, 0x3032: 0xf0001c1c, 0x3033: 0xf0001d1d, + 0x3034: 0xf0001c1c, 0x3035: 0xf0001d1c, 0x3036: 0xf0001c1c, 0x3037: 0xf0001c1c, + 0x3038: 0xf0001c1c, 0x3039: 0xf0001c1c, 0x303a: 0xf0001d1d, 0x303b: 0xf0001f1c, + 0x303c: 0xf0001f1c, 0x303d: 0xf0001f1c, 0x303e: 0xf0001f1c, 0x303f: 0xf0001f1c, + // Block 0xc1, offset 0x3040 + 0x3040: 0xf0001d1c, 0x3041: 0xf0001d1c, 0x3042: 0xf0001d1c, 0x3043: 0xf0001d1c, + 0x3044: 0xf0001d1c, 0x3045: 0xf0001d1d, 0x3046: 0xf0001d1d, 0x3047: 0xf0001d1d, + 0x3048: 0xf0001c1c, 0x3049: 0xf0001c1c, 0x304a: 0xf0001d1c, 0x304b: 0xf0001d1c, + 0x304c: 0xf0001d1c, 0x304d: 0xf0001c1c, 0x304e: 0xf0001c1c, 0x304f: 0xf0001c1c, + 0x3050: 0xf0001c1d, 0x3051: 0xf0001d1c, 0x3052: 0xf0001d1d, 0x3053: 0xf0001d1d, + 0x3054: 0xf0001d1d, 0x3055: 0xf0001c1c, 0x3056: 0xf0001c1c, 0x3057: 0xf0001c1c, + 0x3058: 0xf0001c1c, 0x3059: 0xf0001c1c, 0x305a: 0xf0001c1c, 0x305b: 0xf0001c1c, + 0x305c: 0xf0001c1c, 0x305d: 0xf0001c1c, 0x305e: 0xf0001c1c, 0x305f: 0xf0001c1c, + 0x3060: 0xf0001c1c, 0x3061: 0xf0001c1c, 0x3062: 0xf0001c1c, 0x3063: 0xf0001c1c, + 0x3064: 0xf0001c1c, 0x3065: 0xf0001c1c, 0x3066: 0xf0001c1c, 0x3067: 0xf0001c1c, + 0x3068: 0xf0001c1c, 0x3069: 0xf0001c1d, 0x306a: 0xf0001d1c, 0x306b: 0xf0001d1d, + 0x306c: 0xf0001d1d, 0x306d: 0xf0001c1c, 0x306e: 0xf0001c1c, 0x306f: 0xf0001c1c, + 0x3070: 0xf0001c1c, 0x3071: 0xf0001c1c, 0x3072: 0xf0001c1c, 0x3073: 0xf0001c1c, + 0x3074: 0xf0001d1c, 0x3075: 0xf0001d1c, 0x3076: 0xf0001d1c, 0x3077: 0xf0001d1c, + 0x3078: 0xf0001d1c, 0x3079: 0xf0001d1d, 0x307a: 0xf0001d1c, 0x307b: 0xf0001d1c, + 0x307c: 0xf0001d1c, 0x307d: 0xf0001d1c, 0x307e: 0xf0001d1c, 0x307f: 0xf0001d1d, + // Block 0xc2, offset 0x3080 + 0x3080: 0xf0001d1c, 0x3081: 0xf0001d1d, 0x3082: 0xf0001c1c, 0x3083: 0xf0001c1d, + 0x3084: 0xf0001c1c, 0x3085: 0xf0001c1c, 0x3086: 0xf0001c1d, 0x3087: 0xf0001c1d, + 0x3088: 0xf0001d1c, 0x3089: 0xf0001c1d, 0x308a: 0xf0001c1c, 0x308b: 0xf0001d1d, + 0x308c: 0xf0001c1c, 0x308d: 0xf0001d1d, 0x308e: 0xf0001d1d, 0x308f: 0xf0001c1c, + 0x3090: 0xf0001c1c, 0x3091: 0xf0001c1c, 0x3092: 0xf0001c1c, 0x3093: 0xf0001c1c, + 0x3094: 0xf0001c1c, 0x3095: 0xf0001c1c, 0x3096: 0xf0001c1c, 0x3097: 0xf0001d1d, + 0x3098: 0xf0001c1c, 0x3099: 0xf0001d1d, 0x309a: 0xf0001d1d, 0x309b: 0xf0001c1c, + 0x309c: 0xf0001c1d, 0x309d: 0xf0001c1d, 0x309e: 0xf0001c1d, 0x309f: 0xf0001c1d, + 0x30a0: 0xf0000404, 0x30a1: 0xf0000404, 0x30a2: 0xf0000404, 0x30a3: 0xf0000404, + 0x30a4: 0xf0000404, 0x30a5: 0xf0000404, 0x30a6: 0xf0000404, 0x30a7: 0xf0000404, + 0x30a8: 0xf0000404, 0x30a9: 0xf0000404, 0x30aa: 0xf0000404, 0x30ab: 0xf0000404, + 0x30ac: 0xf0000404, 0x30ad: 0xf0000404, 0x30ae: 0xf0000404, 0x30af: 0xf0000404, + 0x30b0: 0xf0000404, 0x30b1: 0xf0000404, 0x30b2: 0xf0000404, 0x30b3: 0xf0000404, + 0x30b4: 0xf0000404, 0x30b5: 0xf0000404, 0x30b6: 0xf0000404, 0x30b7: 0xf0000404, + 0x30b8: 0xf0000404, 0x30b9: 0xf0000404, 0x30ba: 0xf0000404, 0x30bb: 0xf0000404, + 0x30bc: 0xf0000404, 0x30bd: 0xf0000404, 0x30be: 0xf0000404, 0x30bf: 0xf0001c1c, + // Block 0xc3, offset 0x30c0 + 0x30c0: 0x400c7b20, 0x30c1: 0x400c7c20, 0x30c2: 0x400c7d20, 0x30c3: 0x400c7e20, + 0x30c4: 0x400c7f20, 0x30c5: 0x400c8020, 0x30c6: 0x400c8120, 0x30c7: 0x400c8220, + 0x30c8: 0x400c8320, 0x30c9: 0x400c8420, 0x30ca: 0x400c8520, 0x30cb: 0x400c8620, + 0x30cc: 0x400c8720, 0x30cd: 0x400c8820, 0x30ce: 0x400c8920, 0x30cf: 0x400c8a20, + 0x30d0: 0x400c8b20, 0x30d1: 0x400c8c20, 0x30d2: 0x400c8d20, 0x30d3: 0x400c8e20, + 0x30d4: 0x400c8f20, 0x30d5: 0x400c9020, 0x30d6: 0x400c9120, 0x30d7: 0x400c9220, + 0x30d8: 0x400c9320, 0x30d9: 0x400c9420, 0x30da: 0x400c9520, 0x30db: 0x400c9620, + 0x30dc: 0x400c9720, 0x30dd: 0x400c9820, 0x30de: 0x400c9920, 0x30df: 0x400c9a20, + 0x30e0: 0x400c9b20, 0x30e1: 0x400c9c20, 0x30e2: 0x400c9d20, 0x30e3: 0x400c9e20, + 0x30e4: 0x400c9f20, 0x30e5: 0x400ca020, 0x30e6: 0x400ca120, 0x30e7: 0x400ca220, + 0x30e8: 0x400ca320, 0x30e9: 0x400ca420, 0x30ea: 0x400ca520, 0x30eb: 0x400ca620, + 0x30ec: 0x400ca720, 0x30ed: 0x400ca820, 0x30ee: 0x400ca920, 0x30ef: 0x400caa20, + 0x30f0: 0x400cab20, 0x30f1: 0x400cac20, 0x30f2: 0x400cad20, 0x30f3: 0x400cae20, + 0x30f4: 0x400caf20, 0x30f5: 0x400cb020, 0x30f6: 0x400cb120, 0x30f7: 0x400cb220, + 0x30f8: 0x400cb320, 0x30f9: 0x400cb420, 0x30fa: 0x400cb520, 0x30fb: 0x400cb620, + 0x30fc: 0x400cb720, 0x30fd: 0x400cb820, 0x30fe: 0x400cb920, 0x30ff: 0x400cba20, + // Block 0xc4, offset 0x3100 + 0x3100: 0x4031fb20, 0x3101: 0x4031fc20, 0x3102: 0x4031fd20, 0x3103: 0x4031fe20, + 0x3104: 0x4031ff20, 0x3105: 0x40320020, 0x3106: 0x40320120, 0x3107: 0x40320220, + 0x3108: 0x40320320, 0x3109: 0x40320420, 0x310a: 0x40320520, 0x310b: 0x40320620, + 0x310c: 0x40320720, 0x310d: 0x40320820, 0x310e: 0x40320920, 0x310f: 0x40320a20, + 0x3110: 0x40320b20, 0x3111: 0x40320c20, 0x3112: 0x40320d20, 0x3113: 0x40320e20, + 0x3114: 0x40320f20, 0x3115: 0x40321020, 0x3116: 0x40321120, 0x3117: 0x40321220, + 0x3118: 0x40321320, 0x3119: 0x40321420, 0x311a: 0x40321520, 0x311b: 0x40321620, + 0x311c: 0x40321720, 0x311d: 0x40321820, 0x311e: 0x40321920, 0x311f: 0x40321a20, + 0x3120: 0x40321b20, 0x3121: 0x40321c20, 0x3122: 0x40321d20, 0x3123: 0x40321e20, + 0x3124: 0x40321f20, 0x3125: 0x40322020, 0x3126: 0x40322120, 0x3127: 0x40322220, + 0x3128: 0x40322320, 0x3129: 0x40322420, 0x312a: 0x40322520, 0x312b: 0x40322620, + 0x312c: 0x40322720, 0x312d: 0x40322820, 0x312e: 0x40322920, 0x312f: 0x40322a20, + 0x3130: 0x40322b20, 0x3131: 0x40322c20, 0x3132: 0x40322d20, 0x3133: 0x40322e20, + 0x3134: 0x40322f20, 0x3135: 0x40323020, 0x3136: 0x40323120, 0x3137: 0x40323220, + 0x3138: 0x40323320, 0x3139: 0x40323420, 0x313a: 0x40323520, 0x313b: 0x40323620, + 0x313c: 0x40323720, 0x313d: 0x40323820, 0x313e: 0x40323920, 0x313f: 0x40323a20, + // Block 0xc5, offset 0x3140 + 0x3140: 0x40323b20, 0x3141: 0x40323c20, 0x3142: 0x40323d20, 0x3143: 0x40323e20, + 0x3144: 0x40323f20, 0x3145: 0x40324020, 0x3146: 0x40324120, 0x3147: 0x40324220, + 0x3148: 0x40324320, 0x3149: 0x40324420, 0x314a: 0x40324520, 0x314b: 0x40324620, + 0x314c: 0x40324720, 0x314d: 0x40324820, 0x314e: 0x40324920, 0x314f: 0x40324a20, + 0x3150: 0x40324b20, 0x3151: 0x40324c20, 0x3152: 0x40324d20, 0x3153: 0x40324e20, + 0x3154: 0x40324f20, 0x3155: 0x40325020, 0x3156: 0x40325120, 0x3157: 0x40325220, + 0x3158: 0x40325320, 0x3159: 0x40325420, 0x315a: 0x40325520, 0x315b: 0x40325620, + 0x315c: 0x40325720, 0x315d: 0x40325820, 0x315e: 0x40325920, 0x315f: 0x40325a20, + 0x3160: 0x40325b20, 0x3161: 0x40325c20, 0x3162: 0x40325d20, 0x3163: 0x40325e20, + 0x3164: 0x40325f20, 0x3165: 0x40326020, 0x3166: 0x40326120, 0x3167: 0x40326220, + 0x3168: 0x40326320, 0x3169: 0x40326420, 0x316a: 0x40326520, 0x316b: 0x40326620, + 0x316c: 0x40326720, 0x316d: 0x40326820, 0x316e: 0x40326920, 0x316f: 0x40326a20, + 0x3170: 0x40326b20, 0x3171: 0x40326c20, 0x3172: 0x40326d20, 0x3173: 0x40326e20, + 0x3174: 0x40326f20, 0x3175: 0x40327020, 0x3176: 0x40327120, 0x3177: 0x40327220, + 0x3178: 0x40327320, 0x3179: 0x40327420, 0x317a: 0x40327520, 0x317b: 0x40327620, + 0x317c: 0x40327720, 0x317d: 0x40327820, 0x317e: 0x40327920, 0x317f: 0x40327a20, + // Block 0xc6, offset 0x3180 + 0x3180: 0x40327b20, 0x3181: 0x40327c20, 0x3182: 0x40327d20, 0x3183: 0x40327e20, + 0x3184: 0x40327f20, 0x3185: 0x40328020, 0x3186: 0x40328120, 0x3187: 0x40328220, + 0x3188: 0x40328320, 0x3189: 0x40328420, 0x318a: 0x40328520, 0x318b: 0x40328620, + 0x318c: 0x40328720, 0x318d: 0x40328820, 0x318e: 0x40328920, 0x318f: 0x40328a20, + 0x3190: 0x40328b20, 0x3191: 0x40328c20, 0x3192: 0x40328d20, 0x3193: 0x40328e20, + 0x3194: 0x40328f20, 0x3195: 0x40329020, 0x3196: 0x40329120, 0x3197: 0x40329220, + 0x3198: 0x40329320, 0x3199: 0x40329420, 0x319a: 0x40329520, 0x319b: 0x40329620, + 0x319c: 0x40329720, 0x319d: 0x40329820, 0x319e: 0x40329920, 0x319f: 0x40329a20, + 0x31a0: 0x40329b20, 0x31a1: 0x40329c20, 0x31a2: 0x40329d20, 0x31a3: 0x40329e20, + 0x31a4: 0x40329f20, 0x31a5: 0x4032a020, 0x31a6: 0x4032a120, 0x31a7: 0x4032a220, + 0x31a8: 0x4032a320, 0x31a9: 0x4032a420, 0x31aa: 0x4032a520, 0x31ab: 0x4032a620, + 0x31ac: 0x4032a720, 0x31ad: 0x4032a820, 0x31ae: 0x4032a920, 0x31af: 0x4032aa20, + 0x31b0: 0x4032ab20, 0x31b1: 0x4032ac20, 0x31b2: 0x4032ad20, 0x31b3: 0x4032ae20, + 0x31b4: 0x4032af20, 0x31b5: 0x4032b020, 0x31b6: 0x4032b120, 0x31b7: 0x4032b220, + 0x31b8: 0x4032b320, 0x31b9: 0x4032b420, 0x31ba: 0x4032b520, 0x31bb: 0x4032b620, + 0x31bc: 0x4032b720, 0x31bd: 0x4032b820, 0x31be: 0x4032b920, 0x31bf: 0x4032ba20, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x4032bb20, 0x31c1: 0x4032bc20, 0x31c2: 0x4032bd20, 0x31c3: 0x4032be20, + 0x31c4: 0x4032bf20, 0x31c5: 0x4032c020, 0x31c6: 0x4032c120, 0x31c7: 0x4032c220, + 0x31c8: 0x4032c320, 0x31c9: 0x4032c420, 0x31ca: 0x4032c520, 0x31cb: 0x4032c620, + 0x31cc: 0x4032c720, 0x31cd: 0x4032c820, 0x31ce: 0x4032c920, 0x31cf: 0x4032ca20, + 0x31d0: 0x4032cb20, 0x31d1: 0x4032cc20, 0x31d2: 0x4032cd20, 0x31d3: 0x4032ce20, + 0x31d4: 0x4032cf20, 0x31d5: 0x4032d020, 0x31d6: 0x4032d120, 0x31d7: 0x4032d220, + 0x31d8: 0x4032d320, 0x31d9: 0x4032d420, 0x31da: 0x4032d520, 0x31db: 0x4032d620, + 0x31dc: 0x4032d720, 0x31dd: 0x4032d820, 0x31de: 0x4032d920, 0x31df: 0x4032da20, + 0x31e0: 0x4032db20, 0x31e1: 0x4032dc20, 0x31e2: 0x4032dd20, 0x31e3: 0x4032de20, + 0x31e4: 0x4032df20, 0x31e5: 0x4032e020, 0x31e6: 0x4032e120, 0x31e7: 0x4032e220, + 0x31e8: 0x4032e320, 0x31e9: 0x4032e420, 0x31ea: 0x4032e520, 0x31eb: 0x4032e620, + 0x31ec: 0x4032e720, 0x31ed: 0x4032e820, 0x31ee: 0x4032e920, 0x31ef: 0x4032ea20, + 0x31f0: 0x4032eb20, 0x31f1: 0x4032ec20, 0x31f2: 0x4032ed20, 0x31f3: 0x4032ee20, + 0x31f4: 0x4032ef20, 0x31f5: 0x4032f020, 0x31f6: 0x4032f120, 0x31f7: 0x4032f220, + 0x31f8: 0x4032f320, 0x31f9: 0x4032f420, 0x31fa: 0x4032f520, 0x31fb: 0x4032f620, + 0x31fc: 0x4032f720, 0x31fd: 0x4032f820, 0x31fe: 0x4032f920, 0x31ff: 0x4032fa20, + // Block 0xc8, offset 0x3200 + 0x3200: 0x4032fb20, 0x3201: 0x4032fc20, 0x3202: 0x4032fd20, 0x3203: 0x4032fe20, + 0x3204: 0x4032ff20, 0x3205: 0x40330020, 0x3206: 0x40330120, 0x3207: 0x40330220, + 0x3208: 0x40330320, 0x3209: 0x40330420, 0x320a: 0x40330520, 0x320b: 0x40330620, + 0x320c: 0x40330720, 0x320d: 0x40330820, 0x320e: 0x40330920, 0x320f: 0x40330a20, + 0x3210: 0x40330b20, 0x3211: 0x40330c20, 0x3212: 0x40330d20, 0x3213: 0x40330e20, + 0x3214: 0x40330f20, 0x3215: 0x40331020, 0x3216: 0x40331120, 0x3217: 0x40331220, + 0x3218: 0x40331320, 0x3219: 0x40331420, 0x321a: 0x40331520, 0x321b: 0x40331620, + 0x321c: 0x40331720, 0x321d: 0x40331820, 0x321e: 0x40331920, 0x321f: 0x40331a20, + 0x3220: 0x40331b20, 0x3221: 0x40331c20, 0x3222: 0x40331d20, 0x3223: 0x40331e20, + 0x3224: 0x40331f20, 0x3225: 0x40332020, 0x3226: 0x40332120, 0x3227: 0x40332220, + 0x3228: 0x40332320, 0x3229: 0x40332420, 0x322a: 0x40332520, 0x322b: 0x40332620, + 0x322c: 0x40332720, 0x322d: 0x40332820, 0x322e: 0x40332920, 0x322f: 0x40332a20, + 0x3230: 0x40332b20, 0x3231: 0x40332c20, 0x3232: 0x40332d20, 0x3233: 0x40332e20, + 0x3234: 0x40332f20, 0x3235: 0x40333020, 0x3236: 0x40333120, 0x3237: 0x40333220, + 0x3238: 0x40333320, 0x3239: 0x40333420, 0x323a: 0x40333520, 0x323b: 0x40333620, + 0x323c: 0x40333720, 0x323d: 0x40333820, 0x323e: 0x40333920, 0x323f: 0x40333a20, + // Block 0xc9, offset 0x3240 + 0x3240: 0x40333b20, 0x3241: 0x40333c20, 0x3242: 0x40333d20, 0x3243: 0x40333e20, + 0x3244: 0x40333f20, 0x3245: 0x40334020, 0x3246: 0x40334120, 0x3247: 0x40334220, + 0x3248: 0x40334320, 0x3249: 0x40334420, 0x324a: 0x40334520, 0x324b: 0x40334620, + 0x324c: 0x40334720, 0x324d: 0x40334820, 0x324e: 0x40334920, 0x324f: 0x40334a20, + 0x3250: 0x40334b20, 0x3251: 0x40334c20, 0x3252: 0x40334d20, 0x3253: 0x40334e20, + 0x3254: 0x40334f20, 0x3255: 0x40335020, 0x3256: 0x40335120, 0x3257: 0x40335220, + 0x3258: 0x40335320, 0x3259: 0x40335420, 0x325a: 0x40335520, 0x325b: 0x40335620, + 0x325c: 0x40335720, 0x325d: 0x40335820, 0x325e: 0x40335920, 0x325f: 0x40335a20, + 0x3260: 0x40335b20, 0x3261: 0x40335c20, 0x3262: 0x40335d20, 0x3263: 0x40335e20, + 0x3264: 0x40335f20, 0x3265: 0x40336020, 0x3266: 0x40336120, 0x3267: 0x40336220, + 0x3268: 0x40336320, 0x3269: 0x40336420, 0x326a: 0x40336520, 0x326b: 0x40336620, + 0x326c: 0x40336720, 0x326d: 0x40336820, 0x326e: 0x40336920, 0x326f: 0x40336a20, + 0x3270: 0x40336b20, 0x3271: 0x40336c20, 0x3272: 0x40336d20, 0x3273: 0x40336e20, + 0x3274: 0x40336f20, 0x3275: 0x40337020, 0x3276: 0x40337120, 0x3277: 0x40337220, + 0x3278: 0x40337320, 0x3279: 0x40337420, 0x327a: 0x40337520, 0x327b: 0x40337620, + 0x327c: 0x40337720, 0x327d: 0x40337820, 0x327e: 0x40337920, 0x327f: 0x40337a20, + // Block 0xca, offset 0x3280 + 0x3280: 0x40337b20, 0x3281: 0x40337c20, 0x3282: 0x40337d20, 0x3283: 0x40337e20, + 0x3284: 0x40337f20, 0x3285: 0x40338020, 0x3286: 0x40338120, 0x3287: 0x40338220, + 0x3288: 0x40338320, 0x3289: 0x40338420, 0x328a: 0x40338520, 0x328b: 0x40338620, + 0x328c: 0x40338720, 0x328d: 0x40338820, 0x328e: 0x40338920, 0x328f: 0x40338a20, + 0x3290: 0x40338b20, 0x3291: 0x40338c20, 0x3292: 0x40338d20, 0x3293: 0x40338e20, + 0x3294: 0x40338f20, 0x3295: 0x40339020, 0x3296: 0x40339120, 0x3297: 0x40339220, + 0x3298: 0x40339320, 0x3299: 0x40339420, 0x329a: 0x40339520, 0x329b: 0x40339620, + 0x329c: 0x40339720, 0x329d: 0x40339820, 0x329e: 0x40339920, 0x329f: 0x40339a20, + 0x32a0: 0x40339b20, 0x32a1: 0x40339c20, 0x32a2: 0x40339d20, 0x32a3: 0x40339e20, + 0x32a4: 0x40339f20, 0x32a5: 0x4033a020, 0x32a6: 0x4033a120, 0x32a7: 0x4033a220, + 0x32a8: 0x4033a320, 0x32a9: 0x4033a420, 0x32aa: 0x4033a520, 0x32ab: 0x4033a620, + 0x32ac: 0x4033a720, 0x32ad: 0x4033a820, 0x32ae: 0x4033a920, 0x32af: 0x4033aa20, + 0x32b0: 0x4033ab20, 0x32b1: 0x4033ac20, 0x32b2: 0x4033ad20, 0x32b3: 0x4033ae20, + 0x32b4: 0x4033af20, 0x32b5: 0x4033b020, 0x32b6: 0x4033b120, 0x32b7: 0x4033b220, + 0x32b8: 0x4033b320, 0x32b9: 0x4033b420, 0x32ba: 0x4033b520, 0x32bb: 0x4033b620, + 0x32bc: 0x4033b720, 0x32bd: 0x4033b820, 0x32be: 0x4033b920, 0x32bf: 0x4033ba20, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x4033bb20, 0x32c1: 0x4033bc20, 0x32c2: 0x4033bd20, 0x32c3: 0x4033be20, + 0x32c4: 0x4033bf20, 0x32c5: 0x4033c020, 0x32c6: 0x4033c120, 0x32c7: 0x4033c220, + 0x32c8: 0x4033c320, 0x32c9: 0x4033c420, 0x32ca: 0x4033c520, 0x32cb: 0x4033c620, + 0x32cc: 0x4033c720, 0x32cd: 0x4033c820, 0x32ce: 0x4033c920, 0x32cf: 0x4033ca20, + 0x32d0: 0x4033cb20, 0x32d1: 0x4033cc20, 0x32d2: 0x4033cd20, 0x32d3: 0x4033ce20, + 0x32d4: 0x4033cf20, 0x32d5: 0x4033d020, 0x32d6: 0x4033d120, 0x32d7: 0x4033d220, + 0x32d8: 0x4033d320, 0x32d9: 0x4033d420, 0x32da: 0x4033d520, 0x32db: 0x4033d620, + 0x32dc: 0x4033d720, 0x32dd: 0x4033d820, 0x32de: 0x4033d920, 0x32df: 0x4033da20, + 0x32e0: 0x4033db20, 0x32e1: 0x4033dc20, 0x32e2: 0x4033dd20, 0x32e3: 0x4033de20, + 0x32e4: 0x4033df20, 0x32e5: 0x4033e020, 0x32e6: 0x4033e120, 0x32e7: 0x4033e220, + 0x32e8: 0x4033e320, 0x32e9: 0x4033e420, 0x32ea: 0x4033e520, 0x32eb: 0x4033e620, + 0x32ec: 0x4033e720, 0x32ed: 0x4033e820, 0x32ee: 0x4033e920, 0x32ef: 0x4033ea20, + 0x32f0: 0x4033eb20, 0x32f1: 0x4033ec20, 0x32f2: 0x4033ed20, 0x32f3: 0x4033ee20, + 0x32f4: 0x4033ef20, 0x32f5: 0x4033f020, 0x32f6: 0x4033f120, 0x32f7: 0x4033f220, + 0x32f8: 0x4033f320, 0x32f9: 0x4033f420, 0x32fa: 0x4033f520, 0x32fb: 0x4033f620, + 0x32fc: 0x4033f720, 0x32fd: 0x4033f820, 0x32fe: 0x4033f920, 0x32ff: 0x4033fa20, + // Block 0xcc, offset 0x3300 + 0x3300: 0x4033fb20, 0x3301: 0x4033fc20, 0x3302: 0x4033fd20, 0x3303: 0x4033fe20, + 0x3304: 0x4033ff20, 0x3305: 0x40340020, 0x3306: 0x40340120, 0x3307: 0x40340220, + 0x3308: 0x40340320, 0x3309: 0x40340420, 0x330a: 0x40340520, 0x330b: 0x40340620, + 0x330c: 0x40340720, 0x330d: 0x40340820, 0x330e: 0x40340920, 0x330f: 0x40340a20, + 0x3310: 0x40340b20, 0x3311: 0x40340c20, 0x3312: 0x40340d20, 0x3313: 0x40340e20, + 0x3314: 0x40340f20, 0x3315: 0x40341020, 0x3316: 0x40341120, 0x3317: 0x40341220, + 0x3318: 0x40341320, 0x3319: 0x40341420, 0x331a: 0x40341520, 0x331b: 0x40341620, + 0x331c: 0x40341720, 0x331d: 0x40341820, 0x331e: 0x40341920, 0x331f: 0x40341a20, + 0x3320: 0x40341b20, 0x3321: 0x40341c20, 0x3322: 0x40341d20, 0x3323: 0x40341e20, + 0x3324: 0x40341f20, 0x3325: 0x40342020, 0x3326: 0x40342120, 0x3327: 0x40342220, + 0x3328: 0x40342320, 0x3329: 0x40342420, 0x332a: 0x40342520, 0x332b: 0x40342620, + 0x332c: 0x40342720, 0x332d: 0x40342820, 0x332e: 0x40342920, 0x332f: 0x40342a20, + 0x3330: 0x40342b20, 0x3331: 0x40342c20, 0x3332: 0x40342d20, 0x3333: 0x40342e20, + 0x3334: 0x40342f20, 0x3335: 0x40343020, 0x3336: 0x40343120, 0x3337: 0x40343220, + 0x3338: 0x40343320, 0x3339: 0x40343420, 0x333a: 0x40343520, 0x333b: 0x40343620, + 0x333c: 0x40343720, 0x333d: 0x40343820, 0x333e: 0x40343920, 0x333f: 0x40343a20, + // Block 0xcd, offset 0x3340 + 0x3340: 0x40343b20, 0x3341: 0x40343c20, 0x3342: 0x40343d20, 0x3343: 0x40343e20, + 0x3344: 0x40343f20, 0x3345: 0x40344020, 0x3346: 0x40344120, 0x3347: 0x40344220, + 0x3348: 0x40344320, 0x3349: 0x40344420, 0x334a: 0x40344520, 0x334b: 0x40344620, + 0x334c: 0x40344720, 0x334d: 0x40344820, 0x334e: 0x40344920, 0x334f: 0x40344a20, + 0x3350: 0x40344b20, 0x3351: 0x40344c20, 0x3352: 0x40344d20, 0x3353: 0x40344e20, + 0x3354: 0x40344f20, 0x3355: 0x40345020, 0x3356: 0x40345120, 0x3357: 0x40345220, + 0x3358: 0x40345320, 0x3359: 0x40345420, 0x335a: 0x40345520, 0x335b: 0x40345620, + 0x335c: 0x40345720, 0x335d: 0x40345820, 0x335e: 0x40345920, 0x335f: 0x40345a20, + 0x3360: 0x40345b20, 0x3361: 0x40345c20, 0x3362: 0x40345d20, 0x3363: 0x40345e20, + 0x3364: 0x40345f20, 0x3365: 0x40346020, 0x3366: 0x40346120, 0x3367: 0x40346220, + 0x3368: 0x40346320, 0x3369: 0x40346420, 0x336a: 0x40346520, 0x336b: 0x40346620, + 0x336c: 0x40346720, 0x336d: 0x40346820, 0x336e: 0x40346920, 0x336f: 0x40346a20, + 0x3370: 0x40346b20, 0x3371: 0x40346c20, 0x3372: 0x40346d20, 0x3373: 0x40346e20, + 0x3374: 0x40346f20, 0x3375: 0x40347020, 0x3376: 0x40347120, 0x3377: 0x40347220, + 0x3378: 0x40347320, 0x3379: 0x40347420, 0x337a: 0x40347520, 0x337b: 0x40347620, + 0x337c: 0x40347720, 0x337d: 0x40347820, 0x337e: 0x40347920, 0x337f: 0x40347a20, + // Block 0xce, offset 0x3380 + 0x3380: 0x40347b20, 0x3381: 0x40347c20, 0x3382: 0x40347d20, 0x3383: 0x40347e20, + 0x3384: 0x40347f20, 0x3385: 0x40348020, 0x3386: 0x40348120, 0x3387: 0x40348220, + 0x3388: 0x40348320, 0x3389: 0x40348420, 0x338a: 0x40348520, 0x338b: 0x40348620, + 0x338c: 0x40348720, 0x338d: 0x40348820, 0x338e: 0x40348920, 0x338f: 0x40348a20, + 0x3390: 0x40348b20, 0x3391: 0x40348c20, 0x3392: 0x40348d20, 0x3393: 0x40348e20, + 0x3394: 0x40348f20, 0x3395: 0x40349020, 0x3396: 0x40349120, 0x3397: 0x40349220, + 0x3398: 0x40349320, 0x3399: 0x40349420, 0x339a: 0x40349520, 0x339b: 0x40349620, + 0x339c: 0x40349720, 0x339d: 0x40349820, 0x339e: 0x40349920, 0x339f: 0x40349a20, + 0x33a0: 0x40349b20, 0x33a1: 0x40349c20, 0x33a2: 0x40349d20, 0x33a3: 0x40349e20, + 0x33a4: 0x40349f20, 0x33a5: 0x4034a020, 0x33a6: 0x4034a120, 0x33a7: 0x4034a220, + 0x33a8: 0x4034a320, 0x33a9: 0x4034a420, 0x33aa: 0x4034a520, 0x33ab: 0x4034a620, + 0x33ac: 0x4034a720, 0x33ad: 0x4034a820, 0x33ae: 0x4034a920, 0x33af: 0x4034aa20, + 0x33b0: 0x4034ab20, 0x33b1: 0x4034ac20, 0x33b2: 0x4034ad20, 0x33b3: 0x4034ae20, + 0x33b4: 0x4034af20, 0x33b5: 0x4034b020, 0x33b6: 0x4034b120, 0x33b7: 0x4034b220, + 0x33b8: 0x4034b320, 0x33b9: 0x4034b420, 0x33ba: 0x4034b520, 0x33bb: 0x4034b620, + 0x33bc: 0x4034b720, 0x33bd: 0x4034b820, 0x33be: 0x4034b920, 0x33bf: 0x4034ba20, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x4034bb20, 0x33c1: 0x4034bc20, 0x33c2: 0x4034bd20, 0x33c3: 0x4034be20, + 0x33c4: 0x4034bf20, 0x33c5: 0x4034c020, 0x33c6: 0x4034c120, 0x33c7: 0x4034c220, + 0x33c8: 0x4034c320, 0x33c9: 0x4034c420, 0x33ca: 0x4034c520, 0x33cb: 0x4034c620, + 0x33cc: 0x4034c720, 0x33cd: 0x4034c820, 0x33ce: 0x4034c920, 0x33cf: 0x4034ca20, + 0x33d0: 0x4034cb20, 0x33d1: 0x4034cc20, 0x33d2: 0x4034cd20, 0x33d3: 0x4034ce20, + 0x33d4: 0x4034cf20, 0x33d5: 0x4034d020, 0x33d6: 0x4034d120, 0x33d7: 0x4034d220, + 0x33d8: 0x4034d320, 0x33d9: 0x4034d420, 0x33da: 0x4034d520, 0x33db: 0x4034d620, + 0x33dc: 0x4034d720, 0x33dd: 0x4034d820, 0x33de: 0x4034d920, 0x33df: 0x4034da20, + 0x33e0: 0x4034db20, 0x33e1: 0x4034dc20, 0x33e2: 0x4034dd20, 0x33e3: 0x4034de20, + 0x33e4: 0x4034df20, 0x33e5: 0x4034e020, 0x33e6: 0x4034e120, 0x33e7: 0x4034e220, + 0x33e8: 0x4034e320, 0x33e9: 0x4034e420, 0x33ea: 0x4034e520, 0x33eb: 0x4034e620, + 0x33ec: 0x4034e720, 0x33ed: 0x4034e820, 0x33ee: 0x4034e920, 0x33ef: 0x4034ea20, + 0x33f0: 0x4034eb20, 0x33f1: 0x4034ec20, 0x33f2: 0x4034ed20, 0x33f3: 0x4034ee20, + 0x33f4: 0x4034ef20, 0x33f5: 0x4034f020, 0x33f6: 0x4034f120, 0x33f7: 0x4034f220, + 0x33f8: 0x4034f320, 0x33f9: 0x4034f420, 0x33fa: 0x4034f520, 0x33fb: 0x4034f620, + 0x33fc: 0x4034f720, 0x33fd: 0x4034f820, 0x33fe: 0x4034f920, 0x33ff: 0x4034fa20, + // Block 0xd0, offset 0x3400 + 0x3400: 0x4034fb20, 0x3401: 0x4034fc20, 0x3402: 0x4034fd20, 0x3403: 0x4034fe20, + 0x3404: 0x4034ff20, 0x3405: 0x40350020, 0x3406: 0x40350120, 0x3407: 0x40350220, + 0x3408: 0x40350320, 0x3409: 0x40350420, 0x340a: 0x40350520, 0x340b: 0x40350620, + 0x340c: 0x40350720, 0x340d: 0x40350820, 0x340e: 0x40350920, 0x340f: 0x40350a20, + 0x3410: 0x40350b20, 0x3411: 0x40350c20, 0x3412: 0x40350d20, 0x3413: 0x40350e20, + 0x3414: 0x40350f20, 0x3415: 0x40351020, 0x3416: 0x40351120, 0x3417: 0x40351220, + 0x3418: 0x40351320, 0x3419: 0x40351420, 0x341a: 0x40351520, 0x341b: 0x40351620, + 0x341c: 0x40351720, 0x341d: 0x40351820, 0x341e: 0x40351920, 0x341f: 0x40351a20, + 0x3420: 0x40351b20, 0x3421: 0x40351c20, 0x3422: 0x40351d20, 0x3423: 0x40351e20, + 0x3424: 0x40351f20, 0x3425: 0x40352020, 0x3426: 0x40352120, 0x3427: 0x40352220, + 0x3428: 0x40352320, 0x3429: 0x40352420, 0x342a: 0x40352520, 0x342b: 0x40352620, + 0x342c: 0x40352720, 0x342d: 0x40352820, 0x342e: 0x40352920, 0x342f: 0x40352a20, + 0x3430: 0x40352b20, 0x3431: 0x40352c20, 0x3432: 0x40352d20, 0x3433: 0x40352e20, + 0x3434: 0x40352f20, 0x3435: 0x40353020, 0x3436: 0x40353120, 0x3437: 0x40353220, + 0x3438: 0x40353320, 0x3439: 0x40353420, 0x343a: 0x40353520, 0x343b: 0x40353620, + 0x343c: 0x40353720, 0x343d: 0x40353820, 0x343e: 0x40353920, 0x343f: 0x40353a20, + // Block 0xd1, offset 0x3440 + 0x3440: 0x40353b20, 0x3441: 0x40353c20, 0x3442: 0x40353d20, 0x3443: 0x40353e20, + 0x3444: 0x40353f20, 0x3445: 0x40354020, 0x3446: 0x40354120, 0x3447: 0x40354220, + 0x3448: 0x40354320, 0x3449: 0x40354420, 0x344a: 0x40354520, 0x344b: 0x40354620, + 0x344c: 0x40354720, 0x344d: 0x40354820, 0x344e: 0x40354920, 0x344f: 0x40354a20, + 0x3450: 0x40354b20, 0x3451: 0x40354c20, 0x3452: 0x40354d20, 0x3453: 0x40354e20, + 0x3454: 0x40354f20, 0x3455: 0x40355020, 0x3456: 0x40355120, 0x3457: 0x40355220, + 0x3458: 0x40355320, 0x3459: 0x40355420, 0x345a: 0x40355520, 0x345b: 0x40355620, + 0x345c: 0x40355720, 0x345d: 0x40355820, 0x345e: 0x40355920, 0x345f: 0x40355a20, + 0x3460: 0x40355b20, 0x3461: 0x40355c20, 0x3462: 0x40355d20, 0x3463: 0x40355e20, + 0x3464: 0x40355f20, 0x3465: 0x40356020, 0x3466: 0x40356120, 0x3467: 0x40356220, + 0x3468: 0x40356320, 0x3469: 0x40356420, 0x346a: 0x40356520, 0x346b: 0x40356620, + 0x346c: 0x40356720, 0x346d: 0x40356820, 0x346e: 0x40356920, 0x346f: 0x40356a20, + 0x3470: 0x40356b20, 0x3471: 0x40356c20, 0x3472: 0x40356d20, 0x3473: 0x40356e20, + 0x3474: 0x40356f20, 0x3475: 0x40357020, 0x3476: 0x40357120, 0x3477: 0x40357220, + 0x3478: 0x40357320, 0x3479: 0x40357420, 0x347a: 0x40357520, 0x347b: 0x40357620, + 0x347c: 0x40357720, 0x347d: 0x40357820, 0x347e: 0x40357920, 0x347f: 0x40357a20, + // Block 0xd2, offset 0x3480 + 0x3480: 0x40357b20, 0x3481: 0x40357c20, 0x3482: 0x40357d20, 0x3483: 0x40357e20, + 0x3484: 0x40357f20, 0x3485: 0x40358020, 0x3486: 0x40358120, 0x3487: 0x40358220, + 0x3488: 0x40358320, 0x3489: 0x40358420, 0x348a: 0x40358520, 0x348b: 0x40358620, + 0x348c: 0x40358720, 0x348d: 0x40358820, 0x348e: 0x40358920, 0x348f: 0x40358a20, + 0x3490: 0x40358b20, 0x3491: 0x40358c20, 0x3492: 0x40358d20, 0x3493: 0x40358e20, + 0x3494: 0x40358f20, 0x3495: 0x40359020, 0x3496: 0x40359120, 0x3497: 0x40359220, + 0x3498: 0x40359320, 0x3499: 0x40359420, 0x349a: 0x40359520, 0x349b: 0x40359620, + 0x349c: 0x40359720, 0x349d: 0x40359820, 0x349e: 0x40359920, 0x349f: 0x40359a20, + 0x34a0: 0x40359b20, 0x34a1: 0x40359c20, 0x34a2: 0x40359d20, 0x34a3: 0x40359e20, + 0x34a4: 0x40359f20, 0x34a5: 0x4035a020, 0x34a6: 0x4035a120, 0x34a7: 0x4035a220, + 0x34a8: 0x4035a320, 0x34a9: 0x4035a420, 0x34aa: 0x4035a520, 0x34ab: 0x4035a620, + 0x34ac: 0x4035a720, 0x34ad: 0x4035a820, 0x34ae: 0x4035a920, 0x34af: 0x4035aa20, + 0x34b0: 0x4035ab20, 0x34b1: 0x4035ac20, 0x34b2: 0x4035ad20, 0x34b3: 0x4035ae20, + 0x34b4: 0x4035af20, 0x34b5: 0x4035b020, 0x34b6: 0x4035b120, 0x34b7: 0x4035b220, + 0x34b8: 0x4035b320, 0x34b9: 0x4035b420, 0x34ba: 0x4035b520, 0x34bb: 0x4035b620, + 0x34bc: 0x4035b720, 0x34bd: 0x4035b820, 0x34be: 0x4035b920, 0x34bf: 0x4035ba20, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x4035bb20, 0x34c1: 0x4035bc20, 0x34c2: 0x4035bd20, 0x34c3: 0x4035be20, + 0x34c4: 0x4035bf20, 0x34c5: 0x4035c020, 0x34c6: 0x4035c120, 0x34c7: 0x4035c220, + 0x34c8: 0x4035c320, 0x34c9: 0x4035c420, 0x34ca: 0x4035c520, 0x34cb: 0x4035c620, + 0x34cc: 0x4035c720, 0x34cd: 0x4035c820, 0x34ce: 0x4035c920, 0x34cf: 0x4035ca20, + 0x34d0: 0x4035cb20, 0x34d1: 0x4035cc20, 0x34d2: 0x4035cd20, 0x34d3: 0x4035ce20, + 0x34d4: 0x4035cf20, 0x34d5: 0x4035d020, 0x34d6: 0x4035d120, 0x34d7: 0x4035d220, + 0x34d8: 0x4035d320, 0x34d9: 0x4035d420, 0x34da: 0x4035d520, 0x34db: 0x4035d620, + 0x34dc: 0x4035d720, 0x34dd: 0x4035d820, 0x34de: 0x4035d920, 0x34df: 0x4035da20, + 0x34e0: 0x4035db20, 0x34e1: 0x4035dc20, 0x34e2: 0x4035dd20, 0x34e3: 0x4035de20, + 0x34e4: 0x4035df20, 0x34e5: 0x4035e020, 0x34e6: 0x4035e120, 0x34e7: 0x4035e220, + 0x34e8: 0x4035e320, 0x34e9: 0x4035e420, 0x34ea: 0x4035e520, 0x34eb: 0x4035e620, + 0x34ec: 0x4035e720, 0x34ed: 0x4035e820, 0x34ee: 0x4035e920, 0x34ef: 0x4035ea20, + 0x34f0: 0x4035eb20, 0x34f1: 0x4035ec20, 0x34f2: 0x4035ed20, 0x34f3: 0x4035ee20, + 0x34f4: 0x4035ef20, 0x34f5: 0x4035f020, 0x34f6: 0x4035f120, 0x34f7: 0x4035f220, + 0x34f8: 0x4035f320, 0x34f9: 0x4035f420, 0x34fa: 0x4035f520, 0x34fb: 0x4035f620, + 0x34fc: 0x4035f720, 0x34fd: 0x4035f820, 0x34fe: 0x4035f920, 0x34ff: 0x4035fa20, + // Block 0xd4, offset 0x3500 + 0x3500: 0x4035fb20, 0x3501: 0x4035fc20, 0x3502: 0x4035fd20, 0x3503: 0x4035fe20, + 0x3504: 0x4035ff20, 0x3505: 0x40360020, 0x3506: 0x40360120, 0x3507: 0x40360220, + 0x3508: 0x40360320, 0x3509: 0x40360420, 0x350a: 0x40360520, 0x350b: 0x40360620, + 0x350c: 0x40360720, 0x350d: 0x40360820, 0x350e: 0x40360920, 0x350f: 0x40360a20, + 0x3510: 0x40360b20, 0x3511: 0x40360c20, 0x3512: 0x40360d20, 0x3513: 0x40360e20, + 0x3514: 0x40360f20, 0x3515: 0x40361020, 0x3516: 0x40361120, 0x3517: 0x40361220, + 0x3518: 0x40361320, 0x3519: 0x40361420, 0x351a: 0x40361520, 0x351b: 0x40361620, + 0x351c: 0x40361720, 0x351d: 0x40361820, 0x351e: 0x40361920, 0x351f: 0x40361a20, + 0x3520: 0x40361b20, 0x3521: 0x40361c20, 0x3522: 0x40361d20, 0x3523: 0x40361e20, + 0x3524: 0x40361f20, 0x3525: 0x40362020, 0x3526: 0x40362120, 0x3527: 0x40362220, + 0x3528: 0x40362320, 0x3529: 0x40362420, 0x352a: 0x40362520, 0x352b: 0x40362620, + 0x352c: 0x40362720, 0x352d: 0x40362820, 0x352e: 0x40362920, 0x352f: 0x40362a20, + 0x3530: 0x40362b20, 0x3531: 0x40362c20, 0x3532: 0x40362d20, 0x3533: 0x40362e20, + 0x3534: 0x40362f20, 0x3535: 0x40363020, 0x3536: 0x40363120, 0x3537: 0x40363220, + 0x3538: 0x40363320, 0x3539: 0x40363420, 0x353a: 0x40363520, 0x353b: 0x40363620, + 0x353c: 0x40363720, 0x353d: 0x40363820, 0x353e: 0x40363920, 0x353f: 0x40363a20, + // Block 0xd5, offset 0x3540 + 0x3540: 0x40363b20, 0x3541: 0x40363c20, 0x3542: 0x40363d20, 0x3543: 0x40363e20, + 0x3544: 0x40363f20, 0x3545: 0x40364020, 0x3546: 0x40364120, 0x3547: 0x40364220, + 0x3548: 0x40364320, 0x3549: 0x40364420, 0x354a: 0x40364520, 0x354b: 0x40364620, + 0x354c: 0x40364720, 0x354d: 0x40364820, 0x354e: 0x40364920, 0x354f: 0x40364a20, + 0x3550: 0x40364b20, 0x3551: 0x40364c20, 0x3552: 0x40364d20, 0x3553: 0x40364e20, + 0x3554: 0x40364f20, 0x3555: 0x40365020, 0x3556: 0x40365120, 0x3557: 0x40365220, + 0x3558: 0x40365320, 0x3559: 0x40365420, 0x355a: 0x40365520, 0x355b: 0x40365620, + 0x355c: 0x40365720, 0x355d: 0x40365820, 0x355e: 0x40365920, 0x355f: 0x40365a20, + 0x3560: 0x40365b20, 0x3561: 0x40365c20, 0x3562: 0x40365d20, 0x3563: 0x40365e20, + 0x3564: 0x40365f20, 0x3565: 0x40366020, 0x3566: 0x40366120, 0x3567: 0x40366220, + 0x3568: 0x40366320, 0x3569: 0x40366420, 0x356a: 0x40366520, 0x356b: 0x40366620, + 0x356c: 0x40366720, 0x356d: 0x40366820, 0x356e: 0x40366920, 0x356f: 0x40366a20, + 0x3570: 0x40366b20, 0x3571: 0x40366c20, 0x3572: 0x40366d20, 0x3573: 0x40366e20, + 0x3574: 0x40366f20, 0x3575: 0x40367020, 0x3576: 0x40367120, 0x3577: 0x40367220, + 0x3578: 0x40367320, 0x3579: 0x40367420, 0x357a: 0x40367520, 0x357b: 0x40367620, + 0x357c: 0x40367720, 0x357d: 0x40367820, 0x357e: 0x40367920, 0x357f: 0x40367a20, + // Block 0xd6, offset 0x3580 + 0x3580: 0x40367b20, 0x3581: 0x40367c20, 0x3582: 0x40367d20, 0x3583: 0x40367e20, + 0x3584: 0x40367f20, 0x3585: 0x40368020, 0x3586: 0x40368120, 0x3587: 0x40368220, + 0x3588: 0x40368320, 0x3589: 0x40368420, 0x358a: 0x40368520, 0x358b: 0x40368620, + 0x358c: 0x40368720, + 0x3590: 0x400d1220, 0x3591: 0x400d1320, 0x3592: 0x400d1420, 0x3593: 0x400d1520, + 0x3594: 0x400d1620, 0x3595: 0x400d1720, 0x3596: 0x400d1820, 0x3597: 0x400d1920, + 0x3598: 0x400d1a20, 0x3599: 0x400d1b20, 0x359a: 0x400d1c20, 0x359b: 0x400d1d20, + 0x359c: 0x400d1e20, 0x359d: 0x400d1f20, 0x359e: 0x400d2020, 0x359f: 0x400d2120, + 0x35a0: 0x400d2220, 0x35a1: 0x400d2320, 0x35a2: 0x400d2420, 0x35a3: 0x400d2520, + 0x35a4: 0x400d2620, 0x35a5: 0x400d2720, 0x35a6: 0x400d2820, 0x35a7: 0x400d2920, + 0x35a8: 0x400d2a20, 0x35a9: 0x400d2b20, 0x35aa: 0x400d2c20, 0x35ab: 0x400d2d20, + 0x35ac: 0x400d2e20, 0x35ad: 0x400d2f20, 0x35ae: 0x400d3020, 0x35af: 0x400d3120, + 0x35b0: 0x400d3220, 0x35b1: 0x400d3320, 0x35b2: 0x400d3420, 0x35b3: 0x400d3520, + 0x35b4: 0x400d3620, 0x35b5: 0x400d3720, 0x35b6: 0x400d3820, 0x35b7: 0x400d3920, + 0x35b8: 0x400d3a20, 0x35b9: 0x400d3b20, 0x35ba: 0x400d3c20, 0x35bb: 0x400d3d20, + 0x35bc: 0x400d3e20, 0x35bd: 0x400d3f20, 0x35be: 0x400d4020, 0x35bf: 0x400d4120, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x400d4220, 0x35c1: 0x400d4320, 0x35c2: 0x400d4420, 0x35c3: 0x400d4520, + 0x35c4: 0x400d4620, 0x35c5: 0x400d4720, 0x35c6: 0x400d4820, + 0x35d0: 0x40368e20, 0x35d1: 0x40368f20, 0x35d2: 0x40369020, 0x35d3: 0x40369120, + 0x35d4: 0x40369220, 0x35d5: 0x40369320, 0x35d6: 0x40369420, 0x35d7: 0x40369520, + 0x35d8: 0x40369620, 0x35d9: 0x40369720, 0x35da: 0x40369820, 0x35db: 0x40369920, + 0x35dc: 0x40369a20, 0x35dd: 0x40369b20, 0x35de: 0x40369c20, 0x35df: 0x40369d20, + 0x35e0: 0x40369e20, 0x35e1: 0x40369f20, 0x35e2: 0x4036a020, 0x35e3: 0x4036a120, + 0x35e4: 0x4036a220, 0x35e5: 0x4036a320, 0x35e6: 0x4036a420, 0x35e7: 0x4036a520, + 0x35e8: 0x4036a620, 0x35e9: 0x4036a720, 0x35ea: 0x4036aa20, 0x35eb: 0x4036a820, + 0x35ec: 0x4036ab20, 0x35ed: 0x4036a920, 0x35ee: 0x4036ac20, 0x35ef: 0x4036ad20, + 0x35f0: 0x4036ae20, 0x35f1: 0x4036af20, 0x35f2: 0x4036b020, 0x35f3: 0x4036b120, + 0x35f4: 0x4036b220, 0x35f5: 0x4036b320, 0x35f6: 0x4036b420, 0x35f7: 0x4036b520, + 0x35f8: 0x40368820, 0x35f9: 0x40368920, 0x35fa: 0x40368a20, 0x35fb: 0x40368b20, + 0x35fc: 0x40368d20, 0x35fd: 0x40368c20, 0x35fe: 0x40012820, 0x35ff: 0x40017820, + // Block 0xd8, offset 0x3600 + 0x3600: 0x402c9b20, 0x3601: 0x402c9c20, 0x3602: 0x402c9d20, 0x3603: 0x402c9e20, + 0x3604: 0x402c9f20, 0x3605: 0x402ca020, 0x3606: 0x402ca120, 0x3607: 0x402ca220, + 0x3608: 0x402ca320, 0x3609: 0x402ca420, 0x360a: 0x402ca520, 0x360b: 0x402ca620, + 0x360c: 0x402ca720, 0x360d: 0x402ca820, 0x360e: 0x402ca920, 0x360f: 0x402caa20, + 0x3610: 0x402cab20, 0x3611: 0x402cac20, 0x3612: 0x402cad20, 0x3613: 0x402cae20, + 0x3614: 0x402caf20, 0x3615: 0x402cb020, 0x3616: 0x402cb120, 0x3617: 0x402cb220, + 0x3618: 0x402cb320, 0x3619: 0x402cb420, 0x361a: 0x402cb520, 0x361b: 0x402cb620, + 0x361c: 0x402cb720, 0x361d: 0x402cb820, 0x361e: 0x402cb920, 0x361f: 0x402cba20, + 0x3620: 0x402cbb20, 0x3621: 0x402cbc20, 0x3622: 0x402cbd20, 0x3623: 0x402cbe20, + 0x3624: 0x402cbf20, 0x3625: 0x402cc020, 0x3626: 0x402cc120, 0x3627: 0x402cc220, + 0x3628: 0x402cc320, 0x3629: 0x402cc420, 0x362a: 0x402cc520, 0x362b: 0x402cc620, + 0x362c: 0x402cc720, 0x362d: 0x402cc820, 0x362e: 0x402cc920, 0x362f: 0x402cca20, + 0x3630: 0x402ccb20, 0x3631: 0x402ccc20, 0x3632: 0x402ccd20, 0x3633: 0x402cce20, + 0x3634: 0x402ccf20, 0x3635: 0x402cd020, 0x3636: 0x402cd120, 0x3637: 0x402cd220, + 0x3638: 0x402cd320, 0x3639: 0x402cd420, 0x363a: 0x402cd520, 0x363b: 0x402cd620, + 0x363c: 0x402cd720, 0x363d: 0x402cd820, 0x363e: 0x402cd920, 0x363f: 0x402cda20, + // Block 0xd9, offset 0x3640 + 0x3640: 0x402cdb20, 0x3641: 0x402cdc20, 0x3642: 0x402cdd20, 0x3643: 0x402cde20, + 0x3644: 0x402cdf20, 0x3645: 0x402ce020, 0x3646: 0x402ce120, 0x3647: 0x402ce220, + 0x3648: 0x402ce320, 0x3649: 0x402ce420, 0x364a: 0x402ce520, 0x364b: 0x402ce620, + 0x364c: 0x402ce720, 0x364d: 0x402ce820, 0x364e: 0x402ce920, 0x364f: 0x402cea20, + 0x3650: 0x402ceb20, 0x3651: 0x402cec20, 0x3652: 0x402ced20, 0x3653: 0x402cee20, + 0x3654: 0x402cef20, 0x3655: 0x402cf020, 0x3656: 0x402cf120, 0x3657: 0x402cf220, + 0x3658: 0x402cf320, 0x3659: 0x402cf420, 0x365a: 0x402cf520, 0x365b: 0x402cf620, + 0x365c: 0x402cf720, 0x365d: 0x402cf820, 0x365e: 0x402cf920, 0x365f: 0x402cfa20, + 0x3660: 0x402cfb20, 0x3661: 0x402cfc20, 0x3662: 0x402cfd20, 0x3663: 0x402cfe20, + 0x3664: 0x402cff20, 0x3665: 0x402d0020, 0x3666: 0x402d0120, 0x3667: 0x402d0220, + 0x3668: 0x402d0320, 0x3669: 0x402d0420, 0x366a: 0x402d0520, 0x366b: 0x402d0620, + 0x366c: 0x402d0720, 0x366d: 0x402d0820, 0x366e: 0x402d0920, 0x366f: 0x402d0a20, + 0x3670: 0x402d0b20, 0x3671: 0x402d0c20, 0x3672: 0x402d0d20, 0x3673: 0x402d0e20, + 0x3674: 0x402d0f20, 0x3675: 0x402d1020, 0x3676: 0x402d1120, 0x3677: 0x402d1220, + 0x3678: 0x402d1320, 0x3679: 0x402d1420, 0x367a: 0x402d1520, 0x367b: 0x402d1620, + 0x367c: 0x402d1720, 0x367d: 0x402d1820, 0x367e: 0x402d1920, 0x367f: 0x402d1a20, + // Block 0xda, offset 0x3680 + 0x3680: 0x402d1b20, 0x3681: 0x402d1c20, 0x3682: 0x402d1d20, 0x3683: 0x402d1e20, + 0x3684: 0x402d1f20, 0x3685: 0x402d2020, 0x3686: 0x402d2120, 0x3687: 0x402d2220, + 0x3688: 0x402d2320, 0x3689: 0x402d2420, 0x368a: 0x402d2520, 0x368b: 0x402d2620, + 0x368c: 0x402d2720, 0x368d: 0x402d2820, 0x368e: 0x402d2920, 0x368f: 0x402d2a20, + 0x3690: 0x402d2b20, 0x3691: 0x402d2c20, 0x3692: 0x402d2d20, 0x3693: 0x402d2e20, + 0x3694: 0x402d2f20, 0x3695: 0x402d3020, 0x3696: 0x402d3120, 0x3697: 0x402d3220, + 0x3698: 0x402d3320, 0x3699: 0x402d3420, 0x369a: 0x402d3520, 0x369b: 0x402d3620, + 0x369c: 0x402d3720, 0x369d: 0x402d3820, 0x369e: 0x402d3920, 0x369f: 0x402d3a20, + 0x36a0: 0x402d3b20, 0x36a1: 0x402d3c20, 0x36a2: 0x402d3d20, 0x36a3: 0x402d3e20, + 0x36a4: 0x402d3f20, 0x36a5: 0x402d4020, 0x36a6: 0x402d4120, 0x36a7: 0x402d4220, + 0x36a8: 0x402d4320, 0x36a9: 0x402d4420, 0x36aa: 0x402d4520, 0x36ab: 0x402d4620, + 0x36ac: 0x402d4720, 0x36ad: 0x402d4820, 0x36ae: 0x402d4920, 0x36af: 0x402d4a20, + 0x36b0: 0x402d4b20, 0x36b1: 0x402d4c20, 0x36b2: 0x402d4d20, 0x36b3: 0x402d4e20, + 0x36b4: 0x402d4f20, 0x36b5: 0x402d5020, 0x36b6: 0x402d5120, 0x36b7: 0x402d5220, + 0x36b8: 0x402d5320, 0x36b9: 0x402d5420, 0x36ba: 0x402d5520, 0x36bb: 0x402d5620, + 0x36bc: 0x402d5720, 0x36bd: 0x402d5820, 0x36be: 0x402d5920, 0x36bf: 0x402d5a20, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x402d5b20, 0x36c1: 0x402d5c20, 0x36c2: 0x402d5d20, 0x36c3: 0x402d5e20, + 0x36c4: 0x402d5f20, 0x36c5: 0x402d6020, 0x36c6: 0x402d6120, 0x36c7: 0x402d6220, + 0x36c8: 0x402d6320, 0x36c9: 0x402d6420, 0x36ca: 0x402d6520, 0x36cb: 0x402d6620, + 0x36cc: 0x402d6720, 0x36cd: 0x402d6820, 0x36ce: 0x402d6920, 0x36cf: 0x402d6a20, + 0x36d0: 0x402d6b20, 0x36d1: 0x402d6c20, 0x36d2: 0x402d6d20, 0x36d3: 0x402d6e20, + 0x36d4: 0x402d6f20, 0x36d5: 0x402d7020, 0x36d6: 0x402d7120, 0x36d7: 0x402d7220, + 0x36d8: 0x402d7320, 0x36d9: 0x402d7420, 0x36da: 0x402d7520, 0x36db: 0x402d7620, + 0x36dc: 0x402d7720, 0x36dd: 0x402d7820, 0x36de: 0x402d7920, 0x36df: 0x402d7a20, + 0x36e0: 0x402d7b20, 0x36e1: 0x402d7c20, 0x36e2: 0x402d7d20, 0x36e3: 0x402d7e20, + 0x36e4: 0x402d7f20, 0x36e5: 0x402d8020, 0x36e6: 0x402d8120, 0x36e7: 0x402d8220, + 0x36e8: 0x402d8320, 0x36e9: 0x402d8420, 0x36ea: 0x402d8520, 0x36eb: 0x402d8620, + 0x36ec: 0x402d8720, 0x36ed: 0x402d8820, 0x36ee: 0x402d8920, 0x36ef: 0x402d8a20, + 0x36f0: 0x402d8b20, 0x36f1: 0x402d8c20, 0x36f2: 0x402d8d20, 0x36f3: 0x402d8e20, + 0x36f4: 0x402d8f20, 0x36f5: 0x402d9020, 0x36f6: 0x402d9120, 0x36f7: 0x402d9220, + 0x36f8: 0x402d9320, 0x36f9: 0x402d9420, 0x36fa: 0x402d9520, 0x36fb: 0x402d9620, + 0x36fc: 0x402d9720, 0x36fd: 0x402d9820, 0x36fe: 0x402d9920, 0x36ff: 0x402d9a20, + // Block 0xdc, offset 0x3700 + 0x3700: 0x402d9b20, 0x3701: 0x402d9c20, 0x3702: 0x402d9d20, 0x3703: 0x402d9e20, + 0x3704: 0x402d9f20, 0x3705: 0x402da020, 0x3706: 0x402da120, 0x3707: 0x402da220, + 0x3708: 0x402da320, 0x3709: 0x402da420, 0x370a: 0x402da520, 0x370b: 0x402da620, + 0x370c: 0x402da720, 0x370d: 0x40012920, 0x370e: 0x40017920, 0x370f: 0x40016720, + 0x3710: 0x0059e604, 0x3711: 0x005a0a04, 0x3712: 0x005a4404, 0x3713: 0xe0001132, + 0x3714: 0xe0001135, 0x3715: 0xe0001138, 0x3716: 0xe000113b, 0x3717: 0xe000113e, + 0x3718: 0xe0001141, 0x3719: 0xe0001144, 0x371a: 0xe0001147, 0x371b: 0xe000114a, + 0x371c: 0xe000114d, 0x371d: 0xe0001150, 0x371e: 0xe0001153, 0x371f: 0xe0001156, + 0x3720: 0xe000008d, 0x3721: 0xe0000111, 0x3722: 0xe00001f8, 0x3723: 0xe00002be, + 0x3724: 0xe000037b, 0x3725: 0xe0000435, 0x3726: 0xe00004ec, 0x3727: 0xe0000588, + 0x3728: 0xe0000624, 0x3729: 0xe00006bd, 0x372a: 0x005a1204, 0x372b: 0x005ad804, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00335008, 0x3741: 0x4019a820, 0x3742: 0x00335e08, 0x3743: 0x4019af20, + 0x3744: 0x00336808, 0x3745: 0x4019b420, 0x3746: 0x00339808, 0x3747: 0x4019cc20, + 0x3748: 0x0033b208, 0x3749: 0x4019d920, 0x374a: 0x00350608, 0x374b: 0x401a8320, + 0x374c: 0x00355408, 0x374d: 0x401aaa20, 0x374e: 0x0035d208, 0x374f: 0x401ae920, + 0x3750: 0x0035e008, 0x3751: 0x401af020, 0x3752: 0x00360a08, 0x3753: 0x401b0520, + 0x3754: 0x00362408, 0x3755: 0x401b1220, 0x3756: 0x00362608, 0x3757: 0x401b1320, + 0x3758: 0x00364208, 0x3759: 0x401b2120, 0x375a: 0x00364c08, 0x375b: 0x401b2620, + 0x375c: 0x00365608, 0x375d: 0x401b2b20, 0x375e: 0x00368808, 0x375f: 0x401b4420, + 0x3760: 0x00356e08, 0x3761: 0x401ab720, 0x3762: 0x00330208, 0x3763: 0x40198120, + 0x3764: 0x00340608, 0x3765: 0x401a0320, 0x3766: 0x00341c08, 0x3767: 0x401a0e20, + 0x3768: 0x0034520a, 0x3769: 0x00345204, 0x376a: 0x0034520a, 0x376b: 0x00345204, + 0x376c: 0x0034520a, 0x376d: 0x00345204, 0x376e: 0x00345204, 0x376f: 0x80008402, + 0x3770: 0x80000000, 0x3771: 0x80000000, 0x3772: 0x80000000, 0x3773: 0x40024120, + 0x377c: 0x80005f02, 0x377d: 0x80005f02, 0x377e: 0x40027420, 0x377f: 0x401aeb20, + // Block 0xde, offset 0x3780 + 0x3780: 0x0032f808, 0x3781: 0x40197c20, 0x3782: 0x00337608, 0x3783: 0x4019bb20, + 0x3784: 0x00333608, 0x3785: 0x40199b20, 0x3786: 0x0035a608, 0x3787: 0x401ad320, + 0x3788: 0x00337208, 0x3789: 0x4019b920, 0x378a: 0x0034c408, 0x378b: 0x401a6220, + 0x378c: 0x0034b808, 0x378d: 0x401a5c20, 0x378e: 0x00357008, 0x378f: 0x401ab820, + 0x3790: 0x00357a08, 0x3791: 0x401abd20, 0x3792: 0x00358408, 0x3793: 0x401ac220, + 0x3794: 0x00354208, 0x3795: 0x401aa120, 0x3796: 0x0035c808, 0x3797: 0x401ae420, + 0x37a0: 0x402da820, 0x37a1: 0x402da920, 0x37a2: 0x402daa20, 0x37a3: 0x402dab20, + 0x37a4: 0x402dac20, 0x37a5: 0x402dad20, 0x37a6: 0x402dae20, 0x37a7: 0x402daf20, + 0x37a8: 0x402db020, 0x37a9: 0x402db120, 0x37aa: 0x402db220, 0x37ab: 0x402db320, + 0x37ac: 0x402db420, 0x37ad: 0x402db520, 0x37ae: 0x402db620, 0x37af: 0x402db720, + 0x37b0: 0x402db820, 0x37b1: 0x402db920, 0x37b2: 0x402dba20, 0x37b3: 0x402dbb20, + 0x37b4: 0x402dbc20, 0x37b5: 0x402dbd20, 0x37b6: 0x402dbe20, 0x37b7: 0x402dbf20, + 0x37b8: 0x402dc020, 0x37b9: 0x402dc120, 0x37ba: 0x402dc220, 0x37bb: 0x402dc320, + 0x37bc: 0x402dc420, 0x37bd: 0x402dc520, 0x37be: 0x402dc620, 0x37bf: 0x402dc720, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x402dc820, 0x37c1: 0x402dc920, 0x37c2: 0x402dca20, 0x37c3: 0x402dcb20, + 0x37c4: 0x402dcc20, 0x37c5: 0x402dcd20, 0x37c6: 0x402dce20, 0x37c7: 0x402dcf20, + 0x37c8: 0x402dd020, 0x37c9: 0x402dd120, 0x37ca: 0x402dd220, 0x37cb: 0x402dd320, + 0x37cc: 0x402dd420, 0x37cd: 0x402dd520, 0x37ce: 0x402dd620, 0x37cf: 0x402dd720, + 0x37d0: 0x402dd820, 0x37d1: 0x402dd920, 0x37d2: 0x402dda20, 0x37d3: 0x402ddb20, + 0x37d4: 0x402ddc20, 0x37d5: 0x402ddd20, 0x37d6: 0x402dde20, 0x37d7: 0x402ddf20, + 0x37d8: 0x402de020, 0x37d9: 0x402de120, 0x37da: 0x402de220, 0x37db: 0x402de320, + 0x37dc: 0x402de420, 0x37dd: 0x402de520, 0x37de: 0x402de620, 0x37df: 0x402de720, + 0x37e0: 0x402de820, 0x37e1: 0x402de920, 0x37e2: 0x402dea20, 0x37e3: 0x402deb20, + 0x37e4: 0x402dec20, 0x37e5: 0x402ded20, 0x37e6: 0x402dee20, 0x37e7: 0x402def20, + 0x37e8: 0x402df020, 0x37e9: 0x402df120, 0x37ea: 0x402df220, 0x37eb: 0x402df320, + 0x37ec: 0x402df420, 0x37ed: 0x402df520, 0x37ee: 0x402df620, 0x37ef: 0x402df720, + 0x37f0: 0x8000db02, 0x37f1: 0x8000dc02, 0x37f2: 0x4001b320, 0x37f3: 0x40017a20, + 0x37f4: 0x40015720, 0x37f5: 0x40012a20, 0x37f6: 0x40013120, 0x37f7: 0x40016820, + // Block 0xe0, offset 0x3800 + 0x3800: 0x40035d20, 0x3801: 0x40035e20, 0x3802: 0x40035f20, 0x3803: 0x40036020, + 0x3804: 0x40036120, 0x3805: 0x40036220, 0x3806: 0x40036320, 0x3807: 0x40036420, + 0x3808: 0x40036520, 0x3809: 0x40036620, 0x380a: 0x40036720, 0x380b: 0x40036820, + 0x380c: 0x40036920, 0x380d: 0x40036a20, 0x380e: 0x40036b20, 0x380f: 0x40036c20, + 0x3810: 0x40036d20, 0x3811: 0x40036e20, 0x3812: 0x40036f20, 0x3813: 0x40037020, + 0x3814: 0x40037120, 0x3815: 0x40037220, 0x3816: 0x40037320, 0x3817: 0x40037420, + 0x3818: 0x40037520, 0x3819: 0x40037620, 0x381a: 0x40037720, 0x381b: 0x40037820, + 0x381c: 0x40037920, 0x381d: 0x40037a20, 0x381e: 0x40037b20, 0x381f: 0x40037c20, + 0x3820: 0x40037d20, 0x3821: 0x40037e20, 0x3822: 0x00314a08, 0x3823: 0x4018a520, + 0x3824: 0x00315e08, 0x3825: 0x4018af20, 0x3826: 0x002cf208, 0x3827: 0x40167920, + 0x3828: 0xe0000815, 0x3829: 0xe0000812, 0x382a: 0x00311408, 0x382b: 0x40188a20, + 0x382c: 0x00311608, 0x382d: 0x40188b20, 0x382e: 0x00311808, 0x382f: 0x40188c20, + 0x3830: 0x40163b20, 0x3831: 0x4017aa20, 0x3832: 0xe00006f0, 0x3833: 0xe00006ed, + 0x3834: 0xe0000708, 0x3835: 0xe0000705, 0x3836: 0xe000070e, 0x3837: 0xe000070b, + 0x3838: 0xe0000717, 0x3839: 0xe0000714, 0x383a: 0xe000071e, 0x383b: 0xe000071a, + 0x383c: 0xe0000725, 0x383d: 0xe0000722, 0x383e: 0x002bc608, 0x383f: 0x4015e320, + // Block 0xe1, offset 0x3840 + 0x3840: 0x002d7a08, 0x3841: 0x4016bd20, 0x3842: 0x002d7c08, 0x3843: 0x4016be20, + 0x3844: 0x002d7e08, 0x3845: 0x4016bf20, 0x3846: 0x002d9808, 0x3847: 0x4016cc20, + 0x3848: 0x002d9c08, 0x3849: 0x4016ce20, 0x384a: 0x002e7e08, 0x384b: 0x40173f20, + 0x384c: 0x002e6e08, 0x384d: 0x40173720, 0x384e: 0xe00007c2, 0x384f: 0xe00007bf, + 0x3850: 0x002e9e08, 0x3851: 0x40174f20, 0x3852: 0x002eac08, 0x3853: 0x40175620, + 0x3854: 0x002eae08, 0x3855: 0x40175720, 0x3856: 0x002ec408, 0x3857: 0x40176220, + 0x3858: 0x002ec608, 0x3859: 0x40176320, 0x385a: 0x002ef008, 0x385b: 0x40177820, + 0x385c: 0x002f4a08, 0x385d: 0x4017a520, 0x385e: 0x00302e08, 0x385f: 0x40181720, + 0x3860: 0xe0000822, 0x3861: 0xe000081f, 0x3862: 0x0030c008, 0x3863: 0x40186020, + 0x3864: 0x0030f608, 0x3865: 0x40187b20, 0x3866: 0x0030f808, 0x3867: 0x40187c20, + 0x3868: 0x00310208, 0x3869: 0x40188120, 0x386a: 0x00310408, 0x386b: 0x40188220, + 0x386c: 0x00310608, 0x386d: 0x40188320, 0x386e: 0x00310808, 0x386f: 0x40188420, + 0x3870: 0xf0000014, 0x3871: 0x4015fd20, 0x3872: 0x4016e620, 0x3873: 0x40170120, + 0x3874: 0x40171f20, 0x3875: 0x4017a320, 0x3876: 0x4017a420, 0x3877: 0x4017e420, + 0x3878: 0x40188520, 0x3879: 0xe0000748, 0x387a: 0xe0000745, 0x387b: 0xe000075a, + 0x387c: 0xe0000757, 0x387d: 0xe000076e, 0x387e: 0x002cbc08, 0x387f: 0x40165e20, + // Block 0xe2, offset 0x3880 + 0x3880: 0x002dd608, 0x3881: 0x4016eb20, 0x3882: 0xe00007d4, 0x3883: 0xe00007d1, + 0x3884: 0xe00007e6, 0x3885: 0xe00007e3, 0x3886: 0xe00007ff, 0x3887: 0xe00007fc, + 0x3888: 0x40037f20, 0x3889: 0x40038020, 0x388a: 0x40038120, 0x388b: 0x00314c08, + 0x388c: 0x4018a620, 0x388d: 0x002fee08, 0x388e: 0x4016e120, + 0x3890: 0x002e2a08, 0x3891: 0x40171520, + 0x38a0: 0xe0000768, 0x38a1: 0xe0000765, 0x38a2: 0xe0000780, 0x38a3: 0xe000077d, + 0x38a4: 0xe00007a4, 0x38a5: 0xe00007a1, 0x38a6: 0xe00007ce, 0x38a7: 0xe00007cb, + 0x38a8: 0xe00007da, 0x38a9: 0xe00007d7, + // Block 0xe3, offset 0x38c0 + 0x38fa: 0x40180720, 0x38fb: 0x40164320, + 0x38fc: 0x40175820, 0x38fd: 0x4016ff20, 0x38fe: 0x40168c20, 0x38ff: 0x40170020, + // Block 0xe4, offset 0x3900 + 0x3900: 0x40225f20, 0x3901: 0x40226020, 0x3902: 0x40226120, 0x3903: 0x40226220, + 0x3904: 0x40226320, 0x3905: 0x40226420, 0x3906: 0x40226520, 0x3907: 0x40226620, + 0x3908: 0x40226720, 0x3909: 0x40226820, 0x390a: 0x40226920, 0x390b: 0x80010d02, + 0x390c: 0x40226a20, 0x390d: 0x40226b20, 0x390e: 0x40226c20, 0x390f: 0x40226d20, + 0x3910: 0x40226e20, 0x3911: 0x40226f20, 0x3912: 0x40227020, 0x3913: 0x40227120, + 0x3914: 0x40227220, 0x3915: 0x40227320, 0x3916: 0x40227420, 0x3917: 0x40227520, + 0x3918: 0x40227620, 0x3919: 0x40227720, 0x391a: 0x40227820, 0x391b: 0x40227920, + 0x391c: 0x40227a20, 0x391d: 0x40227b20, 0x391e: 0x40227c20, 0x391f: 0x40227d20, + 0x3920: 0x40227e20, 0x3921: 0x40227f20, 0x3922: 0x40228020, 0x3923: 0x40228120, + 0x3924: 0x40228220, 0x3925: 0x40228320, 0x3926: 0x40228420, 0x3927: 0x40228520, + 0x3928: 0x40039620, 0x3929: 0x40039720, 0x392a: 0x40039820, 0x392b: 0x40039920, + 0x3930: 0x4013d820, 0x3931: 0x4013d920, 0x3932: 0x4013da20, 0x3933: 0x4013db20, + 0x3934: 0x4013dc20, 0x3935: 0x4013dd20, 0x3936: 0x40039a20, 0x3937: 0x40039b20, + 0x3938: 0x4013ad20, 0x3939: 0x40039c20, + // Block 0xe5, offset 0x3940 + 0x3940: 0x4024e020, 0x3941: 0x4024e120, 0x3942: 0x4024e220, 0x3943: 0x4024e320, + 0x3944: 0x4024e420, 0x3945: 0x4024e520, 0x3946: 0x4024e620, 0x3947: 0x4024e720, + 0x3948: 0x4024ec20, 0x3949: 0x4024ed20, 0x394a: 0x4024ee20, 0x394b: 0x4024ef20, + 0x394c: 0x4024f020, 0x394d: 0x4024f120, 0x394e: 0x4024f220, 0x394f: 0x4024f320, + 0x3950: 0x4024f420, 0x3951: 0x4024f520, 0x3952: 0x4024f620, 0x3953: 0x4024f720, + 0x3954: 0x4024f920, 0x3955: 0x4024fa20, 0x3956: 0x4024fb20, 0x3957: 0x4024fc20, + 0x3958: 0x4024ff20, 0x3959: 0x40250220, 0x395a: 0x40250320, 0x395b: 0x40250520, + 0x395c: 0x40250620, 0x395d: 0x40250920, 0x395e: 0x40250e20, 0x395f: 0x40250f20, + 0x3960: 0x40251020, 0x3961: 0x40251120, 0x3962: 0x40250a20, 0x3963: 0x40250b20, + 0x3964: 0x40250c20, 0x3965: 0x40250d20, 0x3966: 0x40251220, 0x3967: 0x4024f820, + 0x3968: 0x4024fd20, 0x3969: 0x4024e820, 0x396a: 0x4024e920, 0x396b: 0x4024ea20, + 0x396c: 0x4024eb20, 0x396d: 0x4024fe20, 0x396e: 0x40250420, 0x396f: 0x40250720, + 0x3970: 0x40250820, 0x3971: 0x40250020, 0x3972: 0x40250120, 0x3973: 0x40251320, + 0x3974: 0x4002b820, 0x3975: 0x4002b920, 0x3976: 0x40018420, 0x3977: 0x40018520, + // Block 0xe6, offset 0x3980 + 0x3980: 0x80010e02, 0x3981: 0x80010f02, 0x3982: 0x40228620, 0x3983: 0x40228720, + 0x3984: 0x40228820, 0x3985: 0x40228920, 0x3986: 0x40228a20, 0x3987: 0x40228b20, + 0x3988: 0x40228c20, 0x3989: 0x40228d20, 0x398a: 0x40228e20, 0x398b: 0x40228f20, + 0x398c: 0x40229020, 0x398d: 0x40229120, 0x398e: 0x40229220, 0x398f: 0x40229320, + 0x3990: 0x40229420, 0x3991: 0x40229520, 0x3992: 0x40229620, 0x3993: 0x40229720, + 0x3994: 0x40229820, 0x3995: 0x40229920, 0x3996: 0x40229a20, 0x3997: 0x40229b20, + 0x3998: 0x40229c20, 0x3999: 0x40229d20, 0x399a: 0x40229e20, 0x399b: 0x40229f20, + 0x399c: 0x4022a020, 0x399d: 0x4022a120, 0x399e: 0x4022a220, 0x399f: 0x4022a320, + 0x39a0: 0x4022a420, 0x39a1: 0x4022a520, 0x39a2: 0x4022a620, 0x39a3: 0x4022a720, + 0x39a4: 0x4022a820, 0x39a5: 0x4022a920, 0x39a6: 0x4022aa20, 0x39a7: 0x4022ab20, + 0x39a8: 0x4022ac20, 0x39a9: 0x4022ad20, 0x39aa: 0x4022ae20, 0x39ab: 0x4022af20, + 0x39ac: 0x4022b020, 0x39ad: 0x4022b120, 0x39ae: 0x4022b220, 0x39af: 0x4022b320, + 0x39b0: 0x4022b420, 0x39b1: 0x4022b520, 0x39b2: 0x4022b620, 0x39b3: 0x4022b720, + 0x39b4: 0x4022b820, 0x39b5: 0x4022b920, 0x39b6: 0x4022ba20, 0x39b7: 0x4022bb20, + 0x39b8: 0x4022bc20, 0x39b9: 0x4022bd20, 0x39ba: 0x4022be20, 0x39bb: 0x4022bf20, + 0x39bc: 0x4022c020, 0x39bd: 0x4022c120, 0x39be: 0x4022c220, 0x39bf: 0x4022c320, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x4022c420, 0x39c1: 0x4022c520, 0x39c2: 0x4022c620, 0x39c3: 0x4022c720, + 0x39c4: 0x4022c820, + 0x39ce: 0x40018020, 0x39cf: 0x40018120, + 0x39d0: 0xe000004e, 0x39d1: 0xe00000cf, 0x39d2: 0xe00001b9, 0x39d3: 0xe000027f, + 0x39d4: 0xe000033c, 0x39d5: 0xe00003f6, 0x39d6: 0xe00004ad, 0x39d7: 0xe0000549, + 0x39d8: 0xe00005e5, 0x39d9: 0xe000067e, + 0x39e0: 0x80000000, 0x39e1: 0x80000000, 0x39e2: 0x80000000, 0x39e3: 0x80000000, + 0x39e4: 0x80000000, 0x39e5: 0x80000000, 0x39e6: 0x80000000, 0x39e7: 0x80000000, + 0x39e8: 0x80000000, 0x39e9: 0x80000000, 0x39ea: 0x80000000, 0x39eb: 0x80000000, + 0x39ec: 0x80000000, 0x39ed: 0x80000000, 0x39ee: 0x80000000, 0x39ef: 0x80000000, + 0x39f0: 0x80000000, 0x39f1: 0x80000000, 0x39f2: 0x401fc020, 0x39f3: 0x003f8004, + 0x39f4: 0x003f8004, 0x39f5: 0x003f8004, 0x39f6: 0x003f8004, 0x39f7: 0x003f8004, + 0x39f8: 0x40028520, 0x39f9: 0x40028620, 0x39fa: 0x40028720, 0x39fb: 0x401fc120, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0xe000006c, 0x3a01: 0xe00000f0, 0x3a02: 0xe00001d7, 0x3a03: 0xe000029d, + 0x3a04: 0xe000035a, 0x3a05: 0xe0000414, 0x3a06: 0xe00004cb, 0x3a07: 0xe0000567, + 0x3a08: 0xe0000603, 0x3a09: 0xe000069c, 0x3a0a: 0x4025f420, 0x3a0b: 0x4025f520, + 0x3a0c: 0x4025f620, 0x3a0d: 0x4025f720, 0x3a0e: 0x4025f820, 0x3a0f: 0x4025f920, + 0x3a10: 0x4025fa20, 0x3a11: 0x4025fb20, 0x3a12: 0x4025fc20, 0x3a13: 0x4025fd20, + 0x3a14: 0x4025fe20, 0x3a15: 0x4025ff20, 0x3a16: 0x40260020, 0x3a17: 0x40260120, + 0x3a18: 0x40260220, 0x3a19: 0x40260320, 0x3a1a: 0x40260420, 0x3a1b: 0x40260520, + 0x3a1c: 0x40260620, 0x3a1d: 0x40260720, 0x3a1e: 0x40260820, 0x3a1f: 0x40260920, + 0x3a20: 0x40260a20, 0x3a21: 0x40260b20, 0x3a22: 0x40260c20, 0x3a23: 0x40260d20, + 0x3a24: 0x40260e20, 0x3a25: 0x40260f20, 0x3a26: 0x40261020, 0x3a27: 0x40261120, + 0x3a28: 0x40261220, 0x3a29: 0x40261320, 0x3a2a: 0x40261420, 0x3a2b: 0x80013002, + 0x3a2c: 0x80013102, 0x3a2d: 0x80013202, 0x3a2e: 0x4002be20, 0x3a2f: 0x40018820, + 0x3a30: 0x4025d020, 0x3a31: 0x4025d120, 0x3a32: 0x4025d220, 0x3a33: 0x4025d320, + 0x3a34: 0x4025d420, 0x3a35: 0x4025d520, 0x3a36: 0x4025d620, 0x3a37: 0x4025d720, + 0x3a38: 0x4025d820, 0x3a39: 0x4025d920, 0x3a3a: 0x4025da20, 0x3a3b: 0x4025db20, + 0x3a3c: 0x4025dc20, 0x3a3d: 0x4025dd20, 0x3a3e: 0x4025de20, 0x3a3f: 0x4025df20, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x4025e020, 0x3a41: 0x4025e120, 0x3a42: 0x4025e220, 0x3a43: 0x4025e320, + 0x3a44: 0x4025e420, 0x3a45: 0x4025e520, 0x3a46: 0x4025e620, 0x3a47: 0x4025e720, + 0x3a48: 0x4025e820, 0x3a49: 0x4025e920, 0x3a4a: 0x4025ea20, 0x3a4b: 0x4025eb20, + 0x3a4c: 0x4025ec20, 0x3a4d: 0x4025ed20, 0x3a4e: 0x4025ee20, 0x3a4f: 0x4025ef20, + 0x3a50: 0x4025f020, 0x3a51: 0x4025f120, 0x3a52: 0x4025f220, 0x3a53: 0x4025f320, + 0x3a5f: 0x4001b420, + 0x3a60: 0x40309020, 0x3a61: 0x40309120, 0x3a62: 0x40309220, 0x3a63: 0x40309320, + 0x3a64: 0x40309420, 0x3a65: 0x40309520, 0x3a66: 0x40309620, 0x3a67: 0x40309720, + 0x3a68: 0x40309820, 0x3a69: 0x40309920, 0x3a6a: 0x40309a20, 0x3a6b: 0x40309b20, + 0x3a6c: 0x40309c20, 0x3a6d: 0x40309d20, 0x3a6e: 0x40309e20, 0x3a6f: 0x40309f20, + 0x3a70: 0x4030a020, 0x3a71: 0x4030a120, 0x3a72: 0x4030a220, 0x3a73: 0x4030a320, + 0x3a74: 0x4030a420, 0x3a75: 0x4030a520, 0x3a76: 0x4030a620, 0x3a77: 0x4030a720, + 0x3a78: 0x4030a820, 0x3a79: 0x4030a920, 0x3a7a: 0x4030aa20, 0x3a7b: 0x4030ab20, + 0x3a7c: 0x4030ac20, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x80010502, 0x3a81: 0x80010602, 0x3a82: 0x80010702, 0x3a83: 0x80010802, + 0x3a84: 0x40283420, 0x3a85: 0x40283520, 0x3a86: 0x40283620, 0x3a87: 0x40283720, + 0x3a88: 0x40283820, 0x3a89: 0x40283920, 0x3a8a: 0x40283a20, 0x3a8b: 0x40283b20, + 0x3a8c: 0x40283c20, 0x3a8d: 0x40283d20, 0x3a8e: 0x40283e20, 0x3a8f: 0x40283f20, + 0x3a90: 0x40284020, 0x3a91: 0x40284120, 0x3a92: 0x40284220, 0x3a93: 0x40284320, + 0x3a94: 0x40284420, 0x3a95: 0x40284520, 0x3a96: 0x40284620, 0x3a97: 0x40284720, + 0x3a98: 0x40284820, 0x3a99: 0x40284920, 0x3a9a: 0x40284a20, 0x3a9b: 0x40284b20, + 0x3a9c: 0x40284c20, 0x3a9d: 0x40284d20, 0x3a9e: 0x40284e20, 0x3a9f: 0x40284f20, + 0x3aa0: 0x40285020, 0x3aa1: 0x40285120, 0x3aa2: 0x40285220, 0x3aa3: 0x40285320, + 0x3aa4: 0x40285420, 0x3aa5: 0x40285520, 0x3aa6: 0x40285620, 0x3aa7: 0x40285720, + 0x3aa8: 0x40285820, 0x3aa9: 0x40285920, 0x3aaa: 0x40285a20, 0x3aab: 0x40285c20, + 0x3aac: 0x0050b804, 0x3aad: 0x40285e20, 0x3aae: 0x40285f20, 0x3aaf: 0x40286020, + 0x3ab0: 0x40286120, 0x3ab1: 0x40286220, 0x3ab2: 0x40286320, 0x3ab3: 0x80010402, + 0x3ab4: 0x40286420, 0x3ab5: 0x40286d20, 0x3ab6: 0x40286620, 0x3ab7: 0x40286720, + 0x3ab8: 0x40286820, 0x3ab9: 0x40286920, 0x3aba: 0x40286b20, 0x3abb: 0x40286c20, + 0x3abc: 0x40286520, 0x3abd: 0x40286a20, 0x3abe: 0x40285b20, 0x3abf: 0x40285d20, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x40286e20, 0x3ac1: 0x4001a920, 0x3ac2: 0x4001aa20, 0x3ac3: 0x4001ab20, + 0x3ac4: 0x4001ac20, 0x3ac5: 0x4001ad20, 0x3ac6: 0x4001ae20, 0x3ac7: 0x40015320, + 0x3ac8: 0x40019320, 0x3ac9: 0x40019420, 0x3aca: 0x4001af20, 0x3acb: 0x4001b020, + 0x3acc: 0x4001b120, 0x3acd: 0x4001b220, 0x3acf: 0x40139820, + 0x3ad0: 0xe0000081, 0x3ad1: 0xe0000105, 0x3ad2: 0xe00001ec, 0x3ad3: 0xe00002b2, + 0x3ad4: 0xe000036f, 0x3ad5: 0xe0000429, 0x3ad6: 0xe00004e0, 0x3ad7: 0xe000057c, + 0x3ad8: 0xe0000618, 0x3ad9: 0xe00006b1, + 0x3ade: 0x4002bf20, 0x3adf: 0x4002c020, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x4027a920, 0x3b01: 0x4027aa20, 0x3b02: 0x4027ab20, 0x3b03: 0x4027ac20, + 0x3b04: 0x4027ad20, 0x3b05: 0x4027ae20, 0x3b06: 0x4027af20, 0x3b07: 0x4027b020, + 0x3b08: 0x4027b120, 0x3b09: 0x4027b220, 0x3b0a: 0x4027b320, 0x3b0b: 0x4027b420, + 0x3b0c: 0x4027b520, 0x3b0d: 0x4027b620, 0x3b0e: 0x4027b720, 0x3b0f: 0x4027b820, + 0x3b10: 0x4027b920, 0x3b11: 0x4027ba20, 0x3b12: 0x4027bb20, 0x3b13: 0x4027bc20, + 0x3b14: 0x4027bd20, 0x3b15: 0x4027be20, 0x3b16: 0x4027bf20, 0x3b17: 0x4027c020, + 0x3b18: 0x4027c120, 0x3b19: 0x4027c220, 0x3b1a: 0x4027c320, 0x3b1b: 0x4027c420, + 0x3b1c: 0x4027c520, 0x3b1d: 0x4027c620, 0x3b1e: 0x4027c720, 0x3b1f: 0x4027c820, + 0x3b20: 0x4027c920, 0x3b21: 0x4027ca20, 0x3b22: 0x4027cb20, 0x3b23: 0x4027cc20, + 0x3b24: 0x4027cd20, 0x3b25: 0x4027ce20, 0x3b26: 0x4027cf20, 0x3b27: 0x4027d020, + 0x3b28: 0x4027d120, 0x3b29: 0x4027d620, 0x3b2a: 0x4027d720, 0x3b2b: 0x4027d820, + 0x3b2c: 0x4027d920, 0x3b2d: 0x4027da20, 0x3b2e: 0x4027db20, 0x3b2f: 0x4027dc20, + 0x3b30: 0x4027dd20, 0x3b31: 0x4027de20, 0x3b32: 0x4027df20, 0x3b33: 0x4027d220, + 0x3b34: 0x4027d320, 0x3b35: 0x4027d420, 0x3b36: 0x4027d520, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x4027e020, 0x3b41: 0x4027e120, 0x3b42: 0x4027e220, 0x3b43: 0x4027e320, + 0x3b44: 0x4027e420, 0x3b45: 0x4027e520, 0x3b46: 0x4027e620, 0x3b47: 0x4027e720, + 0x3b48: 0x4027e820, 0x3b49: 0x4027e920, 0x3b4a: 0x4027ea20, 0x3b4b: 0x4027eb20, + 0x3b4c: 0x4027ec20, 0x3b4d: 0x4027ed20, + 0x3b50: 0xe000007b, 0x3b51: 0xe00000ff, 0x3b52: 0xe00001e6, 0x3b53: 0xe00002ac, + 0x3b54: 0xe0000369, 0x3b55: 0xe0000423, 0x3b56: 0xe00004da, 0x3b57: 0xe0000576, + 0x3b58: 0xe0000612, 0x3b59: 0xe00006ab, + 0x3b5c: 0x4002c120, 0x3b5d: 0x40019520, 0x3b5e: 0x40019620, 0x3b5f: 0x40019720, + 0x3b60: 0x40261b20, 0x3b61: 0x40262120, 0x3b62: 0x40262320, 0x3b63: 0x40262520, + 0x3b64: 0x40262a20, 0x3b65: 0x40262e20, 0x3b66: 0x40263120, 0x3b67: 0x40263320, + 0x3b68: 0x40263520, 0x3b69: 0x40263720, 0x3b6a: 0x40263f20, 0x3b6b: 0x40264220, + 0x3b6c: 0x40265f20, 0x3b6d: 0x40266220, 0x3b6e: 0x40266420, 0x3b6f: 0x40264820, + 0x3b70: 0x40139920, 0x3b71: 0x40266520, 0x3b72: 0x40262720, 0x3b73: 0x40265220, + 0x3b74: 0x4026a820, 0x3b75: 0x4026a920, 0x3b76: 0x4026aa20, 0x3b77: 0x40031c20, + 0x3b78: 0x40031d20, 0x3b79: 0x40031e20, 0x3b7a: 0x40265320, 0x3b7b: 0x4026a720, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x40240320, 0x3b81: 0x40240420, 0x3b82: 0x40240520, 0x3b83: 0x40240620, + 0x3b84: 0x40240720, 0x3b85: 0x40240820, 0x3b86: 0x40240920, 0x3b87: 0x40240a20, + 0x3b88: 0x40240b20, 0x3b89: 0x40240c20, 0x3b8a: 0x40240d20, 0x3b8b: 0x40240e20, + 0x3b8c: 0x40240f20, 0x3b8d: 0x40241020, 0x3b8e: 0x40241120, 0x3b8f: 0x40241220, + 0x3b90: 0x40241320, 0x3b91: 0x40241420, 0x3b92: 0x40241520, 0x3b93: 0x40241620, + 0x3b94: 0x40241720, 0x3b95: 0x40241820, 0x3b96: 0x40241920, 0x3b97: 0x40241a20, + 0x3b98: 0x40241b20, 0x3b99: 0x40241c20, 0x3b9a: 0x40241d20, 0x3b9b: 0x40241e20, + 0x3b9c: 0x40241f20, 0x3b9d: 0x40242020, 0x3b9e: 0x40242120, 0x3b9f: 0x40242220, + 0x3ba0: 0x40242320, 0x3ba1: 0x40242420, 0x3ba2: 0x40242520, 0x3ba3: 0x40242620, + 0x3ba4: 0x40242720, 0x3ba5: 0x40242820, 0x3ba6: 0x40242920, 0x3ba7: 0x40242a20, + 0x3ba8: 0x40242b20, 0x3ba9: 0x40242c20, 0x3baa: 0x40242d20, 0x3bab: 0x40242e20, + 0x3bac: 0x40242f20, 0x3bad: 0x40243020, 0x3bae: 0x40243120, 0x3baf: 0x40243220, + 0x3bb0: 0x40243320, 0x3bb1: 0x40243420, 0x3bb2: 0x40243520, 0x3bb3: 0x40243620, + 0x3bb4: 0x40243720, 0x3bb5: 0xc2040671, 0x3bb6: 0xc2350671, 0x3bb7: 0x40243a20, + 0x3bb8: 0x40243b20, 0x3bb9: 0xc2660671, 0x3bba: 0x40243d20, 0x3bbb: 0xc2970671, + 0x3bbc: 0xc2c80671, 0x3bbd: 0x40244020, 0x3bbe: 0x40244120, 0x3bbf: 0x80012a02, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x40244220, 0x3bc1: 0x80012b02, 0x3bc2: 0x40244320, + 0x3bdb: 0x40244420, + 0x3bdc: 0x40244520, 0x3bdd: 0x40139a20, 0x3bde: 0x40028b20, 0x3bdf: 0x40028c20, + // Block 0xf0, offset 0x3c00 + 0x3c01: 0x401df620, 0x3c02: 0x401df720, 0x3c03: 0x401df820, + 0x3c04: 0x401df920, 0x3c05: 0x401dfa20, 0x3c06: 0x401dfb20, + 0x3c09: 0x401ebd20, 0x3c0a: 0x401ebe20, 0x3c0b: 0x401ebf20, + 0x3c0c: 0x401ec020, 0x3c0d: 0x401ec120, 0x3c0e: 0x401ec220, + 0x3c11: 0x401e9e20, 0x3c12: 0x401e9f20, 0x3c13: 0x401ea020, + 0x3c14: 0x401ea120, 0x3c15: 0x401ea220, 0x3c16: 0x401ea320, + 0x3c20: 0x401f0020, 0x3c21: 0x401f0120, 0x3c22: 0x401f0220, 0x3c23: 0x401f0320, + 0x3c24: 0x401f0420, 0x3c25: 0x401f0520, 0x3c26: 0x401f0620, + 0x3c28: 0x401f1820, 0x3c29: 0x401f1920, 0x3c2a: 0x401f1a20, 0x3c2b: 0x401f1b20, + 0x3c2c: 0x401f1c20, 0x3c2d: 0x401f1d20, 0x3c2e: 0x401f1e20, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x40223320, 0x3c41: 0x40223420, 0x3c42: 0x40223520, 0x3c43: 0x40223620, + 0x3c44: 0x40223720, 0x3c45: 0x40223820, 0x3c46: 0x40223920, 0x3c47: 0x40223a20, + 0x3c48: 0x40223b20, 0x3c49: 0x40223c20, 0x3c4a: 0x40223d20, 0x3c4b: 0x40223e20, + 0x3c4c: 0x40223f20, 0x3c4d: 0x40224020, 0x3c4e: 0x40224120, 0x3c4f: 0x40224220, + 0x3c50: 0x40224320, 0x3c51: 0x40224420, 0x3c52: 0x40224520, 0x3c53: 0x40224620, + 0x3c54: 0x40224720, 0x3c55: 0x40224820, 0x3c56: 0x40224920, 0x3c57: 0x40224a20, + 0x3c58: 0x40224b20, 0x3c59: 0x40224c20, 0x3c5a: 0x40224d20, 0x3c5b: 0x40225620, + 0x3c5c: 0x40225720, 0x3c5d: 0x40225820, 0x3c5e: 0x40225920, 0x3c5f: 0x40225a20, + 0x3c60: 0x40225b20, 0x3c61: 0x40225c20, 0x3c62: 0x40225d20, 0x3c63: 0x40224e20, + 0x3c64: 0x40224f20, 0x3c65: 0x40225020, 0x3c66: 0x40225120, 0x3c67: 0x40225220, + 0x3c68: 0x40225320, 0x3c69: 0x40225420, 0x3c6a: 0x40225520, 0x3c6b: 0x40019820, + 0x3c6c: 0x80010c02, 0x3c6d: 0x40225e20, + 0x3c70: 0xe000004b, 0x3c71: 0xe00000cc, 0x3c72: 0xe00001b6, 0x3c73: 0xe000027c, + 0x3c74: 0xe0000339, 0x3c75: 0xe00003f3, 0x3c76: 0xe00004aa, 0x3c77: 0xe0000546, + 0x3c78: 0xe00005e2, 0x3c79: 0xe000067b, + // Block 0xf2, offset 0x3c80 + 0x3cb0: 0x4030f620, 0x3cb1: 0x4030f720, 0x3cb2: 0x4030f820, 0x3cb3: 0x4030f920, + 0x3cb4: 0x4030fa20, 0x3cb5: 0x4030fb20, 0x3cb6: 0x4030fc20, 0x3cb7: 0x4030fd20, + 0x3cb8: 0x4030fe20, 0x3cb9: 0x4030ff20, 0x3cba: 0x40310020, 0x3cbb: 0x40310120, + 0x3cbc: 0x40310220, 0x3cbd: 0x40310320, 0x3cbe: 0x40310420, 0x3cbf: 0x40310520, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x40310620, 0x3cc1: 0x40310720, 0x3cc2: 0x40310820, 0x3cc3: 0x40310920, + 0x3cc4: 0x40310a20, 0x3cc5: 0x40310b20, 0x3cc6: 0x40310c20, + 0x3ccb: 0x40316520, + 0x3ccc: 0x40316620, 0x3ccd: 0x40316720, 0x3cce: 0x40316820, 0x3ccf: 0x40316920, + 0x3cd0: 0x40316a20, 0x3cd1: 0x40316b20, 0x3cd2: 0x40316c20, 0x3cd3: 0x40316d20, + 0x3cd4: 0x40316e20, 0x3cd5: 0x40316f20, 0x3cd6: 0x40317020, 0x3cd7: 0x40317120, + 0x3cd8: 0x40317220, 0x3cd9: 0x40317320, 0x3cda: 0x40317420, 0x3cdb: 0x40317520, + 0x3cdc: 0x40317620, 0x3cdd: 0x40317720, 0x3cde: 0x40317820, 0x3cdf: 0x40317920, + 0x3ce0: 0x40317a20, 0x3ce1: 0x40317b20, 0x3ce2: 0x40317c20, 0x3ce3: 0x40317d20, + 0x3ce4: 0x40317e20, 0x3ce5: 0x40317f20, 0x3ce6: 0x40318020, 0x3ce7: 0x40318120, + 0x3ce8: 0x40318220, 0x3ce9: 0x40318320, 0x3cea: 0x40318420, 0x3ceb: 0x40318520, + 0x3cec: 0x40318620, 0x3ced: 0x40318720, 0x3cee: 0x40318820, 0x3cef: 0x40318920, + 0x3cf0: 0x40318a20, 0x3cf1: 0x40318b20, 0x3cf2: 0x40318c20, 0x3cf3: 0x40318d20, + 0x3cf4: 0x40318e20, 0x3cf5: 0x40318f20, 0x3cf6: 0x40319020, 0x3cf7: 0x40319120, + 0x3cf8: 0x40319220, 0x3cf9: 0x40319320, 0x3cfa: 0x40319420, 0x3cfb: 0x40319520, + // Block 0xf4, offset 0x3d00 + 0x3d0e: 0x41fa0e20, 0x3d0f: 0x41fa0f20, + 0x3d11: 0x41fa1120, 0x3d13: 0x41fa1320, + 0x3d14: 0x41fa1420, + 0x3d1f: 0x41fa1f20, + 0x3d21: 0x41fa2120, 0x3d23: 0x41fa2320, + 0x3d24: 0x41fa2420, 0x3d27: 0x41fa2720, + 0x3d28: 0x41fa2820, 0x3d29: 0x41fa2920, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0xf0000404, 0x3d41: 0xf0000404, 0x3d42: 0xf0000404, 0x3d43: 0xf0000404, + 0x3d44: 0xf0000404, 0x3d45: 0xe00007f8, 0x3d46: 0xf0000404, + 0x3d53: 0xf0000404, + 0x3d54: 0xf0000404, 0x3d55: 0xf0000404, 0x3d56: 0xf0000404, 0x3d57: 0xf0000404, + 0x3d5e: 0x80009602, + 0x3d60: 0xf0000005, 0x3d61: 0xf0000005, 0x3d62: 0xf0000005, 0x3d63: 0xf0000005, + 0x3d64: 0xf0000005, 0x3d65: 0xf0000005, 0x3d66: 0xf0000005, 0x3d67: 0xf0000005, + 0x3d68: 0xf0000005, 0x3d69: 0xf0000005, + // Block 0xf6, offset 0x3d80 + 0x3d8f: 0xf0000404, + 0x3d90: 0xf000001a, 0x3d91: 0xf0000019, 0x3d92: 0xf000001a, 0x3d93: 0xf0000019, + 0x3d94: 0xf0000017, 0x3d95: 0xf0000018, 0x3d96: 0xf000001a, 0x3d97: 0xf0000019, + 0x3d98: 0xf0000017, 0x3d99: 0xf0000018, 0x3d9a: 0xf000001a, 0x3d9b: 0xf0000019, + 0x3d9c: 0xf0000017, 0x3d9d: 0xf0000018, 0x3d9e: 0xf000001a, 0x3d9f: 0xf0000019, + 0x3da0: 0xf0000017, 0x3da1: 0xf0000018, 0x3da2: 0xf000001a, 0x3da3: 0xf0000019, + 0x3da4: 0xf0000017, 0x3da5: 0xf0000018, 0x3da6: 0xf000001a, 0x3da7: 0xf0000019, + 0x3da8: 0xf0000017, 0x3da9: 0xf0000018, 0x3daa: 0xf000001a, 0x3dab: 0xf0000019, + 0x3dac: 0xf0000017, 0x3dad: 0xf0000018, 0x3dae: 0xf000001a, 0x3daf: 0xf0000019, + 0x3db0: 0xf0000017, 0x3db1: 0xf0000018, 0x3db2: 0xf000001a, 0x3db3: 0xf0000019, + 0x3db4: 0xf0000017, 0x3db5: 0xf0000018, 0x3db6: 0xf000001a, 0x3db7: 0xf0000019, + 0x3db8: 0xf0000017, 0x3db9: 0xf0000018, 0x3dba: 0xf000001a, 0x3dbb: 0xf0000019, + 0x3dbc: 0xf0000017, 0x3dbd: 0xf0000018, 0x3dbe: 0xf000001a, 0x3dbf: 0xf0000019, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0xf0000017, 0x3dc1: 0xf0000018, 0x3dc2: 0xf000001a, 0x3dc3: 0xf0000019, + 0x3dc4: 0xf000001a, 0x3dc5: 0xf0000019, 0x3dc6: 0xf000001a, 0x3dc7: 0xf0000019, + 0x3dc8: 0xf000001a, 0x3dc9: 0xf0000019, 0x3dca: 0xf000001a, 0x3dcb: 0xf0000019, + 0x3dcc: 0xf000001a, 0x3dcd: 0xf0000019, 0x3dce: 0xf000001a, 0x3dcf: 0xf0000019, + 0x3dd0: 0xf0000017, 0x3dd1: 0xf0000018, 0x3dd2: 0xf000001a, 0x3dd3: 0xf0000019, + 0x3dd4: 0xf0000017, 0x3dd5: 0xf0000018, 0x3dd6: 0xf000001a, 0x3dd7: 0xf0000019, + 0x3dd8: 0xf0000017, 0x3dd9: 0xf0000018, 0x3dda: 0xf000001a, 0x3ddb: 0xf0000019, + 0x3ddc: 0xf0000017, 0x3ddd: 0xf0000018, 0x3dde: 0xf000001a, 0x3ddf: 0xf0000019, + 0x3de0: 0xf000001a, 0x3de1: 0xf0000019, 0x3de2: 0xf0000017, 0x3de3: 0xf0000018, + 0x3de4: 0xf0001a1a, 0x3de5: 0xf0001919, 0x3de6: 0xf000001a, 0x3de7: 0xf0000019, + 0x3de8: 0xf0000017, 0x3de9: 0xf0000018, 0x3dea: 0xf000001a, 0x3deb: 0xf0000019, + 0x3dec: 0xf0000017, 0x3ded: 0xf0000018, 0x3dee: 0xf000001a, 0x3def: 0xf0000019, + 0x3df0: 0xf0001a1a, 0x3df1: 0xf0001919, 0x3df2: 0x4002fd20, 0x3df3: 0x4002fe20, + 0x3df4: 0x4002ff20, 0x3df5: 0x40030020, 0x3df6: 0x40030120, 0x3df7: 0x40030220, + 0x3df8: 0x40030320, 0x3df9: 0x40030420, 0x3dfa: 0x40030520, 0x3dfb: 0x40030620, + 0x3dfc: 0x40030720, 0x3dfd: 0x40030820, 0x3dfe: 0x40030920, 0x3dff: 0x40030a20, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x40030b20, 0x3e01: 0x40030c20, + 0x3e13: 0xf000001a, + 0x3e14: 0xf0000019, 0x3e15: 0xf0000017, 0x3e16: 0xf0000018, 0x3e17: 0xf000001a, + 0x3e18: 0xf0000019, 0x3e19: 0xf000001a, 0x3e1a: 0xf0000019, 0x3e1b: 0xf000001a, + 0x3e1c: 0xf0000019, 0x3e1d: 0xf0001a1a, 0x3e1e: 0xf000001a, 0x3e1f: 0xf0000019, + 0x3e20: 0xf000001a, 0x3e21: 0xf0000019, 0x3e22: 0xf000001a, 0x3e23: 0xf0000019, + 0x3e24: 0xf000001a, 0x3e25: 0xf0000019, 0x3e26: 0xf0000017, 0x3e27: 0xf0000018, + 0x3e28: 0xf0000017, 0x3e29: 0xf0000018, 0x3e2a: 0xe000084f, 0x3e2b: 0xe000084c, + 0x3e2c: 0xe000087f, 0x3e2d: 0xe000087c, 0x3e2e: 0xe0000885, 0x3e2f: 0xe0000882, + 0x3e30: 0xe0000891, 0x3e31: 0xe000088e, 0x3e32: 0xe000088b, 0x3e33: 0xe0000888, + 0x3e34: 0xe0000897, 0x3e35: 0xe0000894, 0x3e36: 0xe00008b5, 0x3e37: 0xe00008b2, + 0x3e38: 0xe00008af, 0x3e39: 0xe00008a3, 0x3e3a: 0xe000089d, 0x3e3b: 0xe000089a, + 0x3e3c: 0xf000001a, 0x3e3d: 0xf0000019, 0x3e3e: 0xf0000017, 0x3e3f: 0xf0000018, + // Block 0xf9, offset 0x3e40 + 0x3e40: 0xe0000855, 0x3e41: 0xe000085b, 0x3e42: 0xe0000870, 0x3e43: 0xe00008a6, + 0x3e44: 0xe00008ac, 0x3e45: 0xf0001a1a, 0x3e46: 0xf0001a1a, 0x3e47: 0xf0001a1a, + 0x3e48: 0xf0001a1a, 0x3e49: 0xf0001a1a, 0x3e4a: 0xf0001a1a, 0x3e4b: 0xf0001a1a, + 0x3e4c: 0xf0001a1a, 0x3e4d: 0xf0001a1a, 0x3e4e: 0xf0001a1a, 0x3e4f: 0xf0001a1a, + 0x3e50: 0xf0001a1a, 0x3e51: 0xf0001a1a, 0x3e52: 0xf0001a1a, 0x3e53: 0xf0001a1a, + 0x3e54: 0xf0001a1a, 0x3e55: 0xf0001a1a, 0x3e56: 0xf0001a1a, 0x3e57: 0xf0001a1a, + 0x3e58: 0xf0001a1a, 0x3e59: 0xf0001a1a, 0x3e5a: 0xf0001a1a, 0x3e5b: 0xf0001a1a, + 0x3e5c: 0xf0001a1a, 0x3e5d: 0xf0001a1a, 0x3e5e: 0xf0001a1a, 0x3e5f: 0xf0001a1a, + 0x3e60: 0xf0001a1a, 0x3e61: 0xf0001a1a, 0x3e62: 0xf0001a1a, 0x3e63: 0xf0001a1a, + 0x3e64: 0xf0001a1a, 0x3e65: 0xf0001a1a, 0x3e66: 0xf0001a1a, 0x3e67: 0xf0001a1a, + 0x3e68: 0xf0001a1a, 0x3e69: 0xf0001a1a, 0x3e6a: 0xf0001a1a, 0x3e6b: 0xf0001a1a, + 0x3e6c: 0xf0001a1a, 0x3e6d: 0xf0001a1a, 0x3e6e: 0xf0001a1a, 0x3e6f: 0xf0001a1a, + 0x3e70: 0xf0001a1a, 0x3e71: 0xf0001a1a, 0x3e72: 0xf0001a1a, 0x3e73: 0xf0001a1a, + 0x3e74: 0xf0001a1a, 0x3e75: 0xf0001a1a, 0x3e76: 0xf0001a1a, 0x3e77: 0xf0001a1a, + 0x3e78: 0xf0001a1a, 0x3e79: 0xf0001a1a, 0x3e7a: 0xf0001a1a, 0x3e7b: 0xf0001a1a, + 0x3e7c: 0xf0001a1a, 0x3e7d: 0xf0001a1a, 0x3e7e: 0xf0001a1a, 0x3e7f: 0xf0001a1a, + // Block 0xfa, offset 0x3e80 + 0x3e80: 0xf0001a1a, 0x3e81: 0xf0001a1a, 0x3e82: 0xf0001a1a, 0x3e83: 0xf0001a1a, + 0x3e84: 0xf0001a1a, 0x3e85: 0xf0001a1a, 0x3e86: 0xf0001a1a, 0x3e87: 0xf0001a1a, + 0x3e88: 0xf0001a1a, 0x3e89: 0xf0001a1a, 0x3e8a: 0xf0001a1a, 0x3e8b: 0xf0001a1a, + 0x3e8c: 0xf0001a1a, 0x3e8d: 0xf0001a1a, 0x3e8e: 0xf0001a1a, 0x3e8f: 0xf0001a1a, + 0x3e90: 0xf0001a1a, 0x3e91: 0xf0001a1a, 0x3e92: 0xf0001a1a, 0x3e93: 0xf0001a1a, + 0x3e94: 0xf0001a1a, 0x3e95: 0xf0001a1a, 0x3e96: 0xf0001a1a, 0x3e97: 0xf0001a1a, + 0x3e98: 0xf0001a1a, 0x3e99: 0xf0001a1a, 0x3e9a: 0xf0001a1a, 0x3e9b: 0xf0001a1a, + 0x3e9c: 0xf0001a1a, 0x3e9d: 0xf0001a1a, 0x3e9e: 0xe0000000, 0x3e9f: 0xe0000003, + 0x3ea0: 0xe0000009, 0x3ea1: 0xe000000f, 0x3ea2: 0xe0000015, 0x3ea3: 0xe0000018, + 0x3ea4: 0xe0000861, 0x3ea5: 0xe0000864, 0x3ea6: 0xe000086d, 0x3ea7: 0xe0000873, + 0x3ea8: 0xe00008a0, 0x3ea9: 0xe00008a9, 0x3eaa: 0xf0001919, 0x3eab: 0xf0001919, + 0x3eac: 0xf0001919, 0x3ead: 0xf0001919, 0x3eae: 0xf0001919, 0x3eaf: 0xf0001919, + 0x3eb0: 0xf0001919, 0x3eb1: 0xf0001919, 0x3eb2: 0xf0001919, 0x3eb3: 0xf0001919, + 0x3eb4: 0xf0001919, 0x3eb5: 0xf0001919, 0x3eb6: 0xf0001919, 0x3eb7: 0xf0001919, + 0x3eb8: 0xf0001919, 0x3eb9: 0xf0001919, 0x3eba: 0xf0001919, 0x3ebb: 0xf0001919, + 0x3ebc: 0xf0001919, 0x3ebd: 0xf0001919, 0x3ebe: 0xf0001919, 0x3ebf: 0xf0001919, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0xf0001919, 0x3ec1: 0xf0001919, 0x3ec2: 0xf0001919, 0x3ec3: 0xf0001919, + 0x3ec4: 0xf0001919, 0x3ec5: 0xf0001919, 0x3ec6: 0xf0001919, 0x3ec7: 0xf0001919, + 0x3ec8: 0xf0001919, 0x3ec9: 0xf0001919, 0x3eca: 0xf0001919, 0x3ecb: 0xf0001919, + 0x3ecc: 0xf0001919, 0x3ecd: 0xf0001919, 0x3ece: 0xf0001919, 0x3ecf: 0xf0001919, + 0x3ed0: 0xf0001919, 0x3ed1: 0xf0001919, 0x3ed2: 0xf0001919, 0x3ed3: 0xf0001919, + 0x3ed4: 0xf0001919, 0x3ed5: 0xf0001919, 0x3ed6: 0xf0001919, 0x3ed7: 0xe0000852, + 0x3ed8: 0xe0000858, 0x3ed9: 0xe000085e, 0x3eda: 0xe0000867, 0x3edb: 0xe0000876, + 0x3edc: 0xf0001717, 0x3edd: 0xf0001717, 0x3ede: 0xf0001717, 0x3edf: 0xf0001717, + 0x3ee0: 0xf0001717, 0x3ee1: 0xf0001717, 0x3ee2: 0xf0001717, 0x3ee3: 0xf0001717, + 0x3ee4: 0xf0001717, 0x3ee5: 0xf0001717, 0x3ee6: 0xf0001717, 0x3ee7: 0xf0001717, + 0x3ee8: 0xf0001717, 0x3ee9: 0xf0001717, 0x3eea: 0xf0001717, 0x3eeb: 0xf0001717, + 0x3eec: 0xf0001717, 0x3eed: 0xf0001717, 0x3eee: 0xf0001717, 0x3eef: 0xf0001717, + 0x3ef0: 0xf0001717, 0x3ef1: 0xf0001717, 0x3ef2: 0xf0001717, 0x3ef3: 0xf0001717, + 0x3ef4: 0xf0001717, 0x3ef5: 0xf0001717, 0x3ef6: 0xf0001717, 0x3ef7: 0xf0001717, + 0x3ef8: 0xf0001717, 0x3ef9: 0xf0001717, 0x3efa: 0xf0001717, 0x3efb: 0xf0001717, + 0x3efc: 0xf0001717, 0x3efd: 0xf0001717, 0x3efe: 0xf0001717, 0x3eff: 0xf0001717, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0xf0001717, 0x3f01: 0xf0001717, 0x3f02: 0xf0001717, 0x3f03: 0xf0001717, + 0x3f04: 0xf0001717, 0x3f05: 0xf0001717, 0x3f06: 0xf0001717, 0x3f07: 0xf0001717, + 0x3f08: 0xf0001717, 0x3f09: 0xf0001717, 0x3f0a: 0xf0001717, 0x3f0b: 0xf0001717, + 0x3f0c: 0xf0001717, 0x3f0d: 0xf0001717, 0x3f0e: 0xf0001717, 0x3f0f: 0xf0001717, + 0x3f10: 0xf0001717, 0x3f11: 0xf0001717, 0x3f12: 0xf0001717, 0x3f13: 0xf0001717, + 0x3f14: 0xf0001717, 0x3f15: 0xf0001717, 0x3f16: 0xf0001717, 0x3f17: 0xf0001717, + 0x3f18: 0xf0001717, 0x3f19: 0xf0001717, 0x3f1a: 0xf0001717, 0x3f1b: 0xf0001717, + 0x3f1c: 0xf0001717, 0x3f1d: 0xf0001717, 0x3f1e: 0xf0001717, 0x3f1f: 0xe000086a, + 0x3f20: 0xe0000879, 0x3f21: 0xf0001818, 0x3f22: 0xf0001818, 0x3f23: 0xf0001818, + 0x3f24: 0xf0001818, 0x3f25: 0xf0001818, 0x3f26: 0xf0001818, 0x3f27: 0xf0001818, + 0x3f28: 0xf0001818, 0x3f29: 0xf0001818, 0x3f2a: 0xf0001818, 0x3f2b: 0xf0001818, + 0x3f2c: 0xf0001818, 0x3f2d: 0xf0001818, 0x3f2e: 0xf0001818, 0x3f2f: 0xf0001818, + 0x3f30: 0xf0001818, 0x3f31: 0xf0001818, 0x3f32: 0xe0000006, 0x3f33: 0xe000000c, + 0x3f34: 0xe0000012, 0x3f35: 0xf0001a1a, 0x3f36: 0xf0001a1a, 0x3f37: 0xf0001a1a, + 0x3f38: 0xf0001a1a, 0x3f39: 0xf0001a1a, 0x3f3a: 0xf0001a1a, 0x3f3b: 0xf0001a1a, + 0x3f3c: 0xf0001a1a, 0x3f3d: 0xf0001a1a, 0x3f3e: 0xf0001a1a, 0x3f3f: 0xf0001a1a, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0xf0001a1a, 0x3f41: 0xf0001a1a, 0x3f42: 0xf0001a1a, 0x3f43: 0xf0001a1a, + 0x3f44: 0xf0001a1a, 0x3f45: 0xf0001a1a, 0x3f46: 0xf0001a1a, 0x3f47: 0xf0001a1a, + 0x3f48: 0xf0001a1a, 0x3f49: 0xf0001a1a, 0x3f4a: 0xf0001a1a, 0x3f4b: 0xf0001a1a, + 0x3f4c: 0xf0001a1a, 0x3f4d: 0xf0001a1a, 0x3f4e: 0xf0001a1a, 0x3f4f: 0xf0001a1a, + 0x3f50: 0xf0001a1a, 0x3f51: 0xf0001919, 0x3f52: 0xf0001919, 0x3f53: 0xf0001919, + 0x3f54: 0xf0001919, 0x3f55: 0xf0001919, 0x3f56: 0xf0001919, 0x3f57: 0xf0001919, + 0x3f58: 0xf0001919, 0x3f59: 0xf0001919, 0x3f5a: 0xf0001919, 0x3f5b: 0xf0001919, + 0x3f5c: 0xf0001919, 0x3f5d: 0xf0001919, 0x3f5e: 0xf0001919, 0x3f5f: 0xf0001919, + 0x3f60: 0xf0001919, 0x3f61: 0xf0001919, 0x3f62: 0xf0001919, 0x3f63: 0xf0001919, + 0x3f64: 0xf0001919, 0x3f65: 0xf0001919, 0x3f66: 0xf0001919, 0x3f67: 0xf0001919, + 0x3f68: 0xf0001919, 0x3f69: 0xf0001919, 0x3f6a: 0xf0001919, 0x3f6b: 0xf0001919, + 0x3f6c: 0xf0001919, 0x3f6d: 0xf0001717, 0x3f6e: 0xf0001717, 0x3f6f: 0xf0001717, + 0x3f70: 0xf0001717, 0x3f71: 0xf0001717, 0x3f72: 0xf0001717, 0x3f73: 0xf0001717, + 0x3f74: 0xf0001818, 0x3f75: 0xf0001818, 0x3f76: 0xf0001818, 0x3f77: 0xf0001818, + 0x3f78: 0xf0001818, 0x3f79: 0xf0001818, 0x3f7a: 0xf0001818, 0x3f7b: 0xf0001818, + 0x3f7c: 0xf0001919, 0x3f7d: 0xf0001a1a, 0x3f7e: 0x40023920, 0x3f7f: 0x40023a20, + // Block 0xfe, offset 0x3f80 + 0x3f90: 0xf0001717, 0x3f91: 0xf0001919, 0x3f92: 0xf0001717, 0x3f93: 0xf0001717, + 0x3f94: 0xf0001717, 0x3f95: 0xf0001717, 0x3f96: 0xf0001717, 0x3f97: 0xf0001717, + 0x3f98: 0xf0001919, 0x3f99: 0xf0001717, 0x3f9a: 0xf0001919, 0x3f9b: 0xf0001919, + 0x3f9c: 0xf0001717, 0x3f9d: 0xf0001717, 0x3f9e: 0xf0001919, 0x3f9f: 0xf0001919, + 0x3fa0: 0xf0001717, 0x3fa1: 0xf0001717, 0x3fa2: 0xf0001919, 0x3fa3: 0xf0001717, + 0x3fa4: 0xf0001919, 0x3fa5: 0xf0001717, 0x3fa6: 0xf0001919, 0x3fa7: 0xf0001919, + 0x3fa8: 0xf0001717, 0x3fa9: 0xf0001919, 0x3faa: 0xf0001919, 0x3fab: 0xf0001717, + 0x3fac: 0xf0001919, 0x3fad: 0xf0001717, 0x3fae: 0xf0001919, 0x3faf: 0xf0001919, + 0x3fb0: 0xf0001717, 0x3fb1: 0xf0001919, 0x3fb2: 0xf0001717, 0x3fb3: 0xf0001717, + 0x3fb4: 0xf0001919, 0x3fb5: 0xf0001919, 0x3fb6: 0xf0001919, 0x3fb7: 0xf0001717, + 0x3fb8: 0xf0001919, 0x3fb9: 0xf0001919, 0x3fba: 0xf0001919, 0x3fbb: 0xf0001919, + 0x3fbc: 0xf0001919, 0x3fbd: 0xf0001717, 0x3fbe: 0xf0001919, 0x3fbf: 0xf0001919, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0xf0001919, 0x3fc1: 0xf0001919, 0x3fc2: 0xf0001919, 0x3fc3: 0xf0001717, + 0x3fc4: 0xf0001919, 0x3fc5: 0xf0001919, 0x3fc6: 0xf0001717, 0x3fc7: 0xf0001919, + 0x3fc8: 0xf0001717, 0x3fc9: 0xf0001717, 0x3fca: 0xf0001717, 0x3fcb: 0xf0001919, + 0x3fcc: 0xf0001717, 0x3fcd: 0xf0001717, 0x3fce: 0xf0001717, 0x3fcf: 0xf0001717, + 0x3fd2: 0xf0001717, 0x3fd3: 0xf0001717, + 0x3fd4: 0xf0001717, 0x3fd5: 0xf0001717, 0x3fd6: 0xf0001919, 0x3fd7: 0xf0001919, + 0x3fd8: 0xf0001717, 0x3fd9: 0xf0001919, 0x3fda: 0xf0001919, 0x3fdb: 0xf0001919, + 0x3fdc: 0xf0001919, 0x3fdd: 0xf0001717, 0x3fde: 0xf0001919, 0x3fdf: 0xf0001919, + 0x3fe0: 0xf0001919, 0x3fe1: 0xf0001919, 0x3fe2: 0xf0001919, 0x3fe3: 0xf0001919, + 0x3fe4: 0xf0001919, 0x3fe5: 0xf0001919, 0x3fe6: 0xf0001919, 0x3fe7: 0xf0001919, + 0x3fe8: 0xf0001919, 0x3fe9: 0xf0001919, 0x3fea: 0xf0001919, 0x3feb: 0xf0001919, + 0x3fec: 0xf0001919, 0x3fed: 0xf0001919, 0x3fee: 0xf0001919, 0x3fef: 0xf0001919, + 0x3ff0: 0xf0001919, 0x3ff1: 0xf0001919, 0x3ff2: 0xf0001919, 0x3ff3: 0xf0001919, + 0x3ff4: 0xf0001717, 0x3ff5: 0xf0001717, 0x3ff6: 0xf0001919, 0x3ff7: 0xf0001919, + 0x3ff8: 0xf0001717, 0x3ff9: 0xf0001919, 0x3ffa: 0xf0001717, 0x3ffb: 0xf0001919, + 0x3ffc: 0xf0001919, 0x3ffd: 0xf0001919, 0x3ffe: 0xf0001919, 0x3fff: 0xf0001919, + // Block 0x100, offset 0x4000 + 0x4000: 0xf0001919, 0x4001: 0xf0001919, 0x4002: 0xf0001919, 0x4003: 0xf0001717, + 0x4004: 0xf0001717, 0x4005: 0xf0001717, 0x4006: 0xf0001919, 0x4007: 0xf0001919, + 0x4030: 0xf0001a1a, 0x4031: 0xf0001a1a, 0x4032: 0xf0001a1a, 0x4033: 0xf0001a1a, + 0x4034: 0xf0001a1a, 0x4035: 0xf0001a1a, 0x4036: 0xf0001a1a, 0x4037: 0xf0001a1a, + 0x4038: 0xf0001a1a, 0x4039: 0xf0001a1a, 0x403a: 0xf0001a1a, 0x403b: 0xf0001a1a, + 0x403c: 0x4013cb20, 0x403d: 0x40038920, + // Block 0x101, offset 0x4040 + 0x4040: 0x80000000, 0x4041: 0x80000000, 0x4042: 0x80000000, 0x4043: 0x80000000, + 0x4044: 0x80000000, 0x4045: 0x80000000, 0x4046: 0x80000000, 0x4047: 0x80000000, + 0x4048: 0x80000000, 0x4049: 0x80000000, 0x404a: 0x80000000, 0x404b: 0x80000000, + 0x404c: 0x80000000, 0x404d: 0x80000000, 0x404e: 0x80000000, 0x404f: 0x80000000, + 0x4050: 0xf0000016, 0x4051: 0xf0000016, 0x4052: 0xf0000016, 0x4053: 0xf0000016, + 0x4054: 0xf0000016, 0x4055: 0xf0000016, 0x4056: 0xf0000016, 0x4057: 0xf0000016, + 0x4058: 0xf0000016, 0x4059: 0xf0001616, + 0x4060: 0x80008202, 0x4061: 0x80000000, 0x4062: 0x80008102, 0x4063: 0x80000000, + 0x4064: 0x80000000, 0x4065: 0x80000000, 0x4066: 0x80000000, + 0x4070: 0xf0001616, 0x4071: 0xf0000016, 0x4072: 0xf0000016, 0x4073: 0xf0000016, + 0x4074: 0xf0000016, 0x4075: 0xf0000016, 0x4076: 0xf0000016, 0x4077: 0xf0000016, + 0x4078: 0xf0000016, 0x4079: 0xf0000016, 0x407a: 0xf0000016, 0x407b: 0xf0000016, + 0x407c: 0xf0000016, 0x407d: 0xf0000016, 0x407e: 0xf0000016, 0x407f: 0xf0000016, + // Block 0x102, offset 0x4080 + 0x4080: 0xf0000016, 0x4081: 0xf0000016, 0x4082: 0xf0000016, 0x4083: 0xf0000016, + 0x4084: 0xf0000016, 0x4085: 0x40012c20, 0x4086: 0x40012d20, 0x4087: 0xf0000016, + 0x4088: 0xf0000016, 0x4089: 0x00021604, 0x408a: 0x00021604, 0x408b: 0x00021604, + 0x408c: 0x00021604, 0x408d: 0xf0000004, 0x408e: 0xf0000004, 0x408f: 0xf0000004, + 0x4090: 0xf000000f, 0x4091: 0xf000000f, 0x4092: 0xf000000f, + 0x4094: 0xf000000f, 0x4095: 0xf000000f, 0x4096: 0xf000000f, 0x4097: 0xf000000f, + 0x4098: 0xf000000f, 0x4099: 0xf000000f, 0x409a: 0xf000000f, 0x409b: 0xf000000f, + 0x409c: 0xf000000f, 0x409d: 0xf000000f, 0x409e: 0xf000000f, 0x409f: 0xf000000f, + 0x40a0: 0xf000000f, 0x40a1: 0xf000000f, 0x40a2: 0xf000000f, 0x40a3: 0xf000000f, + 0x40a4: 0xf000000f, 0x40a5: 0xf000000f, 0x40a6: 0xf000000f, + 0x40a8: 0xf000000f, 0x40a9: 0xf000000f, 0x40aa: 0xf000000f, 0x40ab: 0xf000000f, + 0x40b0: 0x8000a21a, 0x40b1: 0x8000a218, 0x40b2: 0x8000a31a, 0x40b3: 0x80000000, + 0x40b4: 0x8000a51a, 0x40b6: 0x8000a71a, 0x40b7: 0x8000a718, + 0x40b8: 0x8000a91a, 0x40b9: 0x8000a918, 0x40ba: 0x8000ab1a, 0x40bb: 0x8000ab18, + 0x40bc: 0x8000ad1a, 0x40bd: 0x8000ad18, 0x40be: 0x8000af1a, 0x40bf: 0x8000af18, + // Block 0x103, offset 0x40c0 + 0x40c0: 0xf000001a, 0x40c1: 0x0038781a, 0x40c2: 0x00387819, 0x40c3: 0x00387a1a, + 0x40c4: 0x00387a19, 0x40c5: 0x0038801a, 0x40c6: 0x00388019, 0x40c7: 0x0038821a, + 0x40c8: 0x00388219, 0x40c9: 0x00388a1a, 0x40ca: 0x00388a19, 0x40cb: 0x00388a17, + 0x40cc: 0x00388a18, 0x40cd: 0xf000001a, 0x40ce: 0xf0000019, 0x40cf: 0xf000001a, + 0x40d0: 0xf0000019, 0x40d1: 0xf0000017, 0x40d2: 0xf0000018, 0x40d3: 0xf000001a, + 0x40d4: 0xf0000019, 0x40d5: 0xf000001a, 0x40d6: 0xf0000019, 0x40d7: 0xf0000017, + 0x40d8: 0xf0000018, 0x40d9: 0xf000001a, 0x40da: 0xf0000019, 0x40db: 0xf0000017, + 0x40dc: 0xf0000018, 0x40dd: 0xf000001a, 0x40de: 0xf0000019, 0x40df: 0xf0000017, + 0x40e0: 0xf0000018, 0x40e1: 0xf000001a, 0x40e2: 0xf0000019, 0x40e3: 0xf0000017, + 0x40e4: 0xf0000018, 0x40e5: 0xf000001a, 0x40e6: 0xf0000019, 0x40e7: 0xf0000017, + 0x40e8: 0xf0000018, 0x40e9: 0xf000001a, 0x40ea: 0xf0000019, 0x40eb: 0xf000001a, + 0x40ec: 0xf0000019, 0x40ed: 0xf000001a, 0x40ee: 0xf0000019, 0x40ef: 0xf000001a, + 0x40f0: 0xf0000019, 0x40f1: 0xf000001a, 0x40f2: 0xf0000019, 0x40f3: 0xf0000017, + 0x40f4: 0xf0000018, 0x40f5: 0xf000001a, 0x40f6: 0xf0000019, 0x40f7: 0xf0000017, + 0x40f8: 0xf0000018, 0x40f9: 0xf000001a, 0x40fa: 0xf0000019, 0x40fb: 0xf0000017, + 0x40fc: 0xf0000018, 0x40fd: 0xf000001a, 0x40fe: 0xf0000019, 0x40ff: 0xf0000017, + // Block 0x104, offset 0x4100 + 0x4100: 0xf0000018, 0x4101: 0xf000001a, 0x4102: 0xf0000019, 0x4103: 0xf0000017, + 0x4104: 0xf0000018, 0x4105: 0xf000001a, 0x4106: 0xf0000019, 0x4107: 0xf0000017, + 0x4108: 0xf0000018, 0x4109: 0xf000001a, 0x410a: 0xf0000019, 0x410b: 0xf0000017, + 0x410c: 0xf0000018, 0x410d: 0xf000001a, 0x410e: 0xf0000019, 0x410f: 0xf0000017, + 0x4110: 0xf0000018, 0x4111: 0xf000001a, 0x4112: 0xf0000019, 0x4113: 0xf0000017, + 0x4114: 0xf0000018, 0x4115: 0xf000001a, 0x4116: 0xf0000019, 0x4117: 0xf0000017, + 0x4118: 0xf0000018, 0x4119: 0xf000001a, 0x411a: 0xf0000019, 0x411b: 0xf0000017, + 0x411c: 0xf0000018, 0x411d: 0xf000001a, 0x411e: 0xf0000019, 0x411f: 0xf0000017, + 0x4120: 0xf0000018, 0x4121: 0xf000001a, 0x4122: 0xf0000019, 0x4123: 0xf0000017, + 0x4124: 0xf0000018, 0x4125: 0xf000001a, 0x4126: 0xf0000019, 0x4127: 0xf0000017, + 0x4128: 0xf0000018, 0x4129: 0xf000001a, 0x412a: 0xf0000019, 0x412b: 0xf0000017, + 0x412c: 0xf0000018, 0x412d: 0xf000001a, 0x412e: 0xf0000019, 0x412f: 0xf000001a, + 0x4130: 0xf0000019, 0x4131: 0xf000001a, 0x4132: 0xf0000019, 0x4133: 0xf0000017, + 0x4134: 0xf0000018, 0x4135: 0xe00008bb, 0x4136: 0xe00008b8, 0x4137: 0xe00008c1, + 0x4138: 0xe00008be, 0x4139: 0xe00008c7, 0x413a: 0xe00008c4, 0x413b: 0xf0001a1a, + 0x413c: 0xf0001919, 0x413f: 0x80000000, + // Block 0x105, offset 0x4140 + 0x4141: 0xf0000003, 0x4142: 0xf0000003, 0x4143: 0xf0000003, + 0x4144: 0xf0000003, 0x4145: 0xf0000003, 0x4146: 0xf0000003, 0x4147: 0xf0000003, + 0x4148: 0xf0000003, 0x4149: 0xf0000003, 0x414a: 0xf0000003, 0x414b: 0xf0000003, + 0x414c: 0xf0000003, 0x414d: 0xf0000003, 0x414e: 0xf0000003, 0x414f: 0xf0000003, + 0x4150: 0xf0000003, 0x4151: 0xf0000003, 0x4152: 0xf0000003, 0x4153: 0xf0000003, + 0x4154: 0xf0000003, 0x4155: 0xf0000003, 0x4156: 0xf0000003, 0x4157: 0xf0000003, + 0x4158: 0xf0000003, 0x4159: 0xf0000003, 0x415a: 0xf0000003, 0x415b: 0xf0000003, + 0x415c: 0xf0000003, 0x415d: 0xf0000003, 0x415e: 0xf0000003, 0x415f: 0xf0000003, + 0x4160: 0xf0000003, 0x4161: 0xf0000009, 0x4162: 0xf0000009, 0x4163: 0xf0000009, + 0x4164: 0xf0000009, 0x4165: 0xf0000009, 0x4166: 0xf0000009, 0x4167: 0xf0000009, + 0x4168: 0xf0000009, 0x4169: 0xf0000009, 0x416a: 0xf0000009, 0x416b: 0xf0000009, + 0x416c: 0xf0000009, 0x416d: 0xf0000009, 0x416e: 0xf0000009, 0x416f: 0xf0000009, + 0x4170: 0xf0000009, 0x4171: 0xf0000009, 0x4172: 0xf0000009, 0x4173: 0xf0000009, + 0x4174: 0xf0000009, 0x4175: 0xf0000009, 0x4176: 0xf0000009, 0x4177: 0xf0000009, + 0x4178: 0xf0000009, 0x4179: 0xf0000009, 0x417a: 0xf0000009, 0x417b: 0xf0000003, + 0x417c: 0xf0000003, 0x417d: 0xf0000003, 0x417e: 0xf0000003, 0x417f: 0xf0000003, + // Block 0x106, offset 0x4180 + 0x4180: 0xf0000003, 0x4181: 0xf0000003, 0x4182: 0xf0000003, 0x4183: 0xf0000003, + 0x4184: 0xf0000003, 0x4185: 0xf0000003, 0x4186: 0xf0000003, 0x4187: 0xf0000003, + 0x4188: 0xf0000003, 0x4189: 0xf0000003, 0x418a: 0xf0000003, 0x418b: 0xf0000003, + 0x418c: 0xf0000003, 0x418d: 0xf0000003, 0x418e: 0xf0000003, 0x418f: 0xf0000003, + 0x4190: 0xf0000003, 0x4191: 0xf0000003, 0x4192: 0xf0000003, 0x4193: 0xf0000003, + 0x4194: 0xf0000003, 0x4195: 0xf0000003, 0x4196: 0xf0000003, 0x4197: 0xf0000003, + 0x4198: 0xf0000003, 0x4199: 0xf0000003, 0x419a: 0xf0000003, 0x419b: 0xf0000003, + 0x419c: 0xf0000003, 0x419d: 0xf0000003, 0x419e: 0xf0000003, 0x419f: 0xf0000003, + 0x41a0: 0xf0000003, 0x41a1: 0xf0000012, 0x41a2: 0xf0000012, 0x41a3: 0xf0000012, + 0x41a4: 0xf0000012, 0x41a5: 0xf0000012, 0x41a6: 0xf0000012, 0x41a7: 0xf0000010, + 0x41a8: 0xf0000010, 0x41a9: 0xf0000010, 0x41aa: 0xf0000010, 0x41ab: 0xf0000010, + 0x41ac: 0xf0000010, 0x41ad: 0xf0000010, 0x41ae: 0xf0000010, 0x41af: 0xf0000010, + 0x41b0: 0xf0000012, 0x41b1: 0xf0000012, 0x41b2: 0xf0000012, 0x41b3: 0xf0000012, + 0x41b4: 0xf0000012, 0x41b5: 0xf0000012, 0x41b6: 0xf0000012, 0x41b7: 0xf0000012, + 0x41b8: 0xf0000012, 0x41b9: 0xf0000012, 0x41ba: 0xf0000012, 0x41bb: 0xf0000012, + 0x41bc: 0xf0000012, 0x41bd: 0xf0000012, 0x41be: 0xf0000012, 0x41bf: 0xf0000012, + // Block 0x107, offset 0x41c0 + 0x41c0: 0xf0000012, 0x41c1: 0xf0000012, 0x41c2: 0xf0000012, 0x41c3: 0xf0000012, + 0x41c4: 0xf0000012, 0x41c5: 0xf0000012, 0x41c6: 0xf0000012, 0x41c7: 0xf0000012, + 0x41c8: 0xf0000012, 0x41c9: 0xf0000012, 0x41ca: 0xf0000012, 0x41cb: 0xf0000012, + 0x41cc: 0xf0000012, 0x41cd: 0xf0000012, 0x41ce: 0xf0000012, 0x41cf: 0xf0000012, + 0x41d0: 0xf0000012, 0x41d1: 0xf0000012, 0x41d2: 0xf0000012, 0x41d3: 0xf0000012, + 0x41d4: 0xf0000012, 0x41d5: 0xf0000012, 0x41d6: 0xf0000012, 0x41d7: 0xf0000012, + 0x41d8: 0xf0000012, 0x41d9: 0xf0000012, 0x41da: 0xf0000012, 0x41db: 0xf0000012, + 0x41dc: 0xf0000012, 0x41dd: 0xf0000012, 0x41de: 0xf0000012, 0x41df: 0xf0000012, + 0x41e0: 0xf0000012, 0x41e1: 0xf0000012, 0x41e2: 0xf0000012, 0x41e3: 0xf0000012, + 0x41e4: 0xf0000012, 0x41e5: 0xf0000012, 0x41e6: 0xf0000012, 0x41e7: 0xf0000012, + 0x41e8: 0xf0000012, 0x41e9: 0xf0000012, 0x41ea: 0xf0000012, 0x41eb: 0xf0000012, + 0x41ec: 0xf0000012, 0x41ed: 0xf0000012, 0x41ee: 0xf0000012, 0x41ef: 0xf0000012, + 0x41f0: 0xf0000012, 0x41f1: 0xf0000012, 0x41f2: 0xf0000012, 0x41f3: 0xf0000012, + 0x41f4: 0xf0000012, 0x41f5: 0xf0000012, 0x41f6: 0xf0000012, 0x41f7: 0xf0000012, + 0x41f8: 0xf0000012, 0x41f9: 0xf0000012, 0x41fa: 0xf0000012, 0x41fb: 0xf0000012, + 0x41fc: 0xf0000012, 0x41fd: 0xf0000012, 0x41fe: 0xf0000012, + // Block 0x108, offset 0x4200 + 0x4202: 0xf0000012, 0x4203: 0xf0000012, + 0x4204: 0xf0000012, 0x4205: 0xf0000012, 0x4206: 0xf0000012, 0x4207: 0xf0000012, + 0x420a: 0xf0000012, 0x420b: 0xf0000012, + 0x420c: 0xf0000012, 0x420d: 0xf0000012, 0x420e: 0xf0000012, 0x420f: 0xf0000012, + 0x4212: 0xf0000012, 0x4213: 0xf0000012, + 0x4214: 0xf0000012, 0x4215: 0xf0000012, 0x4216: 0xf0000012, 0x4217: 0xf0000012, + 0x421a: 0xf0000012, 0x421b: 0xf0000012, + 0x421c: 0xf0000012, + 0x4220: 0xf0000003, 0x4221: 0xf0000003, 0x4222: 0xf0000003, 0x4223: 0x0005e403, + 0x4224: 0xf0000003, 0x4225: 0xf0000003, 0x4226: 0xf0000003, + 0x4228: 0xf0000012, 0x4229: 0xf0000012, 0x422a: 0xf0000012, 0x422b: 0xf0000012, + 0x422c: 0xf0000012, 0x422d: 0xf0000012, 0x422e: 0xf0000012, + 0x4239: 0x80000000, 0x423a: 0x80000000, 0x423b: 0x80000000, + 0x423c: 0x40139020, 0x423d: 0x40139120, 0x423e: 0x00000205, 0x423f: 0x2bfffe05, + // Block 0x109, offset 0x4240 + 0x4240: 0x4037ce20, 0x4241: 0x4037cf20, 0x4242: 0x4037d020, 0x4243: 0x4037d120, + 0x4244: 0x4037d220, 0x4245: 0x4037d320, 0x4246: 0x4037d420, 0x4247: 0x4037d520, + 0x4248: 0x4037d620, 0x4249: 0x4037d720, 0x424a: 0x4037d820, 0x424b: 0x4037d920, + 0x424d: 0x4037da20, 0x424e: 0x4037db20, 0x424f: 0x4037dc20, + 0x4250: 0x4037dd20, 0x4251: 0x4037de20, 0x4252: 0x4037df20, 0x4253: 0x4037e020, + 0x4254: 0x4037e120, 0x4255: 0x4037e220, 0x4256: 0x4037e320, 0x4257: 0x4037e420, + 0x4258: 0x4037e520, 0x4259: 0x4037e620, 0x425a: 0x4037e720, 0x425b: 0x4037e820, + 0x425c: 0x4037e920, 0x425d: 0x4037ea20, 0x425e: 0x4037eb20, 0x425f: 0x4037ec20, + 0x4260: 0x4037ed20, 0x4261: 0x4037ee20, 0x4262: 0x4037ef20, 0x4263: 0x4037f020, + 0x4264: 0x4037f120, 0x4265: 0x4037f220, 0x4266: 0x4037f320, + 0x4268: 0x4037f420, 0x4269: 0x4037f520, 0x426a: 0x4037f620, 0x426b: 0x4037f720, + 0x426c: 0x4037f820, 0x426d: 0x4037f920, 0x426e: 0x4037fa20, 0x426f: 0x4037fb20, + 0x4270: 0x4037fc20, 0x4271: 0x4037fd20, 0x4272: 0x4037fe20, 0x4273: 0x4037ff20, + 0x4274: 0x40380020, 0x4275: 0x40380120, 0x4276: 0x40380220, 0x4277: 0x40380320, + 0x4278: 0x40380420, 0x4279: 0x40380520, 0x427a: 0x40380620, + 0x427c: 0x40380720, 0x427d: 0x40380820, 0x427f: 0x40380920, + // Block 0x10a, offset 0x4280 + 0x4280: 0x40380a20, 0x4281: 0x40380b20, 0x4282: 0x40380c20, 0x4283: 0x40380d20, + 0x4284: 0x40380e20, 0x4285: 0x40380f20, 0x4286: 0x40381020, 0x4287: 0x40381120, + 0x4288: 0x40381220, 0x4289: 0x40381320, 0x428a: 0x40381420, 0x428b: 0x40381520, + 0x428c: 0x40381620, 0x428d: 0x40381720, + 0x4290: 0x40381820, 0x4291: 0x40381920, 0x4292: 0x40381a20, 0x4293: 0x40381b20, + 0x4294: 0x40381c20, 0x4295: 0x40381d20, 0x4296: 0x40381e20, 0x4297: 0x40381f20, + 0x4298: 0x40382020, 0x4299: 0x40382120, 0x429a: 0x40382220, 0x429b: 0x40382320, + 0x429c: 0x40382420, 0x429d: 0x40382520, + // Block 0x10b, offset 0x42c0 + 0x42c0: 0x40382620, 0x42c1: 0x40382720, 0x42c2: 0x40382820, 0x42c3: 0x40382920, + 0x42c4: 0x40382a20, 0x42c5: 0x40382b20, 0x42c6: 0x40382c20, 0x42c7: 0x40382d20, + 0x42c8: 0x40382e20, 0x42c9: 0x40382f20, 0x42ca: 0x40383020, 0x42cb: 0x40383120, + 0x42cc: 0x40383220, 0x42cd: 0x40383320, 0x42ce: 0x40383420, 0x42cf: 0x40383520, + 0x42d0: 0x40383620, 0x42d1: 0x40383720, 0x42d2: 0x40383820, 0x42d3: 0x40383920, + 0x42d4: 0x40383a20, 0x42d5: 0x40383b20, 0x42d6: 0x40383c20, 0x42d7: 0x40383d20, + 0x42d8: 0x40383e20, 0x42d9: 0x40383f20, 0x42da: 0x40384020, 0x42db: 0x40384120, + 0x42dc: 0x40384220, 0x42dd: 0x40384320, 0x42de: 0x40384420, 0x42df: 0x40384520, + 0x42e0: 0x40384620, 0x42e1: 0x40384720, 0x42e2: 0x40384820, 0x42e3: 0x40384920, + 0x42e4: 0x40384a20, 0x42e5: 0x40384b20, 0x42e6: 0x40384c20, 0x42e7: 0x40384d20, + 0x42e8: 0x40384e20, 0x42e9: 0x40384f20, 0x42ea: 0x40385020, 0x42eb: 0x40385120, + 0x42ec: 0x40385220, 0x42ed: 0x40385320, 0x42ee: 0x40385420, 0x42ef: 0x40385520, + 0x42f0: 0x40385620, 0x42f1: 0x40385720, 0x42f2: 0x40385820, 0x42f3: 0x40385920, + 0x42f4: 0x40385a20, 0x42f5: 0x40385b20, 0x42f6: 0x40385c20, 0x42f7: 0x40385d20, + 0x42f8: 0x40385e20, 0x42f9: 0x40385f20, 0x42fa: 0x40386020, 0x42fb: 0x40386120, + 0x42fc: 0x40386220, 0x42fd: 0x40386320, 0x42fe: 0x40386420, 0x42ff: 0x40386520, + // Block 0x10c, offset 0x4300 + 0x4300: 0x40386620, 0x4301: 0x40386720, 0x4302: 0x40386820, 0x4303: 0x40386920, + 0x4304: 0x40386a20, 0x4305: 0x40386b20, 0x4306: 0x40386c20, 0x4307: 0x40386d20, + 0x4308: 0x40386e20, 0x4309: 0x40386f20, 0x430a: 0x40387020, 0x430b: 0x40387120, + 0x430c: 0x40387220, 0x430d: 0x40387320, 0x430e: 0x40387420, 0x430f: 0x40387520, + 0x4310: 0x40387620, 0x4311: 0x40387720, 0x4312: 0x40387820, 0x4313: 0x40387920, + 0x4314: 0x40387a20, 0x4315: 0x40387b20, 0x4316: 0x40387c20, 0x4317: 0x40387d20, + 0x4318: 0x40387e20, 0x4319: 0x40387f20, 0x431a: 0x40388020, 0x431b: 0x40388120, + 0x431c: 0x40388220, 0x431d: 0x40388320, 0x431e: 0x40388420, 0x431f: 0x40388520, + 0x4320: 0x40388620, 0x4321: 0x40388720, 0x4322: 0x40388820, 0x4323: 0x40388920, + 0x4324: 0x40388a20, 0x4325: 0x40388b20, 0x4326: 0x40388c20, 0x4327: 0x40388d20, + 0x4328: 0x40388e20, 0x4329: 0x40388f20, 0x432a: 0x40389020, 0x432b: 0x40389120, + 0x432c: 0x40389220, 0x432d: 0x40389320, 0x432e: 0x40389420, 0x432f: 0x40389520, + 0x4330: 0x40389620, 0x4331: 0x40389720, 0x4332: 0x40389820, 0x4333: 0x40389920, + 0x4334: 0x40389a20, 0x4335: 0x40389b20, 0x4336: 0x40389c20, 0x4337: 0x40389d20, + 0x4338: 0x40389e20, 0x4339: 0x40389f20, 0x433a: 0x4038a020, + // Block 0x10d, offset 0x4340 + 0x4340: 0x4001cf20, 0x4341: 0x4001d020, 0x4342: 0x40031120, + 0x4347: 0xe0000117, + 0x4348: 0xe00001fe, 0x4349: 0xe00002c4, 0x434a: 0xe0000381, 0x434b: 0xe000043b, + 0x434c: 0xe00004f2, 0x434d: 0xe000058e, 0x434e: 0xe000062a, 0x434f: 0xe00006c3, + 0x4350: 0x40141120, 0x4351: 0x40141220, 0x4352: 0x40141320, 0x4353: 0x40141420, + 0x4354: 0x40141520, 0x4355: 0x40141620, 0x4356: 0x40141720, 0x4357: 0x40141820, + 0x4358: 0x40141920, 0x4359: 0x40141a20, 0x435a: 0x40141b20, 0x435b: 0x40141c20, + 0x435c: 0x40141d20, 0x435d: 0x40141e20, 0x435e: 0x40141f20, 0x435f: 0x40142020, + 0x4360: 0x40142120, 0x4361: 0x40142220, 0x4362: 0x40142320, 0x4363: 0x40142420, + 0x4364: 0x40142520, 0x4365: 0x40142620, 0x4366: 0x40142720, 0x4367: 0x40142820, + 0x4368: 0x40142920, 0x4369: 0x40142a20, 0x436a: 0x40142b20, 0x436b: 0x40142c20, + 0x436c: 0x40142d20, 0x436d: 0x40142e20, 0x436e: 0x40142f20, 0x436f: 0x40143020, + 0x4370: 0x40143120, 0x4371: 0x40143220, 0x4372: 0x40143320, 0x4373: 0x40143420, + 0x4377: 0x400d4920, + 0x4378: 0x400d4a20, 0x4379: 0x400d4b20, 0x437a: 0x400d4c20, 0x437b: 0x400d4d20, + 0x437c: 0x400d4e20, 0x437d: 0x400d4f20, 0x437e: 0x400d5020, 0x437f: 0x400d5120, + // Block 0x10e, offset 0x4380 + 0x4380: 0x40143520, 0x4381: 0x40143620, 0x4382: 0xe000011a, 0x4383: 0xe000043e, + 0x4384: 0x40143720, 0x4385: 0x40143820, 0x4386: 0x40143920, 0x4387: 0x40143a20, + 0x4388: 0xe0000441, 0x4389: 0x40143b20, 0x438a: 0x40143c20, 0x438b: 0x40143d20, + 0x438c: 0x40143e20, 0x438d: 0x40143f20, 0x438e: 0x40144020, 0x438f: 0xe0000444, + 0x4390: 0x40144120, 0x4391: 0x40144220, 0x4392: 0x40144320, 0x4393: 0x40144420, + 0x4394: 0x40144520, 0x4395: 0x40144620, 0x4396: 0x40144720, 0x4397: 0x40144820, + 0x4398: 0xe000011d, 0x4399: 0xe0000120, 0x439a: 0xe0000123, 0x439b: 0xe0000201, + 0x439c: 0xe0000204, 0x439d: 0xe0000207, 0x439e: 0xe000020a, 0x439f: 0xe0000447, + 0x43a0: 0x40144920, 0x43a1: 0x40144a20, 0x43a2: 0x40144b20, 0x43a3: 0x40144c20, + 0x43a4: 0x40144d20, 0x43a5: 0x40144e20, 0x43a6: 0x40144f20, 0x43a7: 0x40145020, + 0x43a8: 0x40145120, 0x43a9: 0x40145220, 0x43aa: 0x40145320, 0x43ab: 0x40145420, + 0x43ac: 0x40145520, 0x43ad: 0x40145620, 0x43ae: 0x40145720, 0x43af: 0x40145820, + 0x43b0: 0x40145920, 0x43b1: 0x40145a20, 0x43b2: 0x40145b20, 0x43b3: 0xe000044a, + 0x43b4: 0x40145c20, 0x43b5: 0x40145d20, 0x43b6: 0x40145e20, 0x43b7: 0x40145f20, + 0x43b8: 0x40146020, 0x43b9: 0x400d5220, 0x43ba: 0x400d5320, 0x43bb: 0x400d5420, + 0x43bc: 0x400d5520, 0x43bd: 0x400d5620, 0x43be: 0x400d5720, 0x43bf: 0x400d5820, + // Block 0x10f, offset 0x43c0 + 0x43c0: 0x400d5920, 0x43c1: 0x400d5a20, 0x43c2: 0x400d5b20, 0x43c3: 0x400d5c20, + 0x43c4: 0x400d5d20, 0x43c5: 0x400d5e20, 0x43c6: 0x400d5f20, 0x43c7: 0x400d6020, + 0x43c8: 0x400d6120, 0x43c9: 0x400d6220, 0x43ca: 0xe0000093, + 0x43d0: 0x400d6320, 0x43d1: 0x400d6420, 0x43d2: 0x400d6520, 0x43d3: 0x400d6620, + 0x43d4: 0x400d6720, 0x43d5: 0x400d6820, 0x43d6: 0x400d6920, 0x43d7: 0x400d6a20, + 0x43d8: 0x400d6b20, 0x43d9: 0x400d6c20, 0x43da: 0x400d6d20, 0x43db: 0x400d6e20, + // Block 0x110, offset 0x4400 + 0x4410: 0x400d6f20, 0x4411: 0x400d7020, 0x4412: 0x400d7120, 0x4413: 0x400d7220, + 0x4414: 0x400d7320, 0x4415: 0x400d7420, 0x4416: 0x400d7520, 0x4417: 0x400d7620, + 0x4418: 0x400d7720, 0x4419: 0x400d7820, 0x441a: 0x400d7920, 0x441b: 0x400d7a20, + 0x441c: 0x400d7b20, 0x441d: 0x400d7c20, 0x441e: 0x400d7d20, 0x441f: 0x400d7e20, + 0x4420: 0x400d7f20, 0x4421: 0x400d8020, 0x4422: 0x400d8120, 0x4423: 0x400d8220, + 0x4424: 0x400d8320, 0x4425: 0x400d8420, 0x4426: 0x400d8520, 0x4427: 0x400d8620, + 0x4428: 0x400d8720, 0x4429: 0x400d8820, 0x442a: 0x400d8920, 0x442b: 0x400d8a20, + 0x442c: 0x400d8b20, 0x442d: 0x400d8c20, 0x442e: 0x400d8d20, 0x442f: 0x400d8e20, + 0x4430: 0x400d8f20, 0x4431: 0x400d9020, 0x4432: 0x400d9120, 0x4433: 0x400d9220, + 0x4434: 0x400d9320, 0x4435: 0x400d9420, 0x4436: 0x400d9520, 0x4437: 0x400d9620, + 0x4438: 0x400d9720, 0x4439: 0x400d9820, 0x443a: 0x400d9920, 0x443b: 0x400d9a20, + 0x443c: 0x400d9b20, 0x443d: 0x80015e02, + // Block 0x111, offset 0x4440 + 0x4440: 0x4036b620, 0x4441: 0x4036b720, 0x4442: 0x4036b820, 0x4443: 0x4036b920, + 0x4444: 0x4036ba20, 0x4445: 0x4036bb20, 0x4446: 0x4036bc20, 0x4447: 0x4036bd20, + 0x4448: 0x4036be20, 0x4449: 0x4036bf20, 0x444a: 0x4036c020, 0x444b: 0x4036c120, + 0x444c: 0x4036c220, 0x444d: 0x4036c320, 0x444e: 0x4036c420, 0x444f: 0x4036c520, + 0x4450: 0x4036c620, 0x4451: 0x4036c720, 0x4452: 0x4036c820, 0x4453: 0x4036c920, + 0x4454: 0x4036ca20, 0x4455: 0x4036cb20, 0x4456: 0x4036cc20, 0x4457: 0x4036cd20, + 0x4458: 0x4036ce20, 0x4459: 0x4036cf20, 0x445a: 0x4036d020, 0x445b: 0x4036d120, + 0x445c: 0x4036d220, + 0x4460: 0x4036d320, 0x4461: 0x4036d420, 0x4462: 0x4036d520, 0x4463: 0x4036d620, + 0x4464: 0x4036d720, 0x4465: 0x4036d820, 0x4466: 0x4036d920, 0x4467: 0x4036da20, + 0x4468: 0x4036db20, 0x4469: 0x4036dc20, 0x446a: 0x4036dd20, 0x446b: 0x4036de20, + 0x446c: 0x4036df20, 0x446d: 0x4036e020, 0x446e: 0x4036e120, 0x446f: 0x4036e220, + 0x4470: 0x4036e320, 0x4471: 0x4036e420, 0x4472: 0x4036e520, 0x4473: 0x4036e620, + 0x4474: 0x4036e720, 0x4475: 0x4036e820, 0x4476: 0x4036e920, 0x4477: 0x4036ea20, + 0x4478: 0x4036eb20, 0x4479: 0x4036ec20, 0x447a: 0x4036ed20, 0x447b: 0x4036ee20, + 0x447c: 0x4036ef20, 0x447d: 0x4036f020, 0x447e: 0x4036f120, 0x447f: 0x4036f220, + // Block 0x112, offset 0x4480 + 0x4480: 0x4036f320, 0x4481: 0x4036f420, 0x4482: 0x4036f520, 0x4483: 0x4036f620, + 0x4484: 0x4036f720, 0x4485: 0x4036f820, 0x4486: 0x4036f920, 0x4487: 0x4036fa20, + 0x4488: 0x4036fb20, 0x4489: 0x4036fc20, 0x448a: 0x4036fd20, 0x448b: 0x4036fe20, + 0x448c: 0x4036ff20, 0x448d: 0x40370020, 0x448e: 0x40370120, 0x448f: 0x40370220, + 0x4490: 0x40370320, + // Block 0x113, offset 0x44c0 + 0x44c0: 0x40371e20, 0x44c1: 0x40371f20, 0x44c2: 0x40372020, 0x44c3: 0x40372120, + 0x44c4: 0x40372220, 0x44c5: 0x40372320, 0x44c6: 0x40372420, 0x44c7: 0x40372520, + 0x44c8: 0x40372620, 0x44c9: 0x40372720, 0x44ca: 0x40372820, 0x44cb: 0x40372920, + 0x44cc: 0x40372a20, 0x44cd: 0x40372b20, 0x44ce: 0x40372c20, 0x44cf: 0x40372d20, + 0x44d0: 0x40372e20, 0x44d1: 0x40372f20, 0x44d2: 0x40373020, 0x44d3: 0x40373120, + 0x44d4: 0x40373220, 0x44d5: 0x40373320, 0x44d6: 0x40373420, 0x44d7: 0x40373520, + 0x44d8: 0x40373620, 0x44d9: 0x40373720, 0x44da: 0x40373820, 0x44db: 0x40373920, + 0x44dc: 0x40373a20, 0x44dd: 0x40373b20, 0x44de: 0x40373c20, + 0x44e0: 0xe0000126, 0x44e1: 0xe000044d, 0x44e2: 0x40140f20, 0x44e3: 0x40141020, + 0x44f0: 0x40373d20, 0x44f1: 0x40373e20, 0x44f2: 0x40373f20, 0x44f3: 0x40374020, + 0x44f4: 0x40374120, 0x44f5: 0x40374220, 0x44f6: 0x40374320, 0x44f7: 0x40374420, + 0x44f8: 0x40374520, 0x44f9: 0x40374620, 0x44fa: 0x40374720, 0x44fb: 0x40374820, + 0x44fc: 0x40374920, 0x44fd: 0x40374a20, 0x44fe: 0x40374b20, 0x44ff: 0x40374c20, + // Block 0x114, offset 0x4500 + 0x4500: 0x40374d20, 0x4501: 0x40374e20, 0x4502: 0x40374f20, 0x4503: 0x40375020, + 0x4504: 0x40375120, 0x4505: 0x40375220, 0x4506: 0x40375320, 0x4507: 0x40375420, + 0x4508: 0x40375520, 0x4509: 0x40375620, 0x450a: 0x40375720, + // Block 0x115, offset 0x4540 + 0x4540: 0x40396920, 0x4541: 0x40396a20, 0x4542: 0x40396b20, 0x4543: 0x40396c20, + 0x4544: 0x40396d20, 0x4545: 0x40396e20, 0x4546: 0x40396f20, 0x4547: 0x40397020, + 0x4548: 0x40397120, 0x4549: 0x40397220, 0x454a: 0x40397320, 0x454b: 0x40397420, + 0x454c: 0x40397520, 0x454d: 0x40397620, 0x454e: 0x40397720, 0x454f: 0x40397820, + 0x4550: 0x40397920, 0x4551: 0x40397a20, 0x4552: 0x40397b20, 0x4553: 0x40397c20, + 0x4554: 0x40397d20, 0x4555: 0x40397e20, 0x4556: 0x40397f20, 0x4557: 0x40398020, + 0x4558: 0x40398120, 0x4559: 0x40398220, 0x455a: 0x40398320, 0x455b: 0x40398420, + 0x455c: 0x40398520, 0x455d: 0x40398620, 0x455f: 0x4001d120, + 0x4560: 0x40398720, 0x4561: 0x40398820, 0x4562: 0x40398920, 0x4563: 0x40398a20, + 0x4564: 0x40398b20, 0x4565: 0x40398c20, 0x4566: 0x40398d20, 0x4567: 0x40398e20, + 0x4568: 0x40398f20, 0x4569: 0x40399020, 0x456a: 0x40399120, 0x456b: 0x40399220, + 0x456c: 0x40399320, 0x456d: 0x40399420, 0x456e: 0x40399520, 0x456f: 0x40399620, + 0x4570: 0x40399720, 0x4571: 0x40399820, 0x4572: 0x40399920, 0x4573: 0x40399a20, + 0x4574: 0x40399b20, 0x4575: 0x40399c20, 0x4576: 0x40399d20, 0x4577: 0x40399e20, + 0x4578: 0x40399f20, 0x4579: 0x4039a020, 0x457a: 0x4039a120, 0x457b: 0x4039a220, + 0x457c: 0x4039a320, 0x457d: 0x4039a420, 0x457e: 0x4039a520, 0x457f: 0x4039a620, + // Block 0x116, offset 0x4580 + 0x4580: 0x4039a720, 0x4581: 0x4039a820, 0x4582: 0x4039a920, 0x4583: 0x4039aa20, + 0x4588: 0x4039ab20, 0x4589: 0x4039ac20, 0x458a: 0x4039ad20, 0x458b: 0x4039ae20, + 0x458c: 0x4039af20, 0x458d: 0x4039b020, 0x458e: 0x4039b120, 0x458f: 0x4039b220, + 0x4590: 0x4001d220, 0x4591: 0xe0000129, 0x4592: 0xe000020d, 0x4593: 0x40146120, + 0x4594: 0x40146220, 0x4595: 0x40146320, + // Block 0x117, offset 0x45c0 + 0x45c0: 0x006eb008, 0x45c1: 0x006eb208, 0x45c2: 0x006eb408, 0x45c3: 0x006eb608, + 0x45c4: 0x006eb808, 0x45c5: 0x006eba08, 0x45c6: 0x006ebc08, 0x45c7: 0x006ebe08, + 0x45c8: 0x006ec008, 0x45c9: 0x006ec208, 0x45ca: 0x006ec408, 0x45cb: 0x006ec608, + 0x45cc: 0x006ec808, 0x45cd: 0x006eca08, 0x45ce: 0x006ecc08, 0x45cf: 0x006ece08, + 0x45d0: 0x006ed008, 0x45d1: 0x006ed208, 0x45d2: 0x006ed408, 0x45d3: 0x006ed608, + 0x45d4: 0x006ed808, 0x45d5: 0x006eda08, 0x45d6: 0x006edc08, 0x45d7: 0x006ede08, + 0x45d8: 0x006ee008, 0x45d9: 0x006ee208, 0x45da: 0x006ee408, 0x45db: 0x006ee608, + 0x45dc: 0x006ee808, 0x45dd: 0x006eea08, 0x45de: 0x006eec08, 0x45df: 0x006eee08, + 0x45e0: 0x006ef008, 0x45e1: 0x006ef208, 0x45e2: 0x006ef408, 0x45e3: 0x006ef608, + 0x45e4: 0x006ef808, 0x45e5: 0x006efa08, 0x45e6: 0x006efc08, 0x45e7: 0x006efe08, + 0x45e8: 0x40375820, 0x45e9: 0x40375920, 0x45ea: 0x40375a20, 0x45eb: 0x40375b20, + 0x45ec: 0x40375c20, 0x45ed: 0x40375d20, 0x45ee: 0x40375e20, 0x45ef: 0x40375f20, + 0x45f0: 0x40376020, 0x45f1: 0x40376120, 0x45f2: 0x40376220, 0x45f3: 0x40376320, + 0x45f4: 0x40376420, 0x45f5: 0x40376520, 0x45f6: 0x40376620, 0x45f7: 0x40376720, + 0x45f8: 0x40376820, 0x45f9: 0x40376920, 0x45fa: 0x40376a20, 0x45fb: 0x40376b20, + 0x45fc: 0x40376c20, 0x45fd: 0x40376d20, 0x45fe: 0x40376e20, 0x45ff: 0x40376f20, + // Block 0x118, offset 0x4600 + 0x4600: 0x40377020, 0x4601: 0x40377120, 0x4602: 0x40377220, 0x4603: 0x40377320, + 0x4604: 0x40377420, 0x4605: 0x40377520, 0x4606: 0x40377620, 0x4607: 0x40377720, + 0x4608: 0x40377820, 0x4609: 0x40377920, 0x460a: 0x40377a20, 0x460b: 0x40377b20, + 0x460c: 0x40377c20, 0x460d: 0x40377d20, 0x460e: 0x40377e20, 0x460f: 0x40377f20, + 0x4610: 0x40378020, 0x4611: 0x40378120, 0x4612: 0x40378220, 0x4613: 0x40378320, + 0x4614: 0x40378420, 0x4615: 0x40378520, 0x4616: 0x40378620, 0x4617: 0x40378720, + 0x4618: 0x40378820, 0x4619: 0x40378920, 0x461a: 0x40378a20, 0x461b: 0x40378b20, + 0x461c: 0x40378c20, 0x461d: 0x40378d20, 0x461e: 0x40378e20, 0x461f: 0x40378f20, + 0x4620: 0x40379020, 0x4621: 0x40379120, 0x4622: 0x40379220, 0x4623: 0x40379320, + 0x4624: 0x40379420, 0x4625: 0x40379520, 0x4626: 0x40379620, 0x4627: 0x40379720, + 0x4628: 0x40379820, 0x4629: 0x40379920, 0x462a: 0x40379a20, 0x462b: 0x40379b20, + 0x462c: 0x40379c20, 0x462d: 0x40379d20, 0x462e: 0x40379e20, 0x462f: 0x40379f20, + 0x4630: 0x4037a020, 0x4631: 0x4037a120, 0x4632: 0x4037a220, 0x4633: 0x4037a320, + 0x4634: 0x4037a420, 0x4635: 0x4037a520, 0x4636: 0x4037a620, 0x4637: 0x4037a720, + 0x4638: 0x4037a820, 0x4639: 0x4037a920, 0x463a: 0x4037aa20, 0x463b: 0x4037ab20, + 0x463c: 0x4037ac20, 0x463d: 0x4037ad20, 0x463e: 0x4037ae20, 0x463f: 0x4037af20, + // Block 0x119, offset 0x4640 + 0x4640: 0x4037b020, 0x4641: 0x4037b120, 0x4642: 0x4037b220, 0x4643: 0x4037b320, + 0x4644: 0x4037b420, 0x4645: 0x4037b520, 0x4646: 0x4037b620, 0x4647: 0x4037b720, + 0x4648: 0x4037b820, 0x4649: 0x4037b920, 0x464a: 0x4037ba20, 0x464b: 0x4037bb20, + 0x464c: 0x4037bc20, 0x464d: 0x4037bd20, 0x464e: 0x4037be20, 0x464f: 0x4037bf20, + 0x4650: 0x4037c020, 0x4651: 0x4037c120, 0x4652: 0x4037c220, 0x4653: 0x4037c320, + 0x4654: 0x4037c420, 0x4655: 0x4037c520, 0x4656: 0x4037c620, 0x4657: 0x4037c720, + 0x4658: 0x4037c820, 0x4659: 0x4037c920, 0x465a: 0x4037ca20, 0x465b: 0x4037cb20, + 0x465c: 0x4037cc20, 0x465d: 0x4037cd20, + 0x4660: 0xe000002a, 0x4661: 0xe00000a8, 0x4662: 0xe0000192, 0x4663: 0xe0000258, + 0x4664: 0xe000031b, 0x4665: 0xe00003d5, 0x4666: 0xe000048c, 0x4667: 0xe0000528, + 0x4668: 0xe00005c4, 0x4669: 0xe000065d, + // Block 0x11a, offset 0x4680 + 0x4680: 0x4038a120, 0x4681: 0x4038a220, 0x4682: 0x4038a320, 0x4683: 0x4038a420, + 0x4684: 0x4038a520, 0x4685: 0x4038a620, + 0x4688: 0x4038a720, 0x468a: 0x4038a820, 0x468b: 0x4038a920, + 0x468c: 0x4038aa20, 0x468d: 0x4038ab20, 0x468e: 0x4038ac20, 0x468f: 0x4038ad20, + 0x4690: 0x4038ae20, 0x4691: 0x4038af20, 0x4692: 0x4038b020, 0x4693: 0x4038b120, + 0x4694: 0x4038b220, 0x4695: 0x4038b320, 0x4696: 0x4038b420, 0x4697: 0x4038b520, + 0x4698: 0x4038b620, 0x4699: 0x4038b720, 0x469a: 0x4038b820, 0x469b: 0x4038b920, + 0x469c: 0x4038ba20, 0x469d: 0x4038bb20, 0x469e: 0x4038bc20, 0x469f: 0x4038bd20, + 0x46a0: 0x4038be20, 0x46a1: 0x4038bf20, 0x46a2: 0x4038c020, 0x46a3: 0x4038c120, + 0x46a4: 0x4038c220, 0x46a5: 0x4038c320, 0x46a6: 0x4038c420, 0x46a7: 0x4038c520, + 0x46a8: 0x4038c620, 0x46a9: 0x4038c720, 0x46aa: 0x4038c820, 0x46ab: 0x4038c920, + 0x46ac: 0x4038ca20, 0x46ad: 0x4038cb20, 0x46ae: 0x4038cc20, 0x46af: 0x4038cd20, + 0x46b0: 0x4038ce20, 0x46b1: 0x4038cf20, 0x46b2: 0x4038d020, 0x46b3: 0x4038d120, + 0x46b4: 0x4038d220, 0x46b5: 0x4038d320, 0x46b7: 0x4038d420, + 0x46b8: 0x4038d520, + 0x46bc: 0x4038d620, 0x46bf: 0x4038d720, + // Block 0x11b, offset 0x46c0 + 0x46c0: 0x40392a20, 0x46c1: 0x40392b20, 0x46c2: 0x40392c20, 0x46c3: 0x40392d20, + 0x46c4: 0x40392e20, 0x46c5: 0x40392f20, 0x46c6: 0x40393020, 0x46c7: 0x40393120, + 0x46c8: 0x40393220, 0x46c9: 0x40393320, 0x46ca: 0x40393420, 0x46cb: 0x40393520, + 0x46cc: 0x40393620, 0x46cd: 0x40393720, 0x46ce: 0x40393820, 0x46cf: 0x40393920, + 0x46d0: 0x40393a20, 0x46d1: 0x40393b20, 0x46d2: 0x40393c20, 0x46d3: 0x40393d20, + 0x46d4: 0x40393e20, 0x46d5: 0x40393f20, 0x46d7: 0x4001b520, + 0x46d8: 0xe0000144, 0x46d9: 0xe000022e, 0x46da: 0xe00002f4, 0x46db: 0x40146820, + 0x46dc: 0x40146920, 0x46dd: 0x40146a20, 0x46de: 0x40146b20, 0x46df: 0x40146c20, + // Block 0x11c, offset 0x4700 + 0x4700: 0x401c0b20, 0x4701: 0x401c0c20, 0x4702: 0x401c0d20, 0x4703: 0x401c0e20, + 0x4704: 0x401c0f20, 0x4705: 0x401c1020, 0x4706: 0x401c1120, 0x4707: 0x401c1220, + 0x4708: 0x401c1320, 0x4709: 0x401c1420, 0x470a: 0x401c1520, 0x470b: 0x401c1620, + 0x470c: 0x401c1720, 0x470d: 0x401c1820, 0x470e: 0x401c1920, 0x470f: 0x401c1a20, + 0x4710: 0x401c1b20, 0x4711: 0x401c1c20, 0x4712: 0x401c1d20, 0x4713: 0x401c1e20, + 0x4714: 0x401c1f20, 0x4715: 0x401c2020, 0x4716: 0xe0000141, 0x4717: 0x40146520, + 0x4718: 0x40146620, 0x4719: 0x40146720, 0x471a: 0xe000022b, 0x471b: 0xe00002f1, + 0x471f: 0x4001d320, + 0x4720: 0x40370420, 0x4721: 0x40370520, 0x4722: 0x40370620, 0x4723: 0x40370720, + 0x4724: 0x40370820, 0x4725: 0x40370920, 0x4726: 0x40370a20, 0x4727: 0x40370b20, + 0x4728: 0x40370c20, 0x4729: 0x40370d20, 0x472a: 0x40370e20, 0x472b: 0x40370f20, + 0x472c: 0x40371020, 0x472d: 0x40371120, 0x472e: 0x40371220, 0x472f: 0x40371320, + 0x4730: 0x40371420, 0x4731: 0x40371520, 0x4732: 0x40371620, 0x4733: 0x40371720, + 0x4734: 0x40371820, 0x4735: 0x40371920, 0x4736: 0x40371a20, 0x4737: 0x40371b20, + 0x4738: 0x40371c20, 0x4739: 0x40371d20, + 0x473f: 0x4001ce20, + // Block 0x11d, offset 0x4740 + 0x4740: 0x40236b20, 0x4741: 0x40236c20, 0x4742: 0x40236d20, 0x4743: 0x40236e20, + 0x4745: 0x40236f20, 0x4746: 0x40237020, + 0x474c: 0x40237120, 0x474d: 0x80006002, 0x474e: 0x80011302, 0x474f: 0x80011402, + 0x4750: 0x40237220, 0x4751: 0x40237320, 0x4752: 0x40237420, 0x4753: 0x40237520, + 0x4755: 0x40237620, 0x4756: 0x40237720, 0x4757: 0x40237820, + 0x4759: 0x40237920, 0x475a: 0x40237a20, 0x475b: 0x40237b20, + 0x475c: 0x40237c20, 0x475d: 0x40237d20, 0x475e: 0x40237e20, 0x475f: 0x40237f20, + 0x4760: 0x40238020, 0x4761: 0x40238120, 0x4762: 0x40238220, 0x4763: 0x40238320, + 0x4764: 0x40238420, 0x4765: 0x40238520, 0x4766: 0x40238620, 0x4767: 0x40238720, + 0x4768: 0x40238820, 0x4769: 0x40238920, 0x476a: 0x40238a20, 0x476b: 0x40238b20, + 0x476c: 0x40238c20, 0x476d: 0x40238d20, 0x476e: 0x40238e20, 0x476f: 0x40238f20, + 0x4770: 0x40239020, 0x4771: 0x40239120, 0x4772: 0x40239220, 0x4773: 0x40239320, + 0x4778: 0x80011502, 0x4779: 0x80011602, 0x477a: 0x80011702, + 0x477f: 0x40239420, + // Block 0x11e, offset 0x4780 + 0x4780: 0xe0000153, 0x4781: 0xe000023d, 0x4782: 0xe0000303, 0x4783: 0xe00003bd, + 0x4784: 0x40148020, 0x4785: 0x40148120, 0x4786: 0x40148220, 0x4787: 0x40148320, + 0x4790: 0x4002c720, 0x4791: 0x4002c820, 0x4792: 0x4002c920, 0x4793: 0x4002ca20, + 0x4794: 0x4002cb20, 0x4795: 0x4002cc20, 0x4796: 0x40019920, 0x4797: 0x40019a20, + 0x4798: 0x4002cd20, + 0x47a0: 0x4038d820, 0x47a1: 0x4038d920, 0x47a2: 0x4038da20, 0x47a3: 0x4038db20, + 0x47a4: 0x4038dc20, 0x47a5: 0x4038dd20, 0x47a6: 0x4038de20, 0x47a7: 0x4038df20, + 0x47a8: 0x4038e020, 0x47a9: 0x4038e120, 0x47aa: 0x4038e220, 0x47ab: 0x4038e320, + 0x47ac: 0x4038e420, 0x47ad: 0x4038e520, 0x47ae: 0x4038e620, 0x47af: 0x4038e720, + 0x47b0: 0x4038e820, 0x47b1: 0x4038e920, 0x47b2: 0x4038ea20, 0x47b3: 0x4038eb20, + 0x47b4: 0x4038ec20, 0x47b5: 0x4038ed20, 0x47b6: 0x4038ee20, 0x47b7: 0x4038ef20, + 0x47b8: 0x4038f020, 0x47b9: 0x4038f120, 0x47ba: 0x4038f220, 0x47bb: 0x4038f320, + 0x47bc: 0x4038f420, 0x47bd: 0xe000013e, 0x47be: 0x40146420, 0x47bf: 0x4002ed20, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x4038f520, 0x47c1: 0x4038f620, 0x47c2: 0x4038f720, 0x47c3: 0x4038f820, + 0x47c4: 0x4038f920, 0x47c5: 0x4038fa20, 0x47c6: 0x4038fb20, 0x47c7: 0x4038fc20, + 0x47c8: 0x4038fd20, 0x47c9: 0x4038fe20, 0x47ca: 0x4038ff20, 0x47cb: 0x40390020, + 0x47cc: 0x40390120, 0x47cd: 0x40390220, 0x47ce: 0x40390320, 0x47cf: 0x40390420, + 0x47d0: 0x40390520, 0x47d1: 0x40390620, 0x47d2: 0x40390720, 0x47d3: 0x40390820, + 0x47d4: 0x40390920, 0x47d5: 0x40390a20, 0x47d6: 0x40390b20, 0x47d7: 0x40390c20, + 0x47d8: 0x40390d20, 0x47d9: 0x40390e20, 0x47da: 0x40390f20, 0x47db: 0x40391020, + 0x47dc: 0x40391120, 0x47dd: 0x40391220, 0x47de: 0x40391320, 0x47df: 0x40391420, + 0x47e0: 0x40391520, 0x47e1: 0x40391620, 0x47e2: 0x40391720, 0x47e3: 0x40391820, + 0x47e4: 0x40391920, 0x47e5: 0x40391a20, 0x47e6: 0x40391b20, 0x47e7: 0x40391c20, + 0x47e8: 0x40391d20, 0x47e9: 0x40391e20, 0x47ea: 0x40391f20, 0x47eb: 0x40392020, + 0x47ec: 0x40392120, 0x47ed: 0x40392220, 0x47ee: 0xe0001186, 0x47ef: 0x40392320, + 0x47f0: 0x40392420, 0x47f1: 0x40392520, 0x47f2: 0x40392620, 0x47f3: 0x40392720, + 0x47f4: 0x40392820, 0x47f5: 0x40392920, + 0x47f9: 0x4002ce20, 0x47fa: 0x4001b620, 0x47fb: 0x4001b720, + 0x47fc: 0x4001b820, 0x47fd: 0x4001b920, 0x47fe: 0x4001ba20, 0x47ff: 0x4001bb20, + // Block 0x120, offset 0x4800 + 0x4800: 0x40394020, 0x4801: 0x40394120, 0x4802: 0x40394220, 0x4803: 0x40394320, + 0x4804: 0x40394420, 0x4805: 0x40394520, 0x4806: 0x40394620, 0x4807: 0x40394720, + 0x4808: 0x40394820, 0x4809: 0x40394920, 0x480a: 0x40394a20, 0x480b: 0x40394b20, + 0x480c: 0x40394c20, 0x480d: 0x40394d20, 0x480e: 0x40394e20, 0x480f: 0x40394f20, + 0x4810: 0x40395020, 0x4811: 0x40395120, 0x4812: 0x40395220, 0x4813: 0x40395320, + 0x4814: 0x40395420, 0x4815: 0x40395520, + 0x4818: 0xe0000147, 0x4819: 0xe0000231, 0x481a: 0xe00002f7, 0x481b: 0xe00003b1, + 0x481c: 0x40146d20, 0x481d: 0x40146e20, 0x481e: 0x40146f20, 0x481f: 0x40147020, + 0x4820: 0x40395620, 0x4821: 0x40395720, 0x4822: 0x40395820, 0x4823: 0x40395920, + 0x4824: 0x40395a20, 0x4825: 0x40395b20, 0x4826: 0x40395c20, 0x4827: 0x40395d20, + 0x4828: 0x40395e20, 0x4829: 0x40395f20, 0x482a: 0x40396020, 0x482b: 0x40396120, + 0x482c: 0x40396220, 0x482d: 0x40396320, 0x482e: 0x40396420, 0x482f: 0x40396520, + 0x4830: 0x40396620, 0x4831: 0x40396720, 0x4832: 0x40396820, + 0x4838: 0xe000014a, 0x4839: 0xe0000234, 0x483a: 0xe00002fa, 0x483b: 0xe00003b4, + 0x483c: 0x40147120, 0x483d: 0x40147220, 0x483e: 0x40147320, 0x483f: 0x40147420, + // Block 0x121, offset 0x4840 + 0x4840: 0x402c6e20, 0x4841: 0xe00010de, 0x4842: 0x402c6f20, 0x4843: 0x402c7020, + 0x4844: 0xe00010e1, 0x4845: 0x402c7120, 0x4846: 0x402c7220, 0x4847: 0x402c7320, + 0x4848: 0xe00010e4, 0x4849: 0x402c7420, 0x484a: 0xe00010e7, 0x484b: 0x402c7520, + 0x484c: 0xe00010ea, 0x484d: 0x402c7620, 0x484e: 0xe00010ed, 0x484f: 0x402c7720, + 0x4850: 0xe00010f0, 0x4851: 0x402c7820, 0x4852: 0xe00010f3, 0x4853: 0x402c7920, + 0x4854: 0x402c7a20, 0x4855: 0xe00010f6, 0x4856: 0x402c7b20, 0x4857: 0xe00010f9, + 0x4858: 0x402c7c20, 0x4859: 0xe00010fc, 0x485a: 0x402c7d20, 0x485b: 0xe00010ff, + 0x485c: 0x402c7e20, 0x485d: 0xe0001102, 0x485e: 0x402c7f20, 0x485f: 0xe0001105, + 0x4860: 0x402c8020, 0x4861: 0x402c8120, 0x4862: 0x402c8220, 0x4863: 0x402c8320, + 0x4864: 0x402c8420, 0x4865: 0xe0001108, 0x4866: 0x402c8520, 0x4867: 0xe000110b, + 0x4868: 0x402c8620, 0x4869: 0xe000110e, 0x486a: 0x402c8720, 0x486b: 0xe0001111, + 0x486c: 0x402c8820, 0x486d: 0x402c8920, 0x486e: 0xe0001114, 0x486f: 0x402c8a20, + 0x4870: 0x402c8b20, 0x4871: 0x402c8c20, 0x4872: 0x402c8d20, 0x4873: 0xe0001117, + 0x4874: 0x402c8e20, 0x4875: 0xe000111a, 0x4876: 0x402c8f20, 0x4877: 0xe000111d, + 0x4878: 0x402c9020, 0x4879: 0xe0001120, 0x487a: 0x402c9120, 0x487b: 0xe0001123, + 0x487c: 0x402c9220, 0x487d: 0x402c9320, 0x487e: 0x402c9420, 0x487f: 0x402c9520, + // Block 0x122, offset 0x4880 + 0x4880: 0xe0001126, 0x4881: 0x402c9620, 0x4882: 0xe0001129, 0x4883: 0x402c9720, + 0x4884: 0xe000112c, 0x4885: 0x402c9820, 0x4886: 0xe000112f, 0x4887: 0x402c9920, + 0x4888: 0x402c9a20, + // Block 0x123, offset 0x48c0 + 0x48e0: 0xe000009f, 0x48e1: 0xe0000189, 0x48e2: 0xe000024f, 0x48e3: 0xe0000312, + 0x48e4: 0xe00003cc, 0x48e5: 0xe0000483, 0x48e6: 0xe000051f, 0x48e7: 0xe00005bb, + 0x48e8: 0xe0000654, 0x48e9: 0x4013f820, 0x48ea: 0x4013f920, 0x48eb: 0x4013fa20, + 0x48ec: 0x4013fb20, 0x48ed: 0x4013fc20, 0x48ee: 0x4013fd20, 0x48ef: 0x4013fe20, + 0x48f0: 0x4013ff20, 0x48f1: 0x40140020, 0x48f2: 0x40140120, 0x48f3: 0x40140220, + 0x48f4: 0x40140320, 0x48f5: 0x40140420, 0x48f6: 0x40140520, 0x48f7: 0x40140620, + 0x48f8: 0x40140720, 0x48f9: 0x40140820, 0x48fa: 0x40140920, 0x48fb: 0x40140a20, + 0x48fc: 0x40140b20, 0x48fd: 0x40140c20, 0x48fe: 0x40140d20, + // Block 0x124, offset 0x4900 + 0x4900: 0x80011002, 0x4901: 0x80011102, 0x4902: 0x80011202, 0x4903: 0x40235620, + 0x4904: 0x40235720, 0x4905: 0x40232720, 0x4906: 0x40232820, 0x4907: 0x40232920, + 0x4908: 0x40232a20, 0x4909: 0x40232b20, 0x490a: 0x40232c20, 0x490b: 0x40232d20, + 0x490c: 0x40232e20, 0x490d: 0x40232f20, 0x490e: 0x40233020, 0x490f: 0x40233120, + 0x4910: 0x40233220, 0x4911: 0x40233320, 0x4912: 0x40233420, 0x4913: 0x40233520, + 0x4914: 0x40233620, 0x4915: 0x40233720, 0x4916: 0x40233820, 0x4917: 0x40233920, + 0x4918: 0x40233a20, 0x4919: 0x40233b20, 0x491a: 0x40233c20, 0x491b: 0x40233d20, + 0x491c: 0x40233e20, 0x491d: 0x40233f20, 0x491e: 0x40234020, 0x491f: 0x40234120, + 0x4920: 0x40234220, 0x4921: 0x40234320, 0x4922: 0x40234420, 0x4923: 0x40234520, + 0x4924: 0x40234620, 0x4925: 0x40234720, 0x4926: 0x40234820, 0x4927: 0x40234920, + 0x4928: 0x40234a20, 0x4929: 0x40234b20, 0x492a: 0x40234c20, 0x492b: 0x40234d20, + 0x492c: 0x40234e20, 0x492d: 0x40234f20, 0x492e: 0x40235020, 0x492f: 0x40235120, + 0x4930: 0x40235220, 0x4931: 0x40235320, 0x4932: 0x40235420, 0x4933: 0x40235520, + 0x4934: 0x40235820, 0x4935: 0x40235920, 0x4936: 0x40235a20, 0x4937: 0x40235b20, + 0x4938: 0x40235c20, 0x4939: 0x40235d20, 0x493a: 0x40235e20, 0x493b: 0x40235f20, + 0x493c: 0x40236020, 0x493d: 0x40236120, 0x493e: 0x40236220, 0x493f: 0x40236320, + // Block 0x125, offset 0x4940 + 0x4940: 0x40236420, 0x4941: 0x40236520, 0x4942: 0x40236620, 0x4943: 0x40236720, + 0x4944: 0x40236820, 0x4945: 0x40236920, 0x4946: 0x40236a20, 0x4947: 0x40019b20, + 0x4948: 0x40019c20, 0x4949: 0x4002c220, 0x494a: 0x4002c320, 0x494b: 0x4002c420, + 0x494c: 0x4002c520, 0x494d: 0x4002c620, + 0x4952: 0xe0000150, 0x4953: 0xe000023a, + 0x4954: 0xe0000300, 0x4955: 0xe00003ba, 0x4956: 0xe0000474, 0x4957: 0xe0000510, + 0x4958: 0xe00005ac, 0x4959: 0xe0000645, 0x495a: 0xe00006e4, 0x495b: 0x40147520, + 0x495c: 0x40147620, 0x495d: 0x40147720, 0x495e: 0x40147820, 0x495f: 0x40147920, + 0x4960: 0x40147a20, 0x4961: 0x40147b20, 0x4962: 0x40147c20, 0x4963: 0x40147d20, + 0x4964: 0x40147e20, 0x4965: 0x40147f20, 0x4966: 0xe0000096, 0x4967: 0xe000014d, + 0x4968: 0xe0000237, 0x4969: 0xe00002fd, 0x496a: 0xe00003b7, 0x496b: 0xe0000471, + 0x496c: 0xe000050d, 0x496d: 0xe00005a9, 0x496e: 0xe0000642, 0x496f: 0xe00006e1, + // Block 0x126, offset 0x4980 + 0x4980: 0x80011902, 0x4981: 0x80011a02, 0x4982: 0x80011b02, 0x4983: 0x4022c920, + 0x4984: 0x4022ca20, 0x4985: 0x4022cb20, 0x4986: 0x4022cc20, 0x4987: 0x4022cd20, + 0x4988: 0x4022ce20, 0x4989: 0x4022cf20, 0x498a: 0x4022d020, 0x498b: 0x4022d120, + 0x498c: 0x4022d220, 0x498d: 0x4022d320, 0x498e: 0x4022d420, 0x498f: 0x4022d520, + 0x4990: 0x4022d620, 0x4991: 0x4022d720, 0x4992: 0x4022d820, 0x4993: 0x4022d920, + 0x4994: 0x4022da20, 0x4995: 0x4022db20, 0x4996: 0x4022dc20, 0x4997: 0x4022dd20, + 0x4998: 0x4022de20, 0x4999: 0x4022df20, 0x499b: 0x4022e020, + 0x499d: 0x4022e120, 0x499e: 0x4022e220, 0x499f: 0x4022e320, + 0x49a0: 0x4022e420, 0x49a1: 0x4022e520, 0x49a2: 0x4022e620, 0x49a3: 0x4022e720, + 0x49a4: 0x4022e820, 0x49a5: 0x4022e920, 0x49a6: 0x4022ea20, 0x49a7: 0x4022eb20, + 0x49a8: 0x4022ec20, 0x49a9: 0x4022ed20, 0x49aa: 0x4022ee20, + 0x49ac: 0x4022ef20, 0x49ad: 0x4022f020, 0x49ae: 0x4022f120, 0x49af: 0x4022f220, + 0x49b0: 0x4022f320, 0x49b1: 0x4022f420, 0x49b2: 0x4022f520, 0x49b3: 0x4022f620, + 0x49b4: 0x4022f720, 0x49b5: 0x4022f820, 0x49b6: 0x4022f920, 0x49b7: 0x4022fa20, + 0x49b8: 0x4022fb20, 0x49b9: 0x4022fc20, 0x49ba: 0x80011802, 0x49bb: 0x4002cf20, + 0x49bc: 0x4002d020, 0x49bd: 0x80000000, 0x49be: 0x4001bc20, 0x49bf: 0x4001bd20, + // Block 0x127, offset 0x49c0 + 0x49c0: 0x40019d20, 0x49c1: 0x40019e20, + // Block 0x128, offset 0x4a00 + 0x4a00: 0x4039b320, 0x4a01: 0x4039b420, 0x4a02: 0x4039b520, 0x4a03: 0x4039b620, + 0x4a04: 0x4039b720, 0x4a05: 0x4039b820, 0x4a06: 0x4039b920, 0x4a07: 0x4039ba20, + 0x4a08: 0x4039bb20, 0x4a09: 0x4039bc20, 0x4a0a: 0x4039bd20, 0x4a0b: 0x4039be20, + 0x4a0c: 0x4039bf20, 0x4a0d: 0x4039c020, 0x4a0e: 0x4039c120, 0x4a0f: 0x4039c220, + 0x4a10: 0x4039c320, 0x4a11: 0x4039c420, 0x4a12: 0x4039c520, 0x4a13: 0x4039c620, + 0x4a14: 0x4039c720, 0x4a15: 0x4039c820, 0x4a16: 0x4039c920, 0x4a17: 0x4039ca20, + 0x4a18: 0x4039cb20, 0x4a19: 0x4039cc20, 0x4a1a: 0x4039cd20, 0x4a1b: 0x4039ce20, + 0x4a1c: 0x4039cf20, 0x4a1d: 0x4039d020, 0x4a1e: 0x4039d120, 0x4a1f: 0x4039d220, + 0x4a20: 0x4039d320, 0x4a21: 0x4039d420, 0x4a22: 0x4039d520, 0x4a23: 0x4039d620, + 0x4a24: 0x4039d720, 0x4a25: 0x4039d820, 0x4a26: 0x4039d920, 0x4a27: 0x4039da20, + 0x4a28: 0x4039db20, 0x4a29: 0x4039dc20, 0x4a2a: 0x4039dd20, 0x4a2b: 0x4039de20, + 0x4a2c: 0x4039df20, 0x4a2d: 0x4039e020, 0x4a2e: 0x4039e120, 0x4a2f: 0x4039e220, + 0x4a30: 0x4039e320, 0x4a31: 0x4039e420, 0x4a32: 0x4039e520, 0x4a33: 0x4039e620, + 0x4a34: 0x4039e720, 0x4a35: 0x4039e820, 0x4a36: 0x4039e920, 0x4a37: 0x4039ea20, + 0x4a38: 0x4039eb20, 0x4a39: 0x4039ec20, 0x4a3a: 0x4039ed20, 0x4a3b: 0x4039ee20, + 0x4a3c: 0x4039ef20, 0x4a3d: 0x4039f020, 0x4a3e: 0x4039f120, 0x4a3f: 0x4039f220, + // Block 0x129, offset 0x4a40 + 0x4a40: 0x4039f320, 0x4a41: 0x4039f420, 0x4a42: 0x4039f520, 0x4a43: 0x4039f620, + 0x4a44: 0x4039f720, 0x4a45: 0x4039f820, 0x4a46: 0x4039f920, 0x4a47: 0x4039fa20, + 0x4a48: 0x4039fb20, 0x4a49: 0x4039fc20, 0x4a4a: 0x4039fd20, 0x4a4b: 0x4039fe20, + 0x4a4c: 0x4039ff20, 0x4a4d: 0x403a0020, 0x4a4e: 0x403a0120, 0x4a4f: 0x403a0220, + 0x4a50: 0x403a0320, 0x4a51: 0x403a0420, 0x4a52: 0x403a0520, 0x4a53: 0x403a0620, + 0x4a54: 0x403a0720, 0x4a55: 0x403a0820, 0x4a56: 0x403a0920, 0x4a57: 0x403a0a20, + 0x4a58: 0x403a0b20, 0x4a59: 0x403a0c20, 0x4a5a: 0x403a0d20, 0x4a5b: 0x403a0e20, + 0x4a5c: 0x403a0f20, 0x4a5d: 0x403a1020, 0x4a5e: 0x403a1120, 0x4a5f: 0x403a1220, + 0x4a60: 0x403a1320, 0x4a61: 0x403a1420, 0x4a62: 0x403a1520, 0x4a63: 0x403a1620, + 0x4a64: 0x403a1720, 0x4a65: 0x403a1820, 0x4a66: 0x403a1920, 0x4a67: 0x403a1a20, + 0x4a68: 0x403a1b20, 0x4a69: 0x403a1c20, 0x4a6a: 0x403a1d20, 0x4a6b: 0x403a1e20, + 0x4a6c: 0x403a1f20, 0x4a6d: 0x403a2020, 0x4a6e: 0x403a2120, 0x4a6f: 0x403a2220, + 0x4a70: 0x403a2320, 0x4a71: 0x403a2420, 0x4a72: 0x403a2520, 0x4a73: 0x403a2620, + 0x4a74: 0x403a2720, 0x4a75: 0x403a2820, 0x4a76: 0x403a2920, 0x4a77: 0x403a2a20, + 0x4a78: 0x403a2b20, 0x4a79: 0x403a2c20, 0x4a7a: 0x403a2d20, 0x4a7b: 0x403a2e20, + 0x4a7c: 0x403a2f20, 0x4a7d: 0x403a3020, 0x4a7e: 0x403a3120, 0x4a7f: 0x403a3220, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x403a3320, 0x4a81: 0x403a3420, 0x4a82: 0x403a3520, 0x4a83: 0x403a3620, + 0x4a84: 0x403a3720, 0x4a85: 0x403a3820, 0x4a86: 0x403a3920, 0x4a87: 0x403a3a20, + 0x4a88: 0x403a3b20, 0x4a89: 0x403a3c20, 0x4a8a: 0x403a3d20, 0x4a8b: 0x403a3e20, + 0x4a8c: 0x403a3f20, 0x4a8d: 0x403a4020, 0x4a8e: 0x403a4120, 0x4a8f: 0x403a4220, + 0x4a90: 0x403a4320, 0x4a91: 0x403a4420, 0x4a92: 0x403a4520, 0x4a93: 0x403a4620, + 0x4a94: 0x403a4720, 0x4a95: 0x403a4820, 0x4a96: 0x403a4920, 0x4a97: 0x403a4a20, + 0x4a98: 0x403a4b20, 0x4a99: 0x403a4c20, 0x4a9a: 0x403a4d20, 0x4a9b: 0x403a4e20, + 0x4a9c: 0x403a4f20, 0x4a9d: 0x403a5020, 0x4a9e: 0x403a5120, 0x4a9f: 0x403a5220, + 0x4aa0: 0x403a5320, 0x4aa1: 0x403a5420, 0x4aa2: 0x403a5520, 0x4aa3: 0x403a5620, + 0x4aa4: 0x403a5720, 0x4aa5: 0x403a5820, 0x4aa6: 0x403a5920, 0x4aa7: 0x403a5a20, + 0x4aa8: 0x403a5b20, 0x4aa9: 0x403a5c20, 0x4aaa: 0x403a5d20, 0x4aab: 0x403a5e20, + 0x4aac: 0x403a5f20, 0x4aad: 0x403a6020, 0x4aae: 0x403a6120, 0x4aaf: 0x403a6220, + 0x4ab0: 0x403a6320, 0x4ab1: 0x403a6420, 0x4ab2: 0x403a6520, 0x4ab3: 0x403a6620, + 0x4ab4: 0x403a6720, 0x4ab5: 0x403a6820, 0x4ab6: 0x403a6920, 0x4ab7: 0x403a6a20, + 0x4ab8: 0x403a6b20, 0x4ab9: 0x403a6c20, 0x4aba: 0x403a6d20, 0x4abb: 0x403a6e20, + 0x4abc: 0x403a6f20, 0x4abd: 0x403a7020, 0x4abe: 0x403a7120, 0x4abf: 0x403a7220, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x403a7320, 0x4ac1: 0x403a7420, 0x4ac2: 0x403a7520, 0x4ac3: 0x403a7620, + 0x4ac4: 0x403a7720, 0x4ac5: 0x403a7820, 0x4ac6: 0x403a7920, 0x4ac7: 0x403a7a20, + 0x4ac8: 0x403a7b20, 0x4ac9: 0x403a7c20, 0x4aca: 0x403a7d20, 0x4acb: 0x403a7e20, + 0x4acc: 0x403a7f20, 0x4acd: 0x403a8020, 0x4ace: 0x403a8120, 0x4acf: 0x403a8220, + 0x4ad0: 0x403a8320, 0x4ad1: 0x403a8420, 0x4ad2: 0x403a8520, 0x4ad3: 0x403a8620, + 0x4ad4: 0x403a8720, 0x4ad5: 0x403a8820, 0x4ad6: 0x403a8920, 0x4ad7: 0x403a8a20, + 0x4ad8: 0x403a8b20, 0x4ad9: 0x403a8c20, 0x4ada: 0x403a8d20, 0x4adb: 0x403a8e20, + 0x4adc: 0x403a8f20, 0x4add: 0x403a9020, 0x4ade: 0x403a9120, 0x4adf: 0x403a9220, + 0x4ae0: 0x403a9320, 0x4ae1: 0x403a9420, 0x4ae2: 0x403a9520, 0x4ae3: 0x403a9620, + 0x4ae4: 0x403a9720, 0x4ae5: 0x403a9820, 0x4ae6: 0x403a9920, 0x4ae7: 0x403a9a20, + 0x4ae8: 0x403a9b20, 0x4ae9: 0x403a9c20, 0x4aea: 0x403a9d20, 0x4aeb: 0x403a9e20, + 0x4aec: 0x403a9f20, 0x4aed: 0x403aa020, 0x4aee: 0x403aa120, 0x4aef: 0x403aa220, + 0x4af0: 0x403aa320, 0x4af1: 0x403aa420, 0x4af2: 0x403aa520, 0x4af3: 0x403aa620, + 0x4af4: 0x403aa720, 0x4af5: 0x403aa820, 0x4af6: 0x403aa920, 0x4af7: 0x403aaa20, + 0x4af8: 0x403aab20, 0x4af9: 0x403aac20, 0x4afa: 0x403aad20, 0x4afb: 0x403aae20, + 0x4afc: 0x403aaf20, 0x4afd: 0x403ab020, 0x4afe: 0x403ab120, 0x4aff: 0x403ab220, + // Block 0x12c, offset 0x4b00 + 0x4b00: 0x403ab320, 0x4b01: 0x403ab420, 0x4b02: 0x403ab520, 0x4b03: 0x403ab620, + 0x4b04: 0x403ab720, 0x4b05: 0x403ab820, 0x4b06: 0x403ab920, 0x4b07: 0x403aba20, + 0x4b08: 0x403abb20, 0x4b09: 0x403abc20, 0x4b0a: 0x403abd20, 0x4b0b: 0x403abe20, + 0x4b0c: 0x403abf20, 0x4b0d: 0x403ac020, 0x4b0e: 0x403ac120, 0x4b0f: 0x403ac220, + 0x4b10: 0x403ac320, 0x4b11: 0x403ac420, 0x4b12: 0x403ac520, 0x4b13: 0x403ac620, + 0x4b14: 0x403ac720, 0x4b15: 0x403ac820, 0x4b16: 0x403ac920, 0x4b17: 0x403aca20, + 0x4b18: 0x403acb20, 0x4b19: 0x403acc20, 0x4b1a: 0x403acd20, 0x4b1b: 0x403ace20, + 0x4b1c: 0x403acf20, 0x4b1d: 0x403ad020, 0x4b1e: 0x403ad120, 0x4b1f: 0x403ad220, + 0x4b20: 0x403ad320, 0x4b21: 0x403ad420, 0x4b22: 0x403ad520, 0x4b23: 0x403ad620, + 0x4b24: 0x403ad720, 0x4b25: 0x403ad820, 0x4b26: 0x403ad920, 0x4b27: 0x403ada20, + 0x4b28: 0x403adb20, 0x4b29: 0x403adc20, 0x4b2a: 0x403add20, 0x4b2b: 0x403ade20, + 0x4b2c: 0x403adf20, 0x4b2d: 0x403ae020, 0x4b2e: 0x403ae120, 0x4b2f: 0x403ae220, + 0x4b30: 0x403ae320, 0x4b31: 0x403ae420, 0x4b32: 0x403ae520, 0x4b33: 0x403ae620, + 0x4b34: 0x403ae720, 0x4b35: 0x403ae820, 0x4b36: 0x403ae920, 0x4b37: 0x403aea20, + 0x4b38: 0x403aeb20, 0x4b39: 0x403aec20, 0x4b3a: 0x403aed20, 0x4b3b: 0x403aee20, + 0x4b3c: 0x403aef20, 0x4b3d: 0x403af020, 0x4b3e: 0x403af120, 0x4b3f: 0x403af220, + // Block 0x12d, offset 0x4b40 + 0x4b40: 0x403af320, 0x4b41: 0x403af420, 0x4b42: 0x403af520, 0x4b43: 0x403af620, + 0x4b44: 0x403af720, 0x4b45: 0x403af820, 0x4b46: 0x403af920, 0x4b47: 0x403afa20, + 0x4b48: 0x403afb20, 0x4b49: 0x403afc20, 0x4b4a: 0x403afd20, 0x4b4b: 0x403afe20, + 0x4b4c: 0x403aff20, 0x4b4d: 0x403b0020, 0x4b4e: 0x403b0120, 0x4b4f: 0x403b0220, + 0x4b50: 0x403b0320, 0x4b51: 0x403b0420, 0x4b52: 0x403b0520, 0x4b53: 0x403b0620, + 0x4b54: 0x403b0720, 0x4b55: 0x403b0820, 0x4b56: 0x403b0920, 0x4b57: 0x403b0a20, + 0x4b58: 0x403b0b20, 0x4b59: 0x403b0c20, 0x4b5a: 0x403b0d20, 0x4b5b: 0x403b0e20, + 0x4b5c: 0x403b0f20, 0x4b5d: 0x403b1020, 0x4b5e: 0x403b1120, 0x4b5f: 0x403b1220, + 0x4b60: 0x403b1320, 0x4b61: 0x403b1420, 0x4b62: 0x403b1520, 0x4b63: 0x403b1620, + 0x4b64: 0x403b1720, 0x4b65: 0x403b1820, 0x4b66: 0x403b1920, 0x4b67: 0x403b1a20, + 0x4b68: 0x403b1b20, 0x4b69: 0x403b1c20, 0x4b6a: 0x403b1d20, 0x4b6b: 0x403b1e20, + 0x4b6c: 0x403b1f20, 0x4b6d: 0x403b2020, 0x4b6e: 0x403b2120, 0x4b6f: 0x403b2220, + 0x4b70: 0x403b2320, 0x4b71: 0x403b2420, 0x4b72: 0x403b2520, 0x4b73: 0x403b2620, + 0x4b74: 0x403b2720, 0x4b75: 0x403b2820, 0x4b76: 0x403b2920, 0x4b77: 0x403b2a20, + 0x4b78: 0x403b2b20, 0x4b79: 0x403b2c20, 0x4b7a: 0x403b2d20, 0x4b7b: 0x403b2e20, + 0x4b7c: 0x403b2f20, 0x4b7d: 0x403b3020, 0x4b7e: 0x403b3120, 0x4b7f: 0x403b3220, + // Block 0x12e, offset 0x4b80 + 0x4b80: 0x403b3320, 0x4b81: 0x403b3420, 0x4b82: 0x403b3520, 0x4b83: 0x403b3620, + 0x4b84: 0x403b3720, 0x4b85: 0x403b3820, 0x4b86: 0x403b3920, 0x4b87: 0x403b3a20, + 0x4b88: 0x403b3b20, 0x4b89: 0x403b3c20, 0x4b8a: 0x403b3d20, 0x4b8b: 0x403b3e20, + 0x4b8c: 0x403b3f20, 0x4b8d: 0x403b4020, 0x4b8e: 0x403b4120, 0x4b8f: 0x403b4220, + 0x4b90: 0x403b4320, 0x4b91: 0x403b4420, 0x4b92: 0x403b4520, 0x4b93: 0x403b4620, + 0x4b94: 0x403b4720, 0x4b95: 0x403b4820, 0x4b96: 0x403b4920, 0x4b97: 0x403b4a20, + 0x4b98: 0x403b4b20, 0x4b99: 0x403b4c20, 0x4b9a: 0x403b4d20, 0x4b9b: 0x403b4e20, + 0x4b9c: 0x403b4f20, 0x4b9d: 0x403b5020, 0x4b9e: 0x403b5120, 0x4b9f: 0x403b5220, + 0x4ba0: 0x403b5320, 0x4ba1: 0x403b5420, 0x4ba2: 0x403b5520, 0x4ba3: 0x403b5620, + 0x4ba4: 0x403b5720, 0x4ba5: 0x403b5820, 0x4ba6: 0x403b5920, 0x4ba7: 0x403b5a20, + 0x4ba8: 0x403b5b20, 0x4ba9: 0x403b5c20, 0x4baa: 0x403b5d20, 0x4bab: 0x403b5e20, + 0x4bac: 0x403b5f20, 0x4bad: 0x403b6020, 0x4bae: 0x403b6120, 0x4baf: 0x403b6220, + 0x4bb0: 0x403b6320, 0x4bb1: 0x403b6420, 0x4bb2: 0x403b6520, 0x4bb3: 0x403b6620, + 0x4bb4: 0x403b6720, 0x4bb5: 0x403b6820, 0x4bb6: 0x403b6920, 0x4bb7: 0x403b6a20, + 0x4bb8: 0x403b6b20, 0x4bb9: 0x403b6c20, 0x4bba: 0x403b6d20, 0x4bbb: 0x403b6e20, + 0x4bbc: 0x403b6f20, 0x4bbd: 0x403b7020, 0x4bbe: 0x403b7120, 0x4bbf: 0x403b7220, + // Block 0x12f, offset 0x4bc0 + 0x4bc0: 0x403b7320, 0x4bc1: 0x403b7420, 0x4bc2: 0x403b7520, 0x4bc3: 0x403b7620, + 0x4bc4: 0x403b7720, 0x4bc5: 0x403b7820, 0x4bc6: 0x403b7920, 0x4bc7: 0x403b7a20, + 0x4bc8: 0x403b7b20, 0x4bc9: 0x403b7c20, 0x4bca: 0x403b7d20, 0x4bcb: 0x403b7e20, + 0x4bcc: 0x403b7f20, 0x4bcd: 0x403b8020, 0x4bce: 0x403b8120, 0x4bcf: 0x403b8220, + 0x4bd0: 0x403b8320, 0x4bd1: 0x403b8420, 0x4bd2: 0x403b8520, 0x4bd3: 0x403b8620, + 0x4bd4: 0x403b8720, 0x4bd5: 0x403b8820, 0x4bd6: 0x403b8920, 0x4bd7: 0x403b8a20, + 0x4bd8: 0x403b8b20, 0x4bd9: 0x403b8c20, 0x4bda: 0x403b8d20, 0x4bdb: 0x403b8e20, + 0x4bdc: 0x403b8f20, 0x4bdd: 0x403b9020, 0x4bde: 0x403b9120, 0x4bdf: 0x403b9220, + 0x4be0: 0x403b9320, 0x4be1: 0x403b9420, 0x4be2: 0x403b9520, 0x4be3: 0x403b9620, + 0x4be4: 0x403b9720, 0x4be5: 0x403b9820, 0x4be6: 0x403b9920, 0x4be7: 0x403b9a20, + 0x4be8: 0x403b9b20, 0x4be9: 0x403b9c20, 0x4bea: 0x403b9d20, 0x4beb: 0x403b9e20, + 0x4bec: 0x403b9f20, 0x4bed: 0x403ba020, 0x4bee: 0x403ba120, 0x4bef: 0x403ba220, + 0x4bf0: 0x403ba320, 0x4bf1: 0x403ba420, 0x4bf2: 0x403ba520, 0x4bf3: 0x403ba620, + 0x4bf4: 0x403ba720, 0x4bf5: 0x403ba820, 0x4bf6: 0x403ba920, 0x4bf7: 0x403baa20, + 0x4bf8: 0x403bab20, 0x4bf9: 0x403bac20, 0x4bfa: 0x403bad20, 0x4bfb: 0x403bae20, + 0x4bfc: 0x403baf20, 0x4bfd: 0x403bb020, 0x4bfe: 0x403bb120, 0x4bff: 0x403bb220, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x403bb320, 0x4c01: 0x403bb420, 0x4c02: 0x403bb520, 0x4c03: 0x403bb620, + 0x4c04: 0x403bb720, 0x4c05: 0x403bb820, 0x4c06: 0x403bb920, 0x4c07: 0x403bba20, + 0x4c08: 0x403bbb20, 0x4c09: 0x403bbc20, 0x4c0a: 0x403bbd20, 0x4c0b: 0x403bbe20, + 0x4c0c: 0x403bbf20, 0x4c0d: 0x403bc020, 0x4c0e: 0x403bc120, 0x4c0f: 0x403bc220, + 0x4c10: 0x403bc320, 0x4c11: 0x403bc420, 0x4c12: 0x403bc520, 0x4c13: 0x403bc620, + 0x4c14: 0x403bc720, 0x4c15: 0x403bc820, 0x4c16: 0x403bc920, 0x4c17: 0x403bca20, + 0x4c18: 0x403bcb20, 0x4c19: 0x403bcc20, 0x4c1a: 0x403bcd20, 0x4c1b: 0x403bce20, + 0x4c1c: 0x403bcf20, 0x4c1d: 0x403bd020, 0x4c1e: 0x403bd120, 0x4c1f: 0x403bd220, + 0x4c20: 0x403bd320, 0x4c21: 0x403bd420, 0x4c22: 0x403bd520, 0x4c23: 0x403bd620, + 0x4c24: 0x403bd720, 0x4c25: 0x403bd820, 0x4c26: 0x403bd920, 0x4c27: 0x403bda20, + 0x4c28: 0x403bdb20, 0x4c29: 0x403bdc20, 0x4c2a: 0x403bdd20, 0x4c2b: 0x403bde20, + 0x4c2c: 0x403bdf20, 0x4c2d: 0x403be020, 0x4c2e: 0x403be120, 0x4c2f: 0x403be220, + 0x4c30: 0x403be320, 0x4c31: 0x403be420, 0x4c32: 0x403be520, 0x4c33: 0x403be620, + 0x4c34: 0x403be720, 0x4c35: 0x403be820, 0x4c36: 0x403be920, 0x4c37: 0x403bea20, + 0x4c38: 0x403beb20, 0x4c39: 0x403bec20, 0x4c3a: 0x403bed20, 0x4c3b: 0x403bee20, + 0x4c3c: 0x403bef20, 0x4c3d: 0x403bf020, 0x4c3e: 0x403bf120, 0x4c3f: 0x403bf220, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x403bf320, 0x4c41: 0x403bf420, 0x4c42: 0x403bf520, 0x4c43: 0x403bf620, + 0x4c44: 0x403bf720, 0x4c45: 0x403bf820, 0x4c46: 0x403bf920, 0x4c47: 0x403bfa20, + 0x4c48: 0x403bfb20, 0x4c49: 0x403bfc20, 0x4c4a: 0x403bfd20, 0x4c4b: 0x403bfe20, + 0x4c4c: 0x403bff20, 0x4c4d: 0x403c0020, 0x4c4e: 0x403c0120, 0x4c4f: 0x403c0220, + 0x4c50: 0x403c0320, 0x4c51: 0x403c0420, 0x4c52: 0x403c0520, 0x4c53: 0x403c0620, + 0x4c54: 0x403c0720, 0x4c55: 0x403c0820, 0x4c56: 0x403c0920, 0x4c57: 0x403c0a20, + 0x4c58: 0x403c0b20, 0x4c59: 0x403c0c20, 0x4c5a: 0x403c0d20, 0x4c5b: 0x403c0e20, + 0x4c5c: 0x403c0f20, 0x4c5d: 0x403c1020, 0x4c5e: 0x403c1120, 0x4c5f: 0x403c1220, + 0x4c60: 0x403c1320, 0x4c61: 0x403c1420, 0x4c62: 0x403c1520, 0x4c63: 0x403c1620, + 0x4c64: 0x403c1720, 0x4c65: 0x403c1820, 0x4c66: 0x403c1920, 0x4c67: 0x403c1a20, + 0x4c68: 0x403c1b20, 0x4c69: 0x403c1c20, 0x4c6a: 0x403c1d20, 0x4c6b: 0x403c1e20, + 0x4c6c: 0x403c1f20, 0x4c6d: 0x403c2020, 0x4c6e: 0x403c2120, 0x4c6f: 0x403c2220, + 0x4c70: 0x403c2320, 0x4c71: 0x403c2420, 0x4c72: 0x403c2520, 0x4c73: 0x403c2620, + 0x4c74: 0x403c2720, 0x4c75: 0x403c2820, 0x4c76: 0x403c2920, 0x4c77: 0x403c2a20, + 0x4c78: 0x403c2b20, 0x4c79: 0x403c2c20, 0x4c7a: 0x403c2d20, 0x4c7b: 0x403c2e20, + 0x4c7c: 0x403c2f20, 0x4c7d: 0x403c3020, 0x4c7e: 0x403c3120, 0x4c7f: 0x403c3220, + // Block 0x132, offset 0x4c80 + 0x4c80: 0x403c3320, 0x4c81: 0x403c3420, 0x4c82: 0x403c3520, 0x4c83: 0x403c3620, + 0x4c84: 0x403c3720, 0x4c85: 0x403c3820, 0x4c86: 0x403c3920, 0x4c87: 0x403c3a20, + 0x4c88: 0x403c3b20, 0x4c89: 0x403c3c20, 0x4c8a: 0x403c3d20, 0x4c8b: 0x403c3e20, + 0x4c8c: 0x403c3f20, 0x4c8d: 0x403c4020, 0x4c8e: 0x403c4120, 0x4c8f: 0x403c4220, + 0x4c90: 0x403c4320, 0x4c91: 0x403c4420, 0x4c92: 0x403c4520, 0x4c93: 0x403c4620, + 0x4c94: 0x403c4720, 0x4c95: 0x403c4820, 0x4c96: 0x403c4920, 0x4c97: 0x403c4a20, + 0x4c98: 0x403c4b20, 0x4c99: 0x403c4c20, 0x4c9a: 0x403c4d20, 0x4c9b: 0x403c4e20, + 0x4c9c: 0x403c4f20, 0x4c9d: 0x403c5020, 0x4c9e: 0x403c5120, 0x4c9f: 0x403c5220, + 0x4ca0: 0x403c5320, 0x4ca1: 0x403c5420, 0x4ca2: 0x403c5520, 0x4ca3: 0x403c5620, + 0x4ca4: 0x403c5720, 0x4ca5: 0x403c5820, 0x4ca6: 0x403c5920, 0x4ca7: 0x403c5a20, + 0x4ca8: 0x403c5b20, 0x4ca9: 0x403c5c20, 0x4caa: 0x403c5d20, 0x4cab: 0x403c5e20, + 0x4cac: 0x403c5f20, 0x4cad: 0x403c6020, 0x4cae: 0x403c6120, 0x4caf: 0x403c6220, + 0x4cb0: 0x403c6320, 0x4cb1: 0x403c6420, 0x4cb2: 0x403c6520, 0x4cb3: 0x403c6620, + 0x4cb4: 0x403c6720, 0x4cb5: 0x403c6820, 0x4cb6: 0x403c6920, 0x4cb7: 0x403c6a20, + 0x4cb8: 0x403c6b20, 0x4cb9: 0x403c6c20, 0x4cba: 0x403c6d20, 0x4cbb: 0x403c6e20, + 0x4cbc: 0x403c6f20, 0x4cbd: 0x403c7020, 0x4cbe: 0x403c7120, 0x4cbf: 0x403c7220, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x403c7320, 0x4cc1: 0x403c7420, 0x4cc2: 0x403c7520, 0x4cc3: 0x403c7620, + 0x4cc4: 0x403c7720, 0x4cc5: 0x403c7820, 0x4cc6: 0x403c7920, 0x4cc7: 0x403c7a20, + 0x4cc8: 0x403c7b20, 0x4cc9: 0x403c7c20, 0x4cca: 0x403c7d20, 0x4ccb: 0x403c7e20, + 0x4ccc: 0x403c7f20, 0x4ccd: 0x403c8020, 0x4cce: 0x403c8120, 0x4ccf: 0x403c8220, + 0x4cd0: 0x403c8320, 0x4cd1: 0x403c8420, 0x4cd2: 0x403c8520, 0x4cd3: 0x403c8620, + 0x4cd4: 0x403c8720, 0x4cd5: 0x403c8820, 0x4cd6: 0x403c8920, 0x4cd7: 0x403c8a20, + 0x4cd8: 0x403c8b20, 0x4cd9: 0x403c8c20, 0x4cda: 0x403c8d20, 0x4cdb: 0x403c8e20, + 0x4cdc: 0x403c8f20, 0x4cdd: 0x403c9020, 0x4cde: 0x403c9120, 0x4cdf: 0x403c9220, + 0x4ce0: 0x403c9320, 0x4ce1: 0x403c9420, 0x4ce2: 0x403c9520, 0x4ce3: 0x403c9620, + 0x4ce4: 0x403c9720, 0x4ce5: 0x403c9820, 0x4ce6: 0x403c9920, 0x4ce7: 0x403c9a20, + 0x4ce8: 0x403c9b20, 0x4ce9: 0x403c9c20, 0x4cea: 0x403c9d20, 0x4ceb: 0x403c9e20, + 0x4cec: 0x403c9f20, 0x4ced: 0x403ca020, 0x4cee: 0x403ca120, 0x4cef: 0x403ca220, + 0x4cf0: 0x403ca320, 0x4cf1: 0x403ca420, 0x4cf2: 0x403ca520, 0x4cf3: 0x403ca620, + 0x4cf4: 0x403ca720, 0x4cf5: 0x403ca820, 0x4cf6: 0x403ca920, 0x4cf7: 0x403caa20, + 0x4cf8: 0x403cab20, 0x4cf9: 0x403cac20, 0x4cfa: 0x403cad20, 0x4cfb: 0x403cae20, + 0x4cfc: 0x403caf20, 0x4cfd: 0x403cb020, 0x4cfe: 0x403cb120, 0x4cff: 0x403cb220, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x403cb320, 0x4d01: 0x403cb420, 0x4d02: 0x403cb520, 0x4d03: 0x403cb620, + 0x4d04: 0x403cb720, 0x4d05: 0x403cb820, 0x4d06: 0x403cb920, 0x4d07: 0x403cba20, + 0x4d08: 0x403cbb20, 0x4d09: 0x403cbc20, 0x4d0a: 0x403cbd20, 0x4d0b: 0x403cbe20, + 0x4d0c: 0x403cbf20, 0x4d0d: 0x403cc020, 0x4d0e: 0x403cc120, 0x4d0f: 0x403cc220, + 0x4d10: 0x403cc320, 0x4d11: 0x403cc420, 0x4d12: 0x403cc520, 0x4d13: 0x403cc620, + 0x4d14: 0x403cc720, 0x4d15: 0x403cc820, 0x4d16: 0x403cc920, 0x4d17: 0x403cca20, + 0x4d18: 0x403ccb20, 0x4d19: 0x403ccc20, 0x4d1a: 0x403ccd20, 0x4d1b: 0x403cce20, + 0x4d1c: 0x403ccf20, 0x4d1d: 0x403cd020, 0x4d1e: 0x403cd120, 0x4d1f: 0x403cd220, + 0x4d20: 0x403cd320, 0x4d21: 0x403cd420, 0x4d22: 0x403cd520, 0x4d23: 0x403cd620, + 0x4d24: 0x403cd720, 0x4d25: 0x403cd820, 0x4d26: 0x403cd920, 0x4d27: 0x403cda20, + 0x4d28: 0x403cdb20, 0x4d29: 0x403cdc20, 0x4d2a: 0x403cdd20, 0x4d2b: 0x403cde20, + 0x4d2c: 0x403cdf20, 0x4d2d: 0x403ce020, 0x4d2e: 0x403ce120, 0x4d2f: 0x403ce220, + 0x4d30: 0x403ce320, 0x4d31: 0x403ce420, 0x4d32: 0x403ce520, 0x4d33: 0x403ce620, + 0x4d34: 0x403ce720, 0x4d35: 0x403ce820, 0x4d36: 0x403ce920, 0x4d37: 0x403cea20, + 0x4d38: 0x403ceb20, 0x4d39: 0x403cec20, 0x4d3a: 0x403ced20, 0x4d3b: 0x403cee20, + 0x4d3c: 0x403cef20, 0x4d3d: 0x403cf020, 0x4d3e: 0x403cf120, 0x4d3f: 0x403cf220, + // Block 0x135, offset 0x4d40 + 0x4d40: 0x403cf320, 0x4d41: 0x403cf420, 0x4d42: 0x403cf520, 0x4d43: 0x403cf620, + 0x4d44: 0x403cf720, 0x4d45: 0x403cf820, 0x4d46: 0x403cf920, 0x4d47: 0x403cfa20, + 0x4d48: 0x403cfb20, 0x4d49: 0x403cfc20, 0x4d4a: 0x403cfd20, 0x4d4b: 0x403cfe20, + 0x4d4c: 0x403cff20, 0x4d4d: 0x403d0020, 0x4d4e: 0x403d0120, 0x4d4f: 0x403d0220, + 0x4d50: 0x403d0320, 0x4d51: 0x403d0420, 0x4d52: 0x403d0520, 0x4d53: 0x403d0620, + 0x4d54: 0x403d0720, 0x4d55: 0x403d0820, 0x4d56: 0x403d0920, 0x4d57: 0x403d0a20, + 0x4d58: 0x403d0b20, 0x4d59: 0x403d0c20, 0x4d5a: 0x403d0d20, 0x4d5b: 0x403d0e20, + 0x4d5c: 0x403d0f20, 0x4d5d: 0x403d1020, 0x4d5e: 0x403d1120, 0x4d5f: 0x403d1220, + 0x4d60: 0x403d1320, 0x4d61: 0x403d1420, 0x4d62: 0x403d1520, 0x4d63: 0x403d1620, + 0x4d64: 0x403d1720, 0x4d65: 0x403d1820, 0x4d66: 0x403d1920, 0x4d67: 0x403d1a20, + 0x4d68: 0x403d1b20, 0x4d69: 0x403d1c20, 0x4d6a: 0x403d1d20, 0x4d6b: 0x403d1e20, + 0x4d6c: 0x403d1f20, 0x4d6d: 0x403d2020, 0x4d6e: 0x403d2120, + // Block 0x136, offset 0x4d80 + 0x4d80: 0xe0000210, 0x4d81: 0xe00002c7, 0x4d82: 0xe0000384, 0x4d83: 0xe0000450, + 0x4d84: 0xe00004f8, 0x4d85: 0xe0000591, 0x4d86: 0xe000062d, 0x4d87: 0xe00006c6, + 0x4d88: 0xe00002ca, 0x4d89: 0xe0000387, 0x4d8a: 0xe0000453, 0x4d8b: 0xe00004fb, + 0x4d8c: 0xe0000594, 0x4d8d: 0xe0000630, 0x4d8e: 0xe00006c9, 0x4d8f: 0xe000038a, + 0x4d90: 0xe0000456, 0x4d91: 0xe00004fe, 0x4d92: 0xe0000597, 0x4d93: 0xe0000633, + 0x4d94: 0xe00006cc, 0x4d95: 0xe000012c, 0x4d96: 0xe0000213, 0x4d97: 0xe00002cd, + 0x4d98: 0xe000038d, 0x4d99: 0xe0000459, 0x4d9a: 0xe0000501, 0x4d9b: 0xe000059a, + 0x4d9c: 0xe0000636, 0x4d9d: 0xe00006cf, 0x4d9e: 0xe000012f, 0x4d9f: 0xe0000216, + 0x4da0: 0xe00002d0, 0x4da1: 0xe0000390, 0x4da2: 0xe000045c, 0x4da3: 0xe0000219, + 0x4da4: 0xe00002d3, 0x4da5: 0xe00002d6, 0x4da6: 0xe0000393, 0x4da7: 0xe000045f, + 0x4da8: 0xe0000504, 0x4da9: 0xe000059d, 0x4daa: 0xe0000639, 0x4dab: 0xe00006d2, + 0x4dac: 0xe0000132, 0x4dad: 0xe000021c, 0x4dae: 0xe00002d9, 0x4daf: 0xe00002dc, + 0x4db0: 0xe0000396, 0x4db1: 0xe0000462, 0x4db2: 0x40148420, 0x4db3: 0x40148520, + 0x4db4: 0xe0000135, 0x4db5: 0xe000021f, 0x4db6: 0xe00002df, 0x4db7: 0xe00002e2, + 0x4db8: 0xe0000399, 0x4db9: 0xe0000465, 0x4dba: 0xe00002e5, 0x4dbb: 0xe00002e8, + 0x4dbc: 0xe000039c, 0x4dbd: 0xe000039f, 0x4dbe: 0xe00003a2, 0x4dbf: 0xe00003a5, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0xe0000507, 0x4dc1: 0xe00005a0, 0x4dc2: 0xe00005a3, 0x4dc3: 0xe00005a6, + 0x4dc4: 0xe000063c, 0x4dc5: 0xe000063f, 0x4dc6: 0xe00006d5, 0x4dc7: 0xe00006d8, + 0x4dc8: 0xe00006db, 0x4dc9: 0xe00006de, 0x4dca: 0xe0000222, 0x4dcb: 0xe00002eb, + 0x4dcc: 0xe00003a8, 0x4dcd: 0xe0000468, 0x4dce: 0xe000050a, 0x4dcf: 0xe0000138, + 0x4dd0: 0xe0000225, 0x4dd1: 0xe00002ee, 0x4dd2: 0xe00003ab, 0x4dd3: 0xe00003ae, + 0x4dd4: 0xe000046b, 0x4dd5: 0xe000046e, 0x4dd6: 0x40148620, 0x4dd7: 0x40148720, + 0x4dd8: 0xe000013b, 0x4dd9: 0xe0000228, 0x4dda: 0x40148820, 0x4ddb: 0x40148920, + 0x4ddc: 0x40148a20, 0x4ddd: 0x40148b20, 0x4dde: 0x40148c20, 0x4ddf: 0x40148d20, + 0x4de0: 0x40148e20, 0x4de1: 0x40148f20, 0x4de2: 0x40149020, + 0x4df0: 0x4001d420, 0x4df1: 0x4001d520, 0x4df2: 0x4001d620, 0x4df3: 0x4001d720, + // Block 0x138, offset 0x4e00 + 0x4e00: 0x403d2220, 0x4e01: 0x403d2320, 0x4e02: 0x403d2420, 0x4e03: 0x403d2520, + 0x4e04: 0x403d2620, 0x4e05: 0x403d2720, 0x4e06: 0x403d2820, 0x4e07: 0x403d2920, + 0x4e08: 0x403d2a20, 0x4e09: 0x403d2b20, 0x4e0a: 0x403d2c20, 0x4e0b: 0x403d2d20, + 0x4e0c: 0x403d2e20, 0x4e0d: 0x403d2f20, 0x4e0e: 0x403d3020, 0x4e0f: 0x403d3120, + 0x4e10: 0x403d3220, 0x4e11: 0x403d3320, 0x4e12: 0x403d3420, 0x4e13: 0x403d3520, + 0x4e14: 0x403d3620, 0x4e15: 0x403d3720, 0x4e16: 0x403d3820, 0x4e17: 0x403d3920, + 0x4e18: 0x403d3a20, 0x4e19: 0x403d3b20, 0x4e1a: 0x403d3c20, 0x4e1b: 0x403d3d20, + 0x4e1c: 0x403d3e20, 0x4e1d: 0x403d3f20, 0x4e1e: 0x403d4020, 0x4e1f: 0x403d4120, + 0x4e20: 0x403d4220, 0x4e21: 0x403d4320, 0x4e22: 0x403d4420, 0x4e23: 0x403d4520, + 0x4e24: 0x403d4620, 0x4e25: 0x403d4720, 0x4e26: 0x403d4820, 0x4e27: 0x403d4920, + 0x4e28: 0x403d4a20, 0x4e29: 0x403d4b20, 0x4e2a: 0x403d4c20, 0x4e2b: 0x403d4d20, + 0x4e2c: 0x403d4e20, 0x4e2d: 0x403d4f20, 0x4e2e: 0x403d5020, 0x4e2f: 0x403d5120, + 0x4e30: 0x403d5220, 0x4e31: 0x403d5320, 0x4e32: 0x403d5420, 0x4e33: 0x403d5520, + 0x4e34: 0x403d5620, 0x4e35: 0x403d5720, 0x4e36: 0x403d5820, 0x4e37: 0x403d5920, + 0x4e38: 0x403d5a20, 0x4e39: 0x403d5b20, 0x4e3a: 0x403d5c20, 0x4e3b: 0x403d5d20, + 0x4e3c: 0x403d5e20, 0x4e3d: 0x403d5f20, 0x4e3e: 0x403d6020, 0x4e3f: 0x403d6120, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x403d6220, 0x4e41: 0x403d6320, 0x4e42: 0x403d6420, 0x4e43: 0x403d6520, + 0x4e44: 0x403d6620, 0x4e45: 0x403d6720, 0x4e46: 0x403d6820, 0x4e47: 0x403d6920, + 0x4e48: 0x403d6a20, 0x4e49: 0x403d6b20, 0x4e4a: 0x403d6c20, 0x4e4b: 0x403d6d20, + 0x4e4c: 0x403d6e20, 0x4e4d: 0x403d6f20, 0x4e4e: 0x403d7020, 0x4e4f: 0x403d7120, + 0x4e50: 0x403d7220, 0x4e51: 0x403d7320, 0x4e52: 0x403d7420, 0x4e53: 0x403d7520, + 0x4e54: 0x403d7620, 0x4e55: 0x403d7720, 0x4e56: 0x403d7820, 0x4e57: 0x403d7920, + 0x4e58: 0x403d7a20, 0x4e59: 0x403d7b20, 0x4e5a: 0x403d7c20, 0x4e5b: 0x403d7d20, + 0x4e5c: 0x403d7e20, 0x4e5d: 0x403d7f20, 0x4e5e: 0x403d8020, 0x4e5f: 0x403d8120, + 0x4e60: 0x403d8220, 0x4e61: 0x403d8320, 0x4e62: 0x403d8420, 0x4e63: 0x403d8520, + 0x4e64: 0x403d8620, 0x4e65: 0x403d8720, 0x4e66: 0x403d8820, 0x4e67: 0x403d8920, + 0x4e68: 0x403d8a20, 0x4e69: 0x403d8b20, 0x4e6a: 0x403d8c20, 0x4e6b: 0x403d8d20, + 0x4e6c: 0x403d8e20, 0x4e6d: 0x403d8f20, 0x4e6e: 0x403d9020, 0x4e6f: 0x403d9120, + 0x4e70: 0x403d9220, 0x4e71: 0x403d9320, 0x4e72: 0x403d9420, 0x4e73: 0x403d9520, + 0x4e74: 0x403d9620, 0x4e75: 0x403d9720, 0x4e76: 0x403d9820, 0x4e77: 0x403d9920, + 0x4e78: 0x403d9a20, 0x4e79: 0x403d9b20, 0x4e7a: 0x403d9c20, 0x4e7b: 0x403d9d20, + 0x4e7c: 0x403d9e20, 0x4e7d: 0x403d9f20, 0x4e7e: 0x403da020, 0x4e7f: 0x403da120, + // Block 0x13a, offset 0x4e80 + 0x4e80: 0x403da220, 0x4e81: 0x403da320, 0x4e82: 0x403da420, 0x4e83: 0x403da520, + 0x4e84: 0x403da620, 0x4e85: 0x403da720, 0x4e86: 0x403da820, 0x4e87: 0x403da920, + 0x4e88: 0x403daa20, 0x4e89: 0x403dab20, 0x4e8a: 0x403dac20, 0x4e8b: 0x403dad20, + 0x4e8c: 0x403dae20, 0x4e8d: 0x403daf20, 0x4e8e: 0x403db020, 0x4e8f: 0x403db120, + 0x4e90: 0x403db220, 0x4e91: 0x403db320, 0x4e92: 0x403db420, 0x4e93: 0x403db520, + 0x4e94: 0x403db620, 0x4e95: 0x403db720, 0x4e96: 0x403db820, 0x4e97: 0x403db920, + 0x4e98: 0x403dba20, 0x4e99: 0x403dbb20, 0x4e9a: 0x403dbc20, 0x4e9b: 0x403dbd20, + 0x4e9c: 0x403dbe20, 0x4e9d: 0x403dbf20, 0x4e9e: 0x403dc020, 0x4e9f: 0x403dc120, + 0x4ea0: 0x403dc220, 0x4ea1: 0x403dc320, 0x4ea2: 0x403dc420, 0x4ea3: 0x403dc520, + 0x4ea4: 0x403dc620, 0x4ea5: 0x403dc720, 0x4ea6: 0x403dc820, 0x4ea7: 0x403dc920, + 0x4ea8: 0x403dca20, 0x4ea9: 0x403dcb20, 0x4eaa: 0x403dcc20, 0x4eab: 0x403dcd20, + 0x4eac: 0x403dce20, 0x4ead: 0x403dcf20, 0x4eae: 0x403dd020, 0x4eaf: 0x403dd120, + 0x4eb0: 0x403dd220, 0x4eb1: 0x403dd320, 0x4eb2: 0x403dd420, 0x4eb3: 0x403dd520, + 0x4eb4: 0x403dd620, 0x4eb5: 0x403dd720, 0x4eb6: 0x403dd820, 0x4eb7: 0x403dd920, + 0x4eb8: 0x403dda20, 0x4eb9: 0x403ddb20, 0x4eba: 0x403ddc20, 0x4ebb: 0x403ddd20, + 0x4ebc: 0x403dde20, 0x4ebd: 0x403ddf20, 0x4ebe: 0x403de020, 0x4ebf: 0x403de120, + // Block 0x13b, offset 0x4ec0 + 0x4ec0: 0x403de220, 0x4ec1: 0x403de320, 0x4ec2: 0x403de420, 0x4ec3: 0x403de520, + 0x4ec4: 0x403de620, 0x4ec5: 0x403de720, 0x4ec6: 0x403de820, 0x4ec7: 0x403de920, + 0x4ec8: 0x403dea20, 0x4ec9: 0x403deb20, 0x4eca: 0x403dec20, 0x4ecb: 0x403ded20, + 0x4ecc: 0x403dee20, 0x4ecd: 0x403def20, 0x4ece: 0x403df020, 0x4ecf: 0x403df120, + 0x4ed0: 0x403df220, 0x4ed1: 0x403df320, 0x4ed2: 0x403df420, 0x4ed3: 0x403df520, + 0x4ed4: 0x403df620, 0x4ed5: 0x403df720, 0x4ed6: 0x403df820, 0x4ed7: 0x403df920, + 0x4ed8: 0x403dfa20, 0x4ed9: 0x403dfb20, 0x4eda: 0x403dfc20, 0x4edb: 0x403dfd20, + 0x4edc: 0x403dfe20, 0x4edd: 0x403dff20, 0x4ede: 0x403e0020, 0x4edf: 0x403e0120, + 0x4ee0: 0x403e0220, 0x4ee1: 0x403e0320, 0x4ee2: 0x403e0420, 0x4ee3: 0x403e0520, + 0x4ee4: 0x403e0620, 0x4ee5: 0x403e0720, 0x4ee6: 0x403e0820, 0x4ee7: 0x403e0920, + 0x4ee8: 0x403e0a20, 0x4ee9: 0x403e0b20, 0x4eea: 0x403e0c20, 0x4eeb: 0x403e0d20, + 0x4eec: 0x403e0e20, 0x4eed: 0x403e0f20, 0x4eee: 0x403e1020, 0x4eef: 0x403e1120, + 0x4ef0: 0x403e1220, 0x4ef1: 0x403e1320, 0x4ef2: 0x403e1420, 0x4ef3: 0x403e1520, + 0x4ef4: 0x403e1620, 0x4ef5: 0x403e1720, 0x4ef6: 0x403e1820, 0x4ef7: 0x403e1920, + 0x4ef8: 0x403e1a20, 0x4ef9: 0x403e1b20, 0x4efa: 0x403e1c20, 0x4efb: 0x403e1d20, + 0x4efc: 0x403e1e20, 0x4efd: 0x403e1f20, 0x4efe: 0x403e2020, 0x4eff: 0x403e2120, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x403e2220, 0x4f01: 0x403e2320, 0x4f02: 0x403e2420, 0x4f03: 0x403e2520, + 0x4f04: 0x403e2620, 0x4f05: 0x403e2720, 0x4f06: 0x403e2820, 0x4f07: 0x403e2920, + 0x4f08: 0x403e2a20, 0x4f09: 0x403e2b20, 0x4f0a: 0x403e2c20, 0x4f0b: 0x403e2d20, + 0x4f0c: 0x403e2e20, 0x4f0d: 0x403e2f20, 0x4f0e: 0x403e3020, 0x4f0f: 0x403e3120, + 0x4f10: 0x403e3220, 0x4f11: 0x403e3320, 0x4f12: 0x403e3420, 0x4f13: 0x403e3520, + 0x4f14: 0x403e3620, 0x4f15: 0x403e3720, 0x4f16: 0x403e3820, 0x4f17: 0x403e3920, + 0x4f18: 0x403e3a20, 0x4f19: 0x403e3b20, 0x4f1a: 0x403e3c20, 0x4f1b: 0x403e3d20, + 0x4f1c: 0x403e3e20, 0x4f1d: 0x403e3f20, 0x4f1e: 0x403e4020, 0x4f1f: 0x403e4120, + 0x4f20: 0x403e4220, 0x4f21: 0x403e4320, 0x4f22: 0x403e4420, 0x4f23: 0x403e4520, + 0x4f24: 0x403e4620, 0x4f25: 0x403e4720, 0x4f26: 0x403e4820, 0x4f27: 0x403e4920, + 0x4f28: 0x403e4a20, 0x4f29: 0x403e4b20, 0x4f2a: 0x403e4c20, 0x4f2b: 0x403e4d20, + 0x4f2c: 0x403e4e20, 0x4f2d: 0x403e4f20, 0x4f2e: 0x403e5020, 0x4f2f: 0x403e5120, + 0x4f30: 0x403e5220, 0x4f31: 0x403e5320, 0x4f32: 0x403e5420, 0x4f33: 0x403e5520, + 0x4f34: 0x403e5620, 0x4f35: 0x403e5720, 0x4f36: 0x403e5820, 0x4f37: 0x403e5920, + 0x4f38: 0x403e5a20, 0x4f39: 0x403e5b20, 0x4f3a: 0x403e5c20, 0x4f3b: 0x403e5d20, + 0x4f3c: 0x403e5e20, 0x4f3d: 0x403e5f20, 0x4f3e: 0x403e6020, 0x4f3f: 0x403e6120, + // Block 0x13d, offset 0x4f40 + 0x4f40: 0x403e6220, 0x4f41: 0x403e6320, 0x4f42: 0x403e6420, 0x4f43: 0x403e6520, + 0x4f44: 0x403e6620, 0x4f45: 0x403e6720, 0x4f46: 0x403e6820, 0x4f47: 0x403e6920, + 0x4f48: 0x403e6a20, 0x4f49: 0x403e6b20, 0x4f4a: 0x403e6c20, 0x4f4b: 0x403e6d20, + 0x4f4c: 0x403e6e20, 0x4f4d: 0x403e6f20, 0x4f4e: 0x403e7020, 0x4f4f: 0x403e7120, + 0x4f50: 0x403e7220, 0x4f51: 0x403e7320, 0x4f52: 0x403e7420, 0x4f53: 0x403e7520, + 0x4f54: 0x403e7620, 0x4f55: 0x403e7720, 0x4f56: 0x403e7820, 0x4f57: 0x403e7920, + 0x4f58: 0x403e7a20, 0x4f59: 0x403e7b20, 0x4f5a: 0x403e7c20, 0x4f5b: 0x403e7d20, + 0x4f5c: 0x403e7e20, 0x4f5d: 0x403e7f20, 0x4f5e: 0x403e8020, 0x4f5f: 0x403e8120, + 0x4f60: 0x403e8220, 0x4f61: 0x403e8320, 0x4f62: 0x403e8420, 0x4f63: 0x403e8520, + 0x4f64: 0x403e8620, 0x4f65: 0x403e8720, 0x4f66: 0x403e8820, 0x4f67: 0x403e8920, + 0x4f68: 0x403e8a20, 0x4f69: 0x403e8b20, 0x4f6a: 0x403e8c20, 0x4f6b: 0x403e8d20, + 0x4f6c: 0x403e8e20, 0x4f6d: 0x403e8f20, 0x4f6e: 0x403e9020, 0x4f6f: 0x403e9120, + 0x4f70: 0x403e9220, 0x4f71: 0x403e9320, 0x4f72: 0x403e9420, 0x4f73: 0x403e9520, + 0x4f74: 0x403e9620, 0x4f75: 0x403e9720, 0x4f76: 0x403e9820, 0x4f77: 0x403e9920, + 0x4f78: 0x403e9a20, 0x4f79: 0x403e9b20, 0x4f7a: 0x403e9c20, 0x4f7b: 0x403e9d20, + 0x4f7c: 0x403e9e20, 0x4f7d: 0x403e9f20, 0x4f7e: 0x403ea020, 0x4f7f: 0x403ea120, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x403ea220, 0x4f81: 0x403ea320, 0x4f82: 0x403ea420, 0x4f83: 0x403ea520, + 0x4f84: 0x403ea620, 0x4f85: 0x403ea720, 0x4f86: 0x403ea820, 0x4f87: 0x403ea920, + 0x4f88: 0x403eaa20, 0x4f89: 0x403eab20, 0x4f8a: 0x403eac20, 0x4f8b: 0x403ead20, + 0x4f8c: 0x403eae20, 0x4f8d: 0x403eaf20, 0x4f8e: 0x403eb020, 0x4f8f: 0x403eb120, + 0x4f90: 0x403eb220, 0x4f91: 0x403eb320, 0x4f92: 0x403eb420, 0x4f93: 0x403eb520, + 0x4f94: 0x403eb620, 0x4f95: 0x403eb720, 0x4f96: 0x403eb820, 0x4f97: 0x403eb920, + 0x4f98: 0x403eba20, 0x4f99: 0x403ebb20, 0x4f9a: 0x403ebc20, 0x4f9b: 0x403ebd20, + 0x4f9c: 0x403ebe20, 0x4f9d: 0x403ebf20, 0x4f9e: 0x403ec020, 0x4f9f: 0x403ec120, + 0x4fa0: 0x403ec220, 0x4fa1: 0x403ec320, 0x4fa2: 0x403ec420, 0x4fa3: 0x403ec520, + 0x4fa4: 0x403ec620, 0x4fa5: 0x403ec720, 0x4fa6: 0x403ec820, 0x4fa7: 0x403ec920, + 0x4fa8: 0x403eca20, 0x4fa9: 0x403ecb20, 0x4faa: 0x403ecc20, 0x4fab: 0x403ecd20, + 0x4fac: 0x403ece20, 0x4fad: 0x403ecf20, 0x4fae: 0x403ed020, 0x4faf: 0x403ed120, + 0x4fb0: 0x403ed220, 0x4fb1: 0x403ed320, 0x4fb2: 0x403ed420, 0x4fb3: 0x403ed520, + 0x4fb4: 0x403ed620, 0x4fb5: 0x403ed720, 0x4fb6: 0x403ed820, 0x4fb7: 0x403ed920, + 0x4fb8: 0x403eda20, 0x4fb9: 0x403edb20, 0x4fba: 0x403edc20, 0x4fbb: 0x403edd20, + 0x4fbc: 0x403ede20, 0x4fbd: 0x403edf20, 0x4fbe: 0x403ee020, 0x4fbf: 0x403ee120, + // Block 0x13f, offset 0x4fc0 + 0x4fc0: 0x403ee220, 0x4fc1: 0x403ee320, 0x4fc2: 0x403ee420, 0x4fc3: 0x403ee520, + 0x4fc4: 0x403ee620, 0x4fc5: 0x403ee720, 0x4fc6: 0x403ee820, 0x4fc7: 0x403ee920, + 0x4fc8: 0x403eea20, 0x4fc9: 0x403eeb20, 0x4fca: 0x403eec20, 0x4fcb: 0x403eed20, + 0x4fcc: 0x403eee20, 0x4fcd: 0x403eef20, 0x4fce: 0x403ef020, 0x4fcf: 0x403ef120, + 0x4fd0: 0x403ef220, 0x4fd1: 0x403ef320, 0x4fd2: 0x403ef420, 0x4fd3: 0x403ef520, + 0x4fd4: 0x403ef620, 0x4fd5: 0x403ef720, 0x4fd6: 0x403ef820, 0x4fd7: 0x403ef920, + 0x4fd8: 0x403efa20, 0x4fd9: 0x403efb20, 0x4fda: 0x403efc20, 0x4fdb: 0x403efd20, + 0x4fdc: 0x403efe20, 0x4fdd: 0x403eff20, 0x4fde: 0x403f0020, 0x4fdf: 0x403f0120, + 0x4fe0: 0x403f0220, 0x4fe1: 0x403f0320, 0x4fe2: 0x403f0420, 0x4fe3: 0x403f0520, + 0x4fe4: 0x403f0620, 0x4fe5: 0x403f0720, 0x4fe6: 0x403f0820, 0x4fe7: 0x403f0920, + 0x4fe8: 0x403f0a20, 0x4fe9: 0x403f0b20, 0x4fea: 0x403f0c20, 0x4feb: 0x403f0d20, + 0x4fec: 0x403f0e20, 0x4fed: 0x403f0f20, 0x4fee: 0x403f1020, 0x4fef: 0x403f1120, + 0x4ff0: 0x403f1220, 0x4ff1: 0x403f1320, 0x4ff2: 0x403f1420, 0x4ff3: 0x403f1520, + 0x4ff4: 0x403f1620, 0x4ff5: 0x403f1720, 0x4ff6: 0x403f1820, 0x4ff7: 0x403f1920, + 0x4ff8: 0x403f1a20, 0x4ff9: 0x403f1b20, 0x4ffa: 0x403f1c20, 0x4ffb: 0x403f1d20, + 0x4ffc: 0x403f1e20, 0x4ffd: 0x403f1f20, 0x4ffe: 0x403f2020, 0x4fff: 0x403f2120, + // Block 0x140, offset 0x5000 + 0x5000: 0x403f2220, 0x5001: 0x403f2320, 0x5002: 0x403f2420, 0x5003: 0x403f2520, + 0x5004: 0x403f2620, 0x5005: 0x403f2720, 0x5006: 0x403f2820, 0x5007: 0x403f2920, + 0x5008: 0x403f2a20, 0x5009: 0x403f2b20, 0x500a: 0x403f2c20, 0x500b: 0x403f2d20, + 0x500c: 0x403f2e20, 0x500d: 0x403f2f20, 0x500e: 0x403f3020, 0x500f: 0x403f3120, + 0x5010: 0x403f3220, 0x5011: 0x403f3320, 0x5012: 0x403f3420, 0x5013: 0x403f3520, + 0x5014: 0x403f3620, 0x5015: 0x403f3720, 0x5016: 0x403f3820, 0x5017: 0x403f3920, + 0x5018: 0x403f3a20, 0x5019: 0x403f3b20, 0x501a: 0x403f3c20, 0x501b: 0x403f3d20, + 0x501c: 0x403f3e20, 0x501d: 0x403f3f20, 0x501e: 0x403f4020, 0x501f: 0x403f4120, + 0x5020: 0x403f4220, 0x5021: 0x403f4320, 0x5022: 0x403f4420, 0x5023: 0x403f4520, + 0x5024: 0x403f4620, 0x5025: 0x403f4720, 0x5026: 0x403f4820, 0x5027: 0x403f4920, + 0x5028: 0x403f4a20, 0x5029: 0x403f4b20, 0x502a: 0x403f4c20, 0x502b: 0x403f4d20, + 0x502c: 0x403f4e20, 0x502d: 0x403f4f20, 0x502e: 0x403f5020, 0x502f: 0x403f5120, + 0x5030: 0x403f5220, 0x5031: 0x403f5320, 0x5032: 0x403f5420, 0x5033: 0x403f5520, + 0x5034: 0x403f5620, 0x5035: 0x403f5720, 0x5036: 0x403f5820, 0x5037: 0x403f5920, + 0x5038: 0x403f5a20, 0x5039: 0x403f5b20, 0x503a: 0x403f5c20, 0x503b: 0x403f5d20, + 0x503c: 0x403f5e20, 0x503d: 0x403f5f20, 0x503e: 0x403f6020, 0x503f: 0x403f6120, + // Block 0x141, offset 0x5040 + 0x5040: 0x403f6220, 0x5041: 0x403f6320, 0x5042: 0x403f6420, 0x5043: 0x403f6520, + 0x5044: 0x403f6620, 0x5045: 0x403f6720, 0x5046: 0x403f6820, 0x5047: 0x403f6920, + 0x5048: 0x403f6a20, 0x5049: 0x403f6b20, 0x504a: 0x403f6c20, 0x504b: 0x403f6d20, + 0x504c: 0x403f6e20, 0x504d: 0x403f6f20, 0x504e: 0x403f7020, 0x504f: 0x403f7120, + 0x5050: 0x403f7220, 0x5051: 0x403f7320, 0x5052: 0x403f7420, 0x5053: 0x403f7520, + 0x5054: 0x403f7620, 0x5055: 0x403f7720, 0x5056: 0x403f7820, 0x5057: 0x403f7920, + 0x5058: 0x403f7a20, 0x5059: 0x403f7b20, 0x505a: 0x403f7c20, 0x505b: 0x403f7d20, + 0x505c: 0x403f7e20, 0x505d: 0x403f7f20, 0x505e: 0x403f8020, 0x505f: 0x403f8120, + 0x5060: 0x403f8220, 0x5061: 0x403f8320, 0x5062: 0x403f8420, 0x5063: 0x403f8520, + 0x5064: 0x403f8620, 0x5065: 0x403f8720, 0x5066: 0x403f8820, 0x5067: 0x403f8920, + 0x5068: 0x403f8a20, 0x5069: 0x403f8b20, 0x506a: 0x403f8c20, 0x506b: 0x403f8d20, + 0x506c: 0x403f8e20, 0x506d: 0x403f8f20, 0x506e: 0x403f9020, 0x506f: 0x403f9120, + 0x5070: 0x403f9220, 0x5071: 0x403f9320, 0x5072: 0x403f9420, 0x5073: 0x403f9520, + 0x5074: 0x403f9620, 0x5075: 0x403f9720, 0x5076: 0x403f9820, 0x5077: 0x403f9920, + 0x5078: 0x403f9a20, 0x5079: 0x403f9b20, 0x507a: 0x403f9c20, 0x507b: 0x403f9d20, + 0x507c: 0x403f9e20, 0x507d: 0x403f9f20, 0x507e: 0x403fa020, 0x507f: 0x403fa120, + // Block 0x142, offset 0x5080 + 0x5080: 0x403fa220, 0x5081: 0x403fa320, 0x5082: 0x403fa420, 0x5083: 0x403fa520, + 0x5084: 0x403fa620, 0x5085: 0x403fa720, 0x5086: 0x403fa820, 0x5087: 0x403fa920, + 0x5088: 0x403faa20, 0x5089: 0x403fab20, 0x508a: 0x403fac20, 0x508b: 0x403fad20, + 0x508c: 0x403fae20, 0x508d: 0x403faf20, 0x508e: 0x403fb020, 0x508f: 0x403fb120, + 0x5090: 0x403fb220, 0x5091: 0x403fb320, 0x5092: 0x403fb420, 0x5093: 0x403fb520, + 0x5094: 0x403fb620, 0x5095: 0x403fb720, 0x5096: 0x403fb820, 0x5097: 0x403fb920, + 0x5098: 0x403fba20, 0x5099: 0x403fbb20, 0x509a: 0x403fbc20, 0x509b: 0x403fbd20, + 0x509c: 0x403fbe20, 0x509d: 0x403fbf20, 0x509e: 0x403fc020, 0x509f: 0x403fc120, + 0x50a0: 0x403fc220, 0x50a1: 0x403fc320, 0x50a2: 0x403fc420, 0x50a3: 0x403fc520, + 0x50a4: 0x403fc620, 0x50a5: 0x403fc720, 0x50a6: 0x403fc820, 0x50a7: 0x403fc920, + 0x50a8: 0x403fca20, 0x50a9: 0x403fcb20, 0x50aa: 0x403fcc20, 0x50ab: 0x403fcd20, + 0x50ac: 0x403fce20, 0x50ad: 0x403fcf20, 0x50ae: 0x403fd020, 0x50af: 0x403fd120, + 0x50b0: 0x403fd220, 0x50b1: 0x403fd320, 0x50b2: 0x403fd420, 0x50b3: 0x403fd520, + 0x50b4: 0x403fd620, 0x50b5: 0x403fd720, 0x50b6: 0x403fd820, 0x50b7: 0x403fd920, + 0x50b8: 0x403fda20, 0x50b9: 0x403fdb20, 0x50ba: 0x403fdc20, 0x50bb: 0x403fdd20, + 0x50bc: 0x403fde20, 0x50bd: 0x403fdf20, 0x50be: 0x403fe020, 0x50bf: 0x403fe120, + // Block 0x143, offset 0x50c0 + 0x50c0: 0x403fe220, 0x50c1: 0x403fe320, 0x50c2: 0x403fe420, 0x50c3: 0x403fe520, + 0x50c4: 0x403fe620, 0x50c5: 0x403fe720, 0x50c6: 0x403fe820, 0x50c7: 0x403fe920, + 0x50c8: 0x403fea20, 0x50c9: 0x403feb20, 0x50ca: 0x403fec20, 0x50cb: 0x403fed20, + 0x50cc: 0x403fee20, 0x50cd: 0x403fef20, 0x50ce: 0x403ff020, 0x50cf: 0x403ff120, + 0x50d0: 0x403ff220, 0x50d1: 0x403ff320, 0x50d2: 0x403ff420, 0x50d3: 0x403ff520, + 0x50d4: 0x403ff620, 0x50d5: 0x403ff720, 0x50d6: 0x403ff820, 0x50d7: 0x403ff920, + 0x50d8: 0x403ffa20, 0x50d9: 0x403ffb20, 0x50da: 0x403ffc20, 0x50db: 0x403ffd20, + 0x50dc: 0x403ffe20, 0x50dd: 0x403fff20, 0x50de: 0x40400020, 0x50df: 0x40400120, + 0x50e0: 0x40400220, 0x50e1: 0x40400320, 0x50e2: 0x40400420, 0x50e3: 0x40400520, + 0x50e4: 0x40400620, 0x50e5: 0x40400720, 0x50e6: 0x40400820, 0x50e7: 0x40400920, + 0x50e8: 0x40400a20, 0x50e9: 0x40400b20, 0x50ea: 0x40400c20, 0x50eb: 0x40400d20, + 0x50ec: 0x40400e20, 0x50ed: 0x40400f20, 0x50ee: 0x40401020, 0x50ef: 0x40401120, + 0x50f0: 0x40401220, 0x50f1: 0x40401320, 0x50f2: 0x40401420, 0x50f3: 0x40401520, + 0x50f4: 0x40401620, 0x50f5: 0x40401720, 0x50f6: 0x40401820, 0x50f7: 0x40401920, + 0x50f8: 0x40401a20, 0x50f9: 0x40401b20, 0x50fa: 0x40401c20, 0x50fb: 0x40401d20, + 0x50fc: 0x40401e20, 0x50fd: 0x40401f20, 0x50fe: 0x40402020, 0x50ff: 0x40402120, + // Block 0x144, offset 0x5100 + 0x5100: 0x40402220, 0x5101: 0x40402320, 0x5102: 0x40402420, 0x5103: 0x40402520, + 0x5104: 0x40402620, 0x5105: 0x40402720, 0x5106: 0x40402820, 0x5107: 0x40402920, + 0x5108: 0x40402a20, 0x5109: 0x40402b20, 0x510a: 0x40402c20, 0x510b: 0x40402d20, + 0x510c: 0x40402e20, 0x510d: 0x40402f20, 0x510e: 0x40403020, 0x510f: 0x40403120, + 0x5110: 0x40403220, 0x5111: 0x40403320, 0x5112: 0x40403420, 0x5113: 0x40403520, + 0x5114: 0x40403620, 0x5115: 0x40403720, 0x5116: 0x40403820, 0x5117: 0x40403920, + 0x5118: 0x40403a20, 0x5119: 0x40403b20, 0x511a: 0x40403c20, 0x511b: 0x40403d20, + 0x511c: 0x40403e20, 0x511d: 0x40403f20, 0x511e: 0x40404020, 0x511f: 0x40404120, + 0x5120: 0x40404220, 0x5121: 0x40404320, 0x5122: 0x40404420, 0x5123: 0x40404520, + 0x5124: 0x40404620, 0x5125: 0x40404720, 0x5126: 0x40404820, 0x5127: 0x40404920, + 0x5128: 0x40404a20, 0x5129: 0x40404b20, 0x512a: 0x40404c20, 0x512b: 0x40404d20, + 0x512c: 0x40404e20, 0x512d: 0x40404f20, 0x512e: 0x40405020, 0x512f: 0x40405120, + 0x5130: 0x40405220, 0x5131: 0x40405320, 0x5132: 0x40405420, 0x5133: 0x40405520, + 0x5134: 0x40405620, 0x5135: 0x40405720, 0x5136: 0x40405820, 0x5137: 0x40405920, + 0x5138: 0x40405a20, 0x5139: 0x40405b20, 0x513a: 0x40405c20, 0x513b: 0x40405d20, + 0x513c: 0x40405e20, 0x513d: 0x40405f20, 0x513e: 0x40406020, 0x513f: 0x40406120, + // Block 0x145, offset 0x5140 + 0x5140: 0x40406220, 0x5141: 0x40406320, 0x5142: 0x40406420, 0x5143: 0x40406520, + 0x5144: 0x40406620, 0x5145: 0x40406720, 0x5146: 0x40406820, 0x5147: 0x40406920, + 0x5148: 0x40406a20, 0x5149: 0x40406b20, 0x514a: 0x40406c20, 0x514b: 0x40406d20, + 0x514c: 0x40406e20, 0x514d: 0x40406f20, 0x514e: 0x40407020, 0x514f: 0x40407120, + 0x5150: 0x40407220, 0x5151: 0x40407320, 0x5152: 0x40407420, 0x5153: 0x40407520, + 0x5154: 0x40407620, 0x5155: 0x40407720, 0x5156: 0x40407820, 0x5157: 0x40407920, + 0x5158: 0x40407a20, 0x5159: 0x40407b20, 0x515a: 0x40407c20, 0x515b: 0x40407d20, + 0x515c: 0x40407e20, 0x515d: 0x40407f20, 0x515e: 0x40408020, 0x515f: 0x40408120, + 0x5160: 0x40408220, 0x5161: 0x40408320, 0x5162: 0x40408420, 0x5163: 0x40408520, + 0x5164: 0x40408620, 0x5165: 0x40408720, 0x5166: 0x40408820, 0x5167: 0x40408920, + 0x5168: 0x40408a20, 0x5169: 0x40408b20, 0x516a: 0x40408c20, 0x516b: 0x40408d20, + 0x516c: 0x40408e20, 0x516d: 0x40408f20, 0x516e: 0x40409020, 0x516f: 0x40409120, + 0x5170: 0x40409220, 0x5171: 0x40409320, 0x5172: 0x40409420, 0x5173: 0x40409520, + 0x5174: 0x40409620, 0x5175: 0x40409720, 0x5176: 0x40409820, 0x5177: 0x40409920, + 0x5178: 0x40409a20, 0x5179: 0x40409b20, 0x517a: 0x40409c20, 0x517b: 0x40409d20, + 0x517c: 0x40409e20, 0x517d: 0x40409f20, 0x517e: 0x4040a020, 0x517f: 0x4040a120, + // Block 0x146, offset 0x5180 + 0x5180: 0x4040a220, 0x5181: 0x4040a320, 0x5182: 0x4040a420, 0x5183: 0x4040a520, + 0x5184: 0x4040a620, 0x5185: 0x4040a720, 0x5186: 0x4040a820, 0x5187: 0x4040a920, + 0x5188: 0x4040aa20, 0x5189: 0x4040ab20, 0x518a: 0x4040ac20, 0x518b: 0x4040ad20, + 0x518c: 0x4040ae20, 0x518d: 0x4040af20, 0x518e: 0x4040b020, 0x518f: 0x4040b120, + 0x5190: 0x4040b220, 0x5191: 0x4040b320, 0x5192: 0x4040b420, 0x5193: 0x4040b520, + 0x5194: 0x4040b620, 0x5195: 0x4040b720, 0x5196: 0x4040b820, 0x5197: 0x4040b920, + 0x5198: 0x4040ba20, 0x5199: 0x4040bb20, 0x519a: 0x4040bc20, 0x519b: 0x4040bd20, + 0x519c: 0x4040be20, 0x519d: 0x4040bf20, 0x519e: 0x4040c020, 0x519f: 0x4040c120, + 0x51a0: 0x4040c220, 0x51a1: 0x4040c320, 0x51a2: 0x4040c420, 0x51a3: 0x4040c520, + 0x51a4: 0x4040c620, 0x51a5: 0x4040c720, 0x51a6: 0x4040c820, 0x51a7: 0x4040c920, + 0x51a8: 0x4040ca20, 0x51a9: 0x4040cb20, 0x51aa: 0x4040cc20, 0x51ab: 0x4040cd20, + 0x51ac: 0x4040ce20, 0x51ad: 0x4040cf20, 0x51ae: 0x4040d020, 0x51af: 0x4040d120, + 0x51b0: 0x4040d220, 0x51b1: 0x4040d320, 0x51b2: 0x4040d420, 0x51b3: 0x4040d520, + 0x51b4: 0x4040d620, 0x51b5: 0x4040d720, 0x51b6: 0x4040d820, 0x51b7: 0x4040d920, + 0x51b8: 0x4040da20, 0x51b9: 0x4040db20, 0x51ba: 0x4040dc20, 0x51bb: 0x4040dd20, + 0x51bc: 0x4040de20, 0x51bd: 0x4040df20, 0x51be: 0x4040e020, 0x51bf: 0x4040e120, + // Block 0x147, offset 0x51c0 + 0x51c0: 0x4040e220, 0x51c1: 0x4040e320, 0x51c2: 0x4040e420, 0x51c3: 0x4040e520, + 0x51c4: 0x4040e620, 0x51c5: 0x4040e720, 0x51c6: 0x4040e820, 0x51c7: 0x4040e920, + 0x51c8: 0x4040ea20, 0x51c9: 0x4040eb20, 0x51ca: 0x4040ec20, 0x51cb: 0x4040ed20, + 0x51cc: 0x4040ee20, 0x51cd: 0x4040ef20, 0x51ce: 0x4040f020, 0x51cf: 0x4040f120, + 0x51d0: 0x4040f220, 0x51d1: 0x4040f320, 0x51d2: 0x4040f420, 0x51d3: 0x4040f520, + 0x51d4: 0x4040f620, 0x51d5: 0x4040f720, 0x51d6: 0x4040f820, 0x51d7: 0x4040f920, + 0x51d8: 0x4040fa20, 0x51d9: 0x4040fb20, 0x51da: 0x4040fc20, 0x51db: 0x4040fd20, + 0x51dc: 0x4040fe20, 0x51dd: 0x4040ff20, 0x51de: 0x40410020, 0x51df: 0x40410120, + 0x51e0: 0x40410220, 0x51e1: 0x40410320, 0x51e2: 0x40410420, 0x51e3: 0x40410520, + 0x51e4: 0x40410620, 0x51e5: 0x40410720, 0x51e6: 0x40410820, 0x51e7: 0x40410920, + 0x51e8: 0x40410a20, 0x51e9: 0x40410b20, 0x51ea: 0x40410c20, 0x51eb: 0x40410d20, + 0x51ec: 0x40410e20, 0x51ed: 0x40410f20, 0x51ee: 0x40411020, 0x51ef: 0x40411120, + 0x51f0: 0x40411220, 0x51f1: 0x40411320, 0x51f2: 0x40411420, 0x51f3: 0x40411520, + 0x51f4: 0x40411620, 0x51f5: 0x40411720, 0x51f6: 0x40411820, 0x51f7: 0x40411920, + 0x51f8: 0x40411a20, 0x51f9: 0x40411b20, 0x51fa: 0x40411c20, 0x51fb: 0x40411d20, + 0x51fc: 0x40411e20, 0x51fd: 0x40411f20, 0x51fe: 0x40412020, 0x51ff: 0x40412120, + // Block 0x148, offset 0x5200 + 0x5200: 0x40412220, 0x5201: 0x40412320, 0x5202: 0x40412420, 0x5203: 0x40412520, + 0x5204: 0x40412620, 0x5205: 0x40412720, 0x5206: 0x40412820, 0x5207: 0x40412920, + 0x5208: 0x40412a20, 0x5209: 0x40412b20, 0x520a: 0x40412c20, 0x520b: 0x40412d20, + 0x520c: 0x40412e20, 0x520d: 0x40412f20, 0x520e: 0x40413020, 0x520f: 0x40413120, + 0x5210: 0x40413220, 0x5211: 0x40413320, 0x5212: 0x40413420, 0x5213: 0x40413520, + 0x5214: 0x40413620, 0x5215: 0x40413720, 0x5216: 0x40413820, 0x5217: 0x40413920, + 0x5218: 0x40413a20, 0x5219: 0x40413b20, 0x521a: 0x40413c20, 0x521b: 0x40413d20, + 0x521c: 0x40413e20, 0x521d: 0x40413f20, 0x521e: 0x40414020, 0x521f: 0x40414120, + 0x5220: 0x40414220, 0x5221: 0x40414320, 0x5222: 0x40414420, 0x5223: 0x40414520, + 0x5224: 0x40414620, 0x5225: 0x40414720, 0x5226: 0x40414820, 0x5227: 0x40414920, + 0x5228: 0x40414a20, 0x5229: 0x40414b20, 0x522a: 0x40414c20, 0x522b: 0x40414d20, + 0x522c: 0x40414e20, 0x522d: 0x40414f20, 0x522e: 0x40415020, + // Block 0x149, offset 0x5240 + 0x5240: 0x402df820, 0x5241: 0x402df920, 0x5242: 0x402dfa20, 0x5243: 0x402dfb20, + 0x5244: 0x402dfc20, 0x5245: 0x402dfd20, 0x5246: 0x402dfe20, 0x5247: 0x402dff20, + 0x5248: 0x402e0020, 0x5249: 0x402e0120, 0x524a: 0x402e0220, 0x524b: 0x402e0320, + 0x524c: 0x402e0420, 0x524d: 0x402e0520, 0x524e: 0x402e0620, 0x524f: 0x402e0720, + 0x5250: 0x402e0820, 0x5251: 0x402e0920, 0x5252: 0x402e0a20, 0x5253: 0x402e0b20, + 0x5254: 0x402e0c20, 0x5255: 0x402e0d20, 0x5256: 0x402e0e20, 0x5257: 0x402e0f20, + 0x5258: 0x402e1020, 0x5259: 0x402e1120, 0x525a: 0x402e1220, 0x525b: 0x402e1320, + 0x525c: 0x402e1420, 0x525d: 0x402e1520, 0x525e: 0x402e1620, 0x525f: 0x402e1720, + 0x5260: 0x402e1820, 0x5261: 0x402e1920, 0x5262: 0x402e1a20, 0x5263: 0x402e1b20, + 0x5264: 0x402e1c20, 0x5265: 0x402e1d20, 0x5266: 0x402e1e20, 0x5267: 0x402e1f20, + 0x5268: 0x402e2020, 0x5269: 0x402e2120, 0x526a: 0x402e2220, 0x526b: 0x402e2320, + 0x526c: 0x402e2420, 0x526d: 0x402e2520, 0x526e: 0x402e2620, 0x526f: 0x402e2720, + 0x5270: 0x402e2820, 0x5271: 0x402e2920, 0x5272: 0x402e2a20, 0x5273: 0x402e2b20, + 0x5274: 0x402e2c20, 0x5275: 0x402e2d20, 0x5276: 0x402e2e20, 0x5277: 0x402e2f20, + 0x5278: 0x402e3020, 0x5279: 0x402e3120, 0x527a: 0x402e3220, 0x527b: 0x402e3320, + 0x527c: 0x402e3420, 0x527d: 0x402e3520, 0x527e: 0x402e3620, 0x527f: 0x402e3720, + // Block 0x14a, offset 0x5280 + 0x5280: 0x402e3820, 0x5281: 0x402e3920, 0x5282: 0x402e3a20, 0x5283: 0x402e3b20, + 0x5284: 0x402e3c20, 0x5285: 0x402e3d20, 0x5286: 0x402e3e20, 0x5287: 0x402e3f20, + 0x5288: 0x402e4020, 0x5289: 0x402e4120, 0x528a: 0x402e4220, 0x528b: 0x402e4320, + 0x528c: 0x402e4420, 0x528d: 0x402e4520, 0x528e: 0x402e4620, 0x528f: 0x402e4720, + 0x5290: 0x402e4820, 0x5291: 0x402e4920, 0x5292: 0x402e4a20, 0x5293: 0x402e4b20, + 0x5294: 0x402e4c20, 0x5295: 0x402e4d20, 0x5296: 0x402e4e20, 0x5297: 0x402e4f20, + 0x5298: 0x402e5020, 0x5299: 0x402e5120, 0x529a: 0x402e5220, 0x529b: 0x402e5320, + 0x529c: 0x402e5420, 0x529d: 0x402e5520, 0x529e: 0x402e5620, 0x529f: 0x402e5720, + 0x52a0: 0x402e5820, 0x52a1: 0x402e5920, 0x52a2: 0x402e5a20, 0x52a3: 0x402e5b20, + 0x52a4: 0x402e5c20, 0x52a5: 0x402e5d20, 0x52a6: 0x402e5e20, 0x52a7: 0x402e5f20, + 0x52a8: 0x402e6020, 0x52a9: 0x402e6120, 0x52aa: 0x402e6220, 0x52ab: 0x402e6320, + 0x52ac: 0x402e6420, 0x52ad: 0x402e6520, 0x52ae: 0x402e6620, 0x52af: 0x402e6720, + 0x52b0: 0x402e6820, 0x52b1: 0x402e6920, 0x52b2: 0x402e6a20, 0x52b3: 0x402e6b20, + 0x52b4: 0x402e6c20, 0x52b5: 0x402e6d20, 0x52b6: 0x402e6e20, 0x52b7: 0x402e6f20, + 0x52b8: 0x402e7020, 0x52b9: 0x402e7120, 0x52ba: 0x402e7220, 0x52bb: 0x402e7320, + 0x52bc: 0x402e7420, 0x52bd: 0x402e7520, 0x52be: 0x402e7620, 0x52bf: 0x402e7720, + // Block 0x14b, offset 0x52c0 + 0x52c0: 0x402e7820, 0x52c1: 0x402e7920, 0x52c2: 0x402e7a20, 0x52c3: 0x402e7b20, + 0x52c4: 0x402e7c20, 0x52c5: 0x402e7d20, 0x52c6: 0x402e7e20, 0x52c7: 0x402e7f20, + 0x52c8: 0x402e8020, 0x52c9: 0x402e8120, 0x52ca: 0x402e8220, 0x52cb: 0x402e8320, + 0x52cc: 0x402e8420, 0x52cd: 0x402e8520, 0x52ce: 0x402e8620, 0x52cf: 0x402e8720, + 0x52d0: 0x402e8820, 0x52d1: 0x402e8920, 0x52d2: 0x402e8a20, 0x52d3: 0x402e8b20, + 0x52d4: 0x402e8c20, 0x52d5: 0x402e8d20, 0x52d6: 0x402e8e20, 0x52d7: 0x402e8f20, + 0x52d8: 0x402e9020, 0x52d9: 0x402e9120, 0x52da: 0x402e9220, 0x52db: 0x402e9320, + 0x52dc: 0x402e9420, 0x52dd: 0x402e9520, 0x52de: 0x402e9620, 0x52df: 0x402e9720, + 0x52e0: 0x402e9820, 0x52e1: 0x402e9920, 0x52e2: 0x402e9a20, 0x52e3: 0x402e9b20, + 0x52e4: 0x402e9c20, 0x52e5: 0x402e9d20, 0x52e6: 0x402e9e20, 0x52e7: 0x402e9f20, + 0x52e8: 0x402ea020, 0x52e9: 0x402ea120, 0x52ea: 0x402ea220, 0x52eb: 0x402ea320, + 0x52ec: 0x402ea420, 0x52ed: 0x402ea520, 0x52ee: 0x402ea620, 0x52ef: 0x402ea720, + 0x52f0: 0x402ea820, 0x52f1: 0x402ea920, 0x52f2: 0x402eaa20, 0x52f3: 0x402eab20, + 0x52f4: 0x402eac20, 0x52f5: 0x402ead20, 0x52f6: 0x402eae20, 0x52f7: 0x402eaf20, + 0x52f8: 0x402eb020, 0x52f9: 0x402eb120, 0x52fa: 0x402eb220, 0x52fb: 0x402eb320, + 0x52fc: 0x402eb420, 0x52fd: 0x402eb520, 0x52fe: 0x402eb620, 0x52ff: 0x402eb720, + // Block 0x14c, offset 0x5300 + 0x5300: 0x402eb820, 0x5301: 0x402eb920, 0x5302: 0x402eba20, 0x5303: 0x402ebb20, + 0x5304: 0x402ebc20, 0x5305: 0x402ebd20, 0x5306: 0x402ebe20, 0x5307: 0x402ebf20, + 0x5308: 0x402ec020, 0x5309: 0x402ec120, 0x530a: 0x402ec220, 0x530b: 0x402ec320, + 0x530c: 0x402ec420, 0x530d: 0x402ec520, 0x530e: 0x402ec620, 0x530f: 0x402ec720, + 0x5310: 0x402ec820, 0x5311: 0x402ec920, 0x5312: 0x402eca20, 0x5313: 0x402ecb20, + 0x5314: 0x402ecc20, 0x5315: 0x402ecd20, 0x5316: 0x402ece20, 0x5317: 0x402ecf20, + 0x5318: 0x402ed020, 0x5319: 0x402ed120, 0x531a: 0x402ed220, 0x531b: 0x402ed320, + 0x531c: 0x402ed420, 0x531d: 0x402ed520, 0x531e: 0x402ed620, 0x531f: 0x402ed720, + 0x5320: 0x402ed820, 0x5321: 0x402ed920, 0x5322: 0x402eda20, 0x5323: 0x402edb20, + 0x5324: 0x402edc20, 0x5325: 0x402edd20, 0x5326: 0x402ede20, 0x5327: 0x402edf20, + 0x5328: 0x402ee020, 0x5329: 0x402ee120, 0x532a: 0x402ee220, 0x532b: 0x402ee320, + 0x532c: 0x402ee420, 0x532d: 0x402ee520, 0x532e: 0x402ee620, 0x532f: 0x402ee720, + 0x5330: 0x402ee820, 0x5331: 0x402ee920, 0x5332: 0x402eea20, 0x5333: 0x402eeb20, + 0x5334: 0x402eec20, 0x5335: 0x402eed20, 0x5336: 0x402eee20, 0x5337: 0x402eef20, + 0x5338: 0x402ef020, 0x5339: 0x402ef120, 0x533a: 0x402ef220, 0x533b: 0x402ef320, + 0x533c: 0x402ef420, 0x533d: 0x402ef520, 0x533e: 0x402ef620, 0x533f: 0x402ef720, + // Block 0x14d, offset 0x5340 + 0x5340: 0x402ef820, 0x5341: 0x402ef920, 0x5342: 0x402efa20, 0x5343: 0x402efb20, + 0x5344: 0x402efc20, 0x5345: 0x402efd20, 0x5346: 0x402efe20, 0x5347: 0x402eff20, + 0x5348: 0x402f0020, 0x5349: 0x402f0120, 0x534a: 0x402f0220, 0x534b: 0x402f0320, + 0x534c: 0x402f0420, 0x534d: 0x402f0520, 0x534e: 0x402f0620, 0x534f: 0x402f0720, + 0x5350: 0x402f0820, 0x5351: 0x402f0920, 0x5352: 0x402f0a20, 0x5353: 0x402f0b20, + 0x5354: 0x402f0c20, 0x5355: 0x402f0d20, 0x5356: 0x402f0e20, 0x5357: 0x402f0f20, + 0x5358: 0x402f1020, 0x5359: 0x402f1120, 0x535a: 0x402f1220, 0x535b: 0x402f1320, + 0x535c: 0x402f1420, 0x535d: 0x402f1520, 0x535e: 0x402f1620, 0x535f: 0x402f1720, + 0x5360: 0x402f1820, 0x5361: 0x402f1920, 0x5362: 0x402f1a20, 0x5363: 0x402f1b20, + 0x5364: 0x402f1c20, 0x5365: 0x402f1d20, 0x5366: 0x402f1e20, 0x5367: 0x402f1f20, + 0x5368: 0x402f2020, 0x5369: 0x402f2120, 0x536a: 0x402f2220, 0x536b: 0x402f2320, + 0x536c: 0x402f2420, 0x536d: 0x402f2520, 0x536e: 0x402f2620, 0x536f: 0x402f2720, + 0x5370: 0x402f2820, 0x5371: 0x402f2920, 0x5372: 0x402f2a20, 0x5373: 0x402f2b20, + 0x5374: 0x402f2c20, 0x5375: 0x402f2d20, 0x5376: 0x402f2e20, 0x5377: 0x402f2f20, + 0x5378: 0x402f3020, 0x5379: 0x402f3120, 0x537a: 0x402f3220, 0x537b: 0x402f3320, + 0x537c: 0x402f3420, 0x537d: 0x402f3520, 0x537e: 0x402f3620, 0x537f: 0x402f3720, + // Block 0x14e, offset 0x5380 + 0x5380: 0x402f3820, 0x5381: 0x402f3920, 0x5382: 0x402f3a20, 0x5383: 0x402f3b20, + 0x5384: 0x402f3c20, 0x5385: 0x402f3d20, 0x5386: 0x402f3e20, 0x5387: 0x402f3f20, + 0x5388: 0x402f4020, 0x5389: 0x402f4120, 0x538a: 0x402f4220, 0x538b: 0x402f4320, + 0x538c: 0x402f4420, 0x538d: 0x402f4520, 0x538e: 0x402f4620, 0x538f: 0x402f4720, + 0x5390: 0x402f4820, 0x5391: 0x402f4920, 0x5392: 0x402f4a20, 0x5393: 0x402f4b20, + 0x5394: 0x402f4c20, 0x5395: 0x402f4d20, 0x5396: 0x402f4e20, 0x5397: 0x402f4f20, + 0x5398: 0x402f5020, 0x5399: 0x402f5120, 0x539a: 0x402f5220, 0x539b: 0x402f5320, + 0x539c: 0x402f5420, 0x539d: 0x402f5520, 0x539e: 0x402f5620, 0x539f: 0x402f5720, + 0x53a0: 0x402f5820, 0x53a1: 0x402f5920, 0x53a2: 0x402f5a20, 0x53a3: 0x402f5b20, + 0x53a4: 0x402f5c20, 0x53a5: 0x402f5d20, 0x53a6: 0x402f5e20, 0x53a7: 0x402f5f20, + 0x53a8: 0x402f6020, 0x53a9: 0x402f6120, 0x53aa: 0x402f6220, 0x53ab: 0x402f6320, + 0x53ac: 0x402f6420, 0x53ad: 0x402f6520, 0x53ae: 0x402f6620, 0x53af: 0x402f6720, + 0x53b0: 0x402f6820, 0x53b1: 0x402f6920, 0x53b2: 0x402f6a20, 0x53b3: 0x402f6b20, + 0x53b4: 0x402f6c20, 0x53b5: 0x402f6d20, 0x53b6: 0x402f6e20, 0x53b7: 0x402f6f20, + 0x53b8: 0x402f7020, 0x53b9: 0x402f7120, 0x53ba: 0x402f7220, 0x53bb: 0x402f7320, + 0x53bc: 0x402f7420, 0x53bd: 0x402f7520, 0x53be: 0x402f7620, 0x53bf: 0x402f7720, + // Block 0x14f, offset 0x53c0 + 0x53c0: 0x402f7820, 0x53c1: 0x402f7920, 0x53c2: 0x402f7a20, 0x53c3: 0x402f7b20, + 0x53c4: 0x402f7c20, 0x53c5: 0x402f7d20, 0x53c6: 0x402f7e20, 0x53c7: 0x402f7f20, + 0x53c8: 0x402f8020, 0x53c9: 0x402f8120, 0x53ca: 0x402f8220, 0x53cb: 0x402f8320, + 0x53cc: 0x402f8420, 0x53cd: 0x402f8520, 0x53ce: 0x402f8620, 0x53cf: 0x402f8720, + 0x53d0: 0x402f8820, 0x53d1: 0x402f8920, 0x53d2: 0x402f8a20, 0x53d3: 0x402f8b20, + 0x53d4: 0x402f8c20, 0x53d5: 0x402f8d20, 0x53d6: 0x402f8e20, 0x53d7: 0x402f8f20, + 0x53d8: 0x402f9020, 0x53d9: 0x402f9120, 0x53da: 0x402f9220, 0x53db: 0x402f9320, + 0x53dc: 0x402f9420, 0x53dd: 0x402f9520, 0x53de: 0x402f9620, 0x53df: 0x402f9720, + 0x53e0: 0x402f9820, 0x53e1: 0x402f9920, 0x53e2: 0x402f9a20, 0x53e3: 0x402f9b20, + 0x53e4: 0x402f9c20, 0x53e5: 0x402f9d20, 0x53e6: 0x402f9e20, 0x53e7: 0x402f9f20, + 0x53e8: 0x402fa020, 0x53e9: 0x402fa120, 0x53ea: 0x402fa220, 0x53eb: 0x402fa320, + 0x53ec: 0x402fa420, 0x53ed: 0x402fa520, 0x53ee: 0x402fa620, 0x53ef: 0x402fa720, + 0x53f0: 0x402fa820, 0x53f1: 0x402fa920, 0x53f2: 0x402faa20, 0x53f3: 0x402fab20, + 0x53f4: 0x402fac20, 0x53f5: 0x402fad20, 0x53f6: 0x402fae20, 0x53f7: 0x402faf20, + 0x53f8: 0x402fb020, 0x53f9: 0x402fb120, 0x53fa: 0x402fb220, 0x53fb: 0x402fb320, + 0x53fc: 0x402fb420, 0x53fd: 0x402fb520, 0x53fe: 0x402fb620, 0x53ff: 0x402fb720, + // Block 0x150, offset 0x5400 + 0x5400: 0x402fb820, 0x5401: 0x402fb920, 0x5402: 0x402fba20, 0x5403: 0x402fbb20, + 0x5404: 0x402fbc20, 0x5405: 0x402fbd20, 0x5406: 0x402fbe20, 0x5407: 0x402fbf20, + 0x5408: 0x402fc020, 0x5409: 0x402fc120, 0x540a: 0x402fc220, 0x540b: 0x402fc320, + 0x540c: 0x402fc420, 0x540d: 0x402fc520, 0x540e: 0x402fc620, 0x540f: 0x402fc720, + 0x5410: 0x402fc820, 0x5411: 0x402fc920, 0x5412: 0x402fca20, 0x5413: 0x402fcb20, + 0x5414: 0x402fcc20, 0x5415: 0x402fcd20, 0x5416: 0x402fce20, 0x5417: 0x402fcf20, + 0x5418: 0x402fd020, 0x5419: 0x402fd120, 0x541a: 0x402fd220, 0x541b: 0x402fd320, + 0x541c: 0x402fd420, 0x541d: 0x402fd520, 0x541e: 0x402fd620, 0x541f: 0x402fd720, + 0x5420: 0x402fd820, 0x5421: 0x402fd920, 0x5422: 0x402fda20, 0x5423: 0x402fdb20, + 0x5424: 0x402fdc20, 0x5425: 0x402fdd20, 0x5426: 0x402fde20, 0x5427: 0x402fdf20, + 0x5428: 0x402fe020, 0x5429: 0x402fe120, 0x542a: 0x402fe220, 0x542b: 0x402fe320, + 0x542c: 0x402fe420, 0x542d: 0x402fe520, 0x542e: 0x402fe620, 0x542f: 0x402fe720, + 0x5430: 0x402fe820, 0x5431: 0x402fe920, 0x5432: 0x402fea20, 0x5433: 0x402feb20, + 0x5434: 0x402fec20, 0x5435: 0x402fed20, 0x5436: 0x402fee20, 0x5437: 0x402fef20, + 0x5438: 0x402ff020, 0x5439: 0x402ff120, 0x543a: 0x402ff220, 0x543b: 0x402ff320, + 0x543c: 0x402ff420, 0x543d: 0x402ff520, 0x543e: 0x402ff620, 0x543f: 0x402ff720, + // Block 0x151, offset 0x5440 + 0x5440: 0x402ff820, 0x5441: 0x402ff920, 0x5442: 0x402ffa20, 0x5443: 0x402ffb20, + 0x5444: 0x402ffc20, 0x5445: 0x402ffd20, 0x5446: 0x402ffe20, 0x5447: 0x402fff20, + 0x5448: 0x40300020, 0x5449: 0x40300120, 0x544a: 0x40300220, 0x544b: 0x40300320, + 0x544c: 0x40300420, 0x544d: 0x40300520, 0x544e: 0x40300620, 0x544f: 0x40300720, + 0x5450: 0x40300820, 0x5451: 0x40300920, 0x5452: 0x40300a20, 0x5453: 0x40300b20, + 0x5454: 0x40300c20, 0x5455: 0x40300d20, 0x5456: 0x40300e20, 0x5457: 0x40300f20, + 0x5458: 0x40301020, 0x5459: 0x40301120, 0x545a: 0x40301220, 0x545b: 0x40301320, + 0x545c: 0x40301420, 0x545d: 0x40301520, 0x545e: 0x40301620, 0x545f: 0x40301720, + 0x5460: 0x40301820, 0x5461: 0x40301920, 0x5462: 0x40301a20, 0x5463: 0x40301b20, + 0x5464: 0x40301c20, 0x5465: 0x40301d20, 0x5466: 0x40301e20, 0x5467: 0x40301f20, + 0x5468: 0x40302020, 0x5469: 0x40302120, 0x546a: 0x40302220, 0x546b: 0x40302320, + 0x546c: 0x40302420, 0x546d: 0x40302520, 0x546e: 0x40302620, 0x546f: 0x40302720, + 0x5470: 0x40302820, 0x5471: 0x40302920, 0x5472: 0x40302a20, 0x5473: 0x40302b20, + 0x5474: 0x40302c20, 0x5475: 0x40302d20, 0x5476: 0x40302e20, 0x5477: 0x40302f20, + 0x5478: 0x40303020, + // Block 0x152, offset 0x5480 + 0x5480: 0x40319920, 0x5481: 0x4031bc20, + // Block 0x153, offset 0x54c0 + 0x54c0: 0x400d9c20, 0x54c1: 0x400d9d20, 0x54c2: 0x400d9e20, 0x54c3: 0x400d9f20, + 0x54c4: 0x400da020, 0x54c5: 0x400da120, 0x54c6: 0x400da220, 0x54c7: 0x400da320, + 0x54c8: 0x400da420, 0x54c9: 0x400da520, 0x54ca: 0x400da620, 0x54cb: 0x400da720, + 0x54cc: 0x400da820, 0x54cd: 0x400da920, 0x54ce: 0x400daa20, 0x54cf: 0x400dab20, + 0x54d0: 0x400dac20, 0x54d1: 0x400dad20, 0x54d2: 0x400dae20, 0x54d3: 0x400daf20, + 0x54d4: 0x400db020, 0x54d5: 0x400db120, 0x54d6: 0x400db220, 0x54d7: 0x400db320, + 0x54d8: 0x400db420, 0x54d9: 0x400db520, 0x54da: 0x400db620, 0x54db: 0x400db720, + 0x54dc: 0x400db820, 0x54dd: 0x400db920, 0x54de: 0x400dba20, 0x54df: 0x400dbb20, + 0x54e0: 0x400dbc20, 0x54e1: 0x400dbd20, 0x54e2: 0x400dbe20, 0x54e3: 0x400dbf20, + 0x54e4: 0x400dc020, 0x54e5: 0x400dc120, 0x54e6: 0x400dc220, 0x54e7: 0x400dc320, + 0x54e8: 0x400dc420, 0x54e9: 0x400dc520, 0x54ea: 0x400dc620, 0x54eb: 0x400dc720, + 0x54ec: 0x400dc820, 0x54ed: 0x400dc920, 0x54ee: 0x400dca20, 0x54ef: 0x400dcb20, + 0x54f0: 0x400dcc20, 0x54f1: 0x400dcd20, 0x54f2: 0x400dce20, 0x54f3: 0x400dcf20, + 0x54f4: 0x400dd020, 0x54f5: 0x400dd120, 0x54f6: 0x400dd220, 0x54f7: 0x400dd320, + 0x54f8: 0x400dd420, 0x54f9: 0x400dd520, 0x54fa: 0x400dd620, 0x54fb: 0x400dd720, + 0x54fc: 0x400dd820, 0x54fd: 0x400dd920, 0x54fe: 0x400dda20, 0x54ff: 0x400ddb20, + // Block 0x154, offset 0x5500 + 0x5500: 0x400ddc20, 0x5501: 0x400ddd20, 0x5502: 0x400dde20, 0x5503: 0x400ddf20, + 0x5504: 0x400de020, 0x5505: 0x400de120, 0x5506: 0x400de220, 0x5507: 0x400de320, + 0x5508: 0x400de420, 0x5509: 0x400de520, 0x550a: 0x400de620, 0x550b: 0x400de720, + 0x550c: 0x400de820, 0x550d: 0x400de920, 0x550e: 0x400dea20, 0x550f: 0x400deb20, + 0x5510: 0x400dec20, 0x5511: 0x400ded20, 0x5512: 0x400dee20, 0x5513: 0x400def20, + 0x5514: 0x400df020, 0x5515: 0x400df120, 0x5516: 0x400df220, 0x5517: 0x400df320, + 0x5518: 0x400df420, 0x5519: 0x400df520, 0x551a: 0x400df620, 0x551b: 0x400df720, + 0x551c: 0x400df820, 0x551d: 0x400df920, 0x551e: 0x400dfa20, 0x551f: 0x400dfb20, + 0x5520: 0x400dfc20, 0x5521: 0x400dfd20, 0x5522: 0x400dfe20, 0x5523: 0x400dff20, + 0x5524: 0x400e0020, 0x5525: 0x400e0120, 0x5526: 0x400e0220, 0x5527: 0x400e0320, + 0x5528: 0x400e0420, 0x5529: 0x400e0520, 0x552a: 0x400e0620, 0x552b: 0x400e0720, + 0x552c: 0x400e0820, 0x552d: 0x400e0920, 0x552e: 0x400e0a20, 0x552f: 0x400e0b20, + 0x5530: 0x400e0c20, 0x5531: 0x400e0d20, 0x5532: 0x400e0e20, 0x5533: 0x400e0f20, + 0x5534: 0x400e1020, 0x5535: 0x400e1120, 0x5536: 0x400e1220, 0x5537: 0x400e1320, + 0x5538: 0x400e1420, 0x5539: 0x400e1520, 0x553a: 0x400e1620, 0x553b: 0x400e1720, + 0x553c: 0x400e1820, 0x553d: 0x400e1920, 0x553e: 0x400e1a20, 0x553f: 0x400e1b20, + // Block 0x155, offset 0x5540 + 0x5540: 0x400e1c20, 0x5541: 0x400e1d20, 0x5542: 0x400e1e20, 0x5543: 0x400e1f20, + 0x5544: 0x400e2020, 0x5545: 0x400e2120, 0x5546: 0x400e2220, 0x5547: 0x400e2320, + 0x5548: 0x400e2420, 0x5549: 0x400e2520, 0x554a: 0x400e2620, 0x554b: 0x400e2720, + 0x554c: 0x400e2820, 0x554d: 0x400e2920, 0x554e: 0x400e2a20, 0x554f: 0x400e2b20, + 0x5550: 0x400e2c20, 0x5551: 0x400e2d20, 0x5552: 0x400e2e20, 0x5553: 0x400e2f20, + 0x5554: 0x400e3020, 0x5555: 0x400e3120, 0x5556: 0x400e3220, 0x5557: 0x400e3320, + 0x5558: 0x400e3420, 0x5559: 0x400e3520, 0x555a: 0x400e3620, 0x555b: 0x400e3720, + 0x555c: 0x400e3820, 0x555d: 0x400e3920, 0x555e: 0x400e3a20, 0x555f: 0x400e3b20, + 0x5560: 0x400e3c20, 0x5561: 0x400e3d20, 0x5562: 0x400e3e20, 0x5563: 0x400e3f20, + 0x5564: 0x400e4020, 0x5565: 0x400e4120, 0x5566: 0x400e4220, 0x5567: 0x400e4320, + 0x5568: 0x400e4420, 0x5569: 0x400e4520, 0x556a: 0x400e4620, 0x556b: 0x400e4720, + 0x556c: 0x400e4820, 0x556d: 0x400e4920, 0x556e: 0x400e4a20, 0x556f: 0x400e4b20, + 0x5570: 0x400e4c20, 0x5571: 0x400e4d20, 0x5572: 0x400e4e20, 0x5573: 0x400e4f20, + 0x5574: 0x400e5020, 0x5575: 0x400e5120, 0x5576: 0x400e5220, 0x5577: 0x400e5320, + 0x5578: 0x400e5420, 0x5579: 0x400e5520, 0x557a: 0x400e5620, 0x557b: 0x400e5720, + 0x557c: 0x400e5820, 0x557d: 0x400e5920, 0x557e: 0x400e5a20, 0x557f: 0x400e5b20, + // Block 0x156, offset 0x5580 + 0x5580: 0x400e5c20, 0x5581: 0x400e5d20, 0x5582: 0x400e5e20, 0x5583: 0x400e5f20, + 0x5584: 0x400e6020, 0x5585: 0x400e6120, 0x5586: 0x400e6220, 0x5587: 0x400e6320, + 0x5588: 0x400e6420, 0x5589: 0x400e6520, 0x558a: 0x400e6620, 0x558b: 0x400e6720, + 0x558c: 0x400e6820, 0x558d: 0x400e6920, 0x558e: 0x400e6a20, 0x558f: 0x400e6b20, + 0x5590: 0x400e6c20, 0x5591: 0x400e6d20, 0x5592: 0x400e6e20, 0x5593: 0x400e6f20, + 0x5594: 0x400e7020, 0x5595: 0x400e7120, 0x5596: 0x400e7220, 0x5597: 0x400e7320, + 0x5598: 0x400e7420, 0x5599: 0x400e7520, 0x559a: 0x400e7620, 0x559b: 0x400e7720, + 0x559c: 0x400e7820, 0x559d: 0x400e7920, 0x559e: 0x400e7a20, 0x559f: 0x400e7b20, + 0x55a0: 0x400e7c20, 0x55a1: 0x400e7d20, 0x55a2: 0x400e7e20, 0x55a3: 0x400e7f20, + 0x55a4: 0x400e8020, 0x55a5: 0x400e8120, 0x55a6: 0x400e8220, 0x55a7: 0x400e8320, + 0x55a8: 0x400e8420, 0x55a9: 0x400e8520, 0x55aa: 0x400e8620, 0x55ab: 0x400e8720, + 0x55ac: 0x400e8820, 0x55ad: 0x400e8920, 0x55ae: 0x400e8a20, 0x55af: 0x400e8b20, + 0x55b0: 0x400e8c20, 0x55b1: 0x400e8d20, 0x55b2: 0x400e8e20, 0x55b3: 0x400e8f20, + 0x55b4: 0x400e9020, 0x55b5: 0x400e9120, + // Block 0x157, offset 0x55c0 + 0x55c0: 0x400e9220, 0x55c1: 0x400e9320, 0x55c2: 0x400e9420, 0x55c3: 0x400e9520, + 0x55c4: 0x400e9620, 0x55c5: 0x400e9720, 0x55c6: 0x400e9820, 0x55c7: 0x400e9920, + 0x55c8: 0x400e9a20, 0x55c9: 0x400e9b20, 0x55ca: 0x400e9c20, 0x55cb: 0x400e9d20, + 0x55cc: 0x400e9e20, 0x55cd: 0x400e9f20, 0x55ce: 0x400ea020, 0x55cf: 0x400ea120, + 0x55d0: 0x400ea220, 0x55d1: 0x400ea320, 0x55d2: 0x400ea420, 0x55d3: 0x400ea520, + 0x55d4: 0x400ea620, 0x55d5: 0x400ea720, 0x55d6: 0x400ea820, 0x55d7: 0x400ea920, + 0x55d8: 0x400eaa20, 0x55d9: 0x400eab20, 0x55da: 0x400eac20, 0x55db: 0x400ead20, + 0x55dc: 0x400eae20, 0x55dd: 0x400eaf20, 0x55de: 0x400eb020, 0x55df: 0x400eb120, + 0x55e0: 0x400eb220, 0x55e1: 0x400eb320, 0x55e2: 0x400eb420, 0x55e3: 0x400eb520, + 0x55e4: 0x400eb620, 0x55e5: 0x400eb720, 0x55e6: 0x400eb820, + 0x55e9: 0x400ecc20, 0x55ea: 0x400ebc20, 0x55eb: 0x400ebd20, + 0x55ec: 0x400ebe20, 0x55ed: 0x400ebf20, 0x55ee: 0x400ec020, 0x55ef: 0x400ec120, + 0x55f0: 0x400ec220, 0x55f1: 0x400ec320, 0x55f2: 0x400ec420, 0x55f3: 0x400ec520, + 0x55f4: 0x400ec620, 0x55f5: 0x400ec720, 0x55f6: 0x400ec820, 0x55f7: 0x400ec920, + 0x55f8: 0x400eca20, 0x55f9: 0x400ecb20, 0x55fa: 0x400ecd20, 0x55fb: 0x400ece20, + 0x55fc: 0x400ecf20, 0x55fd: 0x400ed020, 0x55fe: 0x400ed120, 0x55ff: 0x400ed220, + // Block 0x158, offset 0x5600 + 0x5600: 0x400ed320, 0x5601: 0x400ed420, 0x5602: 0x400ed520, 0x5603: 0x400ed620, + 0x5604: 0x400ed720, 0x5605: 0x400ed820, 0x5606: 0x400ed920, 0x5607: 0x400eda20, + 0x5608: 0x400edb20, 0x5609: 0x400edc20, 0x560a: 0x400edd20, 0x560b: 0x400ede20, + 0x560c: 0x400edf20, 0x560d: 0x400ee020, 0x560e: 0x400ee120, 0x560f: 0x400ee220, + 0x5610: 0x400ee320, 0x5611: 0x400ee420, 0x5612: 0x400ee520, 0x5613: 0x400ee620, + 0x5614: 0x400ee720, 0x5615: 0x400ee820, 0x5616: 0x400ee920, 0x5617: 0x400eea20, + 0x5618: 0x400eeb20, 0x5619: 0x400eec20, 0x561a: 0x400eed20, 0x561b: 0x400eee20, + 0x561c: 0x400eef20, 0x561d: 0x400ef020, 0x561e: 0x400eea20, 0x561f: 0x400eeb20, + 0x5620: 0x400eeb20, 0x5621: 0x400eeb20, 0x5622: 0x400eeb20, 0x5623: 0x400eeb20, + 0x5624: 0x400eeb20, 0x5625: 0x80000000, 0x5626: 0x80000000, 0x5627: 0x80000000, + 0x5628: 0x80000000, 0x5629: 0x80000000, 0x562a: 0x400ef120, 0x562b: 0x400ef220, + 0x562c: 0x400ef320, 0x562d: 0x80000000, 0x562e: 0x80000000, 0x562f: 0x80000000, + 0x5630: 0x80000000, 0x5631: 0x80000000, 0x5632: 0x80000000, 0x5633: 0x80000000, + 0x5634: 0x80000000, 0x5635: 0x80000000, 0x5636: 0x80000000, 0x5637: 0x80000000, + 0x5638: 0x80000000, 0x5639: 0x80000000, 0x563a: 0x80000000, 0x563b: 0x80000000, + 0x563c: 0x80000000, 0x563d: 0x80000000, 0x563e: 0x80000000, 0x563f: 0x80000000, + // Block 0x159, offset 0x5640 + 0x5640: 0x80000000, 0x5641: 0x80000000, 0x5642: 0x80000000, 0x5643: 0x400ef420, + 0x5644: 0x400ef520, 0x5645: 0x80000000, 0x5646: 0x80000000, 0x5647: 0x80000000, + 0x5648: 0x80000000, 0x5649: 0x80000000, 0x564a: 0x80000000, 0x564b: 0x80000000, + 0x564c: 0x400ef620, 0x564d: 0x400ef720, 0x564e: 0x400ef820, 0x564f: 0x400ef920, + 0x5650: 0x400efa20, 0x5651: 0x400efb20, 0x5652: 0x400efc20, 0x5653: 0x400efd20, + 0x5654: 0x400efe20, 0x5655: 0x400eff20, 0x5656: 0x400f0020, 0x5657: 0x400f0120, + 0x5658: 0x400f0220, 0x5659: 0x400f0320, 0x565a: 0x400f0420, 0x565b: 0x400f0520, + 0x565c: 0x400f0620, 0x565d: 0x400f0720, 0x565e: 0x400f0820, 0x565f: 0x400f0920, + 0x5660: 0x400f0a20, 0x5661: 0x400f0b20, 0x5662: 0x400f0c20, 0x5663: 0x400f0d20, + 0x5664: 0x400f0e20, 0x5665: 0x400f0f20, 0x5666: 0x400f1020, 0x5667: 0x400f1120, + 0x5668: 0x400f1220, 0x5669: 0x400f1320, 0x566a: 0x80000000, 0x566b: 0x80000000, + 0x566c: 0x80000000, 0x566d: 0x80000000, 0x566e: 0x400f1420, 0x566f: 0x400f1520, + 0x5670: 0x400f1620, 0x5671: 0x400f1720, 0x5672: 0x400f1820, 0x5673: 0x400f1920, + 0x5674: 0x400f1a20, 0x5675: 0x400f1b20, 0x5676: 0x400f1c20, 0x5677: 0x400f1d20, + 0x5678: 0x400f1e20, 0x5679: 0x400f1f20, 0x567a: 0x400f2020, 0x567b: 0x400f1f20, + 0x567c: 0x400f2020, 0x567d: 0x400f1f20, 0x567e: 0x400f2020, 0x567f: 0x400f1f20, + // Block 0x15a, offset 0x5680 + 0x5680: 0x400f2020, 0x5681: 0x400f2120, 0x5682: 0x400f2220, 0x5683: 0x400f2320, + 0x5684: 0x400f2420, 0x5685: 0x400f2520, 0x5686: 0x400f2620, 0x5687: 0x400f2720, + 0x5688: 0x400f2820, 0x5689: 0x400f2920, 0x568a: 0x400f2a20, 0x568b: 0x400f2b20, + 0x568c: 0x400f2c20, 0x568d: 0x400f2d20, 0x568e: 0x400f2e20, 0x568f: 0x400f2f20, + 0x5690: 0x400f3020, 0x5691: 0x400f3120, 0x5692: 0x400f3220, 0x5693: 0x400f3320, + 0x5694: 0x400f3420, 0x5695: 0x400f3520, 0x5696: 0x400f3620, 0x5697: 0x400f3720, + 0x5698: 0x400f3820, 0x5699: 0x400f3920, 0x569a: 0x400f3a20, 0x569b: 0x400f3b20, + 0x569c: 0x400f3c20, 0x569d: 0x400f3d20, + // Block 0x15b, offset 0x56c0 + 0x56c0: 0x400f3e20, 0x56c1: 0x400f3f20, 0x56c2: 0x400f4020, 0x56c3: 0x400f4120, + 0x56c4: 0x400f4220, 0x56c5: 0x400f4320, 0x56c6: 0x400f4420, 0x56c7: 0x400f4520, + 0x56c8: 0x400f4620, 0x56c9: 0x400f4720, 0x56ca: 0x400f4820, 0x56cb: 0x400f4920, + 0x56cc: 0x400f4a20, 0x56cd: 0x400f4b20, 0x56ce: 0x400f4c20, 0x56cf: 0x400f4d20, + 0x56d0: 0x400f4e20, 0x56d1: 0x400f4f20, 0x56d2: 0x400f5020, 0x56d3: 0x400f5120, + 0x56d4: 0x400f5220, 0x56d5: 0x400f5320, 0x56d6: 0x400f5420, 0x56d7: 0x400f5520, + 0x56d8: 0x400f5620, 0x56d9: 0x400f5720, 0x56da: 0x400f5820, 0x56db: 0x400f5920, + 0x56dc: 0x400f5a20, 0x56dd: 0x400f5b20, 0x56de: 0x400f5c20, 0x56df: 0x400f5d20, + 0x56e0: 0x400f5e20, 0x56e1: 0x400f5f20, 0x56e2: 0x400f6020, 0x56e3: 0x400f6120, + 0x56e4: 0x400f6220, 0x56e5: 0x400f6320, 0x56e6: 0x400f6420, 0x56e7: 0x400f6520, + 0x56e8: 0x400f6620, 0x56e9: 0x400f6720, 0x56ea: 0x400f6820, 0x56eb: 0x400f6920, + 0x56ec: 0x400f6a20, 0x56ed: 0x400f6b20, 0x56ee: 0x400f6c20, 0x56ef: 0x400f6d20, + 0x56f0: 0x400f6e20, 0x56f1: 0x400f6f20, 0x56f2: 0x400f7020, 0x56f3: 0x400f7120, + 0x56f4: 0x400f7220, 0x56f5: 0x400f7320, 0x56f6: 0x400f7420, 0x56f7: 0x400f7520, + 0x56f8: 0x400f7620, 0x56f9: 0x400f7720, 0x56fa: 0x400f7820, 0x56fb: 0x400f7920, + 0x56fc: 0x400f7a20, 0x56fd: 0x400f7b20, 0x56fe: 0x400f7c20, 0x56ff: 0x400f7d20, + // Block 0x15c, offset 0x5700 + 0x5700: 0x400f7e20, 0x5701: 0x400f7f20, 0x5702: 0x80000000, 0x5703: 0x80000000, + 0x5704: 0x80000000, 0x5705: 0x400f8020, + // Block 0x15d, offset 0x5740 + 0x5740: 0x400cbb20, 0x5741: 0x400cbc20, 0x5742: 0x400cbd20, 0x5743: 0x400cbe20, + 0x5744: 0x400cbf20, 0x5745: 0x400cc020, 0x5746: 0x400cc120, 0x5747: 0x400cc220, + 0x5748: 0x400cc320, 0x5749: 0x400cc420, 0x574a: 0x400cc520, 0x574b: 0x400cc620, + 0x574c: 0x400cc720, 0x574d: 0x400cc820, 0x574e: 0x400cc920, 0x574f: 0x400cca20, + 0x5750: 0x400ccb20, 0x5751: 0x400ccc20, 0x5752: 0x400ccd20, 0x5753: 0x400cce20, + 0x5754: 0x400ccf20, 0x5755: 0x400cd020, 0x5756: 0x400cd120, 0x5757: 0x400cd220, + 0x5758: 0x400cd320, 0x5759: 0x400cd420, 0x575a: 0x400cd520, 0x575b: 0x400cd620, + 0x575c: 0x400cd720, 0x575d: 0x400cd820, 0x575e: 0x400cd920, 0x575f: 0x400cda20, + 0x5760: 0x400cdb20, 0x5761: 0x400cdc20, 0x5762: 0x400cdd20, 0x5763: 0x400cde20, + 0x5764: 0x400cdf20, 0x5765: 0x400ce020, 0x5766: 0x400ce120, 0x5767: 0x400ce220, + 0x5768: 0x400ce320, 0x5769: 0x400ce420, 0x576a: 0x400ce520, 0x576b: 0x400ce620, + 0x576c: 0x400ce720, 0x576d: 0x400ce820, 0x576e: 0x400ce920, 0x576f: 0x400cea20, + 0x5770: 0x400ceb20, 0x5771: 0x400cec20, 0x5772: 0x400ced20, 0x5773: 0x400cee20, + 0x5774: 0x400cef20, 0x5775: 0x400cf020, 0x5776: 0x400cf120, 0x5777: 0x400cf220, + 0x5778: 0x400cf320, 0x5779: 0x400cf420, 0x577a: 0x400cf520, 0x577b: 0x400cf620, + 0x577c: 0x400cf720, 0x577d: 0x400cf820, 0x577e: 0x400cf920, 0x577f: 0x400cfa20, + // Block 0x15e, offset 0x5780 + 0x5780: 0x400cfb20, 0x5781: 0x400cfc20, 0x5782: 0x400cfd20, 0x5783: 0x400cfe20, + 0x5784: 0x400cff20, 0x5785: 0x400d0020, 0x5786: 0x400d0120, 0x5787: 0x400d0220, + 0x5788: 0x400d0320, 0x5789: 0x400d0420, 0x578a: 0x400d0520, 0x578b: 0x400d0620, + 0x578c: 0x400d0720, 0x578d: 0x400d0820, 0x578e: 0x400d0920, 0x578f: 0x400d0a20, + 0x5790: 0x400d0b20, 0x5791: 0x400d0c20, 0x5792: 0x400d0d20, 0x5793: 0x400d0e20, + 0x5794: 0x400d0f20, 0x5795: 0x400d1020, 0x5796: 0x400d1120, + 0x57a0: 0xe0000156, 0x57a1: 0xe0000240, 0x57a2: 0xe0000306, 0x57a3: 0xe00003c0, + 0x57a4: 0xe0000477, 0x57a5: 0xe0000513, 0x57a6: 0xe00005af, 0x57a7: 0xe0000648, + 0x57a8: 0xe00006e7, 0x57a9: 0x40149120, 0x57aa: 0x40149220, 0x57ab: 0x40149320, + 0x57ac: 0x40149420, 0x57ad: 0x40149520, 0x57ae: 0x40149620, 0x57af: 0x40149720, + 0x57b0: 0x40149820, 0x57b1: 0x40149920, + // Block 0x15f, offset 0x57c0 + 0x57c0: 0xf000000b, 0x57c1: 0xf000000b, 0x57c2: 0xf000000b, 0x57c3: 0xf000000b, + 0x57c4: 0xf000000b, 0x57c5: 0xf000000b, 0x57c6: 0xf000000b, 0x57c7: 0xf000000b, + 0x57c8: 0xf000000b, 0x57c9: 0xf000000b, 0x57ca: 0xf000000b, 0x57cb: 0xf000000b, + 0x57cc: 0xf000000b, 0x57cd: 0xf000000b, 0x57ce: 0xf000000b, 0x57cf: 0xf000000b, + 0x57d0: 0xf000000b, 0x57d1: 0xf000000b, 0x57d2: 0xf000000b, 0x57d3: 0xf000000b, + 0x57d4: 0xf000000b, 0x57d5: 0xf000000b, 0x57d6: 0xf000000b, 0x57d7: 0xf000000b, + 0x57d8: 0xf000000b, 0x57d9: 0xf000000b, 0x57da: 0xf0000005, 0x57db: 0xf0000005, + 0x57dc: 0xf0000005, 0x57dd: 0xf0000005, 0x57de: 0xf0000005, 0x57df: 0xf0000005, + 0x57e0: 0xf0000005, 0x57e1: 0xf0000005, 0x57e2: 0xf0000005, 0x57e3: 0xf0000005, + 0x57e4: 0xf0000005, 0x57e5: 0xf0000005, 0x57e6: 0xf0000005, 0x57e7: 0xf0000005, + 0x57e8: 0xf0000005, 0x57e9: 0xf0000005, 0x57ea: 0xf0000005, 0x57eb: 0xf0000005, + 0x57ec: 0xf0000005, 0x57ed: 0xf0000005, 0x57ee: 0xf0000005, 0x57ef: 0xf0000005, + 0x57f0: 0xf0000005, 0x57f1: 0xf0000005, 0x57f2: 0xf0000005, 0x57f3: 0xf0000005, + 0x57f4: 0xf000000b, 0x57f5: 0xf000000b, 0x57f6: 0xf000000b, 0x57f7: 0xf000000b, + 0x57f8: 0xf000000b, 0x57f9: 0xf000000b, 0x57fa: 0xf000000b, 0x57fb: 0xf000000b, + 0x57fc: 0xf000000b, 0x57fd: 0xf000000b, 0x57fe: 0xf000000b, 0x57ff: 0xf000000b, + // Block 0x160, offset 0x5800 + 0x5800: 0xf000000b, 0x5801: 0xf000000b, 0x5802: 0xf000000b, 0x5803: 0xf000000b, + 0x5804: 0xf000000b, 0x5805: 0xf000000b, 0x5806: 0xf000000b, 0x5807: 0xf000000b, + 0x5808: 0xf000000b, 0x5809: 0xf000000b, 0x580a: 0xf000000b, 0x580b: 0xf000000b, + 0x580c: 0xf000000b, 0x580d: 0xf000000b, 0x580e: 0xf0000005, 0x580f: 0xf0000005, + 0x5810: 0xf0000005, 0x5811: 0xf0000005, 0x5812: 0xf0000005, 0x5813: 0xf0000005, + 0x5814: 0xf0000005, 0x5816: 0xf0000005, 0x5817: 0xf0000005, + 0x5818: 0xf0000005, 0x5819: 0xf0000005, 0x581a: 0xf0000005, 0x581b: 0xf0000005, + 0x581c: 0xf0000005, 0x581d: 0xf0000005, 0x581e: 0xf0000005, 0x581f: 0xf0000005, + 0x5820: 0xf0000005, 0x5821: 0xf0000005, 0x5822: 0xf0000005, 0x5823: 0xf0000005, + 0x5824: 0xf0000005, 0x5825: 0xf0000005, 0x5826: 0xf0000005, 0x5827: 0xf0000005, + 0x5828: 0xf000000b, 0x5829: 0xf000000b, 0x582a: 0xf000000b, 0x582b: 0xf000000b, + 0x582c: 0xf000000b, 0x582d: 0xf000000b, 0x582e: 0xf000000b, 0x582f: 0xf000000b, + 0x5830: 0xf000000b, 0x5831: 0xf000000b, 0x5832: 0xf000000b, 0x5833: 0xf000000b, + 0x5834: 0xf000000b, 0x5835: 0xf000000b, 0x5836: 0xf000000b, 0x5837: 0xf000000b, + 0x5838: 0xf000000b, 0x5839: 0xf000000b, 0x583a: 0xf000000b, 0x583b: 0xf000000b, + 0x583c: 0xf000000b, 0x583d: 0xf000000b, 0x583e: 0xf000000b, 0x583f: 0xf000000b, + // Block 0x161, offset 0x5840 + 0x5840: 0xf000000b, 0x5841: 0xf000000b, 0x5842: 0xf0000005, 0x5843: 0xf0000005, + 0x5844: 0xf0000005, 0x5845: 0xf0000005, 0x5846: 0xf0000005, 0x5847: 0xf0000005, + 0x5848: 0xf0000005, 0x5849: 0xf0000005, 0x584a: 0xf0000005, 0x584b: 0xf0000005, + 0x584c: 0xf0000005, 0x584d: 0xf0000005, 0x584e: 0xf0000005, 0x584f: 0xf0000005, + 0x5850: 0xf0000005, 0x5851: 0xf0000005, 0x5852: 0xf0000005, 0x5853: 0xf0000005, + 0x5854: 0xf0000005, 0x5855: 0xf0000005, 0x5856: 0xf0000005, 0x5857: 0xf0000005, + 0x5858: 0xf0000005, 0x5859: 0xf0000005, 0x585a: 0xf0000005, 0x585b: 0xf0000005, + 0x585c: 0xf000000b, 0x585e: 0xf000000b, 0x585f: 0xf000000b, + 0x5862: 0xf000000b, + 0x5865: 0xf000000b, 0x5866: 0xf000000b, + 0x5869: 0xf000000b, 0x586a: 0xf000000b, 0x586b: 0xf000000b, + 0x586c: 0xf000000b, 0x586e: 0xf000000b, 0x586f: 0xf000000b, + 0x5870: 0xf000000b, 0x5871: 0xf000000b, 0x5872: 0xf000000b, 0x5873: 0xf000000b, + 0x5874: 0xf000000b, 0x5875: 0xf000000b, 0x5876: 0xf0000005, 0x5877: 0xf0000005, + 0x5878: 0xf0000005, 0x5879: 0xf0000005, 0x587b: 0xf0000005, + 0x587d: 0xf0000005, 0x587e: 0xf0000005, 0x587f: 0xf0000005, + // Block 0x162, offset 0x5880 + 0x5880: 0xf0000005, 0x5881: 0xf0000005, 0x5882: 0xf0000005, 0x5883: 0xf0000005, + 0x5885: 0xf0000005, 0x5886: 0xf0000005, 0x5887: 0xf0000005, + 0x5888: 0xf0000005, 0x5889: 0xf0000005, 0x588a: 0xf0000005, 0x588b: 0xf0000005, + 0x588c: 0xf0000005, 0x588d: 0xf0000005, 0x588e: 0xf0000005, 0x588f: 0xf0000005, + 0x5890: 0xf000000b, 0x5891: 0xf000000b, 0x5892: 0xf000000b, 0x5893: 0xf000000b, + 0x5894: 0xf000000b, 0x5895: 0xf000000b, 0x5896: 0xf000000b, 0x5897: 0xf000000b, + 0x5898: 0xf000000b, 0x5899: 0xf000000b, 0x589a: 0xf000000b, 0x589b: 0xf000000b, + 0x589c: 0xf000000b, 0x589d: 0xf000000b, 0x589e: 0xf000000b, 0x589f: 0xf000000b, + 0x58a0: 0xf000000b, 0x58a1: 0xf000000b, 0x58a2: 0xf000000b, 0x58a3: 0xf000000b, + 0x58a4: 0xf000000b, 0x58a5: 0xf000000b, 0x58a6: 0xf000000b, 0x58a7: 0xf000000b, + 0x58a8: 0xf000000b, 0x58a9: 0xf000000b, 0x58aa: 0xf0000005, 0x58ab: 0xf0000005, + 0x58ac: 0xf0000005, 0x58ad: 0xf0000005, 0x58ae: 0xf0000005, 0x58af: 0xf0000005, + 0x58b0: 0xf0000005, 0x58b1: 0xf0000005, 0x58b2: 0xf0000005, 0x58b3: 0xf0000005, + 0x58b4: 0xf0000005, 0x58b5: 0xf0000005, 0x58b6: 0xf0000005, 0x58b7: 0xf0000005, + 0x58b8: 0xf0000005, 0x58b9: 0xf0000005, 0x58ba: 0xf0000005, 0x58bb: 0xf0000005, + 0x58bc: 0xf0000005, 0x58bd: 0xf0000005, 0x58be: 0xf0000005, 0x58bf: 0xf0000005, + // Block 0x163, offset 0x58c0 + 0x58c0: 0xf0000005, 0x58c1: 0xf0000005, 0x58c2: 0xf0000005, 0x58c3: 0xf0000005, + 0x58c4: 0xf000000b, 0x58c5: 0xf000000b, 0x58c7: 0xf000000b, + 0x58c8: 0xf000000b, 0x58c9: 0xf000000b, 0x58ca: 0xf000000b, + 0x58cd: 0xf000000b, 0x58ce: 0xf000000b, 0x58cf: 0xf000000b, + 0x58d0: 0xf000000b, 0x58d1: 0xf000000b, 0x58d2: 0xf000000b, 0x58d3: 0xf000000b, + 0x58d4: 0xf000000b, 0x58d6: 0xf000000b, 0x58d7: 0xf000000b, + 0x58d8: 0xf000000b, 0x58d9: 0xf000000b, 0x58da: 0xf000000b, 0x58db: 0xf000000b, + 0x58dc: 0xf000000b, 0x58de: 0xf0000005, 0x58df: 0xf0000005, + 0x58e0: 0xf0000005, 0x58e1: 0xf0000005, 0x58e2: 0xf0000005, 0x58e3: 0xf0000005, + 0x58e4: 0xf0000005, 0x58e5: 0xf0000005, 0x58e6: 0xf0000005, 0x58e7: 0xf0000005, + 0x58e8: 0xf0000005, 0x58e9: 0xf0000005, 0x58ea: 0xf0000005, 0x58eb: 0xf0000005, + 0x58ec: 0xf0000005, 0x58ed: 0xf0000005, 0x58ee: 0xf0000005, 0x58ef: 0xf0000005, + 0x58f0: 0xf0000005, 0x58f1: 0xf0000005, 0x58f2: 0xf0000005, 0x58f3: 0xf0000005, + 0x58f4: 0xf0000005, 0x58f5: 0xf0000005, 0x58f6: 0xf0000005, 0x58f7: 0xf0000005, + 0x58f8: 0xf000000b, 0x58f9: 0xf000000b, 0x58fb: 0xf000000b, + 0x58fc: 0xf000000b, 0x58fd: 0xf000000b, 0x58fe: 0xf000000b, + // Block 0x164, offset 0x5900 + 0x5900: 0xf000000b, 0x5901: 0xf000000b, 0x5902: 0xf000000b, 0x5903: 0xf000000b, + 0x5904: 0xf000000b, 0x5906: 0xf000000b, + 0x590a: 0xf000000b, 0x590b: 0xf000000b, + 0x590c: 0xf000000b, 0x590d: 0xf000000b, 0x590e: 0xf000000b, 0x590f: 0xf000000b, + 0x5910: 0xf000000b, 0x5912: 0xf0000005, 0x5913: 0xf0000005, + 0x5914: 0xf0000005, 0x5915: 0xf0000005, 0x5916: 0xf0000005, 0x5917: 0xf0000005, + 0x5918: 0xf0000005, 0x5919: 0xf0000005, 0x591a: 0xf0000005, 0x591b: 0xf0000005, + 0x591c: 0xf0000005, 0x591d: 0xf0000005, 0x591e: 0xf0000005, 0x591f: 0xf0000005, + 0x5920: 0xf0000005, 0x5921: 0xf0000005, 0x5922: 0xf0000005, 0x5923: 0xf0000005, + 0x5924: 0xf0000005, 0x5925: 0xf0000005, 0x5926: 0xf0000005, 0x5927: 0xf0000005, + 0x5928: 0xf0000005, 0x5929: 0xf0000005, 0x592a: 0xf0000005, 0x592b: 0xf0000005, + 0x592c: 0xf000000b, 0x592d: 0xf000000b, 0x592e: 0xf000000b, 0x592f: 0xf000000b, + 0x5930: 0xf000000b, 0x5931: 0xf000000b, 0x5932: 0xf000000b, 0x5933: 0xf000000b, + 0x5934: 0xf000000b, 0x5935: 0xf000000b, 0x5936: 0xf000000b, 0x5937: 0xf000000b, + 0x5938: 0xf000000b, 0x5939: 0xf000000b, 0x593a: 0xf000000b, 0x593b: 0xf000000b, + 0x593c: 0xf000000b, 0x593d: 0xf000000b, 0x593e: 0xf000000b, 0x593f: 0xf000000b, + // Block 0x165, offset 0x5940 + 0x5940: 0xf000000b, 0x5941: 0xf000000b, 0x5942: 0xf000000b, 0x5943: 0xf000000b, + 0x5944: 0xf000000b, 0x5945: 0xf000000b, 0x5946: 0xf0000005, 0x5947: 0xf0000005, + 0x5948: 0xf0000005, 0x5949: 0xf0000005, 0x594a: 0xf0000005, 0x594b: 0xf0000005, + 0x594c: 0xf0000005, 0x594d: 0xf0000005, 0x594e: 0xf0000005, 0x594f: 0xf0000005, + 0x5950: 0xf0000005, 0x5951: 0xf0000005, 0x5952: 0xf0000005, 0x5953: 0xf0000005, + 0x5954: 0xf0000005, 0x5955: 0xf0000005, 0x5956: 0xf0000005, 0x5957: 0xf0000005, + 0x5958: 0xf0000005, 0x5959: 0xf0000005, 0x595a: 0xf0000005, 0x595b: 0xf0000005, + 0x595c: 0xf0000005, 0x595d: 0xf0000005, 0x595e: 0xf0000005, 0x595f: 0xf0000005, + 0x5960: 0xf000000b, 0x5961: 0xf000000b, 0x5962: 0xf000000b, 0x5963: 0xf000000b, + 0x5964: 0xf000000b, 0x5965: 0xf000000b, 0x5966: 0xf000000b, 0x5967: 0xf000000b, + 0x5968: 0xf000000b, 0x5969: 0xf000000b, 0x596a: 0xf000000b, 0x596b: 0xf000000b, + 0x596c: 0xf000000b, 0x596d: 0xf000000b, 0x596e: 0xf000000b, 0x596f: 0xf000000b, + 0x5970: 0xf000000b, 0x5971: 0xf000000b, 0x5972: 0xf000000b, 0x5973: 0xf000000b, + 0x5974: 0xf000000b, 0x5975: 0xf000000b, 0x5976: 0xf000000b, 0x5977: 0xf000000b, + 0x5978: 0xf000000b, 0x5979: 0xf000000b, 0x597a: 0xf0000005, 0x597b: 0xf0000005, + 0x597c: 0xf0000005, 0x597d: 0xf0000005, 0x597e: 0xf0000005, 0x597f: 0xf0000005, + // Block 0x166, offset 0x5980 + 0x5980: 0xf0000005, 0x5981: 0xf0000005, 0x5982: 0xf0000005, 0x5983: 0xf0000005, + 0x5984: 0xf0000005, 0x5985: 0xf0000005, 0x5986: 0xf0000005, 0x5987: 0xf0000005, + 0x5988: 0xf0000005, 0x5989: 0xf0000005, 0x598a: 0xf0000005, 0x598b: 0xf0000005, + 0x598c: 0xf0000005, 0x598d: 0xf0000005, 0x598e: 0xf0000005, 0x598f: 0xf0000005, + 0x5990: 0xf0000005, 0x5991: 0xf0000005, 0x5992: 0xf0000005, 0x5993: 0xf0000005, + 0x5994: 0xf000000b, 0x5995: 0xf000000b, 0x5996: 0xf000000b, 0x5997: 0xf000000b, + 0x5998: 0xf000000b, 0x5999: 0xf000000b, 0x599a: 0xf000000b, 0x599b: 0xf000000b, + 0x599c: 0xf000000b, 0x599d: 0xf000000b, 0x599e: 0xf000000b, 0x599f: 0xf000000b, + 0x59a0: 0xf000000b, 0x59a1: 0xf000000b, 0x59a2: 0xf000000b, 0x59a3: 0xf000000b, + 0x59a4: 0xf000000b, 0x59a5: 0xf000000b, 0x59a6: 0xf000000b, 0x59a7: 0xf000000b, + 0x59a8: 0xf000000b, 0x59a9: 0xf000000b, 0x59aa: 0xf000000b, 0x59ab: 0xf000000b, + 0x59ac: 0xf000000b, 0x59ad: 0xf000000b, 0x59ae: 0xf0000005, 0x59af: 0xf0000005, + 0x59b0: 0xf0000005, 0x59b1: 0xf0000005, 0x59b2: 0xf0000005, 0x59b3: 0xf0000005, + 0x59b4: 0xf0000005, 0x59b5: 0xf0000005, 0x59b6: 0xf0000005, 0x59b7: 0xf0000005, + 0x59b8: 0xf0000005, 0x59b9: 0xf0000005, 0x59ba: 0xf0000005, 0x59bb: 0xf0000005, + 0x59bc: 0xf0000005, 0x59bd: 0xf0000005, 0x59be: 0xf0000005, 0x59bf: 0xf0000005, + // Block 0x167, offset 0x59c0 + 0x59c0: 0xf0000005, 0x59c1: 0xf0000005, 0x59c2: 0xf0000005, 0x59c3: 0xf0000005, + 0x59c4: 0xf0000005, 0x59c5: 0xf0000005, 0x59c6: 0xf0000005, 0x59c7: 0xf0000005, + 0x59c8: 0xf000000b, 0x59c9: 0xf000000b, 0x59ca: 0xf000000b, 0x59cb: 0xf000000b, + 0x59cc: 0xf000000b, 0x59cd: 0xf000000b, 0x59ce: 0xf000000b, 0x59cf: 0xf000000b, + 0x59d0: 0xf000000b, 0x59d1: 0xf000000b, 0x59d2: 0xf000000b, 0x59d3: 0xf000000b, + 0x59d4: 0xf000000b, 0x59d5: 0xf000000b, 0x59d6: 0xf000000b, 0x59d7: 0xf000000b, + 0x59d8: 0xf000000b, 0x59d9: 0xf000000b, 0x59da: 0xf000000b, 0x59db: 0xf000000b, + 0x59dc: 0xf000000b, 0x59dd: 0xf000000b, 0x59de: 0xf000000b, 0x59df: 0xf000000b, + 0x59e0: 0xf000000b, 0x59e1: 0xf000000b, 0x59e2: 0xf0000005, 0x59e3: 0xf0000005, + 0x59e4: 0xf0000005, 0x59e5: 0xf0000005, 0x59e6: 0xf0000005, 0x59e7: 0xf0000005, + 0x59e8: 0xf0000005, 0x59e9: 0xf0000005, 0x59ea: 0xf0000005, 0x59eb: 0xf0000005, + 0x59ec: 0xf0000005, 0x59ed: 0xf0000005, 0x59ee: 0xf0000005, 0x59ef: 0xf0000005, + 0x59f0: 0xf0000005, 0x59f1: 0xf0000005, 0x59f2: 0xf0000005, 0x59f3: 0xf0000005, + 0x59f4: 0xf0000005, 0x59f5: 0xf0000005, 0x59f6: 0xf0000005, 0x59f7: 0xf0000005, + 0x59f8: 0xf0000005, 0x59f9: 0xf0000005, 0x59fa: 0xf0000005, 0x59fb: 0xf0000005, + 0x59fc: 0xf000000b, 0x59fd: 0xf000000b, 0x59fe: 0xf000000b, 0x59ff: 0xf000000b, + // Block 0x168, offset 0x5a00 + 0x5a00: 0xf000000b, 0x5a01: 0xf000000b, 0x5a02: 0xf000000b, 0x5a03: 0xf000000b, + 0x5a04: 0xf000000b, 0x5a05: 0xf000000b, 0x5a06: 0xf000000b, 0x5a07: 0xf000000b, + 0x5a08: 0xf000000b, 0x5a09: 0xf000000b, 0x5a0a: 0xf000000b, 0x5a0b: 0xf000000b, + 0x5a0c: 0xf000000b, 0x5a0d: 0xf000000b, 0x5a0e: 0xf000000b, 0x5a0f: 0xf000000b, + 0x5a10: 0xf000000b, 0x5a11: 0xf000000b, 0x5a12: 0xf000000b, 0x5a13: 0xf000000b, + 0x5a14: 0xf000000b, 0x5a15: 0xf000000b, 0x5a16: 0xf0000005, 0x5a17: 0xf0000005, + 0x5a18: 0xf0000005, 0x5a19: 0xf0000005, 0x5a1a: 0xf0000005, 0x5a1b: 0xf0000005, + 0x5a1c: 0xf0000005, 0x5a1d: 0xf0000005, 0x5a1e: 0xf0000005, 0x5a1f: 0xf0000005, + 0x5a20: 0xf0000005, 0x5a21: 0xf0000005, 0x5a22: 0xf0000005, 0x5a23: 0xf0000005, + 0x5a24: 0xf0000005, 0x5a25: 0xf0000005, 0x5a26: 0xf0000005, 0x5a27: 0xf0000005, + 0x5a28: 0xf0000005, 0x5a29: 0xf0000005, 0x5a2a: 0xf0000005, 0x5a2b: 0xf0000005, + 0x5a2c: 0xf0000005, 0x5a2d: 0xf0000005, 0x5a2e: 0xf0000005, 0x5a2f: 0xf0000005, + 0x5a30: 0xf000000b, 0x5a31: 0xf000000b, 0x5a32: 0xf000000b, 0x5a33: 0xf000000b, + 0x5a34: 0xf000000b, 0x5a35: 0xf000000b, 0x5a36: 0xf000000b, 0x5a37: 0xf000000b, + 0x5a38: 0xf000000b, 0x5a39: 0xf000000b, 0x5a3a: 0xf000000b, 0x5a3b: 0xf000000b, + 0x5a3c: 0xf000000b, 0x5a3d: 0xf000000b, 0x5a3e: 0xf000000b, 0x5a3f: 0xf000000b, + // Block 0x169, offset 0x5a40 + 0x5a40: 0xf000000b, 0x5a41: 0xf000000b, 0x5a42: 0xf000000b, 0x5a43: 0xf000000b, + 0x5a44: 0xf000000b, 0x5a45: 0xf000000b, 0x5a46: 0xf000000b, 0x5a47: 0xf000000b, + 0x5a48: 0xf000000b, 0x5a49: 0xf000000b, 0x5a4a: 0xf0000005, 0x5a4b: 0xf0000005, + 0x5a4c: 0xf0000005, 0x5a4d: 0xf0000005, 0x5a4e: 0xf0000005, 0x5a4f: 0xf0000005, + 0x5a50: 0xf0000005, 0x5a51: 0xf0000005, 0x5a52: 0xf0000005, 0x5a53: 0xf0000005, + 0x5a54: 0xf0000005, 0x5a55: 0xf0000005, 0x5a56: 0xf0000005, 0x5a57: 0xf0000005, + 0x5a58: 0xf0000005, 0x5a59: 0xf0000005, 0x5a5a: 0xf0000005, 0x5a5b: 0xf0000005, + 0x5a5c: 0xf0000005, 0x5a5d: 0xf0000005, 0x5a5e: 0xf0000005, 0x5a5f: 0xf0000005, + 0x5a60: 0xf0000005, 0x5a61: 0xf0000005, 0x5a62: 0xf0000005, 0x5a63: 0xf0000005, + 0x5a64: 0xf0000005, 0x5a65: 0xf0000005, + 0x5a68: 0xf000000b, 0x5a69: 0xf000000b, 0x5a6a: 0xf000000b, 0x5a6b: 0xf000000b, + 0x5a6c: 0xf000000b, 0x5a6d: 0xf000000b, 0x5a6e: 0xf000000b, 0x5a6f: 0xf000000b, + 0x5a70: 0xf000000b, 0x5a71: 0xf000000b, 0x5a72: 0xf000000b, 0x5a73: 0xf000000b, + 0x5a74: 0xf000000b, 0x5a75: 0xf000000b, 0x5a76: 0xf000000b, 0x5a77: 0xf000000b, + 0x5a78: 0xf000000b, 0x5a79: 0xf000000b, 0x5a7a: 0xf000000b, 0x5a7b: 0xf000000b, + 0x5a7c: 0xf000000b, 0x5a7d: 0xf000000b, 0x5a7e: 0xf000000b, 0x5a7f: 0xf000000b, + // Block 0x16a, offset 0x5a80 + 0x5a80: 0xf000000b, 0x5a81: 0xf0000005, 0x5a82: 0xf0000005, 0x5a83: 0xf0000005, + 0x5a84: 0xf0000005, 0x5a85: 0xf0000005, 0x5a86: 0xf0000005, 0x5a87: 0xf0000005, + 0x5a88: 0xf0000005, 0x5a89: 0xf0000005, 0x5a8a: 0xf0000005, 0x5a8b: 0xf0000005, + 0x5a8c: 0xf0000005, 0x5a8d: 0xf0000005, 0x5a8e: 0xf0000005, 0x5a8f: 0xf0000005, + 0x5a90: 0xf0000005, 0x5a91: 0xf0000005, 0x5a92: 0xf0000005, 0x5a93: 0xf0000005, + 0x5a94: 0xf0000005, 0x5a95: 0xf0000005, 0x5a96: 0xf0000005, 0x5a97: 0xf0000005, + 0x5a98: 0xf0000005, 0x5a99: 0xf0000005, 0x5a9a: 0xf0000005, 0x5a9b: 0xf0000005, + 0x5a9c: 0xf0000005, 0x5a9d: 0xf0000005, 0x5a9e: 0xf0000005, 0x5a9f: 0xf0000005, + 0x5aa0: 0xf0000005, 0x5aa1: 0xf0000005, 0x5aa2: 0xf000000b, 0x5aa3: 0xf000000b, + 0x5aa4: 0xf000000b, 0x5aa5: 0xf000000b, 0x5aa6: 0xf000000b, 0x5aa7: 0xf000000b, + 0x5aa8: 0xf000000b, 0x5aa9: 0xf000000b, 0x5aaa: 0xf000000b, 0x5aab: 0xf000000b, + 0x5aac: 0xf000000b, 0x5aad: 0xf000000b, 0x5aae: 0xf000000b, 0x5aaf: 0xf000000b, + 0x5ab0: 0xf000000b, 0x5ab1: 0xf000000b, 0x5ab2: 0xf000000b, 0x5ab3: 0xf000000b, + 0x5ab4: 0xf000000b, 0x5ab5: 0xf000000b, 0x5ab6: 0xf000000b, 0x5ab7: 0xf000000b, + 0x5ab8: 0xf000000b, 0x5ab9: 0xf000000b, 0x5aba: 0xf000000b, 0x5abb: 0xf0000005, + 0x5abc: 0xf0000005, 0x5abd: 0xf0000005, 0x5abe: 0xf0000005, 0x5abf: 0xf0000005, + // Block 0x16b, offset 0x5ac0 + 0x5ac0: 0xf0000005, 0x5ac1: 0xf0000005, 0x5ac2: 0xf0000005, 0x5ac3: 0xf0000005, + 0x5ac4: 0xf0000005, 0x5ac5: 0xf0000005, 0x5ac6: 0xf0000005, 0x5ac7: 0xf0000005, + 0x5ac8: 0xf0000005, 0x5ac9: 0xf0000005, 0x5aca: 0xf0000005, 0x5acb: 0xf0000005, + 0x5acc: 0xf0000005, 0x5acd: 0xf0000005, 0x5ace: 0xf0000005, 0x5acf: 0xf0000005, + 0x5ad0: 0xf0000005, 0x5ad1: 0xf0000005, 0x5ad2: 0xf0000005, 0x5ad3: 0xf0000005, + 0x5ad4: 0xf0000005, 0x5ad5: 0xf0000005, 0x5ad6: 0xf0000005, 0x5ad7: 0xf0000005, + 0x5ad8: 0xf0000005, 0x5ad9: 0xf0000005, 0x5ada: 0xf0000005, 0x5adb: 0xf0000005, + 0x5adc: 0xf000000b, 0x5add: 0xf000000b, 0x5ade: 0xf000000b, 0x5adf: 0xf000000b, + 0x5ae0: 0xf000000b, 0x5ae1: 0xf000000b, 0x5ae2: 0xf000000b, 0x5ae3: 0xf000000b, + 0x5ae4: 0xf000000b, 0x5ae5: 0xf000000b, 0x5ae6: 0xf000000b, 0x5ae7: 0xf000000b, + 0x5ae8: 0xf000000b, 0x5ae9: 0xf000000b, 0x5aea: 0xf000000b, 0x5aeb: 0xf000000b, + 0x5aec: 0xf000000b, 0x5aed: 0xf000000b, 0x5aee: 0xf000000b, 0x5aef: 0xf000000b, + 0x5af0: 0xf000000b, 0x5af1: 0xf000000b, 0x5af2: 0xf000000b, 0x5af3: 0xf000000b, + 0x5af4: 0xf000000b, 0x5af5: 0xf0000005, 0x5af6: 0xf0000005, 0x5af7: 0xf0000005, + 0x5af8: 0xf0000005, 0x5af9: 0xf0000005, 0x5afa: 0xf0000005, 0x5afb: 0xf0000005, + 0x5afc: 0xf0000005, 0x5afd: 0xf0000005, 0x5afe: 0xf0000005, 0x5aff: 0xf0000005, + // Block 0x16c, offset 0x5b00 + 0x5b00: 0xf0000005, 0x5b01: 0xf0000005, 0x5b02: 0xf0000005, 0x5b03: 0xf0000005, + 0x5b04: 0xf0000005, 0x5b05: 0xf0000005, 0x5b06: 0xf0000005, 0x5b07: 0xf0000005, + 0x5b08: 0xf0000005, 0x5b09: 0xf0000005, 0x5b0a: 0xf0000005, 0x5b0b: 0xf0000005, + 0x5b0c: 0xf0000005, 0x5b0d: 0xf0000005, 0x5b0e: 0xf0000005, 0x5b0f: 0xf0000005, + 0x5b10: 0xf0000005, 0x5b11: 0xf0000005, 0x5b12: 0xf0000005, 0x5b13: 0xf0000005, + 0x5b14: 0xf0000005, 0x5b15: 0xf0000005, 0x5b16: 0xf000000b, 0x5b17: 0xf000000b, + 0x5b18: 0xf000000b, 0x5b19: 0xf000000b, 0x5b1a: 0xf000000b, 0x5b1b: 0xf000000b, + 0x5b1c: 0xf000000b, 0x5b1d: 0xf000000b, 0x5b1e: 0xf000000b, 0x5b1f: 0xf000000b, + 0x5b20: 0xf000000b, 0x5b21: 0xf000000b, 0x5b22: 0xf000000b, 0x5b23: 0xf000000b, + 0x5b24: 0xf000000b, 0x5b25: 0xf000000b, 0x5b26: 0xf000000b, 0x5b27: 0xf000000b, + 0x5b28: 0xf000000b, 0x5b29: 0xf000000b, 0x5b2a: 0xf000000b, 0x5b2b: 0xf000000b, + 0x5b2c: 0xf000000b, 0x5b2d: 0xf000000b, 0x5b2e: 0xf000000b, 0x5b2f: 0xf0000005, + 0x5b30: 0xf0000005, 0x5b31: 0xf0000005, 0x5b32: 0xf0000005, 0x5b33: 0xf0000005, + 0x5b34: 0xf0000005, 0x5b35: 0xf0000005, 0x5b36: 0xf0000005, 0x5b37: 0xf0000005, + 0x5b38: 0xf0000005, 0x5b39: 0xf0000005, 0x5b3a: 0xf0000005, 0x5b3b: 0xf0000005, + 0x5b3c: 0xf0000005, 0x5b3d: 0xf0000005, 0x5b3e: 0xf0000005, 0x5b3f: 0xf0000005, + // Block 0x16d, offset 0x5b40 + 0x5b40: 0xf0000005, 0x5b41: 0xf0000005, 0x5b42: 0xf0000005, 0x5b43: 0xf0000005, + 0x5b44: 0xf0000005, 0x5b45: 0xf0000005, 0x5b46: 0xf0000005, 0x5b47: 0xf0000005, + 0x5b48: 0xf0000005, 0x5b49: 0xf0000005, 0x5b4a: 0xf0000005, 0x5b4b: 0xf0000005, + 0x5b4c: 0xf0000005, 0x5b4d: 0xf0000005, 0x5b4e: 0xf0000005, 0x5b4f: 0xf0000005, + 0x5b50: 0xf000000b, 0x5b51: 0xf000000b, 0x5b52: 0xf000000b, 0x5b53: 0xf000000b, + 0x5b54: 0xf000000b, 0x5b55: 0xf000000b, 0x5b56: 0xf000000b, 0x5b57: 0xf000000b, + 0x5b58: 0xf000000b, 0x5b59: 0xf000000b, 0x5b5a: 0xf000000b, 0x5b5b: 0xf000000b, + 0x5b5c: 0xf000000b, 0x5b5d: 0xf000000b, 0x5b5e: 0xf000000b, 0x5b5f: 0xf000000b, + 0x5b60: 0xf000000b, 0x5b61: 0xf000000b, 0x5b62: 0xf000000b, 0x5b63: 0xf000000b, + 0x5b64: 0xf000000b, 0x5b65: 0xf000000b, 0x5b66: 0xf000000b, 0x5b67: 0xf000000b, + 0x5b68: 0xf000000b, 0x5b69: 0xf0000005, 0x5b6a: 0xf0000005, 0x5b6b: 0xf0000005, + 0x5b6c: 0xf0000005, 0x5b6d: 0xf0000005, 0x5b6e: 0xf0000005, 0x5b6f: 0xf0000005, + 0x5b70: 0xf0000005, 0x5b71: 0xf0000005, 0x5b72: 0xf0000005, 0x5b73: 0xf0000005, + 0x5b74: 0xf0000005, 0x5b75: 0xf0000005, 0x5b76: 0xf0000005, 0x5b77: 0xf0000005, + 0x5b78: 0xf0000005, 0x5b79: 0xf0000005, 0x5b7a: 0xf0000005, 0x5b7b: 0xf0000005, + 0x5b7c: 0xf0000005, 0x5b7d: 0xf0000005, 0x5b7e: 0xf0000005, 0x5b7f: 0xf0000005, + // Block 0x16e, offset 0x5b80 + 0x5b80: 0xf0000005, 0x5b81: 0xf0000005, 0x5b82: 0xf0000005, 0x5b83: 0xf0000005, + 0x5b84: 0xf0000005, 0x5b85: 0xf0000005, 0x5b86: 0xf0000005, 0x5b87: 0xf0000005, + 0x5b88: 0xf0000005, 0x5b89: 0xf0000005, 0x5b8a: 0xf000000b, 0x5b8b: 0xf0000005, + 0x5b8e: 0xf0000005, 0x5b8f: 0xf0000005, + 0x5b90: 0xf0000005, 0x5b91: 0xf0000005, 0x5b92: 0xf0000005, 0x5b93: 0xf0000005, + 0x5b94: 0xf0000005, 0x5b95: 0xf0000005, 0x5b96: 0xf0000005, 0x5b97: 0xf0000005, + 0x5b98: 0xf0000005, 0x5b99: 0xf0000005, 0x5b9a: 0xf0000005, 0x5b9b: 0xf0000005, + 0x5b9c: 0xf0000005, 0x5b9d: 0xf0000005, 0x5b9e: 0xf0000005, 0x5b9f: 0xf0000005, + 0x5ba0: 0xf0000005, 0x5ba1: 0xf0000005, 0x5ba2: 0xf0000005, 0x5ba3: 0xf0000005, + 0x5ba4: 0xf0000005, 0x5ba5: 0xf0000005, 0x5ba6: 0xf0000005, 0x5ba7: 0xf0000005, + 0x5ba8: 0xf0000005, 0x5ba9: 0xf0000005, 0x5baa: 0xf0000005, 0x5bab: 0xf0000005, + 0x5bac: 0xf0000005, 0x5bad: 0xf0000005, 0x5bae: 0xf0000005, 0x5baf: 0xf0000005, + 0x5bb0: 0xf0000005, 0x5bb1: 0xf0000005, 0x5bb2: 0xf0000005, 0x5bb3: 0xf0000005, + 0x5bb4: 0xf0000005, 0x5bb5: 0xf0000005, 0x5bb6: 0xf0000005, 0x5bb7: 0xf0000005, + 0x5bb8: 0xf0000005, 0x5bb9: 0xf0000005, 0x5bba: 0xf0000005, 0x5bbb: 0xf0000005, + 0x5bbc: 0xf0000005, 0x5bbd: 0xf0000005, 0x5bbe: 0xf0000005, 0x5bbf: 0xf0000005, + // Block 0x16f, offset 0x5bc0 + 0x5bc0: 0x400f8120, 0x5bc1: 0x400f8220, 0x5bc2: 0x400f8320, 0x5bc3: 0x400f8420, + 0x5bc4: 0x400f8520, 0x5bc5: 0x400f8620, 0x5bc6: 0x400f8720, 0x5bc7: 0x400f8820, + 0x5bc8: 0x400f8920, 0x5bc9: 0x400f8a20, 0x5bca: 0x400f8b20, 0x5bcb: 0x400f8c20, + 0x5bcc: 0x400f8d20, 0x5bcd: 0x400f8e20, 0x5bce: 0x400f8f20, 0x5bcf: 0x400f9020, + 0x5bd0: 0x400f9120, 0x5bd1: 0x400f9220, 0x5bd2: 0x400f9320, 0x5bd3: 0x400f9420, + 0x5bd4: 0x400f9520, 0x5bd5: 0x400f9620, 0x5bd6: 0x400f9720, 0x5bd7: 0x400f9820, + 0x5bd8: 0x400f9920, 0x5bd9: 0x400f9a20, 0x5bda: 0x400f9b20, 0x5bdb: 0x400f9c20, + 0x5bdc: 0x400f9d20, 0x5bdd: 0x400f9e20, 0x5bde: 0x400f9f20, 0x5bdf: 0x400fa020, + 0x5be0: 0x400fa120, 0x5be1: 0x400fa220, 0x5be2: 0x400fa320, 0x5be3: 0x400fa420, + 0x5be4: 0x400fa520, 0x5be5: 0x400fa620, 0x5be6: 0x400fa720, 0x5be7: 0x400fa820, + 0x5be8: 0x400fa920, 0x5be9: 0x400faa20, 0x5bea: 0x400fab20, 0x5beb: 0x400fac20, + 0x5bf0: 0x400fad20, 0x5bf1: 0x400fae20, 0x5bf2: 0x400faf20, 0x5bf3: 0x400fb020, + 0x5bf4: 0x400fb120, 0x5bf5: 0x400fb220, 0x5bf6: 0x400fb320, 0x5bf7: 0x400fb420, + 0x5bf8: 0x400fb520, 0x5bf9: 0x400fb620, 0x5bfa: 0x400fb720, 0x5bfb: 0x400fb820, + 0x5bfc: 0x400fb920, 0x5bfd: 0x400fba20, 0x5bfe: 0x400fbb20, 0x5bff: 0x400fbc20, + // Block 0x170, offset 0x5c00 + 0x5c00: 0x400fbd20, 0x5c01: 0x400fbe20, 0x5c02: 0x400fbf20, 0x5c03: 0x400fc020, + 0x5c04: 0x400fc120, 0x5c05: 0x400fc220, 0x5c06: 0x400fc320, 0x5c07: 0x400fc420, + 0x5c08: 0x400fc520, 0x5c09: 0x400fc620, 0x5c0a: 0x400fc720, 0x5c0b: 0x400fc820, + 0x5c0c: 0x400fc920, 0x5c0d: 0x400fca20, 0x5c0e: 0x400fcb20, 0x5c0f: 0x400fcc20, + 0x5c10: 0x400fcd20, 0x5c11: 0x400fce20, 0x5c12: 0x400fcf20, 0x5c13: 0x400fd020, + 0x5c14: 0x400fd120, 0x5c15: 0x400fd220, 0x5c16: 0x400fd320, 0x5c17: 0x400fd420, + 0x5c18: 0x400fd520, 0x5c19: 0x400fd620, 0x5c1a: 0x400fd720, 0x5c1b: 0x400fd820, + 0x5c1c: 0x400fd920, 0x5c1d: 0x400fda20, 0x5c1e: 0x400fdb20, 0x5c1f: 0x400fdc20, + 0x5c20: 0x400fdd20, 0x5c21: 0x400fde20, 0x5c22: 0x400fdf20, 0x5c23: 0x400fe020, + 0x5c24: 0x400fe120, 0x5c25: 0x400fe220, 0x5c26: 0x400fe320, 0x5c27: 0x400fe420, + 0x5c28: 0x400fe520, 0x5c29: 0x400fe620, 0x5c2a: 0x400fe720, 0x5c2b: 0x400fe820, + 0x5c2c: 0x400fe920, 0x5c2d: 0x400fea20, 0x5c2e: 0x400feb20, 0x5c2f: 0x400fec20, + 0x5c30: 0x400fed20, 0x5c31: 0x400fee20, 0x5c32: 0x400fef20, 0x5c33: 0x400ff020, + 0x5c34: 0x400ff120, 0x5c35: 0x400ff220, 0x5c36: 0x400ff320, 0x5c37: 0x400ff420, + 0x5c38: 0x400ff520, 0x5c39: 0x400ff620, 0x5c3a: 0x400ff720, 0x5c3b: 0x400ff820, + 0x5c3c: 0x400ff920, 0x5c3d: 0x400ffa20, 0x5c3e: 0x400ffb20, 0x5c3f: 0x400ffc20, + // Block 0x171, offset 0x5c40 + 0x5c40: 0x400ffd20, 0x5c41: 0x400ffe20, 0x5c42: 0x400fff20, 0x5c43: 0x40100020, + 0x5c44: 0x40100120, 0x5c45: 0x40100220, 0x5c46: 0x40100320, 0x5c47: 0x40100420, + 0x5c48: 0x40100520, 0x5c49: 0x40100620, 0x5c4a: 0x40100720, 0x5c4b: 0x40100820, + 0x5c4c: 0x40100920, 0x5c4d: 0x40100a20, 0x5c4e: 0x40100b20, 0x5c4f: 0x40100c20, + 0x5c50: 0x40100d20, 0x5c51: 0x40100e20, 0x5c52: 0x40100f20, 0x5c53: 0x40101020, + 0x5c60: 0x40101120, 0x5c61: 0x40101220, 0x5c62: 0x40101320, 0x5c63: 0x40101420, + 0x5c64: 0x40101520, 0x5c65: 0x40101620, 0x5c66: 0x40101720, 0x5c67: 0x40101820, + 0x5c68: 0x40101920, 0x5c69: 0x40101a20, 0x5c6a: 0x40101b20, 0x5c6b: 0x40101c20, + 0x5c6c: 0x40101d20, 0x5c6d: 0x40101e20, 0x5c6e: 0x40101f20, + 0x5c71: 0x40102020, 0x5c72: 0x40102120, 0x5c73: 0x40102220, + 0x5c74: 0x40102320, 0x5c75: 0x40102420, 0x5c76: 0x40102520, 0x5c77: 0x40102620, + 0x5c78: 0x40102720, 0x5c79: 0x40102820, 0x5c7a: 0x40102920, 0x5c7b: 0x40102a20, + 0x5c7c: 0x40102b20, 0x5c7d: 0x40102c20, 0x5c7e: 0x40102d20, + // Block 0x172, offset 0x5c80 + 0x5c81: 0x40102e20, 0x5c82: 0x40102f20, 0x5c83: 0x40103020, + 0x5c84: 0x40103120, 0x5c85: 0x40103220, 0x5c86: 0x40103320, 0x5c87: 0x40103420, + 0x5c88: 0x40103520, 0x5c89: 0x40103620, 0x5c8a: 0x40103720, 0x5c8b: 0x40103820, + 0x5c8c: 0x40103920, 0x5c8d: 0x40103a20, 0x5c8e: 0x40103b20, 0x5c8f: 0x40103c20, + 0x5c91: 0x40103d20, 0x5c92: 0x40103e20, 0x5c93: 0x40103f20, + 0x5c94: 0x40104020, 0x5c95: 0x40104120, 0x5c96: 0x40104220, 0x5c97: 0x40104320, + 0x5c98: 0x40104420, 0x5c99: 0x40104520, 0x5c9a: 0x40104620, 0x5c9b: 0x40104720, + 0x5c9c: 0x40104820, 0x5c9d: 0x40104920, 0x5c9e: 0x40104a20, 0x5c9f: 0x40104b20, + // Block 0x173, offset 0x5cc0 + 0x5cc0: 0xf0000404, 0x5cc1: 0xf0000404, 0x5cc2: 0xf0000404, 0x5cc3: 0xf0000404, + 0x5cc4: 0xf0000404, 0x5cc5: 0xf0000404, 0x5cc6: 0xf0000404, 0x5cc7: 0xf0000404, + 0x5cc8: 0xf0000404, 0x5cc9: 0xf0000404, 0x5cca: 0xf0000404, + 0x5cd0: 0xf0000a04, 0x5cd1: 0xf0000a04, 0x5cd2: 0xf0000a04, 0x5cd3: 0xf0000a04, + 0x5cd4: 0xf0000a04, 0x5cd5: 0xf0000a04, 0x5cd6: 0xf0000a04, 0x5cd7: 0xf0000a04, + 0x5cd8: 0xf0000a04, 0x5cd9: 0xf0000a04, 0x5cda: 0xf0000a04, 0x5cdb: 0xf0000a04, + 0x5cdc: 0xf0000a04, 0x5cdd: 0xf0000a04, 0x5cde: 0xf0000a04, 0x5cdf: 0xf0000a04, + 0x5ce0: 0xf0000a04, 0x5ce1: 0xf0000a04, 0x5ce2: 0xf0000a04, 0x5ce3: 0xf0000a04, + 0x5ce4: 0xf0000a04, 0x5ce5: 0xf0000a04, 0x5ce6: 0xf0000a04, 0x5ce7: 0xf0000a04, + 0x5ce8: 0xf0000a04, 0x5ce9: 0xf0000a04, 0x5cea: 0xf0000a04, 0x5ceb: 0xf000000c, + 0x5cec: 0xf000000c, 0x5ced: 0xf0000c0c, 0x5cee: 0xf0000c0c, + 0x5cf0: 0xf000001d, 0x5cf1: 0xf000001d, 0x5cf2: 0xf000001d, 0x5cf3: 0xf000001d, + 0x5cf4: 0xf000001d, 0x5cf5: 0xf000001d, 0x5cf6: 0xf000001d, 0x5cf7: 0xf000001d, + 0x5cf8: 0xf000001d, 0x5cf9: 0xf000001d, 0x5cfa: 0xf000001d, 0x5cfb: 0xf000001d, + 0x5cfc: 0xf000001d, 0x5cfd: 0xf000001d, 0x5cfe: 0xf000001d, 0x5cff: 0xf000001d, + // Block 0x174, offset 0x5d00 + 0x5d00: 0xf000001d, 0x5d01: 0xf000001d, 0x5d02: 0xf000001d, 0x5d03: 0xf000001d, + 0x5d04: 0xf000001d, 0x5d05: 0xf000001d, 0x5d06: 0xf000001d, 0x5d07: 0xf000001d, + 0x5d08: 0xf000001d, 0x5d09: 0xf000001d, 0x5d0a: 0xf0001d1d, 0x5d0b: 0xf0001d1d, + 0x5d0c: 0xf0001d1d, 0x5d0d: 0xf0001d1d, 0x5d0e: 0xf0001d1d, 0x5d0f: 0xf0001d1d, + 0x5d10: 0x002b460c, 0x5d11: 0x002b720c, 0x5d12: 0x002ba20c, 0x5d13: 0x002bc80c, + 0x5d14: 0x002bfe0c, 0x5d15: 0x002c6e0c, 0x5d16: 0x002c880c, 0x5d17: 0x002cce0c, + 0x5d18: 0x002d000c, 0x5d19: 0x002d320c, 0x5d1a: 0x002d640c, 0x5d1b: 0x002d880c, + 0x5d1c: 0x002de80c, 0x5d1d: 0x002e040c, 0x5d1e: 0x002e480c, 0x5d1f: 0x002e920c, + 0x5d20: 0x002ebc0c, 0x5d21: 0x002ee00c, 0x5d22: 0x002f4c0c, 0x5d23: 0x002f920c, + 0x5d24: 0x002fd20c, 0x5d25: 0x0030240c, 0x5d26: 0x0030480c, 0x5d27: 0x00305c0c, + 0x5d28: 0x0030660c, 0x5d29: 0x0030880c, + 0x5d30: 0x002b461d, 0x5d31: 0x002b721d, 0x5d32: 0x002ba21d, 0x5d33: 0x002bc81d, + 0x5d34: 0x002bfe1d, 0x5d35: 0x002c6e1d, 0x5d36: 0x002c881d, 0x5d37: 0x002cce1d, + 0x5d38: 0x002d001d, 0x5d39: 0x002d321d, 0x5d3a: 0x002d641d, 0x5d3b: 0x002d881d, + 0x5d3c: 0x002de81d, 0x5d3d: 0x002e041d, 0x5d3e: 0x002e481d, 0x5d3f: 0x002e921d, + // Block 0x175, offset 0x5d40 + 0x5d40: 0x002ebc1d, 0x5d41: 0x002ee01d, 0x5d42: 0x002f4c1d, 0x5d43: 0x002f921d, + 0x5d44: 0x002fd21d, 0x5d45: 0x0030241d, 0x5d46: 0x0030481d, 0x5d47: 0x00305c1d, + 0x5d48: 0x0030661d, 0x5d49: 0x0030881d, 0x5d4a: 0x002e921d, 0x5d4b: 0xe0000777, + 0x5d4c: 0xe00007c5, 0x5d4d: 0xe00007e9, 0x5d4e: 0xe00006f3, 0x5d4f: 0xe0000825, + 0x5d50: 0xf0001d1d, 0x5d51: 0xe000072b, 0x5d52: 0xe000072e, 0x5d53: 0xe0000760, + 0x5d54: 0xe000077a, 0x5d55: 0xe00007a7, 0x5d56: 0xe00007ab, 0x5d57: 0xe00007bc, + 0x5d58: 0xe00007ec, 0x5d59: 0xe0000818, 0x5d5a: 0xe000081c, + // Block 0x176, offset 0x5d80 + 0x5da6: 0x002b460a, 0x5da7: 0x002b720a, + 0x5da8: 0x002ba20a, 0x5da9: 0x002bc80a, 0x5daa: 0x002bfe0a, 0x5dab: 0x002c6e0a, + 0x5dac: 0x002c880a, 0x5dad: 0x002cce0a, 0x5dae: 0x002d000a, 0x5daf: 0x002d320a, + 0x5db0: 0x002d640a, 0x5db1: 0x002d880a, 0x5db2: 0x002de80a, 0x5db3: 0x002e040a, + 0x5db4: 0x002e480a, 0x5db5: 0x002e920a, 0x5db6: 0x002ebc0a, 0x5db7: 0x002ee00a, + 0x5db8: 0x002f4c0a, 0x5db9: 0x002f920a, 0x5dba: 0x002fd20a, 0x5dbb: 0x0030240a, + 0x5dbc: 0x0030480a, 0x5dbd: 0x00305c0a, 0x5dbe: 0x0030660a, 0x5dbf: 0x0030880a, + // Block 0x177, offset 0x5dc0 + 0x5dc0: 0xf0001c1c, 0x5dc1: 0xf0001c1c, 0x5dc2: 0xf000001c, + 0x5dd0: 0xf000001c, 0x5dd1: 0xf000001c, 0x5dd2: 0xf000001c, 0x5dd3: 0xf0001c1c, + 0x5dd4: 0xf000001c, 0x5dd5: 0xf000001c, 0x5dd6: 0xf000001c, 0x5dd7: 0xf000001c, + 0x5dd8: 0xf000001c, 0x5dd9: 0xf000001c, 0x5dda: 0xf000001c, 0x5ddb: 0xf000001c, + 0x5ddc: 0xf000001c, 0x5ddd: 0xf000001c, 0x5dde: 0xf000001c, 0x5ddf: 0xf000001c, + 0x5de0: 0xf000001c, 0x5de1: 0xf000001c, 0x5de2: 0xf000001c, 0x5de3: 0xf000001c, + 0x5de4: 0xf000001c, 0x5de5: 0xf000001c, 0x5de6: 0xf000001c, 0x5de7: 0xf000001c, + 0x5de8: 0xf000001c, 0x5de9: 0xf000001c, 0x5dea: 0xf000001c, 0x5deb: 0xf000001c, + 0x5dec: 0xf000001c, 0x5ded: 0xf000001c, 0x5dee: 0xf000001c, 0x5def: 0xf000001c, + 0x5df0: 0xf000001c, 0x5df1: 0xf000001c, 0x5df2: 0xf000001c, 0x5df3: 0xf000001c, + 0x5df4: 0xf000001c, 0x5df5: 0xf000001c, 0x5df6: 0xf000001c, 0x5df7: 0xf000001c, + 0x5df8: 0xf000001c, 0x5df9: 0xf000001c, 0x5dfa: 0xf000001c, + // Block 0x178, offset 0x5e00 + 0x5e00: 0xf0000404, 0x5e01: 0xf0000404, 0x5e02: 0xf0000404, 0x5e03: 0xf0000404, + 0x5e04: 0xf0000404, 0x5e05: 0xf0000404, 0x5e06: 0xf0000404, 0x5e07: 0xf0000404, + 0x5e08: 0xf0000404, + 0x5e10: 0xf0000006, 0x5e11: 0xf0000006, + // Block 0x179, offset 0x5e40 + 0x5e40: 0x40104c20, 0x5e41: 0x40104d20, 0x5e42: 0x40104e20, 0x5e43: 0x40104f20, + 0x5e44: 0x40105020, 0x5e45: 0x40105120, 0x5e46: 0x40105220, 0x5e47: 0x40105320, + 0x5e48: 0x40105420, 0x5e49: 0x40105520, 0x5e4a: 0x40105620, 0x5e4b: 0x40105720, + 0x5e4c: 0x40105820, 0x5e4d: 0x40105920, 0x5e4e: 0x40105a20, 0x5e4f: 0x40105b20, + 0x5e50: 0x40105c20, 0x5e51: 0x40105d20, 0x5e52: 0x40105e20, 0x5e53: 0x40105f20, + 0x5e54: 0x40106020, 0x5e55: 0x40106120, 0x5e56: 0x40106220, 0x5e57: 0x40106320, + 0x5e58: 0x40106420, 0x5e59: 0x40106520, 0x5e5a: 0x40106620, 0x5e5b: 0x40106720, + 0x5e5c: 0x40106820, 0x5e5d: 0x40106920, 0x5e5e: 0x40106a20, 0x5e5f: 0x40106b20, + 0x5e60: 0x40106c20, + 0x5e70: 0x40106d20, 0x5e71: 0x40106e20, 0x5e72: 0x40106f20, 0x5e73: 0x40107020, + 0x5e74: 0x40107120, 0x5e75: 0x40107220, 0x5e77: 0x40107320, + 0x5e78: 0x40107420, 0x5e79: 0x40107520, 0x5e7a: 0x40107620, 0x5e7b: 0x40107720, + 0x5e7c: 0x40107820, 0x5e7d: 0x40107920, 0x5e7e: 0x40107a20, 0x5e7f: 0x40107b20, + // Block 0x17a, offset 0x5e80 + 0x5e80: 0x40107c20, 0x5e81: 0x40107d20, 0x5e82: 0x40107e20, 0x5e83: 0x40107f20, + 0x5e84: 0x40108020, 0x5e85: 0x40108120, 0x5e86: 0x40108220, 0x5e87: 0x40108320, + 0x5e88: 0x40108420, 0x5e89: 0x40108520, 0x5e8a: 0x40108620, 0x5e8b: 0x40108720, + 0x5e8c: 0x40108820, 0x5e8d: 0x40108920, 0x5e8e: 0x40108a20, 0x5e8f: 0x40108b20, + 0x5e90: 0x40108c20, 0x5e91: 0x40108d20, 0x5e92: 0x40108e20, 0x5e93: 0x40108f20, + 0x5e94: 0x40109020, 0x5e95: 0x40109120, 0x5e96: 0x40109220, 0x5e97: 0x40109320, + 0x5e98: 0x40109420, 0x5e99: 0x40109520, 0x5e9a: 0x40109620, 0x5e9b: 0x40109720, + 0x5e9c: 0x40109820, 0x5e9d: 0x40109920, 0x5e9e: 0x40109a20, 0x5e9f: 0x40109b20, + 0x5ea0: 0x40109c20, 0x5ea1: 0x40109d20, 0x5ea2: 0x40109e20, 0x5ea3: 0x40109f20, + 0x5ea4: 0x4010a020, 0x5ea5: 0x4010a120, 0x5ea6: 0x4010a220, 0x5ea7: 0x4010a320, + 0x5ea8: 0x4010a420, 0x5ea9: 0x4010a520, 0x5eaa: 0x4010a620, 0x5eab: 0x4010a720, + 0x5eac: 0x4010a820, 0x5ead: 0x4010a920, 0x5eae: 0x4010aa20, 0x5eaf: 0x4010ab20, + 0x5eb0: 0x4010ac20, 0x5eb1: 0x4010ad20, 0x5eb2: 0x4010ae20, 0x5eb3: 0x4010af20, + 0x5eb4: 0x4010b020, 0x5eb5: 0x4010b120, 0x5eb6: 0x4010b220, 0x5eb7: 0x4010b320, + 0x5eb8: 0x4010b420, 0x5eb9: 0x4010b520, 0x5eba: 0x4010b620, 0x5ebb: 0x4010b720, + 0x5ebc: 0x4010b820, + // Block 0x17b, offset 0x5ec0 + 0x5ec0: 0x4010b920, 0x5ec1: 0x4010ba20, 0x5ec2: 0x4010bb20, 0x5ec3: 0x4010bc20, + 0x5ec4: 0x4010bd20, 0x5ec5: 0x4010be20, 0x5ec6: 0x4010bf20, 0x5ec7: 0x4010c020, + 0x5ec8: 0x4010c120, 0x5ec9: 0x4010c220, 0x5eca: 0x4010c320, 0x5ecb: 0x4010c420, + 0x5ecc: 0x4010c520, 0x5ecd: 0x4010c620, 0x5ece: 0x4010c720, 0x5ecf: 0x4010c820, + 0x5ed0: 0x4010c920, 0x5ed1: 0x4010ca20, 0x5ed2: 0x4010cb20, 0x5ed3: 0x4010cc20, + 0x5ee0: 0x4010cd20, 0x5ee1: 0x4010ce20, 0x5ee2: 0x4010cf20, 0x5ee3: 0x4010d020, + 0x5ee4: 0x4010d120, 0x5ee5: 0x4010d220, 0x5ee6: 0x4010d320, 0x5ee7: 0x4010d420, + 0x5ee8: 0x4010d520, 0x5ee9: 0x4010d620, 0x5eea: 0x4010d720, 0x5eeb: 0x4010d820, + 0x5eec: 0x4010d920, 0x5eed: 0x4010da20, 0x5eee: 0x4010db20, 0x5eef: 0x4010dc20, + 0x5ef0: 0x4010dd20, 0x5ef1: 0x4010de20, 0x5ef2: 0x4010df20, 0x5ef3: 0x4010e020, + 0x5ef4: 0x4010e120, 0x5ef5: 0x4010e220, 0x5ef6: 0x4010e320, 0x5ef7: 0x4010e420, + 0x5ef8: 0x4010e520, 0x5ef9: 0x4010e620, 0x5efa: 0x4010e720, 0x5efb: 0x4010e820, + 0x5efc: 0x4010e920, 0x5efd: 0x4010ea20, 0x5efe: 0x4010eb20, 0x5eff: 0x4010ec20, + // Block 0x17c, offset 0x5f00 + 0x5f00: 0x4010ed20, 0x5f01: 0x4010ee20, 0x5f02: 0x4010ef20, 0x5f03: 0x4010f020, + 0x5f04: 0x4010f120, 0x5f06: 0x4010f220, 0x5f07: 0x4010f320, + 0x5f08: 0x4010f420, 0x5f09: 0x4010f520, 0x5f0a: 0x4010f620, + 0x5f20: 0x4010f720, 0x5f21: 0x4010f820, 0x5f22: 0x4010f920, 0x5f23: 0x4010fa20, + 0x5f24: 0x4010fb20, 0x5f25: 0x4010fc20, 0x5f26: 0x4010fd20, 0x5f27: 0x4010fe20, + 0x5f28: 0x4010ff20, 0x5f29: 0x40110020, 0x5f2a: 0x40110120, 0x5f2b: 0x40110220, + 0x5f2c: 0x40110320, 0x5f2d: 0x40110420, 0x5f2e: 0x40110520, 0x5f2f: 0x40110620, + 0x5f30: 0x40110720, + // Block 0x17d, offset 0x5f40 + 0x5f40: 0x40110820, 0x5f41: 0x40110920, 0x5f42: 0x40110a20, 0x5f43: 0x40110b20, + 0x5f44: 0x40110c20, 0x5f45: 0x40110d20, 0x5f46: 0x40110e20, 0x5f47: 0x40110f20, + 0x5f48: 0x40111020, 0x5f49: 0x40111120, 0x5f4a: 0x40111220, 0x5f4b: 0x40111320, + 0x5f4c: 0x40111420, 0x5f4d: 0x40111520, 0x5f4e: 0x40111620, 0x5f4f: 0x40111720, + 0x5f50: 0x40111820, 0x5f51: 0x40111920, 0x5f52: 0x40111a20, 0x5f53: 0x40111b20, + 0x5f54: 0x40111c20, 0x5f55: 0x40111d20, 0x5f56: 0x40111e20, 0x5f57: 0x40111f20, + 0x5f58: 0x40112020, 0x5f59: 0x40112120, 0x5f5a: 0x40112220, 0x5f5b: 0x40112320, + 0x5f5c: 0x40112420, 0x5f5d: 0x40112520, 0x5f5e: 0x40112620, 0x5f5f: 0x40112720, + 0x5f60: 0x40112820, 0x5f61: 0x40112920, 0x5f62: 0x40112a20, 0x5f63: 0x40112b20, + 0x5f64: 0x40112c20, 0x5f65: 0x40112d20, 0x5f66: 0x40112e20, 0x5f67: 0x40112f20, + 0x5f68: 0x40113020, 0x5f69: 0x40113120, 0x5f6a: 0x40113220, 0x5f6b: 0x40113320, + 0x5f6c: 0x40113420, 0x5f6d: 0x40113520, 0x5f6e: 0x40113620, 0x5f6f: 0x40113720, + 0x5f70: 0x40113820, 0x5f71: 0x40113920, 0x5f72: 0x40113a20, 0x5f73: 0x40113b20, + 0x5f74: 0x40113c20, 0x5f75: 0x40113d20, 0x5f76: 0x40113e20, 0x5f77: 0x40113f20, + 0x5f78: 0x40114020, 0x5f79: 0x40114120, 0x5f7a: 0x40114220, 0x5f7b: 0x40114320, + 0x5f7c: 0x40114420, 0x5f7d: 0x40114520, 0x5f7e: 0x40114620, + // Block 0x17e, offset 0x5f80 + 0x5f80: 0x40114720, 0x5f82: 0x40114820, 0x5f83: 0x40114920, + 0x5f84: 0x40114a20, 0x5f85: 0x40114b20, 0x5f86: 0x40114c20, 0x5f87: 0x40114d20, + 0x5f88: 0x40114e20, 0x5f89: 0x40114f20, 0x5f8a: 0x40115020, 0x5f8b: 0x40115120, + 0x5f8c: 0x40115220, 0x5f8d: 0x40115320, 0x5f8e: 0x40115420, 0x5f8f: 0x40115520, + 0x5f90: 0x40115620, 0x5f91: 0x40115720, 0x5f92: 0x40115820, 0x5f93: 0x40115920, + 0x5f94: 0x40115a20, 0x5f95: 0x40115b20, 0x5f96: 0x40115c20, 0x5f97: 0x40115d20, + 0x5f98: 0x40115e20, 0x5f99: 0x40115f20, 0x5f9a: 0x40116020, 0x5f9b: 0x40116120, + 0x5f9c: 0x40116220, 0x5f9d: 0x40116320, 0x5f9e: 0x40116420, 0x5f9f: 0x40116520, + 0x5fa0: 0x40116620, 0x5fa1: 0x40116720, 0x5fa2: 0x40116820, 0x5fa3: 0x40116920, + 0x5fa4: 0x40116a20, 0x5fa5: 0x40116b20, 0x5fa6: 0x40116c20, 0x5fa7: 0x40116d20, + 0x5fa8: 0x40116e20, 0x5fa9: 0x40116f20, 0x5faa: 0x40117020, 0x5fab: 0x40117120, + 0x5fac: 0x40117220, 0x5fad: 0x40117320, 0x5fae: 0x40117420, 0x5faf: 0x40117520, + 0x5fb0: 0x40117620, 0x5fb1: 0x40117720, 0x5fb2: 0x40117820, 0x5fb3: 0x40117920, + 0x5fb4: 0x40117a20, 0x5fb5: 0x40117b20, 0x5fb6: 0x40117c20, 0x5fb7: 0x40117d20, + 0x5fb8: 0x40117e20, 0x5fb9: 0x40117f20, 0x5fba: 0x40118020, 0x5fbb: 0x40118120, + 0x5fbc: 0x40118220, 0x5fbd: 0x40118320, 0x5fbe: 0x40118420, 0x5fbf: 0x40118520, + // Block 0x17f, offset 0x5fc0 + 0x5fc0: 0x40118620, 0x5fc1: 0x40118720, 0x5fc2: 0x40118820, 0x5fc3: 0x40118920, + 0x5fc4: 0x40118a20, 0x5fc5: 0x40118b20, 0x5fc6: 0x40118c20, 0x5fc7: 0x40118d20, + 0x5fc8: 0x40118e20, 0x5fc9: 0x40118f20, 0x5fca: 0x40119020, 0x5fcb: 0x40119120, + 0x5fcc: 0x40119220, 0x5fcd: 0x40119320, 0x5fce: 0x40119420, 0x5fcf: 0x40119520, + 0x5fd0: 0x40119620, 0x5fd1: 0x40119720, 0x5fd2: 0x40119820, 0x5fd3: 0x40119920, + 0x5fd4: 0x40119a20, 0x5fd5: 0x40119b20, 0x5fd6: 0x40119c20, 0x5fd7: 0x40119d20, + 0x5fd8: 0x40119e20, 0x5fd9: 0x40119f20, 0x5fda: 0x4011a020, 0x5fdb: 0x4011a120, + 0x5fdc: 0x4011a220, 0x5fdd: 0x4011a320, 0x5fde: 0x4011a420, 0x5fdf: 0x4011a520, + 0x5fe0: 0x4011a620, 0x5fe1: 0x4011a720, 0x5fe2: 0x4011a820, 0x5fe3: 0x4011a920, + 0x5fe4: 0x4011aa20, 0x5fe5: 0x4011ab20, 0x5fe6: 0x4011ac20, 0x5fe7: 0x4011ad20, + 0x5fe8: 0x4011ae20, 0x5fe9: 0x4011af20, 0x5fea: 0x4011b020, 0x5feb: 0x4011b120, + 0x5fec: 0x4011b220, 0x5fed: 0x4011b320, 0x5fee: 0x4011b420, 0x5fef: 0x4011b520, + 0x5ff0: 0x4011b620, 0x5ff1: 0x4011b720, 0x5ff2: 0x4011b820, 0x5ff3: 0x4011b920, + 0x5ff4: 0x4011ba20, 0x5ff5: 0x4011bb20, 0x5ff6: 0x4011bc20, 0x5ff7: 0x4011bd20, + 0x5ff8: 0x4011be20, 0x5ff9: 0x4011bf20, 0x5ffa: 0x4011c020, 0x5ffb: 0x4011c120, + 0x5ffc: 0x4011c220, 0x5ffd: 0x4011c320, 0x5ffe: 0x4011c420, 0x5fff: 0x4011c520, + // Block 0x180, offset 0x6000 + 0x6000: 0x4011c620, 0x6001: 0x4011c720, 0x6002: 0x4011c820, 0x6003: 0x4011c920, + 0x6004: 0x4011ca20, 0x6005: 0x4011cb20, 0x6006: 0x4011cc20, 0x6007: 0x4011cd20, + 0x6008: 0x4011ce20, 0x6009: 0x4011cf20, 0x600a: 0x4011d020, 0x600b: 0x4011d120, + 0x600c: 0x4011d220, 0x600d: 0x4011d320, 0x600e: 0x4011d420, 0x600f: 0x4011d520, + 0x6010: 0x4011d620, 0x6011: 0x4011d720, 0x6012: 0x4011d820, 0x6013: 0x4011d920, + 0x6014: 0x4011da20, 0x6015: 0x4011db20, 0x6016: 0x4011dc20, 0x6017: 0x4011dd20, + 0x6018: 0x4011de20, 0x6019: 0x4011df20, 0x601a: 0x4011e020, 0x601b: 0x4011e120, + 0x601c: 0x4011e220, 0x601d: 0x4011e320, 0x601e: 0x4011e420, 0x601f: 0x4011e520, + 0x6020: 0x4011e620, 0x6021: 0x4011e720, 0x6022: 0x4011e820, 0x6023: 0x4011e920, + 0x6024: 0x4011ea20, 0x6025: 0x4011eb20, 0x6026: 0x4011ec20, 0x6027: 0x4011ed20, + 0x6028: 0x4011ee20, 0x6029: 0x4011ef20, 0x602a: 0x4011f020, 0x602b: 0x4011f120, + 0x602c: 0x4011f220, 0x602d: 0x4011f320, 0x602e: 0x4011f420, 0x602f: 0x4011f520, + 0x6030: 0x4011f620, 0x6031: 0x4011f720, 0x6032: 0x4011f820, 0x6033: 0x4011f920, + 0x6034: 0x4011fa20, 0x6035: 0x4011fb20, 0x6036: 0x4011fc20, 0x6037: 0x4011fd20, + 0x6039: 0x4011fe20, 0x603a: 0x4011ff20, 0x603b: 0x40120020, + 0x603c: 0x40120120, + // Block 0x181, offset 0x6040 + 0x6040: 0x40120220, 0x6041: 0x40120320, 0x6042: 0x40120420, 0x6043: 0x40120520, + 0x6044: 0x40120620, 0x6045: 0x40120720, 0x6046: 0x40120820, 0x6047: 0x40120920, + 0x6048: 0x40120a20, 0x6049: 0x40120b20, 0x604a: 0x40120c20, 0x604b: 0x40120d20, + 0x604c: 0x40120e20, 0x604d: 0x40120f20, 0x604e: 0x40121020, 0x604f: 0x40121120, + 0x6050: 0x40121220, 0x6051: 0x40121320, 0x6052: 0x40121420, 0x6053: 0x40121520, + 0x6054: 0x40121620, 0x6055: 0x40121720, 0x6056: 0x40121820, 0x6057: 0x40121920, + 0x6058: 0x40121a20, 0x6059: 0x40121b20, 0x605a: 0x40121c20, 0x605b: 0x40121d20, + 0x605c: 0x40121e20, 0x605d: 0x40121f20, 0x605e: 0x40122020, 0x605f: 0x40122120, + 0x6060: 0x40122220, 0x6061: 0x40122320, 0x6062: 0x40122420, 0x6063: 0x40122520, + 0x6064: 0x40122620, 0x6065: 0x40122720, 0x6066: 0x40122820, 0x6067: 0x40122920, + 0x6068: 0x40122a20, 0x6069: 0x40122b20, 0x606a: 0x40122c20, 0x606b: 0x40122d20, + 0x606c: 0x40122e20, 0x606d: 0x40122f20, 0x606e: 0x40123020, 0x606f: 0x40123120, + 0x6070: 0x40123220, 0x6071: 0x40123320, 0x6072: 0x40123420, 0x6073: 0x40123520, + 0x6074: 0x40123620, 0x6075: 0x40123720, 0x6076: 0x40123820, 0x6077: 0x40123920, + 0x6078: 0x40123a20, 0x6079: 0x40123b20, 0x607a: 0x40123c20, 0x607b: 0x40123d20, + 0x607c: 0x40123e20, 0x607d: 0x40123f20, + // Block 0x182, offset 0x6080 + 0x6090: 0x40124020, 0x6091: 0x40124120, 0x6092: 0x40124220, 0x6093: 0x40124320, + 0x6094: 0x40124420, 0x6095: 0x40124520, 0x6096: 0x40124620, 0x6097: 0x40124720, + 0x6098: 0x40124820, 0x6099: 0x40124920, 0x609a: 0x40124a20, 0x609b: 0x40124b20, + 0x609c: 0x40124c20, 0x609d: 0x40124d20, 0x609e: 0x40124e20, 0x609f: 0x40124f20, + 0x60a0: 0x40125020, 0x60a1: 0x40125120, 0x60a2: 0x40125220, 0x60a3: 0x40125320, + 0x60a4: 0x40125420, 0x60a5: 0x40125520, 0x60a6: 0x40125620, 0x60a7: 0x40125720, + // Block 0x183, offset 0x60c0 + 0x60fb: 0x40125820, + 0x60fc: 0x40125920, 0x60fd: 0x40125a20, 0x60fe: 0x40125b20, 0x60ff: 0x40125c20, + // Block 0x184, offset 0x6100 + 0x6101: 0x40125d20, 0x6102: 0x40125e20, 0x6103: 0x40125f20, + 0x6104: 0x40126020, 0x6105: 0x40126120, 0x6106: 0x40126220, 0x6107: 0x40126320, + 0x6108: 0x40126420, 0x6109: 0x40126520, 0x610a: 0x40126620, 0x610b: 0x40126720, + 0x610c: 0x40126820, 0x610d: 0x40126920, 0x610e: 0x40126a20, 0x610f: 0x40126b20, + 0x6110: 0x40126c20, 0x6112: 0x40126d20, 0x6113: 0x40126e20, + 0x6114: 0x40126f20, 0x6116: 0x40127020, + 0x6118: 0x40127120, 0x611a: 0x40127220, + 0x611c: 0x40127320, 0x611d: 0x40127420, 0x611e: 0x40127520, + 0x6120: 0x40127620, 0x6121: 0x40127720, 0x6122: 0x40127820, 0x6123: 0x40127920, + 0x6124: 0x40127a20, 0x6125: 0x40127b20, + 0x6128: 0x40127c20, 0x6129: 0x40127d20, 0x612a: 0x40127e20, 0x612b: 0x40127f20, + 0x612d: 0x40128020, + 0x6130: 0x40128120, 0x6131: 0x40128220, 0x6132: 0x40128320, 0x6133: 0x40128420, + 0x6135: 0x40128520, 0x6136: 0x40128620, 0x6137: 0x40128720, + 0x6138: 0x40128820, 0x6139: 0x40128920, 0x613a: 0x40128a20, 0x613b: 0x40128b20, + 0x613c: 0x40128c20, 0x613d: 0x40128d20, 0x613e: 0x40128e20, 0x613f: 0x40128f20, + // Block 0x185, offset 0x6140 + 0x6140: 0x40129020, + 0x6145: 0x40129120, 0x6146: 0x40129220, 0x6147: 0x40129320, + 0x6148: 0x40129420, 0x6149: 0x40129520, 0x614a: 0x40129620, 0x614b: 0x40129720, + 0x614c: 0x40129820, 0x614d: 0x40129920, 0x614e: 0x40129a20, 0x614f: 0x40129b20, + // Block 0x186, offset 0x6180 + 0x6180: 0x40129c20, 0x6181: 0x40129d20, 0x6182: 0x40129e20, 0x6183: 0x40129f20, + 0x6184: 0x4012a020, 0x6185: 0x4012a120, 0x6186: 0x4012a220, 0x6187: 0x4012a320, + 0x6188: 0x4012a420, 0x6189: 0x4012a520, 0x618a: 0x4012a620, 0x618b: 0x4012a720, + 0x618c: 0x4012a820, 0x618d: 0x4012a920, 0x618e: 0x4012aa20, 0x618f: 0x4012ab20, + 0x6190: 0x4012ac20, 0x6191: 0x4012ad20, 0x6192: 0x4012ae20, 0x6193: 0x4012af20, + 0x6194: 0x4012b020, 0x6195: 0x4012b120, 0x6196: 0x4012b220, 0x6197: 0x4012b320, + 0x6198: 0x4012b420, 0x6199: 0x4012b520, 0x619a: 0x4012b620, 0x619b: 0x4012b720, + 0x619c: 0x4012b820, 0x619d: 0x4012b920, 0x619e: 0x4012ba20, 0x619f: 0x4012bb20, + 0x61a0: 0x4012bc20, 0x61a1: 0x4012bd20, 0x61a2: 0x4012be20, 0x61a3: 0x4012bf20, + 0x61a4: 0x4012c020, 0x61a5: 0x4012c120, 0x61a6: 0x4012c220, 0x61a7: 0x4012c320, + 0x61a8: 0x4012c420, 0x61a9: 0x4012c520, 0x61aa: 0x4012c620, 0x61ab: 0x4012c720, + 0x61ac: 0x4012c820, 0x61ad: 0x4012c920, 0x61ae: 0x4012ca20, 0x61af: 0x4012cb20, + 0x61b0: 0x4012cc20, 0x61b1: 0x4012cd20, 0x61b2: 0x4012ce20, 0x61b3: 0x4012cf20, + 0x61b4: 0x4012d020, 0x61b5: 0x4012d120, 0x61b6: 0x4012d220, 0x61b7: 0x4012d320, + 0x61b8: 0x4012d420, 0x61b9: 0x4012d520, 0x61ba: 0x4012d620, 0x61bb: 0x4012d720, + 0x61bc: 0x4012d820, 0x61bd: 0x4012d920, 0x61be: 0x4012da20, 0x61bf: 0x4012db20, + // Block 0x187, offset 0x61c0 + 0x61c0: 0x4012dc20, 0x61c1: 0x4012dd20, 0x61c2: 0x4012de20, 0x61c3: 0x4012df20, + 0x61c4: 0x4012e020, 0x61c5: 0x4012e120, + // Block 0x188, offset 0x6200 + 0x6200: 0x4012e220, 0x6201: 0x4012e320, 0x6202: 0x4012e420, 0x6203: 0x4012e520, + 0x6204: 0x4012e620, 0x6205: 0x4012e720, 0x6206: 0x4012e820, 0x6207: 0x4012e920, + 0x6208: 0x4012ea20, 0x6209: 0x4012eb20, 0x620a: 0x4012ec20, 0x620b: 0x4012ed20, + 0x620c: 0x4012ee20, 0x620d: 0x4012ef20, 0x620e: 0x4012f020, 0x620f: 0x4012f120, + 0x6210: 0x4012f220, 0x6211: 0x4012f320, 0x6212: 0x4012f420, 0x6213: 0x4012f520, + 0x6214: 0x4012f620, 0x6215: 0x4012f720, 0x6216: 0x4012f820, 0x6217: 0x4012f920, + 0x6218: 0x4012fa20, 0x6219: 0x4012fb20, 0x621a: 0x4012fc20, 0x621b: 0x4012fd20, + 0x621c: 0x4012fe20, 0x621d: 0x4012ff20, 0x621e: 0x40130020, 0x621f: 0x40130120, + 0x6220: 0x40130220, 0x6221: 0x40130320, 0x6222: 0x40130420, 0x6223: 0x40130520, + 0x6224: 0x40130620, 0x6225: 0x40130720, 0x6226: 0x40130820, 0x6227: 0x40130920, + 0x6228: 0x40130a20, 0x6229: 0x40130b20, 0x622a: 0x40130c20, 0x622b: 0x40130d20, + 0x622c: 0x40130e20, 0x622d: 0x40130f20, 0x622e: 0x40131020, 0x622f: 0x40131120, + 0x6230: 0x40131220, 0x6231: 0x40131320, 0x6232: 0x40131420, 0x6233: 0x40131520, + 0x6234: 0x40131620, 0x6235: 0x40131720, 0x6236: 0x40131820, 0x6237: 0x40131920, + 0x6238: 0x40131a20, 0x6239: 0x40131b20, 0x623a: 0x40131c20, 0x623b: 0x40131d20, + 0x623c: 0x40131e20, 0x623d: 0x40131f20, 0x623e: 0x40132020, 0x623f: 0x40132120, + // Block 0x189, offset 0x6240 + 0x6240: 0x40132220, 0x6241: 0x40132320, 0x6242: 0x40132420, 0x6243: 0x40132520, + 0x6244: 0x40132620, 0x6245: 0x40132720, 0x6246: 0x40132820, 0x6247: 0x40132920, + 0x6248: 0x40132a20, 0x6249: 0x40132b20, 0x624a: 0x40132c20, 0x624b: 0x40132d20, + 0x624c: 0x40132e20, 0x624d: 0x40132f20, 0x624e: 0x40133020, 0x624f: 0x40133120, + 0x6250: 0x40133220, 0x6251: 0x40133320, 0x6252: 0x40133420, 0x6253: 0x40133520, + 0x6254: 0x40133620, 0x6255: 0x40133720, 0x6256: 0x40133820, 0x6257: 0x40133920, + 0x6258: 0x40133a20, 0x6259: 0x40133b20, 0x625a: 0x40133c20, 0x625b: 0x40133d20, + 0x625c: 0x40133e20, 0x625d: 0x40133f20, 0x625e: 0x40134020, 0x625f: 0x40134120, + 0x6260: 0x40134220, 0x6261: 0x40134320, 0x6262: 0x40134420, 0x6263: 0x40134520, + 0x6264: 0x40134620, 0x6265: 0x40134720, 0x6266: 0x40134820, 0x6267: 0x40134920, + 0x6268: 0x40134a20, 0x6269: 0x40134b20, 0x626a: 0x40134c20, 0x626b: 0x40134d20, + 0x626c: 0x40134e20, 0x626d: 0x40134f20, 0x626e: 0x40135020, 0x626f: 0x40135120, + 0x6270: 0x40135220, 0x6271: 0x40135320, 0x6272: 0x40135420, 0x6273: 0x40135520, + // Block 0x18a, offset 0x6280 + 0x6281: 0x80000000, + 0x62a0: 0x80000000, 0x62a1: 0x80000000, 0x62a2: 0x80000000, 0x62a3: 0x80000000, + 0x62a4: 0x80000000, 0x62a5: 0x80000000, 0x62a6: 0x80000000, 0x62a7: 0x80000000, + 0x62a8: 0x80000000, 0x62a9: 0x80000000, 0x62aa: 0x80000000, 0x62ab: 0x80000000, + 0x62ac: 0x80000000, 0x62ad: 0x80000000, 0x62ae: 0x80000000, 0x62af: 0x80000000, + 0x62b0: 0x80000000, 0x62b1: 0x80000000, 0x62b2: 0x80000000, 0x62b3: 0x80000000, + 0x62b4: 0x80000000, 0x62b5: 0x80000000, 0x62b6: 0x80000000, 0x62b7: 0x80000000, + 0x62b8: 0x80000000, 0x62b9: 0x80000000, 0x62ba: 0x80000000, 0x62bb: 0x80000000, + 0x62bc: 0x80000000, 0x62bd: 0x80000000, 0x62be: 0x80000000, 0x62bf: 0x80000000, + // Block 0x18b, offset 0x62c0 + 0x62c0: 0x80000000, 0x62c1: 0x80000000, 0x62c2: 0x80000000, 0x62c3: 0x80000000, + 0x62c4: 0x80000000, 0x62c5: 0x80000000, 0x62c6: 0x80000000, 0x62c7: 0x80000000, + 0x62c8: 0x80000000, 0x62c9: 0x80000000, 0x62ca: 0x80000000, 0x62cb: 0x80000000, + 0x62cc: 0x80000000, 0x62cd: 0x80000000, 0x62ce: 0x80000000, 0x62cf: 0x80000000, + 0x62d0: 0x80000000, 0x62d1: 0x80000000, 0x62d2: 0x80000000, 0x62d3: 0x80000000, + 0x62d4: 0x80000000, 0x62d5: 0x80000000, 0x62d6: 0x80000000, 0x62d7: 0x80000000, + 0x62d8: 0x80000000, 0x62d9: 0x80000000, 0x62da: 0x80000000, 0x62db: 0x80000000, + 0x62dc: 0x80000000, 0x62dd: 0x80000000, 0x62de: 0x80000000, 0x62df: 0x80000000, + 0x62e0: 0x80000000, 0x62e1: 0x80000000, 0x62e2: 0x80000000, 0x62e3: 0x80000000, + 0x62e4: 0x80000000, 0x62e5: 0x80000000, 0x62e6: 0x80000000, 0x62e7: 0x80000000, + 0x62e8: 0x80000000, 0x62e9: 0x80000000, 0x62ea: 0x80000000, 0x62eb: 0x80000000, + 0x62ec: 0x80000000, 0x62ed: 0x80000000, 0x62ee: 0x80000000, 0x62ef: 0x80000000, + 0x62f0: 0x80000000, 0x62f1: 0x80000000, 0x62f2: 0x80000000, 0x62f3: 0x80000000, + 0x62f4: 0x80000000, 0x62f5: 0x80000000, 0x62f6: 0x80000000, 0x62f7: 0x80000000, + 0x62f8: 0x80000000, 0x62f9: 0x80000000, 0x62fa: 0x80000000, 0x62fb: 0x80000000, + 0x62fc: 0x80000000, 0x62fd: 0x80000000, 0x62fe: 0x80000000, 0x62ff: 0x80000000, + // Block 0x18c, offset 0x6300 + 0x6300: 0x80000000, 0x6301: 0x80000000, 0x6302: 0x80000000, 0x6303: 0x80000000, + 0x6304: 0x80000000, 0x6305: 0x80000000, 0x6306: 0x80000000, 0x6307: 0x80000000, + 0x6308: 0x80000000, 0x6309: 0x80000000, 0x630a: 0x80000000, 0x630b: 0x80000000, + 0x630c: 0x80000000, 0x630d: 0x80000000, 0x630e: 0x80000000, 0x630f: 0x80000000, + 0x6310: 0x80000000, 0x6311: 0x80000000, 0x6312: 0x80000000, 0x6313: 0x80000000, + 0x6314: 0x80000000, 0x6315: 0x80000000, 0x6316: 0x80000000, 0x6317: 0x80000000, + 0x6318: 0x80000000, 0x6319: 0x80000000, 0x631a: 0x80000000, 0x631b: 0x80000000, + 0x631c: 0x80000000, 0x631d: 0x80000000, 0x631e: 0x80000000, 0x631f: 0x80000000, + 0x6320: 0x80000000, 0x6321: 0x80000000, 0x6322: 0x80000000, 0x6323: 0x80000000, + 0x6324: 0x80000000, 0x6325: 0x80000000, 0x6326: 0x80000000, 0x6327: 0x80000000, + 0x6328: 0x80000000, 0x6329: 0x80000000, 0x632a: 0x80000000, 0x632b: 0x80000000, + 0x632c: 0x80000000, 0x632d: 0x80000000, 0x632e: 0x80000000, 0x632f: 0x80000000, +} + +// mainLookup: 1472 entries, 2944 bytes +// Block 0 is the null block. +var mainLookup = [1472]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0x0e0: 0x1f, 0x0e1: 0x20, 0x0e4: 0x21, 0x0e5: 0x22, 0x0e6: 0x23, 0x0e7: 0x24, + 0x0e8: 0x25, 0x0e9: 0x26, 0x0ea: 0x27, 0x0eb: 0x28, 0x0ec: 0x29, 0x0ed: 0x2a, 0x0ee: 0x2b, 0x0ef: 0x2c, + 0x0f0: 0x2d, 0x0f1: 0x2e, 0x0f2: 0x2f, 0x0f3: 0x30, 0x0f4: 0x31, 0x0f5: 0x32, 0x0f6: 0x33, 0x0f7: 0x34, + 0x0f8: 0x35, 0x0f9: 0x36, 0x0fa: 0x37, 0x0fb: 0x38, 0x0fc: 0x39, 0x0fd: 0x3a, 0x0fe: 0x3b, 0x0ff: 0x3c, + // Block 0x4, offset 0x100 + 0x100: 0x3d, 0x101: 0x3e, 0x102: 0x3f, 0x103: 0x40, 0x104: 0x41, 0x105: 0x42, 0x106: 0x43, 0x107: 0x44, + 0x108: 0x45, 0x109: 0x46, 0x10a: 0x47, 0x10b: 0x48, 0x10c: 0x49, 0x10d: 0x4a, 0x10e: 0x4b, 0x10f: 0x4c, + 0x110: 0x4d, 0x111: 0x4e, 0x112: 0x4f, 0x113: 0x50, 0x114: 0x51, 0x115: 0x52, 0x116: 0x53, 0x117: 0x54, + 0x118: 0x55, 0x119: 0x56, 0x11a: 0x57, 0x11b: 0x58, 0x11c: 0x59, 0x11d: 0x5a, 0x11e: 0x5b, 0x11f: 0x5c, + 0x120: 0x5d, 0x121: 0x5e, 0x122: 0x5f, 0x123: 0x60, 0x124: 0x61, 0x125: 0x62, 0x126: 0x63, 0x127: 0x64, + 0x128: 0x65, 0x129: 0x66, 0x12a: 0x67, 0x12c: 0x68, 0x12d: 0x69, 0x12e: 0x6a, 0x12f: 0x6b, + 0x130: 0x6c, 0x131: 0x6d, 0x133: 0x6e, 0x134: 0x6f, 0x135: 0x70, 0x136: 0x71, 0x137: 0x72, + 0x13a: 0x73, 0x13b: 0x74, 0x13e: 0x75, 0x13f: 0x76, + // Block 0x5, offset 0x140 + 0x140: 0x77, 0x141: 0x78, 0x142: 0x79, 0x143: 0x7a, 0x144: 0x7b, 0x145: 0x7c, 0x146: 0x7d, 0x147: 0x7e, + 0x148: 0x7f, 0x149: 0x80, 0x14a: 0x81, 0x14b: 0x82, 0x14c: 0x83, 0x14d: 0x84, 0x14e: 0x85, 0x14f: 0x86, + 0x150: 0x87, 0x151: 0x88, 0x152: 0x89, 0x153: 0x8a, 0x154: 0x8b, 0x155: 0x8c, 0x156: 0x8d, 0x157: 0x8e, + 0x158: 0x8f, 0x159: 0x90, 0x15a: 0x91, 0x15b: 0x92, 0x15c: 0x93, 0x15d: 0x94, 0x15e: 0x95, 0x15f: 0x96, + 0x160: 0x97, 0x161: 0x98, 0x162: 0x99, 0x163: 0x9a, 0x164: 0x9b, 0x165: 0x9c, 0x166: 0x9d, 0x167: 0x9e, + 0x168: 0x9f, 0x169: 0xa0, 0x16a: 0xa1, 0x16b: 0xa2, 0x16c: 0xa3, 0x16d: 0xa4, + 0x170: 0xa5, 0x171: 0xa6, 0x172: 0xa7, 0x173: 0xa8, 0x174: 0xa9, 0x175: 0xaa, 0x176: 0xab, 0x177: 0xac, + 0x178: 0xad, 0x17a: 0xae, 0x17b: 0xaf, 0x17c: 0xb0, 0x17d: 0xb0, 0x17e: 0xb0, 0x17f: 0xb1, + // Block 0x6, offset 0x180 + 0x180: 0xb2, 0x181: 0xb3, 0x182: 0xb4, 0x183: 0xb5, 0x184: 0xb6, 0x185: 0xb0, 0x186: 0xb7, 0x187: 0xb8, + 0x188: 0xb9, 0x189: 0xba, 0x18a: 0xbb, 0x18b: 0xbc, 0x18c: 0xbd, 0x18d: 0xbe, 0x18e: 0xbf, 0x18f: 0xc0, + // Block 0x7, offset 0x1c0 + 0x1f7: 0xc1, + // Block 0x8, offset 0x200 + 0x200: 0xc2, 0x201: 0xc3, 0x202: 0xc4, 0x203: 0xc5, 0x204: 0xc6, 0x205: 0xc7, 0x206: 0xc8, 0x207: 0xc9, + 0x208: 0xca, 0x209: 0xcb, 0x20a: 0xcc, 0x20b: 0xcd, 0x20c: 0xce, 0x20d: 0xcf, 0x20e: 0xd0, 0x20f: 0xd1, + 0x210: 0xd2, 0x211: 0xd3, 0x212: 0xd4, 0x213: 0xd5, 0x214: 0xd6, 0x215: 0xd7, 0x216: 0xd8, 0x217: 0xd9, + 0x218: 0xda, 0x219: 0xdb, 0x21a: 0xdc, 0x21b: 0xdd, 0x21c: 0xde, 0x21d: 0xdf, 0x21e: 0xe0, 0x21f: 0xe1, + 0x220: 0xe2, 0x221: 0xe3, 0x222: 0xe4, 0x223: 0xe5, 0x224: 0xe6, 0x225: 0xe7, 0x226: 0xe8, 0x227: 0xe9, + 0x228: 0xea, 0x229: 0xeb, 0x22a: 0xec, 0x22b: 0xed, 0x22c: 0xee, 0x22f: 0xef, + // Block 0x9, offset 0x240 + 0x25e: 0xf0, 0x25f: 0xf1, + // Block 0xa, offset 0x280 + 0x2a8: 0xf2, 0x2ac: 0xf3, 0x2ad: 0xf4, 0x2ae: 0xf5, 0x2af: 0xf6, + 0x2b0: 0xf7, 0x2b1: 0xf8, 0x2b2: 0xf9, 0x2b3: 0xfa, 0x2b4: 0xfb, 0x2b5: 0xfc, 0x2b6: 0xfd, 0x2b7: 0xfe, + 0x2b8: 0xff, 0x2b9: 0x100, 0x2ba: 0x101, 0x2bb: 0x102, 0x2bc: 0x103, 0x2bd: 0x104, 0x2be: 0x105, 0x2bf: 0x106, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x107, 0x2c1: 0x108, 0x2c2: 0x109, 0x2c3: 0x10a, 0x2c4: 0x10b, 0x2c5: 0x10c, 0x2c6: 0x10d, 0x2c7: 0x10e, + 0x2ca: 0x10f, 0x2cb: 0x110, 0x2cc: 0x111, 0x2cd: 0x112, 0x2ce: 0x113, 0x2cf: 0x114, + 0x2d0: 0x115, 0x2d1: 0x116, 0x2d2: 0x117, + 0x2e0: 0x118, 0x2e1: 0x119, 0x2e4: 0x11a, + 0x2e8: 0x11b, 0x2e9: 0x11c, 0x2ec: 0x11d, 0x2ed: 0x11e, + 0x2f0: 0x11f, 0x2f1: 0x120, + 0x2f9: 0x121, + // Block 0xc, offset 0x300 + 0x300: 0x122, 0x301: 0x123, 0x302: 0x124, 0x303: 0x125, + // Block 0xd, offset 0x340 + 0x340: 0x126, 0x341: 0x127, 0x342: 0x128, 0x343: 0x129, 0x344: 0x12a, 0x345: 0x12b, 0x346: 0x12c, 0x347: 0x12d, + 0x348: 0x12e, 0x349: 0x12f, 0x34a: 0x130, 0x34b: 0x131, 0x34c: 0x132, 0x34d: 0x133, + 0x350: 0x134, 0x351: 0x135, + // Block 0xe, offset 0x380 + 0x380: 0x136, 0x381: 0x137, 0x382: 0x138, 0x383: 0x139, 0x384: 0x13a, 0x385: 0x13b, 0x386: 0x13c, 0x387: 0x13d, + 0x388: 0x13e, 0x389: 0x13f, 0x38a: 0x140, 0x38b: 0x141, 0x38c: 0x142, 0x38d: 0x143, 0x38e: 0x144, 0x38f: 0x145, + 0x390: 0x146, + // Block 0xf, offset 0x3c0 + 0x3e0: 0x147, 0x3e1: 0x148, 0x3e2: 0x149, 0x3e3: 0x14a, 0x3e4: 0x14b, 0x3e5: 0x14c, 0x3e6: 0x14d, 0x3e7: 0x14e, + 0x3e8: 0x14f, + // Block 0x10, offset 0x400 + 0x400: 0x150, + // Block 0x11, offset 0x440 + 0x440: 0x151, 0x441: 0x152, 0x442: 0x153, 0x443: 0x154, 0x444: 0x155, 0x445: 0x156, 0x446: 0x157, 0x447: 0x158, + 0x448: 0x159, 0x449: 0x15a, 0x44c: 0x15b, 0x44d: 0x15c, + 0x450: 0x15d, 0x451: 0x15e, 0x452: 0x15f, 0x453: 0x160, 0x454: 0x161, 0x455: 0x162, 0x456: 0x163, 0x457: 0x164, + 0x458: 0x165, 0x459: 0x166, 0x45a: 0x167, 0x45b: 0x168, 0x45c: 0x169, 0x45d: 0x16a, 0x45e: 0x16b, 0x45f: 0x16c, + // Block 0x12, offset 0x480 + 0x480: 0x16d, 0x481: 0x16e, 0x482: 0x16f, 0x483: 0x170, 0x484: 0x171, 0x485: 0x172, 0x486: 0x173, 0x487: 0x174, + 0x488: 0x175, 0x489: 0x176, 0x48c: 0x177, 0x48d: 0x178, 0x48e: 0x179, 0x48f: 0x17a, + 0x490: 0x17b, 0x491: 0x17c, 0x492: 0x17d, 0x493: 0x17e, 0x494: 0x17f, 0x495: 0x180, 0x497: 0x181, + 0x498: 0x182, 0x499: 0x183, 0x49a: 0x184, 0x49b: 0x185, 0x49c: 0x186, 0x49d: 0x187, + // Block 0x13, offset 0x4c0 + 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d2: 0x0b, 0x4d3: 0x0c, 0x4d6: 0x0d, + 0x4db: 0x0e, 0x4dd: 0x0f, 0x4df: 0x10, + // Block 0x14, offset 0x500 + 0x500: 0x188, 0x501: 0x189, 0x504: 0x189, 0x505: 0x189, 0x506: 0x189, 0x507: 0x18a, + // Block 0x15, offset 0x540 + 0x560: 0x12, + // Block 0x16, offset 0x580 + 0x582: 0x01, 0x583: 0x02, 0x584: 0x03, 0x585: 0x04, 0x586: 0x05, 0x587: 0x06, + 0x588: 0x07, 0x589: 0x08, 0x58a: 0x09, 0x58b: 0x0a, 0x58c: 0x0b, 0x58d: 0x0c, 0x58e: 0x0d, 0x58f: 0x0e, + 0x590: 0x0f, 0x591: 0x10, 0x592: 0x11, 0x593: 0x12, 0x594: 0x13, 0x595: 0x14, 0x596: 0x15, 0x597: 0x16, + 0x598: 0x17, 0x599: 0x18, 0x59a: 0x19, 0x59b: 0x1a, 0x59c: 0x1b, 0x59d: 0x1c, 0x59e: 0x1d, 0x59f: 0x1e, + 0x5a0: 0x01, 0x5a1: 0x02, 0x5a2: 0x03, 0x5a3: 0x04, 0x5a4: 0x05, + 0x5aa: 0x06, 0x5ad: 0x07, 0x5af: 0x08, + 0x5b0: 0x11, 0x5b3: 0x13, +} + +// mainCTEntries: 126 entries, 504 bytes +var mainCTEntries = [126]struct{ l, h, n, i uint8 }{ + {0xCE, 0x1, 1, 255}, + {0xC2, 0x0, 1, 255}, + {0xB7, 0xB7, 0, 1}, + {0x87, 0x87, 0, 2}, + {0xCC, 0x0, 2, 255}, + {0x88, 0x88, 0, 2}, + {0x86, 0x86, 0, 1}, + {0xCC, 0x0, 1, 255}, + {0x88, 0x88, 0, 1}, + {0xCD, 0x1, 1, 255}, + {0xCC, 0x0, 1, 255}, + {0x81, 0x81, 0, 1}, + {0x81, 0x81, 0, 2}, + {0xCC, 0x0, 1, 255}, + {0x86, 0x86, 0, 1}, + {0xCC, 0x0, 3, 255}, + {0x8B, 0x8B, 0, 3}, + {0x88, 0x88, 0, 2}, + {0x86, 0x86, 0, 1}, + {0xCC, 0x0, 1, 255}, + {0x8F, 0x8F, 0, 1}, + {0xD9, 0x0, 1, 255}, + {0x93, 0x95, 0, 1}, + {0xD9, 0x0, 1, 255}, + {0x94, 0x94, 0, 1}, + {0xE0, 0x0, 2, 255}, + {0xA7, 0x1, 1, 255}, + {0xA6, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0x97, 0x97, 0, 2}, + {0xE0, 0x0, 2, 255}, + {0xAD, 0x1, 1, 255}, + {0xAC, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0x96, 0x97, 0, 2}, + {0xE0, 0x0, 1, 255}, + {0xAF, 0x0, 1, 255}, + {0x97, 0x97, 0, 1}, + {0xE0, 0x0, 2, 255}, + {0xAF, 0x1, 1, 255}, + {0xAE, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0x97, 0x97, 0, 2}, + {0xE0, 0x0, 1, 255}, + {0xAE, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB1, 0x0, 1, 255}, + {0x96, 0x96, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB3, 0x0, 1, 255}, + {0x95, 0x95, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB3, 0x0, 2, 255}, + {0x95, 0x96, 0, 3}, + {0x82, 0x0, 1, 2}, + {0xE0, 0x0, 1, 255}, + {0xB3, 0x0, 1, 255}, + {0x95, 0x95, 0, 1}, + {0xE0, 0x0, 2, 255}, + {0xB5, 0x1, 1, 255}, + {0xB4, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0x97, 0x97, 0, 2}, + {0xE0, 0x0, 1, 255}, + {0xB4, 0x0, 1, 255}, + {0xBE, 0xBE, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB7, 0x0, 3, 255}, + {0x9F, 0x9F, 0, 4}, + {0x8F, 0x0, 1, 3}, + {0x8A, 0x8A, 0, 2}, + {0xE0, 0x0, 1, 255}, + {0xB7, 0x0, 1, 255}, + {0x8A, 0x8A, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB7, 0x0, 1, 255}, + {0x8A, 0x8A, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB8, 0x0, 1, 255}, + {0x81, 0xAE, 0, 1}, + {0xE0, 0x0, 1, 255}, + {0xB8, 0x0, 1, 255}, + {0xB2, 0xB2, 0, 1}, + {0xE0, 0x0, 2, 255}, + {0xBB, 0xC, 1, 255}, + {0xBA, 0x0, 12, 255}, + {0xAD, 0xAE, 0, 26}, + {0xAA, 0xAB, 0, 24}, + {0xA7, 0xA7, 0, 23}, + {0xA5, 0xA5, 0, 22}, + {0xA1, 0xA3, 0, 19}, + {0x99, 0x9F, 0, 12}, + {0x94, 0x97, 0, 8}, + {0x8D, 0x8D, 0, 7}, + {0x8A, 0x8A, 0, 6}, + {0x87, 0x88, 0, 4}, + {0x84, 0x84, 0, 3}, + {0x81, 0x82, 0, 1}, + {0x9C, 0x9D, 0, 28}, + {0xE0, 0x0, 1, 255}, + {0xBA, 0x0, 1, 255}, + {0xB2, 0xB2, 0, 1}, + {0xEA, 0x0, 1, 255}, + {0xAA, 0x0, 1, 255}, + {0x80, 0xAF, 0, 1}, + {0xE0, 0x0, 2, 255}, + {0xBE, 0x4, 1, 255}, + {0xBD, 0x0, 1, 255}, + {0xB1, 0x0, 1, 2}, + {0xE0, 0x0, 1, 255}, + {0xBE, 0x0, 1, 255}, + {0x80, 0x80, 0, 1}, + {0x80, 0x81, 0, 3}, + {0xE0, 0x0, 2, 255}, + {0xBE, 0x2, 1, 255}, + {0xBD, 0x0, 2, 255}, + {0xB4, 0xB4, 0, 2}, + {0xB2, 0xB2, 0, 1}, + {0x80, 0x80, 0, 3}, + {0xE1, 0x0, 1, 255}, + {0x80, 0x0, 1, 255}, + {0xAE, 0xAE, 0, 1}, + {0xE1, 0x0, 1, 255}, + {0xAC, 0x0, 1, 255}, + {0xB5, 0xB5, 0, 1}, +} + +// Total size of mainTable is 126988 bytes diff --git a/libgo/go/exp/locale/collate/tools/colcmp/chars.go b/libgo/go/exp/locale/collate/tools/colcmp/chars.go new file mode 100644 index 0000000..c04998d --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/chars.go @@ -0,0 +1,937 @@ +// Generated by running +// maketables -root=http://unicode.org/Public/UCA/6.0.0/CollationAuxiliary.zip -cldr=http://www.unicode.org/Public/cldr/2.0.1/core.zip +// DO NOT EDIT + +package main + +type exemplarType int + +const ( + exCharacters exemplarType = iota + exContractions + exPunctuation + exAuxiliary + exCurrency + exIndex + exN +) + +var exemplarCharacters = map[string][exN]string{ + "af": { + 0: "a á â b c d e é è ê ë f g h i î ï j k l m n o ô ö p q r s t u û v w x y z", + 3: "á à â ä ã æ ç é è ê ë í ì î ï ó ò ô ö ú ù û ü ý", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "agq": { + 0: "a à â ǎ ā b c d e è ê ě ē ɛ ɛ̀ ɛ̂ ɛ̌ ɛ̄ f g h i ì î ǐ ī ɨ ɨ̀ ɨ̂ ɨ̌ ɨ̄ k l m n ŋ o ò ô ǒ ō ɔ ɔ̀ ɔ̂ ɔ̌ ɔ̄ p s t u ù û ǔ ū ʉ ʉ̀ ʉ̂ ʉ̌ ʉ̄ v w y z ʔ", + 3: "q r x", + 5: "A B C D E Ɛ F G H I Ɨ K L M N Ŋ O Ɔ P S T U Ʉ V W Y Z ʔ", + }, + "ak": { + 0: "a b d e ɛ f g h i k l m n o ɔ p r s t u w y", + 3: "c j q v z", + 5: "A B C D E Ɛ F G H I J K L M N O Ɔ P Q R S T U V W X Y Z", + }, + "am": { + 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቊ ቋ ቌ ቍ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ዯ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጷ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ ፘ ፙ ፚ", + }, + "ar": { + 0: "ً ٌ ٍ َ ُ ِ ّ ْ ء آ أ ؤ إ ئ ا ب ت ة ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي ى", + 3: "\u200c \u200d \u200e \u200f", + }, + "as": { + 0: "অ আ ই ঈ উ ঊ ঋ এ ঐ ও ঔ ং ঁ ঃ ক খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড ড় ড় ঢ ঢ় ঢ় ণ ত থ দ ধ ন প ফ ব ভ ম য য় ৰ ল ৱ শ ষ স হ া ি ী ু ূ ৃ ে ৈ ো ৌ ্", + 3: "\u200c \u200d ৲", + }, + "asa": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "az": { + 0: "a b c ç d e ə f g ğ h x ı i i̇ j k q l m n o ö p r s ş t u ü v y z", + 3: "w", + }, + "az_Cyrl": { + 0: "а ә б в г ғ д е ж з и й ј к ҝ л м н о ө п р с т у ү ф х һ ч ҹ ш ы", + 3: "ц щ ъ ь э ю я", + }, + "bas": { + 0: "a á à â ǎ ā a᷆ a᷇ b ɓ c d e é è ê ě ē e᷆ e᷇ ɛ ɛ́ ɛ̀ ɛ̂ ɛ̌ ɛ̄ ɛ᷆ ɛ᷇ f g h i í ì î ǐ ī i᷆ i᷇ j k l m n ń ǹ ŋ o ó ò ô ǒ ō o᷆ o᷇ ɔ ɔ́ ɔ̀ ɔ̂ ɔ̌ ɔ̄ ɔ᷆ ɔ᷇ p r s t u ú ù û ǔ ū u᷆ u᷇ v w y z", + 3: "q x", + 5: "A B Ɓ C D E Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y Z", + }, + "be": { + 0: "а б в г д дж дз е ё ж з і й к л м н о п р с т у ў ф х ц ч ш ы ь э ю я", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "bem": { + 0: "a b c e f g i j k l m n o p s sh t u w y", + 3: "d h q r v x z", + 5: "A B C E F G I J K L M N O P S SH T U W Y", + }, + "bez": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w y z", + 3: "x", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W Y Z", + }, + "bg": { + 0: "а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ь ю я", + 3: "а̀ ѐ ѝ о̀ у̀ ъ ѣ ю̀ я̀ ѫ", + }, + "bm": { + 0: "a b c d e ɛ f g h i j k l m n ɲ ŋ o ɔ p r s t u w y z", + 3: "q v x", + 5: "A B C D E Ɛ F G H I J K L M N Ɲ Ŋ O Ɔ P R S T U W Y Z", + }, + "bn": { + 0: "৺ অ আ ই ঈ উ ঊ ঋ ৠ ঌ ৡ এ ঐ ও ঔ ় ং ঃ ঁ ক ক্ষ খ গ ঘ ঙ চ ছ জ ঝ ঞ ট ঠ ড ড় ঢ ঢ় ণ ৎ ত থ দ ধ ন প ফ ব ভ ম য য় র ল শ ষ স হ ঽ া ি ী ু ূ ৃ ৄ ৢ ৣ ে ৈ ো ৌ ্ ৗ", + 3: "\u200c \u200d ৸ ৹ ৲ ৳ ৰ ৱ ৴ ৵ ৶ ৷", + 4: "৳", + }, + "bo": { + 0: "ཾ ཿ ཀ ཀྵ ྐ ྐྵ ཁ ྑ ག གྷ ྒ ྒྷ ང ྔ ཅ ྕ ཆ ྖ ཇ ྗ ཉ ྙ ཊ ྚ ཋ ྛ ཌ ཌྷ ྜ ྜྷ ཎ ྞ ཏ ྟ ཐ ྠ ད དྷ ྡ ྡྷ ན ྣ པ ྤ ཕ ྥ བ བྷ ྦ ྦྷ མ ྨ ཙ ྩ ཚ ྪ ཛ ཛྷ ྫ ྫྷ ཝ ྭ ྺ ཞ ྮ ཟ ྯ འ ྰ ཡ ྱ ྻ ར ཪ ྲ ྼ ལ ླ ཤ ྴ ཥ ྵ ས ྶ ཧ ྷ ཨ ྸ ི ཱི ྀ ཱྀ ུ ཱུ ྲྀ ཷ ླྀ ཹ ཹ ེ ཻ ོ ཽ ྄", + 3: "ༀ", + }, + "br": { + 0: "a b ch cʼh d e ê f g h i j k l m n ñ o p r s t u ù v w x y z", + 3: "á à ă â å ä ã ā æ c ç é è ĕ ë ē í ì ĭ î ï ī ó ò ŏ ô ö ø ō œ q ú ŭ û ü ū ÿ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P R S T U V W X Y Z", + }, + "brx": { + 0: "़ ँ ं अ आ इ ई उ ऊ ऍ ए ऐ ऑ ओ औ क ख ग घ च छ ज झ ञ ट ठ ड ड़ ढ ण त थ द ध न प फ ब भ म य र ल ळ व श ष स ह ा ि ी ु ू ृ ॅ े ै ॉ ो ौ ्", + 3: "\u200c \u200d", + 5: "अ आ इ ई उ ऊ ऍ ए ऐ ऑ ओ औ क ख ग घ च छ ज झ ञ ट ठ ड ड़ ढ ण त थ द ध न प फ ब भ म य र ल ळ व श ष स ह", + }, + "bs": { + 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž", + 3: "q w x y", + }, + "byn": { + 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ረ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቊ ቋ ቌ ቍ ቐ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዂ ዃ ዄ ዅ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ደ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ ጘ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጸ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፈ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ", + }, + "ca": { + 0: "a à b c ç d e é è f g h i í ï j k l ŀ m n o ó ò p q r s t u ú ü v w x y z", + 3: "á ă â å ä ã ā æ ĕ ê ë ē ì ĭ î ī ñ º ŏ ô ö ø ō œ ù ŭ û ū ÿ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "cgg": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "chr": { + 0: "Ꭰ Ꭱ Ꭲ Ꭳ Ꭴ Ꭵ Ꭶ Ꭷ Ꭸ Ꭹ Ꭺ Ꭻ Ꭼ Ꭽ Ꭾ Ꭿ Ꮀ Ꮁ Ꮂ Ꮃ Ꮄ Ꮅ Ꮆ Ꮇ Ꮈ Ꮉ Ꮊ Ꮋ Ꮌ Ꮍ Ꮎ Ꮏ Ꮐ Ꮑ Ꮒ Ꮓ Ꮔ Ꮕ Ꮖ Ꮗ Ꮘ Ꮙ Ꮚ Ꮛ Ꮜ Ꮝ Ꮞ Ꮟ Ꮠ Ꮡ Ꮢ Ꮣ Ꮤ Ꮥ Ꮦ Ꮧ Ꮨ Ꮩ Ꮪ Ꮫ Ꮬ Ꮭ Ꮮ Ꮯ Ꮰ Ꮱ Ꮲ Ꮳ Ꮴ Ꮵ Ꮶ Ꮷ Ꮸ Ꮹ Ꮺ Ꮻ Ꮼ Ꮽ Ꮾ Ꮿ Ᏸ Ᏹ Ᏺ Ᏻ Ᏼ", + 5: "Ꭰ Ꭶ Ꭽ Ꮃ Ꮉ Ꮎ Ꮖ Ꮜ Ꮣ Ꮬ Ꮳ Ꮹ Ꮿ", + }, + "cs": { + 0: "a á b c č d ď e é ě f g h ch i í j k l m n ň o ó p q r ř s š t ť u ú ů v w x y ý z ž", + }, + "cy": { + 0: "a á à â ä b c ch d dd e é è ê ë f ff g ng h i í ì î ï l ll m n o ó ò ô ö p ph r rh s t th u ú ù û ü w ẃ ẁ ŵ ẅ y ý ỳ ŷ ÿ", + 3: "j k q v x z", + }, + "da": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z æ ø å", + 2: "- ‐ – , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ′ ″ §", + 3: "á é è ê ë ü ä ö", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Æ Ø Å", + }, + "dav": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "de": { + 0: "a ä b c d e f g h i j k l m n o ö p q r s ß t u ü v w x y z", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ‚ \" “ „ « » ( ) [ ] { } @ * / & # §", + 3: "á à ă â å ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ ú ù ŭ û ū ÿ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "dje": { + 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž", + 3: "v", + 5: "A B C D E F G H I J K L M N Ɲ Ŋ O P Q R S T U W X Y Z", + }, + "dua": { + 0: "a á b ɓ c d ɗ e é ɛ ɛ́ f g i í j k l m n ny ŋ o ó ɔ ɔ́ p r s t u ú ū w y", + 3: "h q v x z", + 5: "A B Ɓ C D Ɗ E Ɛ F G I J K L M N Ŋ O Ɔ P S T U W Y", + }, + "dyo": { + 0: "a á b c d e é f g h i í j k l m n ñ ŋ o ó p q r s t u ú v w x y", + 3: "z", + 5: "A B C D E F G H I J K L M N Ñ Ŋ O P Q R S T U V W X Y", + }, + "dz": { + 0: "ཀ ྐ ཁ ྑ ག ྒ ང ྔ ཅ ཆ ཇ ྗ ཉ ྙ ཏ ྟ ཐ ད ྡ ན ྣ པ ྤ ཕ བ ྦ མ ྨ ཙ ྩ ཚ ཛ ྫ ཝ ྭ ཞ ཟ འ ཡ ྱ ར ྲ ལ ླ ཤ ྵ ས ཧ ྷ ཨ ི ུ ེ ོ", + 3: "ཊ ཋ ཌ ཎ ཥ", + }, + "ebu": { + 0: "a b c d e f g h i ĩ j k l m n o p q r s t u ũ v w x y z", + 5: "A B C D E F G H I Ĩ J K L M N O P Q R S T U Ũ V W X Y Z", + }, + "ee": { + 0: "a á à ã b d ɖ e é è ẽ ɛ ɛ́ ɛ̀ ɛ̃ f ƒ g ɣ h i í ì ĩ k l m n ŋ o ó ò õ ɔ ɔ́ ɔ̀ ɔ̃ p r s t u ú ù ũ v ʋ w x y z", + 3: "c j q", + 5: "A B C D Ɖ E Ɛ F Ƒ G Ɣ H I J K L M N Ŋ O Ɔ P Q R S T U V Ʋ W X Y Z", + }, + "el": { + 0: "α ά β γ δ ε έ ζ η ή θ ι ί ϊ ΐ κ λ μ ν ξ ο ό π ρ σ ς τ υ ύ ϋ ΰ φ χ ψ ω ώ", + 2: "- ‐ – — , ; : ! . … \" ( ) [ ] @ * / \\ & §", + 4: "α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω", + 5: "Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω", + }, + "el_POLYTON": { + 0: "α ἀ ἄ ἂ ἆ ἁ ἅ ἃ ἇ ά ὰ ᾶ β γ δ ε ἐ ἔ ἒ ἑ ἕ ἓ έ ὲ ζ η ἠ ἤ ἢ ἦ ἡ ἥ ἣ ἧ ή ὴ ῆ θ ι ἰ ἴ ἲ ἶ ἱ ἵ ἳ ἷ ί ὶ ῖ ϊ ΐ ῒ ῗ κ λ μ ν ξ ο ὄ ὂ ὃ ό ὸ π ρ σ ς τ υ ὐ ὔ ὒ ὖ ὑ ὕ ὓ ὗ ύ ὺ ῦ ϋ ΰ ῢ ῧ φ χ ψ ω ὤ ὢ ὦ ὥ ὣ ὧ ώ ὼ ῶ", + }, + "en": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §", + 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "en_Dsrt": { + 0: "𐐨 𐐩 𐐪 𐐫 𐐬 𐐭 𐐮 𐐯 𐐰 𐐱 𐐲 𐐳 𐐴 𐐵 𐐶 𐐷 𐐸 𐐹 𐐺 𐐻 𐐼 𐐽 𐐾 𐐿 𐑀 𐑁 𐑂 𐑃 𐑄 𐑅 𐑆 𐑇 𐑈 𐑉 𐑊 𐑋 𐑌 𐑍 𐑎 𐑏", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "en_GB": { + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "en_Shaw": { + 0: "𐑐 𐑑 𐑒 𐑓 𐑔 𐑕 𐑖 𐑗 𐑘 𐑙 𐑚 𐑛 𐑜 𐑝 𐑞 𐑟 𐑠 𐑡 𐑢 𐑣 𐑤 𐑥 𐑦 𐑧 𐑨 𐑩 𐑪 𐑫 𐑬 𐑭 𐑮 𐑯 𐑰 𐑱 𐑲 𐑳 𐑴 𐑵 𐑶 𐑷 𐑸 𐑹 𐑺 𐑻 𐑼 𐑽 𐑾 𐑿", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "eo": { + 0: "a b c ĉ d e f g ĝ h ĥ i j ĵ k l m n o p r s ŝ t u ŭ v z", + 3: "q w x y", + 5: "A B C Ĉ D E F G Ĝ H Ĥ I J Ĵ K L M N O P R S Ŝ T U Ŭ V Z", + }, + "es": { + 0: "a á b c d e é f g h i í j k l m n ñ o ó p q r s t u ú ü v w x y z", + 2: "- ‐ – — , ; : ! ¡ ? ¿ . … ' ‘ ’ \" “ ” « » ( ) [ ] @ * / \\ & # † ‡ ′ ″ §", + 3: "à ă â å ä ã ā æ ç è ĕ ê ë ē ì ĭ î ï ī º ò ŏ ô ö ø ō œ ù ŭ û ū ÿ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N Ñ O P Q R S T U V W X Y Z", + }, + "et": { + 0: "a b c d e f g h i j k l m n o p q r s š z ž t u v w õ ä ö ü x y", + 3: "á à â å ā æ ç é è ê ë ē í ì î ï ī ñ ó ò ŏ ô ø ō œ ú ù û ū", + 4: "a b c d e f g h i j k l m n o p q r s š z ž t u v w õ ä ö ü x y", + 5: "A B C D E F G H I J K L M N O P Q R S Š Z Ž T U V Õ Ä Ö Ü X Y", + }, + "eu": { + 0: "a b c ç d e f g h i j k l m n ñ o p q r s t u v w x y z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ewo": { + 0: "a á à â ǎ b d dz e é è ê ě ǝ ǝ́ ǝ̀ ǝ̂ ǝ̌ ɛ ɛ́ ɛ̀ ɛ̂ ɛ̌ f g h i í ì î ǐ k kp l m n ń ǹ ng nk ŋ o ó ò ô ǒ ɔ ɔ́ ɔ̀ ɔ̂ ɔ̌ p r s t ts u ú ù û ǔ v w y z", + 3: "c j q x", + 5: "A B D E Ǝ Ɛ F G H I K L M N Ŋ O Ɔ P R S T U V W Y Z", + }, + "fa": { + 0: "ً ٍ ٌ ّ ٔ آ ا ء أ ؤ ئ ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ة ی", + 2: "- ‐ ، ٫ ٬ ؛ : ! ؟ . … « » ( ) [ ] * / \\", + 3: "\u200c \u200d \u200e \u200f َ ِ ُ ْ ٖ ٰ ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹", + 4: "﷼ a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "آ ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی", + }, + "fa_AF": { + 3: "ٖ ٰ \u200c \u200d ټ ځ څ ډ ړ ږ ښ ګ ڼ ي", + }, + "ff": { + 0: "a b ɓ c d ɗ e f g h i j k l m n ñ ŋ o p r s t u w y ƴ", + 3: "q v x z", + 5: "A B Ɓ C D Ɗ E F G H I J K L M N Ñ Ŋ O P R S T U W Y Ƴ", + }, + "fi": { + 0: "a b c d e f g h i j k l m n o p q r s š t u v w x y z ž å ä ö", + 3: "á à â ã č ç đ é è ë ǧ ǥ ȟ í ï ǩ ń ñ ŋ ô õ œ ř ŧ ú ü ʒ ǯ æ ø", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Å Ä Ö", + }, + "fil": { + 0: "a b c d e f g h i j k l m n ñ ng o p q r s t u v w x y z", + 3: "á à â é è ê í ì î ó ò ô ú ù û", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "fo": { + 0: "a á b d ð e f g h i í j k l m n o ó p r s t u ú v x y ý æ ø", + 3: "c q w z", + }, + "fr": { + 0: "a à â æ b c ç d e é è ê ë f g h i î ï j k l m n o ô œ p q r s t u ù û ü v w x y ÿ z", + 2: "- ‐ – — , ; : ! ? . … ’ « » ( ) [ ] @ * / & # † ‡ §", + 3: "á å ä ã ā ē í ì ī ñ ó ò ö ø ú ǔ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "fur": { + 0: "a à â b c ç d e è ê f g h i ì î j k l m n o ò ô p q r s t u ù û v w x y z", + 3: "å č é ë ğ ï ñ ó š ü", + }, + "ga": { + 0: "a á b c d e é f g h i í l m n o ó p r s t u ú", + 3: "ḃ ċ ḋ ḟ ġ j k ṁ ṗ q ṡ ṫ v w x y z", + }, + "gl": { + 0: "a á b c d e é f g h i í j k l m n ñ o ó p q r s t u ú ü v w x y z", + 5: "A B C D E F G H I J K L M N Ñ O P Q R S T U V W X Y Z", + }, + "gsw": { + 0: "a ä b c d e f g h i j k l m n o ö p q r s t u ü v w x y z", + 3: "á à ă â å ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ ú ù ŭ û ū ÿ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "gu": { + 0: "઼ ૐ ં ઁ ઃ અ આ ઇ ઈ ઉ ઊ ઋ ૠ ઍ એ ઐ ઑ ઓ ઔ ક ખ ગ ઘ ઙ ચ છ જ ઝ ઞ ટ ઠ ડ ઢ ણ ત થ દ ધ ન પ ફ બ ભ મ ય ર લ વ શ ષ સ હ ળ ઽ ા િ ી ુ ૂ ૃ ૄ ૅ ે ૈ ૉ ો ૌ ્", + 3: "\u200c \u200d", + 4: "ર ૂ", + 5: "અ આ ઇ ઈ ઉ ઊ ઋ એ ઐ ઓ ઔ ક ખ ગ ઘ ઙ ચ છ જ ઝ ઞ ટ ઠ ડ ઢ ણ ત થ દ ધ ન પ ફ બ ભ મ ય ર લ વ શ ષ સ હ ળ", + }, + "guz": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "gv": { + 0: "a b c ç d e f g h i j k l m n o p q r s t u v w x y z", + }, + "ha": { + 0: "a b ɓ c d ɗ e f g h i j k ƙ l m n o r s sh t ts u w y ʼy z ʼ", + 3: "á à â é è ê í ì î ó ò ô p q r̃ ú ù û v x ƴ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "haw": { + 0: "a ā e ē i ī o ō u ū h k l m n p w ʻ", + 3: "b c d f g j q r s t v x y z", + }, + "he": { + 0: "א ב ג ד ה ו ז ח ט י כ ך ל מ ם נ ן ס ע פ ף צ ץ ק ר ש ת", + 3: "ֽ ׄ \u200e \u200f ְ ֱ ֲ ֳ ִ ֵ ֶ ַ ָ ֹ ֻ ׂ ׁ ּ ֿ ־ ׳ ״", + 5: "א ב ג ד ה ו ז ח ט י כ ל מ נ ס ע פ צ ק ר ש ת", + }, + "hi": { + 0: "़ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल ळ व श ष स ह ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्", + 3: "\u200c \u200d", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + }, + "hr": { + 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž", + 3: "q w x y", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C Č Ć D DŽ Đ E F G H I J K L LJ M N NJ O P Q R S Š T U V W X Y Z Ž", + }, + "hu": { + 0: "a á b c cs ccs d dz ddz dzs ddzs e é f g gy ggy h i í j k l ly lly m n ny nny o ó ö ő p r s sz ssz t ty tty u ú ü ű v z zs zzs", + 2: "- – , ; : ! ? . … ' ’ \" ” „ « » ( ) [ ] { } 〈 〉 @ * / & # ⸓ § ~", + 3: "à ă â å ä ã ā æ ç è ĕ ê ë ē ì ĭ î ï ī ñ ò ŏ ô ø ō œ q ù ŭ û ū w x y ÿ", + 5: "A Á B C CS D DZ DZS E É F G GY H I Í J K L LY M N NY O Ó Ö Ő P Q R S SZ T TY U Ú Ü Ű V W X Y Z ZS", + }, + "hy": { + 0: "֊ ՝ ՜ ՞ ՚ ՛ ՟ ա բ գ դ ե զ է ը թ ժ ի լ խ ծ կ հ ձ ղ ճ մ յ ն շ ո չ պ ջ ռ ս վ տ ր ց ւ փ ք և օ ֆ", + }, + "ia": { + 0: "a b c ch d e f g h i j k l m n o p ph q r s t u v w x y z", + }, + "id": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ig": { + 0: "a b ch d e ẹ f g gb gh gw h i ị j k kp kw l m n ṅ nw ny o ọ p r s sh t u ụ v w y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ii": { + 0: "ꀀ ꀀ ꀁ ꀂ ꀃ ꀄ ꀅ ꀆ ꀇ ꀈ ꀉ ꀊ ꀋ ꀌ ꀍ ꀎ ꀏ ꀐ ꀑ ꀒ ꀓ ꀔ ꀕ ꀖ ꀗ ꀘ ꀙ ꀚ ꀛ ꀜ ꀝ ꀞ ꀟ ꀠ ꀡ ꀢ ꀣ ꀤ ꀥ ꀦ ꀧ ꀨ ꀩ ꀪ ꀫ ꀬ ꀭ ꀮ ꀯ ꀰ ꀱ ꀲ ꀳ ꀴ ꀵ ꀶ ꀷ ꀸ ꀹ ꀺ ꀻ ꀼ ꀽ ꀾ ꀿ ꁀ ꁁ ꁂ ꁃ ꁄ ꁅ ꁆ ꁇ ꁈ ꁉ ꁊ ꁋ ꁌ ꁍ ꁎ ꁏ ꁐ ꁑ ꁒ ꁓ ꁔ ꁕ ꁖ ꁗ ꁘ ꁙ ꁚ ꁛ ꁜ ꁝ ꁞ ꁟ ꁠ ꁡ ꁢ ꁣ ꁤ ꁥ ꁦ ꁧ ꁨ ꁩ ꁪ ꁫ ꁬ ꁭ ꁮ ꁯ ꁰ ꁱ ꁲ ꁳ ꁴ ꁵ ꁶ ꁷ ꁸ ꁹ ꁺ ꁻ ꁼ ꁽ ꁾ ꁿ ꂀ ꂁ ꂂ ꂃ ꂄ ꂅ ꂆ ꂇ ꂈ ꂉ ꂊ ꂋ ꂌ ꂍ ꂎ ꂏ ꂐ ꂑ ꂒ ꂓ ꂔ ꂕ ꂖ ꂗ ꂘ ꂙ ꂚ ꂛ ꂜ ꂝ ꂞ ꂟ ꂠ ꂡ ꂢ ꂣ ꂤ ꂥ ꂦ ꂧ ꂨ ꂩ ꂪ ꂫ ꂬ ꂭ ꂮ ꂯ ꂰ ꂱ ꂲ ꂳ ꂴ ꂵ ꂶ ꂷ ꂸ ꂹ ꂺ ꂻ ꂼ ꂽ ꂾ ꂿ ꃀ ꃁ ꃂ ꃃ ꃄ ꃅ ꃆ ꃇ ꃈ ꃉ ꃊ ꃋ ꃌ ꃍ ꃎ ꃏ ꃐ ꃑ ꃒ ꃓ ꃔ ꃕ ꃖ ꃗ ꃘ ꃙ ꃚ ꃛ ꃜ ꃝ ꃞ ꃟ ꃠ ꃡ ꃢ ꃣ ꃤ ꃥ ꃦ ꃧ ꃨ ꃩ ꃪ ꃫ ꃬ ꃭ ꃮ ꃯ ꃰ ꃱ ꃲ ꃳ ꃴ ꃵ ꃶ ꃷ ꃸ ꃹ ꃺ ꃻ ꃼ ꃽ ꃾ ꃿ ꄀ ꄁ ꄂ ꄃ ꄄ ꄅ ꄆ ꄇ ꄈ ꄉ ꄊ ꄋ ꄌ ꄍ ꄎ ꄏ ꄐ ꄑ ꄒ ꄓ ꄔ ꄕ ꄖ ꄗ ꄘ ꄙ ꄚ ꄛ ꄜ ꄝ ꄞ ꄟ ꄠ ꄡ ꄢ ꄣ ꄤ ꄥ ꄦ ꄧ ꄨ ꄩ ꄪ ꄫ ꄬ ꄭ ꄮ ꄯ ꄰ ꄱ ꄲ ꄳ ꄴ ꄵ ꄶ ꄷ ꄸ ꄹ ꄺ ꄻ ꄼ ꄽ ꄾ ꄿ ꅀ ꅁ ꅂ ꅃ ꅄ ꅅ ꅆ ꅇ ꅈ ꅉ ꅊ ꅋ ꅌ ꅍ ꅎ ꅏ ꅐ ꅑ ꅒ ꅓ ꅔ ꅕ ꅖ ꅗ ꅘ ꅙ ꅚ ꅛ ꅜ ꅝ ꅞ ꅟ ꅠ ꅡ ꅢ ꅣ ꅤ ꅥ ꅦ ꅧ ꅨ ꅩ ꅪ ꅫ ꅬ ꅭ ꅮ ꅯ ꅰ ꅱ ꅲ ꅳ ꅴ ꅵ ꅶ ꅷ ꅸ ꅹ ꅺ ꅻ ꅼ ꅽ ꅾ ꅿ ꆀ ꆁ ꆂ ꆃ ꆄ ꆅ ꆆ ꆇ ꆈ ꆉ ꆊ ꆋ ꆌ ꆍ ꆎ ꆏ ꆐ ꆑ ꆒ ꆓ ꆔ ꆕ ꆖ ꆗ ꆘ ꆙ ꆚ ꆛ ꆜ ꆝ ꆞ ꆟ ꆠ ꆡ ꆢ ꆣ ꆤ ꆥ ꆦ ꆧ ꆨ ꆩ ꆪ ꆫ ꆬ ꆭ ꆮ ꆯ ꆰ ꆱ ꆲ ꆳ ꆴ ꆵ ꆶ ꆷ ꆸ ꆹ ꆺ ꆻ ꆼ ꆽ ꆾ ꆿ ꇀ ꇁ ꇂ ꇃ ꇄ ꇅ ꇆ ꇇ ꇈ ꇉ ꇊ ꇋ ꇌ ꇍ ꇎ ꇏ ꇐ ꇑ ꇒ ꇓ ꇔ ꇕ ꇖ ꇗ ꇘ ꇙ ꇚ ꇛ ꇜ ꇝ ꇞ ꇟ ꇠ ꇡ ꇢ ꇣ ꇤ ꇥ ꇦ ꇧ ꇨ ꇩ ꇪ ꇫ ꇬ ꇭ ꇮ ꇯ ꇰ ꇱ ꇲ ꇳ ꇴ ꇵ ꇶ ꇷ ꇸ ꇹ ꇺ ꇻ ꇼ ꇽ ꇾ ꇿ ꈀ ꈁ ꈂ ꈃ ꈄ ꈅ ꈆ ꈇ ꈈ ꈉ ꈊ ꈋ ꈌ ꈍ ꈎ ꈏ ꈐ ꈑ ꈒ ꈓ ꈔ ꈕ ꈖ ꈗ ꈘ ꈙ ꈚ ꈛ ꈜ ꈝ ꈞ ꈟ ꈠ ꈡ ꈢ ꈣ ꈤ ꈥ ꈦ ꈧ ꈨ ꈩ ꈪ ꈫ ꈬ ꈭ ꈮ ꈯ ꈰ ꈱ ꈲ ꈳ ꈴ ꈵ ꈶ ꈷ ꈸ ꈹ ꈺ ꈻ ꈼ ꈽ ꈾ ꈿ ꉀ ꉁ ꉂ ꉃ ꉄ ꉅ ꉆ ꉇ ꉈ ꉉ ꉊ ꉋ ꉌ ꉍ ꉎ ꉏ ꉐ ꉑ ꉒ ꉓ ꉔ ꉕ ꉖ ꉗ ꉘ ꉙ ꉚ ꉛ ꉜ ꉝ ꉞ ꉟ ꉠ ꉡ ꉢ ꉣ ꉤ ꉥ ꉦ ꉧ ꉨ ꉩ ꉪ ꉫ ꉬ ꉭ ꉮ ꉯ ꉰ ꉱ ꉲ ꉳ ꉴ ꉵ ꉶ ꉷ ꉸ ꉹ ꉺ ꉻ ꉼ ꉽ ꉾ ꉿ ꊀ ꊁ ꊂ ꊃ ꊄ ꊅ ꊆ ꊇ ꊈ ꊉ ꊊ ꊋ ꊌ ꊍ ꊎ ꊏ ꊐ ꊑ ꊒ ꊓ ꊔ ꊕ ꊖ ꊗ ꊘ ꊙ ꊚ ꊛ ꊜ ꊝ ꊞ ꊟ ꊠ ꊡ ꊢ ꊣ ꊤ ꊥ ꊦ ꊧ ꊨ ꊩ ꊪ ꊫ ꊬ ꊭ ꊮ ꊯ ꊰ ꊱ ꊲ ꊳ ꊴ ꊵ ꊶ ꊷ ꊸ ꊹ ꊺ ꊻ ꊼ ꊽ ꊾ ꊿ ꋀ ꋁ ꋂ ꋃ ꋄ ꋅ ꋆ ꋇ ꋈ ꋉ ꋊ ꋋ ꋌ ꋍ ꋎ ꋏ ꋐ ꋑ ꋒ ꋓ ꋔ ꋕ ꋖ ꋗ ꋘ ꋙ ꋚ ꋛ ꋜ ꋝ ꋞ ꋟ ꋠ ꋡ ꋢ ꋣ ꋤ ꋥ ꋦ ꋧ ꋨ ꋩ ꋪ ꋫ ꋬ ꋭ ꋮ ꋯ ꋰ ꋱ ꋲ ꋳ ꋴ ꋵ ꋶ ꋷ ꋸ ꋹ ꋺ ꋻ ꋼ ꋽ ꋾ ꋿ ꌀ ꌁ ꌂ ꌃ ꌄ ꌅ ꌆ ꌇ ꌈ ꌉ ꌊ ꌋ ꌌ ꌍ ꌎ ꌏ ꌐ ꌑ ꌒ ꌓ ꌔ ꌕ ꌖ ꌗ ꌘ ꌙ ꌚ ꌛ ꌜ ꌝ ꌞ ꌟ ꌠ ꌡ ꌢ ꌣ ꌤ ꌥ ꌦ ꌧ ꌨ ꌩ ꌪ ꌫ ꌬ ꌭ ꌮ ꌯ ꌰ ꌱ ꌲ ꌳ ꌴ ꌵ ꌶ ꌷ ꌸ ꌹ ꌺ ꌻ ꌼ ꌽ ꌾ ꌿ ꍀ ꍁ ꍂ ꍃ ꍄ ꍅ ꍆ ꍇ ꍈ ꍉ ꍊ ꍋ ꍌ ꍍ ꍎ ꍏ ꍐ ꍑ ꍒ ꍓ ꍔ ꍕ ꍖ ꍗ ꍘ ꍙ ꍚ ꍛ ꍜ ꍝ ꍞ ꍟ ꍠ ꍡ ꍢ ꍣ ꍤ ꍥ ꍦ ꍧ ꍨ ꍩ ꍪ ꍫ ꍬ ꍭ ꍮ ꍯ ꍰ ꍱ ꍲ ꍳ ꍴ ꍵ ꍶ ꍷ ꍸ ꍹ ꍺ ꍻ ꍼ ꍽ ꍾ ꍿ ꎀ ꎁ ꎂ ꎃ ꎄ ꎅ ꎆ ꎇ ꎈ ꎉ ꎊ ꎋ ꎌ ꎍ ꎎ ꎏ ꎐ ꎑ ꎒ ꎓ ꎔ ꎕ ꎖ ꎗ ꎘ ꎙ ꎚ ꎛ ꎜ ꎝ ꎞ ꎟ ꎠ ꎡ ꎢ ꎣ ꎤ ꎥ ꎦ ꎧ ꎨ ꎩ ꎪ ꎫ ꎬ ꎭ ꎮ ꎯ ꎰ ꎱ ꎲ ꎳ ꎴ ꎵ ꎶ ꎷ ꎸ ꎹ ꎺ ꎻ ꎼ ꎽ ꎾ ꎿ ꏀ ꏁ ꏂ ꏃ ꏄ ꏅ ꏆ ꏇ ꏈ ꏉ ꏊ ꏋ ꏌ ꏍ ꏎ ꏏ ꏐ ꏑ ꏒ ꏓ ꏔ ꏕ ꏖ ꏗ ꏘ ꏙ ꏚ ꏛ ꏜ ꏝ ꏞ ꏟ ꏠ ꏡ ꏢ ꏣ ꏤ ꏥ ꏦ ꏧ ꏨ ꏩ ꏪ ꏫ ꏬ ꏭ ꏮ ꏯ ꏰ ꏱ ꏲ ꏳ ꏴ ꏵ ꏶ ꏷ ꏸ ꏹ ꏺ ꏻ ꏼ ꏽ ꏾ ꏿ ꐀ ꐁ ꐂ ꐃ ꐄ ꐅ ꐆ ꐇ ꐈ ꐉ ꐊ ꐋ ꐌ ꐍ ꐎ ꐏ ꐐ ꐑ ꐒ ꐓ ꐔ ꐕ ꐖ ꐗ ꐘ ꐙ ꐚ ꐛ ꐜ ꐝ ꐞ ꐟ ꐠ ꐡ ꐢ ꐣ ꐤ ꐥ ꐦ ꐧ ꐨ ꐩ ꐪ ꐫ ꐬ ꐭ ꐮ ꐯ ꐰ ꐱ ꐲ ꐳ ꐴ ꐵ ꐶ ꐷ ꐸ ꐹ ꐺ ꐻ ꐼ ꐽ ꐾ ꐿ ꑀ ꑁ ꑂ ꑃ ꑄ ꑅ ꑆ ꑇ ꑈ ꑉ ꑊ ꑋ ꑌ ꑍ ꑎ ꑏ ꑐ ꑑ ꑒ ꑓ ꑔ ꑕ ꑖ ꑗ ꑘ ꑙ ꑚ ꑛ ꑜ ꑝ ꑞ ꑟ ꑠ ꑡ ꑢ ꑣ ꑤ ꑥ ꑦ ꑧ ꑨ ꑩ ꑪ ꑫ ꑬ ꑭ ꑮ ꑯ ꑰ ꑱ ꑲ ꑳ ꑴ ꑵ ꑶ ꑷ ꑸ ꑹ ꑺ ꑻ ꑼ ꑽ ꑾ ꑿ ꒀ ꒁ ꒂ ꒃ ꒄ ꒅ ꒆ ꒇ ꒈ ꒉ ꒊ ꒋ ꒌ", + }, + "is": { + 0: "a á b d ð e é f g h i í j k l m n o ó p r s t u ú v y ý þ æ ö", + 3: "c q w x z", + }, + "it": { + 0: "a à b c d e é è f g h i ì j k l m n o ó ò p q r s t u ù v w x y z", + 2: "- — , ; : ! ? . … “ ” ( ) [ ] { } @ /", + 3: "í ï ú", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ja": { + 0: "ゞ ゝ ヽ ヾ ぁ ァ あ ア ぃ ィ い イ ぅ ゥ う ウ ヴ ぇ ェ え エ ぉ ォ お オ ヵ か カ が ガ き キ ぎ ギ く ク ぐ グ ヶ け ケ げ ゲ こ コ ご ゴ さ サ ざ ザ し シ じ ジ す ス ず ズ せ セ ぜ ゼ そ ソ ぞ ゾ た タ だ ダ ち チ ぢ ヂ っ ッ つ ツ づ ヅ て テ で デ と ト ど ド な ナ に ニ ぬ ヌ ね ネ の ノ は ハ ば バ ぱ パ ひ ヒ び ビ ぴ ピ ふ フ ぶ ブ ぷ プ へ ヘ べ ベ ぺ ペ ほ ホ ぼ ボ ぽ ポ ま マ み ミ む ム め メ も モ ゃ ャ や ヤ ゅ ュ ゆ ユ ょ ョ よ ヨ ら ラ り リ る ル れ レ ろ ロ ゎ ヮ わ ワ ゐ ヰ ゑ ヱ を ヲ ん ン 一 丁 七 万 万 丈 三 上 下 不 与 且 世 丘 丙 両 並 中 丸 丹 主 久 乏 乗 乙 九 乱 乳 乾 亀 了 予 争 事 二 互 五 井 亜 亡 交 亨 享 享 京 亭 人 仁 今 介 仏 仕 他 付 仙 代 代 令 以 仮 仰 仲 件 任 企 伏 伏 伐 休 会 伝 伯 伴 伸 伺 似 但 位 位 低 住 佐 体 何 余 作 佳 併 使 例 侍 供 依 価 侮 侯 侵 便 係 促 俊 俗 保 信 修 俳 俵 俸 倉 個 倍 倒 候 借 倣 値 倫 倹 偉 偏 停 健 側 側 偵 偶 偽 傍 傑 傘 備 催 債 傷 傾 働 像 僕 僚 僧 儀 億 儒 償 優 元 元 兄 充 兆 先 光 克 免 児 党 入 全 八 八 公 六 共 兵 具 典 兼 内 円 冊 再 冒 冗 写 冠 冬 冷 准 凍 凝 凡 処 凶 凸 凸 凹 出 刀 刃 分 分 切 刈 刊 刑 列 初 判 別 利 到 制 制 刷 券 刺 刻 則 削 前 剖 剛 剣 剤 副 剰 割 創 劇 力 功 加 劣 助 努 励 労 効 劾 勅 勇 勉 動 勘 務 勝 募 勢 勤 勧 勲 勺 匁 包 化 北 匠 匹 匹 区 医 匿 十 千 升 午 半 卑 卑 卒 卓 協 南 単 博 占 印 危 即 即 却 卵 卸 厄 厘 厚 原 厳 去 参 又 及 及 友 双 反 収 叔 取 受 叙 口 口 古 句 叫 召 可 台 史 右 号 司 各 合 吉 同 同 名 后 吏 吐 向 君 吟 否 含 吸 吹 呈 呈 呉 告 周 味 呼 命 和 咲 哀 品 員 哲 唆 唇 唐 唯 唱 商 問 啓 善 喚 喜 喝 喪 喫 営 嗣 嘆 嘉 嘱 器 噴 嚇 囚 四 回 因 団 困 囲 図 固 国 圏 園 土 圧 在 地 坂 均 坊 坑 坪 垂 型 垣 埋 城 域 執 培 基 堀 堂 堅 堕 堤 堪 報 場 塀 塁 塊 塑 塔 塗 塚 塩 塾 境 墓 増 墜 墨 墳 墾 壁 壇 壊 壌 士 壮 声 声 壱 売 変 夏 夕 外 多 夜 夢 大 天 天 太 夫 央 失 奇 奉 奏 契 奔 奥 奨 奪 奮 女 奴 好 如 如 妃 妄 妊 妙 妥 妨 妹 妻 姉 始 姓 委 姫 姻 姿 威 娘 娠 娯 婆 婚 婦 婿 媒 嫁 嫌 嫡 嬢 子 孔 字 存 孝 季 孤 学 孫 宅 宇 宇 守 安 完 宗 宗 官 宙 定 宜 宝 実 客 客 宣 室 宮 宰 害 害 宴 宵 家 容 宿 寂 寄 密 富 寒 寛 寝 察 寡 寧 審 寮 寸 寺 対 寿 封 専 射 将 尉 尉 尊 尋 導 小 少 尚 就 尺 尼 尼 尽 尾 尿 局 居 屈 届 屋 展 属 層 履 屯 山 岐 岩 岬 岳 岸 峠 峡 峰 島 崇 崎 崩 川 州 巡 巣 工 工 左 巧 巨 差 己 巻 市 布 帆 希 帝 帥 師 席 帯 帰 帳 常 帽 幅 幕 幣 干 干 平 年 幸 幹 幻 幻 幼 幽 幾 庁 広 床 序 底 店 府 度 座 庫 庭 庶 庶 康 庸 廃 廉 廊 延 廷 建 弁 弊 式 弐 弓 弓 弔 引 弘 弟 弦 弧 弱 張 強 弾 当 形 彩 彫 彰 影 役 彼 往 征 径 待 律 後 徐 徒 従 得 御 復 循 微 徳 徴 徹 心 必 忌 忍 志 志 忘 忙 応 忠 快 念 怒 怖 思 怠 急 性 怪 恋 恐 恒 恥 恨 恩 恭 息 恵 悔 悟 悠 患 悦 悩 悪 悲 悼 情 惑 惜 惨 惰 想 愁 愉 意 愚 愛 感 慈 態 慌 慎 慕 慢 慣 慨 慮 慰 慶 憂 憎 憤 憩 憲 憶 憾 懇 懐 懲 懸 成 成 我 戒 戦 戯 戸 戻 房 所 扇 扉 手 才 打 払 扱 扶 批 承 技 抄 把 抑 投 抗 折 抜 択 披 抱 抵 抹 押 抽 担 拍 拐 拒 拓 拘 拙 招 拝 拠 拡 括 拷 拾 持 指 挑 挙 挟 振 挿 捕 捜 捨 据 掃 授 掌 排 掘 掛 採 探 接 控 推 措 掲 描 提 揚 換 握 揮 援 揺 損 搬 搭 携 搾 摂 摘 摩 撃 撤 撮 撲 擁 操 擦 擬 支 改 攻 放 政 故 敏 救 敗 教 敢 散 敬 数 整 敵 敷 文 斉 斎 斗 料 斜 斤 斥 断 新 方 施 旅 旋 族 旗 既 日 旧 旧 旨 早 旬 昆 昇 昌 明 易 昔 星 映 春 昨 昭 是 昼 時 晩 普 景 晴 晶 暁 暇 暑 暖 暗 暦 暫 暮 暴 曇 曜 曲 更 書 曹 替 最 月 有 服 朕 朗 望 朝 期 木 未 未 末 本 札 朱 朴 机 朽 杉 材 村 束 条 来 杯 東 松 板 析 林 枚 果 枝 枠 枢 枯 架 柄 某 染 柔 柱 柳 査 栄 栓 校 株 核 根 格 栽 桃 案 桑 桜 桟 梅 械 棄 棋 棒 棚 棟 森 棺 植 検 業 極 楼 楽 概 構 様 槽 標 模 権 横 樹 橋 機 欄 欠 次 欧 欲 欺 款 歌 歓 止 正 武 歩 歯 歳 歴 死 殉 殉 殊 残 殖 殴 段 殺 殻 殿 母 毎 毒 比 毛 氏 民 気 水 氷 永 汁 求 汎 汗 汚 江 池 決 汽 沈 沖 没 沢 河 沸 油 治 沼 沿 況 泉 泊 泌 法 泡 泡 波 泣 泥 注 泰 泳 洋 洗 洞 津 洪 活 派 流 浄 浅 浜 浦 浪 浮 浴 海 浸 消 涙 涯 液 涼 淑 淡 深 混 添 清 渇 渇 済 渉 渋 渓 減 渡 渦 温 測 港 湖 湯 湾 湾 湿 満 源 準 溝 溶 滅 滋 滑 滝 滞 滴 漁 漂 漆 漏 演 漠 漢 漫 漬 漸 潔 潜 潟 潤 潮 澄 激 濁 濃 濫 濯 瀬 火 灯 灰 災 炉 炊 炎 炭 点 為 烈 無 焦 然 焼 煙 照 煩 煮 熟 熱 燃 燥 爆 爵 父 片 版 牙 牛 牧 物 牲 特 犠 犬 犯 状 狂 狩 独 狭 猛 猟 猫 献 猶 猿 獄 獣 獲 玄 率 玉 王 珍 珠 班 現 球 理 琴 環 璽 瓶 甘 甚 生 産 用 田 田 由 甲 申 男 町 画 界 畑 畔 留 畜 畝 略 番 異 畳 疎 疑 疫 疲 疾 病 症 痘 痛 痢 痴 療 癒 癖 発 登 白 百 的 皆 皇 皮 皿 盆 益 盗 盛 盟 監 盤 目 盲 直 相 盾 省 看 県 真 眠 眺 眼 着 睡 督 瞬 矛 矢 知 短 矯 石 砂 研 砕 砲 破 硝 硫 硬 碁 碑 確 磁 磨 礁 礎 示 礼 社 祈 祉 祖 祚 祝 神 祥 票 祭 禁 禄 禅 禍 禍 禎 福 秀 私 秋 科 秒 秘 租 秩 称 移 程 税 稚 種 稲 稼 稿 穀 穂 積 穏 穫 穴 究 空 突 窃 窒 窓 窮 窯 立 竜 章 童 端 競 竹 笑 笛 符 第 筆 等 筋 筒 答 策 箇 算 管 箱 節 範 築 篤 簡 簿 籍 米 粉 粋 粒 粗 粘 粛 粧 精 糖 糧 糸 系 糾 紀 約 紅 紋 納 純 紙 紙 級 紛 素 素 紡 索 紫 累 細 紳 紹 紺 終 組 経 結 絞 絡 給 統 絵 絶 絹 継 続 維 綱 網 綿 緊 総 緑 緒 線 締 編 緩 緯 練 縁 縄 縛 縦 縫 縮 績 繁 繊 織 繕 繭 繰 缶 罪 置 罰 署 罷 羅 羊 美 群 義 羽 翁 翌 習 翻 翼 老 考 者 耐 耕 耗 耳 聖 聞 聴 職 肉 肌 肖 肝 肢 肥 肩 肪 肯 育 肺 胃 胆 背 胎 胞 胴 胸 能 脂 脅 脈 脚 脱 脳 脹 腐 腕 腰 腸 腹 膚 膜 膨 臓 臣 臨 自 臭 至 致 興 舌 舎 舗 舞 舟 航 般 舶 船 艇 艦 良 色 芋 芝 花 芳 芸 芽 苗 若 苦 英 茂 茎 茶 草 荒 荘 荷 菊 菌 菓 菜 華 落 葉 著 葬 蒸 蓄 蔵 薄 薦 薪 薪 薫 薬 藩 藻 虐 虚 虜 虞 虫 蚊 蚕 蛇 蛍 蛮 融 血 衆 行 術 街 衛 衝 衡 衣 表 衰 衷 袋 被 裁 裂 装 裏 裕 補 裸 製 複 褐 褒 襟 襲 西 要 覆 覇 見 規 視 覚 覧 親 観 角 解 触 言 訂 計 討 訓 託 記 訟 訪 設 許 訳 訴 診 証 詐 詔 評 詞 詠 試 詩 詰 詰 話 該 詳 誇 誉 誌 認 誓 誕 誘 語 誠 誤 説 読 課 調 談 請 論 諭 諮 諸 諾 謀 謁 謄 謙 講 謝 謡 謹 識 譜 警 議 譲 護 谷 豆 豊 豚 象 豪 貝 貞 負 負 財 貢 貧 貧 貨 販 貫 責 貯 貴 買 貸 費 貿 賀 賃 賄 資 賊 賓 賛 賜 賞 賠 賢 賦 質 購 贈 赤 赦 走 赴 起 超 越 趣 足 距 跡 路 跳 践 踊 踏 躍 身 車 軌 軍 軒 軟 転 軸 軽 較 載 輝 輩 輪 輸 轄 辛 辞 辱 農 辺 込 迅 迎 近 返 迫 迭 述 迷 追 退 送 逃 逆 透 逐 逓 途 通 逝 速 造 連 逮 週 進 逸 遂 遅 遇 遊 運 遍 過 道 道 達 違 遠 遣 適 遭 遮 遵 遷 選 遺 避 還 邦 邪 邸 郊 郎 郡 部 郭 郵 郷 都 酌 配 酒 酔 酢 酪 酬 酵 酷 酸 醜 醸 釈 里 里 重 野 量 金 針 釣 鈍 鈴 鉄 鉛 鉢 鉱 銀 銃 銅 銑 銘 銭 鋭 鋳 鋼 錘 錠 錬 錯 録 鍛 鎖 鎮 鏡 鐘 鑑 長 門 閉 開 閑 間 関 閣 閥 閲 闘 防 阻 附 降 限 陛 院 院 陣 除 陥 陪 陰 陳 陵 陶 陸 険 陽 隅 隆 隊 階 随 隔 際 障 隠 隣 隷 隻 雄 雄 雅 集 雇 雉 雌 雑 離 難 雨 雪 雰 雲 零 雷 電 需 震 霊 霜 霧 露 青 静 非 面 革 靴 韓 音 韻 響 頂 項 順 預 預 頑 頒 領 頭 頻 頼 題 額 顔 顕 願 類 顧 風 飛 食 飢 飯 飲 飼 飼 飽 飾 養 餓 館 首 香 馬 駄 駄 駅 駆 駐 騎 騒 験 騰 驚 骨 髄 高 髪 鬼 魂 魅 魔 魚 鮮 鯨 鳥 鳴 鶏 麗 麦 麻 黄 黒 黙 鼓 鼻 齢", + 3: "兌 拼 楔 錄 鳯", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + }, + "jmc": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "ka": { + 0: "ა ბ გ დ ე ვ ზ ჱ თ ი კ ლ მ ნ ჲ ო პ ჟ რ ს ტ ჳ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჴ ჯ ჰ ჵ ჶ ჷ ჸ ჹ ჺ", + 3: "ⴀ ⴁ ⴂ ⴃ ⴄ ⴅ ⴆ ⴡ ⴇ ⴈ ⴉ ⴊ ⴋ ⴌ ⴢ ⴍ ⴎ ⴏ ⴐ ⴑ ⴒ ⴣ ⴓ ⴔ ⴕ ⴖ ⴗ ⴘ ⴙ ⴚ ⴛ ⴜ ⴝ ⴞ ⴤ ⴟ ⴠ ⴥ", + 4: "ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჯ ჰ", + 5: "ა ბ გ დ ე ვ ზ თ ი კ ლ მ ნ ო პ ჟ რ ს ტ უ ფ ქ ღ ყ შ ჩ ც ძ წ ჭ ხ ჯ ჰ", + }, + "kab": { + 0: "a b c č d ḍ e ɛ f g ǧ ɣ h ḥ i j k l m n p q r ṛ s ṣ t ṭ u w x y z ẓ", + 3: "o v", + 5: "A B C Č D Ḍ E Ɛ F G Ǧ Ɣ H Ḥ I J K L M N P Q R Ṛ S Ṣ T Ṭ U W X Y Z Ẓ", + }, + "kam": { + 0: "a b c d e f g h i ĩ j k l m n o p q r s t u ũ v w y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "kde": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "kea": { + 0: "a b d dj e f g i j k l lh m n nh o p r s t tx u v x z", + 3: "á à â ã c ç é ê h í ñ ó ô q ú w y", + 5: "A B D E F G H I J K L M N O P R S T U V X Z", + }, + "khq": { + 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž", + 3: "v", + 5: "A à B C D E Ẽ F G H I J K L M N Ɲ Ŋ O Õ P Q R S Š T U W X Y Z Ž", + }, + "ki": { + 0: "a b c d e g h i ĩ j k m n o r t u ũ w y", + 3: "f l p q s v x z", + 5: "A B C D E G H I J K M N O R T U W Y", + }, + "kk": { + 0: "а ә б в г ғ д е ё ж з и й к қ л м н ң о ө п р с т у ұ ү ф х һ ц ч ш щ ъ ы і ь э ю я", + 5: "А Ә Б В Г Ғ Д Е Ё Ж З И Й К Қ Л М Н Ң О Ө П Р С Т У Ұ Ү Ф Х Һ Ц Ч Ш Щ Ъ Ы І Ь Э Ю Я", + }, + "kl": { + 0: "a á â ã b c d e é ê f g h i í î ĩ j k l m n o ô p q ĸ r s t u ú û ũ v w x y z æ ø å", + }, + "kln": { + 0: "a b c d e g h i j k l m n o p r s t u w y", + 3: "f q v x z", + 5: "A B C D E G H I J K L M N O P R S T U W Y", + }, + "km": { + 0: "៌ ៎ ៏ ៑ ័ ៈ ់ ៉ ៊ ៍ ក ខ គ ឃ ង ច ឆ ជ ឈ ញ ដ ឋ ឌ ឍ ណ ត ថ ទ ធ ន ប ផ ព ភ ម យ រ ឫ ឬ ល ឭ ឮ វ ស ហ ឡ អ អា ឥ ឦ ឧ ឧក ឪ ឩ ឯ ឰ ឱ ឲ ឳ ា ិ ី ឹ ឺ ុ ូ ួ ើ ឿ ៀ េ ែ ៃ ោ ៅ ំ ះ ្", + 3: "\u17b4 \u17b5 \u200b ឝ ឞ", + }, + "kn": { + 0: "಼ ೦ ೧ ೨ ೩ ೪ ೫ ೬ ೭ ೮ ೯ ಅ ಆ ಇ ಈ ಉ ಊ ಋ ೠ ಌ ೡ ಎ ಏ ಐ ಒ ಓ ಔ ಂ ಃ ಕ ಖ ಗ ಘ ಙ ಚ ಛ ಜ ಝ ಞ ಟ ಠ ಡ ಢ ಣ ತ ಥ ದ ಧ ನ ಪ ಫ ಬ ಭ ಮ ಯ ರ ಱ ಲ ವ ಶ ಷ ಸ ಹ ಳ ೞ ಽ ಾ ಿ ೀ ು ೂ ೃ ೄ ೆ ೇ ೈ ೊ ೋ ೌ ್ ೕ ೖ", + 4: "ರ ೂ", + }, + "ko": { + 0: "가 가 각 갂 갃 간 갅 갆 갇 갈 갉 갊 갋 갌 갍 갎 갏 감 갑 값 갓 갔 강 갖 갗 갘 같 갚 갛 개 객 갞 갟 갠 갡 갢 갣 갤 갥 갦 갧 갨 갩 갪 갫 갬 갭 갮 갯 갰 갱 갲 갳 갴 갵 갶 갷 갸 갹 갺 갻 갼 갽 갾 갿 걀 걁 걂 걃 걄 걅 걆 걇 걈 걉 걊 걋 걌 걍 걎 걏 걐 걑 걒 걓 걔 걕 걖 걗 걘 걙 걚 걛 걜 걝 걞 걟 걠 걡 걢 걣 걤 걥 걦 걧 걨 걩 걪 걫 걬 걭 걮 걯 거 걱 걲 걳 건 걵 걶 걷 걸 걹 걺 걻 걼 걽 걾 걿 검 겁 겂 것 겄 겅 겆 겇 겈 겉 겊 겋 게 겍 겎 겏 겐 겑 겒 겓 겔 겕 겖 겗 겘 겙 겚 겛 겜 겝 겞 겟 겠 겡 겢 겣 겤 겥 겦 겧 겨 격 겪 겫 견 겭 겮 겯 결 겱 겲 겳 겴 겵 겶 겷 겸 겹 겺 겻 겼 경 겾 겿 곀 곁 곂 곃 계 곅 곆 곇 곈 곉 곊 곋 곌 곍 곎 곏 곐 곑 곒 곓 곔 곕 곖 곗 곘 곙 곚 곛 곜 곝 곞 곟 고 곡 곢 곣 곤 곥 곦 곧 골 곩 곪 곫 곬 곭 곮 곯 곰 곱 곲 곳 곴 공 곶 곷 곸 곹 곺 곻 과 곽 곾 곿 관 괁 괂 괃 괄 괅 괆 괇 괈 괉 괊 괋 괌 괍 괎 괏 괐 광 괒 괓 괔 괕 괖 괗 괘 괙 괚 괛 괜 괝 괞 괟 괠 괡 괢 괣 괤 괥 괦 괧 괨 괩 괪 괫 괬 괭 괮 괯 괰 괱 괲 괳 괴 괵 괶 괷 괸 괹 괺 괻 괼 괽 괾 괿 굀 굁 굂 굃 굄 굅 굆 굇 굈 굉 굊 굋 굌 굍 굎 굏 교 굑 굒 굓 굔 굕 굖 굗 굘 굙 굚 굛 굜 굝 굞 굟 굠 굡 굢 굣 굤 굥 굦 굧 굨 굩 굪 굫 구 국 굮 굯 군 굱 굲 굳 굴 굵 굶 굷 굸 굹 굺 굻 굼 굽 굾 굿 궀 궁 궂 궃 궄 궅 궆 궇 궈 궉 궊 궋 권 궍 궎 궏 궐 궑 궒 궓 궔 궕 궖 궗 궘 궙 궚 궛 궜 궝 궞 궟 궠 궡 궢 궣 궤 궥 궦 궧 궨 궩 궪 궫 궬 궭 궮 궯 궰 궱 궲 궳 궴 궵 궶 궷 궸 궹 궺 궻 궼 궽 궾 궿 귀 귁 귂 귃 귄 귅 귆 귇 귈 귉 귊 귋 귌 귍 귎 귏 귐 귑 귒 귓 귔 귕 귖 귗 귘 귙 귚 귛 규 귝 귞 귟 균 귡 귢 귣 귤 귥 귦 귧 귨 귩 귪 귫 귬 귭 귮 귯 귰 귱 귲 귳 귴 귵 귶 귷 그 극 귺 귻 근 귽 귾 귿 글 긁 긂 긃 긄 긅 긆 긇 금 급 긊 긋 긌 긍 긎 긏 긐 긑 긒 긓 긔 긕 긖 긗 긘 긙 긚 긛 긜 긝 긞 긟 긠 긡 긢 긣 긤 긥 긦 긧 긨 긩 긪 긫 긬 긭 긮 긯 기 긱 긲 긳 긴 긵 긶 긷 길 긹 긺 긻 긼 긽 긾 긿 김 깁 깂 깃 깄 깅 깆 깇 깈 깉 깊 깋 까 깍 깎 깏 깐 깑 깒 깓 깔 깕 깖 깗 깘 깙 깚 깛 깜 깝 깞 깟 깠 깡 깢 깣 깤 깥 깦 깧 깨 깩 깪 깫 깬 깭 깮 깯 깰 깱 깲 깳 깴 깵 깶 깷 깸 깹 깺 깻 깼 깽 깾 깿 꺀 꺁 꺂 꺃 꺄 꺅 꺆 꺇 꺈 꺉 꺊 꺋 꺌 꺍 꺎 꺏 꺐 꺑 꺒 꺓 꺔 꺕 꺖 꺗 꺘 꺙 꺚 꺛 꺜 꺝 꺞 꺟 꺠 꺡 꺢 꺣 꺤 꺥 꺦 꺧 꺨 꺩 꺪 꺫 꺬 꺭 꺮 꺯 꺰 꺱 꺲 꺳 꺴 꺵 꺶 꺷 꺸 꺹 꺺 꺻 꺼 꺽 꺾 꺿 껀 껁 껂 껃 껄 껅 껆 껇 껈 껉 껊 껋 껌 껍 껎 껏 껐 껑 껒 껓 껔 껕 껖 껗 께 껙 껚 껛 껜 껝 껞 껟 껠 껡 껢 껣 껤 껥 껦 껧 껨 껩 껪 껫 껬 껭 껮 껯 껰 껱 껲 껳 껴 껵 껶 껷 껸 껹 껺 껻 껼 껽 껾 껿 꼀 꼁 꼂 꼃 꼄 꼅 꼆 꼇 꼈 꼉 꼊 꼋 꼌 꼍 꼎 꼏 꼐 꼑 꼒 꼓 꼔 꼕 꼖 꼗 꼘 꼙 꼚 꼛 꼜 꼝 꼞 꼟 꼠 꼡 꼢 꼣 꼤 꼥 꼦 꼧 꼨 꼩 꼪 꼫 꼬 꼭 꼮 꼯 꼰 꼱 꼲 꼳 꼴 꼵 꼶 꼷 꼸 꼹 꼺 꼻 꼼 꼽 꼾 꼿 꽀 꽁 꽂 꽃 꽄 꽅 꽆 꽇 꽈 꽉 꽊 꽋 꽌 꽍 꽎 꽏 꽐 꽑 꽒 꽓 꽔 꽕 꽖 꽗 꽘 꽙 꽚 꽛 꽜 꽝 꽞 꽟 꽠 꽡 꽢 꽣 꽤 꽥 꽦 꽧 꽨 꽩 꽪 꽫 꽬 꽭 꽮 꽯 꽰 꽱 꽲 꽳 꽴 꽵 꽶 꽷 꽸 꽹 꽺 꽻 꽼 꽽 꽾 꽿 꾀 꾁 꾂 꾃 꾄 꾅 꾆 꾇 꾈 꾉 꾊 꾋 꾌 꾍 꾎 꾏 꾐 꾑 꾒 꾓 꾔 꾕 꾖 꾗 꾘 꾙 꾚 꾛 꾜 꾝 꾞 꾟 꾠 꾡 꾢 꾣 꾤 꾥 꾦 꾧 꾨 꾩 꾪 꾫 꾬 꾭 꾮 꾯 꾰 꾱 꾲 꾳 꾴 꾵 꾶 꾷 꾸 꾹 꾺 꾻 꾼 꾽 꾾 꾿 꿀 꿁 꿂 꿃 꿄 꿅 꿆 꿇 꿈 꿉 꿊 꿋 꿌 꿍 꿎 꿏 꿐 꿑 꿒 꿓 꿔 꿕 꿖 꿗 꿘 꿙 꿚 꿛 꿜 꿝 꿞 꿟 꿠 꿡 꿢 꿣 꿤 꿥 꿦 꿧 꿨 꿩 꿪 꿫 꿬 꿭 꿮 꿯 꿰 꿱 꿲 꿳 꿴 꿵 꿶 꿷 꿸 꿹 꿺 꿻 꿼 꿽 꿾 꿿 뀀 뀁 뀂 뀃 뀄 뀅 뀆 뀇 뀈 뀉 뀊 뀋 뀌 뀍 뀎 뀏 뀐 뀑 뀒 뀓 뀔 뀕 뀖 뀗 뀘 뀙 뀚 뀛 뀜 뀝 뀞 뀟 뀠 뀡 뀢 뀣 뀤 뀥 뀦 뀧 뀨 뀩 뀪 뀫 뀬 뀭 뀮 뀯 뀰 뀱 뀲 뀳 뀴 뀵 뀶 뀷 뀸 뀹 뀺 뀻 뀼 뀽 뀾 뀿 끀 끁 끂 끃 끄 끅 끆 끇 끈 끉 끊 끋 끌 끍 끎 끏 끐 끑 끒 끓 끔 끕 끖 끗 끘 끙 끚 끛 끜 끝 끞 끟 끠 끡 끢 끣 끤 끥 끦 끧 끨 끩 끪 끫 끬 끭 끮 끯 끰 끱 끲 끳 끴 끵 끶 끷 끸 끹 끺 끻 끼 끽 끾 끿 낀 낁 낂 낃 낄 낅 낆 낇 낈 낉 낊 낋 낌 낍 낎 낏 낐 낑 낒 낓 낔 낕 낖 낗 나 낙 낚 낛 난 낝 낞 낟 날 낡 낢 낣 낤 낥 낦 낧 남 납 낪 낫 났 낭 낮 낯 낰 낱 낲 낳 내 낵 낶 낷 낸 낹 낺 낻 낼 낽 낾 낿 냀 냁 냂 냃 냄 냅 냆 냇 냈 냉 냊 냋 냌 냍 냎 냏 냐 냑 냒 냓 냔 냕 냖 냗 냘 냙 냚 냛 냜 냝 냞 냟 냠 냡 냢 냣 냤 냥 냦 냧 냨 냩 냪 냫 냬 냭 냮 냯 냰 냱 냲 냳 냴 냵 냶 냷 냸 냹 냺 냻 냼 냽 냾 냿 넀 넁 넂 넃 넄 넅 넆 넇 너 넉 넊 넋 넌 넍 넎 넏 널 넑 넒 넓 넔 넕 넖 넗 넘 넙 넚 넛 넜 넝 넞 넟 넠 넡 넢 넣 네 넥 넦 넧 넨 넩 넪 넫 넬 넭 넮 넯 넰 넱 넲 넳 넴 넵 넶 넷 넸 넹 넺 넻 넼 넽 넾 넿 녀 녁 녂 녃 년 녅 녆 녇 녈 녉 녊 녋 녌 녍 녎 녏 념 녑 녒 녓 녔 녕 녖 녗 녘 녙 녚 녛 녜 녝 녞 녟 녠 녡 녢 녣 녤 녥 녦 녧 녨 녩 녪 녫 녬 녭 녮 녯 녰 녱 녲 녳 녴 녵 녶 녷 노 녹 녺 녻 논 녽 녾 녿 놀 놁 놂 놃 놄 놅 놆 놇 놈 놉 놊 놋 놌 농 놎 놏 놐 놑 높 놓 놔 놕 놖 놗 놘 놙 놚 놛 놜 놝 놞 놟 놠 놡 놢 놣 놤 놥 놦 놧 놨 놩 놪 놫 놬 놭 놮 놯 놰 놱 놲 놳 놴 놵 놶 놷 놸 놹 놺 놻 놼 놽 놾 놿 뇀 뇁 뇂 뇃 뇄 뇅 뇆 뇇 뇈 뇉 뇊 뇋 뇌 뇍 뇎 뇏 뇐 뇑 뇒 뇓 뇔 뇕 뇖 뇗 뇘 뇙 뇚 뇛 뇜 뇝 뇞 뇟 뇠 뇡 뇢 뇣 뇤 뇥 뇦 뇧 뇨 뇩 뇪 뇫 뇬 뇭 뇮 뇯 뇰 뇱 뇲 뇳 뇴 뇵 뇶 뇷 뇸 뇹 뇺 뇻 뇼 뇽 뇾 뇿 눀 눁 눂 눃 누 눅 눆 눇 눈 눉 눊 눋 눌 눍 눎 눏 눐 눑 눒 눓 눔 눕 눖 눗 눘 눙 눚 눛 눜 눝 눞 눟 눠 눡 눢 눣 눤 눥 눦 눧 눨 눩 눪 눫 눬 눭 눮 눯 눰 눱 눲 눳 눴 눵 눶 눷 눸 눹 눺 눻 눼 눽 눾 눿 뉀 뉁 뉂 뉃 뉄 뉅 뉆 뉇 뉈 뉉 뉊 뉋 뉌 뉍 뉎 뉏 뉐 뉑 뉒 뉓 뉔 뉕 뉖 뉗 뉘 뉙 뉚 뉛 뉜 뉝 뉞 뉟 뉠 뉡 뉢 뉣 뉤 뉥 뉦 뉧 뉨 뉩 뉪 뉫 뉬 뉭 뉮 뉯 뉰 뉱 뉲 뉳 뉴 뉵 뉶 뉷 뉸 뉹 뉺 뉻 뉼 뉽 뉾 뉿 늀 늁 늂 늃 늄 늅 늆 늇 늈 늉 늊 늋 늌 늍 늎 늏 느 늑 늒 늓 는 늕 늖 늗 늘 늙 늚 늛 늜 늝 늞 늟 늠 늡 늢 늣 늤 능 늦 늧 늨 늩 늪 늫 늬 늭 늮 늯 늰 늱 늲 늳 늴 늵 늶 늷 늸 늹 늺 늻 늼 늽 늾 늿 닀 닁 닂 닃 닄 닅 닆 닇 니 닉 닊 닋 닌 닍 닎 닏 닐 닑 닒 닓 닔 닕 닖 닗 님 닙 닚 닛 닜 닝 닞 닟 닠 닡 닢 닣 다 닥 닦 닧 단 닩 닪 닫 달 닭 닮 닯 닰 닱 닲 닳 담 답 닶 닷 닸 당 닺 닻 닼 닽 닾 닿 대 댁 댂 댃 댄 댅 댆 댇 댈 댉 댊 댋 댌 댍 댎 댏 댐 댑 댒 댓 댔 댕 댖 댗 댘 댙 댚 댛 댜 댝 댞 댟 댠 댡 댢 댣 댤 댥 댦 댧 댨 댩 댪 댫 댬 댭 댮 댯 댰 댱 댲 댳 댴 댵 댶 댷 댸 댹 댺 댻 댼 댽 댾 댿 덀 덁 덂 덃 덄 덅 덆 덇 덈 덉 덊 덋 덌 덍 덎 덏 덐 덑 덒 덓 더 덕 덖 덗 던 덙 덚 덛 덜 덝 덞 덟 덠 덡 덢 덣 덤 덥 덦 덧 덨 덩 덪 덫 덬 덭 덮 덯 데 덱 덲 덳 덴 덵 덶 덷 델 덹 덺 덻 덼 덽 덾 덿 뎀 뎁 뎂 뎃 뎄 뎅 뎆 뎇 뎈 뎉 뎊 뎋 뎌 뎍 뎎 뎏 뎐 뎑 뎒 뎓 뎔 뎕 뎖 뎗 뎘 뎙 뎚 뎛 뎜 뎝 뎞 뎟 뎠 뎡 뎢 뎣 뎤 뎥 뎦 뎧 뎨 뎩 뎪 뎫 뎬 뎭 뎮 뎯 뎰 뎱 뎲 뎳 뎴 뎵 뎶 뎷 뎸 뎹 뎺 뎻 뎼 뎽 뎾 뎿 돀 돁 돂 돃 도 독 돆 돇 돈 돉 돊 돋 돌 돍 돎 돏 돐 돑 돒 돓 돔 돕 돖 돗 돘 동 돚 돛 돜 돝 돞 돟 돠 돡 돢 돣 돤 돥 돦 돧 돨 돩 돪 돫 돬 돭 돮 돯 돰 돱 돲 돳 돴 돵 돶 돷 돸 돹 돺 돻 돼 돽 돾 돿 됀 됁 됂 됃 됄 됅 됆 됇 됈 됉 됊 됋 됌 됍 됎 됏 됐 됑 됒 됓 됔 됕 됖 됗 되 됙 됚 됛 된 됝 됞 됟 될 됡 됢 됣 됤 됥 됦 됧 됨 됩 됪 됫 됬 됭 됮 됯 됰 됱 됲 됳 됴 됵 됶 됷 됸 됹 됺 됻 됼 됽 됾 됿 둀 둁 둂 둃 둄 둅 둆 둇 둈 둉 둊 둋 둌 둍 둎 둏 두 둑 둒 둓 둔 둕 둖 둗 둘 둙 둚 둛 둜 둝 둞 둟 둠 둡 둢 둣 둤 둥 둦 둧 둨 둩 둪 둫 둬 둭 둮 둯 둰 둱 둲 둳 둴 둵 둶 둷 둸 둹 둺 둻 둼 둽 둾 둿 뒀 뒁 뒂 뒃 뒄 뒅 뒆 뒇 뒈 뒉 뒊 뒋 뒌 뒍 뒎 뒏 뒐 뒑 뒒 뒓 뒔 뒕 뒖 뒗 뒘 뒙 뒚 뒛 뒜 뒝 뒞 뒟 뒠 뒡 뒢 뒣 뒤 뒥 뒦 뒧 뒨 뒩 뒪 뒫 뒬 뒭 뒮 뒯 뒰 뒱 뒲 뒳 뒴 뒵 뒶 뒷 뒸 뒹 뒺 뒻 뒼 뒽 뒾 뒿 듀 듁 듂 듃 듄 듅 듆 듇 듈 듉 듊 듋 듌 듍 듎 듏 듐 듑 듒 듓 듔 듕 듖 듗 듘 듙 듚 듛 드 득 듞 듟 든 듡 듢 듣 들 듥 듦 듧 듨 듩 듪 듫 듬 듭 듮 듯 듰 등 듲 듳 듴 듵 듶 듷 듸 듹 듺 듻 듼 듽 듾 듿 딀 딁 딂 딃 딄 딅 딆 딇 딈 딉 딊 딋 딌 딍 딎 딏 딐 딑 딒 딓 디 딕 딖 딗 딘 딙 딚 딛 딜 딝 딞 딟 딠 딡 딢 딣 딤 딥 딦 딧 딨 딩 딪 딫 딬 딭 딮 딯 따 딱 딲 딳 딴 딵 딶 딷 딸 딹 딺 딻 딼 딽 딾 딿 땀 땁 땂 땃 땄 땅 땆 땇 땈 땉 땊 땋 때 땍 땎 땏 땐 땑 땒 땓 땔 땕 땖 땗 땘 땙 땚 땛 땜 땝 땞 땟 땠 땡 땢 땣 땤 땥 땦 땧 땨 땩 땪 땫 땬 땭 땮 땯 땰 땱 땲 땳 땴 땵 땶 땷 땸 땹 땺 땻 땼 땽 땾 땿 떀 떁 떂 떃 떄 떅 떆 떇 떈 떉 떊 떋 떌 떍 떎 떏 떐 떑 떒 떓 떔 떕 떖 떗 떘 떙 떚 떛 떜 떝 떞 떟 떠 떡 떢 떣 떤 떥 떦 떧 떨 떩 떪 떫 떬 떭 떮 떯 떰 떱 떲 떳 떴 떵 떶 떷 떸 떹 떺 떻 떼 떽 떾 떿 뗀 뗁 뗂 뗃 뗄 뗅 뗆 뗇 뗈 뗉 뗊 뗋 뗌 뗍 뗎 뗏 뗐 뗑 뗒 뗓 뗔 뗕 뗖 뗗 뗘 뗙 뗚 뗛 뗜 뗝 뗞 뗟 뗠 뗡 뗢 뗣 뗤 뗥 뗦 뗧 뗨 뗩 뗪 뗫 뗬 뗭 뗮 뗯 뗰 뗱 뗲 뗳 뗴 뗵 뗶 뗷 뗸 뗹 뗺 뗻 뗼 뗽 뗾 뗿 똀 똁 똂 똃 똄 똅 똆 똇 똈 똉 똊 똋 똌 똍 똎 똏 또 똑 똒 똓 똔 똕 똖 똗 똘 똙 똚 똛 똜 똝 똞 똟 똠 똡 똢 똣 똤 똥 똦 똧 똨 똩 똪 똫 똬 똭 똮 똯 똰 똱 똲 똳 똴 똵 똶 똷 똸 똹 똺 똻 똼 똽 똾 똿 뙀 뙁 뙂 뙃 뙄 뙅 뙆 뙇 뙈 뙉 뙊 뙋 뙌 뙍 뙎 뙏 뙐 뙑 뙒 뙓 뙔 뙕 뙖 뙗 뙘 뙙 뙚 뙛 뙜 뙝 뙞 뙟 뙠 뙡 뙢 뙣 뙤 뙥 뙦 뙧 뙨 뙩 뙪 뙫 뙬 뙭 뙮 뙯 뙰 뙱 뙲 뙳 뙴 뙵 뙶 뙷 뙸 뙹 뙺 뙻 뙼 뙽 뙾 뙿 뚀 뚁 뚂 뚃 뚄 뚅 뚆 뚇 뚈 뚉 뚊 뚋 뚌 뚍 뚎 뚏 뚐 뚑 뚒 뚓 뚔 뚕 뚖 뚗 뚘 뚙 뚚 뚛 뚜 뚝 뚞 뚟 뚠 뚡 뚢 뚣 뚤 뚥 뚦 뚧 뚨 뚩 뚪 뚫 뚬 뚭 뚮 뚯 뚰 뚱 뚲 뚳 뚴 뚵 뚶 뚷 뚸 뚹 뚺 뚻 뚼 뚽 뚾 뚿 뛀 뛁 뛂 뛃 뛄 뛅 뛆 뛇 뛈 뛉 뛊 뛋 뛌 뛍 뛎 뛏 뛐 뛑 뛒 뛓 뛔 뛕 뛖 뛗 뛘 뛙 뛚 뛛 뛜 뛝 뛞 뛟 뛠 뛡 뛢 뛣 뛤 뛥 뛦 뛧 뛨 뛩 뛪 뛫 뛬 뛭 뛮 뛯 뛰 뛱 뛲 뛳 뛴 뛵 뛶 뛷 뛸 뛹 뛺 뛻 뛼 뛽 뛾 뛿 뜀 뜁 뜂 뜃 뜄 뜅 뜆 뜇 뜈 뜉 뜊 뜋 뜌 뜍 뜎 뜏 뜐 뜑 뜒 뜓 뜔 뜕 뜖 뜗 뜘 뜙 뜚 뜛 뜜 뜝 뜞 뜟 뜠 뜡 뜢 뜣 뜤 뜥 뜦 뜧 뜨 뜩 뜪 뜫 뜬 뜭 뜮 뜯 뜰 뜱 뜲 뜳 뜴 뜵 뜶 뜷 뜸 뜹 뜺 뜻 뜼 뜽 뜾 뜿 띀 띁 띂 띃 띄 띅 띆 띇 띈 띉 띊 띋 띌 띍 띎 띏 띐 띑 띒 띓 띔 띕 띖 띗 띘 띙 띚 띛 띜 띝 띞 띟 띠 띡 띢 띣 띤 띥 띦 띧 띨 띩 띪 띫 띬 띭 띮 띯 띰 띱 띲 띳 띴 띵 띶 띷 띸 띹 띺 띻 라 락 띾 띿 란 랁 랂 랃 랄 랅 랆 랇 랈 랉 랊 랋 람 랍 랎 랏 랐 랑 랒 랓 랔 랕 랖 랗 래 랙 랚 랛 랜 랝 랞 랟 랠 랡 랢 랣 랤 랥 랦 랧 램 랩 랪 랫 랬 랭 랮 랯 랰 랱 랲 랳 랴 략 랶 랷 랸 랹 랺 랻 랼 랽 랾 랿 럀 럁 럂 럃 럄 럅 럆 럇 럈 량 럊 럋 럌 럍 럎 럏 럐 럑 럒 럓 럔 럕 럖 럗 럘 럙 럚 럛 럜 럝 럞 럟 럠 럡 럢 럣 럤 럥 럦 럧 럨 럩 럪 럫 러 럭 럮 럯 런 럱 럲 럳 럴 럵 럶 럷 럸 럹 럺 럻 럼 럽 럾 럿 렀 렁 렂 렃 렄 렅 렆 렇 레 렉 렊 렋 렌 렍 렎 렏 렐 렑 렒 렓 렔 렕 렖 렗 렘 렙 렚 렛 렜 렝 렞 렟 렠 렡 렢 렣 려 력 렦 렧 련 렩 렪 렫 렬 렭 렮 렯 렰 렱 렲 렳 렴 렵 렶 렷 렸 령 렺 렻 렼 렽 렾 렿 례 롁 롂 롃 롄 롅 롆 롇 롈 롉 롊 롋 롌 롍 롎 롏 롐 롑 롒 롓 롔 롕 롖 롗 롘 롙 롚 롛 로 록 롞 롟 론 롡 롢 롣 롤 롥 롦 롧 롨 롩 롪 롫 롬 롭 롮 롯 롰 롱 롲 롳 롴 롵 롶 롷 롸 롹 롺 롻 롼 롽 롾 롿 뢀 뢁 뢂 뢃 뢄 뢅 뢆 뢇 뢈 뢉 뢊 뢋 뢌 뢍 뢎 뢏 뢐 뢑 뢒 뢓 뢔 뢕 뢖 뢗 뢘 뢙 뢚 뢛 뢜 뢝 뢞 뢟 뢠 뢡 뢢 뢣 뢤 뢥 뢦 뢧 뢨 뢩 뢪 뢫 뢬 뢭 뢮 뢯 뢰 뢱 뢲 뢳 뢴 뢵 뢶 뢷 뢸 뢹 뢺 뢻 뢼 뢽 뢾 뢿 룀 룁 룂 룃 룄 룅 룆 룇 룈 룉 룊 룋 료 룍 룎 룏 룐 룑 룒 룓 룔 룕 룖 룗 룘 룙 룚 룛 룜 룝 룞 룟 룠 룡 룢 룣 룤 룥 룦 룧 루 룩 룪 룫 룬 룭 룮 룯 룰 룱 룲 룳 룴 룵 룶 룷 룸 룹 룺 룻 룼 룽 룾 룿 뤀 뤁 뤂 뤃 뤄 뤅 뤆 뤇 뤈 뤉 뤊 뤋 뤌 뤍 뤎 뤏 뤐 뤑 뤒 뤓 뤔 뤕 뤖 뤗 뤘 뤙 뤚 뤛 뤜 뤝 뤞 뤟 뤠 뤡 뤢 뤣 뤤 뤥 뤦 뤧 뤨 뤩 뤪 뤫 뤬 뤭 뤮 뤯 뤰 뤱 뤲 뤳 뤴 뤵 뤶 뤷 뤸 뤹 뤺 뤻 뤼 뤽 뤾 뤿 륀 륁 륂 륃 륄 륅 륆 륇 륈 륉 륊 륋 륌 륍 륎 륏 륐 륑 륒 륓 륔 륕 륖 륗 류 륙 륚 륛 륜 륝 륞 륟 률 륡 륢 륣 륤 륥 륦 륧 륨 륩 륪 륫 륬 륭 륮 륯 륰 륱 륲 륳 르 륵 륶 륷 른 륹 륺 륻 를 륽 륾 륿 릀 릁 릂 릃 름 릅 릆 릇 릈 릉 릊 릋 릌 릍 릎 릏 릐 릑 릒 릓 릔 릕 릖 릗 릘 릙 릚 릛 릜 릝 릞 릟 릠 릡 릢 릣 릤 릥 릦 릧 릨 릩 릪 릫 리 릭 릮 릯 린 릱 릲 릳 릴 릵 릶 릷 릸 릹 릺 릻 림 립 릾 릿 맀 링 맂 맃 맄 맅 맆 맇 마 막 맊 맋 만 맍 많 맏 말 맑 맒 맓 맔 맕 맖 맗 맘 맙 맚 맛 맜 망 맞 맟 맠 맡 맢 맣 매 맥 맦 맧 맨 맩 맪 맫 맬 맭 맮 맯 맰 맱 맲 맳 맴 맵 맶 맷 맸 맹 맺 맻 맼 맽 맾 맿 먀 먁 먂 먃 먄 먅 먆 먇 먈 먉 먊 먋 먌 먍 먎 먏 먐 먑 먒 먓 먔 먕 먖 먗 먘 먙 먚 먛 먜 먝 먞 먟 먠 먡 먢 먣 먤 먥 먦 먧 먨 먩 먪 먫 먬 먭 먮 먯 먰 먱 먲 먳 먴 먵 먶 먷 머 먹 먺 먻 먼 먽 먾 먿 멀 멁 멂 멃 멄 멅 멆 멇 멈 멉 멊 멋 멌 멍 멎 멏 멐 멑 멒 멓 메 멕 멖 멗 멘 멙 멚 멛 멜 멝 멞 멟 멠 멡 멢 멣 멤 멥 멦 멧 멨 멩 멪 멫 멬 멭 멮 멯 며 멱 멲 멳 면 멵 멶 멷 멸 멹 멺 멻 멼 멽 멾 멿 몀 몁 몂 몃 몄 명 몆 몇 몈 몉 몊 몋 몌 몍 몎 몏 몐 몑 몒 몓 몔 몕 몖 몗 몘 몙 몚 몛 몜 몝 몞 몟 몠 몡 몢 몣 몤 몥 몦 몧 모 목 몪 몫 몬 몭 몮 몯 몰 몱 몲 몳 몴 몵 몶 몷 몸 몹 몺 못 몼 몽 몾 몿 뫀 뫁 뫂 뫃 뫄 뫅 뫆 뫇 뫈 뫉 뫊 뫋 뫌 뫍 뫎 뫏 뫐 뫑 뫒 뫓 뫔 뫕 뫖 뫗 뫘 뫙 뫚 뫛 뫜 뫝 뫞 뫟 뫠 뫡 뫢 뫣 뫤 뫥 뫦 뫧 뫨 뫩 뫪 뫫 뫬 뫭 뫮 뫯 뫰 뫱 뫲 뫳 뫴 뫵 뫶 뫷 뫸 뫹 뫺 뫻 뫼 뫽 뫾 뫿 묀 묁 묂 묃 묄 묅 묆 묇 묈 묉 묊 묋 묌 묍 묎 묏 묐 묑 묒 묓 묔 묕 묖 묗 묘 묙 묚 묛 묜 묝 묞 묟 묠 묡 묢 묣 묤 묥 묦 묧 묨 묩 묪 묫 묬 묭 묮 묯 묰 묱 묲 묳 무 묵 묶 묷 문 묹 묺 묻 물 묽 묾 묿 뭀 뭁 뭂 뭃 뭄 뭅 뭆 뭇 뭈 뭉 뭊 뭋 뭌 뭍 뭎 뭏 뭐 뭑 뭒 뭓 뭔 뭕 뭖 뭗 뭘 뭙 뭚 뭛 뭜 뭝 뭞 뭟 뭠 뭡 뭢 뭣 뭤 뭥 뭦 뭧 뭨 뭩 뭪 뭫 뭬 뭭 뭮 뭯 뭰 뭱 뭲 뭳 뭴 뭵 뭶 뭷 뭸 뭹 뭺 뭻 뭼 뭽 뭾 뭿 뮀 뮁 뮂 뮃 뮄 뮅 뮆 뮇 뮈 뮉 뮊 뮋 뮌 뮍 뮎 뮏 뮐 뮑 뮒 뮓 뮔 뮕 뮖 뮗 뮘 뮙 뮚 뮛 뮜 뮝 뮞 뮟 뮠 뮡 뮢 뮣 뮤 뮥 뮦 뮧 뮨 뮩 뮪 뮫 뮬 뮭 뮮 뮯 뮰 뮱 뮲 뮳 뮴 뮵 뮶 뮷 뮸 뮹 뮺 뮻 뮼 뮽 뮾 뮿 므 믁 믂 믃 믄 믅 믆 믇 믈 믉 믊 믋 믌 믍 믎 믏 믐 믑 믒 믓 믔 믕 믖 믗 믘 믙 믚 믛 믜 믝 믞 믟 믠 믡 믢 믣 믤 믥 믦 믧 믨 믩 믪 믫 믬 믭 믮 믯 믰 믱 믲 믳 믴 믵 믶 믷 미 믹 믺 믻 민 믽 믾 믿 밀 밁 밂 밃 밄 밅 밆 밇 밈 밉 밊 밋 밌 밍 밎 및 밐 밑 밒 밓 바 박 밖 밗 반 밙 밚 받 발 밝 밞 밟 밠 밡 밢 밣 밤 밥 밦 밧 밨 방 밪 밫 밬 밭 밮 밯 배 백 밲 밳 밴 밵 밶 밷 밸 밹 밺 밻 밼 밽 밾 밿 뱀 뱁 뱂 뱃 뱄 뱅 뱆 뱇 뱈 뱉 뱊 뱋 뱌 뱍 뱎 뱏 뱐 뱑 뱒 뱓 뱔 뱕 뱖 뱗 뱘 뱙 뱚 뱛 뱜 뱝 뱞 뱟 뱠 뱡 뱢 뱣 뱤 뱥 뱦 뱧 뱨 뱩 뱪 뱫 뱬 뱭 뱮 뱯 뱰 뱱 뱲 뱳 뱴 뱵 뱶 뱷 뱸 뱹 뱺 뱻 뱼 뱽 뱾 뱿 벀 벁 벂 벃 버 벅 벆 벇 번 벉 벊 벋 벌 벍 벎 벏 벐 벑 벒 벓 범 법 벖 벗 벘 벙 벚 벛 벜 벝 벞 벟 베 벡 벢 벣 벤 벥 벦 벧 벨 벩 벪 벫 벬 벭 벮 벯 벰 벱 벲 벳 벴 벵 벶 벷 벸 벹 벺 벻 벼 벽 벾 벿 변 볁 볂 볃 별 볅 볆 볇 볈 볉 볊 볋 볌 볍 볎 볏 볐 병 볒 볓 볔 볕 볖 볗 볘 볙 볚 볛 볜 볝 볞 볟 볠 볡 볢 볣 볤 볥 볦 볧 볨 볩 볪 볫 볬 볭 볮 볯 볰 볱 볲 볳 보 복 볶 볷 본 볹 볺 볻 볼 볽 볾 볿 봀 봁 봂 봃 봄 봅 봆 봇 봈 봉 봊 봋 봌 봍 봎 봏 봐 봑 봒 봓 봔 봕 봖 봗 봘 봙 봚 봛 봜 봝 봞 봟 봠 봡 봢 봣 봤 봥 봦 봧 봨 봩 봪 봫 봬 봭 봮 봯 봰 봱 봲 봳 봴 봵 봶 봷 봸 봹 봺 봻 봼 봽 봾 봿 뵀 뵁 뵂 뵃 뵄 뵅 뵆 뵇 뵈 뵉 뵊 뵋 뵌 뵍 뵎 뵏 뵐 뵑 뵒 뵓 뵔 뵕 뵖 뵗 뵘 뵙 뵚 뵛 뵜 뵝 뵞 뵟 뵠 뵡 뵢 뵣 뵤 뵥 뵦 뵧 뵨 뵩 뵪 뵫 뵬 뵭 뵮 뵯 뵰 뵱 뵲 뵳 뵴 뵵 뵶 뵷 뵸 뵹 뵺 뵻 뵼 뵽 뵾 뵿 부 북 붂 붃 분 붅 붆 붇 불 붉 붊 붋 붌 붍 붎 붏 붐 붑 붒 붓 붔 붕 붖 붗 붘 붙 붚 붛 붜 붝 붞 붟 붠 붡 붢 붣 붤 붥 붦 붧 붨 붩 붪 붫 붬 붭 붮 붯 붰 붱 붲 붳 붴 붵 붶 붷 붸 붹 붺 붻 붼 붽 붾 붿 뷀 뷁 뷂 뷃 뷄 뷅 뷆 뷇 뷈 뷉 뷊 뷋 뷌 뷍 뷎 뷏 뷐 뷑 뷒 뷓 뷔 뷕 뷖 뷗 뷘 뷙 뷚 뷛 뷜 뷝 뷞 뷟 뷠 뷡 뷢 뷣 뷤 뷥 뷦 뷧 뷨 뷩 뷪 뷫 뷬 뷭 뷮 뷯 뷰 뷱 뷲 뷳 뷴 뷵 뷶 뷷 뷸 뷹 뷺 뷻 뷼 뷽 뷾 뷿 븀 븁 븂 븃 븄 븅 븆 븇 븈 븉 븊 븋 브 븍 븎 븏 븐 븑 븒 븓 블 븕 븖 븗 븘 븙 븚 븛 븜 븝 븞 븟 븠 븡 븢 븣 븤 븥 븦 븧 븨 븩 븪 븫 븬 븭 븮 븯 븰 븱 븲 븳 븴 븵 븶 븷 븸 븹 븺 븻 븼 븽 븾 븿 빀 빁 빂 빃 비 빅 빆 빇 빈 빉 빊 빋 빌 빍 빎 빏 빐 빑 빒 빓 빔 빕 빖 빗 빘 빙 빚 빛 빜 빝 빞 빟 빠 빡 빢 빣 빤 빥 빦 빧 빨 빩 빪 빫 빬 빭 빮 빯 빰 빱 빲 빳 빴 빵 빶 빷 빸 빹 빺 빻 빼 빽 빾 빿 뺀 뺁 뺂 뺃 뺄 뺅 뺆 뺇 뺈 뺉 뺊 뺋 뺌 뺍 뺎 뺏 뺐 뺑 뺒 뺓 뺔 뺕 뺖 뺗 뺘 뺙 뺚 뺛 뺜 뺝 뺞 뺟 뺠 뺡 뺢 뺣 뺤 뺥 뺦 뺧 뺨 뺩 뺪 뺫 뺬 뺭 뺮 뺯 뺰 뺱 뺲 뺳 뺴 뺵 뺶 뺷 뺸 뺹 뺺 뺻 뺼 뺽 뺾 뺿 뻀 뻁 뻂 뻃 뻄 뻅 뻆 뻇 뻈 뻉 뻊 뻋 뻌 뻍 뻎 뻏 뻐 뻑 뻒 뻓 뻔 뻕 뻖 뻗 뻘 뻙 뻚 뻛 뻜 뻝 뻞 뻟 뻠 뻡 뻢 뻣 뻤 뻥 뻦 뻧 뻨 뻩 뻪 뻫 뻬 뻭 뻮 뻯 뻰 뻱 뻲 뻳 뻴 뻵 뻶 뻷 뻸 뻹 뻺 뻻 뻼 뻽 뻾 뻿 뼀 뼁 뼂 뼃 뼄 뼅 뼆 뼇 뼈 뼉 뼊 뼋 뼌 뼍 뼎 뼏 뼐 뼑 뼒 뼓 뼔 뼕 뼖 뼗 뼘 뼙 뼚 뼛 뼜 뼝 뼞 뼟 뼠 뼡 뼢 뼣 뼤 뼥 뼦 뼧 뼨 뼩 뼪 뼫 뼬 뼭 뼮 뼯 뼰 뼱 뼲 뼳 뼴 뼵 뼶 뼷 뼸 뼹 뼺 뼻 뼼 뼽 뼾 뼿 뽀 뽁 뽂 뽃 뽄 뽅 뽆 뽇 뽈 뽉 뽊 뽋 뽌 뽍 뽎 뽏 뽐 뽑 뽒 뽓 뽔 뽕 뽖 뽗 뽘 뽙 뽚 뽛 뽜 뽝 뽞 뽟 뽠 뽡 뽢 뽣 뽤 뽥 뽦 뽧 뽨 뽩 뽪 뽫 뽬 뽭 뽮 뽯 뽰 뽱 뽲 뽳 뽴 뽵 뽶 뽷 뽸 뽹 뽺 뽻 뽼 뽽 뽾 뽿 뾀 뾁 뾂 뾃 뾄 뾅 뾆 뾇 뾈 뾉 뾊 뾋 뾌 뾍 뾎 뾏 뾐 뾑 뾒 뾓 뾔 뾕 뾖 뾗 뾘 뾙 뾚 뾛 뾜 뾝 뾞 뾟 뾠 뾡 뾢 뾣 뾤 뾥 뾦 뾧 뾨 뾩 뾪 뾫 뾬 뾭 뾮 뾯 뾰 뾱 뾲 뾳 뾴 뾵 뾶 뾷 뾸 뾹 뾺 뾻 뾼 뾽 뾾 뾿 뿀 뿁 뿂 뿃 뿄 뿅 뿆 뿇 뿈 뿉 뿊 뿋 뿌 뿍 뿎 뿏 뿐 뿑 뿒 뿓 뿔 뿕 뿖 뿗 뿘 뿙 뿚 뿛 뿜 뿝 뿞 뿟 뿠 뿡 뿢 뿣 뿤 뿥 뿦 뿧 뿨 뿩 뿪 뿫 뿬 뿭 뿮 뿯 뿰 뿱 뿲 뿳 뿴 뿵 뿶 뿷 뿸 뿹 뿺 뿻 뿼 뿽 뿾 뿿 쀀 쀁 쀂 쀃 쀄 쀅 쀆 쀇 쀈 쀉 쀊 쀋 쀌 쀍 쀎 쀏 쀐 쀑 쀒 쀓 쀔 쀕 쀖 쀗 쀘 쀙 쀚 쀛 쀜 쀝 쀞 쀟 쀠 쀡 쀢 쀣 쀤 쀥 쀦 쀧 쀨 쀩 쀪 쀫 쀬 쀭 쀮 쀯 쀰 쀱 쀲 쀳 쀴 쀵 쀶 쀷 쀸 쀹 쀺 쀻 쀼 쀽 쀾 쀿 쁀 쁁 쁂 쁃 쁄 쁅 쁆 쁇 쁈 쁉 쁊 쁋 쁌 쁍 쁎 쁏 쁐 쁑 쁒 쁓 쁔 쁕 쁖 쁗 쁘 쁙 쁚 쁛 쁜 쁝 쁞 쁟 쁠 쁡 쁢 쁣 쁤 쁥 쁦 쁧 쁨 쁩 쁪 쁫 쁬 쁭 쁮 쁯 쁰 쁱 쁲 쁳 쁴 쁵 쁶 쁷 쁸 쁹 쁺 쁻 쁼 쁽 쁾 쁿 삀 삁 삂 삃 삄 삅 삆 삇 삈 삉 삊 삋 삌 삍 삎 삏 삐 삑 삒 삓 삔 삕 삖 삗 삘 삙 삚 삛 삜 삝 삞 삟 삠 삡 삢 삣 삤 삥 삦 삧 삨 삩 삪 삫 사 삭 삮 삯 산 삱 삲 삳 살 삵 삶 삷 삸 삹 삺 삻 삼 삽 삾 삿 샀 상 샂 샃 샄 샅 샆 샇 새 색 샊 샋 샌 샍 샎 샏 샐 샑 샒 샓 샔 샕 샖 샗 샘 샙 샚 샛 샜 생 샞 샟 샠 샡 샢 샣 샤 샥 샦 샧 샨 샩 샪 샫 샬 샭 샮 샯 샰 샱 샲 샳 샴 샵 샶 샷 샸 샹 샺 샻 샼 샽 샾 샿 섀 섁 섂 섃 섄 섅 섆 섇 섈 섉 섊 섋 섌 섍 섎 섏 섐 섑 섒 섓 섔 섕 섖 섗 섘 섙 섚 섛 서 석 섞 섟 선 섡 섢 섣 설 섥 섦 섧 섨 섩 섪 섫 섬 섭 섮 섯 섰 성 섲 섳 섴 섵 섶 섷 세 섹 섺 섻 센 섽 섾 섿 셀 셁 셂 셃 셄 셅 셆 셇 셈 셉 셊 셋 셌 셍 셎 셏 셐 셑 셒 셓 셔 셕 셖 셗 션 셙 셚 셛 셜 셝 셞 셟 셠 셡 셢 셣 셤 셥 셦 셧 셨 셩 셪 셫 셬 셭 셮 셯 셰 셱 셲 셳 셴 셵 셶 셷 셸 셹 셺 셻 셼 셽 셾 셿 솀 솁 솂 솃 솄 솅 솆 솇 솈 솉 솊 솋 소 속 솎 솏 손 솑 솒 솓 솔 솕 솖 솗 솘 솙 솚 솛 솜 솝 솞 솟 솠 송 솢 솣 솤 솥 솦 솧 솨 솩 솪 솫 솬 솭 솮 솯 솰 솱 솲 솳 솴 솵 솶 솷 솸 솹 솺 솻 솼 솽 솾 솿 쇀 쇁 쇂 쇃 쇄 쇅 쇆 쇇 쇈 쇉 쇊 쇋 쇌 쇍 쇎 쇏 쇐 쇑 쇒 쇓 쇔 쇕 쇖 쇗 쇘 쇙 쇚 쇛 쇜 쇝 쇞 쇟 쇠 쇡 쇢 쇣 쇤 쇥 쇦 쇧 쇨 쇩 쇪 쇫 쇬 쇭 쇮 쇯 쇰 쇱 쇲 쇳 쇴 쇵 쇶 쇷 쇸 쇹 쇺 쇻 쇼 쇽 쇾 쇿 숀 숁 숂 숃 숄 숅 숆 숇 숈 숉 숊 숋 숌 숍 숎 숏 숐 숑 숒 숓 숔 숕 숖 숗 수 숙 숚 숛 순 숝 숞 숟 술 숡 숢 숣 숤 숥 숦 숧 숨 숩 숪 숫 숬 숭 숮 숯 숰 숱 숲 숳 숴 숵 숶 숷 숸 숹 숺 숻 숼 숽 숾 숿 쉀 쉁 쉂 쉃 쉄 쉅 쉆 쉇 쉈 쉉 쉊 쉋 쉌 쉍 쉎 쉏 쉐 쉑 쉒 쉓 쉔 쉕 쉖 쉗 쉘 쉙 쉚 쉛 쉜 쉝 쉞 쉟 쉠 쉡 쉢 쉣 쉤 쉥 쉦 쉧 쉨 쉩 쉪 쉫 쉬 쉭 쉮 쉯 쉰 쉱 쉲 쉳 쉴 쉵 쉶 쉷 쉸 쉹 쉺 쉻 쉼 쉽 쉾 쉿 슀 슁 슂 슃 슄 슅 슆 슇 슈 슉 슊 슋 슌 슍 슎 슏 슐 슑 슒 슓 슔 슕 슖 슗 슘 슙 슚 슛 슜 슝 슞 슟 슠 슡 슢 슣 스 슥 슦 슧 슨 슩 슪 슫 슬 슭 슮 슯 슰 슱 슲 슳 슴 습 슶 슷 슸 승 슺 슻 슼 슽 슾 슿 싀 싁 싂 싃 싄 싅 싆 싇 싈 싉 싊 싋 싌 싍 싎 싏 싐 싑 싒 싓 싔 싕 싖 싗 싘 싙 싚 싛 시 식 싞 싟 신 싡 싢 싣 실 싥 싦 싧 싨 싩 싪 싫 심 십 싮 싯 싰 싱 싲 싳 싴 싵 싶 싷 싸 싹 싺 싻 싼 싽 싾 싿 쌀 쌁 쌂 쌃 쌄 쌅 쌆 쌇 쌈 쌉 쌊 쌋 쌌 쌍 쌎 쌏 쌐 쌑 쌒 쌓 쌔 쌕 쌖 쌗 쌘 쌙 쌚 쌛 쌜 쌝 쌞 쌟 쌠 쌡 쌢 쌣 쌤 쌥 쌦 쌧 쌨 쌩 쌪 쌫 쌬 쌭 쌮 쌯 쌰 쌱 쌲 쌳 쌴 쌵 쌶 쌷 쌸 쌹 쌺 쌻 쌼 쌽 쌾 쌿 썀 썁 썂 썃 썄 썅 썆 썇 썈 썉 썊 썋 썌 썍 썎 썏 썐 썑 썒 썓 썔 썕 썖 썗 썘 썙 썚 썛 썜 썝 썞 썟 썠 썡 썢 썣 썤 썥 썦 썧 써 썩 썪 썫 썬 썭 썮 썯 썰 썱 썲 썳 썴 썵 썶 썷 썸 썹 썺 썻 썼 썽 썾 썿 쎀 쎁 쎂 쎃 쎄 쎅 쎆 쎇 쎈 쎉 쎊 쎋 쎌 쎍 쎎 쎏 쎐 쎑 쎒 쎓 쎔 쎕 쎖 쎗 쎘 쎙 쎚 쎛 쎜 쎝 쎞 쎟 쎠 쎡 쎢 쎣 쎤 쎥 쎦 쎧 쎨 쎩 쎪 쎫 쎬 쎭 쎮 쎯 쎰 쎱 쎲 쎳 쎴 쎵 쎶 쎷 쎸 쎹 쎺 쎻 쎼 쎽 쎾 쎿 쏀 쏁 쏂 쏃 쏄 쏅 쏆 쏇 쏈 쏉 쏊 쏋 쏌 쏍 쏎 쏏 쏐 쏑 쏒 쏓 쏔 쏕 쏖 쏗 쏘 쏙 쏚 쏛 쏜 쏝 쏞 쏟 쏠 쏡 쏢 쏣 쏤 쏥 쏦 쏧 쏨 쏩 쏪 쏫 쏬 쏭 쏮 쏯 쏰 쏱 쏲 쏳 쏴 쏵 쏶 쏷 쏸 쏹 쏺 쏻 쏼 쏽 쏾 쏿 쐀 쐁 쐂 쐃 쐄 쐅 쐆 쐇 쐈 쐉 쐊 쐋 쐌 쐍 쐎 쐏 쐐 쐑 쐒 쐓 쐔 쐕 쐖 쐗 쐘 쐙 쐚 쐛 쐜 쐝 쐞 쐟 쐠 쐡 쐢 쐣 쐤 쐥 쐦 쐧 쐨 쐩 쐪 쐫 쐬 쐭 쐮 쐯 쐰 쐱 쐲 쐳 쐴 쐵 쐶 쐷 쐸 쐹 쐺 쐻 쐼 쐽 쐾 쐿 쑀 쑁 쑂 쑃 쑄 쑅 쑆 쑇 쑈 쑉 쑊 쑋 쑌 쑍 쑎 쑏 쑐 쑑 쑒 쑓 쑔 쑕 쑖 쑗 쑘 쑙 쑚 쑛 쑜 쑝 쑞 쑟 쑠 쑡 쑢 쑣 쑤 쑥 쑦 쑧 쑨 쑩 쑪 쑫 쑬 쑭 쑮 쑯 쑰 쑱 쑲 쑳 쑴 쑵 쑶 쑷 쑸 쑹 쑺 쑻 쑼 쑽 쑾 쑿 쒀 쒁 쒂 쒃 쒄 쒅 쒆 쒇 쒈 쒉 쒊 쒋 쒌 쒍 쒎 쒏 쒐 쒑 쒒 쒓 쒔 쒕 쒖 쒗 쒘 쒙 쒚 쒛 쒜 쒝 쒞 쒟 쒠 쒡 쒢 쒣 쒤 쒥 쒦 쒧 쒨 쒩 쒪 쒫 쒬 쒭 쒮 쒯 쒰 쒱 쒲 쒳 쒴 쒵 쒶 쒷 쒸 쒹 쒺 쒻 쒼 쒽 쒾 쒿 쓀 쓁 쓂 쓃 쓄 쓅 쓆 쓇 쓈 쓉 쓊 쓋 쓌 쓍 쓎 쓏 쓐 쓑 쓒 쓓 쓔 쓕 쓖 쓗 쓘 쓙 쓚 쓛 쓜 쓝 쓞 쓟 쓠 쓡 쓢 쓣 쓤 쓥 쓦 쓧 쓨 쓩 쓪 쓫 쓬 쓭 쓮 쓯 쓰 쓱 쓲 쓳 쓴 쓵 쓶 쓷 쓸 쓹 쓺 쓻 쓼 쓽 쓾 쓿 씀 씁 씂 씃 씄 씅 씆 씇 씈 씉 씊 씋 씌 씍 씎 씏 씐 씑 씒 씓 씔 씕 씖 씗 씘 씙 씚 씛 씜 씝 씞 씟 씠 씡 씢 씣 씤 씥 씦 씧 씨 씩 씪 씫 씬 씭 씮 씯 씰 씱 씲 씳 씴 씵 씶 씷 씸 씹 씺 씻 씼 씽 씾 씿 앀 앁 앂 앃 아 악 앆 앇 안 앉 않 앋 알 앍 앎 앏 앐 앑 앒 앓 암 압 앖 앗 았 앙 앚 앛 앜 앝 앞 앟 애 액 앢 앣 앤 앥 앦 앧 앨 앩 앪 앫 앬 앭 앮 앯 앰 앱 앲 앳 앴 앵 앶 앷 앸 앹 앺 앻 야 약 앾 앿 얀 얁 얂 얃 얄 얅 얆 얇 얈 얉 얊 얋 얌 얍 얎 얏 얐 양 얒 얓 얔 얕 얖 얗 얘 얙 얚 얛 얜 얝 얞 얟 얠 얡 얢 얣 얤 얥 얦 얧 얨 얩 얪 얫 얬 얭 얮 얯 얰 얱 얲 얳 어 억 얶 얷 언 얹 얺 얻 얼 얽 얾 얿 엀 엁 엂 엃 엄 업 없 엇 었 엉 엊 엋 엌 엍 엎 엏 에 엑 엒 엓 엔 엕 엖 엗 엘 엙 엚 엛 엜 엝 엞 엟 엠 엡 엢 엣 엤 엥 엦 엧 엨 엩 엪 엫 여 역 엮 엯 연 엱 엲 엳 열 엵 엶 엷 엸 엹 엺 엻 염 엽 엾 엿 였 영 옂 옃 옄 옅 옆 옇 예 옉 옊 옋 옌 옍 옎 옏 옐 옑 옒 옓 옔 옕 옖 옗 옘 옙 옚 옛 옜 옝 옞 옟 옠 옡 옢 옣 오 옥 옦 옧 온 옩 옪 옫 올 옭 옮 옯 옰 옱 옲 옳 옴 옵 옶 옷 옸 옹 옺 옻 옼 옽 옾 옿 와 왁 왂 왃 완 왅 왆 왇 왈 왉 왊 왋 왌 왍 왎 왏 왐 왑 왒 왓 왔 왕 왖 왗 왘 왙 왚 왛 왜 왝 왞 왟 왠 왡 왢 왣 왤 왥 왦 왧 왨 왩 왪 왫 왬 왭 왮 왯 왰 왱 왲 왳 왴 왵 왶 왷 외 왹 왺 왻 왼 왽 왾 왿 욀 욁 욂 욃 욄 욅 욆 욇 욈 욉 욊 욋 욌 욍 욎 욏 욐 욑 욒 욓 요 욕 욖 욗 욘 욙 욚 욛 욜 욝 욞 욟 욠 욡 욢 욣 욤 욥 욦 욧 욨 용 욪 욫 욬 욭 욮 욯 우 욱 욲 욳 운 욵 욶 욷 울 욹 욺 욻 욼 욽 욾 욿 움 웁 웂 웃 웄 웅 웆 웇 웈 웉 웊 웋 워 웍 웎 웏 원 웑 웒 웓 월 웕 웖 웗 웘 웙 웚 웛 웜 웝 웞 웟 웠 웡 웢 웣 웤 웥 웦 웧 웨 웩 웪 웫 웬 웭 웮 웯 웰 웱 웲 웳 웴 웵 웶 웷 웸 웹 웺 웻 웼 웽 웾 웿 윀 윁 윂 윃 위 윅 윆 윇 윈 윉 윊 윋 윌 윍 윎 윏 윐 윑 윒 윓 윔 윕 윖 윗 윘 윙 윚 윛 윜 윝 윞 윟 유 육 윢 윣 윤 윥 윦 윧 율 윩 윪 윫 윬 윭 윮 윯 윰 윱 윲 윳 윴 융 윶 윷 윸 윹 윺 윻 으 윽 윾 윿 은 읁 읂 읃 을 읅 읆 읇 읈 읉 읊 읋 음 읍 읎 읏 읐 응 읒 읓 읔 읕 읖 읗 의 읙 읚 읛 읜 읝 읞 읟 읠 읡 읢 읣 읤 읥 읦 읧 읨 읩 읪 읫 읬 읭 읮 읯 읰 읱 읲 읳 이 익 읶 읷 인 읹 읺 읻 일 읽 읾 읿 잀 잁 잂 잃 임 입 잆 잇 있 잉 잊 잋 잌 잍 잎 잏 자 작 잒 잓 잔 잕 잖 잗 잘 잙 잚 잛 잜 잝 잞 잟 잠 잡 잢 잣 잤 장 잦 잧 잨 잩 잪 잫 재 잭 잮 잯 잰 잱 잲 잳 잴 잵 잶 잷 잸 잹 잺 잻 잼 잽 잾 잿 쟀 쟁 쟂 쟃 쟄 쟅 쟆 쟇 쟈 쟉 쟊 쟋 쟌 쟍 쟎 쟏 쟐 쟑 쟒 쟓 쟔 쟕 쟖 쟗 쟘 쟙 쟚 쟛 쟜 쟝 쟞 쟟 쟠 쟡 쟢 쟣 쟤 쟥 쟦 쟧 쟨 쟩 쟪 쟫 쟬 쟭 쟮 쟯 쟰 쟱 쟲 쟳 쟴 쟵 쟶 쟷 쟸 쟹 쟺 쟻 쟼 쟽 쟾 쟿 저 적 젂 젃 전 젅 젆 젇 절 젉 젊 젋 젌 젍 젎 젏 점 접 젒 젓 젔 정 젖 젗 젘 젙 젚 젛 제 젝 젞 젟 젠 젡 젢 젣 젤 젥 젦 젧 젨 젩 젪 젫 젬 젭 젮 젯 젰 젱 젲 젳 젴 젵 젶 젷 져 젹 젺 젻 젼 젽 젾 젿 졀 졁 졂 졃 졄 졅 졆 졇 졈 졉 졊 졋 졌 졍 졎 졏 졐 졑 졒 졓 졔 졕 졖 졗 졘 졙 졚 졛 졜 졝 졞 졟 졠 졡 졢 졣 졤 졥 졦 졧 졨 졩 졪 졫 졬 졭 졮 졯 조 족 졲 졳 존 졵 졶 졷 졸 졹 졺 졻 졼 졽 졾 졿 좀 좁 좂 좃 좄 종 좆 좇 좈 좉 좊 좋 좌 좍 좎 좏 좐 좑 좒 좓 좔 좕 좖 좗 좘 좙 좚 좛 좜 좝 좞 좟 좠 좡 좢 좣 좤 좥 좦 좧 좨 좩 좪 좫 좬 좭 좮 좯 좰 좱 좲 좳 좴 좵 좶 좷 좸 좹 좺 좻 좼 좽 좾 좿 죀 죁 죂 죃 죄 죅 죆 죇 죈 죉 죊 죋 죌 죍 죎 죏 죐 죑 죒 죓 죔 죕 죖 죗 죘 죙 죚 죛 죜 죝 죞 죟 죠 죡 죢 죣 죤 죥 죦 죧 죨 죩 죪 죫 죬 죭 죮 죯 죰 죱 죲 죳 죴 죵 죶 죷 죸 죹 죺 죻 주 죽 죾 죿 준 줁 줂 줃 줄 줅 줆 줇 줈 줉 줊 줋 줌 줍 줎 줏 줐 중 줒 줓 줔 줕 줖 줗 줘 줙 줚 줛 줜 줝 줞 줟 줠 줡 줢 줣 줤 줥 줦 줧 줨 줩 줪 줫 줬 줭 줮 줯 줰 줱 줲 줳 줴 줵 줶 줷 줸 줹 줺 줻 줼 줽 줾 줿 쥀 쥁 쥂 쥃 쥄 쥅 쥆 쥇 쥈 쥉 쥊 쥋 쥌 쥍 쥎 쥏 쥐 쥑 쥒 쥓 쥔 쥕 쥖 쥗 쥘 쥙 쥚 쥛 쥜 쥝 쥞 쥟 쥠 쥡 쥢 쥣 쥤 쥥 쥦 쥧 쥨 쥩 쥪 쥫 쥬 쥭 쥮 쥯 쥰 쥱 쥲 쥳 쥴 쥵 쥶 쥷 쥸 쥹 쥺 쥻 쥼 쥽 쥾 쥿 즀 즁 즂 즃 즄 즅 즆 즇 즈 즉 즊 즋 즌 즍 즎 즏 즐 즑 즒 즓 즔 즕 즖 즗 즘 즙 즚 즛 즜 증 즞 즟 즠 즡 즢 즣 즤 즥 즦 즧 즨 즩 즪 즫 즬 즭 즮 즯 즰 즱 즲 즳 즴 즵 즶 즷 즸 즹 즺 즻 즼 즽 즾 즿 지 직 짂 짃 진 짅 짆 짇 질 짉 짊 짋 짌 짍 짎 짏 짐 집 짒 짓 짔 징 짖 짗 짘 짙 짚 짛 짜 짝 짞 짟 짠 짡 짢 짣 짤 짥 짦 짧 짨 짩 짪 짫 짬 짭 짮 짯 짰 짱 짲 짳 짴 짵 짶 짷 째 짹 짺 짻 짼 짽 짾 짿 쨀 쨁 쨂 쨃 쨄 쨅 쨆 쨇 쨈 쨉 쨊 쨋 쨌 쨍 쨎 쨏 쨐 쨑 쨒 쨓 쨔 쨕 쨖 쨗 쨘 쨙 쨚 쨛 쨜 쨝 쨞 쨟 쨠 쨡 쨢 쨣 쨤 쨥 쨦 쨧 쨨 쨩 쨪 쨫 쨬 쨭 쨮 쨯 쨰 쨱 쨲 쨳 쨴 쨵 쨶 쨷 쨸 쨹 쨺 쨻 쨼 쨽 쨾 쨿 쩀 쩁 쩂 쩃 쩄 쩅 쩆 쩇 쩈 쩉 쩊 쩋 쩌 쩍 쩎 쩏 쩐 쩑 쩒 쩓 쩔 쩕 쩖 쩗 쩘 쩙 쩚 쩛 쩜 쩝 쩞 쩟 쩠 쩡 쩢 쩣 쩤 쩥 쩦 쩧 쩨 쩩 쩪 쩫 쩬 쩭 쩮 쩯 쩰 쩱 쩲 쩳 쩴 쩵 쩶 쩷 쩸 쩹 쩺 쩻 쩼 쩽 쩾 쩿 쪀 쪁 쪂 쪃 쪄 쪅 쪆 쪇 쪈 쪉 쪊 쪋 쪌 쪍 쪎 쪏 쪐 쪑 쪒 쪓 쪔 쪕 쪖 쪗 쪘 쪙 쪚 쪛 쪜 쪝 쪞 쪟 쪠 쪡 쪢 쪣 쪤 쪥 쪦 쪧 쪨 쪩 쪪 쪫 쪬 쪭 쪮 쪯 쪰 쪱 쪲 쪳 쪴 쪵 쪶 쪷 쪸 쪹 쪺 쪻 쪼 쪽 쪾 쪿 쫀 쫁 쫂 쫃 쫄 쫅 쫆 쫇 쫈 쫉 쫊 쫋 쫌 쫍 쫎 쫏 쫐 쫑 쫒 쫓 쫔 쫕 쫖 쫗 쫘 쫙 쫚 쫛 쫜 쫝 쫞 쫟 쫠 쫡 쫢 쫣 쫤 쫥 쫦 쫧 쫨 쫩 쫪 쫫 쫬 쫭 쫮 쫯 쫰 쫱 쫲 쫳 쫴 쫵 쫶 쫷 쫸 쫹 쫺 쫻 쫼 쫽 쫾 쫿 쬀 쬁 쬂 쬃 쬄 쬅 쬆 쬇 쬈 쬉 쬊 쬋 쬌 쬍 쬎 쬏 쬐 쬑 쬒 쬓 쬔 쬕 쬖 쬗 쬘 쬙 쬚 쬛 쬜 쬝 쬞 쬟 쬠 쬡 쬢 쬣 쬤 쬥 쬦 쬧 쬨 쬩 쬪 쬫 쬬 쬭 쬮 쬯 쬰 쬱 쬲 쬳 쬴 쬵 쬶 쬷 쬸 쬹 쬺 쬻 쬼 쬽 쬾 쬿 쭀 쭁 쭂 쭃 쭄 쭅 쭆 쭇 쭈 쭉 쭊 쭋 쭌 쭍 쭎 쭏 쭐 쭑 쭒 쭓 쭔 쭕 쭖 쭗 쭘 쭙 쭚 쭛 쭜 쭝 쭞 쭟 쭠 쭡 쭢 쭣 쭤 쭥 쭦 쭧 쭨 쭩 쭪 쭫 쭬 쭭 쭮 쭯 쭰 쭱 쭲 쭳 쭴 쭵 쭶 쭷 쭸 쭹 쭺 쭻 쭼 쭽 쭾 쭿 쮀 쮁 쮂 쮃 쮄 쮅 쮆 쮇 쮈 쮉 쮊 쮋 쮌 쮍 쮎 쮏 쮐 쮑 쮒 쮓 쮔 쮕 쮖 쮗 쮘 쮙 쮚 쮛 쮜 쮝 쮞 쮟 쮠 쮡 쮢 쮣 쮤 쮥 쮦 쮧 쮨 쮩 쮪 쮫 쮬 쮭 쮮 쮯 쮰 쮱 쮲 쮳 쮴 쮵 쮶 쮷 쮸 쮹 쮺 쮻 쮼 쮽 쮾 쮿 쯀 쯁 쯂 쯃 쯄 쯅 쯆 쯇 쯈 쯉 쯊 쯋 쯌 쯍 쯎 쯏 쯐 쯑 쯒 쯓 쯔 쯕 쯖 쯗 쯘 쯙 쯚 쯛 쯜 쯝 쯞 쯟 쯠 쯡 쯢 쯣 쯤 쯥 쯦 쯧 쯨 쯩 쯪 쯫 쯬 쯭 쯮 쯯 쯰 쯱 쯲 쯳 쯴 쯵 쯶 쯷 쯸 쯹 쯺 쯻 쯼 쯽 쯾 쯿 찀 찁 찂 찃 찄 찅 찆 찇 찈 찉 찊 찋 찌 찍 찎 찏 찐 찑 찒 찓 찔 찕 찖 찗 찘 찙 찚 찛 찜 찝 찞 찟 찠 찡 찢 찣 찤 찥 찦 찧 차 착 찪 찫 찬 찭 찮 찯 찰 찱 찲 찳 찴 찵 찶 찷 참 찹 찺 찻 찼 창 찾 찿 챀 챁 챂 챃 채 책 챆 챇 챈 챉 챊 챋 챌 챍 챎 챏 챐 챑 챒 챓 챔 챕 챖 챗 챘 챙 챚 챛 챜 챝 챞 챟 챠 챡 챢 챣 챤 챥 챦 챧 챨 챩 챪 챫 챬 챭 챮 챯 챰 챱 챲 챳 챴 챵 챶 챷 챸 챹 챺 챻 챼 챽 챾 챿 첀 첁 첂 첃 첄 첅 첆 첇 첈 첉 첊 첋 첌 첍 첎 첏 첐 첑 첒 첓 첔 첕 첖 첗 처 척 첚 첛 천 첝 첞 첟 철 첡 첢 첣 첤 첥 첦 첧 첨 첩 첪 첫 첬 청 첮 첯 첰 첱 첲 첳 체 첵 첶 첷 첸 첹 첺 첻 첼 첽 첾 첿 쳀 쳁 쳂 쳃 쳄 쳅 쳆 쳇 쳈 쳉 쳊 쳋 쳌 쳍 쳎 쳏 쳐 쳑 쳒 쳓 쳔 쳕 쳖 쳗 쳘 쳙 쳚 쳛 쳜 쳝 쳞 쳟 쳠 쳡 쳢 쳣 쳤 쳥 쳦 쳧 쳨 쳩 쳪 쳫 쳬 쳭 쳮 쳯 쳰 쳱 쳲 쳳 쳴 쳵 쳶 쳷 쳸 쳹 쳺 쳻 쳼 쳽 쳾 쳿 촀 촁 촂 촃 촄 촅 촆 촇 초 촉 촊 촋 촌 촍 촎 촏 촐 촑 촒 촓 촔 촕 촖 촗 촘 촙 촚 촛 촜 총 촞 촟 촠 촡 촢 촣 촤 촥 촦 촧 촨 촩 촪 촫 촬 촭 촮 촯 촰 촱 촲 촳 촴 촵 촶 촷 촸 촹 촺 촻 촼 촽 촾 촿 쵀 쵁 쵂 쵃 쵄 쵅 쵆 쵇 쵈 쵉 쵊 쵋 쵌 쵍 쵎 쵏 쵐 쵑 쵒 쵓 쵔 쵕 쵖 쵗 쵘 쵙 쵚 쵛 최 쵝 쵞 쵟 쵠 쵡 쵢 쵣 쵤 쵥 쵦 쵧 쵨 쵩 쵪 쵫 쵬 쵭 쵮 쵯 쵰 쵱 쵲 쵳 쵴 쵵 쵶 쵷 쵸 쵹 쵺 쵻 쵼 쵽 쵾 쵿 춀 춁 춂 춃 춄 춅 춆 춇 춈 춉 춊 춋 춌 춍 춎 춏 춐 춑 춒 춓 추 축 춖 춗 춘 춙 춚 춛 출 춝 춞 춟 춠 춡 춢 춣 춤 춥 춦 춧 춨 충 춪 춫 춬 춭 춮 춯 춰 춱 춲 춳 춴 춵 춶 춷 춸 춹 춺 춻 춼 춽 춾 춿 췀 췁 췂 췃 췄 췅 췆 췇 췈 췉 췊 췋 췌 췍 췎 췏 췐 췑 췒 췓 췔 췕 췖 췗 췘 췙 췚 췛 췜 췝 췞 췟 췠 췡 췢 췣 췤 췥 췦 췧 취 췩 췪 췫 췬 췭 췮 췯 췰 췱 췲 췳 췴 췵 췶 췷 췸 췹 췺 췻 췼 췽 췾 췿 츀 츁 츂 츃 츄 츅 츆 츇 츈 츉 츊 츋 츌 츍 츎 츏 츐 츑 츒 츓 츔 츕 츖 츗 츘 츙 츚 츛 츜 츝 츞 츟 츠 측 츢 츣 츤 츥 츦 츧 츨 츩 츪 츫 츬 츭 츮 츯 츰 츱 츲 츳 츴 층 츶 츷 츸 츹 츺 츻 츼 츽 츾 츿 칀 칁 칂 칃 칄 칅 칆 칇 칈 칉 칊 칋 칌 칍 칎 칏 칐 칑 칒 칓 칔 칕 칖 칗 치 칙 칚 칛 친 칝 칞 칟 칠 칡 칢 칣 칤 칥 칦 칧 침 칩 칪 칫 칬 칭 칮 칯 칰 칱 칲 칳 카 칵 칶 칷 칸 칹 칺 칻 칼 칽 칾 칿 캀 캁 캂 캃 캄 캅 캆 캇 캈 캉 캊 캋 캌 캍 캎 캏 캐 캑 캒 캓 캔 캕 캖 캗 캘 캙 캚 캛 캜 캝 캞 캟 캠 캡 캢 캣 캤 캥 캦 캧 캨 캩 캪 캫 캬 캭 캮 캯 캰 캱 캲 캳 캴 캵 캶 캷 캸 캹 캺 캻 캼 캽 캾 캿 컀 컁 컂 컃 컄 컅 컆 컇 컈 컉 컊 컋 컌 컍 컎 컏 컐 컑 컒 컓 컔 컕 컖 컗 컘 컙 컚 컛 컜 컝 컞 컟 컠 컡 컢 컣 커 컥 컦 컧 컨 컩 컪 컫 컬 컭 컮 컯 컰 컱 컲 컳 컴 컵 컶 컷 컸 컹 컺 컻 컼 컽 컾 컿 케 켁 켂 켃 켄 켅 켆 켇 켈 켉 켊 켋 켌 켍 켎 켏 켐 켑 켒 켓 켔 켕 켖 켗 켘 켙 켚 켛 켜 켝 켞 켟 켠 켡 켢 켣 켤 켥 켦 켧 켨 켩 켪 켫 켬 켭 켮 켯 켰 켱 켲 켳 켴 켵 켶 켷 켸 켹 켺 켻 켼 켽 켾 켿 콀 콁 콂 콃 콄 콅 콆 콇 콈 콉 콊 콋 콌 콍 콎 콏 콐 콑 콒 콓 코 콕 콖 콗 콘 콙 콚 콛 콜 콝 콞 콟 콠 콡 콢 콣 콤 콥 콦 콧 콨 콩 콪 콫 콬 콭 콮 콯 콰 콱 콲 콳 콴 콵 콶 콷 콸 콹 콺 콻 콼 콽 콾 콿 쾀 쾁 쾂 쾃 쾄 쾅 쾆 쾇 쾈 쾉 쾊 쾋 쾌 쾍 쾎 쾏 쾐 쾑 쾒 쾓 쾔 쾕 쾖 쾗 쾘 쾙 쾚 쾛 쾜 쾝 쾞 쾟 쾠 쾡 쾢 쾣 쾤 쾥 쾦 쾧 쾨 쾩 쾪 쾫 쾬 쾭 쾮 쾯 쾰 쾱 쾲 쾳 쾴 쾵 쾶 쾷 쾸 쾹 쾺 쾻 쾼 쾽 쾾 쾿 쿀 쿁 쿂 쿃 쿄 쿅 쿆 쿇 쿈 쿉 쿊 쿋 쿌 쿍 쿎 쿏 쿐 쿑 쿒 쿓 쿔 쿕 쿖 쿗 쿘 쿙 쿚 쿛 쿜 쿝 쿞 쿟 쿠 쿡 쿢 쿣 쿤 쿥 쿦 쿧 쿨 쿩 쿪 쿫 쿬 쿭 쿮 쿯 쿰 쿱 쿲 쿳 쿴 쿵 쿶 쿷 쿸 쿹 쿺 쿻 쿼 쿽 쿾 쿿 퀀 퀁 퀂 퀃 퀄 퀅 퀆 퀇 퀈 퀉 퀊 퀋 퀌 퀍 퀎 퀏 퀐 퀑 퀒 퀓 퀔 퀕 퀖 퀗 퀘 퀙 퀚 퀛 퀜 퀝 퀞 퀟 퀠 퀡 퀢 퀣 퀤 퀥 퀦 퀧 퀨 퀩 퀪 퀫 퀬 퀭 퀮 퀯 퀰 퀱 퀲 퀳 퀴 퀵 퀶 퀷 퀸 퀹 퀺 퀻 퀼 퀽 퀾 퀿 큀 큁 큂 큃 큄 큅 큆 큇 큈 큉 큊 큋 큌 큍 큎 큏 큐 큑 큒 큓 큔 큕 큖 큗 큘 큙 큚 큛 큜 큝 큞 큟 큠 큡 큢 큣 큤 큥 큦 큧 큨 큩 큪 큫 크 큭 큮 큯 큰 큱 큲 큳 클 큵 큶 큷 큸 큹 큺 큻 큼 큽 큾 큿 킀 킁 킂 킃 킄 킅 킆 킇 킈 킉 킊 킋 킌 킍 킎 킏 킐 킑 킒 킓 킔 킕 킖 킗 킘 킙 킚 킛 킜 킝 킞 킟 킠 킡 킢 킣 키 킥 킦 킧 킨 킩 킪 킫 킬 킭 킮 킯 킰 킱 킲 킳 킴 킵 킶 킷 킸 킹 킺 킻 킼 킽 킾 킿 타 탁 탂 탃 탄 탅 탆 탇 탈 탉 탊 탋 탌 탍 탎 탏 탐 탑 탒 탓 탔 탕 탖 탗 탘 탙 탚 탛 태 택 탞 탟 탠 탡 탢 탣 탤 탥 탦 탧 탨 탩 탪 탫 탬 탭 탮 탯 탰 탱 탲 탳 탴 탵 탶 탷 탸 탹 탺 탻 탼 탽 탾 탿 턀 턁 턂 턃 턄 턅 턆 턇 턈 턉 턊 턋 턌 턍 턎 턏 턐 턑 턒 턓 턔 턕 턖 턗 턘 턙 턚 턛 턜 턝 턞 턟 턠 턡 턢 턣 턤 턥 턦 턧 턨 턩 턪 턫 턬 턭 턮 턯 터 턱 턲 턳 턴 턵 턶 턷 털 턹 턺 턻 턼 턽 턾 턿 텀 텁 텂 텃 텄 텅 텆 텇 텈 텉 텊 텋 테 텍 텎 텏 텐 텑 텒 텓 텔 텕 텖 텗 텘 텙 텚 텛 템 텝 텞 텟 텠 텡 텢 텣 텤 텥 텦 텧 텨 텩 텪 텫 텬 텭 텮 텯 텰 텱 텲 텳 텴 텵 텶 텷 텸 텹 텺 텻 텼 텽 텾 텿 톀 톁 톂 톃 톄 톅 톆 톇 톈 톉 톊 톋 톌 톍 톎 톏 톐 톑 톒 톓 톔 톕 톖 톗 톘 톙 톚 톛 톜 톝 톞 톟 토 톡 톢 톣 톤 톥 톦 톧 톨 톩 톪 톫 톬 톭 톮 톯 톰 톱 톲 톳 톴 통 톶 톷 톸 톹 톺 톻 톼 톽 톾 톿 퇀 퇁 퇂 퇃 퇄 퇅 퇆 퇇 퇈 퇉 퇊 퇋 퇌 퇍 퇎 퇏 퇐 퇑 퇒 퇓 퇔 퇕 퇖 퇗 퇘 퇙 퇚 퇛 퇜 퇝 퇞 퇟 퇠 퇡 퇢 퇣 퇤 퇥 퇦 퇧 퇨 퇩 퇪 퇫 퇬 퇭 퇮 퇯 퇰 퇱 퇲 퇳 퇴 퇵 퇶 퇷 퇸 퇹 퇺 퇻 퇼 퇽 퇾 퇿 툀 툁 툂 툃 툄 툅 툆 툇 툈 툉 툊 툋 툌 툍 툎 툏 툐 툑 툒 툓 툔 툕 툖 툗 툘 툙 툚 툛 툜 툝 툞 툟 툠 툡 툢 툣 툤 툥 툦 툧 툨 툩 툪 툫 투 툭 툮 툯 툰 툱 툲 툳 툴 툵 툶 툷 툸 툹 툺 툻 툼 툽 툾 툿 퉀 퉁 퉂 퉃 퉄 퉅 퉆 퉇 퉈 퉉 퉊 퉋 퉌 퉍 퉎 퉏 퉐 퉑 퉒 퉓 퉔 퉕 퉖 퉗 퉘 퉙 퉚 퉛 퉜 퉝 퉞 퉟 퉠 퉡 퉢 퉣 퉤 퉥 퉦 퉧 퉨 퉩 퉪 퉫 퉬 퉭 퉮 퉯 퉰 퉱 퉲 퉳 퉴 퉵 퉶 퉷 퉸 퉹 퉺 퉻 퉼 퉽 퉾 퉿 튀 튁 튂 튃 튄 튅 튆 튇 튈 튉 튊 튋 튌 튍 튎 튏 튐 튑 튒 튓 튔 튕 튖 튗 튘 튙 튚 튛 튜 튝 튞 튟 튠 튡 튢 튣 튤 튥 튦 튧 튨 튩 튪 튫 튬 튭 튮 튯 튰 튱 튲 튳 튴 튵 튶 튷 트 특 튺 튻 튼 튽 튾 튿 틀 틁 틂 틃 틄 틅 틆 틇 틈 틉 틊 틋 틌 틍 틎 틏 틐 틑 틒 틓 틔 틕 틖 틗 틘 틙 틚 틛 틜 틝 틞 틟 틠 틡 틢 틣 틤 틥 틦 틧 틨 틩 틪 틫 틬 틭 틮 틯 티 틱 틲 틳 틴 틵 틶 틷 틸 틹 틺 틻 틼 틽 틾 틿 팀 팁 팂 팃 팄 팅 팆 팇 팈 팉 팊 팋 파 팍 팎 팏 판 팑 팒 팓 팔 팕 팖 팗 팘 팙 팚 팛 팜 팝 팞 팟 팠 팡 팢 팣 팤 팥 팦 팧 패 팩 팪 팫 팬 팭 팮 팯 팰 팱 팲 팳 팴 팵 팶 팷 팸 팹 팺 팻 팼 팽 팾 팿 퍀 퍁 퍂 퍃 퍄 퍅 퍆 퍇 퍈 퍉 퍊 퍋 퍌 퍍 퍎 퍏 퍐 퍑 퍒 퍓 퍔 퍕 퍖 퍗 퍘 퍙 퍚 퍛 퍜 퍝 퍞 퍟 퍠 퍡 퍢 퍣 퍤 퍥 퍦 퍧 퍨 퍩 퍪 퍫 퍬 퍭 퍮 퍯 퍰 퍱 퍲 퍳 퍴 퍵 퍶 퍷 퍸 퍹 퍺 퍻 퍼 퍽 퍾 퍿 펀 펁 펂 펃 펄 펅 펆 펇 펈 펉 펊 펋 펌 펍 펎 펏 펐 펑 펒 펓 펔 펕 펖 펗 페 펙 펚 펛 펜 펝 펞 펟 펠 펡 펢 펣 펤 펥 펦 펧 펨 펩 펪 펫 펬 펭 펮 펯 펰 펱 펲 펳 펴 펵 펶 펷 편 펹 펺 펻 펼 펽 펾 펿 폀 폁 폂 폃 폄 폅 폆 폇 폈 평 폊 폋 폌 폍 폎 폏 폐 폑 폒 폓 폔 폕 폖 폗 폘 폙 폚 폛 폜 폝 폞 폟 폠 폡 폢 폣 폤 폥 폦 폧 폨 폩 폪 폫 포 폭 폮 폯 폰 폱 폲 폳 폴 폵 폶 폷 폸 폹 폺 폻 폼 폽 폾 폿 퐀 퐁 퐂 퐃 퐄 퐅 퐆 퐇 퐈 퐉 퐊 퐋 퐌 퐍 퐎 퐏 퐐 퐑 퐒 퐓 퐔 퐕 퐖 퐗 퐘 퐙 퐚 퐛 퐜 퐝 퐞 퐟 퐠 퐡 퐢 퐣 퐤 퐥 퐦 퐧 퐨 퐩 퐪 퐫 퐬 퐭 퐮 퐯 퐰 퐱 퐲 퐳 퐴 퐵 퐶 퐷 퐸 퐹 퐺 퐻 퐼 퐽 퐾 퐿 푀 푁 푂 푃 푄 푅 푆 푇 푈 푉 푊 푋 푌 푍 푎 푏 푐 푑 푒 푓 푔 푕 푖 푗 푘 푙 푚 푛 표 푝 푞 푟 푠 푡 푢 푣 푤 푥 푦 푧 푨 푩 푪 푫 푬 푭 푮 푯 푰 푱 푲 푳 푴 푵 푶 푷 푸 푹 푺 푻 푼 푽 푾 푿 풀 풁 풂 풃 풄 풅 풆 풇 품 풉 풊 풋 풌 풍 풎 풏 풐 풑 풒 풓 풔 풕 풖 풗 풘 풙 풚 풛 풜 풝 풞 풟 풠 풡 풢 풣 풤 풥 풦 풧 풨 풩 풪 풫 풬 풭 풮 풯 풰 풱 풲 풳 풴 풵 풶 풷 풸 풹 풺 풻 풼 풽 풾 풿 퓀 퓁 퓂 퓃 퓄 퓅 퓆 퓇 퓈 퓉 퓊 퓋 퓌 퓍 퓎 퓏 퓐 퓑 퓒 퓓 퓔 퓕 퓖 퓗 퓘 퓙 퓚 퓛 퓜 퓝 퓞 퓟 퓠 퓡 퓢 퓣 퓤 퓥 퓦 퓧 퓨 퓩 퓪 퓫 퓬 퓭 퓮 퓯 퓰 퓱 퓲 퓳 퓴 퓵 퓶 퓷 퓸 퓹 퓺 퓻 퓼 퓽 퓾 퓿 픀 픁 픂 픃 프 픅 픆 픇 픈 픉 픊 픋 플 픍 픎 픏 픐 픑 픒 픓 픔 픕 픖 픗 픘 픙 픚 픛 픜 픝 픞 픟 픠 픡 픢 픣 픤 픥 픦 픧 픨 픩 픪 픫 픬 픭 픮 픯 픰 픱 픲 픳 픴 픵 픶 픷 픸 픹 픺 픻 피 픽 픾 픿 핀 핁 핂 핃 필 핅 핆 핇 핈 핉 핊 핋 핌 핍 핎 핏 핐 핑 핒 핓 핔 핕 핖 핗 하 학 핚 핛 한 핝 핞 핟 할 핡 핢 핣 핤 핥 핦 핧 함 합 핪 핫 핬 항 핮 핯 핰 핱 핲 핳 해 핵 핶 핷 핸 핹 핺 핻 핼 핽 핾 핿 햀 햁 햂 햃 햄 햅 햆 햇 했 행 햊 햋 햌 햍 햎 햏 햐 햑 햒 햓 햔 햕 햖 햗 햘 햙 햚 햛 햜 햝 햞 햟 햠 햡 햢 햣 햤 향 햦 햧 햨 햩 햪 햫 햬 햭 햮 햯 햰 햱 햲 햳 햴 햵 햶 햷 햸 햹 햺 햻 햼 햽 햾 햿 헀 헁 헂 헃 헄 헅 헆 헇 허 헉 헊 헋 헌 헍 헎 헏 헐 헑 헒 헓 헔 헕 헖 헗 험 헙 헚 헛 헜 헝 헞 헟 헠 헡 헢 헣 헤 헥 헦 헧 헨 헩 헪 헫 헬 헭 헮 헯 헰 헱 헲 헳 헴 헵 헶 헷 헸 헹 헺 헻 헼 헽 헾 헿 혀 혁 혂 혃 현 혅 혆 혇 혈 혉 혊 혋 혌 혍 혎 혏 혐 협 혒 혓 혔 형 혖 혗 혘 혙 혚 혛 혜 혝 혞 혟 혠 혡 혢 혣 혤 혥 혦 혧 혨 혩 혪 혫 혬 혭 혮 혯 혰 혱 혲 혳 혴 혵 혶 혷 호 혹 혺 혻 혼 혽 혾 혿 홀 홁 홂 홃 홄 홅 홆 홇 홈 홉 홊 홋 홌 홍 홎 홏 홐 홑 홒 홓 화 확 홖 홗 환 홙 홚 홛 활 홝 홞 홟 홠 홡 홢 홣 홤 홥 홦 홧 홨 황 홪 홫 홬 홭 홮 홯 홰 홱 홲 홳 홴 홵 홶 홷 홸 홹 홺 홻 홼 홽 홾 홿 횀 횁 횂 횃 횄 횅 횆 횇 횈 횉 횊 횋 회 획 횎 횏 횐 횑 횒 횓 횔 횕 횖 횗 횘 횙 횚 횛 횜 횝 횞 횟 횠 횡 횢 횣 횤 횥 횦 횧 효 횩 횪 횫 횬 횭 횮 횯 횰 횱 횲 횳 횴 횵 횶 횷 횸 횹 횺 횻 횼 횽 횾 횿 훀 훁 훂 훃 후 훅 훆 훇 훈 훉 훊 훋 훌 훍 훎 훏 훐 훑 훒 훓 훔 훕 훖 훗 훘 훙 훚 훛 훜 훝 훞 훟 훠 훡 훢 훣 훤 훥 훦 훧 훨 훩 훪 훫 훬 훭 훮 훯 훰 훱 훲 훳 훴 훵 훶 훷 훸 훹 훺 훻 훼 훽 훾 훿 휀 휁 휂 휃 휄 휅 휆 휇 휈 휉 휊 휋 휌 휍 휎 휏 휐 휑 휒 휓 휔 휕 휖 휗 휘 휙 휚 휛 휜 휝 휞 휟 휠 휡 휢 휣 휤 휥 휦 휧 휨 휩 휪 휫 휬 휭 휮 휯 휰 휱 휲 휳 휴 휵 휶 휷 휸 휹 휺 휻 휼 휽 휾 휿 흀 흁 흂 흃 흄 흅 흆 흇 흈 흉 흊 흋 흌 흍 흎 흏 흐 흑 흒 흓 흔 흕 흖 흗 흘 흙 흚 흛 흜 흝 흞 흟 흠 흡 흢 흣 흤 흥 흦 흧 흨 흩 흪 흫 희 흭 흮 흯 흰 흱 흲 흳 흴 흵 흶 흷 흸 흹 흺 흻 흼 흽 흾 흿 힀 힁 힂 힃 힄 힅 힆 힇 히 힉 힊 힋 힌 힍 힎 힏 힐 힑 힒 힓 힔 힕 힖 힗 힘 힙 힚 힛 힜 힝 힞 힟 힠 힡 힢 힣", + 3: "丘 串 乃 久 乖 九 乞 乫 乾 亂 亘 交 京 仇 今 介 件 价 企 伋 伎 伽 佳 佶 侃 來 侊 供 係 俓 俱 個 倞 倦 倨 假 偈 健 傀 傑 傾 僅 僑 價 儆 儉 儺 光 克 兢 內 公 共 其 具 兼 冀 冠 凱 刊 刮 券 刻 剋 剛 劇 劍 劒 功 加 劤 劫 勁 勍 勘 勤 勸 勻 勾 匡 匣 區 南 卦 却 卵 卷 卿 厥 去 及 口 句 叩 叫 可 各 吉 君 告 呱 呵 咎 咬 哥 哭 啓 喀 喇 喝 喫 喬 嗜 嘉 嘔 器 囊 困 固 圈 國 圭 圻 均 坎 坑 坤 坰 坵 垢 基 埼 堀 堅 堈 堪 堺 塊 塏 境 墾 壙 壞 夔 奇 奈 奎 契 奸 妓 妗 姑 姜 姦 娘 娜 嫁 嬌 孔 季 孤 宏 官 客 宮 家 寄 寇 寡 寬 尻 局 居 屆 屈 岐 岡 岬 崎 崑 崗 嵌 嵐 嶇 嶠 工 巧 巨 己 巾 干 幹 幾 庚 庫 康 廊 廐 廓 廣 建 弓 强 彊 徑 忌 急 怪 怯 恐 恝 恪 恭 悸 愆 感 愧 愷 愾 慊 慣 慤 慨 慶 慷 憩 憬 憾 懃 懇 懦 懶 懼 戈 戒 戟 戡 扱 技 抉 拉 拏 拐 拒 拘 括 拮 拱 拳 拷 拿 捏 据 捲 捺 掘 掛 控 揀 揆 揭 擊 擎 擒 據 擧 攪 攷 改 攻 故 敎 救 敢 敬 敲 斛 斤 旗 旣 昆 昑 景 晷 暇 暖 暠 暻 曠 曲 更 曷 朗 朞 期 机 杆 杞 杰 枏 果 枯 架 枸 柑 柩 柬 柯 校 根 格 桀 桂 桔 桿 梏 梗 械 梱 棄 棋 棍 棘 棨 棺 楗 楠 極 槁 構 槐 槨 槪 槻 槿 樂 橄 橋 橘 機 檄 檎 檢 櫃 欄 權 欺 款 歌 歐 歸 殼 毆 毬 氣 求 江 汨 汲 決 汽 沂 沽 洛 洸 浪 涇 淃 淇 減 渠 渴 湳 溝 溪 滑 滾 漑 潔 潰 澗 激 濫 灌 灸 炅 炚 炬 烙 烱 煖 爛 牽 犬 狂 狗 狡 狼 獗 玖 玘 珂 珏 珖 珙 珞 珪 球 琦 琨 琪 琯 琴 瑾 璂 璟 璣 璥 瓊 瓘 瓜 甄 甘 甲 男 畇 界 畸 畺 畿 疆 疥 疳 痂 痙 痼 癎 癩 癸 皆 皎 皐 盖 監 看 眷 睾 瞰 瞼 瞿 矜 矩 矯 硅 硬 碁 碣 磎 磬 磯 磵 祁 祇 祈 祛 祺 禁 禽 科 稈 稼 稽 稿 穀 究 穹 空 窘 窟 窮 窺 竅 竟 竭 競 竿 筋 筐 筠 箇 箕 箝 管 簡 粳 糠 系 糾 紀 納 紘 級 紺 絅 結 絞 給 絳 絹 絿 經 綱 綺 緊 繫 繭 繼 缺 罐 罫 羅 羈 羌 羔 群 羹 翹 考 耆 耉 耕 耭 耿 肌 肝 股 肩 肯 肱 胛 胱 脚 脛 腔 腱 膈 膏 膠 臘 臼 舅 舊 舡 艮 艱 芎 芥 芩 芹 苛 苟 苦 苽 茄 莖 菅 菊 菌 菓 菫 菰 落 葛 葵 蓋 蕎 蕨 薑 藁 藍 藿 蘭 蘿 虔 蚣 蛟 蝎 螺 蠟 蠱 街 衢 衲 衾 衿 袈 袞 袴 裙 裸 褐 襁 襟 襤 見 規 覡 覲 覺 觀 角 計 記 訣 訶 詭 誇 誡 誥 課 諫 諾 謙 講 謳 謹 譏 警 譴 谷 谿 豈 貢 貫 貴 賈 購 赳 起 跏 距 跨 踞 蹇 蹶 躬 軀 車 軌 軍 軻 較 輕 轎 轟 辜 近 迦 迲 适 逑 逕 逵 過 遣 遽 邏 那 邯 邱 郊 郎 郡 郭 酪 醵 金 鈐 鈞 鉀 鉅 鉗 鉤 銶 鋸 鋼 錡 錤 錦 錮 鍋 鍵 鎌 鎧 鏡 鑑 鑒 鑛 開 間 閘 閣 閨 闕 關 降 階 隔 隙 雇 難 鞏 鞠 鞨 鞫 頃 頸 顆 顧 飢 餃 館 饉 饋 饑 駒 駕 駱 騎 騏 騫 驅 驕 驚 驥 骨 高 鬼 魁 鮫 鯤 鯨 鱇 鳩 鵑 鵠 鷄 鷗 鸞 麒 麴 黔 鼓 龕 龜", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "kok": { + 0: "़ ० १ २ ३ ४ ५ ६ ७ ८ ९ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क क़ ख ख़ ग ग़ घ ङ च छ ज ज़ झ ञ ट ठ ड ड़ ढ ढ़ ण त थ द ध न प फ फ़ ब भ म य य़ र ल व श ष स ह ळ ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्", + 3: "\u200c \u200d", + }, + "ksb": { + 0: "a b c d e f g h i j k l m n o p s t u v w y z", + 3: "q r x", + 5: "A B C D E F G H I J K L M N O P S T U V W Y Z", + }, + "ksf": { + 0: "a á b c d e é ǝ ǝ́ ɛ ɛ́ f g h i í j k l m n ŋ o ó ɔ ɔ́ p r s t u ú v w y z", + 3: "q x", + 5: "A B C D E Ǝ Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y Z", + }, + "ksh": { + 0: "a å ä æ b c d e ë ė f g h i j k l m n o ö œ p q r s t u ů ü v w x y z", + 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē ğ í ì ĭ î ï ī ij ı ł ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ", + }, + "ku": { + 0: "ئ ا ب پ ت ج چ ح خ د ر ز ڕ ژ س ش ع غ ف ڤ ق ک گ ل ڵ م ن ه ھ و ۆ ی ێ", + 3: "ً ٌ ٍ َ ُ ِ ّ ْ ء آ أ ؤ إ ئ ا ب ة ث ذ ص ض ط ظ ك ى ي", + }, + "ku_Latn": { + 0: "a b c ç d e ê f g h i î j k l m n o p q r s ş t u û v w x y z", + }, + "kw": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "ky": { + 0: "а б г д е ё ж з и й к л м н ӊ о ө п р с т у ү х ч ш ъ ы э ю я", + 3: "в ф ц щ ь", + }, + "lag": { + 0: "a á b c d e é f g h i í ɨ j k l m n o ó p q r s t u ú ʉ v w x y z", + 5: "A B C D E F G H I Ɨ J K L M N O P Q R S T U Ʉ V W X Y Z", + }, + "lg": { + 0: "a b c d e f g i j k l m n ny ŋ o p r s t u v w y z", + 3: "h q x", + 5: "A B C D E F G I J K L M N Ŋ O P R S T U V W Y Z", + }, + "ln": { + 0: "a á â ǎ b c d e é ê ě ɛ ɛ́ ɛ̂ ɛ̌ f g gb h i í î ǐ k l m mb mp n nd ng nk ns nt ny nz o ó ô ǒ ɔ ɔ́ ɔ̂ ɔ̌ p r s t u ú v w y z", + 3: "j q x", + 5: "A B C D E Ɛ F G Gb H I K L M Mb Mp N Nd Ng Nk Ns Nt Ny Nz O Ɔ P R S T U V W Y Z", + }, + "lo": { + 0: "່ ້ ໊ ໋ ໌ ໍ ໆ ກ ຂ ຄ ງ ຈ ສ ຊ ຍ ດ ຕ ຖ ທ ນ ບ ປ ຜ ຝ ພ ຟ ມ ຢ ຣ ລ ວ ຫ ໜ ໝ ອ ຮ ຯ ະ ັ າ ຳ ິ ີ ຶ ື ຸ ູ ົ ຼ ຽ ເ ແ ໂ ໃ ໄ", + 3: "\u200b ໐ ໑ ໒ ໓ ໔ ໕ ໖ ໗ ໘ ໙", + }, + "lt": { + 0: "a ą b c č d e ę ė f g h i į y j k l m n o p r s š t u ų ū v z ž", + 3: "i̇́ i̇̀ i̇̃ i̇ į̇ j̇ q w x", + 4: "a ą b c č d e ę ė f g h i į y j k l m n o p r s š t u ų ū v z ž", + 5: "A Ą B C Č D E Ę Ė F G H I Į Y J K L M N O P R S Š T U Ų Ū V Z Ž", + }, + "lu": { + 0: "a á à b c d e é è ɛ ɛ́ ɛ̀ f h i í ì j k l m n ng ny o ó ò ɔ ɔ́ ɔ̀ p ph q s shi t u ú ù v w y z", + 3: "g r x", + 5: "A B C D E F H I J K L M N O P Q S T U V W Y Z", + }, + "luo": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y", + 3: "q x z", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y", + }, + "luy": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "lv": { + 0: "a ā b c č d e ē f g ģ h i ī j k ķ l ļ m n ņ o p r s š t u ū v z ž", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ ‚ \" “ ” „ ( ) [ ] @ * / & # † ‡ ′ ″ §", + 3: "q w x y", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C Č D E F G Ģ H I J K Ķ L Ļ M N Ņ O P Q R S Š T U V W X Y Z Ž", + }, + "mas": { + 0: "a á à â ā b c d e é è ê ē ɛ g h i í ì î ī ɨ j k l m n ny ŋ o ó ò ô ō ɔ p r rr s sh t u ú ù û ū ʉ ʉ́ w wu y yi", + 3: "f q v x z", + 5: "A B C D E Ɛ G H I Ɨ J K L M N Ŋ O Ɔ P R S T U Ʉ W Y", + }, + "mer": { + 0: "a b c d e f g h i ĩ j k l m n o p q r s t u ũ v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "mfe": { + 0: "a b c d e f g h i j k l m n o p r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P R S T U V W X Y Z", + }, + "mg": { + 0: "a à â b d e é è ê ë f g h i ì î ï j k l m n ñ o ô p r s t v y z", + 3: "c q u w x", + 5: "A B D E F G H I J K L M N O P R S T V Y Z", + }, + "mgh": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "mk": { + 0: "а б в г д ѓ е ж з ѕ и ј к л љ м н њ о п р с т ќ у ф х ц ч џ ш", + 3: "ѐ ѝ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "А Б В Г Д Ѓ Е Ж З Ѕ И Ј К Л Љ М Н Њ О П Р С Т Ќ У Ф Х Ц Ч Џ Ш", + }, + "ml": { + 0: "\u200c \u200d ഃ അ ആ ഇ ഈ ഉ ഊ ഋ ൠ ഌ ൡ എ ഏ ഐ ഒ ഓ ഔ ക ഖ ഗ ഘ ങ ച ഛ ജ ഝ ഞ ട ഠ ഡ ഢ ണ ത ഥ ദ ധ ന പ ഫ ബ ഭ മ ം യ ര ല വ ശ ഷ സ ഹ ള ഴ റ ാ ി ീ ു ൂ ൃ െ േ ൈ ൊ ോ ൗ ൌ ്", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "mn": { + 0: "а б в г д е ё ж з и й к л м н о ө п р с т у ү ф х ц ч ш щ ъ ы ь э ю я", + 3: "ә җ ӊ һ", + }, + "mn_Mong": { + 0: "᠐ ᠑ ᠒ ᠓ ᠔ ᠕ ᠖ ᠗ ᠘ ᠙ ᠠ ᠡ ᠢ ᠣ ᠤ ᠥ ᠦ ᠧ ᠨ ᠩ ᠪ ᠫ ᠬ ᠭ ᠮ ᠯ ᠰ ᠱ ᠲ ᠳ ᠴ ᠵ ᠶ ᠷ ᠸ ᠹ ᠺ ᠻ ᠼ ᠽ ᠾ ᠿ ᡀ ᡁ ᡂ", + }, + "mr": { + 0: "़ ० १ २ ३ ४ ५ ६ ७ ८ ९ ॐ ं ँ ः अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल व श ष स ह ळ ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्", + 3: "\u200c \u200d", + 4: "र ु", + 5: "\u200d ॐ ं ः अ आ इ ई उ ऊ ऋ ऌ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल व श ष स ह ळ ऽ ॅ ्", + }, + "ms": { + 0: "a ai au b c d dz e f g h i j k kh l m n ng ngg ny o p q r s sy t ts u ua v w x y z", + 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "mt": { + 0: "a à b ċ d e è f ġ g għ h ħ i ì j k l m n o ò p q r s t u ù v w x ż z", + 3: "c y", + }, + "mua": { + 0: "a ã b ɓ c d ɗ e ë ǝ f g h i ĩ j k l m n ŋ o õ p r s t u v ṽ w y z", + 3: "q x", + 5: "A B Ɓ C D Ɗ E Ǝ F G H I J K L M N Ŋ O P R S T U V W Y Z", + }, + "my": { + 0: "က ခ ဂ ဃ င စ ဆ ဇ ဈ ဉ ည ဋ ဌ ဍ ဎ ဏ တ ထ ဒ ဓ န ပ ဖ ဗ ဘ မ ယ ရ လ ဝ သ ဟ ဠ အ ဣ ဤ ဥ ဦ ဧ ဩ ဪ ာ ါ ိ ီ ု ူ ေ ဲ ံ ဿ ျ ြ ွ ှ ္ ် ့ း", + 3: "ၐ ၑ ဨ ဢ ၒ ၓ ၔ ၕ ၖ ၗ ၘ ၙ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "naq": { + 0: "a â b c d e f g h i î k m n o ô p q r s t u û w x y z ǀ ǁ ǂ ǃ", + 3: "j l v", + 5: "A B C D E F G H I K M N O P Q R S T U W X Y Z", + }, + "nb": { + 0: "a à b c d e é f g h i j k l m n o ó ò ô p q r s t u v w x y z æ ø å", + 3: "á ǎ ã č ç đ è ê í ń ñ ŋ š ŧ ü ž ä ö", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Æ Ø Å", + }, + "nd": { + 0: "a b c d e f g h i j k l m n o p q s t u v w x y z", + 3: "r", + 5: "A B C D E F G H I J K L M N O P Q S T U V W X Y Z", + }, + "ne": { + 0: "़ ँ ं ः ॐ अ आ इ ई उ ऊ ऋ ऌ ऍ ए ऐ ऑ ओ औ क ख ग घ ङ च छ ज झ ञ ट ठ ड ढ ण त थ द ध न प फ ब भ म य र ल ळ व श ष स ह ऽ ा ि ी ु ू ृ ॄ ॅ े ै ॉ ो ौ ्", + 3: "\u200c \u200d", + }, + "nl": { + 0: "a á ä b c d e é ë f g h i í ï ij j k l m n o ó ö p q r s t u ú ü v w x y z", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §", + 3: "å ã ç ñ ô", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "nmg": { + 0: "a á ă â ä ā b ɓ c d e é ĕ ê ē ǝ ǝ́ ǝ̆ ǝ̂ ǝ̄ ɛ ɛ́ ɛ̆ ɛ̂ ɛ̄ f g h i í ĭ î ï ī j k l m n ń ŋ o ó ŏ ô ö ō ɔ ɔ́ ɔ̆ ɔ̂ ɔ̄ p r ŕ s t u ú ŭ û ū v w y", + 3: "q x z", + 5: "A B Ɓ C D E Ǝ Ɛ F G H I J K L M N Ŋ O Ɔ P R S T U V W Y", + }, + "nn": { + 0: "a à b c d e é f g h i j k l m n o ó ò ô p q r s t u v w x y z æ ø å", + 3: "á ǎ č ç đ è ê ń ñ ŋ š ŧ ü ž ä ö", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Æ Ø Å", + }, + "nso": { + 0: "a b d e ê f g h i j k l m n o ô p r s š t u w x y", + 3: "c q v z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "nus": { + 0: "a ä a̱ b c d e ë e̱ ɛ ɛ̈ ɛ̱ ɛ̱̈ f g ɣ h i ï i̱ j k l m n ŋ o ö o̱ ɔ ɔ̈ ɔ̱ p q r s t u v w x y z", + 5: "A B C D E Ɛ F G Ɣ H I J K L M N Ŋ O Ɔ P Q R S T U V W X Y Z", + }, + "nyn": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "om": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "or": { + 0: "଼ ଅ ଆ ଇ ଈ ଉ ଊ ଋ ଏ ଐ ଓ ଔ ଁ ଂ ଃ କ ଖ ଗ ଘ ଙ ଚ ଛ ଜ ଝ ଞ ଟ ଠ ଡ ଡ଼ ଢ ଢ଼ ଣ ତ ଥ ଦ ଧ ନ ପ ଫ ବ ଭ ମ ଯ ୟ ର ଲ ଳ ଵ ୱ ଶ ଷ ସ ହ ା ି ୀ ୁ ୂ ୃ େ ୈ ୋ ୌ ୍", + 3: "\u200c \u200d", + }, + "pa": { + 0: "ੱ ੰ ਼ ੦ ੧ ੨ ੩ ੪ ੫ ੬ ੭ ੮ ੯ ੴ ੳ ਉ ਊ ਓ ਅ ਆ ਐ ਔ ੲ ਇ ਈ ਏ ਸ ਸ਼ ਹ ਕ ਖ ਖ਼ ਗ ਗ਼ ਘ ਙ ਚ ਛ ਜ ਜ਼ ਝ ਞ ਟ ਠ ਡ ਢ ਣ ਤ ਥ ਦ ਧ ਨ ਪ ਫ ਫ਼ ਬ ਭ ਮ ਯ ਰ ਲ ਵ ੜ ੍ ਾ ਿ ੀ ੁ ੂ ੇ ੈ ੋ ੌ", + 3: "\u200c \u200d ਃ ਂ ਁ ਲ਼", + }, + "pa_Arab": { + 0: "ُ ء آ ؤ ئ ا ب پ ت ث ٹ ج چ ح خ د ذ ڈ ر ز ڑ ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن ں ه ھ ہ و ی ے", + 3: "أ ٻ ة ٺ ټ ٽ", + }, + "pl": { + 0: "a ą b c ć d e ę f g h i j k l ł m n ń o ó p r s ś t u w y z ź ż", + 3: "q v x", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "ps": { + 0: "َ ِ ُ ً ٍ ٌ ّ ْ ٔ ٰ آ ا أ ء ب پ ت ټ ث ج ځ چ څ ح خ د ډ ذ ر ړ ز ژ ږ س ش ښ ص ض ط ظ ع غ ف ق ک ګ ل م ن ڼ ه ة و ؤ ی ي ې ۍ ئ", + 3: "\u200c \u200d", + }, + "pt": { + 0: "a á à â ã b c ç d e é ê f g h i í j k l m n o ó ò ô õ p q r s t u ú v w x y z", + 3: "ă å ä ā æ è ĕ ë ē ì ĭ î ï ī ñ ŏ ö ø ō œ ù ŭ û ü ū ÿ", + 4: "a b c č d e f g h i j k l ł m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "pt_PT": { + 3: "ª ă å ä ā æ è ĕ ë ē ì ĭ î ï ī ñ º ŏ ö ø ō œ ù ŭ û ü ū ÿ", + }, + "rn": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ro": { + 0: "a ă â b c d e f g h i î j k l m n o p r s ș t ț u v x z", + 3: "á à å ä ç é è ê ë ñ ö q ş ţ ü w y", + 4: "a ă â b c d e f g h i î j k l m n o p q r s ș t ț u v w x y z", + 5: "A Ă Â B C D E F G H I Î J K L M N O P Q R S Ș T Ț U V W X Y Z", + }, + "rof": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "root": { + 2: "- , ; : ! ? . ( ) [ ] { }", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + }, + "ru": { + 0: "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ‚ \" “ „ « » ( ) [ ] { } @ * / & # §", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я", + }, + "rw": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "rwk": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "sah": { + 0: "а б г ҕ д дь и й к л м н нь ҥ о ө п р с т у ү х һ ч ы э", + 3: "в е ё ж з ф ц ш щ ъ ь ю я", + 5: "А Б Г Ҕ Д Дь И Й К Л М Н Нь Ҥ О Ө П Р С Т У Ү Х Һ Ч Ы Э", + }, + "saq": { + 0: "a b c d e g h i j k l m n o p r s t u v w y", + 3: "f q x z", + 5: "A B C D E G H I J K L M N O P R S T U V W Y", + }, + "sbp": { + 0: "a b c d e f g h i j k l m n o p s t u v w y", + 3: "q r x z", + 5: "A B C D E F G H I J K L M N O P S T U V W Y", + }, + "se": { + 0: "a á b c č d đ e f g h i j k l m n ŋ o p r s š t ŧ u v z ž", + 3: "à å ä ã æ ç é è í ń ñ ó ò ö ø q ú ü w x y", + }, + "seh": { + 0: "a á à â ã b c ç d e é ê f g h i í j k l m n o ó ò ô õ p q r s t u ú v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "ses": { + 0: "a ã b c d e ẽ f g h i j k l m n ɲ ŋ o õ p q r s š t u w x y z ž", + 3: "v", + 5: "A à B C D E Ẽ F G H I J K L M N Ɲ Ŋ O Õ P Q R S Š T U W X Y Z Ž", + }, + "sg": { + 0: "a â ä b d e ê ë f g h i î ï j k l m n o ô ö p r s t u ù û ü v w y z", + 3: "c q x", + 5: "A B D E F G H I J K L M N O P R S T U V W Y Z", + }, + "shi": { + 0: "a b c d ḍ e ɛ f g gʷ ɣ h ḥ i j k kʷ l m n q r ṛ s ṣ t ṭ u w x y z", + 3: "o p v", + 5: "A B C D Ḍ E Ɛ F G Gʷ Ɣ H Ḥ I J K Kʷ L M N Q R Ṛ S Ṣ T Ṭ U W X Y Z", + }, + "shi_Tfng": { + 0: "ⴰ ⴱ ⴳ ⴳⵯ ⴷ ⴹ ⴻ ⴼ ⴽ ⴽⵯ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ", + 5: "ⴰ ⴱ ⴳ ⴷ ⴹ ⴻ ⴼ ⴽ ⵀ ⵃ ⵄ ⵅ ⵇ ⵉ ⵊ ⵍ ⵎ ⵏ ⵓ ⵔ ⵕ ⵖ ⵙ ⵚ ⵛ ⵜ ⵟ ⵡ ⵢ ⵣ ⵥ", + }, + "si": { + 0: "අ ආ ඇ ඈ ඉ ඊ උ ඌ ඍ එ ඒ ඓ ඔ ඕ ඖ ං ඃ ක ඛ ග ඝ ඞ ඟ ච ඡ ජ ඣ ඥ ඤ ට ඨ ඩ ඪ ණ ඬ ත ථ ද ධ න ඳ ප ඵ බ භ ම ඹ ය ර ල ව ශ ෂ ස හ ළ ෆ ා ැ ෑ ි ී ු ූ ෘ ෲ ෟ ෙ ේ ෛ ො ෝ ෞ ්", + 3: "\u200b \u200c \u200d ඎ ඏ ඐ ඦ ෳ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "අ ආ ඇ ඈ ඉ ඊ උ ඌ ඍ එ ඒ ඓ ඔ ඕ ඖ ක ඛ ග ඝ ඞ ඟ ච ඡ ජ ඣ ඥ ඤ ට ඨ ඩ ඪ ණ ඬ ත ථ ද ධ න ඳ ප ඵ බ භ ම ඹ ය ර ල ව ශ ෂ ස හ ළ ෆ", + }, + "sk": { + 0: "a á ä b c č d ď e é f g h ch i í j k l ĺ ľ m n ň o ó ô p q r ŕ s š t ť u ú v w x y ý z ž", + }, + "sl": { + 0: "a b c č d e f g h i j k l m n o p r s š t u v z ž", + 3: "á à ă â å ä ā æ ç ć đ é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ q ú ù ŭ û ü ū w x y ÿ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "A B C Č Ć D Đ E F G H I J K L M N O P Q R S Š T U V W X Y Z Ž", + }, + "sn": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "so": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "sq": { + 0: "a b c ç d dh e ë f g gj h i j k l ll m n nj o p q r rr s sh t th u v x xh y z zh", + 3: "w", + }, + "sr": { + 0: "а б в г д ђ е ж з и ј к л љ м н њ о п р с т ћ у ф х ц ч џ ш", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + }, + "sr_Latn": { + 0: "a b c č ć d dž đ e f g h i j k l lj m n nj o p r s š t u v z ž", + 3: "q w x y", + }, + "ss": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "st": { + 0: "a b d e f g h i j k l m n o p q r s t u w y", + 3: "c v x z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "sv": { + 0: "a à b c d e é f g h i j k l m n o p q r s t u v w x y z å ä ö", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §", + 3: "á â ã ā ç ë í î ï ī ñ ó ú ÿ ü æ ø", + 4: "a b c č d e f g h i j k l ł m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Å Ä Ö", + }, + "sv_FI": { + 3: "ã ç ë í ñ ó š ÿ ü ž", + }, + "sw": { + 0: "a b ch d e f g h i j k l m n o p r s t u v w y z", + 3: "c q x", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "swc": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "ta": { + 0: "அ ஆ இ ஈ உ ஊ எ ஏ ஐ ஒ ஓ ஔ ஃ க ங ச ஞ ட ண த ந ப ம ய ர ல வ ழ ள ற ன ஜ ஷ ஸ ஹ ா ி ீ ு ூ ெ ே ை ொ ோ ௌ ்", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "te": { + 0: "అ ఆ ఇ ఈ ఉ ఊ ఋ ౠ ఌ ౡ ఎ ఏ ఐ ఒ ఓ ఔ ఁ ం ః క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ త థ ద ధ న ప ఫ బ భ మ య ర ఱ ల వ శ ష స హ ళ ా ి ీ ు ూ ృ ౄ ె ే ై ొ ో ౌ ్ ౕ ౖ", + 3: "\u200c \u200d ౦ ౧ ౨ ౩ ౪ ౫ ౬ ౭ ౮ ౯", + 5: "అ ఆ ఇ ఈ ఉ ఊ ఋ ౠ ఎ ఏ ఐ ఒ ఓ ఔ క ఖ గ ఘ ఙ చ ఛ జ ఝ ఞ ట ఠ డ ఢ ణ త థ ద ధ న ప ఫ బ భ మ య ర ఱ ల వ శ ష స హ ళ", + }, + "teo": { + 0: "a b c d e g h i j k l m n o p r s t u v w x y", + 3: "f q z", + 5: "A B C D E G H I J K L M N O P R S T U V W X Y", + }, + "tg": { + 0: "а б в г ғ д е ё ж з и ӣ й к қ л м н о п р с т у ӯ ф х ҳ ч ҷ ш ъ э ю я", + 3: "ц щ ы ь", + }, + "th": { + 0: "๎ ์ ็ ่ ้ ๊ ๋ ฯ ๆ ก ข ฃ ค ฅ ฆ ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ ฝ พ ฟ ภ ม ย ร ฤ ล ฦ ว ศ ษ ส ห ฬ อ ฮ ํ ะ ั า ๅ ำ ิ ี ึ ื ุ ู เ แ โ ใ ไ ฺ", + 3: "\u200b", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "ti": { + 0: "፟ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቊ ቋ ቌ ቍ ቐ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዂ ዃ ዄ ዅ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ደ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጒ ጓ ጔ ጕ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጷ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ", + 3: "᎐ ᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሇ ⶀ ᎀ ᎀ ᎁ ᎂ ᎃ ⶁ ⶁ ⶂ ⶃ ⶄ ቇ ᎄ ᎄ ᎅ ᎆ ᎇ ⶅ ⶅ ⶆ ⶇ ኇ ⶈ ⶈ ⶉ ⶊ ኯ ዏ ⶋ ዯ ⶌ ዸ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ⶎ ጏ ጘ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ ⶏ ⶏ ⶐ ⶑ ፇ ᎈ ᎈ ᎉ ᎊ ᎋ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ ፘ ፙ ፚ ⶠ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶰ ⶱ ⶲ ⶳ ⶴ ⶵ ⶶ ⶸ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷀ ⷁ ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷘ ⷙ ⷚ ⷛ ⷜ ⷝ ⷞ", + 5: "ሀ ለ ሐ መ ሠ ረ ሰ ሸ ቀ ቈ ቐ ቘ በ ቨ ተ ቸ ኀ ኈ ነ ኘ አ ከ ኰ ኸ ዀ ወ ዐ ዘ ዠ የ ደ ጀ ገ ጐ ጠ ጨ ጰ ጸ ፀ ፈ ፐ", + }, + "tn": { + 0: "a b d e ê f g h i j k l m n o ô p r s t u w y", + 3: "c q v x z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "to": { + 0: "a ā e ē f h ʻ i ī k l m n ng o ō p s t u ū v", + 3: "à ă â å ä æ b c ç d è ĕ ê ë g ì ĭ î ï j ñ ò ŏ ô ö ø œ q r ù ŭ û ü w x y ÿ z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A Ā B C D E Ē F G H ʻ I Ī J K L M N O Ō P Q R S T U Ū V W X Y Z", + }, + "tr": { + 0: "a b c ç d e f g ğ h ı i i̇ j k l m n o ö p r s ş t u ü v y z", + 2: "- ‐ – — , ; : ! ? . … ' ‘ ’ \" “ ” ( ) [ ] @ * / & # † ‡ ′ ″ §", + 3: "á à ă â å ä ā æ é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ø ō œ q ú ù ŭ û ū w x ÿ", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "A B C Ç D E F G H I İ J K L M N O Ö P Q R S Ş T U Ü V W X Y Z", + }, + "ts": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "twq": { + 0: "a ã b c d e ẽ f g h i j k l m n ŋ ɲ o õ p q r s š t u w x y z ž", + 3: "v", + }, + "tzm": { + 0: "a b c d ḍ e ɛ f g gʷ ɣ h ḥ i j k kʷ l m n q r ṛ s ṣ t ṭ u w x y z", + 3: "o p v", + 5: "A B C D Ḍ E Ɛ F G Ɣ H Ḥ I J K L M N Q R Ṛ S Ṣ T Ṭ U W X Y Z", + }, + "uk": { + 0: "ʼ а б в г ґ д е є ж з и і ї й к л м н о п р с т у ф х ц ч ш щ ю я ь", + 4: "a b c č d e f g h i j k l ł m n o º p q r s t u v w x y z", + 5: "А Б В Г Ґ Д Е Є Ж З И І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ю Я", + }, + "ur": { + 0: "ا أ آ ب پ ت ٹ ث ج چ ح خ د ڈ ذ ر ڑ ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن ں و ؤ ہ ھ ء ی ئ ے ٻ ة ٺ ټ ٽ ه ي", + }, + "uz": { + 0: "а б в г ғ д е ё ж з и й к қ л м н о п р с т у ў ф х ҳ ч ш ъ э ю я", + 3: "ц щ ы ь", + }, + "uz_Arab": { + 0: "ً ٌ ٍ َ ُ ِ ّ ْ ٔ ٰ ء آ أ ؤ ئ ا ب پ ة ت ث ټ ج چ ح خ ځ څ د ذ ډ ر ز ړ ږ ژ س ش ښ ص ض ط ظ ع غ ف ق ک ګ گ ل م ن ڼ ه و ۇ ۉ ي ی ۍ ې", + 3: "\u200c \u200d", + }, + "uz_Latn": { + 0: "a aʼ b ch d e eʼ f g gʼ h i iʼ j k l m n o oʼ p q r s sh t u uʼ v x y z", + 3: "c w", + 5: "A B CH D E F G Gʼ H I J K L M N O Oʼ P Q R S SH T U V X Y Z", + }, + "vai": { + 0: "꘠ ꘠ ꘡ ꘢ ꘣ ꘤ ꘥ ꘦ ꘧ ꘨ ꘩ ꔀ ꔀ ꔁ ꔂ ꔃ ꔄ ꔅ ꔆ ꔇ ꔈ ꔉ ꔊ ꔋ ꔌ ꘓ ꔍ ꔍ ꔎ ꔏ ꔐ ꔑ ꔒ ꔓ ꔔ ꔕ ꔖ ꔗ ꔘ ꔙ ꔚ ꔛ ꔜ ꔝ ꔞ ꘔ ꔟ ꔟ ꔠ ꔡ ꔢ ꔣ ꔤ ꔥ ꔦ ꔧ ꔨ ꔩ ꔪ ꔫ ꔬ ꔭ ꔮ ꔯ ꔰ ꔱ ꔲ ꔳ ꘕ ꔴ ꔴ ꔵ ꔶ ꔷ ꔸ ꔹ ꔺ ꔻ ꔼ ꔽ ꔾ ꔿ ꕀ ꕁ ꕂ ꕃ ꕄ ꕅ ꕆ ꕇ ꘖ ꕈ ꕈ ꕉ ꕊ ꕋ ꕌ ꕍ ꕎ ꕏ ꕐ ꕑ ꕒ ꘗ ꕓ ꕓ ꕔ ꕕ ꕖ ꕗ ꕘ ꘐ ꘘ ꕙ ꕚ ꘙ ꕛ ꕛ ꕜ ꕝ ꕞ ꕟ ꕠ ꘚ ꕡ ꕡ ꕢ ꕣ ꕤ ꕥ ꕦ ꕧ ꕨ ꕩ ꕪ ꘑ ꕫ ꕫ ꕬ ꕭ ꕮ ꘪ ꕯ ꕯ ꕰ ꕱ ꕲ ꕳ ꕴ ꕵ ꕶ ꕷ ꕸ ꕹ ꕺ ꕻ ꕼ ꕽ ꕾ ꕿ ꖀ ꖁ ꖂ ꖃ ꖄ ꖅ ꘛ ꖆ ꖇ ꘒ ꖈ ꖈ ꖉ ꖊ ꖋ ꖌ ꖍ ꖎ ꖏ ꖐ ꖑ ꖒ ꖓ ꖔ ꖕ ꖖ ꖗ ꖘ ꖙ ꖚ ꖛ ꖜ ꖝ ꖞ ꖟ ꖠ ꖡ ꖢ ꖣ ꖤ ꖥ ꖦ ꖧ ꖨ ꖩ ꖪ ꖫ ꖬ ꖭ ꖮ ꖯ ꖰ ꖱ ꖲ ꖳ ꖴ ꘜ ꖵ ꖵ ꖶ ꖷ ꖸ ꖹ ꖺ ꖻ ꖼ ꖽ ꖾ ꖿ ꗀ ꗁ ꗂ ꗃ ꗄ ꗅ ꗆ ꗇ ꗈ ꗉ ꗊ ꗋ ꘝ ꗌ ꗌ ꗍ ꗎ ꗏ ꗐ ꗑ ꘫ ꘞ ꗒ ꗒ ꗓ ꗔ ꗕ ꗖ ꗗ ꗘ ꘟ ꗙ ꗙ ꗚ ꗛ ꗜ ꗝ ꗞ ꗟ ꗠ ꗡ ꗢ ꗣ ꗤ ꗥ ꗦ ꗧ ꗨ ꗩ ꗪ ꗫ ꗬ ꗭ ꗮ ꗯ ꗰ ꗱ ꗲ ꗳ ꗴ ꗵ ꗶ ꗷ ꗸ ꗹ ꗺ ꗻ ꗼ ꗽ ꗾ ꗿ ꘀ ꘁ ꘂ ꘃ ꘄ ꘅ ꘆ ꘇ ꘈ ꘉ ꘊ ꘋ ꘌ", + }, + "vai_Latn": { + 0: "a á ã b ɓ c d ɗ e é ẽ ɛ ɛ́ ɛ̃ f g h i í ĩ j k l m n ŋ o ó õ ɔ ɔ́ ɔ̃ p q r s t u ú ũ v w x y z", + 5: "A B Ɓ C D Ɗ E Ɛ F G H I J K L M N Ŋ O Ɔ P Q R S T U V W X Y Z", + }, + "ve": { + 0: "a b d ḓ e f g h i k l ḽ m n ṅ ṋ o p r s t ṱ u v w x y z", + }, + "vi": { + 0: "a à ả ã á ạ ă ằ ẳ ẵ ắ ặ â ầ ẩ ẫ ấ ậ b c d đ e è ẻ ẽ é ẹ ê ề ể ễ ế ệ f g h i ì ỉ ĩ í ị j k l m n o ò ỏ õ ó ọ ô ồ ổ ỗ ố ộ ơ ờ ở ỡ ớ ợ p q r s t u ù ủ ũ ú ụ ư ừ ử ữ ứ ự v w x y ỳ ỷ ỹ ý ỵ z", + 4: "a b c d đ e f g h i j k l m n o p q r s t u v w x y z", + }, + "vun": { + 0: "a b c d e f g h i j k l m n o p r s t u v w y z", + 3: "q x", + 5: "A B C D E F G H I J K L M N O P R S T U V W Y Z", + }, + "wae": { + 0: "a á ä ã b c č d e é f g h i í j k l m n o ó ö õ p q r s š t u ú ü ũ v w x y z", + 3: "à ă â å ā æ ç è ĕ ê ë ē ì ĭ î ï ī ñ ò ŏ ô ø ō œ ß ù ŭ û ū ÿ", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "wal": { + 0: "፟ ᎐ ᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሀ ሀ ሁ ሂ ሃ ሄ ህ ሆ ሇ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ⶀ ሐ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ᎀ ᎀ ᎁ ᎂ ᎃ ⶁ ሠ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ⶂ ሰ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ⶃ ሸ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ⶄ ቀ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቇ ቈ ቊ ቊ ቋ ቌ ቍ ቐ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቚ ቛ ቜ ቝ በ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ᎄ ᎄ ᎅ ᎆ ᎇ ⶅ ቨ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ⶆ ቸ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ⶇ ኀ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኇ ኈ ኊ ኊ ኋ ኌ ኍ ነ ነ ኑ ኒ ና ኔ ን ኖ ኗ ⶈ ኘ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ ⶉ አ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ⶊ ከ ከ ኩ ኪ ካ ኬ ክ ኮ ኯ ኰ ኲ ኲ ኳ ኴ ኵ ኸ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዂ ዃ ዄ ዅ ወ ወ ዉ ዊ ዋ ዌ ው ዎ ዏ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ⶋ ዠ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ዯ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ⶌ ዸ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ጀ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ⶎ ገ ገ ጉ ጊ ጋ ጌ ግ ጎ ጏ ጐ ጒ ጒ ጓ ጔ ጕ ጘ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶓ ⶔ ⶕ ⶖ ጠ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ⶏ ጨ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ⶐ ጰ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጷ ⶑ ጸ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፇ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ᎈ ᎈ ᎉ ᎊ ᎋ ፐ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ ᎌ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ ፘ ፙ ፚ ⶠ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶰ ⶱ ⶲ ⶳ ⶴ ⶵ ⶶ ⶸ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷀ ⷁ ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷘ ⷙ ⷚ ⷛ ⷜ ⷝ ⷞ", + }, + "xh": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, + "xog": { + 0: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "yav": { + 0: "a á à â ǎ ā b c d e é è ɛ ɛ́ ɛ̀ f h i í ì î ī k l m mb n ny ŋ ŋg o ó ò ô ǒ ō ɔ ɔ́ ɔ̀ p s t u ú ù û ǔ ū v w y", + 3: "g j q r x z", + 5: "A B C D E Ɛ F H I K L M N Ŋ O Ɔ P S T U V W Y", + }, + "yo": { + 0: "a á à b d e é è ẹ ẹ́ ẹ̀ f g gb h i í ì j k l m n o ó ò ọ ọ́ ọ̀ p r s ṣ t u ú ù w y", + 3: "c q v x z", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "zh": { + 0: "一 丁 七 万 万 丈 三 上 下 丌 不 与 专 且 世 丘 丘 丙 业 东 丝 丢 两 严 丧 个 中 丰 串 临 丸 丸 丹 为 主 丽 举 乃 久 么 义 之 之 乌 乍 乎 乏 乐 乔 乖 乘 乙 九 也 也 习 乡 书 买 乱 乾 了 予 争 事 二 于 亏 云 互 五 井 亚 些 亡 交 亦 亨 享 京 亮 亲 人 亿 亿 什 仁 仅 仇 今 介 仍 从 仔 他 付 仙 代 代 令 以 仪 们 仰 仲 件 任 份 仿 企 伊 伍 伏 伏 伐 休 众 伙 会 伟 传 伤 伦 伯 估 伴 伸 似 伽 但 位 位 低 住 佐 佑 体 何 余 佛 作 你 佤 佩 佳 使 例 供 依 侠 侦 侦 侧 侨 侬 侯 侵 便 促 俄 俊 俗 保 信 俩 修 俱 俾 倍 倒 候 倚 借 倦 值 倾 假 偌 偏 做 停 健 偶 偷 储 催 傲 傻 像 僧 儒 允 元 元 兄 充 先 光 克 免 兑 兔 入 全 八 八 公 六 兮 兰 共 关 关 兴 兵 其 具 典 兹 养 养 兼 兽 内 冈 再 冒 写 军 农 冠 冬 冰 冲 冷 准 凌 凝 几 凡 凤 凭 凯 凰 出 击 函 刀 分 切 刊 刑 划 列 列 刘 则 刚 创 初 判 利 别 到 制 制 刷 券 刺 刻 剂 前 剑 剧 剩 剪 副 割 力 劝 劝 办 功 加 务 劣 动 动 助 努 劫 励 励 劲 劳 势 勇 勉 勋 勒 勤 勾 勿 包 匆 匈 化 北 匙 匹 匹 区 医 十 千 升 午 半 华 协 卒 卓 单 单 卖 南 博 占 占 卡 卢 卫 印 危 即 卷 厄 厄 厅 历 厉 压 压 厌 厍 厚 原 去 县 参 又 又 叉 及 友 双 反 发 叔 取 取 受 变 叙 口 口 古 句 另 叫 叫 召 叭 可 台 史 右 叶 叶 号 司 叹 吃 各 合 合 吉 吊 同 同 名 后 吐 向 吓 吗 君 吝 吟 否 吧 含 吵 吸 吹 吻 吾 呀 呆 呈 告 呐 员 呜 呢 呦 周 味 呵 呼 命 和 咖 咦 咧 咪 咬 咯 咱 哀 品 哇 哇 哈 哉 响 哎 哟 哥 哦 哩 哪 哭 哲 唉 唐 唤 唬 售 唯 唱 唷 商 啊 啡 啥 啦 啪 喀 喂 善 喇 喊 喏 喔 喜 喝 喵 喷 喻 嗒 嗨 嗯 嘉 嘛 嘴 嘻 嘿 器 四 回 因 团 园 困 围 固 国 图 圆 圈 土 圣 在 圭 地 场 圾 址 均 坎 坐 坑 块 坚 坚 坛 坜 坡 坤 坦 坪 垂 垃 型 垒 埃 埋 城 埔 域 培 基 堂 堆 堕 堡 堪 塑 塔 塞 填 境 增 墨 壁 壤 士 壮 声 处 备 复 夏 夕 外 多 夜 夥 大 天 天 太 夫 央 失 头 夷 夷 夸 夹 夺 奇 奇 奈 奉 奋 奏 契 奔 套 奥 女 奴 奶 她 好 如 妇 妈 妖 妙 妥 妨 妮 妹 妻 姆 姊 始 姐 姑 姓 委 姿 威 娃 娄 娘 娜 娟 婆 婚 媒 嫁 嫌 嫩 子 孔 孕 字 字 存 孙 孜 孝 孟 季 孤 学 孩 宁 它 宇 宇 守 安 宋 完 宏 宗 宗 官 宙 定 宛 宜 宝 实 审 审 客 宣 室 宪 害 宴 家 容 宽 宽 宾 宿 寂 寄 密 寇 富 寒 寝 寝 寞 察 寡 寨 寸 对 寻 导 寿 封 射 将 尊 小 少 尔 尖 尘 尚 尝 尤 就 尺 尼 尼 尽 尾 局 局 屁 层 居 屋 屏 展 属 屠 山 岁 岂 岗 岘 岚 岛 岳 岸 峡 峰 崇 崩 崴 川 州 巡 工 工 左 巧 巨 巫 差 己 已 巴 巷 币 币 市 布 帅 师 希 帐 帕 帝 带 席 帮 常 帽 幅 幕 干 干 平 年 幸 幻 幻 幼 幽 广 庆 床 序 库 库 应 底 店 庙 府 庞 废 度 座 庭 康 庸 廉 廖 延 廷 建 开 弃 弄 弊 式 引 弗 弘 弟 张 弥 弦 弯 弱 弹 归 当 彝 形 彩 彬 彭 彰 影 彷 役 彻 彼 往 征 径 待 很 律 後 徐 徒 得 循 微 徵 德 心 必 忆 忌 忍 志 志 忘 忙 忠 忧 快 念 忽 怀 态 怎 怒 怕 怖 思 怡 急 性 怨 怪 总 恋 恐 恢 恨 恩 恭 息 恰 恶 恼 悄 悉 悔 悟 悠 患 您 悲 情 惑 惜 惠 惧 惨 惯 想 惹 愁 愈 愉 意 愚 感 愧 慈 慎 慕 慢 慧 慰 憾 懂 懒 戈 戏 戏 成 我 戒 或 战 截 戴 房 房 所 扁 扇 手 才 扎 扑 打 托 扣 执 扩 扫 扫 扬 扭 扮 扯 批 找 找 承 技 抄 把 抑 抓 投 抗 折 抢 护 报 披 抬 抱 抵 抹 抽 担 拆 拉 拍 拒 拔 拖 拘 招 拜 拟 拥 拦 拨 择 括 拳 拷 拼 拾 拿 持 指 按 挑 挖 挝 挡 挤 挥 挪 振 挺 捉 捐 捕 损 捡 换 捷 授 掉 掌 排 探 接 控 控 推 掩 措 掸 描 提 插 握 援 搜 搞 搬 搭 摄 摆 摊 摔 摘 摩 摸 撒 撞 播 操 擎 擦 支 收 改 攻 放 政 故 效 敌 敏 救 教 敝 敢 散 敦 敬 数 敲 整 文 斋 斐 斗 料 斜 斥 断 斯 新 方 於 施 旁 旅 旋 族 旗 无 既 日 日 旦 旧 旨 早 旭 时 旺 昂 昆 昌 明 昏 易 星 映 春 昨 昭 是 显 晃 晋 晒 晓 晚 晨 普 景 晴 晶 智 暂 暑 暖 暗 暮 暴 曰 曲 更 曹 曼 曾 曾 替 最 月 有 朋 服 朗 望 朝 期 木 未 未 末 本 札 术 朱 朵 杀 杂 权 杉 李 材 村 杜 束 条 来 杨 杯 杰 松 板 极 析 林 果 枝 枢 枪 枫 架 柏 某 染 柔 查 柬 柯 柳 柴 标 栋 栏 树 校 样 样 核 根 格 桃 框 案 桌 桑 档 桥 梁 梅 梦 梯 械 梵 检 棉 棋 棒 棚 森 椅 植 椰 楚 楼 概 榜 模 樱 檀 欠 欠 次 欢 欣 欧 欲 欺 款 歉 歌 止 止 正 此 步 武 歪 死 殊 残 段 毅 母 每 毒 比 毕 毛 毫 氏 民 氛 水 永 求 汉 汗 汝 江 江 池 污 汤 汪 汶 汽 沃 沈 沉 沙 沟 沧 河 油 治 沿 泉 泊 法 泛 泡 泡 波 泣 泥 注 泰 泳 泽 洋 洗 洛 洞 津 洪 洲 活 洽 派 流 浅 测 济 浑 浓 浦 浩 浪 浮 浴 海 涅 消 涉 涛 涨 涯 液 涵 淋 淑 淘 淡 深 混 添 清 渐 渡 渣 温 港 渴 游 湖 湾 源 溜 溪 滋 滑 满 滥 滨 滴 漂 漏 演 漠 漫 潘 潜 潮 澎 澳 激 灌 火 灭 灯 灰 灵 灿 炉 炎 炮 炸 点 烂 烈 烤 烦 烧 热 焦 然 煌 煞 照 煮 熊 熟 燃 燕 爆 爪 爬 爱 爵 爵 父 爷 爸 爽 片 版 牌 牙 牛 牡 牢 牧 物 牲 牵 特 牺 犯 状 犹 狂 狐 狗 狠 独 狮 狱 狼 猛 猜 献 玄 率 玉 王 玛 玩 玫 环 现 玲 玻 珀 珊 珍 珠 班 球 理 琊 琪 琳 琴 琼 瑙 瑜 瑞 瑟 瑰 瑶 璃 瓜 瓦 瓶 甘 甚 甜 生 用 田 田 由 甲 申 电 男 甸 画 畅 界 留 略 番 疆 疏 疑 疗 疯 疲 疼 疾 病 痕 痛 痴 登 白 百 的 皆 皇 皮 盈 益 监 盒 盖 盘 盛 盟 目 直 相 盼 盾 省 眉 看 真 眠 眼 睛 睡 督 瞧 矛 矣 知 短 石 矶 码 砂 砍 研 破 础 硕 硬 碍 碎 碗 碟 碧 碰 磁 磅 磨 示 礼 社 祖 祝 神 祥 票 祸 禁 禅 福 秀 私 秋 种 科 秒 秘 租 秤 秦 秩 积 称 移 稀 程 稍 稣 稳 稿 穆 究 穷 穹 空 穿 突 窗 窝 立 站 竞 竞 竟 章 童 端 竹 笑 笔 笛 符 笨 第 等 筋 答 策 筹 签 简 算 管 箭 箱 篇 篮 簿 籍 米 类 粉 粒 粗 粤 粹 精 糊 糕 糖 糟 系 素 索 紧 紫 累 繁 红 约 级 纪 纯 纲 纳 纵 纷 纸 纽 练 组 细 细 织 终 绍 经 结 绕 绘 给 络 统 继 绩 绪 续 维 绵 综 缅 缓 编 缘 缠 缩 缴 缶 缸 缺 罐 罕 罗 罚 罢 罪 置 署 羊 美 羞 群 羯 羽 翁 翅 翔 翘 翠 翰 翻 翼 耀 老 考 者 而 耍 耐 耗 耳 耶 聊 职 联 聚 聪 肉 肖 肚 股 肤 肥 肩 肯 育 胁 胆 背 胎 胖 胞 胡 胶 胸 能 脆 脑 脱 脸 腊 腐 腓 腰 腹 腾 腿 臂 臣 自 臭 至 致 舌 舍 舒 舞 舟 航 般 舰 船 良 色 艺 艾 节 芒 芝 芦 芬 芭 花 芳 苍 苏 苗 若 苦 英 茂 茨 茫 茶 草 荒 荣 药 荷 莉 莎 莪 莫 莱 莲 获 菜 菩 菲 萄 萍 萤 营 萧 萨 落 著 葛 葡 蒂 蒋 蒙 蓉 蓝 蓬 蔑 蔡 薄 薪 藉 藏 藤 虎 虑 虫 虹 虽 虾 蚁 蛇 蛋 蛙 蛮 蜂 蜜 蝶 融 蟹 蠢 血 行 街 衡 衣 补 表 袋 被 袭 裁 裂 装 裕 裤 西 要 覆 见 观 规 视 览 觉 角 解 言 誉 誓 警 计 订 认 讨 让 训 训 议 讯 记 讲 讷 许 论 设 访 证 评 识 诉 词 译 试 诗 诚 话 诞 询 该 详 语 误 说 请 诸 诺 读 课 谁 调 谅 谈 谊 谋 谓 谜 谢 谨 谱 谷 豆 象 豪 貌 贝 贝 贞 负 贡 贡 财 责 贤 败 货 货 质 贩 贪 购 贯 贱 贴 贵 费 贺 贼 贾 资 赋 赌 赏 赐 赔 赖 赚 赛 赞 赠 赢 赤 赫 走 赵 起 趁 超 越 趋 趣 足 跃 跌 跑 距 跟 路 跳 踏 踢 踩 身 躲 车 轨 轩 转 轮 轮 软 轰 轻 载 较 辅 辆 辈 辉 辑 输 辛 辞 辨 辩 辱 边 达 迁 迅 过 迈 迎 运 近 返 还 这 进 进 远 违 连 迟 迦 迪 迫 述 迷 追 退 送 逃 逆 选 逊 透 逐 递 途 通 逛 逝 速 造 逢 逸 逻 逼 遇 遍 道 遗 遭 遮 遵 避 邀 邓 那 邦 邪 邮 邱 邻 郎 郑 部 郭 都 鄂 酋 配 酒 酷 酸 醉 醒 采 释 里 里 重 野 量 金 针 钓 钟 钢 钦 钱 钻 铁 铃 铢 铭 银 销 锁 锅 锋 错 锡 锦 键 锺 镇 镜 镭 长 门 闪 闭 问 间 闷 闹 闻 阁 阐 阔 队 阮 防 防 阳 阴 阵 阶 阻 阿 陀 附 附 际 陆 陈 降 限 院 除 险 陪 陵 陵 陶 陷 隆 随 隐 隔 障 难 雄 雄 雅 集 雨 雪 雯 雳 零 雷 雾 需 震 霍 霖 露 霸 霹 青 靖 静 非 靠 面 革 靼 鞋 鞑 韦 韩 音 页 顶 项 项 顺 须 顽 顽 顾 顿 预 领 颇 频 颗 题 额 风 飘 飙 飞 食 餐 饭 饮 饰 饱 饼 馆 首 香 馨 马 驱 驶 驻 驾 验 骑 骗 骚 骤 骨 高 鬼 魂 魅 魔 鱼 鲁 鲜 鸟 鸣 鸭 鸿 鹅 鹤 鹰 鹿 麦 麻 黄 黎 黑 默 鼓 鼠 鼻 齐 齿 龄 龙 龟", + 3: "侣 傣 卑 厘 吕 堤 奎 巽 录 户 撤 楔 楠 滕 瑚 甫 盲 禄 粟 线 脚 钯 铂 锑 镑 魁", + 5: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z", + }, + "zh_Hant": { + 0: "一 丁 七 丈 丈 三 上 下 丌 不 且 世 丘 丙 丟 並 中 串 丸 丹 主 乃 久 么 之 乎 乏 乖 乘 乙 九 也 乾 亂 了 予 事 二 于 云 互 五 井 些 亞 亡 交 亦 亨 享 京 亮 人 什 仁 仇 今 介 仍 仔 他 付 仙 代 代 令 以 仰 仲 件 任 份 企 伊 伍 伐 休 伙 伯 估 伴 伸 似 伽 但 佈 位 位 低 住 佔 何 余 佛 作 你 佩 佳 使 來 例 供 依 侯 侵 便 係 係 促 俄 俊 俗 保 俠 信 修 俱 俾 個 倍 們 倒 候 倚 借 倫 值 假 偉 偏 做 停 健 側 側 偵 偶 偷 傑 備 傢 傣 傲 傳 傷 傻 傾 僅 像 僑 僧 價 儀 億 儒 儘 優 允 元 元 兄 充 兇 兇 先 光 克 免 兒 兔 入 內 內 全 兩 八 八 公 六 兮 共 兵 兵 其 具 典 兼 冊 再 冒 冠 冬 冰 冷 准 凌 凝 凡 凰 凱 出 函 刀 分 切 刊 列 初 判 別 利 刪 到 制 刷 刺 刻 則 前 剛 剩 剪 副 割 創 劃 劇 劉 劍 力 功 加 助 助 努 劫 勁 勇 勉 勒 動 務 勝 勞 勢 勤 勵 勸 勿 包 匈 化 北 匹 區 十 千 升 午 半 卒 卒 卓 協 南 博 卡 印 危 即 卷 卻 厄 厘 厚 原 厭 厲 去 參 又 及 友 反 叔 取 受 口 口 古 句 另 叫 叫 召 叭 可 台 史 右 司 吃 各 合 合 吉 吊 同 同 名 后 吐 向 君 吝 吝 吞 吟 否 吧 含 吳 吵 吸 吹 吾 呀 呂 呆 告 呢 周 味 呵 呼 命 和 咖 咦 咧 咪 咬 咱 哀 品 哇 哇 哈 哉 哎 員 哥 哦 哩 哪 哭 哲 唉 唐 唬 售 唯 唱 唷 唸 商 啊 問 啟 啡 啥 啦 啪 喀 喂 善 喇 喊 喔 喜 喝 喬 單 喵 嗎 嗚 嗨 嗯 嘆 嘉 嘗 嘛 嘴 嘻 嘿 器 噴 嚇 嚴 囉 四 回 因 困 固 圈 國 圍 園 圓 圖 團 圜 土 在 圭 地 圾 址 均 坎 坐 坡 坤 坦 坪 垂 垃 型 埃 城 埔 域 執 培 基 堂 堅 堆 堡 堪 報 場 塊 塔 塗 塞 填 塵 境 增 墨 墮 壁 壓 壘 壞 壢 士 壯 壽 夏 夕 外 多 夜 夠 夢 夥 大 天 天 太 夫 央 失 夷 夸 夾 奇 奇 奈 奉 奎 奏 契 奔 套 奧 奪 奮 女 奴 奶 她 好 如 妙 妥 妨 妮 妳 妹 妻 姆 姊 始 姐 姑 姓 委 姿 威 娃 娘 婁 婆 婚 婦 媒 媽 嫌 嫩 子 孔 字 存 孝 孟 季 孤 孩 孫 學 它 宅 宇 宇 守 安 宋 完 宏 宗 宗 官 宙 定 宛 宜 客 客 宣 室 宮 害 家 容 宿 寂 寄 密 富 寒 寞 察 寢 實 實 寧 寨 審 寫 寬 寮 寶 封 射 將 專 尊 尋 對 對 導 小 少 尖 尚 尤 就 尺 尼 尾 局 屁 居 屆 屋 屏 展 屠 層 屬 山 岡 岩 岸 峰 島 峽 崇 崙 崴 嵐 嶺 川 州 巡 工 工 左 巧 巨 巫 差 己 已 巴 巷 市 布 希 帕 帛 帝 帥 師 席 帳 帶 常 帽 幅 幕 幣 幫 干 干 平 年 幸 幹 幻 幻 幼 幽 幾 庇 床 序 底 店 府 度 座 庫 庭 康 庸 廉 廖 廠 廢 廣 廳 延 廷 建 弄 式 引 弗 弘 弟 弦 弱 張 強 彈 彊 彌 彎 彞 形 彥 彩 彬 彭 彰 影 役 彼 往 征 待 很 律 後 徐 徐 徑 徒 得 從 復 微 徵 德 徹 心 必 忌 忍 志 志 忘 忙 忠 快 念 忽 怎 怒 怕 怖 思 怡 急 性 怨 怪 恆 恐 恢 恥 恨 恩 恭 息 恰 悅 悉 悔 悟 悠 您 悲 悶 情 惑 惜 惠 惡 惱 想 惹 愁 愈 愉 意 愚 愛 感 慈 態 慕 慘 慢 慣 慧 慮 慰 慶 慾 憂 憐 憑 憲 憶 憾 懂 應 懶 懷 懼 戀 戈 成 成 我 戒 或 截 戰 戲 戴 戶 房 房 所 扁 扇 手 才 扎 打 托 扣 扥 扭 扯 批 找 找 承 技 抄 把 抓 投 抗 折 披 抬 抱 抵 抹 抽 拆 拉 拋 拍 拒 拔 拖 招 拜 括 拳 拼 拾 拿 持 指 按 挑 挖 挪 振 挺 捐 捕 捨 捲 捷 掃 授 掉 掌 排 掛 採 探 接 控 推 措 描 提 插 揚 換 握 揮 援 損 搖 搜 搞 搬 搭 搶 摘 摩 摸 撐 撒 撞 撣 撥 播 撾 撿 擁 擇 擊 擋 操 擎 擔 據 擠 擦 擬 擴 擺 擾 攝 支 收 改 攻 放 政 故 效 敍 敏 救 敗 敗 敘 教 敝 敢 散 敦 敬 整 敵 數 文 斐 斗 料 斯 新 斷 方 於 施 旁 旅 旋 族 旗 既 日 旦 早 旭 旺 昂 昆 昇 昌 明 昏 易 星 映 春 昨 昭 是 時 晉 晒 晚 晨 普 景 晴 晶 智 暑 暖 暗 暫 暴 曆 曉 曰 曲 更 書 曼 曾 曾 替 最 會 月 有 朋 服 朗 望 朝 期 木 未 未 末 本 札 朱 朵 杉 李 材 村 杜 束 杯 杯 杰 東 松 板 析 林 果 枝 架 柏 某 染 柔 查 柬 柯 柳 柴 校 核 根 格 桃 案 桌 桑 梁 梅 條 梨 梯 械 梵 棄 棉 棋 棒 棚 森 椅 植 椰 楊 楓 楚 業 極 概 榜 榮 構 槍 樂 樓 標 樞 模 樣 樹 橋 機 橫 檀 檔 檢 欄 權 次 欣 欲 欺 欽 款 歉 歌 歐 歡 歡 止 正 此 步 武 歲 歷 歸 死 殊 殘 段 殺 殼 毀 毅 母 每 毒 比 毛 毫 氏 民 氣 水 永 求 汗 汝 江 江 池 污 汪 汶 決 汽 沃 沈 沉 沒 沖 沙 河 油 治 沿 況 泉 泊 法 泡 波 泥 注 泰 泳 洋 洗 洛 洞 洩 洪 洲 活 洽 派 流 浦 浩 浪 浮 海 涇 涇 消 涉 涯 液 涵 涼 淑 淚 淡 淨 深 混 淺 清 減 渡 測 港 游 湖 湯 源 準 溝 溪 溫 滄 滅 滋 滑 滴 滾 滿 漂 漏 演 漠 漢 漫 漲 漸 潔 潘 潛 潮 澤 澳 激 濃 濟 濤 濫 濱 灌 灣 火 灰 災 炎 炮 炸 為 烈 烏 烤 無 焦 然 煙 煞 照 煩 熊 熟 熱 燃 燈 燒 營 爆 爐 爛 爪 爬 爭 爵 父 爸 爺 爽 爾 牆 牆 片 版 牌 牙 牛 牠 牧 物 牲 特 牽 犧 犯 狀 狂 狐 狗 狠 狼 猛 猜 猶 獄 獅 獎 獨 獲 獸 獻 玄 率 玉 王 玩 玫 玲 玻 珊 珍 珠 班 現 球 理 琉 琪 琴 瑙 瑜 瑞 瑟 瑤 瑪 瑰 環 瓜 瓦 瓶 甘 甚 甜 生 產 用 田 田 由 甲 申 男 甸 界 留 畢 略 番 畫 異 當 疆 疏 疑 疼 病 痕 痛 痴 瘋 療 癡 登 登 發 白 百 的 皆 皇 皮 盃 益 盛 盜 盟 盡 監 盤 盧 目 盲 直 相 盼 盾 省 眉 看 真 眠 眼 眾 睛 睡 督 瞧 瞭 矛 矣 知 短 石 砂 砍 研 砲 破 硬 碎 碗 碟 碧 碩 碰 確 碼 磁 磨 磯 礎 礙 示 社 祕 祖 祝 神 祥 票 禁 禍 福 禪 禮 秀 私 秋 科 秒 秘 租 秤 秦 移 稅 程 稍 種 稱 稿 穆 穌 積 穩 究 穹 空 穿 突 窗 窩 窮 立 站 竟 章 童 端 競 竹 笑 笛 符 笨 第 筆 等 筋 答 策 简 算 管 箭 箱 節 範 篇 築 簡 簫 簽 簿 籃 籌 籍 米 粉 粗 粵 精 糊 糕 糟 系 糾 紀 約 紅 納 紐 純 紙 紙 級 紛 素 索 紫 累 細 紹 終 組 結 絕 絡 給 統 絲 經 綜 綠 維 綱 網 緊 緒 線 緣 編 緩 緬 緯 練 縣 縮 縱 總 績 繁 繆 織 繞 繪 繳 繼 續 缸 缺 罕 罪 置 罰 署 罵 罷 羅 羊 美 羞 群 義 羽 翁 習 翔 翰 翹 翻 翼 耀 老 考 者 而 耍 耐 耗 耳 耶 聊 聖 聚 聞 聯 聰 聲 職 聽 肉 肚 股 肥 肩 肯 育 背 胎 胖 胞 胡 胸 能 脆 脫 腓 腔 腦 腰 腳 腿 膽 臉 臘 臣 臥 臨 自 臭 至 致 臺 與 與 興 舉 舊 舌 舍 舒 舞 舟 航 般 船 艦 良 色 艾 芝 芬 花 芳 若 苦 英 茅 茫 茲 茶 草 荒 荷 莉 莊 莎 莫 菜 菩 華 菲 萄 萊 萬 落 葉 著 葛 葡 蒂 蒙 蒲 蒼 蓋 蓮 蔕 蔡 蔣 蕭 薄 薦 薩 薪 藉 藍 藏 藝 藤 藥 蘆 蘇 蘭 虎 處 虛 號 虧 蛋 蛙 蜂 蜜 蝶 融 螢 蟲 蟹 蠍 蠻 血 行 術 街 衛 衝 衡 衣 表 袋 被 裁 裂 裕 補 裝 裡 製 複 褲 西 要 覆 見 規 視 親 覺 覽 觀 角 解 觸 言 訂 計 訊 討 訓 託 記 訥 訪 設 許 訴 註 証 評 詞 詢 試 詩 話 話 該 詳 誇 誌 認 誓 誕 語 誠 誤 說 誰 課 誼 調 談 請 諒 論 諸 諺 諾 謀 謂 講 謝 證 識 譜 警 譯 議 護 譽 讀 變 讓 讚 谷 豆 豈 豐 象 豪 豬 貌 貓 貝 貞 負 負 財 貢 貨 貪 貪 貫 責 貴 買 費 貼 賀 資 賈 賓 賜 賞 賢 賢 賣 賤 賦 質 賭 賴 賺 購 賽 贈 贊 贏 赤 赫 走 起 超 越 趕 趙 趣 趨 足 跌 跎 跑 距 跟 跡 路 跳 踏 踢 蹟 蹤 躍 身 躲 車 軌 軍 軒 軟 較 載 輔 輕 輛 輝 輩 輪 輯 輸 轉 轟 辛 辦 辨 辭 辯 辱 農 迅 迎 近 迦 迪 迫 述 迴 迷 追 退 送 逃 逆 透 逐 途 這 這 通 逛 逝 速 造 逢 連 週 進 逸 逼 遇 遊 運 遍 過 道 道 達 違 遙 遜 遠 適 遭 遮 遲 遷 選 遺 避 避 邀 邁 還 邊 邏 那 邦 邪 邱 郎 部 郭 郵 都 鄂 鄉 鄭 鄰 配 酒 酷 酸 醉 醒 醜 醫 采 釋 釋 里 重 野 量 金 針 釣 鈴 銀 銖 銘 銳 銷 鋒 鋼 錄 錢 錦 錫 錯 鍋 鍵 鍾 鎊 鎖 鎮 鏡 鐘 鐵 鑑 長 門 閃 閉 開 閒 間 閣 閱 闆 闊 闐 關 闡 防 阻 阿 陀 附 降 限 院 院 陣 除 陪 陰 陳 陵 陵 陶 陷 陸 陽 隆 隊 階 隔 際 障 隨 險 隱 隻 雄 雄 雅 集 雖 雙 雜 雞 離 難 雨 雪 雲 零 雷 電 需 震 霍 霧 露 霸 霹 靂 靈 青 靖 靜 非 靠 面 革 靼 鞋 韃 韋 韓 音 韻 響 頁 頂 項 順 須 預 頑 頓 頗 領 頭 頻 顆 題 額 顏 願 類 顧 顯 風 飄 飛 食 飯 飲 飽 飾 餅 養 餐 餘 館 首 香 馬 駐 駕 駛 騎 騙 騷 驅 驗 驚 骨 體 高 髮 鬆 鬥 鬧 鬱 鬼 魁 魂 魅 魔 魚 魯 鮮 鳥 鳳 鳴 鴻 鵝 鷹 鹿 麗 麥 麵 麻 麼 黃 黎 黑 默 點 黨 鼓 鼠 鼻 齊 齋 齒 齡 龍 龜", + 3: "伏 侶 兌 兹 别 勳 卑 占 叶 堤 墎 奥 孜 峇 巽 彝 楔 渾 燦 狄 琳 瑚 甫 礁 芒 苗 茨 蚩 蜀 隴", + 5: "一 丁 丈 不 且 丞 並 串 乘 乾 亂 亭 傀 僎 僵 儐 償 儳 儷 儻 叢 嚴 囌 囑 廳", + }, + "zu": { + 0: "a b bh c ch d dl dy e f g gc gq gx h hh hl i j k kh kl kp l m n nc ngc ngq ngx nhl nk nkc nkq nkx nq ntsh nx ny o p ph q qh r rh s sh t th tl ts tsh u v w x xh y z", + 3: "á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ", + 4: "a b c d e f g h i j k l m n o p q r s t u v w x y z", + }, +} diff --git a/libgo/go/exp/locale/collate/tools/colcmp/col.go b/libgo/go/exp/locale/collate/tools/colcmp/col.go new file mode 100644 index 0000000..26e015c --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/col.go @@ -0,0 +1,95 @@ +// Copyright 2012 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 main + +import ( + "exp/locale/collate" + "log" + "unicode/utf16" +) + +// Input holds an input string in both UTF-8 and UTF-16 format. +type Input struct { + index int // used for restoring to original random order + UTF8 []byte + UTF16 []uint16 + key []byte // used for sorting +} + +func (i Input) String() string { + return string(i.UTF8) +} + +func makeInput(s8 []byte, s16 []uint16) Input { + return Input{UTF8: s8, UTF16: s16} +} + +func makeInputString(s string) Input { + return Input{ + UTF8: []byte(s), + UTF16: utf16.Encode([]rune(s)), + } +} + +// Collator is an interface for architecture-specific implementations of collation. +type Collator interface { + // Key generates a sort key for the given input. Implemenations + // may return nil if a collator does not support sort keys. + Key(s Input) []byte + + // Compare returns -1 if a < b, 1 if a > b and 0 if a == b. + Compare(a, b Input) int +} + +// CollatorFactory creates a Collator for a given locale. +type CollatorFactory struct { + name string + makeFn func(locale string) (Collator, error) + description string +} + +var collators = []CollatorFactory{} + +// AddFactory registers f as a factory for an implementation of Collator. +func AddFactory(f CollatorFactory) { + collators = append(collators, f) +} + +func getCollator(name, locale string) Collator { + for _, f := range collators { + if f.name == name { + col, err := f.makeFn(locale) + if err != nil { + log.Fatal(err) + } + return col + } + } + log.Fatalf("collator of type %q not found", name) + return nil +} + +// goCollator is an implemention of Collator using go's own collator. +type goCollator struct { + c *collate.Collator + buf collate.Buffer +} + +func init() { + AddFactory(CollatorFactory{"go", newGoCollator, "Go's native collator implementation."}) +} + +func newGoCollator(locale string) (Collator, error) { + c := &goCollator{c: collate.New(locale)} + return c, nil +} + +func (c *goCollator) Key(b Input) []byte { + return c.c.Key(&c.buf, b.UTF8) +} + +func (c *goCollator) Compare(a, b Input) int { + return c.c.Compare(&c.buf, a.UTF8, b.UTF8) +} diff --git a/libgo/go/exp/locale/collate/tools/colcmp/colcmp.go b/libgo/go/exp/locale/collate/tools/colcmp/colcmp.go new file mode 100644 index 0000000..61c90b5 --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/colcmp.go @@ -0,0 +1,528 @@ +// Copyright 2012 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 main + +import ( + "bytes" + "exp/norm" + "flag" + "fmt" + "io" + "log" + "os" + "runtime/pprof" + "sort" + "strconv" + "strings" + "text/template" + "time" +) + +var ( + doNorm = flag.Bool("norm", false, "normalize input strings") + cases = flag.Bool("case", false, "generate case variants") + verbose = flag.Bool("verbose", false, "print results") + debug = flag.Bool("debug", false, "output debug information") + locale = flag.String("locale", "en_US", "the locale to use. May be a comma-separated list for some commands.") + col = flag.String("col", "go", "collator to test") + gold = flag.String("gold", "go", "collator used as the gold standard") + usecmp = flag.Bool("usecmp", false, + `use comparison instead of sort keys when sorting. Must be "test", "gold" or "both"`) + cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") + exclude = flag.String("exclude", "", "exclude errors that contain any of the characters") + limit = flag.Int("limit", 5000000, "maximum number of samples to generate for one run") +) + +func failOnError(err error) { + if err != nil { + log.Panic(err) + } +} + +// Test holds test data for testing a locale-collator pair. +// Test also provides functionality that is commonly used by the various commands. +type Test struct { + ctxt *Context + Name string + Locale string + ColName string + + Col Collator + UseCompare bool + + Input []Input + Duration time.Duration + + start time.Time + msg string + count int +} + +func (t *Test) clear() { + t.Col = nil + t.Input = nil +} + +const ( + msgGeneratingInput = "generating input" + msgGeneratingKeys = "generating keys" + msgSorting = "sorting" +) + +var lastLen = 0 + +func (t *Test) SetStatus(msg string) { + if *debug || *verbose { + fmt.Printf("%s: %s...\n", t.Name, msg) + } else if t.ctxt.out != nil { + fmt.Fprint(t.ctxt.out, strings.Repeat(" ", lastLen)) + fmt.Fprint(t.ctxt.out, strings.Repeat("\b", lastLen)) + fmt.Fprint(t.ctxt.out, msg, "...") + lastLen = len(msg) + 3 + fmt.Fprint(t.ctxt.out, strings.Repeat("\b", lastLen)) + } +} + +// Start is used by commands to signal the start of an operation. +func (t *Test) Start(msg string) { + t.SetStatus(msg) + t.count = 0 + t.msg = msg + t.start = time.Now() +} + +// Stop is used by commands to signal the end of an operation. +func (t *Test) Stop() (time.Duration, int) { + d := time.Now().Sub(t.start) + t.Duration += d + if *debug || *verbose { + fmt.Printf("%s: %s done. (%.3fs /%dK ops)\n", t.Name, t.msg, d.Seconds(), t.count/1000) + } + return d, t.count +} + +// generateKeys generates sort keys for all the inputs. +func (t *Test) generateKeys() { + for i, s := range t.Input { + b := t.Col.Key(s) + t.Input[i].key = b + if *debug { + fmt.Printf("%s (%X): %X\n", string(s.UTF8), s.UTF16, b) + } + } +} + +// Sort sorts the inputs. It generates sort keys if this is required by the +// chosen sort method. +func (t *Test) Sort() (tkey, tsort time.Duration, nkey, nsort int) { + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + failOnError(err) + pprof.StartCPUProfile(f) + defer pprof.StopCPUProfile() + } + if t.UseCompare || t.Col.Key(t.Input[0]) == nil { + t.Start(msgSorting) + sort.Sort(&testCompare{*t}) + tsort, nsort = t.Stop() + } else { + t.Start(msgGeneratingKeys) + t.generateKeys() + t.count = len(t.Input) + tkey, nkey = t.Stop() + t.Start(msgSorting) + sort.Sort(t) + tsort, nsort = t.Stop() + } + return +} + +func (t *Test) Swap(a, b int) { + t.Input[a], t.Input[b] = t.Input[b], t.Input[a] +} + +func (t *Test) Less(a, b int) bool { + t.count++ + return bytes.Compare(t.Input[a].key, t.Input[b].key) == -1 +} + +func (t Test) Len() int { + return len(t.Input) +} + +type testCompare struct { + Test +} + +func (t *testCompare) Less(a, b int) bool { + t.count++ + return t.Col.Compare(t.Input[a], t.Input[b]) == -1 +} + +type testRestore struct { + Test +} + +func (t *testRestore) Less(a, b int) bool { + return t.Input[a].index < t.Input[b].index +} + +// GenerateInput generates input phrases for the locale tested by t. +func (t *Test) GenerateInput() { + t.Input = nil + if t.ctxt.lastLocale != t.Locale { + gen := phraseGenerator{} + gen.init(t.Locale) + t.SetStatus(msgGeneratingInput) + t.ctxt.lastInput = nil // allow the previous value to be garbage collected. + t.Input = gen.generate(*doNorm) + t.ctxt.lastInput = t.Input + t.ctxt.lastLocale = t.Locale + } else { + t.Input = t.ctxt.lastInput + for i := range t.Input { + t.Input[i].key = nil + } + sort.Sort(&testRestore{*t}) + } +} + +// Context holds all tests and settings translated from command line options. +type Context struct { + test []*Test + last *Test + + lastLocale string + lastInput []Input + + out io.Writer +} + +func (ts *Context) Printf(format string, a ...interface{}) { + ts.assertBuf() + fmt.Fprintf(ts.out, format, a...) +} + +func (ts *Context) Print(a ...interface{}) { + ts.assertBuf() + fmt.Fprint(ts.out, a...) +} + +// assertBuf sets up an io.Writer for ouput, if it doesn't already exist. +// In debug and verbose mode, output is buffered so that the regular output +// will not interfere with the additional output. Otherwise, output is +// written directly to stdout for a more responsive feel. +func (ts *Context) assertBuf() { + if ts.out != nil { + return + } + if *debug || *verbose { + ts.out = &bytes.Buffer{} + } else { + ts.out = os.Stdout + } +} + +// flush flushes the contents of ts.out to stdout, if it is not stdout already. +func (ts *Context) flush() { + if ts.out != nil { + if _, ok := ts.out.(io.ReadCloser); !ok { + io.Copy(os.Stdout, ts.out.(io.Reader)) + } + } +} + +// parseTests creates all tests from command lines and returns +// a Context to hold them. +func parseTests() *Context { + ctxt := &Context{} + colls := strings.Split(*col, ",") + for _, loc := range strings.Split(*locale, ",") { + loc = strings.TrimSpace(loc) + for _, name := range colls { + name = strings.TrimSpace(name) + col := getCollator(name, loc) + ctxt.test = append(ctxt.test, &Test{ + ctxt: ctxt, + Locale: loc, + ColName: name, + UseCompare: *usecmp, + Col: col, + }) + } + } + return ctxt +} + +func (c *Context) Len() int { + return len(c.test) +} + +func (c *Context) Test(i int) *Test { + if c.last != nil { + c.last.clear() + } + c.last = c.test[i] + return c.last +} + +func parseInput(args []string) []Input { + input := []Input{} + for _, s := range args { + rs := []rune{} + for len(s) > 0 { + var r rune + r, _, s, _ = strconv.UnquoteChar(s, '\'') + rs = append(rs, r) + } + s = string(rs) + if *doNorm { + s = norm.NFC.String(s) + } + input = append(input, makeInputString(s)) + } + return input +} + +// A Command is an implementation of a colcmp command. +type Command struct { + Run func(cmd *Context, args []string) + Usage string + Short string + Long string +} + +func (cmd Command) Name() string { + return strings.SplitN(cmd.Usage, " ", 2)[0] +} + +var commands = []*Command{ + cmdSort, + cmdBench, + cmdRegress, +} + +const sortHelp = ` +Sort sorts a given list of strings. Strings are separated by whitespace. +` + +var cmdSort = &Command{ + Run: runSort, + Usage: "sort <string>*", + Short: "sort a given list of strings", + Long: sortHelp, +} + +func runSort(ctxt *Context, args []string) { + input := parseInput(args) + if len(input) == 0 { + log.Fatalf("Nothing to sort.") + } + if ctxt.Len() > 1 { + ctxt.Print("COLL LOCALE RESULT\n") + } + for i := 0; i < ctxt.Len(); i++ { + t := ctxt.Test(i) + t.Input = append(t.Input, input...) + t.Sort() + if ctxt.Len() > 1 { + ctxt.Printf("%-5s %-5s ", t.ColName, t.Locale) + } + for _, s := range t.Input { + ctxt.Print(string(s.UTF8), " ") + } + ctxt.Print("\n") + } +} + +const benchHelp = ` +Bench runs a benchmark for the given list of collator implementations. +If no collator implementations are given, the go collator will be used. +` + +var cmdBench = &Command{ + Run: runBench, + Usage: "bench", + Short: "benchmark a given list of collator implementations", + Long: benchHelp, +} + +func runBench(ctxt *Context, args []string) { + ctxt.Printf("%-7s %-5s %-6s %-24s %-24s %-5s %s\n", "LOCALE", "COLL", "N", "KEYS", "SORT", "AVGLN", "TOTAL") + for i := 0; i < ctxt.Len(); i++ { + t := ctxt.Test(i) + ctxt.Printf("%-7s %-5s ", t.Locale, t.ColName) + t.GenerateInput() + ctxt.Printf("%-6s ", fmt.Sprintf("%dK", t.Len()/1000)) + tkey, tsort, nkey, nsort := t.Sort() + p := func(dur time.Duration, n int) { + s := "" + if dur > 0 { + s = fmt.Sprintf("%6.3fs ", dur.Seconds()) + if n > 0 { + s += fmt.Sprintf("%15s", fmt.Sprintf("(%4.2f ns/op)", float64(dur)/float64(n))) + } + } + ctxt.Printf("%-24s ", s) + } + p(tkey, nkey) + p(tsort, nsort) + + total := 0 + for _, s := range t.Input { + total += len(s.key) + } + ctxt.Printf("%-5d ", total/t.Len()) + ctxt.Printf("%6.3fs\n", t.Duration.Seconds()) + if *debug { + for _, s := range t.Input { + fmt.Print(string(s.UTF8), " ") + } + fmt.Println() + } + } +} + +const regressHelp = ` +Regress runs a monkey test by comparing the results of randomly generated tests +between two implementations of a collator. The user may optionally pass a list +of strings to regress against instead of the default test set. +` + +var cmdRegress = &Command{ + Run: runRegress, + Usage: "regress -gold=<col> -test=<col> [string]*", + Short: "run a monkey test between two collators", + Long: regressHelp, +} + +const failedKeyCompare = ` +%d: incorrect comparison result for input: + a: %q (%.4X) + key: %s + b: %q (%.4X) + key: %s + Compare(a, b) = %d; want %d. + + gold keys: + a: %s + b: %s +` + +const failedCompare = ` +%d: incorrect comparison result for input: + a: %q (%.4X) + b: %q (%.4X) + Compare(a, b) = %d; want %d. +` + +func keyStr(b []byte) string { + buf := &bytes.Buffer{} + for _, v := range b { + fmt.Fprintf(buf, "%.2X ", v) + } + return buf.String() +} + +func runRegress(ctxt *Context, args []string) { + input := parseInput(args) + for i := 0; i < ctxt.Len(); i++ { + t := ctxt.Test(i) + if len(input) > 0 { + t.Input = append(t.Input, input...) + } else { + t.GenerateInput() + } + t.Sort() + count := 0 + gold := getCollator(*gold, t.Locale) + for i := 1; i < len(t.Input); i++ { + ia := t.Input[i-1] + ib := t.Input[i] + if bytes.IndexAny(ib.UTF8, *exclude) != -1 { + i++ + continue + } + if bytes.IndexAny(ia.UTF8, *exclude) != -1 { + continue + } + goldCmp := gold.Compare(ia, ib) + if cmp := bytes.Compare(ia.key, ib.key); cmp != goldCmp { + count++ + a := string(ia.UTF8) + b := string(ib.UTF8) + fmt.Printf(failedKeyCompare, i-1, a, []rune(a), keyStr(ia.key), b, []rune(b), keyStr(ib.key), cmp, goldCmp, keyStr(gold.Key(ia)), keyStr(gold.Key(ib))) + } else if cmp := t.Col.Compare(ia, ib); cmp != goldCmp { + count++ + a := string(ia.UTF8) + b := string(ib.UTF8) + fmt.Printf(failedKeyCompare, i-1, a, []rune(a), b, []rune(b), cmp, goldCmp) + } + } + if count > 0 { + ctxt.Printf("Found %d inconsistencies in %d entries.\n", count, t.Len()-1) + } + } +} + +const helpTemplate = ` +colcmp is a tool for testing and benchmarking collation + +Usage: colcmp command [arguments] + +The commands are: +{{range .}} + {{.Name | printf "%-11s"}} {{.Short}}{{end}} + +Use "col help [topic]" for more information about that topic. +` + +const detailedHelpTemplate = ` +Usage: colcmp {{.Usage}} + +{{.Long | trim}} +` + +func runHelp(args []string) { + t := template.New("help") + t.Funcs(template.FuncMap{"trim": strings.TrimSpace}) + if len(args) < 1 { + template.Must(t.Parse(helpTemplate)) + failOnError(t.Execute(os.Stderr, &commands)) + } else { + for _, cmd := range commands { + if cmd.Name() == args[0] { + template.Must(t.Parse(detailedHelpTemplate)) + failOnError(t.Execute(os.Stderr, cmd)) + os.Exit(0) + } + } + log.Fatalf("Unknown command %q. Run 'colcmp help'.", args[0]) + } + os.Exit(0) +} + +func main() { + flag.Parse() + log.SetFlags(0) + + ctxt := parseTests() + + if flag.NArg() < 1 { + runHelp(nil) + } + args := flag.Args()[1:] + if flag.Arg(0) == "help" { + runHelp(args) + } + for _, cmd := range commands { + if cmd.Name() == flag.Arg(0) { + cmd.Run(ctxt, args) + ctxt.flush() + return + } + } + runHelp(flag.Args()) +} diff --git a/libgo/go/exp/locale/collate/tools/colcmp/darwin.go b/libgo/go/exp/locale/collate/tools/colcmp/darwin.go new file mode 100644 index 0000000..ce2ab46 --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/darwin.go @@ -0,0 +1,111 @@ +// Copyright 2012 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 darwin + +package main + +/* +#cgo LDFLAGS: -framework CoreFoundation +#include <CoreFoundation/CFBase.h> +#include <CoreFoundation/CoreFoundation.h> +*/ +import "C" +import ( + "unsafe" +) + +func init() { + AddFactory(CollatorFactory{"osx", newOSX16Collator, + "OS X/Darwin collator, using native strings."}) + AddFactory(CollatorFactory{"osx8", newOSX8Collator, + "OS X/Darwin collator for UTF-8."}) +} + +func osxUInt8P(s []byte) *C.UInt8 { + return (*C.UInt8)(unsafe.Pointer(&s[0])) +} + +func osxCharP(s []uint16) *C.UniChar { + return (*C.UniChar)(unsafe.Pointer(&s[0])) +} + +// osxCollator implements an Collator based on OS X's CoreFoundation. +type osxCollator struct { + loc C.CFLocaleRef + opt C.CFStringCompareFlags +} + +func (c *osxCollator) init(locale string) { + l := C.CFStringCreateWithBytes( + nil, + osxUInt8P([]byte(locale)), + C.CFIndex(len(locale)), + C.kCFStringEncodingUTF8, + C.Boolean(0), + ) + c.loc = C.CFLocaleCreate(nil, l) +} + +func newOSX8Collator(locale string) (Collator, error) { + c := &osx8Collator{} + c.init(locale) + return c, nil +} + +func newOSX16Collator(locale string) (Collator, error) { + c := &osx16Collator{} + c.init(locale) + return c, nil +} + +func (c osxCollator) Key(s Input) []byte { + return nil // sort keys not supported by OS X CoreFoundation +} + +type osx8Collator struct { + osxCollator +} + +type osx16Collator struct { + osxCollator +} + +func (c osx16Collator) Compare(a, b Input) int { + sa := C.CFStringCreateWithCharactersNoCopy( + nil, + osxCharP(a.UTF16), + C.CFIndex(len(a.UTF16)), + C.kCFAllocatorNull, + ) + sb := C.CFStringCreateWithCharactersNoCopy( + nil, + osxCharP(b.UTF16), + C.CFIndex(len(b.UTF16)), + C.kCFAllocatorNull, + ) + _range := C.CFRangeMake(0, C.CFStringGetLength(sa)) + return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc)) +} + +func (c osx8Collator) Compare(a, b Input) int { + sa := C.CFStringCreateWithBytesNoCopy( + nil, + osxUInt8P(a.UTF8), + C.CFIndex(len(a.UTF8)), + C.kCFStringEncodingUTF8, + C.Boolean(0), + C.kCFAllocatorNull, + ) + sb := C.CFStringCreateWithBytesNoCopy( + nil, + osxUInt8P(b.UTF8), + C.CFIndex(len(b.UTF8)), + C.kCFStringEncodingUTF8, + C.Boolean(0), + C.kCFAllocatorNull, + ) + _range := C.CFRangeMake(0, C.CFStringGetLength(sa)) + return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc)) +} diff --git a/libgo/go/exp/locale/collate/tools/colcmp/gen.go b/libgo/go/exp/locale/collate/tools/colcmp/gen.go new file mode 100644 index 0000000..f9e3118 --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/gen.go @@ -0,0 +1,179 @@ +// Copyright 2012 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 main + +import ( + "exp/norm" + "math" + "math/rand" + "strings" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// parent computes the parent locale for the given locale. +// It returns false if the parent is already root. +func parent(locale string) (parent string, ok bool) { + if locale == "root" { + return "", false + } + if i := strings.LastIndex(locale, "_"); i != -1 { + return locale[:i], true + } + return "root", true +} + +// rewriter is used to both unique strings and create variants of strings +// to add to the test set. +type rewriter struct { + seen map[string]bool + addCases bool +} + +func newRewriter() *rewriter { + return &rewriter{ + seen: make(map[string]bool), + } +} + +func (r *rewriter) insert(a []string, s string) []string { + if !r.seen[s] { + r.seen[s] = true + a = append(a, s) + } + return a +} + +// rewrite takes a sequence of strings in, adds variants of the these strings +// based on options and removes duplicates. +func (r *rewriter) rewrite(ss []string) []string { + ns := []string{} + for _, s := range ss { + ns = r.insert(ns, s) + if r.addCases { + rs := []rune(s) + rn := rs[0] + for c := unicode.SimpleFold(rn); c != rn; c = unicode.SimpleFold(c) { + rs[0] = c + ns = r.insert(ns, string(rs)) + } + } + } + return ns +} + +// exemplarySet holds a parsed set of characters from the exemplarCharacters table. +type exemplarySet struct { + typ exemplarType + set []string + charIndex int // cumulative total of phrases, including this set +} + +type phraseGenerator struct { + sets [exN]exemplarySet + n int +} + +func (g *phraseGenerator) init(locale string) { + ec := exemplarCharacters + // get sets for locale or parent locale if the set is not defined. + for i := range g.sets { + for p, ok := locale, true; ok; p, ok = parent(p) { + if set, ok := ec[p]; ok && set[i] != "" { + g.sets[i].set = strings.Split(set[i], " ") + break + } + } + } + r := newRewriter() + r.addCases = *cases + for i := range g.sets { + g.sets[i].set = r.rewrite(g.sets[i].set) + } + // compute indexes + for i, set := range g.sets { + g.n += len(set.set) + g.sets[i].charIndex = g.n + } +} + +// phrase returns the ith phrase, where i < g.n. +func (g *phraseGenerator) phrase(i int) string { + for _, set := range g.sets { + if i < set.charIndex { + return set.set[i-(set.charIndex-len(set.set))] + } + } + panic("index out of range") +} + +// generate generates inputs by combining all pairs of examplar strings. +// If doNorm is true, all input strings are normalized to NFC. +// TODO: allow other variations, statistical models, and random +// trailing sequences. +func (g *phraseGenerator) generate(doNorm bool) []Input { + const ( + M = 1024 * 1024 + buf8Size = 30 * M + buf16Size = 10 * M + ) + // TODO: use a better way to limit the input size. + if sq := int(math.Sqrt(float64(*limit))); g.n > sq { + g.n = sq + } + size := g.n * g.n + a := make([]Input, 0, size) + buf8 := make([]byte, 0, buf8Size) + buf16 := make([]uint16, 0, buf16Size) + + addInput := func(str string) { + buf8 = buf8[len(buf8):] + buf16 = buf16[len(buf16):] + if len(str) > cap(buf8) { + buf8 = make([]byte, 0, buf8Size) + } + if len(str) > cap(buf16) { + buf16 = make([]uint16, 0, buf16Size) + } + if doNorm { + buf8 = norm.NFC.AppendString(buf8, str) + } else { + buf8 = append(buf8, str...) + } + buf16 = appendUTF16(buf16, buf8) + a = append(a, makeInput(buf8, buf16)) + } + for i := 0; i < g.n; i++ { + p1 := g.phrase(i) + addInput(p1) + for j := 0; j < g.n; j++ { + p2 := g.phrase(j) + addInput(p1 + p2) + } + } + // permutate + rnd := rand.New(rand.NewSource(int64(rand.Int()))) + for i := range a { + j := i + rnd.Intn(len(a)-i) + a[i], a[j] = a[j], a[i] + a[i].index = i // allow restoring this order if input is used multiple times. + } + return a +} + +func appendUTF16(buf []uint16, s []byte) []uint16 { + for len(s) > 0 { + r, sz := utf8.DecodeRune(s) + s = s[sz:] + r1, r2 := utf16.EncodeRune(r) + if r1 != 0xFFFD { + buf = append(buf, uint16(r1), uint16(r2)) + } else { + buf = append(buf, uint16(r)) + } + } + return buf +} diff --git a/libgo/go/exp/locale/collate/tools/colcmp/icu.go b/libgo/go/exp/locale/collate/tools/colcmp/icu.go new file mode 100644 index 0000000..91980ac --- /dev/null +++ b/libgo/go/exp/locale/collate/tools/colcmp/icu.go @@ -0,0 +1,209 @@ +// Copyright 2012 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 icu + +package main + +/* +#cgo LDFLAGS: -licui18n -licuuc +#include <stdlib.h> +#include <unicode/ucol.h> +#include <unicode/uiter.h> +#include <unicode/utypes.h> +*/ +import "C" +import ( + "fmt" + "log" + "unicode/utf16" + "unicode/utf8" + "unsafe" +) + +func init() { + AddFactory(CollatorFactory{"icu", newUTF16, + "Main ICU collator, using native strings."}) + AddFactory(CollatorFactory{"icu8", newUTF8iter, + "ICU collator using ICU iterators to process UTF8."}) + AddFactory(CollatorFactory{"icu16", newUTF8conv, + "ICU collation by first converting UTF8 to UTF16."}) +} + +func icuCharP(s []byte) *C.char { + return (*C.char)(unsafe.Pointer(&s[0])) +} + +func icuUInt8P(s []byte) *C.uint8_t { + return (*C.uint8_t)(unsafe.Pointer(&s[0])) +} + +func icuUCharP(s []uint16) *C.UChar { + return (*C.UChar)(unsafe.Pointer(&s[0])) +} +func icuULen(s []uint16) C.int32_t { + return C.int32_t(len(s)) +} +func icuSLen(s []byte) C.int32_t { + return C.int32_t(len(s)) +} + +// icuCollator implements a Collator based on ICU. +type icuCollator struct { + loc *C.char + col *C.UCollator + keyBuf []byte +} + +const growBufSize = 10 * 1024 * 1024 + +func (c *icuCollator) init(locale string) error { + err := C.UErrorCode(0) + c.loc = C.CString(locale) + c.col = C.ucol_open(c.loc, &err) + if err > 0 { + return fmt.Errorf("failed opening collator for %q", locale) + } else if err < 0 { + loc := C.ucol_getLocaleByType(c.col, 0, &err) + fmt, ok := map[int]string{ + -127: "warning: using default collator: %s", + -128: "warning: using fallback collator: %s", + }[int(err)] + if ok { + log.Printf(fmt, C.GoString(loc)) + } + } + c.keyBuf = make([]byte, 0, growBufSize) + return nil +} + +func (c *icuCollator) buf() (*C.uint8_t, C.int32_t) { + if len(c.keyBuf) == cap(c.keyBuf) { + c.keyBuf = make([]byte, 0, growBufSize) + } + b := c.keyBuf[len(c.keyBuf):cap(c.keyBuf)] + return icuUInt8P(b), icuSLen(b) +} + +func (c *icuCollator) extendBuf(n C.int32_t) []byte { + end := len(c.keyBuf) + int(n) + if end > cap(c.keyBuf) { + if len(c.keyBuf) == 0 { + log.Fatalf("icuCollator: max string size exceeded: %v > %v", n, growBufSize) + } + c.keyBuf = make([]byte, 0, growBufSize) + return nil + } + b := c.keyBuf[len(c.keyBuf):end] + c.keyBuf = c.keyBuf[:end] + return b +} + +func (c *icuCollator) Close() error { + C.ucol_close(c.col) + C.free(unsafe.Pointer(c.loc)) + return nil +} + +// icuUTF16 implements the Collator interface. +type icuUTF16 struct { + icuCollator +} + +func newUTF16(locale string) (Collator, error) { + c := &icuUTF16{} + return c, c.init(locale) +} + +func (c *icuUTF16) Compare(a, b Input) int { + return int(C.ucol_strcoll(c.col, icuUCharP(a.UTF16), icuULen(a.UTF16), icuUCharP(b.UTF16), icuULen(b.UTF16))) +} + +func (c *icuUTF16) Key(s Input) []byte { + bp, bn := c.buf() + n := C.ucol_getSortKey(c.col, icuUCharP(s.UTF16), icuULen(s.UTF16), bp, bn) + if b := c.extendBuf(n); b != nil { + return b + } + return c.Key(s) +} + +// icuUTF8iter implements the Collator interface +// This implementation wraps the UTF8 string in an iterator +// which is passed to the collator. +type icuUTF8iter struct { + icuCollator + a, b C.UCharIterator +} + +func newUTF8iter(locale string) (Collator, error) { + c := &icuUTF8iter{} + return c, c.init(locale) +} + +func (c *icuUTF8iter) Compare(a, b Input) int { + err := C.UErrorCode(0) + C.uiter_setUTF8(&c.a, icuCharP(a.UTF8), icuSLen(a.UTF8)) + C.uiter_setUTF8(&c.b, icuCharP(b.UTF8), icuSLen(b.UTF8)) + return int(C.ucol_strcollIter(c.col, &c.a, &c.b, &err)) +} + +func (c *icuUTF8iter) Key(s Input) []byte { + err := C.UErrorCode(0) + state := [2]C.uint32_t{} + C.uiter_setUTF8(&c.a, icuCharP(s.UTF8), icuSLen(s.UTF8)) + bp, bn := c.buf() + n := C.ucol_nextSortKeyPart(c.col, &c.a, &(state[0]), bp, bn, &err) + if n >= bn { + // Force failure. + if c.extendBuf(n+1) != nil { + log.Fatal("expected extension to fail") + } + return c.Key(s) + } + return c.extendBuf(n) +} + +// icuUTF8conv implementes the Collator interface. +// This implentation first converts the give UTF8 string +// to UTF16 and then calls the main ICU collation function. +type icuUTF8conv struct { + icuCollator +} + +func newUTF8conv(locale string) (Collator, error) { + c := &icuUTF8conv{} + return c, c.init(locale) +} + +func (c *icuUTF8conv) Compare(sa, sb Input) int { + a := encodeUTF16(sa.UTF8) + b := encodeUTF16(sb.UTF8) + return int(C.ucol_strcoll(c.col, icuUCharP(a), icuULen(a), icuUCharP(b), icuULen(b))) +} + +func (c *icuUTF8conv) Key(s Input) []byte { + a := encodeUTF16(s.UTF8) + bp, bn := c.buf() + n := C.ucol_getSortKey(c.col, icuUCharP(a), icuULen(a), bp, bn) + if b := c.extendBuf(n); b != nil { + return b + } + return c.Key(s) +} + +func encodeUTF16(b []byte) []uint16 { + a := []uint16{} + for len(b) > 0 { + r, sz := utf8.DecodeRune(b) + b = b[sz:] + r1, r2 := utf16.EncodeRune(r) + if r1 != 0xFFFD { + a = append(a, uint16(r1), uint16(r2)) + } else { + a = append(a, uint16(r)) + } + } + return a +} diff --git a/libgo/go/exp/locale/collate/trie.go b/libgo/go/exp/locale/collate/trie.go new file mode 100644 index 0000000..c70a89b --- /dev/null +++ b/libgo/go/exp/locale/collate/trie.go @@ -0,0 +1,99 @@ +// Copyright 2012 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. + +// The trie in this file is used to associate the first full character +// in an UTF-8 string to a collation element. +// All but the last byte in a UTF-8 byte sequence are +// used to lookup offsets in the index table to be used for the next byte. +// The last byte is used to index into a table of collation elements. +// For a full description, see exp/locale/collate/build/trie.go. + +package collate + +const blockSize = 64 + +type trie struct { + index0 []uint16 // index for first byte (0xC0-0xFF) + values0 []uint32 // index for first byte (0x00-0x7F) + index []uint16 + values []uint32 +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + t6 = 0xFC // 1111 1100 + te = 0xFE // 1111 1110 +) + +func (t *trie) lookupValue(n uint16, b byte) colElem { + return colElem(t.values[int(n)<<6+int(b)]) +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *trie) lookup(s []byte) (v colElem, sz int) { + c0 := s[0] + switch { + case c0 < tx: + return colElem(t.values0[c0]), 1 + case c0 < t2: + return 0, 1 + case c0 < t3: + if len(s) < 2 { + return 0, 0 + } + i := t.index0[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + return t.lookupValue(i, c1), 2 + case c0 < t4: + if len(s) < 3 { + return 0, 0 + } + i := t.index0[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := int(i)<<6 + int(c1) + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + return t.lookupValue(i, c2), 3 + case c0 < t5: + if len(s) < 4 { + return 0, 0 + } + i := t.index0[c0] + c1 := s[1] + if c1 < tx || t2 <= c1 { + return 0, 1 + } + o := int(i)<<6 + int(c1) + i = t.index[o] + c2 := s[2] + if c2 < tx || t2 <= c2 { + return 0, 2 + } + o = int(i)<<6 + int(c2) + i = t.index[o] + c3 := s[3] + if c3 < tx || t2 <= c3 { + return 0, 3 + } + return t.lookupValue(i, c3), 4 + } + // Illegal rune + return 0, 1 +} diff --git a/libgo/go/exp/locale/collate/trie_test.go b/libgo/go/exp/locale/collate/trie_test.go new file mode 100644 index 0000000..00d636c --- /dev/null +++ b/libgo/go/exp/locale/collate/trie_test.go @@ -0,0 +1,106 @@ +// Copyright 2012 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 collate + +import ( + "testing" +) + +// We take the smallest, largest and an arbitrary value for each +// of the UTF-8 sequence lengths. +var testRunes = []rune{ + 0x01, 0x0C, 0x7F, // 1-byte sequences + 0x80, 0x100, 0x7FF, // 2-byte sequences + 0x800, 0x999, 0xFFFF, // 3-byte sequences + 0x10000, 0x10101, 0x10FFFF, // 4-byte sequences + 0x200, 0x201, 0x202, 0x210, 0x215, // five entries in one sparse block +} + +// Test cases for illegal runes. +type trietest struct { + size int + bytes []byte +} + +var tests = []trietest{ + // illegal runes + {1, []byte{0x80}}, + {1, []byte{0xFF}}, + {1, []byte{t2, tx - 1}}, + {1, []byte{t2, t2}}, + {2, []byte{t3, tx, tx - 1}}, + {2, []byte{t3, tx, t2}}, + {1, []byte{t3, tx - 1, tx}}, + {3, []byte{t4, tx, tx, tx - 1}}, + {3, []byte{t4, tx, tx, t2}}, + {1, []byte{t4, t2, tx, tx - 1}}, + {2, []byte{t4, tx, t2, tx - 1}}, + + // short runes + {0, []byte{t2}}, + {0, []byte{t3, tx}}, + {0, []byte{t4, tx, tx}}, + + // we only support UTF-8 up to utf8.UTFMax bytes (4 bytes) + {1, []byte{t5, tx, tx, tx, tx}}, + {1, []byte{t6, tx, tx, tx, tx, tx}}, +} + +func TestLookupTrie(t *testing.T) { + for i, r := range testRunes { + b := []byte(string(r)) + v, sz := testTrie.lookup(b) + if int(v) != i { + t.Errorf("lookup(%U): found value %#x, expected %#x", r, v, i) + } + if sz != len(b) { + t.Errorf("lookup(%U): found size %d, expected %d", r, sz, len(b)) + } + } + for i, tt := range tests { + v, sz := testTrie.lookup(tt.bytes) + if int(v) != 0 { + t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) + } + if sz != tt.size { + t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) + } + } +} + +// test data is taken from exp/collate/locale/build/trie_test.go +var testValues = [832]uint32{ + 0x000c: 0x00000001, + 0x007f: 0x00000002, + 0x00c0: 0x00000003, + 0x0100: 0x00000004, + 0x0140: 0x0000000c, 0x0141: 0x0000000d, 0x0142: 0x0000000e, + 0x0150: 0x0000000f, + 0x0155: 0x00000010, + 0x01bf: 0x00000005, + 0x01c0: 0x00000006, + 0x0219: 0x00000007, + 0x027f: 0x00000008, + 0x0280: 0x00000009, + 0x02c1: 0x0000000a, + 0x033f: 0x0000000b, +} + +var testLookup = [640]uint16{ + 0x0e0: 0x05, 0x0e6: 0x06, + 0x13f: 0x07, + 0x140: 0x08, 0x144: 0x09, + 0x190: 0x03, + 0x1ff: 0x0a, + 0x20f: 0x05, + 0x242: 0x01, 0x244: 0x02, + 0x248: 0x03, + 0x25f: 0x04, + 0x260: 0x01, + 0x26f: 0x02, + 0x270: 0x04, 0x274: 0x06, +} + +var testTrie = trie{testLookup[6*blockSize:], testValues[:], testLookup[:], testValues[:]} diff --git a/libgo/go/exp/norm/composition.go b/libgo/go/exp/norm/composition.go index 2cbe1ac..7f84b94 100644 --- a/libgo/go/exp/norm/composition.go +++ b/libgo/go/exp/norm/composition.go @@ -22,10 +22,10 @@ const ( // the UTF-8 characters in order. Only the rune array is maintained in sorted // order. flush writes the resulting segment to a byte array. type reorderBuffer struct { - rune [maxBufferSize]runeInfo // Per character info. - byte [maxByteBufferSize]byte // UTF-8 buffer. Referenced by runeInfo.pos. - nrune int // Number of runeInfos. - nbyte uint8 // Number or bytes. + rune [maxBufferSize]Properties // Per character info. + byte [maxByteBufferSize]byte // UTF-8 buffer. Referenced by runeInfo.pos. + nrune int // Number of runeInfos. + nbyte uint8 // Number or bytes. f formInfo src input @@ -81,7 +81,7 @@ func (rb *reorderBuffer) flushCopy(buf []byte) int { // insertOrdered inserts a rune in the buffer, ordered by Canonical Combining Class. // It returns false if the buffer is not large enough to hold the rune. // It is used internally by insert and insertString only. -func (rb *reorderBuffer) insertOrdered(info runeInfo) bool { +func (rb *reorderBuffer) insertOrdered(info Properties) bool { n := rb.nrune if n >= maxCombiningChars+1 { return false @@ -107,12 +107,12 @@ func (rb *reorderBuffer) insertOrdered(info runeInfo) bool { // insert inserts the given rune in the buffer ordered by CCC. // It returns true if the buffer was large enough to hold the decomposed rune. -func (rb *reorderBuffer) insert(src input, i int, info runeInfo) bool { +func (rb *reorderBuffer) insert(src input, i int, info Properties) bool { if rune := src.hangul(i); rune != 0 { return rb.decomposeHangul(rune) } if info.hasDecomposition() { - return rb.insertDecomposed(info.decomposition()) + return rb.insertDecomposed(info.Decomposition()) } return rb.insertSingle(src, i, info) } @@ -136,7 +136,7 @@ func (rb *reorderBuffer) insertDecomposed(dcomp []byte) bool { // insertSingle inserts an entry in the reorderBuffer for the rune at // position i. info is the runeInfo for the rune at position i. -func (rb *reorderBuffer) insertSingle(src input, i int, info runeInfo) bool { +func (rb *reorderBuffer) insertSingle(src input, i int, info Properties) bool { // insertOrder changes nbyte pos := rb.nbyte if !rb.insertOrdered(info) { @@ -151,7 +151,7 @@ func (rb *reorderBuffer) appendRune(r rune) { bn := rb.nbyte sz := utf8.EncodeRune(rb.byte[bn:], rune(r)) rb.nbyte += utf8.UTFMax - rb.rune[rb.nrune] = runeInfo{pos: bn, size: uint8(sz)} + rb.rune[rb.nrune] = Properties{pos: bn, size: uint8(sz)} rb.nrune++ } @@ -159,7 +159,7 @@ func (rb *reorderBuffer) appendRune(r rune) { func (rb *reorderBuffer) assignRune(pos int, r rune) { bn := rb.rune[pos].pos sz := utf8.EncodeRune(rb.byte[bn:], rune(r)) - rb.rune[pos] = runeInfo{pos: bn, size: uint8(sz)} + rb.rune[pos] = Properties{pos: bn, size: uint8(sz)} } // runeAt returns the rune at position n. It is used for Hangul and recomposition. diff --git a/libgo/go/exp/norm/forminfo.go b/libgo/go/exp/norm/forminfo.go index c443b78..a982174 100644 --- a/libgo/go/exp/norm/forminfo.go +++ b/libgo/go/exp/norm/forminfo.go @@ -32,8 +32,8 @@ const ( headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte ) -// runeInfo is a representation for the data stored in charinfoTrie. -type runeInfo struct { +// Properties provides access to normalization properties of a rune. +type Properties struct { pos uint8 // start position in reorderBuffer; used in composition.go size uint8 // length of UTF-8 encoding of this rune ccc uint8 // leading canonical combining class (ccc if not decomposition) @@ -43,7 +43,7 @@ type runeInfo struct { } // functions dispatchable per form -type lookupFunc func(b input, i int) runeInfo +type lookupFunc func(b input, i int) Properties // formInfo holds Form-specific functions and tables. type formInfo struct { @@ -75,11 +75,14 @@ func init() { // We do not distinguish between boundaries for NFC, NFD, etc. to avoid // unexpected behavior for the user. For example, in NFD, there is a boundary -// after 'a'. However, a might combine with modifiers, so from the application's +// after 'a'. However, 'a' might combine with modifiers, so from the application's // perspective it is not a good boundary. We will therefore always use the // boundaries for the combining variants. -func (i runeInfo) boundaryBefore() bool { - if i.ccc == 0 && !i.combinesBackward() { + +// BoundaryBefore returns true if this rune starts a new segment and +// cannot combine with any rune on the left. +func (p Properties) BoundaryBefore() bool { + if p.ccc == 0 && !p.combinesBackward() { return true } // We assume that the CCC of the first character in a decomposition @@ -88,8 +91,10 @@ func (i runeInfo) boundaryBefore() bool { return false } -func (i runeInfo) boundaryAfter() bool { - return i.isInert() +// BoundaryAfter returns true if this rune cannot combine with runes to the right +// and always denotes the end of a segment. +func (p Properties) BoundaryAfter() bool { + return p.isInert() } // We pack quick check data in 4 bits: @@ -101,25 +106,52 @@ func (i runeInfo) boundaryAfter() bool { // influenced by normalization. type qcInfo uint8 -func (i runeInfo) isYesC() bool { return i.flags&0x4 == 0 } -func (i runeInfo) isYesD() bool { return i.flags&0x1 == 0 } +func (p Properties) isYesC() bool { return p.flags&0x4 == 0 } +func (p Properties) isYesD() bool { return p.flags&0x1 == 0 } -func (i runeInfo) combinesForward() bool { return i.flags&0x8 != 0 } -func (i runeInfo) combinesBackward() bool { return i.flags&0x2 != 0 } // == isMaybe -func (i runeInfo) hasDecomposition() bool { return i.flags&0x1 != 0 } // == isNoD +func (p Properties) combinesForward() bool { return p.flags&0x8 != 0 } +func (p Properties) combinesBackward() bool { return p.flags&0x2 != 0 } // == isMaybe +func (p Properties) hasDecomposition() bool { return p.flags&0x1 != 0 } // == isNoD -func (r runeInfo) isInert() bool { - return r.flags&0xf == 0 && r.ccc == 0 +func (p Properties) isInert() bool { + return p.flags&0xf == 0 && p.ccc == 0 } -func (r runeInfo) decomposition() []byte { - if r.index == 0 { +// Decomposition returns the decomposition for the underlying rune +// or nil if there is none. +func (p Properties) Decomposition() []byte { + if p.index == 0 { return nil } - p := r.index - n := decomps[p] & 0x3F - p++ - return decomps[p : p+uint16(n)] + i := p.index + n := decomps[i] & headerLenMask + i++ + return decomps[i : i+uint16(n)] +} + +// Size returns the length of UTF-8 encoding of the rune. +func (p Properties) Size() int { + return int(p.size) +} + +// CCC returns the canonical combining class of the underlying rune. +func (p Properties) CCC() uint8 { + if p.index > firstCCCZeroExcept { + return 0 + } + return p.ccc +} + +// LeadCCC returns the CCC of the first rune in the decomposition. +// If there is no decomposition, LeadCCC equals CCC. +func (p Properties) LeadCCC() uint8 { + return p.ccc +} + +// TrailCCC returns the CCC of the last rune in the decomposition. +// If there is no decomposition, TrailCCC equals CCC. +func (p Properties) TrailCCC() uint8 { + return p.tccc } // Recomposition @@ -135,24 +167,40 @@ func combine(a, b rune) rune { return recompMap[key] } -func lookupInfoNFC(b input, i int) runeInfo { +func lookupInfoNFC(b input, i int) Properties { v, sz := b.charinfoNFC(i) return compInfo(v, sz) } -func lookupInfoNFKC(b input, i int) runeInfo { +func lookupInfoNFKC(b input, i int) Properties { v, sz := b.charinfoNFKC(i) return compInfo(v, sz) } +// Properties returns properties for the first rune in s. +func (f Form) Properties(s []byte) Properties { + if f == NFC || f == NFD { + return compInfo(nfcTrie.lookup(s)) + } + return compInfo(nfkcTrie.lookup(s)) +} + +// PropertiesString returns properties for the first rune in s. +func (f Form) PropertiesString(s string) Properties { + if f == NFC || f == NFD { + return compInfo(nfcTrie.lookupString(s)) + } + return compInfo(nfkcTrie.lookupString(s)) +} + // compInfo converts the information contained in v and sz -// to a runeInfo. See the comment at the top of the file +// to a Properties. See the comment at the top of the file // for more information on the format. -func compInfo(v uint16, sz int) runeInfo { +func compInfo(v uint16, sz int) Properties { if v == 0 { - return runeInfo{size: uint8(sz)} + return Properties{size: uint8(sz)} } else if v >= 0x8000 { - return runeInfo{ + return Properties{ size: uint8(sz), ccc: uint8(v), tccc: uint8(v), @@ -162,7 +210,7 @@ func compInfo(v uint16, sz int) runeInfo { // has decomposition h := decomps[v] f := (qcInfo(h&headerFlagsMask) >> 4) | 0x1 - ri := runeInfo{size: uint8(sz), flags: f, index: v} + ri := Properties{size: uint8(sz), flags: f, index: v} if v >= firstCCC { v += uint16(h&headerLenMask) + 1 ri.tccc = decomps[v] diff --git a/libgo/go/exp/norm/iter.go b/libgo/go/exp/norm/iter.go index 761ba90..e37ad7b 100644 --- a/libgo/go/exp/norm/iter.go +++ b/libgo/go/exp/norm/iter.go @@ -10,8 +10,8 @@ const MaxSegmentSize = maxByteBufferSize // to a given Form. type Iter struct { rb reorderBuffer - info runeInfo // first character saved from previous iteration - next iterFunc // implementation of next depends on form + info Properties // first character saved from previous iteration + next iterFunc // implementation of next depends on form p int // current position in input source outStart int // start of current segment in output buffer @@ -124,7 +124,7 @@ doFast: break } } - } else if d := i.info.decomposition(); d != nil { + } else if d := i.info.Decomposition(); d != nil { i.rb.src.copySlice(out[outCopyStart:], inCopyStart, i.p) p := outp + len(d) if p > i.maxseg && i.setStart(outp, i.p) { @@ -245,7 +245,7 @@ doFast: if i.setStart(outp-1, i.p-1) { i.p-- outp-- - i.info = runeInfo{size: 1} + i.info = Properties{size: 1} break } } @@ -274,7 +274,7 @@ doNorm: return outp } i.info = i.rb.f.info(i.rb.src, i.p) - if i.info.boundaryBefore() { + if i.info.BoundaryBefore() { break } } diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go index 1deedc9..8ac64ba 100644 --- a/libgo/go/exp/norm/maketables.go +++ b/libgo/go/exp/norm/maketables.go @@ -23,6 +23,7 @@ import ( "sort" "strconv" "strings" + "unicode" ) func main() { @@ -38,7 +39,7 @@ func main() { } var url = flag.String("url", - "http://www.unicode.org/Public/6.0.0/ucd/", + "http://www.unicode.org/Public/"+unicode.Version+"/ucd/", "URL of Unicode database directory") var tablelist = flag.String("tables", "all", @@ -605,6 +606,10 @@ func printCharInfoTables() int { lccc := ccc(d[0]) tccc := ccc(d[len(d)-1]) + cc := ccc(r) + if cc != 0 && lccc == 0 && tccc == 0 { + logger.Fatalf("%U: trailing and leading ccc are 0 for non-zero ccc %d", r, cc) + } if tccc < lccc && lccc != 0 { const msg = "%U: lccc (%d) must be <= tcc (%d)" logger.Fatalf(msg, r, lccc, tccc) @@ -615,7 +620,13 @@ func printCharInfoTables() int { index = 1 if lccc > 0 { s += string([]byte{lccc}) - index |= 2 + index = 2 + } + if cc != lccc { + if cc != 0 { + logger.Fatalf("%U: for lccc != ccc, expected ccc to be 0; was %d", r, cc) + } + index = 3 } } return index, s @@ -642,7 +653,7 @@ func printCharInfoTables() int { size := 0 positionMap := make(map[string]uint16) decompositions.WriteString("\000") - cname := []string{"firstCCC", "firstLeadingCCC", "", "lastDecomp"} + cname := []string{"firstCCC", "firstLeadingCCC", "firstCCCZeroExcept", "lastDecomp"} fmt.Println("const (") for i, m := range decompSet { sa := []string{} diff --git a/libgo/go/exp/norm/normalize.go b/libgo/go/exp/norm/normalize.go index c1d74f8..1c3e49b 100644 --- a/libgo/go/exp/norm/normalize.go +++ b/libgo/go/exp/norm/normalize.go @@ -185,14 +185,14 @@ func doAppend(rb *reorderBuffer, out []byte, p int) []byte { } fd := &rb.f if doMerge { - var info runeInfo + var info Properties if p < n { info = fd.info(src, p) - if p == 0 && !info.boundaryBefore() { + if p == 0 && !info.BoundaryBefore() { out = decomposeToLastBoundary(rb, out) } } - if info.size == 0 || info.boundaryBefore() { + if info.size == 0 || info.BoundaryBefore() { if fd.composing { rb.compose() } @@ -316,13 +316,13 @@ func firstBoundary(rb *reorderBuffer) int { } fd := &rb.f info := fd.info(src, i) - for n := 0; info.size != 0 && !info.boundaryBefore(); { + for n := 0; info.size != 0 && !info.BoundaryBefore(); { i += int(info.size) if n++; n >= maxCombiningChars { return i } if i >= nsrc { - if !info.boundaryAfter() { + if !info.BoundaryAfter() { return -1 } return nsrc @@ -368,11 +368,11 @@ func lastBoundary(fd *formInfo, b []byte) int { if p+int(info.size) != i { // trailing non-starter bytes: illegal UTF-8 return i } - if info.boundaryAfter() { + if info.BoundaryAfter() { return i } i = p - for n := 0; i >= 0 && !info.boundaryBefore(); { + for n := 0; i >= 0 && !info.BoundaryBefore(); { info, p = lastRuneStart(fd, b[:i]) if n++; n >= maxCombiningChars { return len(b) @@ -404,7 +404,7 @@ func decomposeSegment(rb *reorderBuffer, sp int) int { break } info = rb.f.info(rb.src, sp) - bound := info.boundaryBefore() + bound := info.BoundaryBefore() if bound || info.size == 0 { break } @@ -414,12 +414,12 @@ func decomposeSegment(rb *reorderBuffer, sp int) int { // lastRuneStart returns the runeInfo and position of the last // rune in buf or the zero runeInfo and -1 if no rune was found. -func lastRuneStart(fd *formInfo, buf []byte) (runeInfo, int) { +func lastRuneStart(fd *formInfo, buf []byte) (Properties, int) { p := len(buf) - 1 for ; p >= 0 && !utf8.RuneStart(buf[p]); p-- { } if p < 0 { - return runeInfo{}, -1 + return Properties{}, -1 } return fd.info(inputBytes(buf), p), p } @@ -433,15 +433,15 @@ func decomposeToLastBoundary(rb *reorderBuffer, buf []byte) []byte { // illegal trailing continuation bytes return buf } - if info.boundaryAfter() { + if info.BoundaryAfter() { return buf } - var add [maxBackRunes]runeInfo // stores runeInfo in reverse order + var add [maxBackRunes]Properties // stores runeInfo in reverse order add[0] = info padd := 1 n := 1 p := len(buf) - int(info.size) - for ; p >= 0 && !info.boundaryBefore(); p -= int(info.size) { + for ; p >= 0 && !info.BoundaryBefore(); p -= int(info.size) { info, i = lastRuneStart(fd, buf[:p]) if int(info.size) != p-i { break @@ -452,7 +452,7 @@ func decomposeToLastBoundary(rb *reorderBuffer, buf []byte) []byte { i += int(info.size) n++ } else { - dcomp := info.decomposition() + dcomp := info.Decomposition() for i := 0; i < len(dcomp); { inf := rb.f.info(inputBytes(dcomp), i) i += int(inf.size) diff --git a/libgo/go/exp/norm/normregtest.go b/libgo/go/exp/norm/normregtest.go index 507de1a..6d21884 100644 --- a/libgo/go/exp/norm/normregtest.go +++ b/libgo/go/exp/norm/normregtest.go @@ -22,6 +22,7 @@ import ( "strconv" "strings" "time" + "unicode" "unicode/utf8" ) @@ -39,7 +40,7 @@ func main() { const file = "NormalizationTest.txt" var url = flag.String("url", - "http://www.unicode.org/Public/6.0.0/ucd/"+file, + "http://www.unicode.org/Public/"+unicode.Version+"/ucd/"+file, "URL of Unicode database directory") var localFiles = flag.Bool("local", false, @@ -48,7 +49,7 @@ var localFiles = flag.Bool("local", var logger = log.New(os.Stderr, "", log.Lshortfile) // This regression test runs the test set in NormalizationTest.txt -// (taken from http://www.unicode.org/Public/6.0.0/ucd/). +// (taken from http://www.unicode.org/Public/<unicode.Version>/ucd/). // // NormalizationTest.txt has form: // @Part0 # Specific cases diff --git a/libgo/go/exp/norm/tables.go b/libgo/go/exp/norm/tables.go index e97b171..231d85d 100644 --- a/libgo/go/exp/norm/tables.go +++ b/libgo/go/exp/norm/tables.go @@ -8,10 +8,11 @@ package norm const Version = "6.0.0" const ( - firstCCC = 0x2E45 - firstLeadingCCC = 0x4965 - lastDecomp = 0x49A2 - maxDecomp = 0x8000 + firstCCC = 0x2E45 + firstLeadingCCC = 0x4965 + firstCCCZeroExcept = 0x497B + lastDecomp = 0x49A2 + maxDecomp = 0x8000 ) // decomps: 18850 bytes @@ -2660,10 +2661,10 @@ var decomps = [...]byte{ 0xCC, 0x94, 0xCC, 0x81, 0xE6, 0x86, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xE6, 0x42, 0xCC, 0x80, 0xE6, 0xE6, 0x42, 0xCC, 0x81, 0xE6, 0xE6, 0x42, - 0xCC, 0x93, 0xE6, 0xE6, 0x43, 0xE3, 0x82, 0x99, - 0x08, 0x08, 0x43, 0xE3, 0x82, 0x9A, 0x08, 0x08, + 0xCC, 0x93, 0xE6, 0xE6, 0x44, 0xCC, 0x88, 0xCC, + 0x81, 0xE6, 0xE6, 0x43, 0xE3, 0x82, 0x99, 0x08, // Bytes 4980 - 49bf - 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xE6, 0xE6, 0x46, + 0x08, 0x43, 0xE3, 0x82, 0x9A, 0x08, 0x08, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0x82, 0x81, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0x84, 0x81, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, @@ -2756,7 +2757,7 @@ var nfcValues = [2944]uint16{ 0x0236: 0x8001, 0x0237: 0x8001, 0x0238: 0x8601, 0x0239: 0x80dc, 0x023a: 0x80dc, 0x023b: 0x80dc, 0x023c: 0x80dc, 0x023d: 0x80e6, 0x023e: 0x80e6, 0x023f: 0x80e6, // Block 0x9, offset 0x240 - 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4980, 0x0245: 0x86f0, + 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4974, 0x0245: 0x86f0, 0x0246: 0x80e6, 0x0247: 0x80dc, 0x0248: 0x80dc, 0x0249: 0x80dc, 0x024a: 0x80e6, 0x024b: 0x80e6, 0x024c: 0x80e6, 0x024d: 0x80dc, 0x024e: 0x80dc, 0x0250: 0x80e6, 0x0251: 0x80e6, 0x0252: 0x80e6, 0x0253: 0x80dc, 0x0254: 0x80dc, 0x0255: 0x80dc, 0x0256: 0x80dc, 0x0257: 0x80e6, @@ -3745,75 +3746,75 @@ var nfcLookup = [1088]uint8{ // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x0c2: 0x2e, 0x0c3: 0x03, 0x0c4: 0x04, 0x0c5: 0x05, 0x0c6: 0x2f, 0x0c7: 0x06, - 0x0c8: 0x07, 0x0ca: 0x30, 0x0cc: 0x08, 0x0cd: 0x09, 0x0ce: 0x0a, 0x0cf: 0x31, - 0x0d0: 0x0b, 0x0d1: 0x32, 0x0d2: 0x33, 0x0d3: 0x0c, 0x0d6: 0x0d, 0x0d7: 0x34, - 0x0d8: 0x35, 0x0d9: 0x0e, 0x0db: 0x36, 0x0dc: 0x37, 0x0dd: 0x38, 0x0df: 0x39, - 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, - 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, - 0x0f0: 0x10, + 0x0c2: 0x2c, 0x0c3: 0x01, 0x0c4: 0x02, 0x0c5: 0x03, 0x0c6: 0x2d, 0x0c7: 0x04, + 0x0c8: 0x05, 0x0ca: 0x2e, 0x0cc: 0x06, 0x0cd: 0x07, 0x0ce: 0x08, 0x0cf: 0x2f, + 0x0d0: 0x09, 0x0d1: 0x30, 0x0d2: 0x31, 0x0d3: 0x0a, 0x0d6: 0x0b, 0x0d7: 0x32, + 0x0d8: 0x33, 0x0d9: 0x0c, 0x0db: 0x34, 0x0dc: 0x35, 0x0dd: 0x36, 0x0df: 0x37, + 0x0e0: 0x02, 0x0e1: 0x03, 0x0e2: 0x04, 0x0e3: 0x05, + 0x0ea: 0x06, 0x0eb: 0x07, 0x0ec: 0x07, 0x0ed: 0x08, 0x0ef: 0x09, + 0x0f0: 0x0e, // Block 0x4, offset 0x100 - 0x120: 0x3a, 0x121: 0x3b, 0x124: 0x3c, 0x125: 0x3d, 0x126: 0x3e, 0x127: 0x3f, - 0x128: 0x40, 0x129: 0x41, 0x12a: 0x42, 0x12b: 0x43, 0x12c: 0x3e, 0x12d: 0x44, 0x12e: 0x45, 0x12f: 0x46, - 0x131: 0x47, 0x132: 0x48, 0x133: 0x49, 0x134: 0x4a, 0x135: 0x4b, 0x137: 0x4c, - 0x138: 0x4d, 0x139: 0x4e, 0x13a: 0x4f, 0x13b: 0x50, 0x13c: 0x51, 0x13d: 0x52, 0x13e: 0x53, 0x13f: 0x54, + 0x120: 0x38, 0x121: 0x39, 0x124: 0x3a, 0x125: 0x3b, 0x126: 0x3c, 0x127: 0x3d, + 0x128: 0x3e, 0x129: 0x3f, 0x12a: 0x40, 0x12b: 0x41, 0x12c: 0x3c, 0x12d: 0x42, 0x12e: 0x43, 0x12f: 0x44, + 0x131: 0x45, 0x132: 0x46, 0x133: 0x47, 0x134: 0x48, 0x135: 0x49, 0x137: 0x4a, + 0x138: 0x4b, 0x139: 0x4c, 0x13a: 0x4d, 0x13b: 0x4e, 0x13c: 0x4f, 0x13d: 0x50, 0x13e: 0x51, 0x13f: 0x52, // Block 0x5, offset 0x140 - 0x140: 0x55, 0x142: 0x56, 0x144: 0x57, 0x145: 0x58, 0x146: 0x59, 0x147: 0x5a, - 0x14d: 0x5b, - 0x15c: 0x5c, 0x15f: 0x5d, - 0x162: 0x5e, 0x164: 0x5f, - 0x168: 0x60, 0x169: 0x61, 0x16c: 0x0f, 0x16d: 0x62, 0x16e: 0x63, 0x16f: 0x64, - 0x170: 0x65, 0x173: 0x66, 0x177: 0x67, - 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17, + 0x140: 0x53, 0x142: 0x54, 0x144: 0x55, 0x145: 0x56, 0x146: 0x57, 0x147: 0x58, + 0x14d: 0x59, + 0x15c: 0x5a, 0x15f: 0x5b, + 0x162: 0x5c, 0x164: 0x5d, + 0x168: 0x5e, 0x169: 0x5f, 0x16c: 0x0d, 0x16d: 0x60, 0x16e: 0x61, 0x16f: 0x62, + 0x170: 0x63, 0x173: 0x64, 0x177: 0x65, + 0x178: 0x0e, 0x179: 0x0f, 0x17a: 0x10, 0x17b: 0x11, 0x17c: 0x12, 0x17d: 0x13, 0x17e: 0x14, 0x17f: 0x15, // Block 0x6, offset 0x180 - 0x180: 0x68, 0x183: 0x69, 0x184: 0x6a, 0x186: 0x6b, 0x187: 0x6c, - 0x188: 0x6d, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x6e, 0x18c: 0x6f, - 0x1ab: 0x70, - 0x1b3: 0x71, 0x1b5: 0x72, 0x1b7: 0x73, + 0x180: 0x66, 0x183: 0x67, 0x184: 0x68, 0x186: 0x69, 0x187: 0x6a, + 0x188: 0x6b, 0x189: 0x16, 0x18a: 0x17, 0x18b: 0x6c, 0x18c: 0x6d, + 0x1ab: 0x6e, + 0x1b3: 0x6f, 0x1b5: 0x70, 0x1b7: 0x71, // Block 0x7, offset 0x1c0 - 0x1c0: 0x74, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, + 0x1c0: 0x72, 0x1c1: 0x18, 0x1c2: 0x19, 0x1c3: 0x1a, // Block 0x8, offset 0x200 - 0x219: 0x75, 0x21b: 0x76, - 0x220: 0x77, 0x223: 0x78, 0x224: 0x79, 0x225: 0x7a, 0x226: 0x7b, 0x227: 0x7c, - 0x22a: 0x7d, 0x22b: 0x7e, 0x22f: 0x7f, - 0x230: 0x80, 0x231: 0x80, 0x232: 0x80, 0x233: 0x80, 0x234: 0x80, 0x235: 0x80, 0x236: 0x80, 0x237: 0x80, - 0x238: 0x80, 0x239: 0x80, 0x23a: 0x80, 0x23b: 0x80, 0x23c: 0x80, 0x23d: 0x80, 0x23e: 0x80, 0x23f: 0x80, + 0x219: 0x73, 0x21b: 0x74, + 0x220: 0x75, 0x223: 0x76, 0x224: 0x77, 0x225: 0x78, 0x226: 0x79, 0x227: 0x7a, + 0x22a: 0x7b, 0x22b: 0x7c, 0x22f: 0x7d, + 0x230: 0x7e, 0x231: 0x7e, 0x232: 0x7e, 0x233: 0x7e, 0x234: 0x7e, 0x235: 0x7e, 0x236: 0x7e, 0x237: 0x7e, + 0x238: 0x7e, 0x239: 0x7e, 0x23a: 0x7e, 0x23b: 0x7e, 0x23c: 0x7e, 0x23d: 0x7e, 0x23e: 0x7e, 0x23f: 0x7e, // Block 0x9, offset 0x240 - 0x240: 0x80, 0x241: 0x80, 0x242: 0x80, 0x243: 0x80, 0x244: 0x80, 0x245: 0x80, 0x246: 0x80, 0x247: 0x80, - 0x248: 0x80, 0x249: 0x80, 0x24a: 0x80, 0x24b: 0x80, 0x24c: 0x80, 0x24d: 0x80, 0x24e: 0x80, 0x24f: 0x80, - 0x250: 0x80, 0x251: 0x80, 0x252: 0x80, 0x253: 0x80, 0x254: 0x80, 0x255: 0x80, 0x256: 0x80, 0x257: 0x80, - 0x258: 0x80, 0x259: 0x80, 0x25a: 0x80, 0x25b: 0x80, 0x25c: 0x80, 0x25d: 0x80, 0x25e: 0x80, 0x25f: 0x80, - 0x260: 0x80, 0x261: 0x80, 0x262: 0x80, 0x263: 0x80, 0x264: 0x80, 0x265: 0x80, 0x266: 0x80, 0x267: 0x80, - 0x268: 0x80, 0x269: 0x80, 0x26a: 0x80, 0x26b: 0x80, 0x26c: 0x80, 0x26d: 0x80, 0x26e: 0x80, 0x26f: 0x80, - 0x270: 0x80, 0x271: 0x80, 0x272: 0x80, 0x273: 0x80, 0x274: 0x80, 0x275: 0x80, 0x276: 0x80, 0x277: 0x80, - 0x278: 0x80, 0x279: 0x80, 0x27a: 0x80, 0x27b: 0x80, 0x27c: 0x80, 0x27d: 0x80, 0x27e: 0x80, 0x27f: 0x80, + 0x240: 0x7e, 0x241: 0x7e, 0x242: 0x7e, 0x243: 0x7e, 0x244: 0x7e, 0x245: 0x7e, 0x246: 0x7e, 0x247: 0x7e, + 0x248: 0x7e, 0x249: 0x7e, 0x24a: 0x7e, 0x24b: 0x7e, 0x24c: 0x7e, 0x24d: 0x7e, 0x24e: 0x7e, 0x24f: 0x7e, + 0x250: 0x7e, 0x251: 0x7e, 0x252: 0x7e, 0x253: 0x7e, 0x254: 0x7e, 0x255: 0x7e, 0x256: 0x7e, 0x257: 0x7e, + 0x258: 0x7e, 0x259: 0x7e, 0x25a: 0x7e, 0x25b: 0x7e, 0x25c: 0x7e, 0x25d: 0x7e, 0x25e: 0x7e, 0x25f: 0x7e, + 0x260: 0x7e, 0x261: 0x7e, 0x262: 0x7e, 0x263: 0x7e, 0x264: 0x7e, 0x265: 0x7e, 0x266: 0x7e, 0x267: 0x7e, + 0x268: 0x7e, 0x269: 0x7e, 0x26a: 0x7e, 0x26b: 0x7e, 0x26c: 0x7e, 0x26d: 0x7e, 0x26e: 0x7e, 0x26f: 0x7e, + 0x270: 0x7e, 0x271: 0x7e, 0x272: 0x7e, 0x273: 0x7e, 0x274: 0x7e, 0x275: 0x7e, 0x276: 0x7e, 0x277: 0x7e, + 0x278: 0x7e, 0x279: 0x7e, 0x27a: 0x7e, 0x27b: 0x7e, 0x27c: 0x7e, 0x27d: 0x7e, 0x27e: 0x7e, 0x27f: 0x7e, // Block 0xa, offset 0x280 - 0x280: 0x80, 0x281: 0x80, 0x282: 0x80, 0x283: 0x80, 0x284: 0x80, 0x285: 0x80, 0x286: 0x80, 0x287: 0x80, - 0x288: 0x80, 0x289: 0x80, 0x28a: 0x80, 0x28b: 0x80, 0x28c: 0x80, 0x28d: 0x80, 0x28e: 0x80, 0x28f: 0x80, - 0x290: 0x80, 0x291: 0x80, 0x292: 0x80, 0x293: 0x80, 0x294: 0x80, 0x295: 0x80, 0x296: 0x80, 0x297: 0x80, - 0x298: 0x80, 0x299: 0x80, 0x29a: 0x80, 0x29b: 0x80, 0x29c: 0x80, 0x29d: 0x80, 0x29e: 0x81, + 0x280: 0x7e, 0x281: 0x7e, 0x282: 0x7e, 0x283: 0x7e, 0x284: 0x7e, 0x285: 0x7e, 0x286: 0x7e, 0x287: 0x7e, + 0x288: 0x7e, 0x289: 0x7e, 0x28a: 0x7e, 0x28b: 0x7e, 0x28c: 0x7e, 0x28d: 0x7e, 0x28e: 0x7e, 0x28f: 0x7e, + 0x290: 0x7e, 0x291: 0x7e, 0x292: 0x7e, 0x293: 0x7e, 0x294: 0x7e, 0x295: 0x7e, 0x296: 0x7e, 0x297: 0x7e, + 0x298: 0x7e, 0x299: 0x7e, 0x29a: 0x7e, 0x29b: 0x7e, 0x29c: 0x7e, 0x29d: 0x7e, 0x29e: 0x7f, // Block 0xb, offset 0x2c0 - 0x2e4: 0x1d, 0x2e5: 0x1e, 0x2e6: 0x1f, 0x2e7: 0x20, - 0x2e8: 0x21, 0x2e9: 0x22, 0x2ea: 0x23, 0x2eb: 0x24, 0x2ec: 0x82, 0x2ed: 0x83, - 0x2f8: 0x84, + 0x2e4: 0x1b, 0x2e5: 0x1c, 0x2e6: 0x1d, 0x2e7: 0x1e, + 0x2e8: 0x1f, 0x2e9: 0x20, 0x2ea: 0x21, 0x2eb: 0x22, 0x2ec: 0x80, 0x2ed: 0x81, + 0x2f8: 0x82, // Block 0xc, offset 0x300 - 0x307: 0x85, - 0x328: 0x86, + 0x307: 0x83, + 0x328: 0x84, // Block 0xd, offset 0x340 - 0x341: 0x77, 0x342: 0x87, + 0x341: 0x75, 0x342: 0x85, // Block 0xe, offset 0x380 - 0x385: 0x88, 0x386: 0x89, 0x387: 0x8a, - 0x389: 0x8b, + 0x385: 0x86, 0x386: 0x87, 0x387: 0x88, + 0x389: 0x89, // Block 0xf, offset 0x3c0 - 0x3e0: 0x25, 0x3e1: 0x26, 0x3e2: 0x27, 0x3e3: 0x28, 0x3e4: 0x29, 0x3e5: 0x2a, 0x3e6: 0x2b, 0x3e7: 0x2c, - 0x3e8: 0x2d, + 0x3e0: 0x23, 0x3e1: 0x24, 0x3e2: 0x25, 0x3e3: 0x26, 0x3e4: 0x27, 0x3e5: 0x28, 0x3e6: 0x29, 0x3e7: 0x2a, + 0x3e8: 0x2b, // Block 0x10, offset 0x400 - 0x410: 0x0c, 0x411: 0x0d, - 0x41d: 0x0e, - 0x42f: 0x0f, + 0x410: 0x0a, 0x411: 0x0b, + 0x41d: 0x0c, + 0x42f: 0x0d, } -var nfcTrie = trie{nfcLookup[:], nfcValues[:], nfcSparseValues[:], nfcSparseOffset[:], 46} +var nfcTrie = trie{nfcLookup[:], nfcValues[:], nfcSparseValues[:], nfcSparseOffset[:], 44} // nfkcValues: 5568 entries, 11136 bytes // Block 2 is the null block. @@ -3903,7 +3904,7 @@ var nfkcValues = [5568]uint16{ 0x0236: 0x8001, 0x0237: 0x8001, 0x0238: 0x8601, 0x0239: 0x80dc, 0x023a: 0x80dc, 0x023b: 0x80dc, 0x023c: 0x80dc, 0x023d: 0x80e6, 0x023e: 0x80e6, 0x023f: 0x80e6, // Block 0x9, offset 0x240 - 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4980, 0x0245: 0x86f0, + 0x0240: 0x4965, 0x0241: 0x496a, 0x0242: 0x86e6, 0x0243: 0x496f, 0x0244: 0x4974, 0x0245: 0x86f0, 0x0246: 0x80e6, 0x0247: 0x80dc, 0x0248: 0x80dc, 0x0249: 0x80dc, 0x024a: 0x80e6, 0x024b: 0x80e6, 0x024c: 0x80e6, 0x024d: 0x80dc, 0x024e: 0x80dc, 0x0250: 0x80e6, 0x0251: 0x80e6, 0x0252: 0x80e6, 0x0253: 0x80dc, 0x0254: 0x80dc, 0x0255: 0x80dc, 0x0256: 0x80dc, 0x0257: 0x80e6, @@ -4609,7 +4610,7 @@ var nfkcValues = [5568]uint16{ 0x124c: 0x0a89, 0x124d: 0x0a8d, 0x124e: 0x0a91, 0x124f: 0x0a95, 0x1250: 0x0a99, 0x1251: 0x0a9d, 0x1252: 0x0aa1, 0x1253: 0x0aa5, 0x1254: 0x0aad, 0x1255: 0x0ab5, 0x1256: 0x0abd, 0x1257: 0x0ac1, 0x1258: 0x0ac5, 0x1259: 0x0ac9, 0x125a: 0x0acd, 0x125b: 0x0ad1, 0x125c: 0x0ad5, 0x125d: 0x0ae5, - 0x125e: 0x4974, 0x125f: 0x497a, 0x1260: 0x0889, 0x1261: 0x07d9, 0x1262: 0x07dd, 0x1263: 0x0901, + 0x125e: 0x497b, 0x125f: 0x4981, 0x1260: 0x0889, 0x1261: 0x07d9, 0x1262: 0x07dd, 0x1263: 0x0901, 0x1264: 0x07e1, 0x1265: 0x0905, 0x1266: 0x0909, 0x1267: 0x07e5, 0x1268: 0x07e9, 0x1269: 0x07ed, 0x126a: 0x090d, 0x126b: 0x0911, 0x126c: 0x0915, 0x126d: 0x0919, 0x126e: 0x091d, 0x126f: 0x0921, 0x1270: 0x082d, 0x1271: 0x07f1, 0x1272: 0x07f5, 0x1273: 0x07f9, 0x1274: 0x0841, 0x1275: 0x07fd, @@ -5641,84 +5642,84 @@ var nfkcLookup = [1152]uint8{ // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x0c2: 0x57, 0x0c3: 0x03, 0x0c4: 0x04, 0x0c5: 0x05, 0x0c6: 0x58, 0x0c7: 0x06, - 0x0c8: 0x07, 0x0ca: 0x59, 0x0cb: 0x5a, 0x0cc: 0x08, 0x0cd: 0x09, 0x0ce: 0x0a, 0x0cf: 0x0b, - 0x0d0: 0x0c, 0x0d1: 0x5b, 0x0d2: 0x5c, 0x0d3: 0x0d, 0x0d6: 0x0e, 0x0d7: 0x5d, - 0x0d8: 0x5e, 0x0d9: 0x0f, 0x0db: 0x5f, 0x0dc: 0x60, 0x0dd: 0x61, 0x0df: 0x62, - 0x0e0: 0x04, 0x0e1: 0x05, 0x0e2: 0x06, 0x0e3: 0x07, - 0x0ea: 0x08, 0x0eb: 0x09, 0x0ec: 0x09, 0x0ed: 0x0a, 0x0ef: 0x0b, - 0x0f0: 0x11, + 0x0c2: 0x55, 0x0c3: 0x01, 0x0c4: 0x02, 0x0c5: 0x03, 0x0c6: 0x56, 0x0c7: 0x04, + 0x0c8: 0x05, 0x0ca: 0x57, 0x0cb: 0x58, 0x0cc: 0x06, 0x0cd: 0x07, 0x0ce: 0x08, 0x0cf: 0x09, + 0x0d0: 0x0a, 0x0d1: 0x59, 0x0d2: 0x5a, 0x0d3: 0x0b, 0x0d6: 0x0c, 0x0d7: 0x5b, + 0x0d8: 0x5c, 0x0d9: 0x0d, 0x0db: 0x5d, 0x0dc: 0x5e, 0x0dd: 0x5f, 0x0df: 0x60, + 0x0e0: 0x02, 0x0e1: 0x03, 0x0e2: 0x04, 0x0e3: 0x05, + 0x0ea: 0x06, 0x0eb: 0x07, 0x0ec: 0x07, 0x0ed: 0x08, 0x0ef: 0x09, + 0x0f0: 0x0f, // Block 0x4, offset 0x100 - 0x120: 0x63, 0x121: 0x64, 0x124: 0x65, 0x125: 0x66, 0x126: 0x67, 0x127: 0x68, - 0x128: 0x69, 0x129: 0x6a, 0x12a: 0x6b, 0x12b: 0x6c, 0x12c: 0x67, 0x12d: 0x6d, 0x12e: 0x6e, 0x12f: 0x6f, - 0x131: 0x70, 0x132: 0x71, 0x133: 0x72, 0x134: 0x73, 0x135: 0x74, 0x137: 0x75, - 0x138: 0x76, 0x139: 0x77, 0x13a: 0x78, 0x13b: 0x79, 0x13c: 0x7a, 0x13d: 0x7b, 0x13e: 0x7c, 0x13f: 0x7d, + 0x120: 0x61, 0x121: 0x62, 0x124: 0x63, 0x125: 0x64, 0x126: 0x65, 0x127: 0x66, + 0x128: 0x67, 0x129: 0x68, 0x12a: 0x69, 0x12b: 0x6a, 0x12c: 0x65, 0x12d: 0x6b, 0x12e: 0x6c, 0x12f: 0x6d, + 0x131: 0x6e, 0x132: 0x6f, 0x133: 0x70, 0x134: 0x71, 0x135: 0x72, 0x137: 0x73, + 0x138: 0x74, 0x139: 0x75, 0x13a: 0x76, 0x13b: 0x77, 0x13c: 0x78, 0x13d: 0x79, 0x13e: 0x7a, 0x13f: 0x7b, // Block 0x5, offset 0x140 - 0x140: 0x7e, 0x142: 0x7f, 0x143: 0x80, 0x144: 0x81, 0x145: 0x82, 0x146: 0x83, 0x147: 0x84, - 0x14d: 0x85, - 0x15c: 0x86, 0x15f: 0x87, - 0x162: 0x88, 0x164: 0x89, - 0x168: 0x8a, 0x169: 0x8b, 0x16c: 0x10, 0x16d: 0x8c, 0x16e: 0x8d, 0x16f: 0x8e, - 0x170: 0x8f, 0x173: 0x90, 0x174: 0x91, 0x175: 0x11, 0x176: 0x12, 0x177: 0x92, - 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a, + 0x140: 0x7c, 0x142: 0x7d, 0x143: 0x7e, 0x144: 0x7f, 0x145: 0x80, 0x146: 0x81, 0x147: 0x82, + 0x14d: 0x83, + 0x15c: 0x84, 0x15f: 0x85, + 0x162: 0x86, 0x164: 0x87, + 0x168: 0x88, 0x169: 0x89, 0x16c: 0x0e, 0x16d: 0x8a, 0x16e: 0x8b, 0x16f: 0x8c, + 0x170: 0x8d, 0x173: 0x8e, 0x174: 0x8f, 0x175: 0x0f, 0x176: 0x10, 0x177: 0x90, + 0x178: 0x11, 0x179: 0x12, 0x17a: 0x13, 0x17b: 0x14, 0x17c: 0x15, 0x17d: 0x16, 0x17e: 0x17, 0x17f: 0x18, // Block 0x6, offset 0x180 - 0x180: 0x93, 0x181: 0x94, 0x182: 0x95, 0x183: 0x96, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x97, 0x187: 0x98, - 0x188: 0x99, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0x9a, 0x18c: 0x9b, - 0x191: 0x1f, 0x192: 0x20, 0x193: 0x9c, - 0x1a8: 0x9d, 0x1a9: 0x9e, 0x1ab: 0x9f, - 0x1b1: 0xa0, 0x1b3: 0xa1, 0x1b5: 0xa2, 0x1b7: 0xa3, - 0x1ba: 0xa4, 0x1bb: 0xa5, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xa6, + 0x180: 0x91, 0x181: 0x92, 0x182: 0x93, 0x183: 0x94, 0x184: 0x19, 0x185: 0x1a, 0x186: 0x95, 0x187: 0x96, + 0x188: 0x97, 0x189: 0x1b, 0x18a: 0x1c, 0x18b: 0x98, 0x18c: 0x99, + 0x191: 0x1d, 0x192: 0x1e, 0x193: 0x9a, + 0x1a8: 0x9b, 0x1a9: 0x9c, 0x1ab: 0x9d, + 0x1b1: 0x9e, 0x1b3: 0x9f, 0x1b5: 0xa0, 0x1b7: 0xa1, + 0x1ba: 0xa2, 0x1bb: 0xa3, 0x1bc: 0x1f, 0x1bd: 0x20, 0x1be: 0x21, 0x1bf: 0xa4, // Block 0x7, offset 0x1c0 - 0x1c0: 0xa7, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xa8, 0x1c5: 0xa9, 0x1c6: 0x27, - 0x1c8: 0x28, 0x1c9: 0x29, 0x1ca: 0x2a, 0x1cb: 0x2b, 0x1cc: 0x2c, 0x1cd: 0x2d, 0x1ce: 0x2e, 0x1cf: 0x2f, + 0x1c0: 0xa5, 0x1c1: 0x22, 0x1c2: 0x23, 0x1c3: 0x24, 0x1c4: 0xa6, 0x1c5: 0xa7, 0x1c6: 0x25, + 0x1c8: 0x26, 0x1c9: 0x27, 0x1ca: 0x28, 0x1cb: 0x29, 0x1cc: 0x2a, 0x1cd: 0x2b, 0x1ce: 0x2c, 0x1cf: 0x2d, // Block 0x8, offset 0x200 - 0x219: 0xaa, 0x21b: 0xab, 0x21d: 0xac, - 0x220: 0xad, 0x223: 0xae, 0x224: 0xaf, 0x225: 0xb0, 0x226: 0xb1, 0x227: 0xb2, - 0x22a: 0xb3, 0x22b: 0xb4, 0x22f: 0xb5, - 0x230: 0xb6, 0x231: 0xb6, 0x232: 0xb6, 0x233: 0xb6, 0x234: 0xb6, 0x235: 0xb6, 0x236: 0xb6, 0x237: 0xb6, - 0x238: 0xb6, 0x239: 0xb6, 0x23a: 0xb6, 0x23b: 0xb6, 0x23c: 0xb6, 0x23d: 0xb6, 0x23e: 0xb6, 0x23f: 0xb6, + 0x219: 0xa8, 0x21b: 0xa9, 0x21d: 0xaa, + 0x220: 0xab, 0x223: 0xac, 0x224: 0xad, 0x225: 0xae, 0x226: 0xaf, 0x227: 0xb0, + 0x22a: 0xb1, 0x22b: 0xb2, 0x22f: 0xb3, + 0x230: 0xb4, 0x231: 0xb4, 0x232: 0xb4, 0x233: 0xb4, 0x234: 0xb4, 0x235: 0xb4, 0x236: 0xb4, 0x237: 0xb4, + 0x238: 0xb4, 0x239: 0xb4, 0x23a: 0xb4, 0x23b: 0xb4, 0x23c: 0xb4, 0x23d: 0xb4, 0x23e: 0xb4, 0x23f: 0xb4, // Block 0x9, offset 0x240 - 0x240: 0xb6, 0x241: 0xb6, 0x242: 0xb6, 0x243: 0xb6, 0x244: 0xb6, 0x245: 0xb6, 0x246: 0xb6, 0x247: 0xb6, - 0x248: 0xb6, 0x249: 0xb6, 0x24a: 0xb6, 0x24b: 0xb6, 0x24c: 0xb6, 0x24d: 0xb6, 0x24e: 0xb6, 0x24f: 0xb6, - 0x250: 0xb6, 0x251: 0xb6, 0x252: 0xb6, 0x253: 0xb6, 0x254: 0xb6, 0x255: 0xb6, 0x256: 0xb6, 0x257: 0xb6, - 0x258: 0xb6, 0x259: 0xb6, 0x25a: 0xb6, 0x25b: 0xb6, 0x25c: 0xb6, 0x25d: 0xb6, 0x25e: 0xb6, 0x25f: 0xb6, - 0x260: 0xb6, 0x261: 0xb6, 0x262: 0xb6, 0x263: 0xb6, 0x264: 0xb6, 0x265: 0xb6, 0x266: 0xb6, 0x267: 0xb6, - 0x268: 0xb6, 0x269: 0xb6, 0x26a: 0xb6, 0x26b: 0xb6, 0x26c: 0xb6, 0x26d: 0xb6, 0x26e: 0xb6, 0x26f: 0xb6, - 0x270: 0xb6, 0x271: 0xb6, 0x272: 0xb6, 0x273: 0xb6, 0x274: 0xb6, 0x275: 0xb6, 0x276: 0xb6, 0x277: 0xb6, - 0x278: 0xb6, 0x279: 0xb6, 0x27a: 0xb6, 0x27b: 0xb6, 0x27c: 0xb6, 0x27d: 0xb6, 0x27e: 0xb6, 0x27f: 0xb6, + 0x240: 0xb4, 0x241: 0xb4, 0x242: 0xb4, 0x243: 0xb4, 0x244: 0xb4, 0x245: 0xb4, 0x246: 0xb4, 0x247: 0xb4, + 0x248: 0xb4, 0x249: 0xb4, 0x24a: 0xb4, 0x24b: 0xb4, 0x24c: 0xb4, 0x24d: 0xb4, 0x24e: 0xb4, 0x24f: 0xb4, + 0x250: 0xb4, 0x251: 0xb4, 0x252: 0xb4, 0x253: 0xb4, 0x254: 0xb4, 0x255: 0xb4, 0x256: 0xb4, 0x257: 0xb4, + 0x258: 0xb4, 0x259: 0xb4, 0x25a: 0xb4, 0x25b: 0xb4, 0x25c: 0xb4, 0x25d: 0xb4, 0x25e: 0xb4, 0x25f: 0xb4, + 0x260: 0xb4, 0x261: 0xb4, 0x262: 0xb4, 0x263: 0xb4, 0x264: 0xb4, 0x265: 0xb4, 0x266: 0xb4, 0x267: 0xb4, + 0x268: 0xb4, 0x269: 0xb4, 0x26a: 0xb4, 0x26b: 0xb4, 0x26c: 0xb4, 0x26d: 0xb4, 0x26e: 0xb4, 0x26f: 0xb4, + 0x270: 0xb4, 0x271: 0xb4, 0x272: 0xb4, 0x273: 0xb4, 0x274: 0xb4, 0x275: 0xb4, 0x276: 0xb4, 0x277: 0xb4, + 0x278: 0xb4, 0x279: 0xb4, 0x27a: 0xb4, 0x27b: 0xb4, 0x27c: 0xb4, 0x27d: 0xb4, 0x27e: 0xb4, 0x27f: 0xb4, // Block 0xa, offset 0x280 - 0x280: 0xb6, 0x281: 0xb6, 0x282: 0xb6, 0x283: 0xb6, 0x284: 0xb6, 0x285: 0xb6, 0x286: 0xb6, 0x287: 0xb6, - 0x288: 0xb6, 0x289: 0xb6, 0x28a: 0xb6, 0x28b: 0xb6, 0x28c: 0xb6, 0x28d: 0xb6, 0x28e: 0xb6, 0x28f: 0xb6, - 0x290: 0xb6, 0x291: 0xb6, 0x292: 0xb6, 0x293: 0xb6, 0x294: 0xb6, 0x295: 0xb6, 0x296: 0xb6, 0x297: 0xb6, - 0x298: 0xb6, 0x299: 0xb6, 0x29a: 0xb6, 0x29b: 0xb6, 0x29c: 0xb6, 0x29d: 0xb6, 0x29e: 0xb7, + 0x280: 0xb4, 0x281: 0xb4, 0x282: 0xb4, 0x283: 0xb4, 0x284: 0xb4, 0x285: 0xb4, 0x286: 0xb4, 0x287: 0xb4, + 0x288: 0xb4, 0x289: 0xb4, 0x28a: 0xb4, 0x28b: 0xb4, 0x28c: 0xb4, 0x28d: 0xb4, 0x28e: 0xb4, 0x28f: 0xb4, + 0x290: 0xb4, 0x291: 0xb4, 0x292: 0xb4, 0x293: 0xb4, 0x294: 0xb4, 0x295: 0xb4, 0x296: 0xb4, 0x297: 0xb4, + 0x298: 0xb4, 0x299: 0xb4, 0x29a: 0xb4, 0x29b: 0xb4, 0x29c: 0xb4, 0x29d: 0xb4, 0x29e: 0xb5, // Block 0xb, offset 0x2c0 - 0x2e4: 0x30, 0x2e5: 0x31, 0x2e6: 0x32, 0x2e7: 0x33, - 0x2e8: 0x34, 0x2e9: 0x35, 0x2ea: 0x36, 0x2eb: 0x37, 0x2ec: 0x38, 0x2ed: 0x39, 0x2ee: 0x3a, 0x2ef: 0x3b, - 0x2f0: 0x3c, 0x2f1: 0x3d, 0x2f2: 0x3e, 0x2f3: 0x3f, 0x2f4: 0x40, 0x2f5: 0x41, 0x2f6: 0x42, 0x2f7: 0x43, - 0x2f8: 0x44, 0x2f9: 0x45, 0x2fa: 0x46, 0x2fb: 0x47, 0x2fc: 0xb8, 0x2fd: 0x48, 0x2fe: 0x49, 0x2ff: 0xb9, + 0x2e4: 0x2e, 0x2e5: 0x2f, 0x2e6: 0x30, 0x2e7: 0x31, + 0x2e8: 0x32, 0x2e9: 0x33, 0x2ea: 0x34, 0x2eb: 0x35, 0x2ec: 0x36, 0x2ed: 0x37, 0x2ee: 0x38, 0x2ef: 0x39, + 0x2f0: 0x3a, 0x2f1: 0x3b, 0x2f2: 0x3c, 0x2f3: 0x3d, 0x2f4: 0x3e, 0x2f5: 0x3f, 0x2f6: 0x40, 0x2f7: 0x41, + 0x2f8: 0x42, 0x2f9: 0x43, 0x2fa: 0x44, 0x2fb: 0x45, 0x2fc: 0xb6, 0x2fd: 0x46, 0x2fe: 0x47, 0x2ff: 0xb7, // Block 0xc, offset 0x300 - 0x307: 0xba, - 0x328: 0xbb, + 0x307: 0xb8, + 0x328: 0xb9, // Block 0xd, offset 0x340 - 0x341: 0xad, 0x342: 0xbc, + 0x341: 0xab, 0x342: 0xba, // Block 0xe, offset 0x380 - 0x385: 0xbd, 0x386: 0xbe, 0x387: 0xbf, - 0x389: 0xc0, - 0x390: 0xc1, 0x391: 0xc2, 0x392: 0xc3, 0x393: 0xc4, 0x394: 0xc5, 0x395: 0xc6, 0x396: 0xc7, 0x397: 0xc8, - 0x398: 0xc9, 0x399: 0xca, 0x39a: 0x4a, 0x39b: 0xcb, 0x39c: 0xcc, 0x39d: 0xcd, 0x39e: 0xce, 0x39f: 0x4b, + 0x385: 0xbb, 0x386: 0xbc, 0x387: 0xbd, + 0x389: 0xbe, + 0x390: 0xbf, 0x391: 0xc0, 0x392: 0xc1, 0x393: 0xc2, 0x394: 0xc3, 0x395: 0xc4, 0x396: 0xc5, 0x397: 0xc6, + 0x398: 0xc7, 0x399: 0xc8, 0x39a: 0x48, 0x39b: 0xc9, 0x39c: 0xca, 0x39d: 0xcb, 0x39e: 0xcc, 0x39f: 0x49, // Block 0xf, offset 0x3c0 - 0x3c4: 0x4c, 0x3c5: 0xcf, 0x3c6: 0xd0, - 0x3c8: 0x4d, 0x3c9: 0xd1, + 0x3c4: 0x4a, 0x3c5: 0xcd, 0x3c6: 0xce, + 0x3c8: 0x4b, 0x3c9: 0xcf, // Block 0x10, offset 0x400 - 0x420: 0x4e, 0x421: 0x4f, 0x422: 0x50, 0x423: 0x51, 0x424: 0x52, 0x425: 0x53, 0x426: 0x54, 0x427: 0x55, - 0x428: 0x56, + 0x420: 0x4c, 0x421: 0x4d, 0x422: 0x4e, 0x423: 0x4f, 0x424: 0x50, 0x425: 0x51, 0x426: 0x52, 0x427: 0x53, + 0x428: 0x54, // Block 0x11, offset 0x440 - 0x450: 0x0c, 0x451: 0x0d, - 0x45d: 0x0e, 0x45f: 0x0f, - 0x46f: 0x10, + 0x450: 0x0a, 0x451: 0x0b, + 0x45d: 0x0c, 0x45f: 0x0d, + 0x46f: 0x0e, } -var nfkcTrie = trie{nfkcLookup[:], nfkcValues[:], nfkcSparseValues[:], nfkcSparseOffset[:], 87} +var nfkcTrie = trie{nfkcLookup[:], nfkcValues[:], nfkcSparseValues[:], nfkcSparseOffset[:], 85} // recompMap: 7448 bytes (entries only) var recompMap = map[uint32]rune{ diff --git a/libgo/go/exp/norm/trie.go b/libgo/go/exp/norm/trie.go index 93cb9c3..82267a8 100644 --- a/libgo/go/exp/norm/trie.go +++ b/libgo/go/exp/norm/trie.go @@ -23,7 +23,7 @@ type trie struct { // the value for b is by r.value + (b - r.lo) * stride. func (t *trie) lookupValue(n uint8, b byte) uint16 { if n < t.cutoff { - return t.values[uint16(n)<<6+uint16(b&maskx)] + return t.values[uint16(n)<<6+uint16(b)] } offset := t.sparseOffset[n-t.cutoff] header := t.sparse[offset] @@ -53,11 +53,6 @@ const ( t5 = 0xF8 // 1111 1000 t6 = 0xFC // 1111 1100 te = 0xFE // 1111 1110 - - maskx = 0x3F // 0011 1111 - mask2 = 0x1F // 0001 1111 - mask3 = 0x0F // 0000 1111 - mask4 = 0x07 // 0000 0111 ) // lookup returns the trie value for the first UTF-8 encoding in s and @@ -89,7 +84,7 @@ func (t *trie) lookup(s []byte) (v uint16, sz int) { if c1 < tx || t2 <= c1 { return 0, 1 } - o := uint16(i)<<6 + uint16(c1)&maskx + o := uint16(i)<<6 + uint16(c1) i = t.index[o] c2 := s[2] if c2 < tx || t2 <= c2 { @@ -105,13 +100,13 @@ func (t *trie) lookup(s []byte) (v uint16, sz int) { if c1 < tx || t2 <= c1 { return 0, 1 } - o := uint16(i)<<6 + uint16(c1)&maskx + o := uint16(i)<<6 + uint16(c1) i = t.index[o] c2 := s[2] if c2 < tx || t2 <= c2 { return 0, 2 } - o = uint16(i)<<6 + uint16(c2)&maskx + o = uint16(i)<<6 + uint16(c2) i = t.index[o] c3 := s[3] if c3 < tx || t2 <= c3 { @@ -152,7 +147,7 @@ func (t *trie) lookupString(s string) (v uint16, sz int) { if c1 < tx || t2 <= c1 { return 0, 1 } - o := uint16(i)<<6 + uint16(c1)&maskx + o := uint16(i)<<6 + uint16(c1) i = t.index[o] c2 := s[2] if c2 < tx || t2 <= c2 { @@ -168,13 +163,13 @@ func (t *trie) lookupString(s string) (v uint16, sz int) { if c1 < tx || t2 <= c1 { return 0, 1 } - o := uint16(i)<<6 + uint16(c1)&maskx + o := uint16(i)<<6 + uint16(c1) i = t.index[o] c2 := s[2] if c2 < tx || t2 <= c2 { return 0, 2 } - o = uint16(i)<<6 + uint16(c2)&maskx + o = uint16(i)<<6 + uint16(c2) i = t.index[o] c3 := s[3] if c3 < tx || t2 <= c3 { @@ -200,11 +195,11 @@ func (t *trie) lookupUnsafe(s []byte) uint16 { if c0 < t3 { return t.lookupValue(i, s[1]) } - i = t.index[uint16(i)<<6+uint16(s[1])&maskx] + i = t.index[uint16(i)<<6+uint16(s[1])] if c0 < t4 { return t.lookupValue(i, s[2]) } - i = t.index[uint16(i)<<6+uint16(s[2])&maskx] + i = t.index[uint16(i)<<6+uint16(s[2])] if c0 < t5 { return t.lookupValue(i, s[3]) } @@ -225,11 +220,11 @@ func (t *trie) lookupStringUnsafe(s string) uint16 { if c0 < t3 { return t.lookupValue(i, s[1]) } - i = t.index[uint16(i)<<6+uint16(s[1])&maskx] + i = t.index[uint16(i)<<6+uint16(s[1])] if c0 < t4 { return t.lookupValue(i, s[2]) } - i = t.index[uint16(i)<<6+uint16(s[2])&maskx] + i = t.index[uint16(i)<<6+uint16(s[2])] if c0 < t5 { return t.lookupValue(i, s[3]) } diff --git a/libgo/go/exp/norm/trie_test.go b/libgo/go/exp/norm/trie_test.go index c457c9d..1a75cc7 100644 --- a/libgo/go/exp/norm/trie_test.go +++ b/libgo/go/exp/norm/trie_test.go @@ -96,13 +96,17 @@ func TestLookup(t *testing.T) { } for i, tt := range tests { v, sz := testdata.lookup(tt.bytes) - if int(v) != 0 { + if v != 0 { t.Errorf("lookup of illegal rune, case %d: found value %#x, expected 0", i, v) } if sz != tt.size { t.Errorf("lookup of illegal rune, case %d: found size %d, expected %d", i, sz, tt.size) } } + // Verify defaults. + if v, _ := testdata.lookup([]byte{0xC1, 0x8C}); v != 0 { + t.Errorf("lookup of non-existing rune should be 0; found %X", v) + } } func TestLookupUnsafe(t *testing.T) { diff --git a/libgo/go/exp/norm/triedata_test.go b/libgo/go/exp/norm/triedata_test.go index 7f62760..d6c832d 100644 --- a/libgo/go/exp/norm/triedata_test.go +++ b/libgo/go/exp/norm/triedata_test.go @@ -4,7 +4,7 @@ package norm -var testRunes = []rune{1, 12, 127, 128, 256, 2047, 2048, 2457, 65535, 65536, 65793, 1114111, 512, 513, 514, 528, 533} +var testRunes = []int32{1, 12, 127, 128, 256, 2047, 2048, 2457, 65535, 65536, 65793, 1114111, 512, 513, 514, 528, 533} // testdataValues: 192 entries, 384 bytes // Block 2 is the null block. @@ -62,24 +62,24 @@ var testdataLookup = [640]uint8{ // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0x0c2: 0x03, 0x0c4: 0x04, - 0x0c8: 0x05, - 0x0df: 0x06, - 0x0e0: 0x04, - 0x0ef: 0x05, - 0x0f0: 0x07, 0x0f4: 0x09, + 0x0c2: 0x01, 0x0c4: 0x02, + 0x0c8: 0x03, + 0x0df: 0x04, + 0x0e0: 0x02, + 0x0ef: 0x03, + 0x0f0: 0x05, 0x0f4: 0x07, // Block 0x4, offset 0x100 - 0x120: 0x07, 0x126: 0x08, + 0x120: 0x05, 0x126: 0x06, // Block 0x5, offset 0x140 - 0x17f: 0x09, + 0x17f: 0x07, // Block 0x6, offset 0x180 - 0x180: 0x0a, 0x184: 0x0b, + 0x180: 0x08, 0x184: 0x09, // Block 0x7, offset 0x1c0 - 0x1d0: 0x06, + 0x1d0: 0x04, // Block 0x8, offset 0x200 - 0x23f: 0x0c, + 0x23f: 0x0a, // Block 0x9, offset 0x240 - 0x24f: 0x08, + 0x24f: 0x06, } -var testdataTrie = trie{testdataLookup[:], testdataValues[:], testdataSparseValues[:], testdataSparseOffset[:], 3} +var testdataTrie = trie{testdataLookup[:], testdataValues[:], testdataSparseValues[:], testdataSparseOffset[:], 1} diff --git a/libgo/go/exp/norm/triegen.go b/libgo/go/exp/norm/triegen.go index 2e275a0..1780ac7 100644 --- a/libgo/go/exp/norm/triegen.go +++ b/libgo/go/exp/norm/triegen.go @@ -19,8 +19,11 @@ import ( "unicode/utf8" ) -const blockSize = 64 -const maxSparseEntries = 16 +const ( + blockSize = 64 + blockOffset = 2 // Substract two blocks to compensate for the 0x80 added to continuation bytes. + maxSparseEntries = 16 +) // Intermediate trie structure type trieNode struct { @@ -157,7 +160,7 @@ func computeOffsets(index *nodeIndex, n *trieNode) int { if n.isInternal() { v, ok := index.lookupBlockIdx[h] if !ok { - v = len(index.lookupBlocks) + v = len(index.lookupBlocks) - blockOffset index.lookupBlocks = append(index.lookupBlocks, n) index.lookupBlockIdx[h] = v } @@ -166,7 +169,7 @@ func computeOffsets(index *nodeIndex, n *trieNode) int { v, ok := index.valueBlockIdx[h] if !ok { if c := n.countSparseEntries(); c > maxSparseEntries { - v = len(index.valueBlocks) + v = len(index.valueBlocks) - blockOffset index.valueBlocks = append(index.valueBlocks, n) index.valueBlockIdx[h] = v } else { @@ -295,7 +298,7 @@ func (t *trieNode) printTables(name string) int { } fmt.Print("\n}\n\n") - cutoff := len(index.valueBlocks) + cutoff := len(index.valueBlocks) - blockOffset ni := len(index.lookupBlocks) * blockSize fmt.Printf("// %sLookup: %d bytes\n", name, ni) fmt.Printf("// Block 0 is the null block.\n") diff --git a/libgo/go/exp/types/check.go b/libgo/go/exp/types/check.go index ae0beb4..bd947a1 100644 --- a/libgo/go/exp/types/check.go +++ b/libgo/go/exp/types/check.go @@ -30,6 +30,7 @@ func (c *checker) errorf(pos token.Pos, format string, args ...interface{}) stri // collectFields collects struct fields tok = token.STRUCT), interface methods // (tok = token.INTERFACE), and function arguments/results (tok = token.FUNC). +// func (c *checker) collectFields(tok token.Token, list *ast.FieldList, cycleOk bool) (fields ObjList, tags []string, isVariadic bool) { if list != nil { for _, field := range list.List { @@ -104,7 +105,7 @@ func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) { obj := t.Obj if obj == nil { // unresolved identifier (error has been reported before) - return &Bad{Msg: "unresolved identifier"} + return &Bad{Msg: fmt.Sprintf("%s is unresolved", t.Name)} } if obj.Kind != ast.Typ { msg := c.errorf(t.Pos(), "%s is not a type", t.Name) @@ -112,10 +113,7 @@ func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) { } c.checkObj(obj, cycleOk) if !cycleOk && obj.Type.(*Name).Underlying == nil { - // TODO(gri) Enable this message again once its position - // is independent of the underlying map implementation. - // msg := c.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name) - msg := "illegal cycle" + msg := c.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name) return &Bad{Msg: msg} } return obj.Type.(Type) @@ -158,8 +156,8 @@ func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) { return &Struct{Fields: fields, Tags: tags} case *ast.FuncType: - params, _, _ := c.collectFields(token.FUNC, t.Params, true) - results, _, isVariadic := c.collectFields(token.FUNC, t.Results, true) + params, _, isVariadic := c.collectFields(token.FUNC, t.Params, true) + results, _, _ := c.collectFields(token.FUNC, t.Results, true) return &Func{Recv: nil, Params: params, Results: results, IsVariadic: isVariadic} case *ast.InterfaceType: @@ -168,7 +166,7 @@ func (c *checker) makeType(x ast.Expr, cycleOk bool) (typ Type) { return &Interface{Methods: methods} case *ast.MapType: - return &Map{Key: c.makeType(t.Key, true), Elt: c.makeType(t.Key, true)} + return &Map{Key: c.makeType(t.Key, true), Elt: c.makeType(t.Value, true)} case *ast.ChanType: return &Chan{Dir: t.Dir, Elt: c.makeType(t.Value, true)} @@ -200,7 +198,21 @@ func (c *checker) checkObj(obj *ast.Object, ref bool) { // TODO(gri) complete this case ast.Fun: - // TODO(gri) complete this + fdecl := obj.Decl.(*ast.FuncDecl) + ftyp := c.makeType(fdecl.Type, ref).(*Func) + obj.Type = ftyp + if fdecl.Recv != nil { + recvField := fdecl.Recv.List[0] + if len(recvField.Names) > 0 { + ftyp.Recv = recvField.Names[0].Obj + } else { + ftyp.Recv = ast.NewObj(ast.Var, "_") + ftyp.Recv.Decl = recvField + } + c.checkObj(ftyp.Recv, ref) + // TODO(axw) add method to a list in the receiver type. + } + // TODO(axw) check function body, if non-nil. default: panic("unreachable") @@ -213,11 +225,25 @@ func (c *checker) checkObj(obj *ast.Object, ref bool) { // there are errors. // func Check(fset *token.FileSet, pkg *ast.Package) (types map[ast.Expr]Type, err error) { + // Sort objects so that we get reproducible error + // positions (this is only needed for testing). + // TODO(gri): Consider ast.Scope implementation that + // provides both a list and a map for fast lookup. + // Would permit the use of scopes instead of ObjMaps + // elsewhere. + list := make(ObjList, len(pkg.Scope.Objects)) + i := 0 + for _, obj := range pkg.Scope.Objects { + list[i] = obj + i++ + } + list.Sort() + var c checker c.fset = fset c.types = make(map[ast.Expr]Type) - for _, obj := range pkg.Scope.Objects { + for _, obj := range list { c.checkObj(obj, false) } diff --git a/libgo/go/exp/types/check_test.go b/libgo/go/exp/types/check_test.go index 34c26c9..50c58e3 100644 --- a/libgo/go/exp/types/check_test.go +++ b/libgo/go/exp/types/check_test.go @@ -23,13 +23,13 @@ package types import ( - "fmt" + // "fmt" "go/ast" "go/parser" "go/scanner" "go/token" "io/ioutil" - "os" + // "os" "regexp" "testing" ) @@ -167,6 +167,10 @@ func eliminate(t *testing.T, expected map[token.Pos]string, errors error) { } } +/* + +This test doesn't work with gccgo--it can't read gccgo imports. + func check(t *testing.T, testname string, testfiles []string) { // TODO(gri) Eventually all these different phases should be // subsumed into a single function call that takes @@ -203,7 +207,7 @@ func check(t *testing.T, testname string, testfiles []string) { func TestCheck(t *testing.T) { // For easy debugging w/o changing the testing code, // if there is a local test file, only test that file. - const testfile = "test.go" + const testfile = "testdata/test.go" if fi, err := os.Stat(testfile); err == nil && !fi.IsDir() { fmt.Printf("WARNING: Testing only %s (remove it to run all tests)\n", testfile) check(t, testfile, []string{testfile}) @@ -215,3 +219,5 @@ func TestCheck(t *testing.T) { check(t, test.name, test.files) } } + +*/ diff --git a/libgo/go/exp/types/exportdata.go b/libgo/go/exp/types/exportdata.go index bca2038..2219015 100644 --- a/libgo/go/exp/types/exportdata.go +++ b/libgo/go/exp/types/exportdata.go @@ -52,13 +52,14 @@ func FindGcExportData(r *bufio.Reader) (err error) { var name string var size int - // First entry should be __.SYMDEF. + // First entry should be __.GOSYMDEF. + // Older archives used __.SYMDEF, so allow that too. // Read and discard. if name, size, err = readGopackHeader(r); err != nil { return } - if name != "__.SYMDEF" { - err = errors.New("go archive does not begin with __.SYMDEF") + if name != "__.SYMDEF" && name != "__.GOSYMDEF" { + err = errors.New("go archive does not begin with __.SYMDEF or __.GOSYMDEF") return } const block = 4096 diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go index 07ab087..51121b7 100644 --- a/libgo/go/exp/types/gcimporter.go +++ b/libgo/go/exp/types/gcimporter.go @@ -42,7 +42,8 @@ func FindPkg(path, srcDir string) (filename, id string) { switch { default: // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" - bp, _ := build.Import(path, srcDir, build.FindOnly) + // Don't require the source files to be present. + bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) if bp.PkgObj == "" { return } @@ -89,10 +90,6 @@ func GcImportData(imports map[string]*ast.Object, filename, id string, data *buf fmt.Printf("importing %s (%s)\n", id, filename) } - if imports[id] != nil { - panic(fmt.Sprintf("package %s already imported", id)) - } - // support for gcParser error handling defer func() { if r := recover(); r != nil { @@ -128,9 +125,12 @@ func GcImport(imports map[string]*ast.Object, path string) (pkg *ast.Object, err return } - if pkg = imports[id]; pkg != nil { - return // package was imported before - } + // Note: imports[id] may already contain a partially imported package. + // We must continue doing the full import here since we don't + // know if something is missing. + // TODO: There's no need to re-import a package if we know that we + // have done a full import before. At the moment we cannot + // tell from the available information in this function alone. // open file f, err := os.Open(filename) @@ -182,7 +182,7 @@ func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]* func (p *gcParser) next() { p.tok = p.scanner.Scan() switch p.tok { - case scanner.Ident, scanner.Int, scanner.String: + case scanner.Ident, scanner.Int, scanner.String, '·': p.lit = p.scanner.TokenText() default: p.lit = "" @@ -294,9 +294,8 @@ func (p *gcParser) parsePkgId() *ast.Object { pkg := p.imports[id] if pkg == nil { - scope = ast.NewScope(nil) pkg = ast.NewObj(ast.Pkg, "") - pkg.Data = scope + pkg.Data = ast.NewScope(nil) p.imports[id] = pkg } @@ -509,32 +508,21 @@ func (p *gcParser) parseSignature() *Func { return &Func{Params: params, Results: results, IsVariadic: isVariadic} } -// MethodOrEmbedSpec = Name [ Signature ] . +// InterfaceType = "interface" "{" [ MethodList ] "}" . +// MethodList = Method { ";" Method } . +// Method = Name Signature . // -func (p *gcParser) parseMethodOrEmbedSpec() *ast.Object { - p.parseName() - if p.tok == '(' { - p.parseSignature() - // TODO(gri) compute method object - return ast.NewObj(ast.Fun, "_") - } - // TODO lookup name and return that type - return ast.NewObj(ast.Typ, "_") -} - -// InterfaceType = "interface" "{" [ MethodOrEmbedList ] "}" . -// MethodOrEmbedList = MethodOrEmbedSpec { ";" MethodOrEmbedSpec } . +// (The methods of embedded interfaces are always "inlined" +// by the compiler and thus embedded interfaces are never +// visible in the export data.) // func (p *gcParser) parseInterfaceType() Type { var methods ObjList parseMethod := func() { - switch m := p.parseMethodOrEmbedSpec(); m.Kind { - case ast.Typ: - // TODO expand embedded methods - case ast.Fun: - methods = append(methods, m) - } + obj := ast.NewObj(ast.Fun, p.parseName()) + obj.Type = p.parseSignature() + methods = append(methods, obj) } p.expectKeyword("interface") @@ -664,7 +652,7 @@ func (p *gcParser) parseInt() (sign, val string) { func (p *gcParser) parseNumber() Const { // mantissa sign, val := p.parseInt() - mant, ok := new(big.Int).SetString(sign+val, 10) + mant, ok := new(big.Int).SetString(sign+val, 0) assert(ok) if p.lit == "p" { @@ -693,7 +681,7 @@ func (p *gcParser) parseNumber() Const { // ConstDecl = "const" ExportedName [ Type ] "=" Literal . // Literal = bool_lit | int_lit | float_lit | complex_lit | string_lit . // bool_lit = "true" | "false" . -// complex_lit = "(" float_lit "+" float_lit ")" . +// complex_lit = "(" float_lit "+" float_lit "i" ")" . // rune_lit = "(" int_lit "+" int_lit ")" . // string_lit = `"` { unicode_char } `"` . // @@ -737,6 +725,7 @@ func (p *gcParser) parseConstDecl() { re := p.parseNumber() p.expect('+') im := p.parseNumber() + p.expectKeyword("i") p.expect(')') x = Const{cmplx{re.val.(*big.Rat), im.val.(*big.Rat)}} typ = Complex128.Underlying @@ -867,10 +856,12 @@ func (p *gcParser) parseExport() *ast.Object { } p.expect('\n') - assert(p.imports[p.id] == nil) - pkg := ast.NewObj(ast.Pkg, name) - pkg.Data = ast.NewScope(nil) - p.imports[p.id] = pkg + pkg := p.imports[p.id] + if pkg == nil { + pkg = ast.NewObj(ast.Pkg, name) + pkg.Data = ast.NewScope(nil) + p.imports[p.id] = pkg + } for p.tok != '$' && p.tok != scanner.EOF { p.parseDecl() diff --git a/libgo/go/exp/types/gcimporter_test.go b/libgo/go/exp/types/gcimporter_test.go index 20247b0..0fed72a 100644 --- a/libgo/go/exp/types/gcimporter_test.go +++ b/libgo/go/exp/types/gcimporter_test.go @@ -36,15 +36,17 @@ func init() { gcPath = filepath.Join(build.ToolDir, gc) } -func compile(t *testing.T, dirname, filename string) { +func compile(t *testing.T, dirname, filename string) string { cmd := exec.Command(gcPath, filename) cmd.Dir = dirname out, err := cmd.CombinedOutput() if err != nil { - t.Errorf("%s %s failed: %s", gcPath, filename, err) - return + t.Logf("%s", out) + t.Fatalf("%s %s failed: %s", gcPath, filename, err) } - t.Logf("%s", string(out)) + archCh, _ := build.ArchChar(runtime.GOARCH) + // filename should end with ".go" + return filepath.Join(dirname, filename[:len(filename)-2]+archCh) } // Use the same global imports map for all tests. The effect is @@ -99,7 +101,9 @@ func TestGcImport(t *testing.T) { return } - compile(t, "testdata", "exports.go") + if outFn := compile(t, "testdata", "exports.go"); outFn != "" { + defer os.Remove(outFn) + } nimports := 0 if testPath(t, "./testdata/exports") { @@ -108,3 +112,48 @@ func TestGcImport(t *testing.T) { nimports += testDir(t, "", time.Now().Add(maxTime)) // installed packages t.Logf("tested %d imports", nimports) } + +/* + +Does not work with gccgo. + +var importedObjectTests = []struct { + name string + kind ast.ObjKind + typ string +}{ + {"unsafe.Pointer", ast.Typ, "Pointer"}, + {"math.Pi", ast.Con, "basicType"}, // TODO(gri) need to complete BasicType + {"io.Reader", ast.Typ, "interface{Read(p []byte) (n int, err error)}"}, + {"io.ReadWriter", ast.Typ, "interface{Read(p []byte) (n int, err error); Write(p []byte) (n int, err error)}"}, + {"math.Sin", ast.Fun, "func(x float64) (_ float64)"}, + // TODO(gri) add more tests +} + +func TestGcImportedTypes(t *testing.T) { + for _, test := range importedObjectTests { + s := strings.Split(test.name, ".") + if len(s) != 2 { + t.Fatal("inconsistent test data") + } + importPath := s[0] + objName := s[1] + + pkg, err := GcImport(imports, importPath) + if err != nil { + t.Error(err) + continue + } + + obj := pkg.Data.(*ast.Scope).Lookup(objName) + if obj.Kind != test.kind { + t.Errorf("%s: got kind = %q; want %q", test.name, obj.Kind, test.kind) + } + typ := TypeString(Underlying(obj.Type.(Type))) + if typ != test.typ { + t.Errorf("%s: got type = %q; want %q", test.name, typ, test.typ) + } + } +} + +*/ diff --git a/libgo/go/exp/types/resolver_test.go b/libgo/go/exp/types/resolver_test.go new file mode 100644 index 0000000..15b0141 --- /dev/null +++ b/libgo/go/exp/types/resolver_test.go @@ -0,0 +1,136 @@ +// Copyright 2011 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 types + +import ( + "fmt" + "go/ast" + // "go/parser" + "go/scanner" + "go/token" + // "testing" +) + +var sources = []string{ + `package p + import "fmt" + import "math" + const pi = math.Pi + func sin(x float64) float64 { + return math.Sin(x) + } + var Println = fmt.Println + `, + `package p + import "fmt" + func f() string { + return fmt.Sprintf("%d", g()) + } + `, + `package p + import . "go/parser" + func g() Mode { return ImportsOnly }`, +} + +var pkgnames = []string{ + "fmt", + "go/parser", + "math", +} + +// ResolveQualifiedIdents resolves the selectors of qualified +// identifiers by associating the correct ast.Object with them. +// TODO(gri): Eventually, this functionality should be subsumed +// by Check. +// +func ResolveQualifiedIdents(fset *token.FileSet, pkg *ast.Package) error { + var errors scanner.ErrorList + + findObj := func(pkg *ast.Object, name *ast.Ident) *ast.Object { + scope := pkg.Data.(*ast.Scope) + obj := scope.Lookup(name.Name) + if obj == nil { + errors.Add(fset.Position(name.Pos()), fmt.Sprintf("no %s in package %s", name.Name, pkg.Name)) + } + return obj + } + + ast.Inspect(pkg, func(n ast.Node) bool { + if s, ok := n.(*ast.SelectorExpr); ok { + if x, ok := s.X.(*ast.Ident); ok && x.Obj != nil && x.Obj.Kind == ast.Pkg { + // find selector in respective package + s.Sel.Obj = findObj(x.Obj, s.Sel) + } + return false + } + return true + }) + + return errors.Err() +} + +/* + +Does not work with gccgo. + +func TestResolveQualifiedIdents(t *testing.T) { + // parse package files + fset := token.NewFileSet() + files := make(map[string]*ast.File) + for i, src := range sources { + filename := fmt.Sprintf("file%d", i) + f, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) + if err != nil { + t.Fatal(err) + } + files[filename] = f + } + + // resolve package AST + pkg, err := ast.NewPackage(fset, files, GcImport, Universe) + if err != nil { + t.Fatal(err) + } + + // check that all packages were imported + for _, name := range pkgnames { + if pkg.Imports[name] == nil { + t.Errorf("package %s not imported", name) + } + } + + // check that there are no top-level unresolved identifiers + for _, f := range pkg.Files { + for _, x := range f.Unresolved { + t.Errorf("%s: unresolved global identifier %s", fset.Position(x.Pos()), x.Name) + } + } + + // resolve qualified identifiers + if err := ResolveQualifiedIdents(fset, pkg); err != nil { + t.Error(err) + } + + // check that qualified identifiers are resolved + ast.Inspect(pkg, func(n ast.Node) bool { + if s, ok := n.(*ast.SelectorExpr); ok { + if x, ok := s.X.(*ast.Ident); ok { + if x.Obj == nil { + t.Errorf("%s: unresolved qualified identifier %s", fset.Position(x.Pos()), x.Name) + return false + } + if x.Obj.Kind == ast.Pkg && s.Sel != nil && s.Sel.Obj == nil { + t.Errorf("%s: unresolved selector %s", fset.Position(s.Sel.Pos()), s.Sel.Name) + return false + } + return false + } + return false + } + return true + }) +} + +*/ diff --git a/libgo/go/exp/types/staging/builtins.go b/libgo/go/exp/types/staging/builtins.go new file mode 100644 index 0000000..ef9ae80 --- /dev/null +++ b/libgo/go/exp/types/staging/builtins.go @@ -0,0 +1,349 @@ +// Copyright 2012 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. + +// This file implements typechecking of builtin function calls. + +package types + +import ( + "go/ast" + "go/token" +) + +// builtin typechecks a built-in call. The built-in type is bin, and iota is the current +// value of iota or -1 if iota doesn't have a value in the current context. The result +// of the call is returned via x. If the call has type errors, the returned x is marked +// as invalid (x.mode == invalid). +// +func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *builtin, iota int) { + args := call.Args + id := bin.id + + // declare before goto's + var arg0 ast.Expr + var typ0 Type + + // check argument count + n := len(args) + msg := "" + if n < bin.nargs { + msg = "not enough" + } else if !bin.isVariadic && n > bin.nargs { + msg = "too many" + } + if msg != "" { + check.invalidOp(call.Pos(), msg+"arguments for %s (expected %d, found %d)", call, bin.nargs, n) + goto Error + } + + // common case: evaluate first argument if present; + // if it is an expression, x has the expression value + if n > 0 { + arg0 = args[0] + switch id { + case _Make, _New: + // argument must be a type + typ0 = underlying(check.typ(arg0, false)) + if typ0 == Typ[Invalid] { + goto Error + } + case _Trace: + // _Trace implementation does the work + default: + // argument must be an expression + check.expr(x, arg0, nil, iota) + if x.mode == invalid { + goto Error + } + typ0 = underlying(x.typ) + } + } + + switch id { + case _Append: + s, ok := typ0.(*Slice) + if !ok { + check.invalidArg(x.pos(), "%s is not a typed slice", x) + goto Error + } + for _, arg := range args[1:] { + check.expr(x, arg, nil, iota) + if x.mode == invalid { + goto Error + } + // TODO(gri) check assignability + } + x.mode = value + x.typ = s + + case _Cap, _Len: + mode := invalid + var val interface{} + switch typ := implicitDeref(typ0).(type) { + case *Basic: + if isString(typ) && id == _Len { + if x.mode == constant { + mode = constant + val = int64(len(x.val.(string))) + } else { + mode = value + } + } + + case *Array: + mode = value + if !containsCallsOrReceives(arg0) { + mode = constant + val = typ.Len + } + + case *Slice, *Chan: + mode = value + + case *Map: + if id == _Len { + mode = value + } + } + + if mode == invalid { + check.invalidArg(x.pos(), "%s for %s", x, bin.name) + goto Error + } + x.mode = mode + x.typ = Typ[Int] + x.val = val + + case _Close: + ch, ok := typ0.(*Chan) + if !ok { + check.invalidArg(x.pos(), "%s is not a channel", x) + goto Error + } + if ch.Dir&ast.SEND == 0 { + check.invalidArg(x.pos(), "%s must not be a receive-only channel", x) + goto Error + } + x.mode = novalue + + case _Complex: + var y operand + check.expr(&y, args[1], nil, iota) + if y.mode == invalid { + goto Error + } + // TODO(gri) handle complex(a, b) like (a + toImag(b)) + unimplemented() + + case _Copy: + // TODO(gri) implements checks + unimplemented() + x.mode = value + x.typ = Typ[Int] + + case _Delete: + m, ok := typ0.(*Map) + if !ok { + check.invalidArg(x.pos(), "%s is not a map", x) + goto Error + } + check.expr(x, args[1], nil, iota) + if x.mode == invalid { + goto Error + } + if !x.isAssignable(m.Key) { + check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.Key) + goto Error + } + x.mode = novalue + + case _Imag, _Real: + if !isComplex(typ0) { + check.invalidArg(x.pos(), "%s must be a complex number", x) + goto Error + } + if x.mode == constant { + // nothing to do for x.val == 0 + if !isZeroConst(x.val) { + c := x.val.(complex) + if id == _Real { + x.val = c.re + } else { + x.val = c.im + } + } + } else { + x.mode = value + } + k := Invalid + switch typ0.(*Basic).Kind { + case Complex64: + k = Float32 + case Complex128: + k = Float64 + case UntypedComplex: + k = UntypedFloat + default: + unreachable() + } + x.typ = Typ[k] + + case _Make: + var min int // minimum number of arguments + switch typ0.(type) { + case *Slice: + min = 2 + case *Map, *Chan: + min = 1 + default: + check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0) + goto Error + } + if n := len(args); n < min || min+1 < n { + check.errorf(call.Pos(), "%s expects %d or %d arguments; found %d", call, min, min+1, n) + goto Error + } + for _, arg := range args[1:] { + check.expr(x, arg, nil, iota) + if !x.isInteger() { + check.invalidArg(x.pos(), "%s must be an integer", x) + // safe to continue + } + } + x.mode = variable + x.typ = typ0 + + case _New: + x.mode = variable + x.typ = &Pointer{Base: typ0} + + case _Panic, _Print, _Println: + x.mode = novalue + + case _Recover: + x.mode = value + x.typ = emptyInterface + + case _Alignof: + x.mode = constant + x.typ = Typ[Uintptr] + // For now we return 1 always as it satisfies the spec's alignment guarantees. + // TODO(gri) Extend typechecker API so that platform-specific values can be + // provided. + x.val = int64(1) + + case _Offsetof: + if _, ok := unparen(x.expr).(*ast.SelectorExpr); !ok { + check.invalidArg(x.pos(), "%s is not a selector", x) + goto Error + } + x.mode = constant + x.typ = Typ[Uintptr] + // because of the size guarantees for basic types (> 0 for some), + // returning 0 is only correct if two distinct non-zero size + // structs can have the same address (the spec permits that) + x.val = int64(0) + + case _Sizeof: + // basic types with specified sizes have size guarantees; for all others we use 0 + var size int64 + if typ, ok := typ0.(*Basic); ok { + size = typ.Size + } + x.mode = constant + x.typ = Typ[Uintptr] + x.val = size + + case _Assert: + // assert(pred) causes a typechecker error if pred is false. + // The result of assert is the value of pred if there is no error. + // Note: assert is only available in self-test mode. + if x.mode != constant || !isBoolean(typ0) { + check.invalidArg(x.pos(), "%s is not a boolean constant", x) + goto Error + } + pred, ok := x.val.(bool) + if !ok { + check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x) + goto Error + } + if !pred { + check.errorf(call.Pos(), "%s failed", call) + // compile-time assertion failure - safe to continue + } + + case _Trace: + // trace(x, y, z, ...) dumps the positions, expressions, and + // values of its arguments. The result of trace is the value + // of the first argument. + // Note: trace is only available in self-test mode. + if len(args) == 0 { + check.dump("%s: trace() without arguments", call.Pos()) + x.mode = novalue + x.expr = call + return + } + var t operand + x1 := x + for _, arg := range args { + check.exprOrType(x1, arg, nil, iota, true) // permit trace for types, e.g.: new(trace(T)) + check.dump("%s: %s", x1.pos(), x1) + x1 = &t // use incoming x only for first argument + } + + default: + check.invalidAST(call.Pos(), "unknown builtin id %d", id) + goto Error + } + + x.expr = call + return + +Error: + x.mode = invalid + x.expr = call +} + +// implicitDeref returns A if typ is of the form *A and A is an array; +// otherwise it returns typ. +// +func implicitDeref(typ Type) Type { + if p, ok := typ.(*Pointer); ok { + if a, ok := underlying(p.Base).(*Array); ok { + return a + } + } + return typ +} + +// containsCallsOrReceives returns true if the expression x contains +// function calls or channel receives; it returns false otherwise. +// +func containsCallsOrReceives(x ast.Expr) bool { + res := false + ast.Inspect(x, func(x ast.Node) bool { + switch x := x.(type) { + case *ast.CallExpr: + res = true + return false + case *ast.UnaryExpr: + if x.Op == token.ARROW { + res = true + return false + } + } + return true + }) + return res +} + +// unparen removes any parentheses surrounding an expression and returns +// the naked expression. +// +func unparen(x ast.Expr) ast.Expr { + if p, ok := x.(*ast.ParenExpr); ok { + return unparen(p.X) + } + return x +} diff --git a/libgo/go/exp/types/staging/check.go b/libgo/go/exp/types/staging/check.go new file mode 100644 index 0000000..1fc4134 --- /dev/null +++ b/libgo/go/exp/types/staging/check.go @@ -0,0 +1,352 @@ +// Copyright 2011 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. + +// This file implements the Check function, which typechecks a package. + +package types + +import ( + "fmt" + "go/ast" + "go/token" + "sort" +) + +type checker struct { + fset *token.FileSet + pkg *ast.Package + errh func(token.Pos, string) + mapf func(ast.Expr, Type) + + // lazily initialized + firsterr error + filenames []string // sorted list of package file names for reproducible iteration order + initexprs map[*ast.ValueSpec][]ast.Expr // "inherited" initialization expressions for constant declarations +} + +// declare declares an object of the given kind and name (ident) in scope; +// decl is the corresponding declaration in the AST. An error is reported +// if the object was declared before. +// +// TODO(gri) This is very similar to the declare function in go/parser; it +// is only used to associate methods with their respective receiver base types. +// In a future version, it might be simpler and cleaner do to all the resolution +// in the type-checking phase. It would simplify the parser, AST, and also +// reduce some amount of code duplication. +// +func (check *checker) declare(scope *ast.Scope, kind ast.ObjKind, ident *ast.Ident, decl ast.Decl) { + assert(ident.Obj == nil) // identifier already declared or resolved + obj := ast.NewObj(kind, ident.Name) + obj.Decl = decl + ident.Obj = obj + if ident.Name != "_" { + if alt := scope.Insert(obj); alt != nil { + prevDecl := "" + if pos := alt.Pos(); pos.IsValid() { + prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", check.fset.Position(pos)) + } + check.errorf(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl)) + } + } +} + +func (check *checker) valueSpec(pos token.Pos, obj *ast.Object, lhs []*ast.Ident, typ ast.Expr, rhs []ast.Expr, iota int) { + if len(lhs) == 0 { + check.invalidAST(pos, "missing lhs in declaration") + return + } + + var t Type + if typ != nil { + t = check.typ(typ, false) + } + + // len(lhs) >= 1 + if len(lhs) == len(rhs) { + // check only corresponding lhs and rhs + var l, r ast.Expr + for i, ident := range lhs { + if ident.Obj == obj { + l = lhs[i] + r = rhs[i] + break + } + } + assert(l != nil) + obj.Type = t + // check rhs + var x operand + check.expr(&x, r, t, iota) + // assign to lhs + check.assignment(l, &x, true) + return + } + + if t != nil { + for _, name := range lhs { + name.Obj.Type = t + } + } + + // check initial values, if any + if len(rhs) > 0 { + // TODO(gri) should try to avoid this conversion + lhx := make([]ast.Expr, len(lhs)) + for i, e := range lhs { + lhx[i] = e + } + check.assignNtoM(lhx, rhs, true, iota) + } +} + +// ident type checks an identifier. +func (check *checker) ident(name *ast.Ident, cycleOk bool) { + obj := name.Obj + if obj == nil { + check.invalidAST(name.Pos(), "missing object for %s", name.Name) + return + } + + if obj.Type != nil { + // object has already been type checked + return + } + + switch obj.Kind { + case ast.Bad, ast.Pkg: + // nothing to do + + case ast.Con, ast.Var: + // The obj.Data field for constants and variables is initialized + // to the respective (hypothetical, for variables) iota value by + // the parser. The object's fields can be in one of the following + // states: + // Type != nil => the constant value is Data + // Type == nil => the object is not typechecked yet, and Data can be: + // Data is int => Data is the value of iota for this declaration + // Data == nil => the object's expression is being evaluated + if obj.Data == nil { + check.errorf(obj.Pos(), "illegal cycle in initialization of %s", obj.Name) + return + } + spec := obj.Decl.(*ast.ValueSpec) + iota := obj.Data.(int) + obj.Data = nil + // determine initialization expressions + values := spec.Values + if len(values) == 0 && obj.Kind == ast.Con { + values = check.initexprs[spec] + } + check.valueSpec(spec.Pos(), obj, spec.Names, spec.Type, values, iota) + + case ast.Typ: + typ := &NamedType{Obj: obj} + obj.Type = typ // "mark" object so recursion terminates + typ.Underlying = underlying(check.typ(obj.Decl.(*ast.TypeSpec).Type, cycleOk)) + // collect associated methods, if any + if obj.Data != nil { + scope := obj.Data.(*ast.Scope) + // struct fields must not conflict with methods + if t, ok := typ.Underlying.(*Struct); ok { + for _, f := range t.Fields { + if m := scope.Lookup(f.Name); m != nil { + check.errorf(m.Pos(), "type %s has both field and method named %s", obj.Name, f.Name) + } + } + } + // collect methods + methods := make(ObjList, len(scope.Objects)) + i := 0 + for _, m := range scope.Objects { + methods[i] = m + i++ + } + methods.Sort() + typ.Methods = methods + // methods cannot be associated with an interface type + // (do this check after sorting for reproducible error positions - needed for testing) + if _, ok := typ.Underlying.(*Interface); ok { + for _, m := range methods { + recv := m.Decl.(*ast.FuncDecl).Recv.List[0].Type + check.errorf(recv.Pos(), "invalid receiver type %s (%s is an interface type)", obj.Name, obj.Name) + } + } + } + + case ast.Fun: + fdecl := obj.Decl.(*ast.FuncDecl) + ftyp := check.typ(fdecl.Type, cycleOk).(*Signature) + obj.Type = ftyp + if fdecl.Recv != nil { + // TODO(gri) handle method receiver + } + check.stmt(fdecl.Body) + + default: + panic("unreachable") + } +} + +// assocInitvals associates "inherited" initialization expressions +// with the corresponding *ast.ValueSpec in the check.initexprs map +// for constant declarations without explicit initialization expressions. +// +func (check *checker) assocInitvals(decl *ast.GenDecl) { + var values []ast.Expr + for _, s := range decl.Specs { + if s, ok := s.(*ast.ValueSpec); ok { + if len(s.Values) > 0 { + values = s.Values + } else { + check.initexprs[s] = values + } + } + } + if len(values) == 0 { + check.invalidAST(decl.Pos(), "no initialization values provided") + } +} + +// assocMethod associates a method declaration with the respective +// receiver base type. meth.Recv must exist. +// +func (check *checker) assocMethod(meth *ast.FuncDecl) { + // The receiver type is one of the following (enforced by parser): + // - *ast.Ident + // - *ast.StarExpr{*ast.Ident} + // - *ast.BadExpr (parser error) + typ := meth.Recv.List[0].Type + if ptr, ok := typ.(*ast.StarExpr); ok { + typ = ptr.X + } + // determine receiver base type object (or nil if error) + var obj *ast.Object + if ident, ok := typ.(*ast.Ident); ok && ident.Obj != nil { + obj = ident.Obj + if obj.Kind != ast.Typ { + check.errorf(ident.Pos(), "%s is not a type", ident.Name) + obj = nil + } + // TODO(gri) determine if obj was defined in this package + /* + if check.notLocal(obj) { + check.errorf(ident.Pos(), "cannot define methods on non-local type %s", ident.Name) + obj = nil + } + */ + } else { + // If it's not an identifier or the identifier wasn't declared/resolved, + // the parser/resolver already reported an error. Nothing to do here. + } + // determine base type scope (or nil if error) + var scope *ast.Scope + if obj != nil { + if obj.Data != nil { + scope = obj.Data.(*ast.Scope) + } else { + scope = ast.NewScope(nil) + obj.Data = scope + } + } else { + // use a dummy scope so that meth can be declared in + // presence of an error and get an associated object + // (always use a new scope so that we don't get double + // declaration errors) + scope = ast.NewScope(nil) + } + check.declare(scope, ast.Fun, meth.Name, meth) +} + +func (check *checker) assocInitvalsOrMethod(decl ast.Decl) { + switch d := decl.(type) { + case *ast.GenDecl: + if d.Tok == token.CONST { + check.assocInitvals(d) + } + case *ast.FuncDecl: + if d.Recv != nil { + check.assocMethod(d) + } + } +} + +func (check *checker) decl(decl ast.Decl) { + switch d := decl.(type) { + case *ast.BadDecl: + // ignore + case *ast.GenDecl: + for _, spec := range d.Specs { + switch s := spec.(type) { + case *ast.ImportSpec: + // nothing to do (handled by ast.NewPackage) + case *ast.ValueSpec: + for _, name := range s.Names { + if name.Name == "_" { + // TODO(gri) why is _ special here? + } else { + check.ident(name, false) + } + } + case *ast.TypeSpec: + check.ident(s.Name, false) + default: + check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s) + } + } + case *ast.FuncDecl: + check.ident(d.Name, false) + default: + check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) + } +} + +// iterate calls f for each package-level declaration. +func (check *checker) iterate(f func(*checker, ast.Decl)) { + list := check.filenames + + if list == nil { + // initialize lazily + for filename := range check.pkg.Files { + list = append(list, filename) + } + sort.Strings(list) + check.filenames = list + } + + for _, filename := range list { + for _, decl := range check.pkg.Files[filename].Decls { + f(check, decl) + } + } +} + +// A bailout panic is raised to indicate early termination. +type bailout struct{} + +func check(fset *token.FileSet, pkg *ast.Package, errh func(token.Pos, string), f func(ast.Expr, Type)) (err error) { + // initialize checker + var check checker + check.fset = fset + check.pkg = pkg + check.errh = errh + check.mapf = f + check.initexprs = make(map[*ast.ValueSpec][]ast.Expr) + + // handle bailouts + defer func() { + if p := recover(); p != nil { + _ = p.(bailout) // re-panic if not a bailout + } + err = check.firsterr + }() + + // determine missing constant initialization expressions + // and associate methods with types + check.iterate((*checker).assocInitvalsOrMethod) + + // typecheck all declarations + check.iterate((*checker).decl) + + return +} diff --git a/libgo/go/exp/types/staging/check_test.go b/libgo/go/exp/types/staging/check_test.go new file mode 100644 index 0000000..abcfcfb --- /dev/null +++ b/libgo/go/exp/types/staging/check_test.go @@ -0,0 +1,257 @@ +// Copyright 2011 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. + +// This file implements a typechecker test harness. The packages specified +// in tests are typechecked. Error messages reported by the typechecker are +// compared against the error messages expected in the test files. +// +// Expected errors are indicated in the test files by putting a comment +// of the form /* ERROR "rx" */ immediately following an offending token. +// The harness will verify that an error matching the regular expression +// rx is reported at that source position. Consecutive comments may be +// used to indicate multiple errors for the same token position. +// +// For instance, the following test file indicates that a "not declared" +// error should be reported for the undeclared variable x: +// +// package p +// func f() { +// _ = x /* ERROR "not declared" */ + 1 +// } + +package types + +import ( + "flag" + "fmt" + "go/ast" + "go/parser" + "go/scanner" + "go/token" + "io/ioutil" + "os" + "regexp" + "testing" +) + +var listErrors = flag.Bool("list", false, "list errors") + +func init() { + // declare builtins for testing + def(ast.Fun, "assert").Type = &builtin{aType, _Assert, "assert", 1, false, true} + def(ast.Fun, "trace").Type = &builtin{aType, _Trace, "trace", 0, true, true} +} + +// The test filenames do not end in .go so that they are invisible +// to gofmt since they contain comments that must not change their +// positions relative to surrounding tokens. + +var tests = []struct { + name string + files []string +}{ + {"decls0", []string{"testdata/decls0.src"}}, + {"decls1", []string{"testdata/decls1.src"}}, + {"decls2", []string{"testdata/decls2a.src", "testdata/decls2b.src"}}, + {"const0", []string{"testdata/const0.src"}}, + {"expr0", []string{"testdata/expr0.src"}}, + {"expr1", []string{"testdata/expr1.src"}}, + {"expr2", []string{"testdata/expr2.src"}}, + {"expr3", []string{"testdata/expr3.src"}}, + {"builtins", []string{"testdata/builtins.src"}}, + {"conversions", []string{"testdata/conversions.src"}}, + {"stmt0", []string{"testdata/stmt0.src"}}, +} + +var fset = token.NewFileSet() + +func getFile(filename string) (file *token.File) { + fset.Iterate(func(f *token.File) bool { + if f.Name() == filename { + file = f + return false // end iteration + } + return true + }) + return file +} + +func getPos(filename string, offset int) token.Pos { + if f := getFile(filename); f != nil { + return f.Pos(offset) + } + return token.NoPos +} + +func parseFiles(t *testing.T, testname string, filenames []string) (map[string]*ast.File, error) { + files := make(map[string]*ast.File) + var errors scanner.ErrorList + for _, filename := range filenames { + if _, exists := files[filename]; exists { + t.Fatalf("%s: duplicate file %s", testname, filename) + } + file, err := parser.ParseFile(fset, filename, nil, parser.DeclarationErrors) + if file == nil { + t.Fatalf("%s: could not parse file %s", testname, filename) + } + files[filename] = file + if err != nil { + // if the parser returns a non-scanner.ErrorList error + // the file couldn't be read in the first place and + // file == nil; in that case we shouldn't reach here + errors = append(errors, err.(scanner.ErrorList)...) + } + + } + return files, errors +} + +// ERROR comments must be of the form /* ERROR "rx" */ and rx is +// a regular expression that matches the expected error message. +// +var errRx = regexp.MustCompile(`^/\* *ERROR *"([^"]*)" *\*/$`) + +// expectedErrors collects the regular expressions of ERROR comments found +// in files and returns them as a map of error positions to error messages. +// +func expectedErrors(t *testing.T, testname string, files map[string]*ast.File) map[token.Pos][]string { + errors := make(map[token.Pos][]string) + + for filename := range files { + src, err := ioutil.ReadFile(filename) + if err != nil { + t.Fatalf("%s: could not read %s", testname, filename) + } + + var s scanner.Scanner + // file was parsed already - do not add it again to the file + // set otherwise the position information returned here will + // not match the position information collected by the parser + s.Init(getFile(filename), src, nil, scanner.ScanComments) + var prev token.Pos // position of last non-comment, non-semicolon token + + scanFile: + for { + pos, tok, lit := s.Scan() + switch tok { + case token.EOF: + break scanFile + case token.COMMENT: + s := errRx.FindStringSubmatch(lit) + if len(s) == 2 { + list := errors[prev] + errors[prev] = append(list, string(s[1])) + } + case token.SEMICOLON: + // ignore automatically inserted semicolon + if lit == "\n" { + break + } + fallthrough + default: + prev = pos + } + } + } + + return errors +} + +func eliminate(t *testing.T, expected map[token.Pos][]string, errors error) { + if *listErrors || errors == nil { + return + } + for _, error := range errors.(scanner.ErrorList) { + // error.Pos is a token.Position, but we want + // a token.Pos so we can do a map lookup + pos := getPos(error.Pos.Filename, error.Pos.Offset) + list := expected[pos] + index := -1 // list index of matching message, if any + // we expect one of the messages in list to match the error at pos + for i, msg := range list { + rx, err := regexp.Compile(msg) + if err != nil { + t.Errorf("%s: %v", error.Pos, err) + continue + } + if match := rx.MatchString(error.Msg); match { + index = i + break + } + } + if index >= 0 { + // eliminate from list + n := len(list) - 1 + if n > 0 { + // not the last entry - swap in last element and shorten list by 1 + list[index] = list[n] + expected[pos] = list[:n] + } else { + // last entry - remove list from map + delete(expected, pos) + } + } else { + t.Errorf("%s: no error expected: %q", error.Pos, error.Msg) + continue + } + } +} + +func checkFiles(t *testing.T, testname string, testfiles []string) { + // TODO(gri) Eventually all these different phases should be + // subsumed into a single function call that takes + // a set of files and creates a fully resolved and + // type-checked AST. + + files, err := parseFiles(t, testname, testfiles) + + // we are expecting the following errors + // (collect these after parsing the files so that + // they are found in the file set) + errors := expectedErrors(t, testname, files) + + // verify errors returned by the parser + eliminate(t, errors, err) + + // verify errors returned after resolving identifiers + pkg, err := ast.NewPackage(fset, files, GcImport, Universe) + eliminate(t, errors, err) + + // verify errors returned by the typechecker + var list scanner.ErrorList + errh := func(pos token.Pos, msg string) { + list.Add(fset.Position(pos), msg) + } + err = Check(fset, pkg, errh, nil) + eliminate(t, errors, list) + + if *listErrors { + scanner.PrintError(os.Stdout, err) + return + } + + // there should be no expected errors left + if len(errors) > 0 { + t.Errorf("%s: %d errors not reported:", testname, len(errors)) + for pos, msg := range errors { + t.Errorf("%s: %s\n", fset.Position(pos), msg) + } + } +} + +func TestCheck(t *testing.T) { + // For easy debugging w/o changing the testing code, + // if there is a local test file, only test that file. + const testfile = "testdata/test.go" + if fi, err := os.Stat(testfile); err == nil && !fi.IsDir() { + fmt.Printf("WARNING: Testing only %s (remove it to run all tests)\n", testfile) + checkFiles(t, testfile, []string{testfile}) + return + } + + // Otherwise, run all the tests. + for _, test := range tests { + checkFiles(t, test.name, test.files) + } +} diff --git a/libgo/go/exp/types/staging/const.go b/libgo/go/exp/types/staging/const.go new file mode 100644 index 0000000..e817f1f --- /dev/null +++ b/libgo/go/exp/types/staging/const.go @@ -0,0 +1,662 @@ +// Copyright 2011 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. + +// This file implements operations on constant values. + +package types + +import ( + "fmt" + "go/token" + "math/big" + "strconv" +) + +// TODO(gri) At the moment, constants are different types +// passed around as interface{} values. Consider introducing +// a Const type and use methods instead of xConst functions. + +// Representation of constant values. +// +// bool -> bool (true, false) +// numeric -> int64, *big.Int, *big.Rat, complex (ordered by increasing data structure "size") +// string -> string +// nil -> nilType (nilConst) +// +// Numeric constants are normalized after each operation such +// that they are represented by the "smallest" data structure +// required to represent the constant, independent of actual +// type. Non-numeric constants are always normalized. + +// Representation of complex numbers. +type complex struct { + re, im *big.Rat +} + +func (c complex) String() string { + if c.re.Sign() == 0 { + return fmt.Sprintf("%si", c.im) + } + // normalized complex values always have an imaginary part + return fmt.Sprintf("(%s + %si)", c.re, c.im) +} + +// Representation of nil. +type nilType struct{} + +func (nilType) String() string { + return "nil" +} + +// Frequently used constants. +var ( + zeroConst = int64(0) + oneConst = int64(1) + minusOneConst = int64(-1) + nilConst = new(nilType) +) + +// int64 bounds +var ( + minInt64 = big.NewInt(-1 << 63) + maxInt64 = big.NewInt(1<<63 - 1) +) + +// normalizeIntConst returns the smallest constant representation +// for the specific value of x; either an int64 or a *big.Int value. +// +func normalizeIntConst(x *big.Int) interface{} { + if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 { + return x.Int64() + } + return x +} + +// normalizeRatConst returns the smallest constant representation +// for the specific value of x; either an int64, *big.Int value, +// or *big.Rat value. +// +func normalizeRatConst(x *big.Rat) interface{} { + if x.IsInt() { + return normalizeIntConst(x.Num()) + } + return x +} + +// normalizeComplexConst returns the smallest constant representation +// for the specific value of x; either an int64, *big.Int value, *big.Rat, +// or complex value. +// +func normalizeComplexConst(x complex) interface{} { + if x.im.Sign() == 0 { + return normalizeRatConst(x.re) + } + return x +} + +// makeRuneConst returns the int64 code point for the rune literal +// lit. The result is nil if lit is not a correct rune literal. +// +func makeRuneConst(lit string) interface{} { + if n := len(lit); n >= 2 { + if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil { + return int64(code) + } + } + return nil +} + +// makeRuneConst returns the smallest integer constant representation +// (int64, *big.Int) for the integer literal lit. The result is nil if +// lit is not a correct integer literal. +// +func makeIntConst(lit string) interface{} { + if x, err := strconv.ParseInt(lit, 0, 64); err == nil { + return x + } + if x, ok := new(big.Int).SetString(lit, 0); ok { + return x + } + return nil +} + +// makeFloatConst returns the smallest floating-point constant representation +// (int64, *big.Int, *big.Rat) for the floating-point literal lit. The result +// is nil if lit is not a correct floating-point literal. +// +func makeFloatConst(lit string) interface{} { + if x, ok := new(big.Rat).SetString(lit); ok { + return normalizeRatConst(x) + } + return nil +} + +// makeComplexConst returns the complex constant representation (complex) for +// the imaginary literal lit. The result is nil if lit is not a correct imaginary +// literal. +// +func makeComplexConst(lit string) interface{} { + n := len(lit) + if n > 0 && lit[n-1] == 'i' { + if im, ok := new(big.Rat).SetString(lit[0 : n-1]); ok { + return normalizeComplexConst(complex{big.NewRat(0, 1), im}) + } + } + return nil +} + +// makeStringConst returns the string constant representation (string) for +// the string literal lit. The result is nil if lit is not a correct string +// literal. +// +func makeStringConst(lit string) interface{} { + if s, err := strconv.Unquote(lit); err == nil { + return s + } + return nil +} + +// isZeroConst reports whether the value of constant x is 0. +// x must be normalized. +// +func isZeroConst(x interface{}) bool { + i, ok := x.(int64) // good enough since constants are normalized + return ok && i == 0 +} + +// isNegConst reports whether the value of constant x is < 0. +// x must be a non-complex numeric value. +// +func isNegConst(x interface{}) bool { + switch x := x.(type) { + case int64: + return x < 0 + case *big.Int: + return x.Sign() < 0 + case *big.Rat: + return x.Sign() < 0 + } + unreachable() + return false +} + +// isRepresentableConst reports whether the value of constant x can +// be represented as a value of the basic type Typ[as] without loss +// of precision. +// +func isRepresentableConst(x interface{}, as BasicKind) bool { + const intBits = 32 // TODO(gri) implementation-specific constant + const ptrBits = 64 // TODO(gri) implementation-specific constant + + switch x := x.(type) { + case bool: + return as == Bool || as == UntypedBool + + case int64: + switch as { + case Int: + return -1<<(intBits-1) <= x && x <= 1<<(intBits-1)-1 + case Int8: + return -1<<(8-1) <= x && x <= 1<<(8-1)-1 + case Int16: + return -1<<(16-1) <= x && x <= 1<<(16-1)-1 + case Int32, UntypedRune: + return -1<<(32-1) <= x && x <= 1<<(32-1)-1 + case Int64: + return true + case Uint: + return 0 <= x && x <= 1<<intBits-1 + case Uint8: + return 0 <= x && x <= 1<<8-1 + case Uint16: + return 0 <= x && x <= 1<<16-1 + case Uint32: + return 0 <= x && x <= 1<<32-1 + case Uint64: + return 0 <= x + case Uintptr: + assert(ptrBits == 64) + return 0 <= x + case Float32: + return true // TODO(gri) fix this + case Float64: + return true // TODO(gri) fix this + case Complex64: + return true // TODO(gri) fix this + case Complex128: + return true // TODO(gri) fix this + case UntypedInt, UntypedFloat, UntypedComplex: + return true + } + + case *big.Int: + switch as { + case Uint: + return x.Sign() >= 0 && x.BitLen() <= intBits + case Uint64: + return x.Sign() >= 0 && x.BitLen() <= 64 + case Uintptr: + return x.Sign() >= 0 && x.BitLen() <= ptrBits + case Float32: + return true // TODO(gri) fix this + case Float64: + return true // TODO(gri) fix this + case Complex64: + return true // TODO(gri) fix this + case Complex128: + return true // TODO(gri) fix this + case UntypedInt, UntypedFloat, UntypedComplex: + return true + } + + case *big.Rat: + switch as { + case Float32: + return true // TODO(gri) fix this + case Float64: + return true // TODO(gri) fix this + case Complex64: + return true // TODO(gri) fix this + case Complex128: + return true // TODO(gri) fix this + case UntypedFloat, UntypedComplex: + return true + } + + case complex: + switch as { + case Complex64: + return true // TODO(gri) fix this + case Complex128: + return true // TODO(gri) fix this + case UntypedComplex: + return true + } + + case string: + return as == String || as == UntypedString + + case nilType: + return as == UntypedNil + + default: + unreachable() + } + + return false +} + +var ( + int1 = big.NewInt(1) + rat0 = big.NewRat(0, 1) +) + +// complexity returns a measure of representation complexity for constant x. +func complexity(x interface{}) int { + switch x.(type) { + case bool, string, nilType: + return 1 + case int64: + return 2 + case *big.Int: + return 3 + case *big.Rat: + return 4 + case complex: + return 5 + } + unreachable() + return 0 +} + +// matchConst returns the matching representation (same type) with the +// smallest complexity for two constant values x and y. They must be +// of the same "kind" (boolean, numeric, string, or nilType). +// +func matchConst(x, y interface{}) (_, _ interface{}) { + if complexity(x) > complexity(y) { + y, x = matchConst(y, x) + return x, y + } + // complexity(x) <= complexity(y) + + switch x := x.(type) { + case bool, complex, string, nilType: + return x, y + + case int64: + switch y := y.(type) { + case int64: + return x, y + case *big.Int: + return big.NewInt(x), y + case *big.Rat: + return big.NewRat(x, 1), y + case complex: + return complex{big.NewRat(x, 1), rat0}, y + } + + case *big.Int: + switch y := y.(type) { + case *big.Int: + return x, y + case *big.Rat: + return new(big.Rat).SetFrac(x, int1), y + case complex: + return complex{new(big.Rat).SetFrac(x, int1), rat0}, y + } + + case *big.Rat: + switch y := y.(type) { + case *big.Rat: + return x, y + case complex: + return complex{x, rat0}, y + } + } + + unreachable() + return nil, nil +} + +// is32bit reports whether x can be represented using 32 bits. +func is32bit(x int64) bool { + return -1<<31 <= x && x <= 1<<31-1 +} + +// is63bit reports whether x can be represented using 63 bits. +func is63bit(x int64) bool { + return -1<<62 <= x && x <= 1<<62-1 +} + +// binaryOpConst returns the result of the constant evaluation x op y; +// both operands must be of the same "kind" (boolean, numeric, or string). +// If intDiv is true, division (op == token.QUO) is using integer division +// (and the result is guaranteed to be integer) rather than floating-point +// division. Division by zero leads to a run-time panic. +// +func binaryOpConst(x, y interface{}, op token.Token, intDiv bool) interface{} { + x, y = matchConst(x, y) + + switch x := x.(type) { + case bool: + y := y.(bool) + switch op { + case token.LAND: + return x && y + case token.LOR: + return x || y + default: + unreachable() + } + + case int64: + y := y.(int64) + switch op { + case token.ADD: + // TODO(gri) can do better than this + if is63bit(x) && is63bit(y) { + return x + y + } + return normalizeIntConst(new(big.Int).Add(big.NewInt(x), big.NewInt(y))) + case token.SUB: + // TODO(gri) can do better than this + if is63bit(x) && is63bit(y) { + return x - y + } + return normalizeIntConst(new(big.Int).Sub(big.NewInt(x), big.NewInt(y))) + case token.MUL: + // TODO(gri) can do better than this + if is32bit(x) && is32bit(y) { + return x * y + } + return normalizeIntConst(new(big.Int).Mul(big.NewInt(x), big.NewInt(y))) + case token.REM: + return x % y + case token.QUO: + if intDiv { + return x / y + } + return normalizeRatConst(new(big.Rat).SetFrac(big.NewInt(x), big.NewInt(y))) + case token.AND: + return x & y + case token.OR: + return x | y + case token.XOR: + return x ^ y + case token.AND_NOT: + return x &^ y + default: + unreachable() + } + + case *big.Int: + y := y.(*big.Int) + var z big.Int + switch op { + case token.ADD: + z.Add(x, y) + case token.SUB: + z.Sub(x, y) + case token.MUL: + z.Mul(x, y) + case token.REM: + z.Rem(x, y) + case token.QUO: + if intDiv { + z.Quo(x, y) + } else { + return normalizeRatConst(new(big.Rat).SetFrac(x, y)) + } + case token.AND: + z.And(x, y) + case token.OR: + z.Or(x, y) + case token.XOR: + z.Xor(x, y) + case token.AND_NOT: + z.AndNot(x, y) + default: + unreachable() + } + return normalizeIntConst(&z) + + case *big.Rat: + y := y.(*big.Rat) + var z big.Rat + switch op { + case token.ADD: + z.Add(x, y) + case token.SUB: + z.Sub(x, y) + case token.MUL: + z.Mul(x, y) + case token.QUO: + z.Quo(x, y) + default: + unreachable() + } + return normalizeRatConst(&z) + + case complex: + y := y.(complex) + a, b := x.re, x.im + c, d := y.re, y.im + var re, im big.Rat + switch op { + case token.ADD: + // (a+c) + i(b+d) + re.Add(a, c) + im.Add(b, d) + case token.SUB: + // (a-c) + i(b-d) + re.Sub(a, c) + im.Sub(b, d) + case token.MUL: + // (ac-bd) + i(bc+ad) + var ac, bd, bc, ad big.Rat + ac.Mul(a, c) + bd.Mul(b, d) + bc.Mul(b, c) + ad.Mul(a, d) + re.Sub(&ac, &bd) + im.Add(&bc, &ad) + case token.QUO: + // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd + var ac, bd, bc, ad, s big.Rat + ac.Mul(a, c) + bd.Mul(b, d) + bc.Mul(b, c) + ad.Mul(a, d) + s.Add(c.Mul(c, c), d.Mul(d, d)) + re.Add(&ac, &bd) + re.Quo(&re, &s) + im.Sub(&bc, &ad) + im.Quo(&im, &s) + default: + unreachable() + } + return normalizeComplexConst(complex{&re, &im}) + + case string: + if op == token.ADD { + return x + y.(string) + } + } + + unreachable() + return nil +} + +// shiftConst returns the result of the constant evaluation x op s +// where op is token.SHL or token.SHR (<< or >>). x must be an +// integer constant. +// +func shiftConst(x interface{}, s uint, op token.Token) interface{} { + switch x := x.(type) { + case int64: + switch op { + case token.SHL: + z := big.NewInt(x) + return normalizeIntConst(z.Lsh(z, s)) + case token.SHR: + return x >> s + } + + case *big.Int: + var z big.Int + switch op { + case token.SHL: + return normalizeIntConst(z.Lsh(x, s)) + case token.SHR: + return normalizeIntConst(z.Rsh(x, s)) + } + } + + unreachable() + return nil +} + +// compareConst returns the result of the constant comparison x op y; +// both operands must be of the same "kind" (boolean, numeric, string, +// or nilType). +// +func compareConst(x, y interface{}, op token.Token) (z bool) { + x, y = matchConst(x, y) + + // x == y => x == y + // x != y => x != y + // x > y => y < x + // x >= y => u <= x + swap := false + switch op { + case token.GTR: + swap = true + op = token.LSS + case token.GEQ: + swap = true + op = token.LEQ + } + + // x == y => x == y + // x != y => !(x == y) + // x < y => x < y + // x <= y => !(y < x) + negate := false + switch op { + case token.NEQ: + negate = true + op = token.EQL + case token.LEQ: + swap = !swap + negate = true + op = token.LSS + } + + if negate { + defer func() { z = !z }() + } + + if swap { + x, y = y, x + } + + switch x := x.(type) { + case bool: + if op == token.EQL { + return x == y.(bool) + } + + case int64: + y := y.(int64) + switch op { + case token.EQL: + return x == y + case token.LSS: + return x < y + } + + case *big.Int: + s := x.Cmp(y.(*big.Int)) + switch op { + case token.EQL: + return s == 0 + case token.LSS: + return s < 0 + } + + case *big.Rat: + s := x.Cmp(y.(*big.Rat)) + switch op { + case token.EQL: + return s == 0 + case token.LSS: + return s < 0 + } + + case complex: + y := y.(complex) + if op == token.EQL { + return x.re.Cmp(y.re) == 0 && x.im.Cmp(y.im) == 0 + } + + case string: + y := y.(string) + switch op { + case token.EQL: + return x == y + case token.LSS: + return x < y + } + + case nilType: + if op == token.EQL { + return x == y.(nilType) + } + } + + fmt.Printf("x = %s (%T), y = %s (%T)\n", x, x, y, y) + unreachable() + return +} diff --git a/libgo/go/exp/types/staging/conversions.go b/libgo/go/exp/types/staging/conversions.go new file mode 100644 index 0000000..ac4d59f --- /dev/null +++ b/libgo/go/exp/types/staging/conversions.go @@ -0,0 +1,39 @@ +// Copyright 2012 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. + +// This file implements typechecking of conversions. + +package types + +import ( + "go/ast" +) + +// conversion typechecks the type conversion conv to type typ. iota is the current +// value of iota or -1 if iota doesn't have a value in the current context. The result +// of the conversion is returned via x. If the conversion has type errors, the returned +// x is marked as invalid (x.mode == invalid). +// +func (check *checker) conversion(x *operand, conv *ast.CallExpr, typ Type, iota int) { + // all conversions have one argument + if len(conv.Args) != 1 { + check.invalidOp(conv.Pos(), "%s conversion requires exactly one argument", conv) + goto Error + } + + // evaluate argument + check.expr(x, conv.Args[0], nil, iota) + if x.mode == invalid { + goto Error + } + + // TODO(gri) fix this - implement all checks and constant evaluation + x.mode = value + x.expr = conv + x.typ = typ + return + +Error: + x.mode = invalid +} diff --git a/libgo/go/exp/types/staging/errors.go b/libgo/go/exp/types/staging/errors.go new file mode 100644 index 0000000..64ce25f --- /dev/null +++ b/libgo/go/exp/types/staging/errors.go @@ -0,0 +1,301 @@ +// Copyright 2012 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. + +// This file implements various error reporters. + +package types + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" +) + +// debugging flags +const debug = false +const trace = false + +// TODO(gri) eventually assert and unimplemented should disappear. +func assert(p bool) { + if !p { + panic("assertion failed") + } +} + +func unimplemented() { + if debug { + panic("unimplemented") + } +} + +func unreachable() { + panic("unreachable") +} + +func (check *checker) formatMsg(format string, args []interface{}) string { + for i, arg := range args { + switch a := arg.(type) { + case token.Pos: + args[i] = check.fset.Position(a) + case ast.Expr: + args[i] = exprString(a) + case Type: + args[i] = typeString(a) + case operand: + panic("internal error: should always pass *operand") + } + } + return fmt.Sprintf(format, args...) +} + +// dump is only needed for debugging +func (check *checker) dump(format string, args ...interface{}) { + fmt.Println(check.formatMsg(format, args)) +} + +func (check *checker) errorf(pos token.Pos, format string, args ...interface{}) { + msg := check.formatMsg(format, args) + if check.firsterr == nil { + check.firsterr = fmt.Errorf("%s: %s", check.fset.Position(pos), msg) + } + if check.errh == nil { + panic(bailout{}) // report only first error + } + check.errh(pos, msg) +} + +func (check *checker) invalidAST(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid AST: "+format, args...) +} + +func (check *checker) invalidArg(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid argument: "+format, args...) +} + +func (check *checker) invalidOp(pos token.Pos, format string, args ...interface{}) { + check.errorf(pos, "invalid operation: "+format, args...) +} + +// exprString returns a (simplified) string representation for an expression. +func exprString(expr ast.Expr) string { + var buf bytes.Buffer + writeExpr(&buf, expr) + return buf.String() +} + +// TODO(gri) Need to merge with typeString since some expressions are types (try: ([]int)(a)) +func writeExpr(buf *bytes.Buffer, expr ast.Expr) { + switch x := expr.(type) { + case *ast.Ident: + buf.WriteString(x.Name) + + case *ast.BasicLit: + buf.WriteString(x.Value) + + case *ast.FuncLit: + buf.WriteString("(func literal)") + + case *ast.CompositeLit: + buf.WriteString("(composite literal)") + + case *ast.ParenExpr: + buf.WriteByte('(') + writeExpr(buf, x.X) + buf.WriteByte(')') + + case *ast.SelectorExpr: + writeExpr(buf, x.X) + buf.WriteByte('.') + buf.WriteString(x.Sel.Name) + + case *ast.IndexExpr: + writeExpr(buf, x.X) + buf.WriteByte('[') + writeExpr(buf, x.Index) + buf.WriteByte(']') + + case *ast.SliceExpr: + writeExpr(buf, x.X) + buf.WriteByte('[') + if x.Low != nil { + writeExpr(buf, x.Low) + } + buf.WriteByte(':') + if x.High != nil { + writeExpr(buf, x.High) + } + buf.WriteByte(']') + + case *ast.TypeAssertExpr: + writeExpr(buf, x.X) + buf.WriteString(".(...)") + + case *ast.CallExpr: + writeExpr(buf, x.Fun) + buf.WriteByte('(') + for i, arg := range x.Args { + if i > 0 { + buf.WriteString(", ") + } + writeExpr(buf, arg) + } + buf.WriteByte(')') + + case *ast.StarExpr: + buf.WriteByte('*') + writeExpr(buf, x.X) + + case *ast.UnaryExpr: + buf.WriteString(x.Op.String()) + writeExpr(buf, x.X) + + case *ast.BinaryExpr: + // The AST preserves source-level parentheses so there is + // no need to introduce parentheses here for correctness. + writeExpr(buf, x.X) + buf.WriteByte(' ') + buf.WriteString(x.Op.String()) + buf.WriteByte(' ') + writeExpr(buf, x.Y) + + default: + fmt.Fprintf(buf, "<expr %T>", x) + } +} + +// typeString returns a string representation for typ. +func typeString(typ Type) string { + var buf bytes.Buffer + writeType(&buf, typ) + return buf.String() +} + +func writeParams(buf *bytes.Buffer, params ObjList, isVariadic bool) { + buf.WriteByte('(') + for i, par := range params { + if i > 0 { + buf.WriteString(", ") + } + if par.Name != "" { + buf.WriteString(par.Name) + buf.WriteByte(' ') + } + if isVariadic && i == len(params)-1 { + buf.WriteString("...") + } + writeType(buf, par.Type.(Type)) + } + buf.WriteByte(')') +} + +func writeSignature(buf *bytes.Buffer, sig *Signature) { + writeParams(buf, sig.Params, sig.IsVariadic) + if len(sig.Results) == 0 { + // no result + return + } + + buf.WriteByte(' ') + if len(sig.Results) == 1 && sig.Results[0].Name == "" { + // single unnamed result + writeType(buf, sig.Results[0].Type.(Type)) + return + } + + // multiple or named result(s) + writeParams(buf, sig.Results, false) +} + +func writeType(buf *bytes.Buffer, typ Type) { + switch t := typ.(type) { + case nil: + buf.WriteString("<nil>") + + case *Basic: + buf.WriteString(t.Name) + + case *Array: + fmt.Fprintf(buf, "[%d]", t.Len) + writeType(buf, t.Elt) + + case *Slice: + buf.WriteString("[]") + writeType(buf, t.Elt) + + case *Struct: + buf.WriteString("struct{") + for i, f := range t.Fields { + if i > 0 { + buf.WriteString("; ") + } + if !f.IsAnonymous { + buf.WriteString(f.Name) + buf.WriteByte(' ') + } + writeType(buf, f.Type) + if f.Tag != "" { + fmt.Fprintf(buf, " %q", f.Tag) + } + } + buf.WriteByte('}') + + case *Pointer: + buf.WriteByte('*') + writeType(buf, t.Base) + + case *tuple: + buf.WriteByte('(') + for i, typ := range t.list { + if i > 0 { + buf.WriteString("; ") + } + writeType(buf, typ) + } + buf.WriteByte(')') + + case *Signature: + buf.WriteString("func") + writeSignature(buf, t) + + case *builtin: + fmt.Fprintf(buf, "<type of %s>", t.name) + + case *Interface: + buf.WriteString("interface{") + for i, m := range t.Methods { + if i > 0 { + buf.WriteString("; ") + } + buf.WriteString(m.Name) + writeSignature(buf, m.Type.(*Signature)) + } + buf.WriteByte('}') + + case *Map: + buf.WriteString("map[") + writeType(buf, t.Key) + buf.WriteByte(']') + writeType(buf, t.Elt) + + case *Chan: + var s string + switch t.Dir { + case ast.SEND: + s = "chan<- " + case ast.RECV: + s = "<-chan " + default: + s = "chan " + } + buf.WriteString(s) + writeType(buf, t.Elt) + + case *NamedType: + buf.WriteString(t.Obj.Name) + + default: + fmt.Fprintf(buf, "<type %T>", t) + } +} diff --git a/libgo/go/exp/types/staging/exportdata.go b/libgo/go/exp/types/staging/exportdata.go new file mode 100644 index 0000000..2219015 --- /dev/null +++ b/libgo/go/exp/types/staging/exportdata.go @@ -0,0 +1,110 @@ +// Copyright 2011 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. + +// This file implements FindGcExportData. + +package types + +import ( + "bufio" + "errors" + "fmt" + "io" + "strconv" + "strings" +) + +func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { + // See $GOROOT/include/ar.h. + hdr := make([]byte, 16+12+6+6+8+10+2) + _, err = io.ReadFull(r, hdr) + if err != nil { + return + } + if trace { + fmt.Printf("header: %s", hdr) + } + s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) + size, err = strconv.Atoi(s) + if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { + err = errors.New("invalid archive header") + return + } + name = strings.TrimSpace(string(hdr[:16])) + return +} + +// FindGcExportData positions the reader r at the beginning of the +// export data section of an underlying GC-created object/archive +// file by reading from it. The reader must be positioned at the +// start of the file before calling this function. +// +func FindGcExportData(r *bufio.Reader) (err error) { + // Read first line to make sure this is an object file. + line, err := r.ReadSlice('\n') + if err != nil { + return + } + if string(line) == "!<arch>\n" { + // Archive file. Scan to __.PKGDEF, which should + // be second archive entry. + var name string + var size int + + // First entry should be __.GOSYMDEF. + // Older archives used __.SYMDEF, so allow that too. + // Read and discard. + if name, size, err = readGopackHeader(r); err != nil { + return + } + if name != "__.SYMDEF" && name != "__.GOSYMDEF" { + err = errors.New("go archive does not begin with __.SYMDEF or __.GOSYMDEF") + return + } + const block = 4096 + tmp := make([]byte, block) + for size > 0 { + n := size + if n > block { + n = block + } + if _, err = io.ReadFull(r, tmp[:n]); err != nil { + return + } + size -= n + } + + // Second entry should be __.PKGDEF. + if name, size, err = readGopackHeader(r); err != nil { + return + } + if name != "__.PKGDEF" { + err = errors.New("go archive is missing __.PKGDEF") + return + } + + // Read first line of __.PKGDEF data, so that line + // is once again the first line of the input. + if line, err = r.ReadSlice('\n'); err != nil { + return + } + } + + // Now at __.PKGDEF in archive or still at beginning of file. + // Either way, line should begin with "go object ". + if !strings.HasPrefix(string(line), "go object ") { + err = errors.New("not a go object file") + return + } + + // Skip over object header to export data. + // Begins after first line with $$. + for line[0] != '$' { + if line, err = r.ReadSlice('\n'); err != nil { + return + } + } + + return +} diff --git a/libgo/go/exp/types/staging/expr.go b/libgo/go/exp/types/staging/expr.go new file mode 100644 index 0000000..560b16c --- /dev/null +++ b/libgo/go/exp/types/staging/expr.go @@ -0,0 +1,867 @@ +// Copyright 2012 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. + +// This file implements typechecking of expressions. + +package types + +import ( + "go/ast" + "go/token" + "strconv" +) + +// TODO(gri) +// - don't print error messages referring to invalid types (they are likely spurious errors) +// - simplify invalid handling: maybe just use Typ[Invalid] as marker, get rid of invalid Mode for values? + +func (check *checker) tag(field *ast.Field) string { + if t := field.Tag; t != nil { + assert(t.Kind == token.STRING) + if tag, err := strconv.Unquote(t.Value); err == nil { + return tag + } + check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value) + } + return "" +} + +// collectFields collects interface methods (tok = token.INTERFACE), and function arguments/results (tok = token.FUNC). +func (check *checker) collectFields(tok token.Token, list *ast.FieldList, cycleOk bool) (fields ObjList, tags []string, isVariadic bool) { + if list != nil { + for _, field := range list.List { + ftype := field.Type + if t, ok := ftype.(*ast.Ellipsis); ok { + ftype = t.Elt + isVariadic = true + } + typ := check.typ(ftype, cycleOk) + tag := check.tag(field) + if len(field.Names) > 0 { + // named fields + for _, name := range field.Names { + obj := name.Obj + obj.Type = typ + fields = append(fields, obj) + if tok == token.STRUCT { + tags = append(tags, tag) + } + } + } else { + // anonymous field + switch tok { + case token.FUNC: + obj := ast.NewObj(ast.Var, "") + obj.Type = typ + fields = append(fields, obj) + case token.INTERFACE: + utyp := underlying(typ) + if typ, ok := utyp.(*Interface); ok { + // TODO(gri) This is not good enough. Check for double declarations! + fields = append(fields, typ.Methods...) + } else if utyp != Typ[Invalid] { + // if utyp is invalid, don't complain (the root cause was reported before) + check.errorf(ftype.Pos(), "interface contains embedded non-interface type") + } + default: + panic("unreachable") + } + } + } + } + return +} + +func (check *checker) collectStructFields(list *ast.FieldList, cycleOk bool) (fields []*StructField) { + if list == nil { + return + } + for _, f := range list.List { + typ := check.typ(f.Type, cycleOk) + tag := check.tag(f) + if len(f.Names) > 0 { + // named fields + for _, name := range f.Names { + fields = append(fields, &StructField{name.Name, typ, tag, false}) + } + } else { + // anonymous field + switch t := deref(typ).(type) { + case *Basic: + fields = append(fields, &StructField{t.Name, t, tag, true}) + case *NamedType: + fields = append(fields, &StructField{t.Obj.Name, t, tag, true}) + default: + if typ != Typ[Invalid] { + check.errorf(f.Type.Pos(), "invalid anonymous field type %s", typ) + } + } + } + } + return +} + +type opPredicates map[token.Token]func(Type) bool + +var unaryOpPredicates = opPredicates{ + token.ADD: isNumeric, + token.SUB: isNumeric, + token.XOR: isInteger, + token.NOT: isBoolean, + token.ARROW: func(typ Type) bool { t, ok := underlying(typ).(*Chan); return ok && t.Dir&ast.RECV != 0 }, +} + +func (check *checker) op(m opPredicates, x *operand, op token.Token) bool { + if pred := m[op]; pred != nil { + if !pred(x.typ) { + // TODO(gri) better error message for <-x where x is a send-only channel + // (<- is defined but not permitted). Special-case here or + // handle higher up. + check.invalidOp(x.pos(), "operator %s not defined for %s", op, x) + return false + } + } else { + check.invalidAST(x.pos(), "unknown operator %s", op) + return false + } + return true +} + +func (check *checker) unary(x *operand, op token.Token) { + if op == token.AND { + // TODO(gri) need to check for composite literals, somehow (they are not variables, in general) + if x.mode != variable { + check.invalidOp(x.pos(), "cannot take address of %s", x) + x.mode = invalid + return + } + x.typ = &Pointer{Base: x.typ} + return + } + + if !check.op(unaryOpPredicates, x, op) { + x.mode = invalid + return + } + + if x.mode == constant { + switch op { + case token.ADD: + // nothing to do + case token.SUB: + x.val = binaryOpConst(zeroConst, x.val, token.SUB, false) + case token.XOR: + x.val = binaryOpConst(minusOneConst, x.val, token.XOR, false) + case token.NOT: + x.val = !x.val.(bool) + default: + unreachable() + } + // Typed constants must be representable in + // their type after each constant operation. + check.isRepresentable(x, x.typ.(*Basic)) + return + } + + x.mode = value +} + +func isShift(op token.Token) bool { + return op == token.SHL || op == token.SHR +} + +func isComparison(op token.Token) bool { + // Note: tokens are not ordered well to make this much easier + switch op { + case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ: + return true + } + return false +} + +// isRepresentable checks that a constant operand is representable in the given type. +func (check *checker) isRepresentable(x *operand, typ *Basic) { + if x.mode != constant || isUntyped(typ) { + return + } + + if !isRepresentableConst(x.val, typ.Kind) { + var msg string + if isNumeric(x.typ) && isNumeric(typ) { + msg = "%s overflows %s" + } else { + msg = "cannot convert %s to %s" + } + check.errorf(x.pos(), msg, x, typ) + x.mode = invalid + } +} + +// convertUntyped attempts to set the type of an untyped value to the target type. +func (check *checker) convertUntyped(x *operand, target Type) { + if x.mode == invalid || !isUntyped(x.typ) { + return + } + + // TODO(gri) Sloppy code - clean up. This function is central + // to assignment and expression checking. + + if isUntyped(target) { + // both x and target are untyped + xkind := x.typ.(*Basic).Kind + tkind := target.(*Basic).Kind + if isNumeric(x.typ) && isNumeric(target) { + if xkind < tkind { + x.typ = target + } + } else if xkind != tkind { + check.errorf(x.pos(), "cannot convert %s to %s", x, target) + x.mode = invalid // avoid spurious errors + } + return + } + + // typed target + switch t := underlying(target).(type) { + case *Basic: + check.isRepresentable(x, t) + + case *Pointer, *Signature, *Interface, *Slice, *Map, *Chan: + if x.typ != Typ[UntypedNil] { + check.errorf(x.pos(), "cannot convert %s to %s", x, target) + x.mode = invalid + } + } + + x.typ = target +} + +func (check *checker) comparison(x, y *operand, op token.Token) { + // TODO(gri) deal with interface vs non-interface comparison + + valid := false + if x.isAssignable(y.typ) || y.isAssignable(x.typ) { + switch op { + case token.EQL, token.NEQ: + valid = isComparable(x.typ) + case token.LSS, token.LEQ, token.GTR, token.GEQ: + valid = isOrdered(y.typ) + default: + unreachable() + } + } + + if !valid { + check.invalidOp(x.pos(), "cannot compare %s and %s", x, y) + x.mode = invalid + return + } + + if x.mode == constant && y.mode == constant { + x.val = compareConst(x.val, y.val, op) + } else { + x.mode = value + } + + x.typ = Typ[UntypedBool] +} + +// untyped lhs shift operands convert to the hint type +// TODO(gri) shift hinting is not correct +func (check *checker) shift(x, y *operand, op token.Token, hint Type) { + // The right operand in a shift expression must have unsigned integer type + // or be an untyped constant that can be converted to unsigned integer type. + if y.mode == constant && isUntyped(y.typ) { + if isRepresentableConst(y.val, UntypedInt) { + y.typ = Typ[UntypedInt] + } + } + if !isInteger(y.typ) || !isUnsigned(y.typ) && !isUntyped(y.typ) { + check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y) + x.mode = invalid + return + } + + // If the left operand of a non-constant shift expression is an untyped + // constant, the type of the constant is what it would be if the shift + // expression were replaced by its left operand alone; the type is int + // if it cannot be determined from the context (for instance, if the + // shift expression is an operand in a comparison against an untyped + // constant) + if x.mode == constant && isUntyped(x.typ) { + if y.mode == constant { + // constant shift - accept values of any (untyped) type + // as long as the value is representable as an integer + if isRepresentableConst(x.val, UntypedInt) { + x.typ = Typ[UntypedInt] + } + } else { + // non-constant shift + if hint != nil { + check.convertUntyped(x, hint) + if x.mode == invalid { + return + } + } + } + } + + if !isInteger(x.typ) { + check.invalidOp(x.pos(), "shifted operand %s must be integer", x) + x.mode = invalid + return + } + + if y.mode == constant { + const stupidShift = 1024 + s, ok := y.val.(int64) + if !ok || s < 0 || s >= stupidShift { + check.invalidOp(y.pos(), "%s: stupid shift", y) + x.mode = invalid + return + } + if x.mode == constant { + x.val = shiftConst(x.val, uint(s), op) + return + } + x.mode = value + } + + // x.mode, x.Typ are unchanged +} + +var binaryOpPredicates = opPredicates{ + token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) }, + token.SUB: isNumeric, + token.MUL: isNumeric, + token.QUO: isNumeric, + token.REM: isInteger, + + token.AND: isInteger, + token.OR: isInteger, + token.XOR: isInteger, + token.AND_NOT: isInteger, + + token.LAND: isBoolean, + token.LOR: isBoolean, +} + +func (check *checker) binary(x, y *operand, op token.Token, hint Type) { + if isShift(op) { + check.shift(x, y, op, hint) + return + } + + check.convertUntyped(x, y.typ) + if x.mode == invalid { + return + } + check.convertUntyped(y, x.typ) + if y.mode == invalid { + x.mode = invalid + return + } + + if isComparison(op) { + check.comparison(x, y, op) + return + } + + if !isIdentical(x.typ, y.typ) { + check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ) + x.mode = invalid + return + } + + if !check.op(binaryOpPredicates, x, op) { + x.mode = invalid + return + } + + if (op == token.QUO || op == token.REM) && y.mode == constant && isZeroConst(y.val) { + check.invalidOp(y.pos(), "division by zero") + x.mode = invalid + return + } + + if x.mode == constant && y.mode == constant { + x.val = binaryOpConst(x.val, y.val, op, isInteger(x.typ)) + // Typed constants must be representable in + // their type after each constant operation. + check.isRepresentable(x, x.typ.(*Basic)) + return + } + + x.mode = value + // x.typ is unchanged +} + +// index checks an index expression for validity. If length >= 0, it is the upper +// bound for the index. The result is a valid constant index >= 0, or a negative +// value. +// +func (check *checker) index(index ast.Expr, length int64, iota int) int64 { + var x operand + var i int64 // index value, valid if >= 0 + + check.expr(&x, index, nil, iota) + if !x.isInteger() { + check.errorf(x.pos(), "index %s must be integer", &x) + return -1 + } + if x.mode != constant { + return -1 // we cannot check more + } + // x.mode == constant and the index value must be >= 0 + if isNegConst(x.val) { + check.errorf(x.pos(), "index %s must not be negative", &x) + return -1 + } + var ok bool + if i, ok = x.val.(int64); !ok { + // index value doesn't fit into an int64 + i = length // trigger out of bounds check below if we know length (>= 0) + } + + if length >= 0 && i >= length { + check.errorf(x.pos(), "index %s is out of bounds (>= %d)", &x, length) + return -1 + } + + return i +} + +func (check *checker) callRecord(x *operand) { + if x.mode != invalid { + check.mapf(x.expr, x.typ) + } +} + +// expr typechecks expression e and initializes x with the expression +// value or type. If an error occured, x.mode is set to invalid. +// A hint != nil is used as operand type for untyped shifted operands; +// iota >= 0 indicates that the expression is part of a constant declaration. +// cycleOk indicates whether it is ok for a type expression to refer to itself. +// +func (check *checker) exprOrType(x *operand, e ast.Expr, hint Type, iota int, cycleOk bool) { + if check.mapf != nil { + defer check.callRecord(x) + } + + switch e := e.(type) { + case *ast.BadExpr: + x.mode = invalid + + case *ast.Ident: + if e.Name == "_" { + check.invalidOp(e.Pos(), "cannot use _ as value or type") + goto Error + } + obj := e.Obj + if obj == nil { + // unresolved identifier (error has been reported before) + goto Error + } + check.ident(e, cycleOk) + switch obj.Kind { + case ast.Bad: + goto Error + case ast.Pkg: + check.errorf(e.Pos(), "use of package %s not in selector", obj.Name) + goto Error + case ast.Con: + if obj.Data == nil { + goto Error // cycle detected + } + x.mode = constant + if obj == universeIota { + if iota < 0 { + check.invalidAST(e.Pos(), "cannot use iota outside constant declaration") + goto Error + } + x.val = int64(iota) + } else { + x.val = obj.Data + } + case ast.Typ: + x.mode = typexpr + if !cycleOk && underlying(obj.Type.(Type)) == nil { + check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name) + x.expr = e + x.typ = Typ[Invalid] + return // don't goto Error - need x.mode == typexpr + } + case ast.Var: + x.mode = variable + case ast.Fun: + x.mode = value + default: + unreachable() + } + x.typ = obj.Type.(Type) + + case *ast.BasicLit: + x.setConst(e.Kind, e.Value) + if x.mode == invalid { + check.invalidAST(e.Pos(), "invalid literal %v", e.Value) + goto Error + } + + case *ast.FuncLit: + x.mode = value + x.typ = check.typ(e.Type, false) + check.stmt(e.Body) + + case *ast.CompositeLit: + // TODO(gri) + // - determine element type if nil + // - deal with map elements + for _, e := range e.Elts { + var x operand + check.expr(&x, e, hint, iota) + // TODO(gri) check assignment compatibility to element type + } + x.mode = value // TODO(gri) composite literals are addressable + + case *ast.ParenExpr: + check.exprOrType(x, e.X, hint, iota, cycleOk) + + case *ast.SelectorExpr: + // If the identifier refers to a package, handle everything here + // so we don't need a "package" mode for operands: package names + // can only appear in qualified identifiers which are mapped to + // selector expressions. + if ident, ok := e.X.(*ast.Ident); ok { + if obj := ident.Obj; obj != nil && obj.Kind == ast.Pkg { + exp := obj.Data.(*ast.Scope).Lookup(e.Sel.Name) + if exp == nil { + check.errorf(e.Sel.Pos(), "cannot refer to unexported %s", e.Sel.Name) + goto Error + } + // simplified version of the code for *ast.Idents: + // imported objects are always fully initialized + switch exp.Kind { + case ast.Con: + assert(exp.Data != nil) + x.mode = constant + x.val = exp.Data + case ast.Typ: + x.mode = typexpr + case ast.Var: + x.mode = variable + case ast.Fun: + x.mode = value + default: + unreachable() + } + x.expr = e + x.typ = exp.Type.(Type) + return + } + } + + // TODO(gri) lots of checks missing below - just raw outline + check.expr(x, e.X, hint, iota) + switch typ := x.typ.(type) { + case *Struct: + if fld := lookupField(typ, e.Sel.Name); fld != nil { + // TODO(gri) only variable if struct is variable + x.mode = variable + x.expr = e + x.typ = fld.Type + return + } + case *Interface: + unimplemented() + case *NamedType: + unimplemented() + } + check.invalidOp(e.Pos(), "%s has no field or method %s", x.typ, e.Sel.Name) + goto Error + + case *ast.IndexExpr: + check.expr(x, e.X, hint, iota) + + valid := false + length := int64(-1) // valid if >= 0 + switch typ := underlying(x.typ).(type) { + case *Basic: + if isString(typ) { + valid = true + if x.mode == constant { + length = int64(len(x.val.(string))) + } + // an indexed string always yields a byte value + // (not a constant) even if the string and the + // index are constant + x.mode = value + x.typ = Typ[Byte] + } + + case *Array: + valid = true + length = typ.Len + if x.mode != variable { + x.mode = value + } + x.typ = typ.Elt + + case *Slice: + valid = true + x.mode = variable + x.typ = typ.Elt + + case *Map: + // TODO(gri) check index type + x.mode = variable + x.typ = typ.Elt + return + } + + if !valid { + check.invalidOp(x.pos(), "cannot index %s", x) + goto Error + } + + if e.Index == nil { + check.invalidAST(e.Pos(), "missing index expression for %s", x) + return + } + + check.index(e.Index, length, iota) + // ok to continue + + case *ast.SliceExpr: + check.expr(x, e.X, hint, iota) + + valid := false + length := int64(-1) // valid if >= 0 + switch typ := underlying(x.typ).(type) { + case *Basic: + if isString(typ) { + valid = true + if x.mode == constant { + length = int64(len(x.val.(string))) + 1 // +1 for slice + } + // a sliced string always yields a string value + // of the same type as the original string (not + // a constant) even if the string and the indexes + // are constant + x.mode = value + // x.typ doesn't change + } + + case *Array: + valid = true + length = typ.Len + 1 // +1 for slice + if x.mode != variable { + check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x) + goto Error + } + x.typ = &Slice{Elt: typ.Elt} + + case *Slice: + valid = true + x.mode = variable + // x.typ doesn't change + } + + if !valid { + check.invalidOp(x.pos(), "cannot slice %s", x) + goto Error + } + + var lo int64 + if e.Low != nil { + lo = check.index(e.Low, length, iota) + } + + var hi int64 = length + if e.High != nil { + hi = check.index(e.High, length, iota) + } + + if hi >= 0 && lo > hi { + check.errorf(e.Low.Pos(), "inverted slice range: %d > %d", lo, hi) + // ok to continue + } + + case *ast.TypeAssertExpr: + check.expr(x, e.X, hint, iota) + if _, ok := x.typ.(*Interface); !ok { + check.invalidOp(e.X.Pos(), "non-interface type %s in type assertion", x.typ) + // ok to continue + } + // TODO(gri) some type asserts are compile-time decidable + x.mode = valueok + x.expr = e + x.typ = check.typ(e.Type, false) + + case *ast.CallExpr: + check.exprOrType(x, e.Fun, nil, iota, false) + if x.mode == typexpr { + check.conversion(x, e, x.typ, iota) + + } else if sig, ok := underlying(x.typ).(*Signature); ok { + // check parameters + // TODO(gri) complete this + // - deal with various forms of calls + // - handle variadic calls + if len(sig.Params) == len(e.Args) { + var z, x operand + z.mode = variable + for i, arg := range e.Args { + z.expr = nil // TODO(gri) can we do better here? + z.typ = sig.Params[i].Type.(Type) // TODO(gri) should become something like checkObj(&z, ...) eventually + check.expr(&x, arg, z.typ, iota) + if x.mode == invalid { + goto Error + } + check.assignOperand(&z, &x) + } + } + + // determine result + x.mode = value + if len(sig.Results) == 1 { + x.typ = sig.Results[0].Type.(Type) + } else { + // TODO(gri) change Signature representation to use tuples, + // then this conversion is not required + list := make([]Type, len(sig.Results)) + for i, obj := range sig.Results { + list[i] = obj.Type.(Type) + } + x.typ = &tuple{list: list} + } + + } else if bin, ok := x.typ.(*builtin); ok { + check.builtin(x, e, bin, iota) + + } else { + check.invalidOp(x.pos(), "cannot call non-function %s", x) + goto Error + } + + case *ast.StarExpr: + check.exprOrType(x, e.X, hint, iota, true) + switch x.mode { + case novalue: + check.errorf(x.pos(), "%s used as value or type", x) + goto Error + case typexpr: + x.typ = &Pointer{Base: x.typ} + default: + if typ, ok := x.typ.(*Pointer); ok { + x.mode = variable + x.typ = typ.Base + } else { + check.invalidOp(x.pos(), "cannot indirect %s", x) + goto Error + } + } + + case *ast.UnaryExpr: + check.expr(x, e.X, hint, iota) + check.unary(x, e.Op) + + case *ast.BinaryExpr: + var y operand + check.expr(x, e.X, hint, iota) + check.expr(&y, e.Y, hint, iota) + check.binary(x, &y, e.Op, hint) + + case *ast.KeyValueExpr: + unimplemented() + + case *ast.ArrayType: + if e.Len != nil { + check.expr(x, e.Len, nil, 0) + if x.mode == invalid { + goto Error + } + var n int64 = -1 + if x.mode == constant { + if i, ok := x.val.(int64); ok && i == int64(int(i)) { + n = i + } + } + if n < 0 { + check.errorf(e.Len.Pos(), "invalid array bound %s", e.Len) + // ok to continue + n = 0 + } + x.typ = &Array{Len: n, Elt: check.typ(e.Elt, cycleOk)} + } else { + x.typ = &Slice{Elt: check.typ(e.Elt, true)} + } + x.mode = typexpr + + case *ast.StructType: + x.mode = typexpr + x.typ = &Struct{Fields: check.collectStructFields(e.Fields, cycleOk)} + + case *ast.FuncType: + params, _, isVariadic := check.collectFields(token.FUNC, e.Params, true) + results, _, _ := check.collectFields(token.FUNC, e.Results, true) + x.mode = typexpr + x.typ = &Signature{Recv: nil, Params: params, Results: results, IsVariadic: isVariadic} + + case *ast.InterfaceType: + methods, _, _ := check.collectFields(token.INTERFACE, e.Methods, cycleOk) + methods.Sort() + x.mode = typexpr + x.typ = &Interface{Methods: methods} + + case *ast.MapType: + x.mode = typexpr + x.typ = &Map{Key: check.typ(e.Key, true), Elt: check.typ(e.Value, true)} + + case *ast.ChanType: + x.mode = typexpr + x.typ = &Chan{Dir: e.Dir, Elt: check.typ(e.Value, true)} + + default: + check.dump("e = %s", e) + unreachable() + } + + // everything went well + x.expr = e + return + +Error: + x.mode = invalid + x.expr = e +} + +// expr is like exprOrType but also checks that e represents a value (rather than a type). +func (check *checker) expr(x *operand, e ast.Expr, hint Type, iota int) { + check.exprOrType(x, e, hint, iota, false) + switch x.mode { + case novalue: + check.errorf(x.pos(), "%s used as value", x) + x.mode = invalid + case typexpr: + check.errorf(x.pos(), "%s is not an expression", x) + x.mode = invalid + } +} + +// typ is like exprOrType but also checks that e represents a type (rather than a value). +// If an error occured, the result is Typ[Invalid]. +// +func (check *checker) typ(e ast.Expr, cycleOk bool) Type { + var x operand + check.exprOrType(&x, e, nil, -1, cycleOk) + switch { + case x.mode == novalue: + check.errorf(x.pos(), "%s used as type", &x) + x.typ = Typ[Invalid] + case x.mode != typexpr: + check.errorf(x.pos(), "%s is not a type", &x) + x.typ = Typ[Invalid] + } + return x.typ +} diff --git a/libgo/go/exp/types/staging/gcimporter.go b/libgo/go/exp/types/staging/gcimporter.go new file mode 100644 index 0000000..b152387 --- /dev/null +++ b/libgo/go/exp/types/staging/gcimporter.go @@ -0,0 +1,889 @@ +// Copyright 2011 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. + +// This file implements an ast.Importer for gc-generated object files. +// TODO(gri) Eventually move this into a separate package outside types. + +package types + +import ( + "bufio" + "errors" + "fmt" + "go/ast" + "go/build" + "go/token" + "io" + "math/big" + "os" + "path/filepath" + "strconv" + "strings" + "text/scanner" +) + +var pkgExts = [...]string{".a", ".5", ".6", ".8"} + +// FindPkg returns the filename and unique package id for an import +// path based on package information provided by build.Import (using +// the build.Default build.Context). +// If no file was found, an empty filename is returned. +// +func FindPkg(path, srcDir string) (filename, id string) { + if len(path) == 0 { + return + } + + id = path + var noext string + switch { + default: + // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" + // Don't require the source files to be present. + bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) + if bp.PkgObj == "" { + return + } + noext = bp.PkgObj + if strings.HasSuffix(noext, ".a") { + noext = noext[:len(noext)-len(".a")] + } + + case build.IsLocalImport(path): + // "./x" -> "/this/directory/x.ext", "/this/directory/x" + noext = filepath.Join(srcDir, path) + id = noext + + case filepath.IsAbs(path): + // for completeness only - go/build.Import + // does not support absolute imports + // "/x" -> "/x.ext", "/x" + noext = path + } + + // try extensions + for _, ext := range pkgExts { + filename = noext + ext + if f, err := os.Stat(filename); err == nil && !f.IsDir() { + return + } + } + + filename = "" // not found + return +} + +// GcImportData imports a package by reading the gc-generated export data, +// adds the corresponding package object to the imports map indexed by id, +// and returns the object. +// +// The imports map must contains all packages already imported, and no map +// entry with id as the key must be present. The data reader position must +// be the beginning of the export data section. The filename is only used +// in error messages. +// +func GcImportData(imports map[string]*ast.Object, filename, id string, data *bufio.Reader) (pkg *ast.Object, err error) { + if trace { + fmt.Printf("importing %s (%s)\n", id, filename) + } + + // support for gcParser error handling + defer func() { + if r := recover(); r != nil { + err = r.(importError) // will re-panic if r is not an importError + } + }() + + var p gcParser + p.init(filename, id, data, imports) + pkg = p.parseExport() + + return +} + +// GcImport imports a gc-generated package given its import path, adds the +// corresponding package object to the imports map, and returns the object. +// Local import paths are interpreted relative to the current working directory. +// The imports map must contains all packages already imported. +// GcImport satisfies the ast.Importer signature. +// +func GcImport(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) { + if path == "unsafe" { + return Unsafe, nil + } + + srcDir, err := os.Getwd() + if err != nil { + return + } + filename, id := FindPkg(path, srcDir) + if filename == "" { + err = errors.New("can't find import: " + id) + return + } + + // Note: imports[id] may already contain a partially imported package. + // We must continue doing the full import here since we don't + // know if something is missing. + // TODO: There's no need to re-import a package if we know that we + // have done a full import before. At the moment we cannot + // tell from the available information in this function alone. + + // open file + f, err := os.Open(filename) + if err != nil { + return + } + defer func() { + f.Close() + if err != nil { + // Add file name to error. + err = fmt.Errorf("reading export data: %s: %v", filename, err) + } + }() + + buf := bufio.NewReader(f) + if err = FindGcExportData(buf); err != nil { + return + } + + pkg, err = GcImportData(imports, filename, id, buf) + + return +} + +// ---------------------------------------------------------------------------- +// gcParser + +// gcParser parses the exports inside a gc compiler-produced +// object/archive file and populates its scope with the results. +type gcParser struct { + scanner scanner.Scanner + tok rune // current token + lit string // literal string; only valid for Ident, Int, String tokens + id string // package id of imported package + imports map[string]*ast.Object // package id -> package object +} + +func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]*ast.Object) { + p.scanner.Init(src) + p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } + p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments + p.scanner.Whitespace = 1<<'\t' | 1<<' ' + p.scanner.Filename = filename // for good error messages + p.next() + p.id = id + p.imports = imports +} + +func (p *gcParser) next() { + p.tok = p.scanner.Scan() + switch p.tok { + case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·': + p.lit = p.scanner.TokenText() + default: + p.lit = "" + } + if trace { + fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit) + } +} + +// Declare inserts a named object of the given kind in scope. +func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object { + // the object may have been imported before - if it exists + // already in the respective package scope, return that object + if obj := scope.Lookup(name); obj != nil { + assert(obj.Kind == kind) + return obj + } + + // otherwise create a new object and insert it into the package scope + obj := ast.NewObj(kind, name) + if scope.Insert(obj) != nil { + p.errorf("already declared: %v %s", kind, obj.Name) + } + + // if the new type object is a named type it may be referred + // to before the underlying type is known - set it up + if kind == ast.Typ { + obj.Type = &NamedType{Obj: obj} + } + + return obj +} + +// ---------------------------------------------------------------------------- +// Error handling + +// Internal errors are boxed as importErrors. +type importError struct { + pos scanner.Position + err error +} + +func (e importError) Error() string { + return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) +} + +func (p *gcParser) error(err interface{}) { + if s, ok := err.(string); ok { + err = errors.New(s) + } + // panic with a runtime.Error if err is not an error + panic(importError{p.scanner.Pos(), err.(error)}) +} + +func (p *gcParser) errorf(format string, args ...interface{}) { + p.error(fmt.Sprintf(format, args...)) +} + +func (p *gcParser) expect(tok rune) string { + lit := p.lit + if p.tok != tok { + p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) + } + p.next() + return lit +} + +func (p *gcParser) expectSpecial(tok string) { + sep := 'x' // not white space + i := 0 + for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' { + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + i++ + } + if i < len(tok) { + p.errorf("expected %q, got %q", tok, tok[0:i]) + } +} + +func (p *gcParser) expectKeyword(keyword string) { + lit := p.expect(scanner.Ident) + if lit != keyword { + p.errorf("expected keyword %s, got %q", keyword, lit) + } +} + +// ---------------------------------------------------------------------------- +// Import declarations + +// ImportPath = string_lit . +// +func (p *gcParser) parsePkgId() *ast.Object { + id, err := strconv.Unquote(p.expect(scanner.String)) + if err != nil { + p.error(err) + } + + switch id { + case "": + // id == "" stands for the imported package id + // (only known at time of package installation) + id = p.id + case "unsafe": + // package unsafe is not in the imports map - handle explicitly + return Unsafe + } + + pkg := p.imports[id] + if pkg == nil { + pkg = ast.NewObj(ast.Pkg, "") + pkg.Data = ast.NewScope(nil) + p.imports[id] = pkg + } + + return pkg +} + +// dotIdentifier = ( ident | '·' ) { ident | int | '·' } . +func (p *gcParser) parseDotIdent() string { + ident := "" + if p.tok != scanner.Int { + sep := 'x' // not white space + for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' { + ident += p.lit + sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token + p.next() + } + } + if ident == "" { + p.expect(scanner.Ident) // use expect() for error handling + } + return ident +} + +// ExportedName = "@" ImportPath "." dotIdentifier . +// +func (p *gcParser) parseExportedName() (*ast.Object, string) { + p.expect('@') + pkg := p.parsePkgId() + p.expect('.') + name := p.parseDotIdent() + return pkg, name +} + +// ---------------------------------------------------------------------------- +// Types + +// BasicType = identifier . +// +func (p *gcParser) parseBasicType() Type { + id := p.expect(scanner.Ident) + obj := Universe.Lookup(id) + if obj == nil || obj.Kind != ast.Typ { + p.errorf("not a basic type: %s", id) + } + return obj.Type.(Type) +} + +// ArrayType = "[" int_lit "]" Type . +// +func (p *gcParser) parseArrayType() Type { + // "[" already consumed and lookahead known not to be "]" + lit := p.expect(scanner.Int) + p.expect(']') + elt := p.parseType() + n, err := strconv.ParseInt(lit, 10, 64) + if err != nil { + p.error(err) + } + return &Array{Len: n, Elt: elt} +} + +// MapType = "map" "[" Type "]" Type . +// +func (p *gcParser) parseMapType() Type { + p.expectKeyword("map") + p.expect('[') + key := p.parseType() + p.expect(']') + elt := p.parseType() + return &Map{Key: key, Elt: elt} +} + +// Name = identifier | "?" | ExportedName . +// +func (p *gcParser) parseName() (name string) { + switch p.tok { + case scanner.Ident: + name = p.lit + p.next() + case '?': + // anonymous + p.next() + case '@': + // exported name prefixed with package path + _, name = p.parseExportedName() + default: + p.error("name expected") + } + return +} + +// Field = Name Type [ string_lit ] . +// +func (p *gcParser) parseField() *StructField { + var f StructField + f.Name = p.parseName() + f.Type = p.parseType() + if p.tok == scanner.String { + f.Tag = p.expect(scanner.String) + } + if f.Name == "" { + // anonymous field - typ must be T or *T and T must be a type name + if typ, ok := deref(f.Type).(*NamedType); ok && typ.Obj != nil { + f.Name = typ.Obj.Name + } else { + p.errorf("anonymous field expected") + } + } + return &f +} + +// StructType = "struct" "{" [ FieldList ] "}" . +// FieldList = Field { ";" Field } . +// +func (p *gcParser) parseStructType() Type { + var fields []*StructField + + parseField := func() { + fields = append(fields, p.parseField()) + } + + p.expectKeyword("struct") + p.expect('{') + if p.tok != '}' { + parseField() + for p.tok == ';' { + p.next() + parseField() + } + } + p.expect('}') + + return &Struct{Fields: fields} +} + +// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] . +// +func (p *gcParser) parseParameter() (par *ast.Object, isVariadic bool) { + name := p.parseName() + if name == "" { + name = "_" // cannot access unnamed identifiers + } + if p.tok == '.' { + p.expectSpecial("...") + isVariadic = true + } + ptyp := p.parseType() + // ignore argument tag (e.g. "noescape") + if p.tok == scanner.String { + p.expect(scanner.String) + } + par = ast.NewObj(ast.Var, name) + par.Type = ptyp + return +} + +// Parameters = "(" [ ParameterList ] ")" . +// ParameterList = { Parameter "," } Parameter . +// +func (p *gcParser) parseParameters() (list []*ast.Object, isVariadic bool) { + parseParameter := func() { + par, variadic := p.parseParameter() + list = append(list, par) + if variadic { + if isVariadic { + p.error("... not on final argument") + } + isVariadic = true + } + } + + p.expect('(') + if p.tok != ')' { + parseParameter() + for p.tok == ',' { + p.next() + parseParameter() + } + } + p.expect(')') + + return +} + +// Signature = Parameters [ Result ] . +// Result = Type | Parameters . +// +func (p *gcParser) parseSignature() *Signature { + params, isVariadic := p.parseParameters() + + // optional result type + var results []*ast.Object + switch p.tok { + case scanner.Ident, '[', '*', '<', '@': + // single, unnamed result + result := ast.NewObj(ast.Var, "_") + result.Type = p.parseType() + results = []*ast.Object{result} + case '(': + // named or multiple result(s) + var variadic bool + results, variadic = p.parseParameters() + if variadic { + p.error("... not permitted on result type") + } + } + + return &Signature{Params: params, Results: results, IsVariadic: isVariadic} +} + +// InterfaceType = "interface" "{" [ MethodList ] "}" . +// MethodList = Method { ";" Method } . +// Method = Name Signature . +// +// (The methods of embedded interfaces are always "inlined" +// by the compiler and thus embedded interfaces are never +// visible in the export data.) +// +func (p *gcParser) parseInterfaceType() Type { + var methods ObjList + + parseMethod := func() { + obj := ast.NewObj(ast.Fun, p.parseName()) + obj.Type = p.parseSignature() + methods = append(methods, obj) + } + + p.expectKeyword("interface") + p.expect('{') + if p.tok != '}' { + parseMethod() + for p.tok == ';' { + p.next() + parseMethod() + } + } + p.expect('}') + + methods.Sort() + return &Interface{Methods: methods} +} + +// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type . +// +func (p *gcParser) parseChanType() Type { + dir := ast.SEND | ast.RECV + if p.tok == scanner.Ident { + p.expectKeyword("chan") + if p.tok == '<' { + p.expectSpecial("<-") + dir = ast.SEND + } + } else { + p.expectSpecial("<-") + p.expectKeyword("chan") + dir = ast.RECV + } + elt := p.parseType() + return &Chan{Dir: dir, Elt: elt} +} + +// Type = +// BasicType | TypeName | ArrayType | SliceType | StructType | +// PointerType | FuncType | InterfaceType | MapType | ChanType | +// "(" Type ")" . +// BasicType = ident . +// TypeName = ExportedName . +// SliceType = "[" "]" Type . +// PointerType = "*" Type . +// FuncType = "func" Signature . +// +func (p *gcParser) parseType() Type { + switch p.tok { + case scanner.Ident: + switch p.lit { + default: + return p.parseBasicType() + case "struct": + return p.parseStructType() + case "func": + // FuncType + p.next() + return p.parseSignature() + case "interface": + return p.parseInterfaceType() + case "map": + return p.parseMapType() + case "chan": + return p.parseChanType() + } + case '@': + // TypeName + pkg, name := p.parseExportedName() + return p.declare(pkg.Data.(*ast.Scope), ast.Typ, name).Type.(Type) + case '[': + p.next() // look ahead + if p.tok == ']' { + // SliceType + p.next() + return &Slice{Elt: p.parseType()} + } + return p.parseArrayType() + case '*': + // PointerType + p.next() + return &Pointer{Base: p.parseType()} + case '<': + return p.parseChanType() + case '(': + // "(" Type ")" + p.next() + typ := p.parseType() + p.expect(')') + return typ + } + p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit) + return nil +} + +// ---------------------------------------------------------------------------- +// Declarations + +// ImportDecl = "import" identifier string_lit . +// +func (p *gcParser) parseImportDecl() { + p.expectKeyword("import") + // The identifier has no semantic meaning in the import data. + // It exists so that error messages can print the real package + // name: binary.ByteOrder instead of "encoding/binary".ByteOrder. + name := p.expect(scanner.Ident) + pkg := p.parsePkgId() + assert(pkg.Name == "" || pkg.Name == name) + pkg.Name = name +} + +// int_lit = [ "+" | "-" ] { "0" ... "9" } . +// +func (p *gcParser) parseInt() (neg bool, val string) { + switch p.tok { + case '-': + neg = true + fallthrough + case '+': + p.next() + } + val = p.expect(scanner.Int) + return +} + +// number = int_lit [ "p" int_lit ] . +// +func (p *gcParser) parseNumber() (x operand) { + x.mode = constant + + // mantissa + neg, val := p.parseInt() + mant, ok := new(big.Int).SetString(val, 0) + assert(ok) + if neg { + mant.Neg(mant) + } + + if p.lit == "p" { + // exponent (base 2) + p.next() + neg, val = p.parseInt() + exp64, err := strconv.ParseUint(val, 10, 0) + if err != nil { + p.error(err) + } + exp := uint(exp64) + if neg { + denom := big.NewInt(1) + denom.Lsh(denom, exp) + x.typ = Typ[UntypedFloat] + x.val = normalizeRatConst(new(big.Rat).SetFrac(mant, denom)) + return + } + if exp > 0 { + mant.Lsh(mant, exp) + } + x.typ = Typ[UntypedFloat] + x.val = normalizeIntConst(mant) + return + } + + x.typ = Typ[UntypedInt] + x.val = normalizeIntConst(mant) + return +} + +// ConstDecl = "const" ExportedName [ Type ] "=" Literal . +// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . +// bool_lit = "true" | "false" . +// complex_lit = "(" float_lit "+" float_lit "i" ")" . +// rune_lit = "(" int_lit "+" int_lit ")" . +// string_lit = `"` { unicode_char } `"` . +// +func (p *gcParser) parseConstDecl() { + p.expectKeyword("const") + pkg, name := p.parseExportedName() + obj := p.declare(pkg.Data.(*ast.Scope), ast.Con, name) + var x operand + if p.tok != '=' { + obj.Type = p.parseType() + } + p.expect('=') + switch p.tok { + case scanner.Ident: + // bool_lit + if p.lit != "true" && p.lit != "false" { + p.error("expected true or false") + } + x.typ = Typ[UntypedBool] + x.val = p.lit == "true" + p.next() + + case '-', scanner.Int: + // int_lit + x = p.parseNumber() + + case '(': + // complex_lit or rune_lit + p.next() + if p.tok == scanner.Char { + p.next() + p.expect('+') + x = p.parseNumber() + x.typ = Typ[UntypedRune] + p.expect(')') + break + } + re := p.parseNumber() + p.expect('+') + im := p.parseNumber() + p.expectKeyword("i") + p.expect(')') + x.typ = Typ[UntypedComplex] + // TODO(gri) fix this + _, _ = re, im + x.val = zeroConst + + case scanner.Char: + // rune_lit + x.setConst(token.CHAR, p.lit) + p.next() + + case scanner.String: + // string_lit + x.setConst(token.STRING, p.lit) + p.next() + + default: + p.errorf("expected literal got %s", scanner.TokenString(p.tok)) + } + if obj.Type == nil { + obj.Type = x.typ + } + assert(x.val != nil) + obj.Data = x.val +} + +// TypeDecl = "type" ExportedName Type . +// +func (p *gcParser) parseTypeDecl() { + p.expectKeyword("type") + pkg, name := p.parseExportedName() + obj := p.declare(pkg.Data.(*ast.Scope), ast.Typ, name) + + // The type object may have been imported before and thus already + // have a type associated with it. We still need to parse the type + // structure, but throw it away if the object already has a type. + // This ensures that all imports refer to the same type object for + // a given type declaration. + typ := p.parseType() + + if name := obj.Type.(*NamedType); name.Underlying == nil { + name.Underlying = typ + } +} + +// VarDecl = "var" ExportedName Type . +// +func (p *gcParser) parseVarDecl() { + p.expectKeyword("var") + pkg, name := p.parseExportedName() + obj := p.declare(pkg.Data.(*ast.Scope), ast.Var, name) + obj.Type = p.parseType() +} + +// FuncBody = "{" ... "}" . +// +func (p *gcParser) parseFuncBody() { + p.expect('{') + for i := 1; i > 0; p.next() { + switch p.tok { + case '{': + i++ + case '}': + i-- + } + } +} + +// FuncDecl = "func" ExportedName Signature [ FuncBody ] . +// +func (p *gcParser) parseFuncDecl() { + // "func" already consumed + pkg, name := p.parseExportedName() + obj := p.declare(pkg.Data.(*ast.Scope), ast.Fun, name) + obj.Type = p.parseSignature() + if p.tok == '{' { + p.parseFuncBody() + } +} + +// MethodDecl = "func" Receiver Name Signature . +// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ]. +// +func (p *gcParser) parseMethodDecl() { + // "func" already consumed + p.expect('(') + p.parseParameter() // receiver + p.expect(')') + p.parseName() // unexported method names in imports are qualified with their package. + p.parseSignature() + if p.tok == '{' { + p.parseFuncBody() + } +} + +// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" . +// +func (p *gcParser) parseDecl() { + switch p.lit { + case "import": + p.parseImportDecl() + case "const": + p.parseConstDecl() + case "type": + p.parseTypeDecl() + case "var": + p.parseVarDecl() + case "func": + p.next() // look ahead + if p.tok == '(' { + p.parseMethodDecl() + } else { + p.parseFuncDecl() + } + } + p.expect('\n') +} + +// ---------------------------------------------------------------------------- +// Export + +// Export = "PackageClause { Decl } "$$" . +// PackageClause = "package" identifier [ "safe" ] "\n" . +// +func (p *gcParser) parseExport() *ast.Object { + p.expectKeyword("package") + name := p.expect(scanner.Ident) + if p.tok != '\n' { + // A package is safe if it was compiled with the -u flag, + // which disables the unsafe package. + // TODO(gri) remember "safe" package + p.expectKeyword("safe") + } + p.expect('\n') + + pkg := p.imports[p.id] + if pkg == nil { + pkg = ast.NewObj(ast.Pkg, name) + pkg.Data = ast.NewScope(nil) + p.imports[p.id] = pkg + } + + for p.tok != '$' && p.tok != scanner.EOF { + p.parseDecl() + } + + if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { + // don't call next()/expect() since reading past the + // export data may cause scanner errors (e.g. NUL chars) + p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) + } + + if n := p.scanner.ErrorCount; n != 0 { + p.errorf("expected no scanner errors, got %d", n) + } + + return pkg +} diff --git a/libgo/go/exp/types/staging/gcimporter_test.go b/libgo/go/exp/types/staging/gcimporter_test.go new file mode 100644 index 0000000..2f89d3a --- /dev/null +++ b/libgo/go/exp/types/staging/gcimporter_test.go @@ -0,0 +1,153 @@ +// Copyright 2011 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 types + +import ( + "go/ast" + "go/build" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +var gcPath string // Go compiler path + +func init() { + // determine compiler + var gc string + switch runtime.GOARCH { + case "386": + gc = "8g" + case "amd64": + gc = "6g" + case "arm": + gc = "5g" + default: + gcPath = "unknown-GOARCH-compiler" + return + } + gcPath = filepath.Join(build.ToolDir, gc) +} + +func compile(t *testing.T, dirname, filename string) string { + cmd := exec.Command(gcPath, filename) + cmd.Dir = dirname + out, err := cmd.CombinedOutput() + if err != nil { + t.Logf("%s", out) + t.Fatalf("%s %s failed: %s", gcPath, filename, err) + } + archCh, _ := build.ArchChar(runtime.GOARCH) + // filename should end with ".go" + return filepath.Join(dirname, filename[:len(filename)-2]+archCh) +} + +// Use the same global imports map for all tests. The effect is +// as if all tested packages were imported into a single package. +var imports = make(map[string]*ast.Object) + +func testPath(t *testing.T, path string) bool { + _, err := GcImport(imports, path) + if err != nil { + t.Errorf("testPath(%s): %s", path, err) + return false + } + return true +} + +const maxTime = 3 * time.Second + +func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) { + dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir) + list, err := ioutil.ReadDir(dirname) + if err != nil { + t.Errorf("testDir(%s): %s", dirname, err) + } + for _, f := range list { + if time.Now().After(endTime) { + t.Log("testing time used up") + return + } + switch { + case !f.IsDir(): + // try extensions + for _, ext := range pkgExts { + if strings.HasSuffix(f.Name(), ext) { + name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension + if testPath(t, filepath.Join(dir, name)) { + nimports++ + } + } + } + case f.IsDir(): + nimports += testDir(t, filepath.Join(dir, f.Name()), endTime) + } + } + return +} + +func TestGcImport(t *testing.T) { + // On cross-compile builds, the path will not exist. + // Need to use GOHOSTOS, which is not available. + if _, err := os.Stat(gcPath); err != nil { + t.Logf("skipping test: %v", err) + return + } + + if outFn := compile(t, "testdata", "exports.go"); outFn != "" { + defer os.Remove(outFn) + } + + nimports := 0 + if testPath(t, "./testdata/exports") { + nimports++ + } + nimports += testDir(t, "", time.Now().Add(maxTime)) // installed packages + t.Logf("tested %d imports", nimports) +} + +var importedObjectTests = []struct { + name string + kind ast.ObjKind + typ string +}{ + {"unsafe.Pointer", ast.Typ, "Pointer"}, + {"math.Pi", ast.Con, "untyped float"}, + {"io.Reader", ast.Typ, "interface{Read(p []byte) (n int, err error)}"}, + {"io.ReadWriter", ast.Typ, "interface{Read(p []byte) (n int, err error); Write(p []byte) (n int, err error)}"}, + {"math.Sin", ast.Fun, "func(x float64) (_ float64)"}, + // TODO(gri) add more tests +} + +func TestGcImportedTypes(t *testing.T) { + for _, test := range importedObjectTests { + s := strings.Split(test.name, ".") + if len(s) != 2 { + t.Fatal("inconsistent test data") + } + importPath := s[0] + objName := s[1] + + pkg, err := GcImport(imports, importPath) + if err != nil { + t.Error(err) + continue + } + + obj := pkg.Data.(*ast.Scope).Lookup(objName) + if obj.Kind != test.kind { + t.Errorf("%s: got kind = %q; want %q", test.name, obj.Kind, test.kind) + } + typ := typeString(underlying(obj.Type.(Type))) + if typ != test.typ { + t.Errorf("%s: got type = %q; want %q", test.name, typ, test.typ) + } + } +} diff --git a/libgo/go/exp/types/staging/operand.go b/libgo/go/exp/types/staging/operand.go new file mode 100644 index 0000000..f2440c2 --- /dev/null +++ b/libgo/go/exp/types/staging/operand.go @@ -0,0 +1,201 @@ +// Copyright 2012 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. + +// This file defines operands and associated operations. + +package types + +import ( + "bytes" + "fmt" + "go/ast" + "go/token" +) + +// An operandMode specifies the (addressing) mode of an operand. +type operandMode int + +const ( + invalid operandMode = iota // operand is invalid (due to an earlier error) - ignore + novalue // operand represents no value (result of a function call w/o result) + typexpr // operand is a type + constant // operand is a constant; the operand's typ is a Basic type + variable // operand is an addressable variable + value // operand is a computed value + valueok // like mode == value, but operand may be used in a comma,ok expression +) + +var operandModeString = [...]string{ + invalid: "invalid", + novalue: "no value", + typexpr: "type", + constant: "constant", + variable: "variable", + value: "value", + valueok: "value,ok", +} + +// An operand represents an intermediate value during type checking. +// Operands have an (addressing) mode, the expression evaluating to +// the operand, the operand's type, and for constants a constant value. +// +type operand struct { + mode operandMode + expr ast.Expr + typ Type + val interface{} +} + +// pos returns the position of the expression corresponding to x. +// If x is invalid the position is token.NoPos. +// +func (x *operand) pos() token.Pos { + // x.expr may not be set if x is invalid + if x.expr == nil { + return token.NoPos + } + return x.expr.Pos() +} + +func (x *operand) String() string { + if x.mode == invalid { + return "invalid operand" + } + var buf bytes.Buffer + if x.expr != nil { + buf.WriteString(exprString(x.expr)) + buf.WriteString(" (") + } + buf.WriteString(operandModeString[x.mode]) + if x.mode == constant { + fmt.Fprintf(&buf, " %v", x.val) + } + if x.mode != novalue && (x.mode != constant || !isUntyped(x.typ)) { + fmt.Fprintf(&buf, " of type %s", typeString(x.typ)) + } + if x.expr != nil { + buf.WriteByte(')') + } + return buf.String() +} + +// setConst sets x to the untyped constant for literal lit. +func (x *operand) setConst(tok token.Token, lit string) { + x.mode = invalid + + var kind BasicKind + var val interface{} + switch tok { + case token.INT: + kind = UntypedInt + val = makeIntConst(lit) + + case token.FLOAT: + kind = UntypedFloat + val = makeFloatConst(lit) + + case token.IMAG: + kind = UntypedComplex + val = makeComplexConst(lit) + + case token.CHAR: + kind = UntypedRune + val = makeRuneConst(lit) + + case token.STRING: + kind = UntypedString + val = makeStringConst(lit) + } + + if val != nil { + x.mode = constant + x.typ = Typ[kind] + x.val = val + } +} + +// implements reports whether x implements interface T. +func (x *operand) implements(T *Interface) bool { + if x.mode == invalid { + return true // avoid spurious errors + } + + unimplemented() + return true +} + +// isAssignable reports whether x is assignable to a variable of type T. +func (x *operand) isAssignable(T Type) bool { + if x.mode == invalid || T == Typ[Invalid] { + return true // avoid spurious errors + } + + V := x.typ + + // x's type is identical to T + if isIdentical(V, T) { + return true + } + + Vu := underlying(V) + Tu := underlying(T) + + // x's type V and T have identical underlying types + // and at least one of V or T is not a named type + if isIdentical(Vu, Tu) { + return !isNamed(V) || !isNamed(T) + } + + // T is an interface type and x implements T + if Ti, ok := Tu.(*Interface); ok && x.implements(Ti) { + return true + } + + // x is a bidirectional channel value, T is a channel + // type, x's type V and T have identical element types, + // and at least one of V or T is not a named type + if Vc, ok := Vu.(*Chan); ok && Vc.Dir == ast.SEND|ast.RECV { + if Tc, ok := Tu.(*Chan); ok && isIdentical(Vc.Elt, Tc.Elt) { + return !isNamed(V) || !isNamed(T) + } + } + + // x is the predeclared identifier nil and T is a pointer, + // function, slice, map, channel, or interface type + if x.typ == Typ[UntypedNil] { + switch Tu.(type) { + case *Pointer, *Signature, *Slice, *Map, *Chan, *Interface: + return true + } + return false + } + + // x is an untyped constant representable by a value of type T + // - this is taken care of in the assignment check + // TODO(gri) double-check - isAssignable is used elsewhere + + return false +} + +// isInteger reports whether x is a (typed or untyped) integer value. +func (x *operand) isInteger() bool { + return x.mode == invalid || + isInteger(x.typ) || + x.mode == constant && isRepresentableConst(x.val, UntypedInt) +} + +// lookupField returns the struct field with the given name in typ. +// If no such field exists, the result is nil. +// TODO(gri) should this be a method of Struct? +// +func lookupField(typ *Struct, name string) *StructField { + // TODO(gri) deal with embedding and conflicts - this is + // a very basic version to get going for now. + for _, f := range typ.Fields { + if f.Name == name { + return f + } + } + return nil +} diff --git a/libgo/go/exp/types/staging/predicates.go b/libgo/go/exp/types/staging/predicates.go new file mode 100644 index 0000000..35fcf85 --- /dev/null +++ b/libgo/go/exp/types/staging/predicates.go @@ -0,0 +1,236 @@ +// Copyright 2012 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. + +// This file implements commonly used type predicates. + +package types + +func isNamed(typ Type) bool { + if _, ok := typ.(*Basic); ok { + return ok + } + _, ok := typ.(*NamedType) + return ok +} + +func isBoolean(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsBoolean != 0 +} + +func isInteger(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsInteger != 0 +} + +func isUnsigned(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsUnsigned != 0 +} + +func isFloat(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsFloat != 0 +} + +func isComplex(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsComplex != 0 +} + +func isNumeric(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsNumeric != 0 +} + +func isString(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsString != 0 +} + +func isUntyped(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsUntyped != 0 +} + +func isOrdered(typ Type) bool { + t, ok := underlying(typ).(*Basic) + return ok && t.Info&IsOrdered != 0 +} + +func isComparable(typ Type) bool { + switch t := underlying(typ).(type) { + case *Basic: + return t.Kind != Invalid + case *Pointer, *Chan, *Interface: + // assumes types are equal for pointers and channels + return true + case *Struct: + for _, f := range t.Fields { + if !isComparable(f.Type) { + return false + } + } + return true + case *Array: + return isComparable(t.Elt) + } + return false +} + +// identical returns true if x and y are identical. +func isIdentical(x, y Type) bool { + if x == y { + return true + } + + switch x := x.(type) { + case *Basic: + // Basic types are singletons except for the rune and byte + // aliases, thus we cannot solely rely on the x == y check + // above. + if y, ok := y.(*Basic); ok { + return x.Kind == y.Kind + } + + case *Array: + // Two array types are identical if they have identical element types + // and the same array length. + if y, ok := y.(*Array); ok { + return x.Len == y.Len && isIdentical(x.Elt, y.Elt) + } + + case *Slice: + // Two slice types are identical if they have identical element types. + if y, ok := y.(*Slice); ok { + return isIdentical(x.Elt, y.Elt) + } + + case *Struct: + // Two struct types are identical if they have the same sequence of fields, + // and if corresponding fields have the same names, and identical types, + // and identical tags. Two anonymous fields are considered to have the same + // name. Lower-case field names from different packages are always different. + if y, ok := y.(*Struct); ok { + // TODO(gri) handle structs from different packages + if len(x.Fields) == len(y.Fields) { + for i, f := range x.Fields { + g := y.Fields[i] + if f.Name != g.Name || + !isIdentical(f.Type, g.Type) || + f.Tag != g.Tag || + f.IsAnonymous != g.IsAnonymous { + return false + } + } + return true + } + } + + case *Pointer: + // Two pointer types are identical if they have identical base types. + if y, ok := y.(*Pointer); ok { + return isIdentical(x.Base, y.Base) + } + + case *Signature: + // Two function types are identical if they have the same number of parameters + // and result values, corresponding parameter and result types are identical, + // and either both functions are variadic or neither is. Parameter and result + // names are not required to match. + if y, ok := y.(*Signature); ok { + return identicalTypes(x.Params, y.Params) && + identicalTypes(x.Results, y.Results) && + x.IsVariadic == y.IsVariadic + } + + case *Interface: + // Two interface types are identical if they have the same set of methods with + // the same names and identical function types. Lower-case method names from + // different packages are always different. The order of the methods is irrelevant. + if y, ok := y.(*Interface); ok { + return identicalTypes(x.Methods, y.Methods) // methods are sorted + } + + case *Map: + // Two map types are identical if they have identical key and value types. + if y, ok := y.(*Map); ok { + return isIdentical(x.Key, y.Key) && isIdentical(x.Elt, y.Elt) + } + + case *Chan: + // Two channel types are identical if they have identical value types + // and the same direction. + if y, ok := y.(*Chan); ok { + return x.Dir == y.Dir && isIdentical(x.Elt, y.Elt) + } + + case *NamedType: + // Two named types are identical if their type names originate + // in the same type declaration. + if y, ok := y.(*NamedType); ok { + return x.Obj == y.Obj + } + } + + return false +} + +// identicalTypes returns true if both lists a and b have the +// same length and corresponding objects have identical types. +func identicalTypes(a, b ObjList) bool { + if len(a) == len(b) { + for i, x := range a { + y := b[i] + if !isIdentical(x.Type.(Type), y.Type.(Type)) { + return false + } + } + return true + } + return false +} + +// underlying returns the underlying type of typ. +func underlying(typ Type) Type { + // Basic types are representing themselves directly even though they are named. + if typ, ok := typ.(*NamedType); ok { + return typ.Underlying // underlying types are never NamedTypes + } + return typ +} + +// deref returns a pointer's base type; otherwise it returns typ. +func deref(typ Type) Type { + if typ, ok := underlying(typ).(*Pointer); ok { + return typ.Base + } + return typ +} + +// defaultType returns the default "typed" type for an "untyped" type; +// it returns the argument typ for all other types. +func defaultType(typ Type) Type { + if t, ok := typ.(*Basic); ok { + var k BasicKind + switch t.Kind { + case UntypedBool: + k = Bool + case UntypedRune: + k = Rune + case UntypedInt: + k = Int + case UntypedFloat: + k = Float64 + case UntypedComplex: + k = Complex128 + case UntypedString: + k = String + default: + unreachable() + } + typ = Typ[k] + } + return typ +} diff --git a/libgo/go/exp/types/staging/resolver_test.go b/libgo/go/exp/types/staging/resolver_test.go new file mode 100644 index 0000000..4e9aa09 --- /dev/null +++ b/libgo/go/exp/types/staging/resolver_test.go @@ -0,0 +1,130 @@ +// Copyright 2011 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 types + +import ( + "fmt" + "go/ast" + "go/parser" + "go/scanner" + "go/token" + "testing" +) + +var sources = []string{ + `package p + import "fmt" + import "math" + const pi = math.Pi + func sin(x float64) float64 { + return math.Sin(x) + } + var Println = fmt.Println + `, + `package p + import "fmt" + func f() string { + return fmt.Sprintf("%d", g()) + } + `, + `package p + import . "go/parser" + func g() Mode { return ImportsOnly }`, +} + +var pkgnames = []string{ + "fmt", + "go/parser", + "math", +} + +// ResolveQualifiedIdents resolves the selectors of qualified +// identifiers by associating the correct ast.Object with them. +// TODO(gri): Eventually, this functionality should be subsumed +// by Check. +// +func ResolveQualifiedIdents(fset *token.FileSet, pkg *ast.Package) error { + var errors scanner.ErrorList + + findObj := func(pkg *ast.Object, name *ast.Ident) *ast.Object { + scope := pkg.Data.(*ast.Scope) + obj := scope.Lookup(name.Name) + if obj == nil { + errors.Add(fset.Position(name.Pos()), fmt.Sprintf("no %s in package %s", name.Name, pkg.Name)) + } + return obj + } + + ast.Inspect(pkg, func(n ast.Node) bool { + if s, ok := n.(*ast.SelectorExpr); ok { + if x, ok := s.X.(*ast.Ident); ok && x.Obj != nil && x.Obj.Kind == ast.Pkg { + // find selector in respective package + s.Sel.Obj = findObj(x.Obj, s.Sel) + } + return false + } + return true + }) + + return errors.Err() +} + +func TestResolveQualifiedIdents(t *testing.T) { + // parse package files + fset := token.NewFileSet() + files := make(map[string]*ast.File) + for i, src := range sources { + filename := fmt.Sprintf("file%d", i) + f, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) + if err != nil { + t.Fatal(err) + } + files[filename] = f + } + + // resolve package AST + pkg, err := ast.NewPackage(fset, files, GcImport, Universe) + if err != nil { + t.Fatal(err) + } + + // check that all packages were imported + for _, name := range pkgnames { + if pkg.Imports[name] == nil { + t.Errorf("package %s not imported", name) + } + } + + // check that there are no top-level unresolved identifiers + for _, f := range pkg.Files { + for _, x := range f.Unresolved { + t.Errorf("%s: unresolved global identifier %s", fset.Position(x.Pos()), x.Name) + } + } + + // resolve qualified identifiers + if err := ResolveQualifiedIdents(fset, pkg); err != nil { + t.Error(err) + } + + // check that qualified identifiers are resolved + ast.Inspect(pkg, func(n ast.Node) bool { + if s, ok := n.(*ast.SelectorExpr); ok { + if x, ok := s.X.(*ast.Ident); ok { + if x.Obj == nil { + t.Errorf("%s: unresolved qualified identifier %s", fset.Position(x.Pos()), x.Name) + return false + } + if x.Obj.Kind == ast.Pkg && s.Sel != nil && s.Sel.Obj == nil { + t.Errorf("%s: unresolved selector %s", fset.Position(s.Sel.Pos()), s.Sel.Name) + return false + } + return false + } + return false + } + return true + }) +} diff --git a/libgo/go/exp/types/staging/stmt.go b/libgo/go/exp/types/staging/stmt.go new file mode 100644 index 0000000..be5caa1 --- /dev/null +++ b/libgo/go/exp/types/staging/stmt.go @@ -0,0 +1,473 @@ +// Copyright 2012 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. + +// This file implements typechecking of statements. + +package types + +import ( + "go/ast" + "go/token" +) + +func (check *checker) assignOperand(z, x *operand) { + if t, ok := x.typ.(*tuple); ok { + // TODO(gri) elsewhere we use "assignment count mismatch" (consolidate) + check.errorf(x.pos(), "%d-valued expression %s used as single value", len(t.list), x) + x.mode = invalid + return + } + + check.convertUntyped(x, z.typ) + + if !x.isAssignable(z.typ) { + check.errorf(x.pos(), "cannot assign %s to %s", x, z) + x.mode = invalid + } +} + +// assignment typechecks a single assignment of the form lhs := x. If decl is set, +// the lhs operand must be an identifier. If its type is not set, it is deduced +// from the type or value of x. +// +func (check *checker) assignment(lhs ast.Expr, x *operand, decl bool) { + if decl { + ident, ok := lhs.(*ast.Ident) + if !ok { + check.errorf(lhs.Pos(), "cannot declare %s", lhs) + return + } + + obj := ident.Obj + if obj.Type == nil { + // determine type from rhs expression + var typ Type = Typ[Invalid] + if x.mode != invalid { + typ = x.typ + // determine the default type for variables + if obj.Kind == ast.Var && isUntyped(typ) { + typ = defaultType(typ) + } + } + obj.Type = typ + } + + var z operand + switch obj.Kind { + case ast.Con: + z.mode = constant + case ast.Var: + z.mode = variable + default: + unreachable() + } + z.expr = ident + z.typ = obj.Type.(Type) + + check.assignOperand(&z, x) + + // for constants, set the constant value + if obj.Kind == ast.Con { + assert(obj.Data == nil) + if x.mode != invalid && x.mode != constant { + check.errorf(x.pos(), "%s is not constant", x) // TODO(gri) better error position + x.mode = invalid + } + if x.mode == constant { + obj.Data = x.val + } else { + // set the constant to the type's zero value to reduce spurious errors + // TODO(gri) factor this out - useful elsewhere + switch typ := underlying(obj.Type.(Type)); { + case typ == Typ[Invalid]: + // ignore + case isBoolean(typ): + obj.Data = false + case isNumeric(typ): + obj.Data = int64(0) + case isString(typ): + obj.Data = "" + default: + check.dump("%s: typ(%s) = %s", obj.Pos(), obj.Name, typ) + unreachable() + } + } + } + + return + } + + // regular assignment + var z operand + check.expr(&z, lhs, nil, -1) + check.assignOperand(&z, x) + if x.mode != invalid && z.mode == constant { + check.errorf(x.pos(), "cannot assign %s to %s", x, z) + } +} + +func (check *checker) assign1to1(lhs, rhs ast.Expr, decl bool, iota int) { + ident, _ := lhs.(*ast.Ident) + + if ident != nil && ident.Name == "_" { + // anything can be assigned to a blank identifier - check rhs only + var x operand + check.expr(&x, rhs, nil, iota) + return + } + + if !decl { + // regular assignment - start with lhs[0] to obtain a type hint + var z operand + check.expr(&z, lhs, nil, -1) + if z.mode == invalid { + z.typ = nil // so we can proceed with rhs + } + + var x operand + check.expr(&x, rhs, z.typ, -1) + if x.mode == invalid { + return + } + + check.assignOperand(&z, &x) + return + } + + // declaration - rhs may or may not be typed yet + if ident == nil { + check.errorf(lhs.Pos(), "cannot declare %s", lhs) + return + } + + obj := ident.Obj + var typ Type + if obj.Type != nil { + typ = obj.Type.(Type) + } + + var x operand + check.expr(&x, rhs, typ, iota) + if x.mode == invalid { + return + } + + if typ == nil { + // determine lhs type from rhs expression; + // for variables, convert untyped types to + // default types + typ = x.typ + if obj.Kind == ast.Var && isUntyped(typ) { + // TODO(gri) factor this out + var k BasicKind + switch typ.(*Basic).Kind { + case UntypedBool: + k = Bool + case UntypedRune: + k = Rune + case UntypedInt: + k = Int + case UntypedFloat: + k = Float64 + case UntypedComplex: + k = Complex128 + case UntypedString: + k = String + default: + unreachable() + } + typ = Typ[k] + } + obj.Type = typ + } + + var z operand + switch obj.Kind { + case ast.Con: + z.mode = constant + case ast.Var: + z.mode = variable + default: + unreachable() + } + z.expr = ident + z.typ = typ + + check.assignOperand(&z, &x) + + // for constants, set their value + if obj.Kind == ast.Con { + assert(obj.Data == nil) + if x.mode != constant { + check.errorf(x.pos(), "%s is not constant", x) + // set the constant to the type's zero value to reduce spurious errors + // TODO(gri) factor this out - useful elsewhere + switch typ := underlying(typ); { + case typ == Typ[Invalid]: + // ignore + case isBoolean(typ): + obj.Data = false + case isNumeric(typ): + obj.Data = int64(0) + case isString(typ): + obj.Data = "" + default: + unreachable() + } + return + } + obj.Data = x.val + } +} + +// assignNtoM typechecks a general assignment. If decl is set, the lhs operands +// must be identifiers. If their types are not set, they are deduced from the +// types of the corresponding rhs expressions. iota >= 0 indicates that the +// "assignment" is part of a constant declaration. +// Precondition: len(lhs) > 0 . +// +func (check *checker) assignNtoM(lhs, rhs []ast.Expr, decl bool, iota int) { + assert(len(lhs) >= 1) + + if len(lhs) == len(rhs) { + for i, e := range rhs { + check.assign1to1(lhs[i], e, decl, iota) + } + return + } + + if len(rhs) == 1 { + // len(lhs) >= 2; therefore a correct rhs expression + // cannot be a shift and we don't need a type hint - + // ok to evaluate rhs first + var x operand + check.expr(&x, rhs[0], nil, iota) + if x.mode == invalid { + return + } + + if t, ok := x.typ.(*tuple); ok && len(lhs) == len(t.list) { + // function result + x.mode = value + for i, typ := range t.list { + x.expr = nil // TODO(gri) should do better here + x.typ = typ + check.assignment(lhs[i], &x, decl) + } + return + } + + if x.mode == valueok && len(lhs) == 2 { + // comma-ok expression + x.mode = value + check.assignment(lhs[0], &x, decl) + + x.mode = value + x.typ = Typ[UntypedBool] + check.assignment(lhs[1], &x, decl) + return + } + } + + check.errorf(lhs[0].Pos(), "assignment count mismatch: %d = %d", len(lhs), len(rhs)) + + // avoid checking the same declaration over and over + // again for each lhs identifier that has no type yet + if iota >= 0 { + // declaration + for _, e := range lhs { + if ident, ok := e.(*ast.Ident); ok { + ident.Obj.Type = Typ[Invalid] + } + } + } +} + +func (check *checker) optionalStmt(s ast.Stmt) { + if s != nil { + check.stmt(s) + } +} + +func (check *checker) stmtList(list []ast.Stmt) { + for _, s := range list { + check.stmt(s) + } +} + +// stmt typechecks statement s. +func (check *checker) stmt(s ast.Stmt) { + switch s := s.(type) { + case *ast.BadStmt, *ast.EmptyStmt: + // ignore + + case *ast.DeclStmt: + unimplemented() + + case *ast.LabeledStmt: + unimplemented() + + case *ast.ExprStmt: + var x operand + used := false + switch e := unparen(s.X).(type) { + case *ast.CallExpr: + // function calls are permitted + used = true + // but some builtins are excluded + check.expr(&x, e.Fun, nil, -1) + if x.mode != invalid { + if b, ok := x.typ.(*builtin); ok && !b.isStatement { + used = false + } + } + case *ast.UnaryExpr: + // receive operations are permitted + if e.Op == token.ARROW { + used = true + } + } + if !used { + check.errorf(s.Pos(), "%s not used", s.X) + // ok to continue + } + check.exprOrType(&x, s.X, nil, -1, false) + if x.mode == typexpr { + check.errorf(x.pos(), "%s is not an expression", x) + } + + case *ast.SendStmt: + var ch, x operand + check.expr(&ch, s.Chan, nil, -1) + check.expr(&x, s.Value, nil, -1) + if ch.mode == invalid || x.mode == invalid { + return + } + if tch, ok := underlying(ch.typ).(*Chan); !ok || tch.Dir&ast.SEND == 0 || !x.isAssignable(tch.Elt) { + check.invalidOp(ch.pos(), "cannot send %s to channel %s", &x, &ch) + } + + case *ast.IncDecStmt: + unimplemented() + + case *ast.AssignStmt: + switch s.Tok { + case token.ASSIGN, token.DEFINE: + if len(s.Lhs) == 0 { + check.invalidAST(s.Pos(), "missing lhs in assignment") + return + } + check.assignNtoM(s.Lhs, s.Rhs, s.Tok == token.DEFINE, -1) + default: + // assignment operations + if len(s.Lhs) != 1 || len(s.Rhs) != 1 { + check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok) + return + } + // TODO(gri) make this conversion more efficient + var op token.Token + switch s.Tok { + case token.ADD_ASSIGN: + op = token.ADD + case token.SUB_ASSIGN: + op = token.SUB + case token.MUL_ASSIGN: + op = token.MUL + case token.QUO_ASSIGN: + op = token.QUO + case token.REM_ASSIGN: + op = token.REM + case token.AND_ASSIGN: + op = token.AND + case token.OR_ASSIGN: + op = token.OR + case token.XOR_ASSIGN: + op = token.XOR + case token.SHL_ASSIGN: + op = token.SHL + case token.SHR_ASSIGN: + op = token.SHR + case token.AND_NOT_ASSIGN: + op = token.AND_NOT + } + var x, y operand + check.expr(&x, s.Lhs[0], nil, -1) + check.expr(&y, s.Rhs[0], nil, -1) + check.binary(&x, &y, op, nil) + check.assignment(s.Lhs[0], &x, false) + } + + case *ast.GoStmt: + unimplemented() + + case *ast.DeferStmt: + unimplemented() + + case *ast.ReturnStmt: + unimplemented() + + case *ast.BranchStmt: + unimplemented() + + case *ast.BlockStmt: + check.stmtList(s.List) + + case *ast.IfStmt: + check.optionalStmt(s.Init) + var x operand + check.expr(&x, s.Cond, nil, -1) + if !isBoolean(x.typ) { + check.errorf(s.Cond.Pos(), "non-boolean condition in if statement") + } + check.stmt(s.Body) + check.optionalStmt(s.Else) + + case *ast.SwitchStmt: + check.optionalStmt(s.Init) + var x operand + if s.Tag != nil { + check.expr(&x, s.Tag, nil, -1) + } else { + x.mode = constant + x.typ = Typ[UntypedBool] + x.val = true + } + for _, s := range s.Body.List { + if clause, ok := s.(*ast.CaseClause); ok { + for _, expr := range clause.List { + var y operand + check.expr(&y, expr, nil, -1) + // TODO(gri) x and y must be comparable + } + check.stmtList(clause.Body) + } else { + check.errorf(s.Pos(), "invalid AST: case clause expected") + } + } + + case *ast.TypeSwitchStmt: + unimplemented() + + case *ast.SelectStmt: + unimplemented() + + case *ast.ForStmt: + check.optionalStmt(s.Init) + if s.Cond != nil { + var x operand + check.expr(&x, s.Cond, nil, -1) + if !isBoolean(x.typ) { + check.errorf(s.Cond.Pos(), "non-boolean condition in for statement") + } + } + check.optionalStmt(s.Post) + check.stmt(s.Body) + + case *ast.RangeStmt: + unimplemented() + + default: + check.errorf(s.Pos(), "invalid statement") + } +} diff --git a/libgo/go/exp/types/staging/testdata/builtins.src b/libgo/go/exp/types/staging/testdata/builtins.src new file mode 100644 index 0000000..c641537e --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/builtins.src @@ -0,0 +1,258 @@ +// Copyright 2012 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. + +// builtin calls + +package builtins + +import "unsafe" + +func _append() { + var x int + var s []byte + _0 := append /* ERROR "argument" */ () + _1 := append("foo" /* ERROR "not a typed slice" */) + _2 := append(nil /* ERROR "not a typed slice" */, s) + _3 := append(x /* ERROR "not a typed slice" */, s) + _4 := append(s) + append /* ERROR "not used" */ (s) +} + +func _cap() { + var a [10]bool + var p *[20]int + var s []int + var c chan string + _0 := cap /* ERROR "argument" */ () + _1 := cap /* ERROR "argument" */ (1, 2) + _2 := cap(42 /* ERROR "invalid" */) + const _3 = cap(a) + assert(_3 == 10) + const _4 = cap(p) + assert(_4 == 20) + _5 := cap(c) + cap /* ERROR "not used" */ (c) +} + +func _close() { + var c chan int + var r <-chan int + close /* ERROR "argument" */ () + close /* ERROR "argument" */ (1, 2) + close(42 /* ERROR "not a channel" */) + close(r /* ERROR "receive-only channel" */) + close(c) +} + +func _complex() { + _0 := complex /* ERROR "argument" */ () + _1 := complex /* ERROR "argument" */ (1) + _2 := complex(1, 2) + // TODO(gri) add tests checking types + complex /* ERROR "not used" */ (1, 2) +} + +func _delete() { + var m map[string]int + var s string + delete /* ERROR "argument" */ () + delete /* ERROR "argument" */ (1) + delete /* ERROR "argument" */ (1, 2, 3) + delete(m, 0 /* ERROR "not assignable" */) + delete(m, s) +} + +func _imag() { + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + _0 := imag /* ERROR "argument" */ () + _1 := imag /* ERROR "argument" */ (1, 2) + _2 := imag(10 /* ERROR "must be a complex number" */) + _3 := imag(2.7182818 /* ERROR "must be a complex number" */) + _4 := imag("foo" /* ERROR "must be a complex number" */) + const _5 = imag(1 + 2i) + assert(_5 == 2) + f32 = _5 + f64 = _5 + const _6 = imag(0i) + assert(_6 == 0) + f32 = imag(c64) + f64 = imag(c128) + f32 = imag /* ERROR "cannot assign" */ (c128) + f64 = imag /* ERROR "cannot assign" */ (c64) + imag /* ERROR "not used" */ (c64) +} + +func _len() { + const c = "foobar" + var a [10]bool + var p *[20]int + var s []int + var m map[string]complex128 + _0 := len /* ERROR "argument" */ () + _1 := len /* ERROR "argument" */ (1, 2) + _2 := len(42 /* ERROR "invalid" */) + const _3 = len(c) + assert(_3 == 6) + const _4 = len(a) + assert(_4 == 10) + const _5 = len(p) + assert(_5 == 20) + _6 := len(m) + len /* ERROR "not used" */ (c) + + // esoteric case + var t string + var hash map[interface{}][]*[10]int + const n = len /* ERROR "not constant" */ (hash[recover()][len(t)]) + assert /* ERROR "failed" */ (n == 10) + var ch <-chan int + const nn = len /* ERROR "not constant" */ (hash[<-ch][len(t)]) + _7 := nn // TODO(gri) remove this once unused constants get type-checked +} + +func _make() { + n := 0 + + _0 := make /* ERROR "argument" */ () + _1 := make(1 /* ERROR "not a type" */) + _2 := make(int /* ERROR "cannot make" */) + + // slices + _3 := make/* ERROR "arguments" */ ([]int) + _4 := make/* ERROR "arguments" */ ([]int, 2, 3, 4) + _5 := make([]int, int /* ERROR "not an expression" */) + _6 := make([]int, 10, float32 /* ERROR "not an expression" */) + _7 := make([]int, "foo" /* ERROR "must be an integer" */) + _8 := make([]int, 10, 2.3 /* ERROR "must be an integer" */) + _9 := make([]int, 5, 10.0) + _10 := make([]int, 0i) + _11 := make([]int, -1, 1<<100) // out-of-range constants lead to run-time errors + + // maps + _12 := make /* ERROR "arguments" */ (map[int]string, 10, 20) + _13 := make(map[int]float32, int /* ERROR "not an expression" */) + _14 := make(map[int]float32, "foo" /* ERROR "must be an integer" */) + _15 := make(map[int]float32, 10) + _16 := make(map[int]float32, n) + _17 := make(map[int]float32, int64(n)) + + // channels + _22 := make /* ERROR "arguments" */ (chan int, 10, 20) + _23 := make(chan int, int /* ERROR "not an expression" */) + _24 := make(chan<- int, "foo" /* ERROR "must be an integer" */) + _25 := make(<-chan float64, 10) + _26 := make(chan chan int, n) + _27 := make(chan string, int64(n)) + + make /* ERROR "not used" */ ([]int, 10) +} + +func _new() { + _0 := new /* ERROR "argument" */ () + _1 := new /* ERROR "argument" */ (1, 2) + _3 := new("foo" /* ERROR "not a type" */) + _4 := new(float64) + _5 := new(struct{ x, y int }) + _6 := new(*float64) + _7 := *_4 == **_6 + new /* ERROR "not used" */ (int) +} + +func _real() { + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + _0 := real /* ERROR "argument" */ () + _1 := real /* ERROR "argument" */ (1, 2) + _2 := real(10 /* ERROR "must be a complex number" */) + _3 := real(2.7182818 /* ERROR "must be a complex number" */) + _4 := real("foo" /* ERROR "must be a complex number" */) + const _5 = real(1 + 2i) + assert(_5 == 1) + f32 = _5 + f64 = _5 + const _6 = real(0i) + assert(_6 == 0) + f32 = real(c64) + f64 = real(c128) + f32 = real /* ERROR "cannot assign" */ (c128) + f64 = real /* ERROR "cannot assign" */ (c64) + real /* ERROR "not used" */ (c64) +} + +func _recover() { + _0 := recover() + _1 := recover /* ERROR "argument" */ (10) + recover() +} + +func _Alignof() { + var x int + _0 := unsafe /* ERROR "argument" */ .Alignof() + _1 := unsafe /* ERROR "argument" */ .Alignof(1, 2) + _3 := unsafe.Alignof(int /* ERROR "not an expression" */) + _4 := unsafe.Alignof(42) + _5 := unsafe.Alignof(new(struct{})) + unsafe /* ERROR "not used" */ .Alignof(x) +} + +func _Offsetof() { + var x struct{ f int } + _0 := unsafe /* ERROR "argument" */ .Offsetof() + _1 := unsafe /* ERROR "argument" */ .Offsetof(1, 2) + _2 := unsafe.Offsetof(int /* ERROR "not an expression" */) + _3 := unsafe.Offsetof(x /* ERROR "not a selector" */) + _4 := unsafe.Offsetof(x.f) + _5 := unsafe.Offsetof((x.f)) + _6 := unsafe.Offsetof((((((((x))).f))))) + unsafe /* ERROR "not used" */ .Offsetof(x.f) +} + +func _Sizeof() { + var x int + _0 := unsafe /* ERROR "argument" */ .Sizeof() + _1 := unsafe /* ERROR "argument" */ .Sizeof(1, 2) + _2 := unsafe.Sizeof(int /* ERROR "not an expression" */) + _3 := unsafe.Sizeof(42) + _4 := unsafe.Sizeof(new(complex128)) + unsafe /* ERROR "not used" */ .Sizeof(x) + + // basic types have size guarantees + assert(unsafe.Sizeof(byte(0)) == 1) + assert(unsafe.Sizeof(uint8(0)) == 1) + assert(unsafe.Sizeof(int8(0)) == 1) + assert(unsafe.Sizeof(uint16(0)) == 2) + assert(unsafe.Sizeof(int16(0)) == 2) + assert(unsafe.Sizeof(uint32(0)) == 4) + assert(unsafe.Sizeof(int32(0)) == 4) + assert(unsafe.Sizeof(float32(0)) == 4) + assert(unsafe.Sizeof(uint64(0)) == 8) + assert(unsafe.Sizeof(int64(0)) == 8) + assert(unsafe.Sizeof(float64(0)) == 8) + assert(unsafe.Sizeof(complex64(0)) == 8) + assert(unsafe.Sizeof(complex128(0)) == 16) +} + +// self-testing only +func _assert() { + var x int + assert /* ERROR "argument" */ () + assert /* ERROR "argument" */ (1, 2) + assert("foo" /* ERROR "boolean constant" */ ) + assert(x /* ERROR "boolean constant" */) + assert(true) + assert /* ERROR "failed" */ (false) +} + +// self-testing only +func _trace() { + // Uncomment the code below to test trace - will produce console output + // _0 := trace /* ERROR "no value" */ () + // _1 := trace(1) + // _2 := trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar") +} diff --git a/libgo/go/exp/types/staging/testdata/const0.src b/libgo/go/exp/types/staging/testdata/const0.src new file mode 100644 index 0000000..4599397 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/const0.src @@ -0,0 +1,209 @@ +// Copyright 2012 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. + +// constant declarations + +package const0 + +// constants declarations must be initialized by constants +var x = 0 +const c0 = x /* ERROR "not constant" */ + +// untyped constants +const ( + // boolean values + ub0 = false + ub1 = true + ub2 = 2 < 1 + ub3 = ui1 == uf1 + ub4 = true /* ERROR "cannot convert" */ == 0 + + // integer values + ui0 = 0 + ui1 = 1 + ui2 = 42 + ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286 + ui4 = -10 + + ui5 = ui0 + ui1 + ui6 = ui1 - ui1 + ui7 = ui2 * ui1 + ui8 = ui3 / ui3 + ui9 = ui3 % ui3 + + ui10 = 1 / 0 /* ERROR "division by zero" */ + ui11 = ui1 / 0 /* ERROR "division by zero" */ + ui12 = ui3 / ui0 /* ERROR "division by zero" */ + ui13 = 1 % 0 /* ERROR "division by zero" */ + ui14 = ui1 % 0 /* ERROR "division by zero" */ + ui15 = ui3 % ui0 /* ERROR "division by zero" */ + + ui16 = ui2 & ui3 + ui17 = ui2 | ui3 + ui18 = ui2 ^ ui3 + + // floating point values + uf0 = 0. + uf1 = 1. + uf2 = 4.2e1 + uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 + uf4 = 1e-1 + + uf5 = uf0 + uf1 + uf6 = uf1 - uf1 + uf7 = uf2 * uf1 + uf8 = uf3 / uf3 + uf9 = uf3 /* ERROR "not defined" */ % uf3 + + uf10 = 1 / 0 /* ERROR "division by zero" */ + uf11 = uf1 / 0 /* ERROR "division by zero" */ + uf12 = uf3 / uf0 /* ERROR "division by zero" */ + + uf16 = uf2 /* ERROR "not defined" */ & uf3 + uf17 = uf2 /* ERROR "not defined" */ | uf3 + uf18 = uf2 /* ERROR "not defined" */ ^ uf3 + + // complex values + uc0 = 0.i + uc1 = 1.i + uc2 = 4.2e1i + uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i + uc4 = 1e-1i + + uc5 = uc0 + uc1 + uc6 = uc1 - uc1 + uc7 = uc2 * uc1 + uc8 = uc3 / uc3 + uc9 = uc3 /* ERROR "not defined" */ % uc3 + + uc10 = 1 / 0 /* ERROR "division by zero" */ + uc11 = uc1 / 0 /* ERROR "division by zero" */ + uc12 = uc3 / uc0 /* ERROR "division by zero" */ + + uc16 = uc2 /* ERROR "not defined" */ & uc3 + uc17 = uc2 /* ERROR "not defined" */ | uc3 + uc18 = uc2 /* ERROR "not defined" */ ^ uc3 +) + +type ( + mybool bool + myint int + myfloat float64 + mycomplex complex128 +) + +// typed constants +const ( + // boolean values + tb0 bool = false + tb1 bool = true + tb2 mybool = 2 < 1 + tb3 mybool = ti1 /* ERROR "cannot compare" */ == tf1 + + // integer values + ti0 int8 = ui0 + ti1 int32 = ui1 + ti2 int64 = ui2 + ti3 myint = ui3 /* ERROR "overflows" */ + ti4 myint = ui4 + + ti5 = ti0 /* ERROR "mismatched types" */ + ti1 + ti6 = ti1 - ti1 + ti7 = ti2 /* ERROR "mismatched types" */ * ti1 + //ti8 = ti3 / ti3 // TODO(gri) enable this + //ti9 = ti3 % ti3 // TODO(gri) enable this + + ti10 = 1 / 0 /* ERROR "division by zero" */ + ti11 = ti1 / 0 /* ERROR "division by zero" */ + ti12 = ti3 /* ERROR "mismatched types" */ / ti0 + ti13 = 1 % 0 /* ERROR "division by zero" */ + ti14 = ti1 % 0 /* ERROR "division by zero" */ + ti15 = ti3 /* ERROR "mismatched types" */ % ti0 + + ti16 = ti2 /* ERROR "mismatched types" */ & ti3 + ti17 = ti2 /* ERROR "mismatched types" */ | ti4 + ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown + + // floating point values + tf0 float32 = 0. + tf1 float32 = 1. + tf2 float64 = 4.2e1 + tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 + tf4 myfloat = 1e-1 + + tf5 = tf0 + tf1 + tf6 = tf1 - tf1 + tf7 = tf2 /* ERROR "mismatched types" */ * tf1 + // tf8 = tf3 / tf3 // TODO(gri) enable this + tf9 = tf3 /* ERROR "not defined" */ % tf3 + + tf10 = 1 / 0 /* ERROR "division by zero" */ + tf11 = tf1 / 0 /* ERROR "division by zero" */ + tf12 = tf3 /* ERROR "mismatched types" */ / tf0 + + tf16 = tf2 /* ERROR "mismatched types" */ & tf3 + tf17 = tf2 /* ERROR "mismatched types" */ | tf3 + tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3 + + // complex values + tc0 = 0.i + tc1 = 1.i + tc2 = 4.2e1i + tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i + tc4 = 1e-1i + + tc5 = tc0 + tc1 + tc6 = tc1 - tc1 + tc7 = tc2 * tc1 + tc8 = tc3 / tc3 + tc9 = tc3 /* ERROR "not defined" */ % tc3 + + tc10 = 1 / 0 /* ERROR "division by zero" */ + tc11 = tc1 / 0 /* ERROR "division by zero" */ + tc12 = tc3 / tc0 /* ERROR "division by zero" */ + + tc16 = tc2 /* ERROR "not defined" */ & tc3 + tc17 = tc2 /* ERROR "not defined" */ | tc3 + tc18 = tc2 /* ERROR "not defined" */ ^ tc3 +) + +// initialization cycles +const ( + a /* ERROR "cycle" */ = a + b /* ERROR "cycle" */ , c /* ERROR "cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error + f float64 = d +) + +// multiple initialization +const ( + a1, a2, a3 = 7, 3.1415926, "foo" + b1, b2, b3 = b3, b1, 42 + _p0 = assert(a1 == 7) + _p1 = assert(a2 == 3.1415926) + _p2 = assert(a3 == "foo") + _p3 = assert(b1 == 42) + _p4 = assert(b2 == 42) + _p5 = assert(b3 == 42) +) + +// iota +const ( + iota0 = iota + iota1 = iota + iota2 = iota*2 + _a0 = assert(iota0 == 0) + _a1 = assert(iota1 == 1) + _a2 = assert(iota2 == 4) + iota6 = iota*3 + + iota7 + iota8 + _a3 = assert(iota7 == 21) + _a4 = assert(iota8 == 24) +) + +const ( + _b0 = iota + _b1 = assert(iota + iota2 == 5) +)
\ No newline at end of file diff --git a/libgo/go/exp/types/staging/testdata/conversions.src b/libgo/go/exp/types/staging/testdata/conversions.src new file mode 100644 index 0000000..1b15183 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/conversions.src @@ -0,0 +1,18 @@ +// Copyright 2012 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. + +// conversions + +package conversions + +// argument count +var ( + _v0 = int /* ERROR "one argument" */ () + _v1 = int /* ERROR "one argument" */ (1, 2) +) + +// +var ( + _v2 = int8(0) +)
\ No newline at end of file diff --git a/libgo/go/exp/types/staging/testdata/decls0.src b/libgo/go/exp/types/staging/testdata/decls0.src new file mode 100644 index 0000000..e8ae53b --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/decls0.src @@ -0,0 +1,168 @@ +// Copyright 2011 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. + +// type declarations + +package decls0 + +import ( + "unsafe" + // we can have multiple blank imports (was bug) + _ "math" + _ "net/rpc" +) + +const pi = 3.1415 + +type ( + N undeclared /* ERROR "undeclared" */ /* ERROR "not a type" */ + B bool + I int32 + A [10]P + T struct { + x, y P + } + P *T + R (*R) + F func(A) I + Y interface { + f(A) I + } + S [](((P))) + M map[I]F + C chan<- I + + // blank types must be typechecked + _ pi /* ERROR "not a type" */ + _ struct{} + _ struct{ pi /* ERROR "not a type" */ } +) + + +type ( + p1 pi /* ERROR "no field or method foo" */ /* ERROR "not a type" */ .foo + p2 unsafe.Pointer +) + + +type ( + Pi pi /* ERROR "not a type" */ + + a /* ERROR "illegal cycle" */ a + a /* ERROR "redeclared" */ int + + // where the cycle error appears depends on the + // order in which declarations are processed + // (which depends on the order in which a map + // is iterated through) + b /* ERROR "illegal cycle" */ c + c d + d e + e b + + t *t + + U V + V *W + W U + + P1 *S2 + P2 P1 + + S0 struct { + } + S1 struct { + a, b, c int + u, v, a /* ERROR "redeclared" */ float32 + } + S2 struct { + U // anonymous field + // TODO(gri) recognize double-declaration below + // U /* ERROR "redeclared" */ int + } + S3 struct { + x S2 + } + S4/* ERROR "illegal cycle" */ struct { + S4 + } + S5 /* ERROR "illegal cycle" */ struct { + S6 + } + S6 struct { + field S7 + } + S7 struct { + S5 + } + + L1 []L1 + L2 []int + + A1 [10.0]int + A2 /* ERROR "illegal cycle" */ [10]A2 + A3 /* ERROR "illegal cycle" */ [10]struct { + x A4 + } + A4 [10]A3 + + F1 func() + F2 func(x, y, z float32) + F3 func(x, y, x /* ERROR "redeclared" */ float32) + F4 func() (x, y, x /* ERROR "redeclared" */ float32) + F5 func(x int) (x /* ERROR "redeclared" */ float32) + F6 func(x ...int) + + I1 interface{} + I2 interface { + m1() + } + I3 interface { + m1() + m1 /* ERROR "redeclared" */ () + } + I4 interface { + m1(x, y, x /* ERROR "redeclared" */ float32) + m2() (x, y, x /* ERROR "redeclared" */ float32) + m3(x int) (x /* ERROR "redeclared" */ float32) + } + I5 interface { + m1(I5) + } + I6 interface { + S0 /* ERROR "non-interface" */ + } + I7 interface { + I1 + I1 + } + I8 /* ERROR "illegal cycle" */ interface { + I8 + } + // Use I09 (rather than I9) because it appears lexically before + // I10 so that we get the illegal cycle here rather then in the + // declaration of I10. If the implementation sorts by position + // rather than name, the error message will still be here. + I09 /* ERROR "illegal cycle" */ interface { + I10 + } + I10 interface { + I11 + } + I11 interface { + I09 + } + + C1 chan int + C2 <-chan int + C3 chan<- C3 + C4 chan C5 + C5 chan C6 + C6 chan C4 + + M1 map[Last]string + M2 map[string]M2 + + Last int +) diff --git a/libgo/go/exp/types/staging/testdata/decls1.src b/libgo/go/exp/types/staging/testdata/decls1.src new file mode 100644 index 0000000..32859fc --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/decls1.src @@ -0,0 +1,123 @@ +// Copyright 2012 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. + +// variable declarations + +package decls1 + +import ( + "math" +) + +// Global variables without initialization +var ( + a, b bool + c byte + d uint8 + r rune + i int + j, k, l int + x, y float32 + xx, yy float64 + u, v complex64 + uu, vv complex128 + s, t string + array []byte + iface interface{} + + blank _ /* ERROR "cannot use _" */ /* ERROR "not a type" */ +) + +// Global variables with initialization +var ( + s1 = i + j + s2 = i /* ERROR "mismatched types" */ + x + s3 = c + d + s4 = s + t + s5 = s /* ERROR "invalid operation" */ / t + s6 = array[t1] + s7 = array[x /* ERROR "index" */] + s8 = &a + s10 = &42 /* ERROR "cannot take address" */ + s11 = &v + s12 = -(u + *t11) / *&v + s13 = a /* ERROR "shifted operand" */ << d + s14 = i << j /* ERROR "must be unsigned" */ + s18 = math.Pi * 10.0 + s19 = s1 /* ERROR "cannot call" */ () + s20 = f0 /* ERROR "used as single value" */ () + s21 = f6(1, s1, i) + s22 = f6(1, s1, uu /* ERROR "cannot assign" */ ) + + t1 int = i + j + t2 int = i /* ERROR "mismatched types" */ + x + t3 int = c /* ERROR "cannot assign" */ + d + t4 string = s + t + t5 string = s /* ERROR "invalid operation" */ / t + t6 byte = array[t1] + t7 byte = array[x /* ERROR "index" */] + t8 *int = & /* ERROR "cannot assign" */ a + t10 *int = &42 /* ERROR "cannot take address" */ + t11 *complex64 = &v + t12 complex64 = -(u + *t11) / *&v + t13 int = a /* ERROR "shifted operand" */ << d + t14 int = i << j /* ERROR "must be unsigned" */ + t15 math /* ERROR "not in selector" */ /* ERROR "not a type" */ + t16 math /* ERROR "not a type" */ .xxx /* ERROR "unexported" */ + t17 math /* ERROR "not a type" */ .Pi + t18 float64 = math.Pi * 10.0 + t19 int = t1 /* ERROR "cannot call" */ () + t20 int = f0 /* ERROR "used as single value" */ () +) + +// Various more complex expressions +var ( + u1 = x /* ERROR "non-interface type" */ .(int) + u2 = iface.([]int) + u3 = iface.(a /* ERROR "not a type" */ ) + u4, ok = iface.(int) + u5 /* ERROR "assignment count mismatch" */ , ok2, ok3 = iface.(int) +) + +// Constant expression initializations +var ( + v1 = 1 /* ERROR "cannot convert" */ + "foo" + v2 = c + 255 + v3 = c + 256 /* ERROR "overflows" */ + v4 = r + 2147483647 + v5 = r + 2147483648 /* ERROR "overflows" */ + v6 = 42 + v7 = v6 + 2147483647 + v8 = v6 + 2147483648 /* ERROR "overflows" */ + v9 = i + 1 << 10 + v10 byte = 1024 /* ERROR "overflows" */ + v11 = xx/yy*yy - xx + v12 = true && false +) + +// Multiple assignment expressions +var ( + m1a, m1b = 1, 2 + m2a /* ERROR "assignment count mismatch" */ , m2b, m2c = 1, 2 + m3a /* ERROR "assignment count mismatch" */ , m3b = 1, 2, 3 +) + +// Declaration of parameters and results +func f0() {} +func f1(a /* ERROR "not a type" */) {} +func f2(a, b, c d /* ERROR "not a type" */) {} + +func f3() int {} +func f4() a /* ERROR "not a type" */ {} +func f5() (a, b, c d /* ERROR "not a type" */) {} + +func f6(a, b, c int) complex128 { return 0 } + +// Declaration of receivers +type T struct{} + +func (T) m0() {} +func (*T) m1() {} +func (x T) m2() {} +func (x *T) m3() {} diff --git a/libgo/go/exp/types/staging/testdata/decls2a.src b/libgo/go/exp/types/staging/testdata/decls2a.src new file mode 100644 index 0000000..738bcb7 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/decls2a.src @@ -0,0 +1,66 @@ +// Copyright 2012 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. + +// method declarations + +package decls2 + +import "time" + +// T1 declared before its methods. +type T1 struct{ + f int +} + +func (T1) m() {} +func (T1) m /* ERROR "redeclared" */ () {} +func (x *T1) f /* ERROR "field and method" */ () {} + +// T2's method declared before the type. +func (*T2) f /* ERROR "field and method" */ () {} + +type T2 struct { + f int +} + +// Methods declared without a declared type. +func (undeclared /* ERROR "undeclared" */) m() {} +func (x *undeclared /* ERROR "undeclared" */) m() {} + +func (pi /* ERROR "not a type" */) m1() {} +func (x pi /* ERROR "not a type" */) m2() {} +func (x *pi /* ERROR "not a type" */) m3() {} + +// Blank types. +type _ struct { m int } +type _ struct { m int } + +// TODO(gri) blank idents not fully checked - disabled for now +// func (_ /* ERROR "cannot use _" */) m() {} +// func (_ /* ERROR "cannot use _" */) m() {} + +// Methods with receiver base type declared in another file. +func (T3) m1() {} +func (*T3) m2() {} +func (x T3) m3() {} +func (x *T3) f /* ERROR "field and method" */ () {} + +// Methods of non-struct type. +type T4 func() + +func (self T4) m() func() { return self } + +// Methods associated with an interface. +type T5 interface { + m() int +} + +func (T5 /* ERROR "invalid receiver" */) m1() {} +func (T5 /* ERROR "invalid receiver" */) m2() {} + +// Methods associated with non-local or unnamed types. +// func (int) m() {} TODO(gri) check for methods associated with external (not package-local) types +func ([ /* ERROR "expected" */ ]int) m() {} +func (time /* ERROR "expected" */ .Time) m() {} +func (x interface /* ERROR "expected" */ {}) m() {} diff --git a/libgo/go/exp/types/staging/testdata/decls2b.src b/libgo/go/exp/types/staging/testdata/decls2b.src new file mode 100644 index 0000000..9537c08 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/decls2b.src @@ -0,0 +1,15 @@ +// Copyright 2012 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. + +// method declarations + +package decls2 + +const pi = 3.1415 + +func (T1) m /* ERROR "redeclared" */ () {} + +type T3 struct { + f *T3 +} diff --git a/libgo/go/exp/types/staging/testdata/exports.go b/libgo/go/exp/types/staging/testdata/exports.go new file mode 100644 index 0000000..8ee28b0 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/exports.go @@ -0,0 +1,89 @@ +// Copyright 2011 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. + +// This file is used to generate an object file which +// serves as test file for gcimporter_test.go. + +package exports + +import ( + "go/ast" +) + +// Issue 3682: Correctly read dotted identifiers from export data. +const init1 = 0 + +func init() {} + +const ( + C0 int = 0 + C1 = 3.14159265 + C2 = 2.718281828i + C3 = -123.456e-789 + C4 = +123.456E+789 + C5 = 1234i + C6 = "foo\n" + C7 = `bar\n` +) + +type ( + T1 int + T2 [10]int + T3 []int + T4 *int + T5 chan int + T6a chan<- int + T6b chan (<-chan int) + T6c chan<- (chan int) + T7 <-chan *ast.File + T8 struct{} + T9 struct { + a int + b, c float32 + d []string `go:"tag"` + } + T10 struct { + T8 + T9 + _ *T10 + } + T11 map[int]string + T12 interface{} + T13 interface { + m1() + m2(int) float32 + } + T14 interface { + T12 + T13 + m3(x ...struct{}) []T9 + } + T15 func() + T16 func(int) + T17 func(x int) + T18 func() float32 + T19 func() (x float32) + T20 func(...interface{}) + T21 struct{ next *T21 } + T22 struct{ link *T23 } + T23 struct{ link *T22 } + T24 *T24 + T25 *T26 + T26 *T27 + T27 *T25 + T28 func(T28) T28 +) + +var ( + V0 int + V1 = -991.0 +) + +func F1() {} +func F2(x int) {} +func F3() int { return 0 } +func F4() float32 { return 0 } +func F5(a, b, c int, u, v, w struct{ x, y T1 }, more ...interface{}) (p, q, r chan<- T10) + +func (p *T1) M1() diff --git a/libgo/go/exp/types/staging/testdata/expr0.src b/libgo/go/exp/types/staging/testdata/expr0.src new file mode 100644 index 0000000..c54d42b --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/expr0.src @@ -0,0 +1,135 @@ +// Copyright 2012 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. + +// unary expressions + +package expr0 + +var ( + // bool + b0 = true + b1 bool = b0 + b2 = !true + b3 = !b1 + b4 bool = !true + b5 bool = !b4 + b6 = +b0 /* ERROR "not defined" */ + b7 = -b0 /* ERROR "not defined" */ + b8 = ^b0 /* ERROR "not defined" */ + b9 = *b0 /* ERROR "cannot indirect" */ + b10 = &true /* ERROR "cannot take address" */ + b11 = &b0 + b12 = <-b0 /* ERROR "not defined" */ + + // int + i0 = 1 + i1 int = i0 + i2 = +1 + i3 = +i0 + i4 int = +1 + i5 int = +i4 + i6 = -1 + i7 = -i0 + i8 int = -1 + i9 int = -i4 + i10 = !i0 /* ERROR "not defined" */ + i11 = ^1 + i12 = ^i0 + i13 int = ^1 + i14 int = ^i4 + i15 = *i0 /* ERROR "cannot indirect" */ + i16 = &i0 + i17 = *i16 + i18 = <-i16 /* ERROR "not defined" */ + + // uint + u0 = uint(1) + u1 uint = u0 + u2 = +1 + u3 = +u0 + u4 uint = +1 + u5 uint = +u4 + u6 = -1 + u7 = -u0 + u8 uint = - /* ERROR "overflows" */ 1 + u9 uint = -u4 + u10 = !u0 /* ERROR "not defined" */ + u11 = ^1 + u12 = ^i0 + u13 uint = ^ /* ERROR "overflows" */ 1 + u14 uint = ^u4 + u15 = *u0 /* ERROR "cannot indirect" */ + u16 = &u0 + u17 = *u16 + u18 = <-u16 /* ERROR "not defined" */ + + // float64 + f0 = float64(1) + f1 float64 = f0 + f2 = +1 + f3 = +f0 + f4 float64 = +1 + f5 float64 = +f4 /* ERROR not defined */ + f6 = -1 + f7 = -f0 + f8 float64 = -1 + f9 float64 = -f4 + f10 = !f0 /* ERROR "not defined" */ + f11 = ^1 + f12 = ^i0 + f13 float64 = ^1 + f14 float64 = ^f4 /* ERROR "not defined" */ + f15 = *f0 /* ERROR "cannot indirect" */ + f16 = &f0 + f17 = *u16 + f18 = <-u16 /* ERROR "not defined" */ + + // complex128 + c0 = complex128(1) + c1 complex128 = c0 + c2 = +1 + c3 = +c0 + c4 complex128 = +1 + c5 complex128 = +c4 /* ERROR not defined */ + c6 = -1 + c7 = -c0 + c8 complex128 = -1 + c9 complex128 = -c4 + c10 = !c0 /* ERROR "not defined" */ + c11 = ^1 + c12 = ^i0 + c13 complex128 = ^1 + c14 complex128 = ^c4 /* ERROR "not defined" */ + c15 = *c0 /* ERROR "cannot indirect" */ + c16 = &c0 + c17 = *u16 + c18 = <-u16 /* ERROR "not defined" */ + + // string + s0 = "foo" + s1 = +"foo" /* ERROR "not defined" */ + s2 = -s0 /* ERROR "not defined" */ + s3 = !s0 /* ERROR "not defined" */ + s4 = ^s0 /* ERROR "not defined" */ + s5 = *s4 /* ERROR "cannot indirect" */ + s6 = &s4 + s7 = *s6 + s8 = <-s7 /* ERROR "not defined" */ + + // channel + ch chan int + rc <-chan float64 + sc chan <- string + ch0 = +ch /* ERROR "not defined" */ + ch1 = -ch /* ERROR "not defined" */ + ch2 = !ch /* ERROR "not defined" */ + ch3 = ^ch /* ERROR "not defined" */ + ch4 = *ch /* ERROR "cannot indirect" */ + ch5 = &ch + ch6 = *ch5 + ch7 = <-ch + ch8 = <-rc + ch9 = <-sc /* ERROR "not defined" */ + +)
\ No newline at end of file diff --git a/libgo/go/exp/types/staging/testdata/expr1.src b/libgo/go/exp/types/staging/testdata/expr1.src new file mode 100644 index 0000000..8ef0aed --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/expr1.src @@ -0,0 +1,7 @@ +// Copyright 2012 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. + +// binary expressions + +package expr1 diff --git a/libgo/go/exp/types/staging/testdata/expr2.src b/libgo/go/exp/types/staging/testdata/expr2.src new file mode 100644 index 0000000..a3167f4 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/expr2.src @@ -0,0 +1,7 @@ +// Copyright 2012 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. + +// comparisons + +package expr2 diff --git a/libgo/go/exp/types/staging/testdata/expr3.src b/libgo/go/exp/types/staging/testdata/expr3.src new file mode 100644 index 0000000..5635e12 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/expr3.src @@ -0,0 +1,115 @@ +// Copyright 2012 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. + +// various expressions + +package expr3 + +// TODO(gri) Move the code below into function "shifts" once we check +// declarations with initilizations inside functions. +var ( + i0 int + u0 uint +) + +var ( + v0 = 1<<0 + v1 = 1<<i0 /* ERROR "must be unsigned" */ + v2 = 1<<u0 + v3 = 1<<"foo" /* ERROR "must be unsigned" */ + v4 = 1<<- /* ERROR "stupid shift" */ 1 + v5 = 1<<1025 /* ERROR "stupid shift" */ + v6 = 1 /* ERROR "overflows" */ <<100 + + v10 uint = 1 << 0 + v11 uint = 1 << u0 + v12 float32 = 1 /* ERROR "must be integer" */ << u0 +) + +// TODO(gri) enable commented out tests below. + +// from the spec +var ( + s uint = 33 + i = 1<<s // 1 has type int + j int32 = 1<<s // 1 has type int32; j == 0 + k = uint64(1<<s) // 1 has type uint64; k == 1<<33 + m int = 1.0<<s // 1.0 has type int +// n = 1.0<<s != 0 // 1.0 has type int; n == false if ints are 32bits in size + o = 1<<s == 2<<s // 1 and 2 have type int; o == true if ints are 32bits in size +// p = 1<<s == 1 /* ERROR "overflows" */ <<33 // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int + u = 1.0 /* ERROR "must be integer" */ <<s // illegal: 1.0 has type float64, cannot shift + v float32 = 1 /* ERROR "must be integer" */ <<s // illegal: 1 has type float32, cannot shift + w int64 = 1.0<<33 // 1.0<<33 is a constant shift expression +) + +// TODO(gri) The error messages below depond on adjusting the spec +// to reflect what gc is doing at the moment (the spec +// asks for run-time errors at the moment - see issue 4231). +// +func indexes() { + _ = 1 /* ERROR "cannot index" */ [0] + _ = indexes /* ERROR "cannot index" */ [0] + _ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2] + + var a [10]int + _ = a[true /* ERROR "must be integer" */ ] + _ = a["foo" /* ERROR "must be integer" */ ] + _ = a[1.1 /* ERROR "must be integer" */ ] + _ = a[1.0] + _ = a[- /* ERROR "index .* negative" */ 1] + _ = a[- /* ERROR "index .* negative" */ 1 :] + _ = a[: - /* ERROR "index .* negative" */ 1] + var a0 int + a0 = a[0] + var a1 int32 + a1 = a /* ERROR "cannot assign" */ [1] + _ = a[9] + _ = a[10 /* ERROR "index .* out of bounds" */ ] + _ = a[10:] + _ = a[:10] + _ = a[10:10] + _ = a[11 /* ERROR "index .* out of bounds" */ :] + _ = a[: 11 /* ERROR "index .* out of bounds" */ ] + + var b [0]int + _ = b[0 /* ERROR "index .* out of bounds" */ ] + _ = b[:] + _ = b[0:] + _ = b[:0] + _ = b[0:0] + + var s []int + _ = s[- /* ERROR "index .* negative" */ 1] + _ = s[- /* ERROR "index .* negative" */ 1 :] + _ = s[: - /* ERROR "index .* negative" */ 1] + _ = s[0] + _ = s[1 : 2] + _ = s[2 /* ERROR "inverted slice range" */ : 1] + _ = s[2 :] + + var t string + _ = t[- /* ERROR "index .* negative" */ 1] + _ = t[- /* ERROR "index .* negative" */ 1 :] + _ = t[: - /* ERROR "index .* negative" */ 1] + var t0 byte + t0 = t[0] + var t1 rune + t1 = t /* ERROR "cannot assign" */ [2] + _ = ("foo" + "bar")[5] + _ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ] + + const c = "foo" + _ = c[- /* ERROR "index .* negative" */ 1] + _ = c[- /* ERROR "index .* negative" */ 1 :] + _ = c[: - /* ERROR "index .* negative" */ 1] + var c0 byte + c0 = c[0] + var c2 float32 + c2 = c /* ERROR "cannot assign" */ [2] + _ = c[3 /* ERROR "index .* out of bounds" */ ] + _ = ""[0 /* ERROR "index .* out of bounds" */ ] + + _ = s[1<<30] // no compile-time error here +} diff --git a/libgo/go/exp/types/staging/testdata/stmt0.src b/libgo/go/exp/types/staging/testdata/stmt0.src new file mode 100644 index 0000000..a98c930 --- /dev/null +++ b/libgo/go/exp/types/staging/testdata/stmt0.src @@ -0,0 +1,42 @@ +// Copyright 2012 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. + +// statements + +package stmt0 + +func _() { + b, i, f, c, s := false, 1, 1.0, 1i, "foo" + b = i /* ERROR "cannot assign" */ + i = f /* ERROR "cannot assign" */ + f = c /* ERROR "cannot assign" */ + c = s /* ERROR "cannot assign" */ + s = b /* ERROR "cannot assign" */ + + v0 /* ERROR "mismatch" */, v1, v2 := 1, 2, 3, 4 + + b = true + + i += 1 + i += "foo" /* ERROR "cannot convert.*int" */ + + f -= 1 + f -= "foo" /* ERROR "cannot convert.*float64" */ + + c *= 1 + c /= 0 /* ERROR "division by zero" */ + + s += "bar" + s += 1 /* ERROR "cannot convert.*string" */ +} + +func _sends() { + var ch chan int + var rch <-chan int + var x int + x /* ERROR "cannot send" */ <- x + rch /* ERROR "cannot send" */ <- x + ch /* ERROR "cannot send" */ <- "foo" + ch <- x +}
\ No newline at end of file diff --git a/libgo/go/exp/types/staging/types.go b/libgo/go/exp/types/staging/types.go new file mode 100644 index 0000000..b6e7c1e --- /dev/null +++ b/libgo/go/exp/types/staging/types.go @@ -0,0 +1,235 @@ +// Copyright 2011 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 types declares the data structures for representing +// Go types and implements typechecking of an *ast.Package. +// +// PACKAGE UNDER CONSTRUCTION. ANY AND ALL PARTS MAY CHANGE. +// +package types + +import ( + "go/ast" + "go/token" + "sort" +) + +// Check typechecks a package pkg. It returns the first error, or nil. +// +// Check augments the AST by assigning types to ast.Objects. It +// calls err with the error position and message for each error. +// It calls f with each valid AST expression and corresponding +// type. If err == nil, Check terminates as soon as the first error +// is found. If f is nil, it is not invoked. +// +func Check(fset *token.FileSet, pkg *ast.Package, err func(token.Pos, string), f func(ast.Expr, Type)) error { + return check(fset, pkg, err, f) +} + +// All types implement the Type interface. +// TODO(gri) Eventually determine what common Type functionality should be exported. +type Type interface { + aType() +} + +// BasicKind describes the kind of basic type. +type BasicKind int + +const ( + Invalid BasicKind = iota // type is invalid + + // predeclared types + Bool + Int + Int8 + Int16 + Int32 + Int64 + Uint + Uint8 + Uint16 + Uint32 + Uint64 + Uintptr + Float32 + Float64 + Complex64 + Complex128 + String + UnsafePointer + + // types for untyped values + UntypedBool + UntypedInt + UntypedRune + UntypedFloat + UntypedComplex + UntypedString + UntypedNil + + // aliases + Byte = Uint8 + Rune = Int32 +) + +// BasicInfo is a set of flags describing properties of a basic type. +type BasicInfo int + +// Properties of basic types. +const ( + IsBoolean BasicInfo = 1 << iota + IsInteger + IsUnsigned + IsFloat + IsComplex + IsString + IsUntyped + + IsOrdered = IsInteger | IsFloat | IsString + IsNumeric = IsInteger | IsFloat | IsComplex +) + +// A Basic represents a basic type. +type Basic struct { + implementsType + Kind BasicKind + Info BasicInfo + Size int64 // > 0 if valid + Name string +} + +// An Array represents an array type [Len]Elt. +type Array struct { + implementsType + Len int64 + Elt Type +} + +// A Slice represents a slice type []Elt. +type Slice struct { + implementsType + Elt Type +} + +type StructField struct { + Name string // unqualified type name for anonymous fields + Type Type + Tag string + IsAnonymous bool +} + +// A Struct represents a struct type struct{...}. +type Struct struct { + implementsType + Fields []*StructField +} + +// A Pointer represents a pointer type *Base. +type Pointer struct { + implementsType + Base Type +} + +// A tuple represents a multi-value function return. +// TODO(gri) use better name to avoid confusion (Go doesn't have tuples). +type tuple struct { + implementsType + list []Type +} + +// A Signature represents a user-defined function type func(...) (...). +// TODO(gri) consider using "tuples" to represent parameters and results (see comment on tuples). +type Signature struct { + implementsType + Recv *ast.Object // nil if not a method + Params ObjList // (incoming) parameters from left to right; or nil + Results ObjList // (outgoing) results from left to right; or nil + IsVariadic bool // true if the last parameter's type is of the form ...T +} + +// builtinId is an id of a builtin function. +type builtinId int + +// Predeclared builtin functions. +const ( + // Universe scope + _Append builtinId = iota + _Cap + _Close + _Complex + _Copy + _Delete + _Imag + _Len + _Make + _New + _Panic + _Print + _Println + _Real + _Recover + + // Unsafe package + _Alignof + _Offsetof + _Sizeof + + // Testing support + _Assert + _Trace +) + +// A builtin represents the type of a built-in function. +type builtin struct { + implementsType + id builtinId + name string + nargs int // number of arguments (minimum if variadic) + isVariadic bool + isStatement bool // true if the built-in is valid as an expression statement +} + +// An Interface represents an interface type interface{...}. +type Interface struct { + implementsType + Methods ObjList // interface methods sorted by name; or nil +} + +// A Map represents a map type map[Key]Elt. +type Map struct { + implementsType + Key, Elt Type +} + +// A Chan represents a channel type chan Elt, <-chan Elt, or chan<-Elt. +type Chan struct { + implementsType + Dir ast.ChanDir + Elt Type +} + +// A NamedType represents a named type as declared in a type declaration. +type NamedType struct { + implementsType + Obj *ast.Object // corresponding declared object + Underlying Type // nil if not fully declared yet, never a *NamedType + Methods ObjList // associated methods; or nil +} + +// An ObjList represents an ordered (in some fashion) list of objects. +type ObjList []*ast.Object + +// ObjList implements sort.Interface. +func (list ObjList) Len() int { return len(list) } +func (list ObjList) Less(i, j int) bool { return list[i].Name < list[j].Name } +func (list ObjList) Swap(i, j int) { list[i], list[j] = list[j], list[i] } + +// Sort sorts an object list by object name. +func (list ObjList) Sort() { sort.Sort(list) } + +// All concrete types embed implementsType which +// ensures that all types implement the Type interface. +type implementsType struct{} + +func (*implementsType) aType() {} diff --git a/libgo/go/exp/types/staging/types_test.go b/libgo/go/exp/types/staging/types_test.go new file mode 100644 index 0000000..e6959bc --- /dev/null +++ b/libgo/go/exp/types/staging/types_test.go @@ -0,0 +1,181 @@ +// Copyright 2012 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. + +// This file contains tests verifying the types associated with an AST after +// type checking. + +package types + +import ( + "go/ast" + "go/parser" + "testing" +) + +const filename = "<src>" + +func makePkg(t *testing.T, src string) (*ast.Package, error) { + file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) + if err != nil { + return nil, err + } + files := map[string]*ast.File{filename: file} + pkg, err := ast.NewPackage(fset, files, GcImport, Universe) + if err != nil { + return nil, err + } + if err := Check(fset, pkg, nil, nil); err != nil { + return nil, err + } + return pkg, nil +} + +type testEntry struct { + src, str string +} + +// dup returns a testEntry where both src and str are the same. +func dup(s string) testEntry { + return testEntry{s, s} +} + +var testTypes = []testEntry{ + // basic types + dup("int"), + dup("float32"), + dup("string"), + + // arrays + dup("[10]int"), + + // slices + dup("[]int"), + dup("[][]int"), + + // structs + dup("struct{}"), + dup("struct{x int}"), + {`struct { + x, y int + z float32 "foo" + }`, `struct{x int; y int; z float32 "foo"}`}, + {`struct { + string + elems []T + }`, `struct{string; elems []T}`}, + + // pointers + dup("*int"), + dup("***struct{}"), + dup("*struct{a int; b float32}"), + + // functions + dup("func()"), + dup("func(x int)"), + {"func(x, y int)", "func(x int, y int)"}, + {"func(x, y int, z string)", "func(x int, y int, z string)"}, + dup("func(int)"), + {"func(int, string, byte)", "func(int, string, byte)"}, + + dup("func() int"), + {"func() (string)", "func() string"}, + dup("func() (u int)"), + {"func() (u, v int, w string)", "func() (u int, v int, w string)"}, + + dup("func(int) string"), + dup("func(x int) string"), + dup("func(x int) (u string)"), + {"func(x, y int) (u string)", "func(x int, y int) (u string)"}, + + dup("func(...int) string"), + dup("func(x ...int) string"), + dup("func(x ...int) (u string)"), + {"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"}, + + // interfaces + dup("interface{}"), + dup("interface{m()}"), + {`interface{ + m(int) float32 + String() string + }`, `interface{String() string; m(int) float32}`}, // methods are sorted + // TODO(gri) add test for interface w/ anonymous field + + // maps + dup("map[string]int"), + {"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"}, + + // channels + dup("chan int"), + dup("chan<- func()"), + dup("<-chan []func() int"), +} + +func TestTypes(t *testing.T) { + for _, test := range testTypes { + src := "package p; type T " + test.src + pkg, err := makePkg(t, src) + if err != nil { + t.Errorf("%s: %s", src, err) + continue + } + typ := underlying(pkg.Scope.Lookup("T").Type.(Type)) + str := typeString(typ) + if str != test.str { + t.Errorf("%s: got %s, want %s", test.src, str, test.str) + } + } +} + +var testExprs = []testEntry{ + // basic type literals + dup("x"), + dup("true"), + dup("42"), + dup("3.1415"), + dup("2.71828i"), + dup(`'a'`), + dup(`"foo"`), + dup("`bar`"), + + // arbitrary expressions + dup("&x"), + dup("*x"), + dup("(x)"), + dup("x + y"), + dup("x + y * 10"), + dup("s.foo"), + dup("s[0]"), + dup("s[x:y]"), + dup("s[:y]"), + dup("s[x:]"), + dup("s[:]"), + dup("f(1, 2.3)"), + dup("-f(10, 20)"), + dup("f(x + y, +3.1415)"), + {"func(a, b int) {}", "(func literal)"}, + {"func(a, b int) []int {}()[x]", "(func literal)()[x]"}, + {"[]int{1, 2, 3}", "(composite literal)"}, + {"[]int{1, 2, 3}[x:]", "(composite literal)[x:]"}, + {"x.([]string)", "x.(...)"}, +} + +func TestExprs(t *testing.T) { + for _, test := range testExprs { + src := "package p; var _ = " + test.src + "; var (x, y int; s []string; f func(int, float32))" + pkg, err := makePkg(t, src) + if err != nil { + t.Errorf("%s: %s", src, err) + continue + } + // TODO(gri) writing the code below w/o the decl variable will + // cause a 386 compiler error (out of fixed registers) + decl := pkg.Files[filename].Decls[0].(*ast.GenDecl) + expr := decl.Specs[0].(*ast.ValueSpec).Values[0] + str := exprString(expr) + if str != test.str { + t.Errorf("%s: got %s, want %s", test.src, str, test.str) + } + } +} diff --git a/libgo/go/exp/types/staging/universe.go b/libgo/go/exp/types/staging/universe.go new file mode 100644 index 0000000..bb8b6a2 --- /dev/null +++ b/libgo/go/exp/types/staging/universe.go @@ -0,0 +1,159 @@ +// Copyright 2011 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. + +// This file implements the universe and unsafe package scopes. + +package types + +import ( + "go/ast" + "strings" +) + +var ( + aType implementsType + Universe, unsafe *ast.Scope + Unsafe *ast.Object // package unsafe +) + +// Predeclared types, indexed by BasicKind. +var Typ = [...]*Basic{ + Invalid: {aType, Invalid, 0, 0, "invalid type"}, + + Bool: {aType, Bool, IsBoolean, 1, "bool"}, + Int: {aType, Int, IsInteger, 0, "int"}, + Int8: {aType, Int8, IsInteger, 1, "int8"}, + Int16: {aType, Int16, IsInteger, 2, "int16"}, + Int32: {aType, Int32, IsInteger, 4, "int32"}, + Int64: {aType, Int64, IsInteger, 8, "int64"}, + Uint: {aType, Uint, IsInteger | IsUnsigned, 0, "uint"}, + Uint8: {aType, Uint8, IsInteger | IsUnsigned, 1, "uint8"}, + Uint16: {aType, Uint16, IsInteger | IsUnsigned, 2, "uint16"}, + Uint32: {aType, Uint32, IsInteger | IsUnsigned, 4, "uint32"}, + Uint64: {aType, Uint64, IsInteger | IsUnsigned, 8, "uint64"}, + Uintptr: {aType, Uintptr, IsInteger | IsUnsigned, 0, "uintptr"}, + Float32: {aType, Float32, IsFloat, 4, "float32"}, + Float64: {aType, Float64, IsFloat, 8, "float64"}, + Complex64: {aType, Complex64, IsComplex, 8, "complex64"}, + Complex128: {aType, Complex128, IsComplex, 16, "complex128"}, + String: {aType, String, IsString, 0, "string"}, + UnsafePointer: {aType, UnsafePointer, 0, 0, "Pointer"}, + + UntypedBool: {aType, UntypedBool, IsBoolean | IsUntyped, 0, "untyped boolean"}, + UntypedInt: {aType, UntypedInt, IsInteger | IsUntyped, 0, "untyped integer"}, + UntypedRune: {aType, UntypedRune, IsInteger | IsUntyped, 0, "untyped rune"}, + UntypedFloat: {aType, UntypedFloat, IsFloat | IsUntyped, 0, "untyped float"}, + UntypedComplex: {aType, UntypedComplex, IsComplex | IsUntyped, 0, "untyped complex"}, + UntypedString: {aType, UntypedString, IsString | IsUntyped, 0, "untyped string"}, + UntypedNil: {aType, UntypedNil, IsUntyped, 0, "untyped nil"}, +} + +var aliases = [...]*Basic{ + {aType, Byte, IsInteger | IsUnsigned, 1, "byte"}, + {aType, Rune, IsInteger, 4, "rune"}, +} + +var predeclaredConstants = [...]*struct { + kind BasicKind + name string + val interface{} +}{ + {UntypedBool, "true", true}, + {UntypedBool, "false", false}, + {UntypedInt, "iota", zeroConst}, + {UntypedNil, "nil", nilConst}, +} + +var predeclaredFunctions = [...]*builtin{ + {aType, _Append, "append", 1, true, false}, + {aType, _Cap, "cap", 1, false, false}, + {aType, _Close, "close", 1, false, true}, + {aType, _Complex, "complex", 2, false, false}, + {aType, _Copy, "copy", 2, false, true}, + {aType, _Delete, "delete", 2, false, true}, + {aType, _Imag, "imag", 1, false, false}, + {aType, _Len, "len", 1, false, false}, + {aType, _Make, "make", 1, true, false}, + {aType, _New, "new", 1, false, false}, + {aType, _Panic, "panic", 1, false, true}, + {aType, _Print, "print", 1, true, true}, + {aType, _Println, "println", 1, true, true}, + {aType, _Real, "real", 1, false, false}, + {aType, _Recover, "recover", 0, false, true}, + + {aType, _Alignof, "Alignof", 1, false, false}, + {aType, _Offsetof, "Offsetof", 1, false, false}, + {aType, _Sizeof, "Sizeof", 1, false, false}, +} + +// commonly used types +var ( + emptyInterface = new(Interface) +) + +// commonly used constants +var ( + universeIota *ast.Object +) + +func init() { + // Universe scope + Universe = ast.NewScope(nil) + + // unsafe package and its scope + unsafe = ast.NewScope(nil) + Unsafe = ast.NewObj(ast.Pkg, "unsafe") + Unsafe.Data = unsafe + + // predeclared types + for _, t := range Typ { + def(ast.Typ, t.Name).Type = t + } + for _, t := range aliases { + def(ast.Typ, t.Name).Type = t + } + + // error type + { + obj := def(ast.Typ, "error") + // TODO(gri) set up correct interface type + typ := &NamedType{Underlying: &Interface{}, Obj: obj} + obj.Type = typ + } + + // predeclared constants + for _, t := range predeclaredConstants { + obj := def(ast.Con, t.name) + obj.Type = Typ[t.kind] + obj.Data = t.val + } + + // predeclared functions + for _, f := range predeclaredFunctions { + def(ast.Fun, f.name).Type = f + } + + universeIota = Universe.Lookup("iota") +} + +// Objects with names containing blanks are internal and not entered into +// a scope. Objects with exported names are inserted in the unsafe package +// scope; other objects are inserted in the universe scope. +// +func def(kind ast.ObjKind, name string) *ast.Object { + obj := ast.NewObj(kind, name) + // insert non-internal objects into respective scope + if strings.Index(name, " ") < 0 { + scope := Universe + // exported identifiers go into package unsafe + if ast.IsExported(name) { + scope = unsafe + } + if scope.Insert(obj) != nil { + panic("internal error: double declaration") + } + obj.Decl = scope + } + return obj +} diff --git a/libgo/go/exp/types/testdata/exports.go b/libgo/go/exp/types/testdata/exports.go index ed63bf9..8ee28b0 100644 --- a/libgo/go/exp/types/testdata/exports.go +++ b/libgo/go/exp/types/testdata/exports.go @@ -11,6 +11,11 @@ import ( "go/ast" ) +// Issue 3682: Correctly read dotted identifiers from export data. +const init1 = 0 + +func init() {} + const ( C0 int = 0 C1 = 3.14159265 diff --git a/libgo/go/exp/types/testdata/test0.src b/libgo/go/exp/types/testdata/test0.src index 84a1abe..a770a19 100644 --- a/libgo/go/exp/types/testdata/test0.src +++ b/libgo/go/exp/types/testdata/test0.src @@ -6,7 +6,12 @@ package test0 -import "unsafe" +import ( + "unsafe" + // we can have multiple blank imports (was bug) + _ "math" + _ "net/rpc" +) const pi = 3.1415 @@ -39,15 +44,15 @@ type ( type ( Pi pi /* ERROR "not a type" */ - a /* DISABLED "illegal cycle" */ a + a /* ERROR "illegal cycle" */ a a /* ERROR "redeclared" */ int // where the cycle error appears depends on the // order in which declarations are processed // (which depends on the order in which a map // is iterated through) - b c - c /* DISABLED "illegal cycle" */ d + b /* ERROR "illegal cycle" */ c + c d d e e b @@ -74,13 +79,13 @@ type ( S3 struct { x S2 } - S4/* DISABLED "illegal cycle" */ struct { + S4/* ERROR "illegal cycle" */ struct { S4 } - S5 struct { + S5 /* ERROR "illegal cycle" */ struct { S6 } - S6 /* DISABLED "illegal cycle" */ struct { + S6 struct { field S7 } S7 struct { @@ -91,8 +96,8 @@ type ( L2 []int A1 [10]int - A2 /* DISABLED "illegal cycle" */ [10]A2 - A3 /* DISABLED "illegal cycle" */ [10]struct { + A2 /* ERROR "illegal cycle" */ [10]A2 + A3 /* ERROR "illegal cycle" */ [10]struct { x A4 } A4 [10]A3 @@ -127,17 +132,21 @@ type ( I1 I1 } - I8 /* DISABLED "illegal cycle" */ interface { + I8 /* ERROR "illegal cycle" */ interface { I8 } - I9 /* DISABLED "illegal cycle" */ interface { + // Use I09 (rather than I9) because it appears lexically before + // I10 so that we get the illegal cycle here rather then in the + // declaration of I10. If the implementation sorts by position + // rather than name, the error message will still be here. + I09 /* ERROR "illegal cycle" */ interface { I10 } I10 interface { I11 } I11 interface { - I9 + I09 } C1 chan int diff --git a/libgo/go/exp/types/types.go b/libgo/go/exp/types/types.go index 85d244c..50d85b7 100644 --- a/libgo/go/exp/types/types.go +++ b/libgo/go/exp/types/types.go @@ -8,6 +8,8 @@ package types import ( + "bytes" + "fmt" "go/ast" "sort" ) @@ -17,41 +19,41 @@ type Type interface { isType() } -// All concrete types embed ImplementsType which +// All concrete types embed implementsType which // ensures that all types implement the Type interface. -type ImplementsType struct{} +type implementsType struct{} -func (t *ImplementsType) isType() {} +func (t *implementsType) isType() {} // A Bad type is a non-nil placeholder type when we don't know a type. type Bad struct { - ImplementsType + implementsType Msg string // for better error reporting/debugging } // A Basic represents a (unnamed) basic type. type Basic struct { - ImplementsType + implementsType // TODO(gri) need a field specifying the exact basic type } // An Array represents an array type [Len]Elt. type Array struct { - ImplementsType + implementsType Len uint64 Elt Type } // A Slice represents a slice type []Elt. type Slice struct { - ImplementsType + implementsType Elt Type } // A Struct represents a struct type struct{...}. // Anonymous fields are represented by objects with empty names. type Struct struct { - ImplementsType + implementsType Fields ObjList // struct fields; or nil Tags []string // corresponding tags; or nil // TODO(gri) This type needs some rethinking: @@ -62,14 +64,14 @@ type Struct struct { // A Pointer represents a pointer type *Base. type Pointer struct { - ImplementsType + implementsType Base Type } // A Func represents a function type func(...) (...). // Unnamed parameters are represented by objects with empty names. type Func struct { - ImplementsType + implementsType Recv *ast.Object // nil if not a method Params ObjList // (incoming) parameters from left to right; or nil Results ObjList // (outgoing) results from left to right; or nil @@ -78,31 +80,151 @@ type Func struct { // An Interface represents an interface type interface{...}. type Interface struct { - ImplementsType + implementsType Methods ObjList // interface methods sorted by name; or nil } // A Map represents a map type map[Key]Elt. type Map struct { - ImplementsType + implementsType Key, Elt Type } // A Chan represents a channel type chan Elt, <-chan Elt, or chan<-Elt. type Chan struct { - ImplementsType + implementsType Dir ast.ChanDir Elt Type } // A Name represents a named type as declared in a type declaration. type Name struct { - ImplementsType + implementsType Underlying Type // nil if not fully declared Obj *ast.Object // corresponding declared object // TODO(gri) need to remember fields and methods. } +func writeParams(buf *bytes.Buffer, params ObjList, isVariadic bool) { + buf.WriteByte('(') + for i, par := range params { + if i > 0 { + buf.WriteString(", ") + } + if par.Name != "" { + buf.WriteString(par.Name) + buf.WriteByte(' ') + } + if isVariadic && i == len(params)-1 { + buf.WriteString("...") + } + writeType(buf, par.Type.(Type)) + } + buf.WriteByte(')') +} + +func writeSignature(buf *bytes.Buffer, t *Func) { + writeParams(buf, t.Params, t.IsVariadic) + if len(t.Results) == 0 { + // no result + return + } + + buf.WriteByte(' ') + if len(t.Results) == 1 && t.Results[0].Name == "" { + // single unnamed result + writeType(buf, t.Results[0].Type.(Type)) + return + } + + // multiple or named result(s) + writeParams(buf, t.Results, false) +} + +func writeType(buf *bytes.Buffer, typ Type) { + switch t := typ.(type) { + case *Bad: + fmt.Fprintf(buf, "badType(%s)", t.Msg) + + case *Basic: + buf.WriteString("basicType") // TODO(gri) print actual type information + + case *Array: + fmt.Fprintf(buf, "[%d]", t.Len) + writeType(buf, t.Elt) + + case *Slice: + buf.WriteString("[]") + writeType(buf, t.Elt) + + case *Struct: + buf.WriteString("struct{") + for i, fld := range t.Fields { + if i > 0 { + buf.WriteString("; ") + } + if fld.Name != "" { + buf.WriteString(fld.Name) + buf.WriteByte(' ') + } + writeType(buf, fld.Type.(Type)) + if i < len(t.Tags) && t.Tags[i] != "" { + fmt.Fprintf(buf, " %q", t.Tags[i]) + } + } + buf.WriteByte('}') + + case *Pointer: + buf.WriteByte('*') + writeType(buf, t.Base) + + case *Func: + buf.WriteString("func") + writeSignature(buf, t) + + case *Interface: + buf.WriteString("interface{") + for i, m := range t.Methods { + if i > 0 { + buf.WriteString("; ") + } + buf.WriteString(m.Name) + writeSignature(buf, m.Type.(*Func)) + } + buf.WriteByte('}') + + case *Map: + buf.WriteString("map[") + writeType(buf, t.Key) + buf.WriteByte(']') + writeType(buf, t.Elt) + + case *Chan: + var s string + switch t.Dir { + case ast.SEND: + s = "chan<- " + case ast.RECV: + s = "<-chan " + default: + s = "chan " + } + buf.WriteString(s) + writeType(buf, t.Elt) + + case *Name: + buf.WriteString(t.Obj.Name) + + } +} + +// TypeString returns a string representation for typ. +func TypeString(typ Type) string { + var buf bytes.Buffer + writeType(&buf, typ) + return buf.String() +} + // If typ is a pointer type, Deref returns the pointer's base type; // otherwise it returns typ. func Deref(typ Type) Type { diff --git a/libgo/go/exp/types/types_test.go b/libgo/go/exp/types/types_test.go new file mode 100644 index 0000000..c49f366 --- /dev/null +++ b/libgo/go/exp/types/types_test.go @@ -0,0 +1,128 @@ +// Copyright 2012 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. + +// This file contains tests verifying the types associated with an AST after +// type checking. + +package types + +import ( + "go/ast" + "go/parser" + "testing" +) + +func makePkg(t *testing.T, src string) (*ast.Package, error) { + const filename = "<src>" + file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) + if err != nil { + return nil, err + } + files := map[string]*ast.File{filename: file} + pkg, err := ast.NewPackage(fset, files, GcImport, Universe) + if err != nil { + return nil, err + } + if _, err := Check(fset, pkg); err != nil { + return nil, err + } + return pkg, nil +} + +type testEntry struct { + src, str string +} + +// dup returns a testEntry where both src and str are the same. +func dup(s string) testEntry { + return testEntry{s, s} +} + +var testTypes = []testEntry{ + // basic types + dup("int"), + dup("float32"), + dup("string"), + + // arrays + {"[10]int", "[0]int"}, // TODO(gri) fix array length, add more array tests + + // slices + dup("[]int"), + dup("[][]int"), + + // structs + dup("struct{}"), + dup("struct{x int}"), + {`struct { + x, y int + z float32 "foo" + }`, `struct{x int; y int; z float32 "foo"}`}, + {`struct { + string + elems []T + }`, `struct{string; elems []T}`}, + + // pointers + dup("*int"), + dup("***struct{}"), + dup("*struct{a int; b float32}"), + + // functions + dup("func()"), + dup("func(x int)"), + {"func(x, y int)", "func(x int, y int)"}, + {"func(x, y int, z string)", "func(x int, y int, z string)"}, + dup("func(int)"), + dup("func(int, string, byte)"), + + dup("func() int"), + {"func() (string)", "func() string"}, + dup("func() (u int)"), + {"func() (u, v int, w string)", "func() (u int, v int, w string)"}, + + dup("func(int) string"), + dup("func(x int) string"), + dup("func(x int) (u string)"), + {"func(x, y int) (u string)", "func(x int, y int) (u string)"}, + + dup("func(...int) string"), + dup("func(x ...int) string"), + dup("func(x ...int) (u string)"), + {"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"}, + + // interfaces + dup("interface{}"), + dup("interface{m()}"), + {`interface{ + m(int) float32 + String() string + }`, `interface{String() string; m(int) float32}`}, // methods are sorted + // TODO(gri) add test for interface w/ anonymous field + + // maps + dup("map[string]int"), + {"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"}, + + // channels + dup("chan int"), + dup("chan<- func()"), + dup("<-chan []func() int"), +} + +func TestTypes(t *testing.T) { + for _, test := range testTypes { + src := "package p; type T " + test.src + pkg, err := makePkg(t, src) + if err != nil { + t.Errorf("%s: %s", src, err) + continue + } + typ := Underlying(pkg.Scope.Lookup("T").Type.(Type)) + str := TypeString(typ) + if str != test.str { + t.Errorf("%s: got %s, want %s", test.src, str, test.str) + } + } +} |