diff --git a/vendor/rsc.io/pdf/LICENSE b/vendor/rsc.io/pdf/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/rsc.io/pdf/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/rsc.io/pdf/README.md b/vendor/rsc.io/pdf/README.md new file mode 100644 index 000000000..902a7e1a5 --- /dev/null +++ b/vendor/rsc.io/pdf/README.md @@ -0,0 +1,3 @@ +go get rsc.io/pdf + +http://godoc.org/rsc.io/pdf diff --git a/vendor/rsc.io/pdf/lex.go b/vendor/rsc.io/pdf/lex.go new file mode 100644 index 000000000..ee73fd927 --- /dev/null +++ b/vendor/rsc.io/pdf/lex.go @@ -0,0 +1,529 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Reading of PDF tokens and objects from a raw byte stream. + +package pdf + +import ( + "fmt" + "io" + "strconv" +) + +// A token is a PDF token in the input stream, one of the following Go types: +// +// bool, a PDF boolean +// int64, a PDF integer +// float64, a PDF real +// string, a PDF string literal +// keyword, a PDF keyword +// name, a PDF name without the leading slash +// +type token interface{} + +// A name is a PDF name, without the leading slash. +type name string + +// A keyword is a PDF keyword. +// Delimiter tokens used in higher-level syntax, +// such as "<<", ">>", "[", "]", "{", "}", are also treated as keywords. +type keyword string + +// A buffer holds buffered input bytes from the PDF file. +type buffer struct { + r io.Reader // source of data + buf []byte // buffered data + pos int // read index in buf + offset int64 // offset at end of buf; aka offset of next read + tmp []byte // scratch space for accumulating token + unread []token // queue of read but then unread tokens + allowEOF bool + allowObjptr bool + allowStream bool + eof bool + key []byte + useAES bool + objptr objptr +} + +// newBuffer returns a new buffer reading from r at the given offset. +func newBuffer(r io.Reader, offset int64) *buffer { + return &buffer{ + r: r, + offset: offset, + buf: make([]byte, 0, 4096), + allowObjptr: true, + allowStream: true, + } +} + +func (b *buffer) seek(offset int64) { + b.offset = offset + b.buf = b.buf[:0] + b.pos = 0 + b.unread = b.unread[:0] +} + +func (b *buffer) readByte() byte { + if b.pos >= len(b.buf) { + b.reload() + if b.pos >= len(b.buf) { + return '\n' + } + } + c := b.buf[b.pos] + b.pos++ + return c +} + +func (b *buffer) errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} + +func (b *buffer) reload() bool { + n := cap(b.buf) - int(b.offset%int64(cap(b.buf))) + n, err := b.r.Read(b.buf[:n]) + if n == 0 && err != nil { + b.buf = b.buf[:0] + b.pos = 0 + if b.allowEOF && err == io.EOF { + b.eof = true + return false + } + b.errorf("malformed PDF: reading at offset %d: %v", b.offset, err) + return false + } + b.offset += int64(n) + b.buf = b.buf[:n] + b.pos = 0 + return true +} + +func (b *buffer) seekForward(offset int64) { + for b.offset < offset { + if !b.reload() { + return + } + } + b.pos = len(b.buf) - int(b.offset-offset) +} + +func (b *buffer) readOffset() int64 { + return b.offset - int64(len(b.buf)) + int64(b.pos) +} + +func (b *buffer) unreadByte() { + if b.pos > 0 { + b.pos-- + } +} + +func (b *buffer) unreadToken(t token) { + b.unread = append(b.unread, t) +} + +func (b *buffer) readToken() token { + if n := len(b.unread); n > 0 { + t := b.unread[n-1] + b.unread = b.unread[:n-1] + return t + } + + // Find first non-space, non-comment byte. + c := b.readByte() + for { + if isSpace(c) { + if b.eof { + return io.EOF + } + c = b.readByte() + } else if c == '%' { + for c != '\r' && c != '\n' { + c = b.readByte() + } + } else { + break + } + } + + switch c { + case '<': + if b.readByte() == '<' { + return keyword("<<") + } + b.unreadByte() + return b.readHexString() + + case '(': + return b.readLiteralString() + + case '[', ']', '{', '}': + return keyword(string(c)) + + case '/': + return b.readName() + + case '>': + if b.readByte() == '>' { + return keyword(">>") + } + b.unreadByte() + fallthrough + + default: + if isDelim(c) { + b.errorf("unexpected delimiter %#q", rune(c)) + return nil + } + b.unreadByte() + return b.readKeyword() + } +} + +func (b *buffer) readHexString() token { + tmp := b.tmp[:0] + for { + Loop: + c := b.readByte() + if c == '>' { + break + } + if isSpace(c) { + goto Loop + } + Loop2: + c2 := b.readByte() + if isSpace(c2) { + goto Loop2 + } + x := unhex(c)<<4 | unhex(c2) + if x < 0 { + b.errorf("malformed hex string %c %c %s", c, c2, b.buf[b.pos:]) + break + } + tmp = append(tmp, byte(x)) + } + b.tmp = tmp + return string(tmp) +} + +func unhex(b byte) int { + switch { + case '0' <= b && b <= '9': + return int(b) - '0' + case 'a' <= b && b <= 'f': + return int(b) - 'a' + 10 + case 'A' <= b && b <= 'F': + return int(b) - 'A' + 10 + } + return -1 +} + +func (b *buffer) readLiteralString() token { + tmp := b.tmp[:0] + depth := 1 +Loop: + for { + c := b.readByte() + switch c { + default: + tmp = append(tmp, c) + case '(': + depth++ + tmp = append(tmp, c) + case ')': + if depth--; depth == 0 { + break Loop + } + tmp = append(tmp, c) + case '\\': + switch c = b.readByte(); c { + default: + b.errorf("invalid escape sequence \\%c", c) + tmp = append(tmp, '\\', c) + case 'n': + tmp = append(tmp, '\n') + case 'r': + tmp = append(tmp, '\r') + case 'b': + tmp = append(tmp, '\b') + case 't': + tmp = append(tmp, '\t') + case 'f': + tmp = append(tmp, '\f') + case '(', ')', '\\': + tmp = append(tmp, c) + case '\r': + if b.readByte() != '\n' { + b.unreadByte() + } + fallthrough + case '\n': + // no append + case '0', '1', '2', '3', '4', '5', '6', '7': + x := int(c - '0') + for i := 0; i < 2; i++ { + c = b.readByte() + if c < '0' || c > '7' { + b.unreadByte() + break + } + x = x*8 + int(c-'0') + } + if x > 255 { + b.errorf("invalid octal escape \\%03o", x) + } + tmp = append(tmp, byte(x)) + } + } + } + b.tmp = tmp + return string(tmp) +} + +func (b *buffer) readName() token { + tmp := b.tmp[:0] + for { + c := b.readByte() + if isDelim(c) || isSpace(c) { + b.unreadByte() + break + } + if c == '#' { + x := unhex(b.readByte())<<4 | unhex(b.readByte()) + if x < 0 { + b.errorf("malformed name") + } + tmp = append(tmp, byte(x)) + continue + } + tmp = append(tmp, c) + } + b.tmp = tmp + return name(string(tmp)) +} + +func (b *buffer) readKeyword() token { + tmp := b.tmp[:0] + for { + c := b.readByte() + if isDelim(c) || isSpace(c) { + b.unreadByte() + break + } + tmp = append(tmp, c) + } + b.tmp = tmp + s := string(tmp) + switch { + case s == "true": + return true + case s == "false": + return false + case isInteger(s): + x, err := strconv.ParseInt(s, 10, 64) + if err != nil { + b.errorf("invalid integer %s", s) + } + return x + case isReal(s): + x, err := strconv.ParseFloat(s, 64) + if err != nil { + b.errorf("invalid real %s", s) + } + return x + } + return keyword(string(tmp)) +} + +func isInteger(s string) bool { + if len(s) > 0 && (s[0] == '+' || s[0] == '-') { + s = s[1:] + } + if len(s) == 0 { + return false + } + for _, c := range s { + if c < '0' || '9' < c { + return false + } + } + return true +} + +func isReal(s string) bool { + if len(s) > 0 && (s[0] == '+' || s[0] == '-') { + s = s[1:] + } + if len(s) == 0 { + return false + } + ndot := 0 + for _, c := range s { + if c == '.' { + ndot++ + continue + } + if c < '0' || '9' < c { + return false + } + } + return ndot == 1 +} + +// An object is a PDF syntax object, one of the following Go types: +// +// bool, a PDF boolean +// int64, a PDF integer +// float64, a PDF real +// string, a PDF string literal +// name, a PDF name without the leading slash +// dict, a PDF dictionary +// array, a PDF array +// stream, a PDF stream +// objptr, a PDF object reference +// objdef, a PDF object definition +// +// An object may also be nil, to represent the PDF null. +type object interface{} + +type dict map[name]object + +type array []object + +type stream struct { + hdr dict + ptr objptr + offset int64 +} + +type objptr struct { + id uint32 + gen uint16 +} + +type objdef struct { + ptr objptr + obj object +} + +func (b *buffer) readObject() object { + tok := b.readToken() + if kw, ok := tok.(keyword); ok { + switch kw { + case "null": + return nil + case "<<": + return b.readDict() + case "[": + return b.readArray() + } + b.errorf("unexpected keyword %q parsing object", kw) + return nil + } + + if str, ok := tok.(string); ok && b.key != nil && b.objptr.id != 0 { + tok = decryptString(b.key, b.useAES, b.objptr, str) + } + + if !b.allowObjptr { + return tok + } + + if t1, ok := tok.(int64); ok && int64(uint32(t1)) == t1 { + tok2 := b.readToken() + if t2, ok := tok2.(int64); ok && int64(uint16(t2)) == t2 { + tok3 := b.readToken() + switch tok3 { + case keyword("R"): + return objptr{uint32(t1), uint16(t2)} + case keyword("obj"): + old := b.objptr + b.objptr = objptr{uint32(t1), uint16(t2)} + obj := b.readObject() + if _, ok := obj.(stream); !ok { + tok4 := b.readToken() + if tok4 != keyword("endobj") { + b.errorf("missing endobj after indirect object definition") + b.unreadToken(tok4) + } + } + b.objptr = old + return objdef{objptr{uint32(t1), uint16(t2)}, obj} + } + b.unreadToken(tok3) + } + b.unreadToken(tok2) + } + return tok +} + +func (b *buffer) readArray() object { + var x array + for { + tok := b.readToken() + if tok == nil || tok == keyword("]") { + break + } + b.unreadToken(tok) + x = append(x, b.readObject()) + } + return x +} + +func (b *buffer) readDict() object { + x := make(dict) + for { + tok := b.readToken() + if tok == nil || tok == keyword(">>") { + break + } + n, ok := tok.(name) + if !ok { + b.errorf("unexpected non-name key %T(%v) parsing dictionary", tok, tok) + continue + } + x[n] = b.readObject() + } + + if !b.allowStream { + return x + } + + tok := b.readToken() + if tok != keyword("stream") { + b.unreadToken(tok) + return x + } + + switch b.readByte() { + case '\r': + if b.readByte() != '\n' { + b.unreadByte() + } + case '\n': + // ok + default: + b.errorf("stream keyword not followed by newline") + } + + return stream{x, b.objptr, b.readOffset()} +} + +func isSpace(b byte) bool { + switch b { + case '\x00', '\t', '\n', '\f', '\r', ' ': + return true + } + return false +} + +func isDelim(b byte) bool { + switch b { + case '<', '>', '(', ')', '[', ']', '{', '}', '/', '%': + return true + } + return false +} diff --git a/vendor/rsc.io/pdf/name.go b/vendor/rsc.io/pdf/name.go new file mode 100644 index 000000000..38257843c --- /dev/null +++ b/vendor/rsc.io/pdf/name.go @@ -0,0 +1,4286 @@ +// Derived from http://www.jdawiseman.com/papers/trivia/character-entities.html + +package pdf + +var nameToRune = map[string]rune{ + "nbspace": 0x00A0, + "nonbreakingspace": 0x00A0, + "exclamdown": 0x00A1, + "cent": 0x00A2, + "sterling": 0x00A3, + "currency": 0x00A4, + "yen": 0x00A5, + "brokenbar": 0x00A6, + "section": 0x00A7, + "dieresis": 0x00A8, + "copyright": 0x00A9, + "ordfeminine": 0x00AA, + "guillemotleft": 0x00AB, + "logicalnot": 0x00AC, + "sfthyphen": 0x00AD, + "softhyphen": 0x00AD, + "registered": 0x00AE, + "macron": 0x00AF, + "overscore": 0x00AF, + "degree": 0x00B0, + "plusminus": 0x00B1, + "twosuperior": 0x00B2, + "threesuperior": 0x00B3, + "acute": 0x00B4, + "mu": 0x00B5, + "mu1": 0x00B5, + "paragraph": 0x00B6, + "middot": 0x00B7, + "periodcentered": 0x00B7, + "cedilla": 0x00B8, + "onesuperior": 0x00B9, + "ordmasculine": 0x00BA, + "guillemotright": 0x00BB, + "onequarter": 0x00BC, + "onehalf": 0x00BD, + "threequarters": 0x00BE, + "questiondown": 0x00BF, + "Agrave": 0x00C0, + "Aacute": 0x00C1, + "Acircumflex": 0x00C2, + "Atilde": 0x00C3, + "Adieresis": 0x00C4, + "Aring": 0x00C5, + "AE": 0x00C6, + "Ccedilla": 0x00C7, + "Egrave": 0x00C8, + "Eacute": 0x00C9, + "Ecircumflex": 0x00CA, + "Edieresis": 0x00CB, + "Igrave": 0x00CC, + "Iacute": 0x00CD, + "Icircumflex": 0x00CE, + "Idieresis": 0x00CF, + "Eth": 0x00D0, + "Ntilde": 0x00D1, + "Ograve": 0x00D2, + "Oacute": 0x00D3, + "Ocircumflex": 0x00D4, + "Otilde": 0x00D5, + "Odieresis": 0x00D6, + "multiply": 0x00D7, + "Oslash": 0x00D8, + "Ugrave": 0x00D9, + "Uacute": 0x00DA, + "Ucircumflex": 0x00DB, + "Udieresis": 0x00DC, + "Yacute": 0x00DD, + "Thorn": 0x00DE, + "germandbls": 0x00DF, + "agrave": 0x00E0, + "aacute": 0x00E1, + "acircumflex": 0x00E2, + "atilde": 0x00E3, + "adieresis": 0x00E4, + "aring": 0x00E5, + "ae": 0x00E6, + "ccedilla": 0x00E7, + "egrave": 0x00E8, + "eacute": 0x00E9, + "ecircumflex": 0x00EA, + "edieresis": 0x00EB, + "igrave": 0x00EC, + "iacute": 0x00ED, + "icircumflex": 0x00EE, + "idieresis": 0x00EF, + "eth": 0x00F0, + "ntilde": 0x00F1, + "ograve": 0x00F2, + "oacute": 0x00F3, + "ocircumflex": 0x00F4, + "otilde": 0x00F5, + "odieresis": 0x00F6, + "divide": 0x00F7, + "oslash": 0x00F8, + "ugrave": 0x00F9, + "uacute": 0x00FA, + "ucircumflex": 0x00FB, + "udieresis": 0x00FC, + "yacute": 0x00FD, + "thorn": 0x00FE, + "ydieresis": 0x00FF, + "florin": 0x0192, + "Alpha": 0x0391, + "Beta": 0x0392, + "Gamma": 0x0393, + "Deltagreek": 0x0394, + "Epsilon": 0x0395, + "Zeta": 0x0396, + "Eta": 0x0397, + "Theta": 0x0398, + "Iota": 0x0399, + "Kappa": 0x039A, + "Lambda": 0x039B, + "Mu": 0x039C, + "Nu": 0x039D, + "Xi": 0x039E, + "Omicron": 0x039F, + "Pi": 0x03A0, + "Rho": 0x03A1, + "Sigma": 0x03A3, + "Tau": 0x03A4, + "Upsilon": 0x03A5, + "Phi": 0x03A6, + "Chi": 0x03A7, + "Psi": 0x03A8, + "Omegagreek": 0x03A9, + "alpha": 0x03B1, + "beta": 0x03B2, + "gamma": 0x03B3, + "delta": 0x03B4, + "epsilon": 0x03B5, + "zeta": 0x03B6, + "eta": 0x03B7, + "theta": 0x03B8, + "iota": 0x03B9, + "kappa": 0x03BA, + "lambda": 0x03BB, + "mugreek": 0x03BC, + "nu": 0x03BD, + "xi": 0x03BE, + "omicron": 0x03BF, + "pi": 0x03C0, + "rho": 0x03C1, + "sigma1": 0x03C2, + "sigmafinal": 0x03C2, + "sigma": 0x03C3, + "tau": 0x03C4, + "upsilon": 0x03C5, + "phi": 0x03C6, + "chi": 0x03C7, + "psi": 0x03C8, + "omega": 0x03C9, + "theta1": 0x03D1, + "thetasymbolgreek": 0x03D1, + "Upsilon1": 0x03D2, + "Upsilonhooksymbol": 0x03D2, + "omega1": 0x03D6, + "pisymbolgreek": 0x03D6, + "bullet": 0x2022, + "ellipsis": 0x2026, + "minute": 0x2032, + "second": 0x2033, + "overline": 0x203E, + "fraction": 0x2044, + "weierstrass": 0x2118, + "Ifraktur": 0x2111, + "Rfraktur": 0x211C, + "trademark": 0x2122, + "aleph": 0x2135, + "arrowleft": 0x2190, + "arrowup": 0x2191, + "arrowright": 0x2192, + "arrowdown": 0x2193, + "arrowboth": 0x2194, + "carriagereturn": 0x21B5, + "arrowdblleft": 0x21D0, + "arrowleftdbl": 0x21D0, + "arrowdblup": 0x21D1, + "arrowdblright": 0x21D2, + "dblarrowright": 0x21D2, + "arrowdbldown": 0x21D3, + "arrowdblboth": 0x21D4, + "dblarrowleft": 0x21D4, + "forall": 0x2200, + "universal": 0x2200, + "partialdiff": 0x2202, + "existential": 0x2203, + "thereexists": 0x2203, + "emptyset": 0x2205, + "gradient": 0x2207, + "nabla": 0x2207, + "element": 0x2208, + "notelement": 0x2209, + "notelementof": 0x2209, + "suchthat": 0x220B, + "product": 0x220F, + "summation": 0x2211, + "minus": 0x2212, + "asteriskmath": 0x2217, + "radical": 0x221A, + "proportional": 0x221D, + "infinity": 0x221E, + "angle": 0x2220, + "logicaland": 0x2227, + "logicalor": 0x2228, + "intersection": 0x2229, + "union": 0x222A, + "integral": 0x222B, + "therefore": 0x2234, + "similar": 0x223C, + "tildeoperator": 0x223C, + "approximatelyequal": 0x2245, + "congruent": 0x2245, + "approxequal": 0x2248, + "notequal": 0x2260, + "equivalence": 0x2261, + "lessequal": 0x2264, + "greaterequal": 0x2265, + "propersubset": 0x2282, + "subset": 0x2282, + "propersuperset": 0x2283, + "superset": 0x2283, + "notsubset": 0x2284, + "reflexsubset": 0x2286, + "subsetorequal": 0x2286, + "reflexsuperset": 0x2287, + "supersetorequal": 0x2287, + "circleplus": 0x2295, + "pluscircle": 0x2295, + "circlemultiply": 0x2297, + "timescircle": 0x2297, + "perpendicular": 0x22A5, + "dotmath": 0x22C5, + "angleleft": 0x2329, + "angleright": 0x232A, + "lozenge": 0x25CA, + "spade": 0x2660, + "spadesuitblack": 0x2660, + "club": 0x2663, + "clubsuitblack": 0x2663, + "heart": 0x2665, + "heartsuitblack": 0x2665, + "diamond": 0x2666, + "quotedbl": 0x0022, + "ampersand": 0x0026, + "less": 0x003C, + "greater": 0x003E, + "OE": 0x0152, + "oe": 0x0153, + "Scaron": 0x0160, + "scaron": 0x0161, + "Ydieresis": 0x0178, + "circumflex": 0x02C6, + "ilde": 0x02DC, + "tilde": 0x02DC, + "enspace": 0x2002, + "afii61664": 0x200C, + "zerowidthnonjoiner": 0x200C, + "afii301": 0x200D, + "afii299": 0x200E, + "afii300": 0x200F, + "endash": 0x2013, + "emdash": 0x2014, + "quoteleft": 0x2018, + "quoteright": 0x2019, + "quotesinglbase": 0x201A, + "quotedblleft": 0x201C, + "quotedblright": 0x201D, + "quotedblbase": 0x201E, + "dagger": 0x2020, + "daggerdbl": 0x2021, + "perthousand": 0x2030, + "guilsinglleft": 0x2039, + "guilsinglright": 0x203A, + "Euro": 0x20AC, + "controlSTX": 0x0001, + "controlSOT": 0x0002, + "controlETX": 0x0003, + "controlEOT": 0x0004, + "controlENQ": 0x0005, + "controlACK": 0x0006, + "controlBEL": 0x0007, + "controlBS": 0x0008, + "controlHT": 0x0009, + "controlLF": 0x000A, + "controlVT": 0x000B, + "controlFF": 0x000C, + "controlCR": 0x000D, + "controlSO": 0x000E, + "controlSI": 0x000F, + "controlDLE": 0x0010, + "controlDC1": 0x0011, + "controlDC2": 0x0012, + "controlDC3": 0x0013, + "controlDC4": 0x0014, + "controlNAK": 0x0015, + "controlSYN": 0x0016, + "controlETB": 0x0017, + "controlCAN": 0x0018, + "controlEM": 0x0019, + "controlSUB": 0x001A, + "controlESC": 0x001B, + "controlFS": 0x001C, + "controlGS": 0x001D, + "controlRS": 0x001E, + "controlUS": 0x001F, + "space": 0x0020, + "spacehackarabic": 0x0020, + "exclam": 0x0021, + "numbersign": 0x0023, + "dollar": 0x0024, + "percent": 0x0025, + "quotesingle": 0x0027, + "parenleft": 0x0028, + "parenright": 0x0029, + "asterisk": 0x002A, + "plus": 0x002B, + "comma": 0x002C, + "hyphen": 0x002D, + "period": 0x002E, + "slash": 0x002F, + "zero": 0x0030, + "one": 0x0031, + "two": 0x0032, + "three": 0x0033, + "four": 0x0034, + "five": 0x0035, + "six": 0x0036, + "seven": 0x0037, + "eight": 0x0038, + "nine": 0x0039, + "colon": 0x003A, + "semicolon": 0x003B, + "equal": 0x003D, + "question": 0x003F, + "at": 0x0040, + "A": 0x0041, + "B": 0x0042, + "C": 0x0043, + "D": 0x0044, + "E": 0x0045, + "F": 0x0046, + "G": 0x0047, + "H": 0x0048, + "I": 0x0049, + "J": 0x004A, + "K": 0x004B, + "L": 0x004C, + "M": 0x004D, + "N": 0x004E, + "O": 0x004F, + "P": 0x0050, + "Q": 0x0051, + "R": 0x0052, + "S": 0x0053, + "T": 0x0054, + "U": 0x0055, + "V": 0x0056, + "W": 0x0057, + "X": 0x0058, + "Y": 0x0059, + "Z": 0x005A, + "bracketleft": 0x005B, + "backslash": 0x005C, + "bracketright": 0x005D, + "asciicircum": 0x005E, + "underscore": 0x005F, + "grave": 0x0060, + "a": 0x0061, + "b": 0x0062, + "c": 0x0063, + "d": 0x0064, + "e": 0x0065, + "f": 0x0066, + "g": 0x0067, + "h": 0x0068, + "i": 0x0069, + "j": 0x006A, + "k": 0x006B, + "l": 0x006C, + "m": 0x006D, + "n": 0x006E, + "o": 0x006F, + "p": 0x0070, + "q": 0x0071, + "r": 0x0072, + "s": 0x0073, + "t": 0x0074, + "u": 0x0075, + "v": 0x0076, + "w": 0x0077, + "x": 0x0078, + "y": 0x0079, + "z": 0x007A, + "braceleft": 0x007B, + "bar": 0x007C, + "verticalbar": 0x007C, + "braceright": 0x007D, + "asciitilde": 0x007E, + "controlDEL": 0x007F, + "Amacron": 0x0100, + "amacron": 0x0101, + "Abreve": 0x0102, + "abreve": 0x0103, + "Aogonek": 0x0104, + "aogonek": 0x0105, + "Cacute": 0x0106, + "cacute": 0x0107, + "Ccircumflex": 0x0108, + "ccircumflex": 0x0109, + "Cdot": 0x010A, + "Cdotaccent": 0x010A, + "cdot": 0x010B, + "cdotaccent": 0x010B, + "Ccaron": 0x010C, + "ccaron": 0x010D, + "Dcaron": 0x010E, + "dcaron": 0x010F, + "Dcroat": 0x0110, + "Dslash": 0x0110, + "dcroat": 0x0111, + "dmacron": 0x0111, + "Emacron": 0x0112, + "emacron": 0x0113, + "Ebreve": 0x0114, + "ebreve": 0x0115, + "Edot": 0x0116, + "Edotaccent": 0x0116, + "edot": 0x0117, + "edotaccent": 0x0117, + "Eogonek": 0x0118, + "eogonek": 0x0119, + "Ecaron": 0x011A, + "ecaron": 0x011B, + "Gcircumflex": 0x011C, + "gcircumflex": 0x011D, + "Gbreve": 0x011E, + "gbreve": 0x011F, + "Gdot": 0x0120, + "Gdotaccent": 0x0120, + "gdot": 0x0121, + "gdotaccent": 0x0121, + "Gcedilla": 0x0122, + "Gcommaaccent": 0x0122, + "gcedilla": 0x0123, + "gcommaaccent": 0x0123, + "Hcircumflex": 0x0124, + "hcircumflex": 0x0125, + "Hbar": 0x0126, + "hbar": 0x0127, + "Itilde": 0x0128, + "itilde": 0x0129, + "Imacron": 0x012A, + "imacron": 0x012B, + "Ibreve": 0x012C, + "ibreve": 0x012D, + "Iogonek": 0x012E, + "iogonek": 0x012F, + "Idot": 0x0130, + "Idotaccent": 0x0130, + "dotlessi": 0x0131, + "IJ": 0x0132, + "ij": 0x0133, + "Jcircumflex": 0x0134, + "jcircumflex": 0x0135, + "Kcedilla": 0x0136, + "Kcommaaccent": 0x0136, + "kcedilla": 0x0137, + "kcommaaccent": 0x0137, + "kgreenlandic": 0x0138, + "Lacute": 0x0139, + "lacute": 0x013A, + "Lcedilla": 0x013B, + "Lcommaaccent": 0x013B, + "lcedilla": 0x013C, + "lcommaaccent": 0x013C, + "Lcaron": 0x013D, + "lcaron": 0x013E, + "Ldot": 0x013F, + "Ldotaccent": 0x013F, + "ldot": 0x0140, + "ldotaccent": 0x0140, + "Lslash": 0x0141, + "lslash": 0x0142, + "Nacute": 0x0143, + "nacute": 0x0144, + "Ncedilla": 0x0145, + "Ncommaaccent": 0x0145, + "ncedilla": 0x0146, + "ncommaaccent": 0x0146, + "Ncaron": 0x0147, + "ncaron": 0x0148, + "napostrophe": 0x0149, + "quoterightn": 0x0149, + "Eng": 0x014A, + "eng": 0x014B, + "Omacron": 0x014C, + "omacron": 0x014D, + "Obreve": 0x014E, + "obreve": 0x014F, + "Odblacute": 0x0150, + "Ohungarumlaut": 0x0150, + "odblacute": 0x0151, + "ohungarumlaut": 0x0151, + "Racute": 0x0154, + "racute": 0x0155, + "Rcedilla": 0x0156, + "Rcommaaccent": 0x0156, + "rcedilla": 0x0157, + "rcommaaccent": 0x0157, + "Rcaron": 0x0158, + "rcaron": 0x0159, + "Sacute": 0x015A, + "sacute": 0x015B, + "Scircumflex": 0x015C, + "scircumflex": 0x015D, + "Scedilla": 0x015E, + "scedilla": 0x015F, + "Tcedilla": 0x0162, + "Tcommaaccent": 0x0162, + "tcedilla": 0x0163, + "tcommaaccent": 0x0163, + "Tcaron": 0x0164, + "tcaron": 0x0165, + "Tbar": 0x0166, + "tbar": 0x0167, + "Utilde": 0x0168, + "utilde": 0x0169, + "Umacron": 0x016A, + "umacron": 0x016B, + "Ubreve": 0x016C, + "ubreve": 0x016D, + "Uring": 0x016E, + "uring": 0x016F, + "Udblacute": 0x0170, + "Uhungarumlaut": 0x0170, + "udblacute": 0x0171, + "uhungarumlaut": 0x0171, + "Uogonek": 0x0172, + "uogonek": 0x0173, + "Wcircumflex": 0x0174, + "wcircumflex": 0x0175, + "Ycircumflex": 0x0176, + "ycircumflex": 0x0177, + "Zacute": 0x0179, + "zacute": 0x017A, + "Zdot": 0x017B, + "Zdotaccent": 0x017B, + "zdot": 0x017C, + "zdotaccent": 0x017C, + "Zcaron": 0x017D, + "zcaron": 0x017E, + "longs": 0x017F, + "slong": 0x017F, + "bstroke": 0x0180, + "Bhook": 0x0181, + "Btopbar": 0x0182, + "btopbar": 0x0183, + "Tonesix": 0x0184, + "tonesix": 0x0185, + "Oopen": 0x0186, + "Chook": 0x0187, + "chook": 0x0188, + "Dafrican": 0x0189, + "Dhook": 0x018A, + "Dtopbar": 0x018B, + "dtopbar": 0x018C, + "deltaturned": 0x018D, + "Ereversed": 0x018E, + "Schwa": 0x018F, + "Eopen": 0x0190, + "Fhook": 0x0191, + "Ghook": 0x0193, + "Gammaafrican": 0x0194, + "hv": 0x0195, + "Iotaafrican": 0x0196, + "Istroke": 0x0197, + "Khook": 0x0198, + "khook": 0x0199, + "lbar": 0x019A, + "lambdastroke": 0x019B, + "Mturned": 0x019C, + "Nhookleft": 0x019D, + "nlegrightlong": 0x019E, + "Ocenteredtilde": 0x019F, + "Ohorn": 0x01A0, + "ohorn": 0x01A1, + "Oi": 0x01A2, + "oi": 0x01A3, + "Phook": 0x01A4, + "phook": 0x01A5, + "yr": 0x01A6, + "Tonetwo": 0x01A7, + "tonetwo": 0x01A8, + "Esh": 0x01A9, + "eshreversedloop": 0x01AA, + "tpalatalhook": 0x01AB, + "Thook": 0x01AC, + "thook": 0x01AD, + "Tretroflexhook": 0x01AE, + "Uhorn": 0x01AF, + "uhorn": 0x01B0, + "Upsilonafrican": 0x01B1, + "Vhook": 0x01B2, + "Yhook": 0x01B3, + "yhook": 0x01B4, + "Zstroke": 0x01B5, + "zstroke": 0x01B6, + "Ezh": 0x01B7, + "Ezhreversed": 0x01B8, + "ezhreversed": 0x01B9, + "ezhtail": 0x01BA, + "twostroke": 0x01BB, + "Tonefive": 0x01BC, + "tonefive": 0x01BD, + "glottalinvertedstroke": 0x01BE, + "wynn": 0x01BF, + "clickdental": 0x01C0, + "clicklateral": 0x01C1, + "clickalveolar": 0x01C2, + "clickretroflex": 0x01C3, + "DZcaron": 0x01C4, + "Dzcaron": 0x01C5, + "dzcaron": 0x01C6, + "LJ": 0x01C7, + "Lj": 0x01C8, + "lj": 0x01C9, + "NJ": 0x01CA, + "Nj": 0x01CB, + "nj": 0x01CC, + "Acaron": 0x01CD, + "acaron": 0x01CE, + "Icaron": 0x01CF, + "icaron": 0x01D0, + "Ocaron": 0x01D1, + "ocaron": 0x01D2, + "Ucaron": 0x01D3, + "ucaron": 0x01D4, + "Udieresismacron": 0x01D5, + "udieresismacron": 0x01D6, + "Udieresisacute": 0x01D7, + "udieresisacute": 0x01D8, + "Udieresiscaron": 0x01D9, + "udieresiscaron": 0x01DA, + "Udieresisgrave": 0x01DB, + "udieresisgrave": 0x01DC, + "eturned": 0x01DD, + "Adieresismacron": 0x01DE, + "adieresismacron": 0x01DF, + "Adotmacron": 0x01E0, + "adotmacron": 0x01E1, + "AEmacron": 0x01E2, + "aemacron": 0x01E3, + "Gstroke": 0x01E4, + "gstroke": 0x01E5, + "Gcaron": 0x01E6, + "gcaron": 0x01E7, + "Kcaron": 0x01E8, + "kcaron": 0x01E9, + "Oogonek": 0x01EA, + "oogonek": 0x01EB, + "Oogonekmacron": 0x01EC, + "oogonekmacron": 0x01ED, + "Ezhcaron": 0x01EE, + "ezhcaron": 0x01EF, + "jcaron": 0x01F0, + "DZ": 0x01F1, + "Dz": 0x01F2, + "dz": 0x01F3, + "Gacute": 0x01F4, + "gacute": 0x01F5, + "Aringacute": 0x01FA, + "aringacute": 0x01FB, + "AEacute": 0x01FC, + "aeacute": 0x01FD, + "Oslashacute": 0x01FE, + "Ostrokeacute": 0x01FE, + "oslashacute": 0x01FF, + "ostrokeacute": 0x01FF, + "Adblgrave": 0x0200, + "adblgrave": 0x0201, + "Ainvertedbreve": 0x0202, + "ainvertedbreve": 0x0203, + "Edblgrave": 0x0204, + "edblgrave": 0x0205, + "Einvertedbreve": 0x0206, + "einvertedbreve": 0x0207, + "Idblgrave": 0x0208, + "idblgrave": 0x0209, + "Iinvertedbreve": 0x020A, + "iinvertedbreve": 0x020B, + "Odblgrave": 0x020C, + "odblgrave": 0x020D, + "Oinvertedbreve": 0x020E, + "oinvertedbreve": 0x020F, + "Rdblgrave": 0x0210, + "rdblgrave": 0x0211, + "Rinvertedbreve": 0x0212, + "rinvertedbreve": 0x0213, + "Udblgrave": 0x0214, + "udblgrave": 0x0215, + "Uinvertedbreve": 0x0216, + "uinvertedbreve": 0x0217, + "Scommaaccent": 0x0218, + "scommaaccent": 0x0219, + "aturned": 0x0250, + "ascript": 0x0251, + "ascriptturned": 0x0252, + "bhook": 0x0253, + "oopen": 0x0254, + "ccurl": 0x0255, + "dtail": 0x0256, + "dhook": 0x0257, + "ereversed": 0x0258, + "schwa": 0x0259, + "schwahook": 0x025A, + "eopen": 0x025B, + "eopenreversed": 0x025C, + "eopenreversedhook": 0x025D, + "eopenreversedclosed": 0x025E, + "jdotlessstroke": 0x025F, + "ghook": 0x0260, + "gscript": 0x0261, + "gammalatinsmall": 0x0263, + "ramshorn": 0x0264, + "hturned": 0x0265, + "hhook": 0x0266, + "henghook": 0x0267, + "istroke": 0x0268, + "iotalatin": 0x0269, + "lmiddletilde": 0x026B, + "lbelt": 0x026C, + "lhookretroflex": 0x026D, + "lezh": 0x026E, + "mturned": 0x026F, + "mlonglegturned": 0x0270, + "mhook": 0x0271, + "nhookleft": 0x0272, + "nhookretroflex": 0x0273, + "obarred": 0x0275, + "omegalatinclosed": 0x0277, + "philatin": 0x0278, + "rturned": 0x0279, + "rlonglegturned": 0x027A, + "rhookturned": 0x027B, + "rlongleg": 0x027C, + "rhook": 0x027D, + "rfishhook": 0x027E, + "rfishhookreversed": 0x027F, + "Rsmallinverted": 0x0281, + "shook": 0x0282, + "esh": 0x0283, + "dotlessjstrokehook": 0x0284, + "eshsquatreversed": 0x0285, + "eshcurl": 0x0286, + "tturned": 0x0287, + "tretroflexhook": 0x0288, + "ubar": 0x0289, + "upsilonlatin": 0x028A, + "vhook": 0x028B, + "vturned": 0x028C, + "wturned": 0x028D, + "yturned": 0x028E, + "zretroflexhook": 0x0290, + "zcurl": 0x0291, + "ezh": 0x0292, + "ezhcurl": 0x0293, + "glottalstop": 0x0294, + "glottalstopreversed": 0x0295, + "glottalstopinverted": 0x0296, + "cstretched": 0x0297, + "bilabialclick": 0x0298, + "eopenclosed": 0x029A, + "Gsmallhook": 0x029B, + "jcrossedtail": 0x029D, + "kturned": 0x029E, + "qhook": 0x02A0, + "glottalstopstroke": 0x02A1, + "glottalstopstrokereversed": 0x02A2, + "dzaltone": 0x02A3, + "dezh": 0x02A4, + "dzcurl": 0x02A5, + "ts": 0x02A6, + "tesh": 0x02A7, + "tccurl": 0x02A8, + "hsuperior": 0x02B0, + "hhooksuperior": 0x02B1, + "jsuperior": 0x02B2, + "rturnedsuperior": 0x02B4, + "rhookturnedsuperior": 0x02B5, + "Rsmallinvertedsuperior": 0x02B6, + "wsuperior": 0x02B7, + "ysuperior": 0x02B8, + "primemod": 0x02B9, + "dblprimemod": 0x02BA, + "commaturnedmod": 0x02BB, + "afii57929": 0x02BC, + "apostrophemod": 0x02BC, + "afii64937": 0x02BD, + "commareversedmod": 0x02BD, + "ringhalfright": 0x02BE, + "ringhalfleft": 0x02BF, + "glottalstopmod": 0x02C0, + "glottalstopreversedmod": 0x02C1, + "arrowheadleftmod": 0x02C2, + "arrowheadrightmod": 0x02C3, + "arrowheadupmod": 0x02C4, + "arrowheaddownmod": 0x02C5, + "caron": 0x02C7, + "verticallinemod": 0x02C8, + "firsttonechinese": 0x02C9, + "secondtonechinese": 0x02CA, + "fourthtonechinese": 0x02CB, + "verticallinelowmod": 0x02CC, + "macronlowmod": 0x02CD, + "gravelowmod": 0x02CE, + "acutelowmod": 0x02CF, + "colontriangularmod": 0x02D0, + "colontriangularhalfmod": 0x02D1, + "ringhalfrightcentered": 0x02D2, + "ringhalfleftcentered": 0x02D3, + "uptackmod": 0x02D4, + "downtackmod": 0x02D5, + "plusmod": 0x02D6, + "minusmod": 0x02D7, + "breve": 0x02D8, + "dotaccent": 0x02D9, + "ring": 0x02DA, + "ogonek": 0x02DB, + "hungarumlaut": 0x02DD, + "rhotichookmod": 0x02DE, + "gammasuperior": 0x02E0, + "xsuperior": 0x02E3, + "glottalstopreversedsuperior": 0x02E4, + "tonebarextrahighmod": 0x02E5, + "tonebarhighmod": 0x02E6, + "tonebarmidmod": 0x02E7, + "tonebarlowmod": 0x02E8, + "tonebarextralowmod": 0x02E9, + "gravecmb": 0x0300, + "gravecomb": 0x0300, + "acutecmb": 0x0301, + "acutecomb": 0x0301, + "circumflexcmb": 0x0302, + "tildecmb": 0x0303, + "tildecomb": 0x0303, + "macroncmb": 0x0304, + "overlinecmb": 0x0305, + "brevecmb": 0x0306, + "dotaccentcmb": 0x0307, + "dieresiscmb": 0x0308, + "hookabovecomb": 0x0309, + "hookcmb": 0x0309, + "ringcmb": 0x030A, + "hungarumlautcmb": 0x030B, + "caroncmb": 0x030C, + "verticallineabovecmb": 0x030D, + "dblverticallineabovecmb": 0x030E, + "dblgravecmb": 0x030F, + "candrabinducmb": 0x0310, + "breveinvertedcmb": 0x0311, + "commaturnedabovecmb": 0x0312, + "commaabovecmb": 0x0313, + "commareversedabovecmb": 0x0314, + "commaaboverightcmb": 0x0315, + "gravebelowcmb": 0x0316, + "acutebelowcmb": 0x0317, + "lefttackbelowcmb": 0x0318, + "righttackbelowcmb": 0x0319, + "leftangleabovecmb": 0x031A, + "horncmb": 0x031B, + "ringhalfleftbelowcmb": 0x031C, + "uptackbelowcmb": 0x031D, + "downtackbelowcmb": 0x031E, + "plusbelowcmb": 0x031F, + "minusbelowcmb": 0x0320, + "hookpalatalizedbelowcmb": 0x0321, + "hookretroflexbelowcmb": 0x0322, + "dotbelowcmb": 0x0323, + "dotbelowcomb": 0x0323, + "dieresisbelowcmb": 0x0324, + "ringbelowcmb": 0x0325, + "cedillacmb": 0x0327, + "ogonekcmb": 0x0328, + "verticallinebelowcmb": 0x0329, + "bridgebelowcmb": 0x032A, + "dblarchinvertedbelowcmb": 0x032B, + "caronbelowcmb": 0x032C, + "circumflexbelowcmb": 0x032D, + "brevebelowcmb": 0x032E, + "breveinvertedbelowcmb": 0x032F, + "tildebelowcmb": 0x0330, + "macronbelowcmb": 0x0331, + "lowlinecmb": 0x0332, + "dbllowlinecmb": 0x0333, + "tildeoverlaycmb": 0x0334, + "strokeshortoverlaycmb": 0x0335, + "strokelongoverlaycmb": 0x0336, + "solidusshortoverlaycmb": 0x0337, + "soliduslongoverlaycmb": 0x0338, + "ringhalfrightbelowcmb": 0x0339, + "bridgeinvertedbelowcmb": 0x033A, + "squarebelowcmb": 0x033B, + "seagullbelowcmb": 0x033C, + "xabovecmb": 0x033D, + "tildeverticalcmb": 0x033E, + "dbloverlinecmb": 0x033F, + "gravetonecmb": 0x0340, + "acutetonecmb": 0x0341, + "perispomenigreekcmb": 0x0342, + "koroniscmb": 0x0343, + "dialytikatonoscmb": 0x0344, + "ypogegrammenigreekcmb": 0x0345, + "tildedoublecmb": 0x0360, + "breveinverteddoublecmb": 0x0361, + "numeralsigngreek": 0x0374, + "numeralsignlowergreek": 0x0375, + "ypogegrammeni": 0x037A, + "questiongreek": 0x037E, + "tonos": 0x0384, + "dialytikatonos": 0x0385, + "dieresistonos": 0x0385, + "Alphatonos": 0x0386, + "anoteleia": 0x0387, + "Epsilontonos": 0x0388, + "Etatonos": 0x0389, + "Iotatonos": 0x038A, + "Omicrontonos": 0x038C, + "Upsilontonos": 0x038E, + "Omegatonos": 0x038F, + "iotadieresistonos": 0x0390, + "Iotadieresis": 0x03AA, + "Upsilondieresis": 0x03AB, + "alphatonos": 0x03AC, + "epsilontonos": 0x03AD, + "etatonos": 0x03AE, + "iotatonos": 0x03AF, + "upsilondieresistonos": 0x03B0, + "iotadieresis": 0x03CA, + "upsilondieresis": 0x03CB, + "omicrontonos": 0x03CC, + "upsilontonos": 0x03CD, + "omegatonos": 0x03CE, + "betasymbolgreek": 0x03D0, + "Upsilonacutehooksymbolgreek": 0x03D3, + "Upsilondieresishooksymbolgreek": 0x03D4, + "phi1": 0x03D5, + "phisymbolgreek": 0x03D5, + "Stigmagreek": 0x03DA, + "Digammagreek": 0x03DC, + "Koppagreek": 0x03DE, + "Sampigreek": 0x03E0, + "Sheicoptic": 0x03E2, + "sheicoptic": 0x03E3, + "Feicoptic": 0x03E4, + "feicoptic": 0x03E5, + "Kheicoptic": 0x03E6, + "kheicoptic": 0x03E7, + "Horicoptic": 0x03E8, + "horicoptic": 0x03E9, + "Gangiacoptic": 0x03EA, + "gangiacoptic": 0x03EB, + "Shimacoptic": 0x03EC, + "shimacoptic": 0x03ED, + "Deicoptic": 0x03EE, + "deicoptic": 0x03EF, + "kappasymbolgreek": 0x03F0, + "rhosymbolgreek": 0x03F1, + "sigmalunatesymbolgreek": 0x03F2, + "yotgreek": 0x03F3, + "Iocyrillic": 0x0401, + "afii10023": 0x0401, + "Djecyrillic": 0x0402, + "afii10051": 0x0402, + "Gjecyrillic": 0x0403, + "afii10052": 0x0403, + "Ecyrillic": 0x0404, + "afii10053": 0x0404, + "Dzecyrillic": 0x0405, + "afii10054": 0x0405, + "Icyrillic": 0x0406, + "afii10055": 0x0406, + "Yicyrillic": 0x0407, + "afii10056": 0x0407, + "Jecyrillic": 0x0408, + "afii10057": 0x0408, + "Ljecyrillic": 0x0409, + "afii10058": 0x0409, + "Njecyrillic": 0x040A, + "afii10059": 0x040A, + "Tshecyrillic": 0x040B, + "afii10060": 0x040B, + "Kjecyrillic": 0x040C, + "afii10061": 0x040C, + "Ushortcyrillic": 0x040E, + "afii10062": 0x040E, + "Dzhecyrillic": 0x040F, + "afii10145": 0x040F, + "Acyrillic": 0x0410, + "afii10017": 0x0410, + "Becyrillic": 0x0411, + "afii10018": 0x0411, + "Vecyrillic": 0x0412, + "afii10019": 0x0412, + "Gecyrillic": 0x0413, + "afii10020": 0x0413, + "Decyrillic": 0x0414, + "afii10021": 0x0414, + "Iecyrillic": 0x0415, + "afii10022": 0x0415, + "Zhecyrillic": 0x0416, + "afii10024": 0x0416, + "Zecyrillic": 0x0417, + "afii10025": 0x0417, + "Iicyrillic": 0x0418, + "afii10026": 0x0418, + "Iishortcyrillic": 0x0419, + "afii10027": 0x0419, + "Kacyrillic": 0x041A, + "afii10028": 0x041A, + "Elcyrillic": 0x041B, + "afii10029": 0x041B, + "Emcyrillic": 0x041C, + "afii10030": 0x041C, + "Encyrillic": 0x041D, + "afii10031": 0x041D, + "Ocyrillic": 0x041E, + "afii10032": 0x041E, + "Pecyrillic": 0x041F, + "afii10033": 0x041F, + "Ercyrillic": 0x0420, + "afii10034": 0x0420, + "Escyrillic": 0x0421, + "afii10035": 0x0421, + "Tecyrillic": 0x0422, + "afii10036": 0x0422, + "Ucyrillic": 0x0423, + "afii10037": 0x0423, + "Efcyrillic": 0x0424, + "afii10038": 0x0424, + "Khacyrillic": 0x0425, + "afii10039": 0x0425, + "Tsecyrillic": 0x0426, + "afii10040": 0x0426, + "Checyrillic": 0x0427, + "afii10041": 0x0427, + "Shacyrillic": 0x0428, + "afii10042": 0x0428, + "Shchacyrillic": 0x0429, + "afii10043": 0x0429, + "Hardsigncyrillic": 0x042A, + "afii10044": 0x042A, + "Yericyrillic": 0x042B, + "afii10045": 0x042B, + "Softsigncyrillic": 0x042C, + "afii10046": 0x042C, + "Ereversedcyrillic": 0x042D, + "afii10047": 0x042D, + "IUcyrillic": 0x042E, + "afii10048": 0x042E, + "IAcyrillic": 0x042F, + "afii10049": 0x042F, + "acyrillic": 0x0430, + "afii10065": 0x0430, + "afii10066": 0x0431, + "becyrillic": 0x0431, + "afii10067": 0x0432, + "vecyrillic": 0x0432, + "afii10068": 0x0433, + "gecyrillic": 0x0433, + "afii10069": 0x0434, + "decyrillic": 0x0434, + "afii10070": 0x0435, + "iecyrillic": 0x0435, + "afii10072": 0x0436, + "zhecyrillic": 0x0436, + "afii10073": 0x0437, + "zecyrillic": 0x0437, + "afii10074": 0x0438, + "iicyrillic": 0x0438, + "afii10075": 0x0439, + "iishortcyrillic": 0x0439, + "afii10076": 0x043A, + "kacyrillic": 0x043A, + "afii10077": 0x043B, + "elcyrillic": 0x043B, + "afii10078": 0x043C, + "emcyrillic": 0x043C, + "afii10079": 0x043D, + "encyrillic": 0x043D, + "afii10080": 0x043E, + "ocyrillic": 0x043E, + "afii10081": 0x043F, + "pecyrillic": 0x043F, + "afii10082": 0x0440, + "ercyrillic": 0x0440, + "afii10083": 0x0441, + "escyrillic": 0x0441, + "afii10084": 0x0442, + "tecyrillic": 0x0442, + "afii10085": 0x0443, + "ucyrillic": 0x0443, + "afii10086": 0x0444, + "efcyrillic": 0x0444, + "afii10087": 0x0445, + "khacyrillic": 0x0445, + "afii10088": 0x0446, + "tsecyrillic": 0x0446, + "afii10089": 0x0447, + "checyrillic": 0x0447, + "afii10090": 0x0448, + "shacyrillic": 0x0448, + "afii10091": 0x0449, + "shchacyrillic": 0x0449, + "afii10092": 0x044A, + "hardsigncyrillic": 0x044A, + "afii10093": 0x044B, + "yericyrillic": 0x044B, + "afii10094": 0x044C, + "softsigncyrillic": 0x044C, + "afii10095": 0x044D, + "ereversedcyrillic": 0x044D, + "afii10096": 0x044E, + "iucyrillic": 0x044E, + "afii10097": 0x044F, + "iacyrillic": 0x044F, + "afii10071": 0x0451, + "iocyrillic": 0x0451, + "afii10099": 0x0452, + "djecyrillic": 0x0452, + "afii10100": 0x0453, + "gjecyrillic": 0x0453, + "afii10101": 0x0454, + "ecyrillic": 0x0454, + "afii10102": 0x0455, + "dzecyrillic": 0x0455, + "afii10103": 0x0456, + "icyrillic": 0x0456, + "afii10104": 0x0457, + "yicyrillic": 0x0457, + "afii10105": 0x0458, + "jecyrillic": 0x0458, + "afii10106": 0x0459, + "ljecyrillic": 0x0459, + "afii10107": 0x045A, + "njecyrillic": 0x045A, + "afii10108": 0x045B, + "tshecyrillic": 0x045B, + "afii10109": 0x045C, + "kjecyrillic": 0x045C, + "afii10110": 0x045E, + "ushortcyrillic": 0x045E, + "afii10193": 0x045F, + "dzhecyrillic": 0x045F, + "Omegacyrillic": 0x0460, + "omegacyrillic": 0x0461, + "Yatcyrillic": 0x0462, + "afii10146": 0x0462, + "afii10194": 0x0463, + "yatcyrillic": 0x0463, + "Eiotifiedcyrillic": 0x0464, + "eiotifiedcyrillic": 0x0465, + "Yuslittlecyrillic": 0x0466, + "yuslittlecyrillic": 0x0467, + "Yuslittleiotifiedcyrillic": 0x0468, + "yuslittleiotifiedcyrillic": 0x0469, + "Yusbigcyrillic": 0x046A, + "yusbigcyrillic": 0x046B, + "Yusbigiotifiedcyrillic": 0x046C, + "yusbigiotifiedcyrillic": 0x046D, + "Ksicyrillic": 0x046E, + "ksicyrillic": 0x046F, + "Psicyrillic": 0x0470, + "psicyrillic": 0x0471, + "Fitacyrillic": 0x0472, + "afii10147": 0x0472, + "afii10195": 0x0473, + "fitacyrillic": 0x0473, + "Izhitsacyrillic": 0x0474, + "afii10148": 0x0474, + "afii10196": 0x0475, + "izhitsacyrillic": 0x0475, + "Izhitsadblgravecyrillic": 0x0476, + "izhitsadblgravecyrillic": 0x0477, + "Ukcyrillic": 0x0478, + "ukcyrillic": 0x0479, + "Omegaroundcyrillic": 0x047A, + "omegaroundcyrillic": 0x047B, + "Omegatitlocyrillic": 0x047C, + "omegatitlocyrillic": 0x047D, + "Otcyrillic": 0x047E, + "otcyrillic": 0x047F, + "Koppacyrillic": 0x0480, + "koppacyrillic": 0x0481, + "thousandcyrillic": 0x0482, + "titlocyrilliccmb": 0x0483, + "palatalizationcyrilliccmb": 0x0484, + "dasiapneumatacyrilliccmb": 0x0485, + "psilipneumatacyrilliccmb": 0x0486, + "Gheupturncyrillic": 0x0490, + "afii10050": 0x0490, + "afii10098": 0x0491, + "gheupturncyrillic": 0x0491, + "Ghestrokecyrillic": 0x0492, + "ghestrokecyrillic": 0x0493, + "Ghemiddlehookcyrillic": 0x0494, + "ghemiddlehookcyrillic": 0x0495, + "Zhedescendercyrillic": 0x0496, + "zhedescendercyrillic": 0x0497, + "Zedescendercyrillic": 0x0498, + "zedescendercyrillic": 0x0499, + "Kadescendercyrillic": 0x049A, + "kadescendercyrillic": 0x049B, + "Kaverticalstrokecyrillic": 0x049C, + "kaverticalstrokecyrillic": 0x049D, + "Kastrokecyrillic": 0x049E, + "kastrokecyrillic": 0x049F, + "Kabashkircyrillic": 0x04A0, + "kabashkircyrillic": 0x04A1, + "Endescendercyrillic": 0x04A2, + "endescendercyrillic": 0x04A3, + "Enghecyrillic": 0x04A4, + "enghecyrillic": 0x04A5, + "Pemiddlehookcyrillic": 0x04A6, + "pemiddlehookcyrillic": 0x04A7, + "Haabkhasiancyrillic": 0x04A8, + "haabkhasiancyrillic": 0x04A9, + "Esdescendercyrillic": 0x04AA, + "esdescendercyrillic": 0x04AB, + "Tedescendercyrillic": 0x04AC, + "tedescendercyrillic": 0x04AD, + "Ustraightcyrillic": 0x04AE, + "ustraightcyrillic": 0x04AF, + "Ustraightstrokecyrillic": 0x04B0, + "ustraightstrokecyrillic": 0x04B1, + "Hadescendercyrillic": 0x04B2, + "hadescendercyrillic": 0x04B3, + "Tetsecyrillic": 0x04B4, + "tetsecyrillic": 0x04B5, + "Chedescendercyrillic": 0x04B6, + "chedescendercyrillic": 0x04B7, + "Cheverticalstrokecyrillic": 0x04B8, + "cheverticalstrokecyrillic": 0x04B9, + "Shhacyrillic": 0x04BA, + "shhacyrillic": 0x04BB, + "Cheabkhasiancyrillic": 0x04BC, + "cheabkhasiancyrillic": 0x04BD, + "Chedescenderabkhasiancyrillic": 0x04BE, + "chedescenderabkhasiancyrillic": 0x04BF, + "palochkacyrillic": 0x04C0, + "Zhebrevecyrillic": 0x04C1, + "zhebrevecyrillic": 0x04C2, + "Kahookcyrillic": 0x04C3, + "kahookcyrillic": 0x04C4, + "Enhookcyrillic": 0x04C7, + "enhookcyrillic": 0x04C8, + "Chekhakassiancyrillic": 0x04CB, + "chekhakassiancyrillic": 0x04CC, + "Abrevecyrillic": 0x04D0, + "abrevecyrillic": 0x04D1, + "Adieresiscyrillic": 0x04D2, + "adieresiscyrillic": 0x04D3, + "Aiecyrillic": 0x04D4, + "aiecyrillic": 0x04D5, + "Iebrevecyrillic": 0x04D6, + "iebrevecyrillic": 0x04D7, + "Schwacyrillic": 0x04D8, + "afii10846": 0x04D9, + "schwacyrillic": 0x04D9, + "Schwadieresiscyrillic": 0x04DA, + "schwadieresiscyrillic": 0x04DB, + "Zhedieresiscyrillic": 0x04DC, + "zhedieresiscyrillic": 0x04DD, + "Zedieresiscyrillic": 0x04DE, + "zedieresiscyrillic": 0x04DF, + "Dzeabkhasiancyrillic": 0x04E0, + "dzeabkhasiancyrillic": 0x04E1, + "Imacroncyrillic": 0x04E2, + "imacroncyrillic": 0x04E3, + "Idieresiscyrillic": 0x04E4, + "idieresiscyrillic": 0x04E5, + "Odieresiscyrillic": 0x04E6, + "odieresiscyrillic": 0x04E7, + "Obarredcyrillic": 0x04E8, + "obarredcyrillic": 0x04E9, + "Obarreddieresiscyrillic": 0x04EA, + "obarreddieresiscyrillic": 0x04EB, + "Umacroncyrillic": 0x04EE, + "umacroncyrillic": 0x04EF, + "Udieresiscyrillic": 0x04F0, + "udieresiscyrillic": 0x04F1, + "Uhungarumlautcyrillic": 0x04F2, + "uhungarumlautcyrillic": 0x04F3, + "Chedieresiscyrillic": 0x04F4, + "chedieresiscyrillic": 0x04F5, + "Yerudieresiscyrillic": 0x04F8, + "yerudieresiscyrillic": 0x04F9, + "Aybarmenian": 0x0531, + "Benarmenian": 0x0532, + "Gimarmenian": 0x0533, + "Daarmenian": 0x0534, + "Echarmenian": 0x0535, + "Zaarmenian": 0x0536, + "Eharmenian": 0x0537, + "Etarmenian": 0x0538, + "Toarmenian": 0x0539, + "Zhearmenian": 0x053A, + "Iniarmenian": 0x053B, + "Liwnarmenian": 0x053C, + "Xeharmenian": 0x053D, + "Caarmenian": 0x053E, + "Kenarmenian": 0x053F, + "Hoarmenian": 0x0540, + "Jaarmenian": 0x0541, + "Ghadarmenian": 0x0542, + "Cheharmenian": 0x0543, + "Menarmenian": 0x0544, + "Yiarmenian": 0x0545, + "Nowarmenian": 0x0546, + "Shaarmenian": 0x0547, + "Voarmenian": 0x0548, + "Chaarmenian": 0x0549, + "Peharmenian": 0x054A, + "Jheharmenian": 0x054B, + "Raarmenian": 0x054C, + "Seharmenian": 0x054D, + "Vewarmenian": 0x054E, + "Tiwnarmenian": 0x054F, + "Reharmenian": 0x0550, + "Coarmenian": 0x0551, + "Yiwnarmenian": 0x0552, + "Piwrarmenian": 0x0553, + "Keharmenian": 0x0554, + "Oharmenian": 0x0555, + "Feharmenian": 0x0556, + "ringhalfleftarmenian": 0x0559, + "apostrophearmenian": 0x055A, + "emphasismarkarmenian": 0x055B, + "exclamarmenian": 0x055C, + "commaarmenian": 0x055D, + "questionarmenian": 0x055E, + "abbreviationmarkarmenian": 0x055F, + "aybarmenian": 0x0561, + "benarmenian": 0x0562, + "gimarmenian": 0x0563, + "daarmenian": 0x0564, + "echarmenian": 0x0565, + "zaarmenian": 0x0566, + "eharmenian": 0x0567, + "etarmenian": 0x0568, + "toarmenian": 0x0569, + "zhearmenian": 0x056A, + "iniarmenian": 0x056B, + "liwnarmenian": 0x056C, + "xeharmenian": 0x056D, + "caarmenian": 0x056E, + "kenarmenian": 0x056F, + "hoarmenian": 0x0570, + "jaarmenian": 0x0571, + "ghadarmenian": 0x0572, + "cheharmenian": 0x0573, + "menarmenian": 0x0574, + "yiarmenian": 0x0575, + "nowarmenian": 0x0576, + "shaarmenian": 0x0577, + "voarmenian": 0x0578, + "chaarmenian": 0x0579, + "peharmenian": 0x057A, + "jheharmenian": 0x057B, + "raarmenian": 0x057C, + "seharmenian": 0x057D, + "vewarmenian": 0x057E, + "tiwnarmenian": 0x057F, + "reharmenian": 0x0580, + "coarmenian": 0x0581, + "yiwnarmenian": 0x0582, + "piwrarmenian": 0x0583, + "keharmenian": 0x0584, + "oharmenian": 0x0585, + "feharmenian": 0x0586, + "echyiwnarmenian": 0x0587, + "periodarmenian": 0x0589, + "etnahtafoukhhebrew": 0x0591, + "etnahtafoukhlefthebrew": 0x0591, + "etnahtahebrew": 0x0591, + "etnahtalefthebrew": 0x0591, + "segoltahebrew": 0x0592, + "shalshelethebrew": 0x0593, + "zaqefqatanhebrew": 0x0594, + "zaqefgadolhebrew": 0x0595, + "tipehahebrew": 0x0596, + "tipehalefthebrew": 0x0596, + "reviahebrew": 0x0597, + "reviamugrashhebrew": 0x0597, + "zarqahebrew": 0x0598, + "pashtahebrew": 0x0599, + "yetivhebrew": 0x059A, + "tevirhebrew": 0x059B, + "tevirlefthebrew": 0x059B, + "gereshaccenthebrew": 0x059C, + "gereshmuqdamhebrew": 0x059D, + "gershayimaccenthebrew": 0x059E, + "qarneyparahebrew": 0x059F, + "telishagedolahebrew": 0x05A0, + "pazerhebrew": 0x05A1, + "munahhebrew": 0x05A3, + "munahlefthebrew": 0x05A3, + "mahapakhhebrew": 0x05A4, + "mahapakhlefthebrew": 0x05A4, + "merkhahebrew": 0x05A5, + "merkhalefthebrew": 0x05A5, + "merkhakefulahebrew": 0x05A6, + "merkhakefulalefthebrew": 0x05A6, + "dargahebrew": 0x05A7, + "dargalefthebrew": 0x05A7, + "qadmahebrew": 0x05A8, + "telishaqetanahebrew": 0x05A9, + "yerahbenyomohebrew": 0x05AA, + "yerahbenyomolefthebrew": 0x05AA, + "olehebrew": 0x05AB, + "iluyhebrew": 0x05AC, + "dehihebrew": 0x05AD, + "zinorhebrew": 0x05AE, + "masoracirclehebrew": 0x05AF, + "afii57799": 0x05B0, + "sheva": 0x05B0, + "sheva115": 0x05B0, + "sheva15": 0x05B0, + "sheva22": 0x05B0, + "sheva2e": 0x05B0, + "shevahebrew": 0x05B0, + "shevanarrowhebrew": 0x05B0, + "shevaquarterhebrew": 0x05B0, + "shevawidehebrew": 0x05B0, + "afii57801": 0x05B1, + "hatafsegol": 0x05B1, + "hatafsegol17": 0x05B1, + "hatafsegol24": 0x05B1, + "hatafsegol30": 0x05B1, + "hatafsegolhebrew": 0x05B1, + "hatafsegolnarrowhebrew": 0x05B1, + "hatafsegolquarterhebrew": 0x05B1, + "hatafsegolwidehebrew": 0x05B1, + "afii57800": 0x05B2, + "hatafpatah": 0x05B2, + "hatafpatah16": 0x05B2, + "hatafpatah23": 0x05B2, + "hatafpatah2f": 0x05B2, + "hatafpatahhebrew": 0x05B2, + "hatafpatahnarrowhebrew": 0x05B2, + "hatafpatahquarterhebrew": 0x05B2, + "hatafpatahwidehebrew": 0x05B2, + "afii57802": 0x05B3, + "hatafqamats": 0x05B3, + "hatafqamats1b": 0x05B3, + "hatafqamats28": 0x05B3, + "hatafqamats34": 0x05B3, + "hatafqamatshebrew": 0x05B3, + "hatafqamatsnarrowhebrew": 0x05B3, + "hatafqamatsquarterhebrew": 0x05B3, + "hatafqamatswidehebrew": 0x05B3, + "afii57793": 0x05B4, + "hiriq": 0x05B4, + "hiriq14": 0x05B4, + "hiriq21": 0x05B4, + "hiriq2d": 0x05B4, + "hiriqhebrew": 0x05B4, + "hiriqnarrowhebrew": 0x05B4, + "hiriqquarterhebrew": 0x05B4, + "hiriqwidehebrew": 0x05B4, + "afii57794": 0x05B5, + "tsere": 0x05B5, + "tsere12": 0x05B5, + "tsere1e": 0x05B5, + "tsere2b": 0x05B5, + "tserehebrew": 0x05B5, + "tserenarrowhebrew": 0x05B5, + "tserequarterhebrew": 0x05B5, + "tserewidehebrew": 0x05B5, + "afii57795": 0x05B6, + "segol": 0x05B6, + "segol13": 0x05B6, + "segol1f": 0x05B6, + "segol2c": 0x05B6, + "segolhebrew": 0x05B6, + "segolnarrowhebrew": 0x05B6, + "segolquarterhebrew": 0x05B6, + "segolwidehebrew": 0x05B6, + "afii57798": 0x05B7, + "patah": 0x05B7, + "patah11": 0x05B7, + "patah1d": 0x05B7, + "patah2a": 0x05B7, + "patahhebrew": 0x05B7, + "patahnarrowhebrew": 0x05B7, + "patahquarterhebrew": 0x05B7, + "patahwidehebrew": 0x05B7, + "afii57797": 0x05B8, + "qamats": 0x05B8, + "qamats10": 0x05B8, + "qamats1a": 0x05B8, + "qamats1c": 0x05B8, + "qamats27": 0x05B8, + "qamats29": 0x05B8, + "qamats33": 0x05B8, + "qamatsde": 0x05B8, + "qamatshebrew": 0x05B8, + "qamatsnarrowhebrew": 0x05B8, + "qamatsqatanhebrew": 0x05B8, + "qamatsqatannarrowhebrew": 0x05B8, + "qamatsqatanquarterhebrew": 0x05B8, + "qamatsqatanwidehebrew": 0x05B8, + "qamatsquarterhebrew": 0x05B8, + "qamatswidehebrew": 0x05B8, + "afii57806": 0x05B9, + "holam": 0x05B9, + "holam19": 0x05B9, + "holam26": 0x05B9, + "holam32": 0x05B9, + "holamhebrew": 0x05B9, + "holamnarrowhebrew": 0x05B9, + "holamquarterhebrew": 0x05B9, + "holamwidehebrew": 0x05B9, + "afii57796": 0x05BB, + "qubuts": 0x05BB, + "qubuts18": 0x05BB, + "qubuts25": 0x05BB, + "qubuts31": 0x05BB, + "qubutshebrew": 0x05BB, + "qubutsnarrowhebrew": 0x05BB, + "qubutsquarterhebrew": 0x05BB, + "qubutswidehebrew": 0x05BB, + "afii57807": 0x05BC, + "dagesh": 0x05BC, + "dageshhebrew": 0x05BC, + "afii57839": 0x05BD, + "siluqhebrew": 0x05BD, + "siluqlefthebrew": 0x05BD, + "afii57645": 0x05BE, + "maqafhebrew": 0x05BE, + "afii57841": 0x05BF, + "rafe": 0x05BF, + "rafehebrew": 0x05BF, + "afii57842": 0x05C0, + "paseqhebrew": 0x05C0, + "afii57804": 0x05C1, + "shindothebrew": 0x05C1, + "afii57803": 0x05C2, + "sindothebrew": 0x05C2, + "afii57658": 0x05C3, + "sofpasuqhebrew": 0x05C3, + "upperdothebrew": 0x05C4, + "afii57664": 0x05D0, + "alef": 0x05D0, + "alefhebrew": 0x05D0, + "afii57665": 0x05D1, + "bet": 0x05D1, + "bethebrew": 0x05D1, + "afii57666": 0x05D2, + "gimel": 0x05D2, + "gimelhebrew": 0x05D2, + "afii57667": 0x05D3, + "dalet": 0x05D3, + "dalethebrew": 0x05D3, + "daletsheva": 0x05D3, + "daletshevahebrew": 0x05D3, + "dalethatafsegol": 0x05D3, + "dalethatafsegolhebrew": 0x05D3, + "dalethatafpatah": 0x05D3, + "dalethatafpatahhebrew": 0x05D3, + "dalethiriq": 0x05D3, + "dalethiriqhebrew": 0x05D3, + "dalettsere": 0x05D3, + "dalettserehebrew": 0x05D3, + "daletsegol": 0x05D3, + "daletsegolhebrew": 0x05D3, + "daletpatah": 0x05D3, + "daletpatahhebrew": 0x05D3, + "daletqamats": 0x05D3, + "daletqamatshebrew": 0x05D3, + "daletholam": 0x05D3, + "daletholamhebrew": 0x05D3, + "daletqubuts": 0x05D3, + "daletqubutshebrew": 0x05D3, + "afii57668": 0x05D4, + "he": 0x05D4, + "hehebrew": 0x05D4, + "afii57669": 0x05D5, + "vav": 0x05D5, + "vavhebrew": 0x05D5, + "afii57670": 0x05D6, + "zayin": 0x05D6, + "zayinhebrew": 0x05D6, + "afii57671": 0x05D7, + "het": 0x05D7, + "hethebrew": 0x05D7, + "afii57672": 0x05D8, + "tet": 0x05D8, + "tethebrew": 0x05D8, + "afii57673": 0x05D9, + "yod": 0x05D9, + "yodhebrew": 0x05D9, + "afii57674": 0x05DA, + "finalkaf": 0x05DA, + "finalkafhebrew": 0x05DA, + "finalkafsheva": 0x05DA, + "finalkafshevahebrew": 0x05DA, + "finalkafqamats": 0x05DA, + "finalkafqamatshebrew": 0x05DA, + "afii57675": 0x05DB, + "kaf": 0x05DB, + "kafhebrew": 0x05DB, + "afii57676": 0x05DC, + "lamed": 0x05DC, + "lamedhebrew": 0x05DC, + "lamedholam": 0x05DC, + "lamedholamhebrew": 0x05DC, + "lamedholamdagesh": 0x05DC, + "lamedholamdageshhebrew": 0x05DC, + "afii57677": 0x05DD, + "finalmem": 0x05DD, + "finalmemhebrew": 0x05DD, + "afii57678": 0x05DE, + "mem": 0x05DE, + "memhebrew": 0x05DE, + "afii57679": 0x05DF, + "finalnun": 0x05DF, + "finalnunhebrew": 0x05DF, + "afii57680": 0x05E0, + "nun": 0x05E0, + "nunhebrew": 0x05E0, + "afii57681": 0x05E1, + "samekh": 0x05E1, + "samekhhebrew": 0x05E1, + "afii57682": 0x05E2, + "ayin": 0x05E2, + "ayinhebrew": 0x05E2, + "afii57683": 0x05E3, + "finalpe": 0x05E3, + "finalpehebrew": 0x05E3, + "afii57684": 0x05E4, + "pe": 0x05E4, + "pehebrew": 0x05E4, + "afii57685": 0x05E5, + "finaltsadi": 0x05E5, + "finaltsadihebrew": 0x05E5, + "afii57686": 0x05E6, + "tsadi": 0x05E6, + "tsadihebrew": 0x05E6, + "afii57687": 0x05E7, + "qof": 0x05E7, + "qofhebrew": 0x05E7, + "qofsheva": 0x05E7, + "qofshevahebrew": 0x05E7, + "qofhatafsegol": 0x05E7, + "qofhatafsegolhebrew": 0x05E7, + "qofhatafpatah": 0x05E7, + "qofhatafpatahhebrew": 0x05E7, + "qofhiriq": 0x05E7, + "qofhiriqhebrew": 0x05E7, + "qoftsere": 0x05E7, + "qoftserehebrew": 0x05E7, + "qofsegol": 0x05E7, + "qofsegolhebrew": 0x05E7, + "qofpatah": 0x05E7, + "qofpatahhebrew": 0x05E7, + "qofqamats": 0x05E7, + "qofqamatshebrew": 0x05E7, + "qofholam": 0x05E7, + "qofholamhebrew": 0x05E7, + "qofqubuts": 0x05E7, + "qofqubutshebrew": 0x05E7, + "afii57688": 0x05E8, + "resh": 0x05E8, + "reshhebrew": 0x05E8, + "reshsheva": 0x05E8, + "reshshevahebrew": 0x05E8, + "reshhatafsegol": 0x05E8, + "reshhatafsegolhebrew": 0x05E8, + "reshhatafpatah": 0x05E8, + "reshhatafpatahhebrew": 0x05E8, + "reshhiriq": 0x05E8, + "reshhiriqhebrew": 0x05E8, + "reshtsere": 0x05E8, + "reshtserehebrew": 0x05E8, + "reshsegol": 0x05E8, + "reshsegolhebrew": 0x05E8, + "reshpatah": 0x05E8, + "reshpatahhebrew": 0x05E8, + "reshqamats": 0x05E8, + "reshqamatshebrew": 0x05E8, + "reshholam": 0x05E8, + "reshholamhebrew": 0x05E8, + "reshqubuts": 0x05E8, + "reshqubutshebrew": 0x05E8, + "afii57689": 0x05E9, + "shin": 0x05E9, + "shinhebrew": 0x05E9, + "afii57690": 0x05EA, + "tav": 0x05EA, + "tavhebrew": 0x05EA, + "afii57716": 0x05F0, + "vavvavhebrew": 0x05F0, + "afii57717": 0x05F1, + "vavyodhebrew": 0x05F1, + "afii57718": 0x05F2, + "yodyodhebrew": 0x05F2, + "gereshhebrew": 0x05F3, + "gershayimhebrew": 0x05F4, + "afii57388": 0x060C, + "commaarabic": 0x060C, + "afii57403": 0x061B, + "semicolonarabic": 0x061B, + "afii57407": 0x061F, + "questionarabic": 0x061F, + "afii57409": 0x0621, + "hamzaarabic": 0x0621, + "hamzalowarabic": 0x0621, + "hamzafathatanarabic": 0x0621, + "hamzadammatanarabic": 0x0621, + "hamzalowkasratanarabic": 0x0621, + "hamzafathaarabic": 0x0621, + "hamzadammaarabic": 0x0621, + "hamzalowkasraarabic": 0x0621, + "hamzasukunarabic": 0x0621, + "afii57410": 0x0622, + "alefmaddaabovearabic": 0x0622, + "afii57411": 0x0623, + "alefhamzaabovearabic": 0x0623, + "afii57412": 0x0624, + "wawhamzaabovearabic": 0x0624, + "afii57413": 0x0625, + "alefhamzabelowarabic": 0x0625, + "afii57414": 0x0626, + "yehhamzaabovearabic": 0x0626, + "afii57415": 0x0627, + "alefarabic": 0x0627, + "afii57416": 0x0628, + "beharabic": 0x0628, + "afii57417": 0x0629, + "tehmarbutaarabic": 0x0629, + "afii57418": 0x062A, + "teharabic": 0x062A, + "afii57419": 0x062B, + "theharabic": 0x062B, + "afii57420": 0x062C, + "jeemarabic": 0x062C, + "afii57421": 0x062D, + "haharabic": 0x062D, + "afii57422": 0x062E, + "khaharabic": 0x062E, + "afii57423": 0x062F, + "dalarabic": 0x062F, + "afii57424": 0x0630, + "thalarabic": 0x0630, + "afii57425": 0x0631, + "reharabic": 0x0631, + "rehyehaleflamarabic": 0x0631, + "afii57426": 0x0632, + "zainarabic": 0x0632, + "afii57427": 0x0633, + "seenarabic": 0x0633, + "afii57428": 0x0634, + "sheenarabic": 0x0634, + "afii57429": 0x0635, + "sadarabic": 0x0635, + "afii57430": 0x0636, + "dadarabic": 0x0636, + "afii57431": 0x0637, + "taharabic": 0x0637, + "afii57432": 0x0638, + "zaharabic": 0x0638, + "afii57433": 0x0639, + "ainarabic": 0x0639, + "afii57434": 0x063A, + "ghainarabic": 0x063A, + "afii57440": 0x0640, + "kashidaautoarabic": 0x0640, + "kashidaautonosidebearingarabic": 0x0640, + "tatweelarabic": 0x0640, + "afii57441": 0x0641, + "feharabic": 0x0641, + "afii57442": 0x0642, + "qafarabic": 0x0642, + "afii57443": 0x0643, + "kafarabic": 0x0643, + "afii57444": 0x0644, + "lamarabic": 0x0644, + "afii57445": 0x0645, + "meemarabic": 0x0645, + "afii57446": 0x0646, + "noonarabic": 0x0646, + "afii57470": 0x0647, + "heharabic": 0x0647, + "afii57448": 0x0648, + "wawarabic": 0x0648, + "afii57449": 0x0649, + "alefmaksuraarabic": 0x0649, + "afii57450": 0x064A, + "yeharabic": 0x064A, + "afii57451": 0x064B, + "fathatanarabic": 0x064B, + "afii57452": 0x064C, + "dammatanaltonearabic": 0x064C, + "dammatanarabic": 0x064C, + "afii57453": 0x064D, + "kasratanarabic": 0x064D, + "afii57454": 0x064E, + "fathaarabic": 0x064E, + "fathalowarabic": 0x064E, + "afii57455": 0x064F, + "dammaarabic": 0x064F, + "dammalowarabic": 0x064F, + "afii57456": 0x0650, + "kasraarabic": 0x0650, + "afii57457": 0x0651, + "shaddaarabic": 0x0651, + "shaddafathatanarabic": 0x0651, + "afii57458": 0x0652, + "sukunarabic": 0x0652, + "afii57392": 0x0660, + "zeroarabic": 0x0660, + "zerohackarabic": 0x0660, + "afii57393": 0x0661, + "onearabic": 0x0661, + "onehackarabic": 0x0661, + "afii57394": 0x0662, + "twoarabic": 0x0662, + "twohackarabic": 0x0662, + "afii57395": 0x0663, + "threearabic": 0x0663, + "threehackarabic": 0x0663, + "afii57396": 0x0664, + "fourarabic": 0x0664, + "fourhackarabic": 0x0664, + "afii57397": 0x0665, + "fivearabic": 0x0665, + "fivehackarabic": 0x0665, + "afii57398": 0x0666, + "sixarabic": 0x0666, + "sixhackarabic": 0x0666, + "afii57399": 0x0667, + "sevenarabic": 0x0667, + "sevenhackarabic": 0x0667, + "afii57400": 0x0668, + "eightarabic": 0x0668, + "eighthackarabic": 0x0668, + "afii57401": 0x0669, + "ninearabic": 0x0669, + "ninehackarabic": 0x0669, + "afii57381": 0x066A, + "percentarabic": 0x066A, + "decimalseparatorarabic": 0x066B, + "decimalseparatorpersian": 0x066B, + "thousandsseparatorarabic": 0x066C, + "thousandsseparatorpersian": 0x066C, + "afii63167": 0x066D, + "asteriskaltonearabic": 0x066D, + "asteriskarabic": 0x066D, + "afii57511": 0x0679, + "tteharabic": 0x0679, + "afii57506": 0x067E, + "peharabic": 0x067E, + "afii57507": 0x0686, + "tcheharabic": 0x0686, + "afii57512": 0x0688, + "ddalarabic": 0x0688, + "afii57513": 0x0691, + "rreharabic": 0x0691, + "afii57508": 0x0698, + "jeharabic": 0x0698, + "afii57505": 0x06A4, + "veharabic": 0x06A4, + "afii57509": 0x06AF, + "gafarabic": 0x06AF, + "afii57514": 0x06BA, + "noonghunnaarabic": 0x06BA, + "haaltonearabic": 0x06C1, + "hehaltonearabic": 0x06C1, + "yehthreedotsbelowarabic": 0x06D1, + "afii57519": 0x06D2, + "yehbarreearabic": 0x06D2, + "afii57534": 0x06D5, + "zeropersian": 0x06F0, + "onepersian": 0x06F1, + "twopersian": 0x06F2, + "threepersian": 0x06F3, + "fourpersian": 0x06F4, + "fivepersian": 0x06F5, + "sixpersian": 0x06F6, + "sevenpersian": 0x06F7, + "eightpersian": 0x06F8, + "ninepersian": 0x06F9, + "candrabindudeva": 0x0901, + "anusvaradeva": 0x0902, + "visargadeva": 0x0903, + "adeva": 0x0905, + "aadeva": 0x0906, + "ideva": 0x0907, + "iideva": 0x0908, + "udeva": 0x0909, + "uudeva": 0x090A, + "rvocalicdeva": 0x090B, + "lvocalicdeva": 0x090C, + "ecandradeva": 0x090D, + "eshortdeva": 0x090E, + "edeva": 0x090F, + "aideva": 0x0910, + "ocandradeva": 0x0911, + "oshortdeva": 0x0912, + "odeva": 0x0913, + "audeva": 0x0914, + "kadeva": 0x0915, + "khadeva": 0x0916, + "gadeva": 0x0917, + "ghadeva": 0x0918, + "ngadeva": 0x0919, + "cadeva": 0x091A, + "chadeva": 0x091B, + "jadeva": 0x091C, + "jhadeva": 0x091D, + "nyadeva": 0x091E, + "ttadeva": 0x091F, + "tthadeva": 0x0920, + "ddadeva": 0x0921, + "ddhadeva": 0x0922, + "nnadeva": 0x0923, + "tadeva": 0x0924, + "thadeva": 0x0925, + "dadeva": 0x0926, + "dhadeva": 0x0927, + "nadeva": 0x0928, + "nnnadeva": 0x0929, + "padeva": 0x092A, + "phadeva": 0x092B, + "badeva": 0x092C, + "bhadeva": 0x092D, + "madeva": 0x092E, + "yadeva": 0x092F, + "radeva": 0x0930, + "rradeva": 0x0931, + "ladeva": 0x0932, + "lladeva": 0x0933, + "llladeva": 0x0934, + "vadeva": 0x0935, + "shadeva": 0x0936, + "ssadeva": 0x0937, + "sadeva": 0x0938, + "hadeva": 0x0939, + "nuktadeva": 0x093C, + "avagrahadeva": 0x093D, + "aavowelsigndeva": 0x093E, + "ivowelsigndeva": 0x093F, + "iivowelsigndeva": 0x0940, + "uvowelsigndeva": 0x0941, + "uuvowelsigndeva": 0x0942, + "rvocalicvowelsigndeva": 0x0943, + "rrvocalicvowelsigndeva": 0x0944, + "ecandravowelsigndeva": 0x0945, + "eshortvowelsigndeva": 0x0946, + "evowelsigndeva": 0x0947, + "aivowelsigndeva": 0x0948, + "ocandravowelsigndeva": 0x0949, + "oshortvowelsigndeva": 0x094A, + "ovowelsigndeva": 0x094B, + "auvowelsigndeva": 0x094C, + "viramadeva": 0x094D, + "omdeva": 0x0950, + "udattadeva": 0x0951, + "anudattadeva": 0x0952, + "gravedeva": 0x0953, + "acutedeva": 0x0954, + "qadeva": 0x0958, + "khhadeva": 0x0959, + "ghhadeva": 0x095A, + "zadeva": 0x095B, + "dddhadeva": 0x095C, + "rhadeva": 0x095D, + "fadeva": 0x095E, + "yyadeva": 0x095F, + "rrvocalicdeva": 0x0960, + "llvocalicdeva": 0x0961, + "lvocalicvowelsigndeva": 0x0962, + "llvocalicvowelsigndeva": 0x0963, + "danda": 0x0964, + "dbldanda": 0x0965, + "zerodeva": 0x0966, + "onedeva": 0x0967, + "twodeva": 0x0968, + "threedeva": 0x0969, + "fourdeva": 0x096A, + "fivedeva": 0x096B, + "sixdeva": 0x096C, + "sevendeva": 0x096D, + "eightdeva": 0x096E, + "ninedeva": 0x096F, + "abbreviationsigndeva": 0x0970, + "candrabindubengali": 0x0981, + "anusvarabengali": 0x0982, + "visargabengali": 0x0983, + "abengali": 0x0985, + "aabengali": 0x0986, + "ibengali": 0x0987, + "iibengali": 0x0988, + "ubengali": 0x0989, + "uubengali": 0x098A, + "rvocalicbengali": 0x098B, + "lvocalicbengali": 0x098C, + "ebengali": 0x098F, + "aibengali": 0x0990, + "obengali": 0x0993, + "aubengali": 0x0994, + "kabengali": 0x0995, + "khabengali": 0x0996, + "gabengali": 0x0997, + "ghabengali": 0x0998, + "ngabengali": 0x0999, + "cabengali": 0x099A, + "chabengali": 0x099B, + "jabengali": 0x099C, + "jhabengali": 0x099D, + "nyabengali": 0x099E, + "ttabengali": 0x099F, + "tthabengali": 0x09A0, + "ddabengali": 0x09A1, + "ddhabengali": 0x09A2, + "nnabengali": 0x09A3, + "tabengali": 0x09A4, + "thabengali": 0x09A5, + "dabengali": 0x09A6, + "dhabengali": 0x09A7, + "nabengali": 0x09A8, + "pabengali": 0x09AA, + "phabengali": 0x09AB, + "babengali": 0x09AC, + "bhabengali": 0x09AD, + "mabengali": 0x09AE, + "yabengali": 0x09AF, + "rabengali": 0x09B0, + "labengali": 0x09B2, + "shabengali": 0x09B6, + "ssabengali": 0x09B7, + "sabengali": 0x09B8, + "habengali": 0x09B9, + "nuktabengali": 0x09BC, + "aavowelsignbengali": 0x09BE, + "ivowelsignbengali": 0x09BF, + "iivowelsignbengali": 0x09C0, + "uvowelsignbengali": 0x09C1, + "uuvowelsignbengali": 0x09C2, + "rvocalicvowelsignbengali": 0x09C3, + "rrvocalicvowelsignbengali": 0x09C4, + "evowelsignbengali": 0x09C7, + "aivowelsignbengali": 0x09C8, + "ovowelsignbengali": 0x09CB, + "auvowelsignbengali": 0x09CC, + "viramabengali": 0x09CD, + "aulengthmarkbengali": 0x09D7, + "rrabengali": 0x09DC, + "rhabengali": 0x09DD, + "yyabengali": 0x09DF, + "rrvocalicbengali": 0x09E0, + "llvocalicbengali": 0x09E1, + "lvocalicvowelsignbengali": 0x09E2, + "llvocalicvowelsignbengali": 0x09E3, + "zerobengali": 0x09E6, + "onebengali": 0x09E7, + "twobengali": 0x09E8, + "threebengali": 0x09E9, + "fourbengali": 0x09EA, + "fivebengali": 0x09EB, + "sixbengali": 0x09EC, + "sevenbengali": 0x09ED, + "eightbengali": 0x09EE, + "ninebengali": 0x09EF, + "ramiddlediagonalbengali": 0x09F0, + "ralowerdiagonalbengali": 0x09F1, + "rupeemarkbengali": 0x09F2, + "rupeesignbengali": 0x09F3, + "onenumeratorbengali": 0x09F4, + "twonumeratorbengali": 0x09F5, + "threenumeratorbengali": 0x09F6, + "fournumeratorbengali": 0x09F7, + "denominatorminusonenumeratorbengali": 0x09F8, + "sixteencurrencydenominatorbengali": 0x09F9, + "issharbengali": 0x09FA, + "bindigurmukhi": 0x0A02, + "agurmukhi": 0x0A05, + "aagurmukhi": 0x0A06, + "igurmukhi": 0x0A07, + "iigurmukhi": 0x0A08, + "ugurmukhi": 0x0A09, + "uugurmukhi": 0x0A0A, + "eegurmukhi": 0x0A0F, + "aigurmukhi": 0x0A10, + "oogurmukhi": 0x0A13, + "augurmukhi": 0x0A14, + "kagurmukhi": 0x0A15, + "khagurmukhi": 0x0A16, + "gagurmukhi": 0x0A17, + "ghagurmukhi": 0x0A18, + "ngagurmukhi": 0x0A19, + "cagurmukhi": 0x0A1A, + "chagurmukhi": 0x0A1B, + "jagurmukhi": 0x0A1C, + "jhagurmukhi": 0x0A1D, + "nyagurmukhi": 0x0A1E, + "ttagurmukhi": 0x0A1F, + "tthagurmukhi": 0x0A20, + "ddagurmukhi": 0x0A21, + "ddhagurmukhi": 0x0A22, + "nnagurmukhi": 0x0A23, + "tagurmukhi": 0x0A24, + "thagurmukhi": 0x0A25, + "dagurmukhi": 0x0A26, + "dhagurmukhi": 0x0A27, + "nagurmukhi": 0x0A28, + "pagurmukhi": 0x0A2A, + "phagurmukhi": 0x0A2B, + "bagurmukhi": 0x0A2C, + "bhagurmukhi": 0x0A2D, + "magurmukhi": 0x0A2E, + "yagurmukhi": 0x0A2F, + "ragurmukhi": 0x0A30, + "lagurmukhi": 0x0A32, + "vagurmukhi": 0x0A35, + "shagurmukhi": 0x0A36, + "sagurmukhi": 0x0A38, + "hagurmukhi": 0x0A39, + "nuktagurmukhi": 0x0A3C, + "aamatragurmukhi": 0x0A3E, + "imatragurmukhi": 0x0A3F, + "iimatragurmukhi": 0x0A40, + "umatragurmukhi": 0x0A41, + "uumatragurmukhi": 0x0A42, + "eematragurmukhi": 0x0A47, + "aimatragurmukhi": 0x0A48, + "oomatragurmukhi": 0x0A4B, + "aumatragurmukhi": 0x0A4C, + "halantgurmukhi": 0x0A4D, + "khhagurmukhi": 0x0A59, + "ghhagurmukhi": 0x0A5A, + "zagurmukhi": 0x0A5B, + "rragurmukhi": 0x0A5C, + "fagurmukhi": 0x0A5E, + "zerogurmukhi": 0x0A66, + "onegurmukhi": 0x0A67, + "twogurmukhi": 0x0A68, + "threegurmukhi": 0x0A69, + "fourgurmukhi": 0x0A6A, + "fivegurmukhi": 0x0A6B, + "sixgurmukhi": 0x0A6C, + "sevengurmukhi": 0x0A6D, + "eightgurmukhi": 0x0A6E, + "ninegurmukhi": 0x0A6F, + "tippigurmukhi": 0x0A70, + "addakgurmukhi": 0x0A71, + "irigurmukhi": 0x0A72, + "uragurmukhi": 0x0A73, + "ekonkargurmukhi": 0x0A74, + "candrabindugujarati": 0x0A81, + "anusvaragujarati": 0x0A82, + "visargagujarati": 0x0A83, + "agujarati": 0x0A85, + "aagujarati": 0x0A86, + "igujarati": 0x0A87, + "iigujarati": 0x0A88, + "ugujarati": 0x0A89, + "uugujarati": 0x0A8A, + "rvocalicgujarati": 0x0A8B, + "ecandragujarati": 0x0A8D, + "egujarati": 0x0A8F, + "aigujarati": 0x0A90, + "ocandragujarati": 0x0A91, + "ogujarati": 0x0A93, + "augujarati": 0x0A94, + "kagujarati": 0x0A95, + "khagujarati": 0x0A96, + "gagujarati": 0x0A97, + "ghagujarati": 0x0A98, + "ngagujarati": 0x0A99, + "cagujarati": 0x0A9A, + "chagujarati": 0x0A9B, + "jagujarati": 0x0A9C, + "jhagujarati": 0x0A9D, + "nyagujarati": 0x0A9E, + "ttagujarati": 0x0A9F, + "tthagujarati": 0x0AA0, + "ddagujarati": 0x0AA1, + "ddhagujarati": 0x0AA2, + "nnagujarati": 0x0AA3, + "tagujarati": 0x0AA4, + "thagujarati": 0x0AA5, + "dagujarati": 0x0AA6, + "dhagujarati": 0x0AA7, + "nagujarati": 0x0AA8, + "pagujarati": 0x0AAA, + "phagujarati": 0x0AAB, + "bagujarati": 0x0AAC, + "bhagujarati": 0x0AAD, + "magujarati": 0x0AAE, + "yagujarati": 0x0AAF, + "ragujarati": 0x0AB0, + "lagujarati": 0x0AB2, + "llagujarati": 0x0AB3, + "vagujarati": 0x0AB5, + "shagujarati": 0x0AB6, + "ssagujarati": 0x0AB7, + "sagujarati": 0x0AB8, + "hagujarati": 0x0AB9, + "nuktagujarati": 0x0ABC, + "aavowelsigngujarati": 0x0ABE, + "ivowelsigngujarati": 0x0ABF, + "iivowelsigngujarati": 0x0AC0, + "uvowelsigngujarati": 0x0AC1, + "uuvowelsigngujarati": 0x0AC2, + "rvocalicvowelsigngujarati": 0x0AC3, + "rrvocalicvowelsigngujarati": 0x0AC4, + "ecandravowelsigngujarati": 0x0AC5, + "evowelsigngujarati": 0x0AC7, + "aivowelsigngujarati": 0x0AC8, + "ocandravowelsigngujarati": 0x0AC9, + "ovowelsigngujarati": 0x0ACB, + "auvowelsigngujarati": 0x0ACC, + "viramagujarati": 0x0ACD, + "omgujarati": 0x0AD0, + "rrvocalicgujarati": 0x0AE0, + "zerogujarati": 0x0AE6, + "onegujarati": 0x0AE7, + "twogujarati": 0x0AE8, + "threegujarati": 0x0AE9, + "fourgujarati": 0x0AEA, + "fivegujarati": 0x0AEB, + "sixgujarati": 0x0AEC, + "sevengujarati": 0x0AED, + "eightgujarati": 0x0AEE, + "ninegujarati": 0x0AEF, + "kokaithai": 0x0E01, + "khokhaithai": 0x0E02, + "khokhuatthai": 0x0E03, + "khokhwaithai": 0x0E04, + "khokhonthai": 0x0E05, + "khorakhangthai": 0x0E06, + "ngonguthai": 0x0E07, + "chochanthai": 0x0E08, + "chochingthai": 0x0E09, + "chochangthai": 0x0E0A, + "sosothai": 0x0E0B, + "chochoethai": 0x0E0C, + "yoyingthai": 0x0E0D, + "dochadathai": 0x0E0E, + "topatakthai": 0x0E0F, + "thothanthai": 0x0E10, + "thonangmonthothai": 0x0E11, + "thophuthaothai": 0x0E12, + "nonenthai": 0x0E13, + "dodekthai": 0x0E14, + "totaothai": 0x0E15, + "thothungthai": 0x0E16, + "thothahanthai": 0x0E17, + "thothongthai": 0x0E18, + "nonuthai": 0x0E19, + "bobaimaithai": 0x0E1A, + "poplathai": 0x0E1B, + "phophungthai": 0x0E1C, + "fofathai": 0x0E1D, + "phophanthai": 0x0E1E, + "fofanthai": 0x0E1F, + "phosamphaothai": 0x0E20, + "momathai": 0x0E21, + "yoyakthai": 0x0E22, + "roruathai": 0x0E23, + "ruthai": 0x0E24, + "lolingthai": 0x0E25, + "luthai": 0x0E26, + "wowaenthai": 0x0E27, + "sosalathai": 0x0E28, + "sorusithai": 0x0E29, + "sosuathai": 0x0E2A, + "hohipthai": 0x0E2B, + "lochulathai": 0x0E2C, + "oangthai": 0x0E2D, + "honokhukthai": 0x0E2E, + "paiyannoithai": 0x0E2F, + "saraathai": 0x0E30, + "maihanakatthai": 0x0E31, + "saraaathai": 0x0E32, + "saraamthai": 0x0E33, + "saraithai": 0x0E34, + "saraiithai": 0x0E35, + "sarauethai": 0x0E36, + "saraueethai": 0x0E37, + "sarauthai": 0x0E38, + "sarauuthai": 0x0E39, + "phinthuthai": 0x0E3A, + "bahtthai": 0x0E3F, + "saraethai": 0x0E40, + "saraaethai": 0x0E41, + "saraothai": 0x0E42, + "saraaimaimuanthai": 0x0E43, + "saraaimaimalaithai": 0x0E44, + "lakkhangyaothai": 0x0E45, + "maiyamokthai": 0x0E46, + "maitaikhuthai": 0x0E47, + "maiekthai": 0x0E48, + "maithothai": 0x0E49, + "maitrithai": 0x0E4A, + "maichattawathai": 0x0E4B, + "thanthakhatthai": 0x0E4C, + "nikhahitthai": 0x0E4D, + "yamakkanthai": 0x0E4E, + "fongmanthai": 0x0E4F, + "zerothai": 0x0E50, + "onethai": 0x0E51, + "twothai": 0x0E52, + "threethai": 0x0E53, + "fourthai": 0x0E54, + "fivethai": 0x0E55, + "sixthai": 0x0E56, + "seventhai": 0x0E57, + "eightthai": 0x0E58, + "ninethai": 0x0E59, + "angkhankhuthai": 0x0E5A, + "khomutthai": 0x0E5B, + "Aringbelow": 0x1E00, + "aringbelow": 0x1E01, + "Bdotaccent": 0x1E02, + "bdotaccent": 0x1E03, + "Bdotbelow": 0x1E04, + "bdotbelow": 0x1E05, + "Blinebelow": 0x1E06, + "blinebelow": 0x1E07, + "Ccedillaacute": 0x1E08, + "ccedillaacute": 0x1E09, + "Ddotaccent": 0x1E0A, + "ddotaccent": 0x1E0B, + "Ddotbelow": 0x1E0C, + "ddotbelow": 0x1E0D, + "Dlinebelow": 0x1E0E, + "dlinebelow": 0x1E0F, + "Dcedilla": 0x1E10, + "dcedilla": 0x1E11, + "Dcircumflexbelow": 0x1E12, + "dcircumflexbelow": 0x1E13, + "Emacrongrave": 0x1E14, + "emacrongrave": 0x1E15, + "Emacronacute": 0x1E16, + "emacronacute": 0x1E17, + "Ecircumflexbelow": 0x1E18, + "ecircumflexbelow": 0x1E19, + "Etildebelow": 0x1E1A, + "etildebelow": 0x1E1B, + "Ecedillabreve": 0x1E1C, + "ecedillabreve": 0x1E1D, + "Fdotaccent": 0x1E1E, + "fdotaccent": 0x1E1F, + "Gmacron": 0x1E20, + "gmacron": 0x1E21, + "Hdotaccent": 0x1E22, + "hdotaccent": 0x1E23, + "Hdotbelow": 0x1E24, + "hdotbelow": 0x1E25, + "Hdieresis": 0x1E26, + "hdieresis": 0x1E27, + "Hcedilla": 0x1E28, + "hcedilla": 0x1E29, + "Hbrevebelow": 0x1E2A, + "hbrevebelow": 0x1E2B, + "Itildebelow": 0x1E2C, + "itildebelow": 0x1E2D, + "Idieresisacute": 0x1E2E, + "idieresisacute": 0x1E2F, + "Kacute": 0x1E30, + "kacute": 0x1E31, + "Kdotbelow": 0x1E32, + "kdotbelow": 0x1E33, + "Klinebelow": 0x1E34, + "klinebelow": 0x1E35, + "Ldotbelow": 0x1E36, + "ldotbelow": 0x1E37, + "Ldotbelowmacron": 0x1E38, + "ldotbelowmacron": 0x1E39, + "Llinebelow": 0x1E3A, + "llinebelow": 0x1E3B, + "Lcircumflexbelow": 0x1E3C, + "lcircumflexbelow": 0x1E3D, + "Macute": 0x1E3E, + "macute": 0x1E3F, + "Mdotaccent": 0x1E40, + "mdotaccent": 0x1E41, + "Mdotbelow": 0x1E42, + "mdotbelow": 0x1E43, + "Ndotaccent": 0x1E44, + "ndotaccent": 0x1E45, + "Ndotbelow": 0x1E46, + "ndotbelow": 0x1E47, + "Nlinebelow": 0x1E48, + "nlinebelow": 0x1E49, + "Ncircumflexbelow": 0x1E4A, + "ncircumflexbelow": 0x1E4B, + "Otildeacute": 0x1E4C, + "otildeacute": 0x1E4D, + "Otildedieresis": 0x1E4E, + "otildedieresis": 0x1E4F, + "Omacrongrave": 0x1E50, + "omacrongrave": 0x1E51, + "Omacronacute": 0x1E52, + "omacronacute": 0x1E53, + "Pacute": 0x1E54, + "pacute": 0x1E55, + "Pdotaccent": 0x1E56, + "pdotaccent": 0x1E57, + "Rdotaccent": 0x1E58, + "rdotaccent": 0x1E59, + "Rdotbelow": 0x1E5A, + "rdotbelow": 0x1E5B, + "Rdotbelowmacron": 0x1E5C, + "rdotbelowmacron": 0x1E5D, + "Rlinebelow": 0x1E5E, + "rlinebelow": 0x1E5F, + "Sdotaccent": 0x1E60, + "sdotaccent": 0x1E61, + "Sdotbelow": 0x1E62, + "sdotbelow": 0x1E63, + "Sacutedotaccent": 0x1E64, + "sacutedotaccent": 0x1E65, + "Scarondotaccent": 0x1E66, + "scarondotaccent": 0x1E67, + "Sdotbelowdotaccent": 0x1E68, + "sdotbelowdotaccent": 0x1E69, + "Tdotaccent": 0x1E6A, + "tdotaccent": 0x1E6B, + "Tdotbelow": 0x1E6C, + "tdotbelow": 0x1E6D, + "Tlinebelow": 0x1E6E, + "tlinebelow": 0x1E6F, + "Tcircumflexbelow": 0x1E70, + "tcircumflexbelow": 0x1E71, + "Udieresisbelow": 0x1E72, + "udieresisbelow": 0x1E73, + "Utildebelow": 0x1E74, + "utildebelow": 0x1E75, + "Ucircumflexbelow": 0x1E76, + "ucircumflexbelow": 0x1E77, + "Utildeacute": 0x1E78, + "utildeacute": 0x1E79, + "Umacrondieresis": 0x1E7A, + "umacrondieresis": 0x1E7B, + "Vtilde": 0x1E7C, + "vtilde": 0x1E7D, + "Vdotbelow": 0x1E7E, + "vdotbelow": 0x1E7F, + "Wgrave": 0x1E80, + "wgrave": 0x1E81, + "Wacute": 0x1E82, + "wacute": 0x1E83, + "Wdieresis": 0x1E84, + "wdieresis": 0x1E85, + "Wdotaccent": 0x1E86, + "wdotaccent": 0x1E87, + "Wdotbelow": 0x1E88, + "wdotbelow": 0x1E89, + "Xdotaccent": 0x1E8A, + "xdotaccent": 0x1E8B, + "Xdieresis": 0x1E8C, + "xdieresis": 0x1E8D, + "Ydotaccent": 0x1E8E, + "ydotaccent": 0x1E8F, + "Zcircumflex": 0x1E90, + "zcircumflex": 0x1E91, + "Zdotbelow": 0x1E92, + "zdotbelow": 0x1E93, + "Zlinebelow": 0x1E94, + "zlinebelow": 0x1E95, + "hlinebelow": 0x1E96, + "tdieresis": 0x1E97, + "wring": 0x1E98, + "yring": 0x1E99, + "arighthalfring": 0x1E9A, + "slongdotaccent": 0x1E9B, + "Adotbelow": 0x1EA0, + "adotbelow": 0x1EA1, + "Ahookabove": 0x1EA2, + "ahookabove": 0x1EA3, + "Acircumflexacute": 0x1EA4, + "acircumflexacute": 0x1EA5, + "Acircumflexgrave": 0x1EA6, + "acircumflexgrave": 0x1EA7, + "Acircumflexhookabove": 0x1EA8, + "acircumflexhookabove": 0x1EA9, + "Acircumflextilde": 0x1EAA, + "acircumflextilde": 0x1EAB, + "Acircumflexdotbelow": 0x1EAC, + "acircumflexdotbelow": 0x1EAD, + "Abreveacute": 0x1EAE, + "abreveacute": 0x1EAF, + "Abrevegrave": 0x1EB0, + "abrevegrave": 0x1EB1, + "Abrevehookabove": 0x1EB2, + "abrevehookabove": 0x1EB3, + "Abrevetilde": 0x1EB4, + "abrevetilde": 0x1EB5, + "Abrevedotbelow": 0x1EB6, + "abrevedotbelow": 0x1EB7, + "Edotbelow": 0x1EB8, + "edotbelow": 0x1EB9, + "Ehookabove": 0x1EBA, + "ehookabove": 0x1EBB, + "Etilde": 0x1EBC, + "etilde": 0x1EBD, + "Ecircumflexacute": 0x1EBE, + "ecircumflexacute": 0x1EBF, + "Ecircumflexgrave": 0x1EC0, + "ecircumflexgrave": 0x1EC1, + "Ecircumflexhookabove": 0x1EC2, + "ecircumflexhookabove": 0x1EC3, + "Ecircumflextilde": 0x1EC4, + "ecircumflextilde": 0x1EC5, + "Ecircumflexdotbelow": 0x1EC6, + "ecircumflexdotbelow": 0x1EC7, + "Ihookabove": 0x1EC8, + "ihookabove": 0x1EC9, + "Idotbelow": 0x1ECA, + "idotbelow": 0x1ECB, + "Odotbelow": 0x1ECC, + "odotbelow": 0x1ECD, + "Ohookabove": 0x1ECE, + "ohookabove": 0x1ECF, + "Ocircumflexacute": 0x1ED0, + "ocircumflexacute": 0x1ED1, + "Ocircumflexgrave": 0x1ED2, + "ocircumflexgrave": 0x1ED3, + "Ocircumflexhookabove": 0x1ED4, + "ocircumflexhookabove": 0x1ED5, + "Ocircumflextilde": 0x1ED6, + "ocircumflextilde": 0x1ED7, + "Ocircumflexdotbelow": 0x1ED8, + "ocircumflexdotbelow": 0x1ED9, + "Ohornacute": 0x1EDA, + "ohornacute": 0x1EDB, + "Ohorngrave": 0x1EDC, + "ohorngrave": 0x1EDD, + "Ohornhookabove": 0x1EDE, + "ohornhookabove": 0x1EDF, + "Ohorntilde": 0x1EE0, + "ohorntilde": 0x1EE1, + "Ohorndotbelow": 0x1EE2, + "ohorndotbelow": 0x1EE3, + "Udotbelow": 0x1EE4, + "udotbelow": 0x1EE5, + "Uhookabove": 0x1EE6, + "uhookabove": 0x1EE7, + "Uhornacute": 0x1EE8, + "uhornacute": 0x1EE9, + "Uhorngrave": 0x1EEA, + "uhorngrave": 0x1EEB, + "Uhornhookabove": 0x1EEC, + "uhornhookabove": 0x1EED, + "Uhorntilde": 0x1EEE, + "uhorntilde": 0x1EEF, + "Uhorndotbelow": 0x1EF0, + "uhorndotbelow": 0x1EF1, + "Ygrave": 0x1EF2, + "ygrave": 0x1EF3, + "Ydotbelow": 0x1EF4, + "ydotbelow": 0x1EF5, + "Yhookabove": 0x1EF6, + "yhookabove": 0x1EF7, + "Ytilde": 0x1EF8, + "ytilde": 0x1EF9, + "zerowidthspace": 0x200B, + "hyphentwo": 0x2010, + "figuredash": 0x2012, + "afii00208": 0x2015, + "horizontalbar": 0x2015, + "dblverticalbar": 0x2016, + "dbllowline": 0x2017, + "underscoredbl": 0x2017, + "quoteleftreversed": 0x201B, + "quotereversed": 0x201B, + "onedotenleader": 0x2024, + "twodotenleader": 0x2025, + "twodotleader": 0x2025, + "afii61573": 0x202C, + "afii61574": 0x202D, + "afii61575": 0x202E, + "primereversed": 0x2035, + "referencemark": 0x203B, + "exclamdbl": 0x203C, + "asterism": 0x2042, + "zerosuperior": 0x2070, + "foursuperior": 0x2074, + "fivesuperior": 0x2075, + "sixsuperior": 0x2076, + "sevensuperior": 0x2077, + "eightsuperior": 0x2078, + "ninesuperior": 0x2079, + "plussuperior": 0x207A, + "equalsuperior": 0x207C, + "parenleftsuperior": 0x207D, + "parenrightsuperior": 0x207E, + "nsuperior": 0x207F, + "zeroinferior": 0x2080, + "oneinferior": 0x2081, + "twoinferior": 0x2082, + "threeinferior": 0x2083, + "fourinferior": 0x2084, + "fiveinferior": 0x2085, + "sixinferior": 0x2086, + "seveninferior": 0x2087, + "eightinferior": 0x2088, + "nineinferior": 0x2089, + "parenleftinferior": 0x208D, + "parenrightinferior": 0x208E, + "colonmonetary": 0x20A1, + "colonsign": 0x20A1, + "cruzeiro": 0x20A2, + "franc": 0x20A3, + "afii08941": 0x20A4, + "lira": 0x20A4, + "peseta": 0x20A7, + "won": 0x20A9, + "afii57636": 0x20AA, + "newsheqelsign": 0x20AA, + "sheqel": 0x20AA, + "sheqelhebrew": 0x20AA, + "dong": 0x20AB, + "centigrade": 0x2103, + "afii61248": 0x2105, + "careof": 0x2105, + "fahrenheit": 0x2109, + "afii61289": 0x2113, + "lsquare": 0x2113, + "afii61352": 0x2116, + "numero": 0x2116, + "prescription": 0x211E, + "telephone": 0x2121, + "Ohm": 0x2126, + "Omega": 0x2126, + "angstrom": 0x212B, + "estimated": 0x212E, + "onethird": 0x2153, + "twothirds": 0x2154, + "oneeighth": 0x215B, + "threeeighths": 0x215C, + "fiveeighths": 0x215D, + "seveneighths": 0x215E, + "Oneroman": 0x2160, + "Tworoman": 0x2161, + "Threeroman": 0x2162, + "Fourroman": 0x2163, + "Fiveroman": 0x2164, + "Sixroman": 0x2165, + "Sevenroman": 0x2166, + "Eightroman": 0x2167, + "Nineroman": 0x2168, + "Tenroman": 0x2169, + "Elevenroman": 0x216A, + "Twelveroman": 0x216B, + "oneroman": 0x2170, + "tworoman": 0x2171, + "threeroman": 0x2172, + "fourroman": 0x2173, + "fiveroman": 0x2174, + "sixroman": 0x2175, + "sevenroman": 0x2176, + "eightroman": 0x2177, + "nineroman": 0x2178, + "tenroman": 0x2179, + "elevenroman": 0x217A, + "twelveroman": 0x217B, + "arrowupdn": 0x2195, + "arrowupleft": 0x2196, + "arrowupright": 0x2197, + "arrowdownright": 0x2198, + "arrowdownleft": 0x2199, + "arrowupdnbse": 0x21A8, + "arrowupdownbase": 0x21A8, + "harpoonleftbarbup": 0x21BC, + "harpoonrightbarbup": 0x21C0, + "arrowrightoverleft": 0x21C4, + "arrowupleftofdown": 0x21C5, + "arrowleftoverright": 0x21C6, + "arrowleftdblstroke": 0x21CD, + "arrowrightdblstroke": 0x21CF, + "pageup": 0x21DE, + "pagedown": 0x21DF, + "arrowdashleft": 0x21E0, + "arrowdashup": 0x21E1, + "arrowdashright": 0x21E2, + "arrowdashdown": 0x21E3, + "arrowtableft": 0x21E4, + "arrowtabright": 0x21E5, + "arrowleftwhite": 0x21E6, + "arrowupwhite": 0x21E7, + "arrowrightwhite": 0x21E8, + "arrowdownwhite": 0x21E9, + "capslock": 0x21EA, + "Delta": 0x2206, + "increment": 0x2206, + "notcontains": 0x220C, + "minusplus": 0x2213, + "divisionslash": 0x2215, + "bulletoperator": 0x2219, + "orthogonal": 0x221F, + "rightangle": 0x221F, + "divides": 0x2223, + "parallel": 0x2225, + "notparallel": 0x2226, + "dblintegral": 0x222C, + "contourintegral": 0x222E, + "because": 0x2235, + "ratio": 0x2236, + "proportion": 0x2237, + "reversedtilde": 0x223D, + "asymptoticallyequal": 0x2243, + "allequal": 0x224C, + "approaches": 0x2250, + "geometricallyequal": 0x2251, + "approxequalorimage": 0x2252, + "imageorapproximatelyequal": 0x2253, + "notidentical": 0x2262, + "lessoverequal": 0x2266, + "greateroverequal": 0x2267, + "muchless": 0x226A, + "muchgreater": 0x226B, + "notless": 0x226E, + "notgreater": 0x226F, + "notlessnorequal": 0x2270, + "notgreaternorequal": 0x2271, + "lessorequivalent": 0x2272, + "greaterorequivalent": 0x2273, + "lessorgreater": 0x2276, + "greaterorless": 0x2277, + "notgreaternorless": 0x2279, + "precedes": 0x227A, + "succeeds": 0x227B, + "notprecedes": 0x2280, + "notsucceeds": 0x2281, + "notsuperset": 0x2285, + "subsetnotequal": 0x228A, + "supersetnotequal": 0x228B, + "minuscircle": 0x2296, + "circleot": 0x2299, + "tackleft": 0x22A3, + "tackdown": 0x22A4, + "righttriangle": 0x22BF, + "curlyor": 0x22CE, + "curlyand": 0x22CF, + "lessequalorgreater": 0x22DA, + "greaterequalorless": 0x22DB, + "ellipsisvertical": 0x22EE, + "house": 0x2302, + "control": 0x2303, + "projective": 0x2305, + "logicalnotreversed": 0x2310, + "revlogicalnot": 0x2310, + "arc": 0x2312, + "propellor": 0x2318, + "integraltop": 0x2320, + "integraltp": 0x2320, + "integralbottom": 0x2321, + "integralbt": 0x2321, + "option": 0x2325, + "deleteright": 0x2326, + "clear": 0x2327, + "deleteleft": 0x232B, + "blank": 0x2423, + "onecircle": 0x2460, + "twocircle": 0x2461, + "threecircle": 0x2462, + "fourcircle": 0x2463, + "fivecircle": 0x2464, + "sixcircle": 0x2465, + "sevencircle": 0x2466, + "eightcircle": 0x2467, + "ninecircle": 0x2468, + "tencircle": 0x2469, + "elevencircle": 0x246A, + "twelvecircle": 0x246B, + "thirteencircle": 0x246C, + "fourteencircle": 0x246D, + "fifteencircle": 0x246E, + "sixteencircle": 0x246F, + "seventeencircle": 0x2470, + "eighteencircle": 0x2471, + "nineteencircle": 0x2472, + "twentycircle": 0x2473, + "oneparen": 0x2474, + "twoparen": 0x2475, + "threeparen": 0x2476, + "fourparen": 0x2477, + "fiveparen": 0x2478, + "sixparen": 0x2479, + "sevenparen": 0x247A, + "eightparen": 0x247B, + "nineparen": 0x247C, + "tenparen": 0x247D, + "elevenparen": 0x247E, + "twelveparen": 0x247F, + "thirteenparen": 0x2480, + "fourteenparen": 0x2481, + "fifteenparen": 0x2482, + "sixteenparen": 0x2483, + "seventeenparen": 0x2484, + "eighteenparen": 0x2485, + "nineteenparen": 0x2486, + "twentyparen": 0x2487, + "oneperiod": 0x2488, + "twoperiod": 0x2489, + "threeperiod": 0x248A, + "fourperiod": 0x248B, + "fiveperiod": 0x248C, + "sixperiod": 0x248D, + "sevenperiod": 0x248E, + "eightperiod": 0x248F, + "nineperiod": 0x2490, + "tenperiod": 0x2491, + "elevenperiod": 0x2492, + "twelveperiod": 0x2493, + "thirteenperiod": 0x2494, + "fourteenperiod": 0x2495, + "fifteenperiod": 0x2496, + "sixteenperiod": 0x2497, + "seventeenperiod": 0x2498, + "eighteenperiod": 0x2499, + "nineteenperiod": 0x249A, + "twentyperiod": 0x249B, + "aparen": 0x249C, + "bparen": 0x249D, + "cparen": 0x249E, + "dparen": 0x249F, + "eparen": 0x24A0, + "fparen": 0x24A1, + "gparen": 0x24A2, + "hparen": 0x24A3, + "iparen": 0x24A4, + "jparen": 0x24A5, + "kparen": 0x24A6, + "lparen": 0x24A7, + "mparen": 0x24A8, + "nparen": 0x24A9, + "oparen": 0x24AA, + "pparen": 0x24AB, + "qparen": 0x24AC, + "rparen": 0x24AD, + "sparen": 0x24AE, + "tparen": 0x24AF, + "uparen": 0x24B0, + "vparen": 0x24B1, + "wparen": 0x24B2, + "xparen": 0x24B3, + "yparen": 0x24B4, + "zparen": 0x24B5, + "Acircle": 0x24B6, + "Bcircle": 0x24B7, + "Ccircle": 0x24B8, + "Dcircle": 0x24B9, + "Ecircle": 0x24BA, + "Fcircle": 0x24BB, + "Gcircle": 0x24BC, + "Hcircle": 0x24BD, + "Icircle": 0x24BE, + "Jcircle": 0x24BF, + "Kcircle": 0x24C0, + "Lcircle": 0x24C1, + "Mcircle": 0x24C2, + "Ncircle": 0x24C3, + "Ocircle": 0x24C4, + "Pcircle": 0x24C5, + "Qcircle": 0x24C6, + "Rcircle": 0x24C7, + "Scircle": 0x24C8, + "Tcircle": 0x24C9, + "Ucircle": 0x24CA, + "Vcircle": 0x24CB, + "Wcircle": 0x24CC, + "Xcircle": 0x24CD, + "Ycircle": 0x24CE, + "Zcircle": 0x24CF, + "acircle": 0x24D0, + "bcircle": 0x24D1, + "ccircle": 0x24D2, + "dcircle": 0x24D3, + "ecircle": 0x24D4, + "fcircle": 0x24D5, + "gcircle": 0x24D6, + "hcircle": 0x24D7, + "icircle": 0x24D8, + "jcircle": 0x24D9, + "kcircle": 0x24DA, + "lcircle": 0x24DB, + "mcircle": 0x24DC, + "ncircle": 0x24DD, + "ocircle": 0x24DE, + "pcircle": 0x24DF, + "qcircle": 0x24E0, + "rcircle": 0x24E1, + "scircle": 0x24E2, + "tcircle": 0x24E3, + "ucircle": 0x24E4, + "vcircle": 0x24E5, + "wcircle": 0x24E6, + "xcircle": 0x24E7, + "ycircle": 0x24E8, + "zcircle": 0x24E9, + "SF100000": 0x2500, + "SF110000": 0x2502, + "SF010000": 0x250C, + "SF030000": 0x2510, + "SF020000": 0x2514, + "SF040000": 0x2518, + "SF080000": 0x251C, + "SF090000": 0x2524, + "SF060000": 0x252C, + "SF070000": 0x2534, + "SF050000": 0x253C, + "SF430000": 0x2550, + "SF240000": 0x2551, + "SF510000": 0x2552, + "SF520000": 0x2553, + "SF390000": 0x2554, + "SF220000": 0x2555, + "SF210000": 0x2556, + "SF250000": 0x2557, + "SF500000": 0x2558, + "SF490000": 0x2559, + "SF380000": 0x255A, + "SF280000": 0x255B, + "SF270000": 0x255C, + "SF260000": 0x255D, + "SF360000": 0x255E, + "SF370000": 0x255F, + "SF420000": 0x2560, + "SF190000": 0x2561, + "SF200000": 0x2562, + "SF230000": 0x2563, + "SF470000": 0x2564, + "SF480000": 0x2565, + "SF410000": 0x2566, + "SF450000": 0x2567, + "SF460000": 0x2568, + "SF400000": 0x2569, + "SF540000": 0x256A, + "SF530000": 0x256B, + "SF440000": 0x256C, + "upblock": 0x2580, + "dnblock": 0x2584, + "block": 0x2588, + "lfblock": 0x258C, + "rtblock": 0x2590, + "ltshade": 0x2591, + "shadelight": 0x2591, + "shade": 0x2592, + "shademedium": 0x2592, + "dkshade": 0x2593, + "shadedark": 0x2593, + "blacksquare": 0x25A0, + "filledbox": 0x25A0, + "H22073": 0x25A1, + "whitesquare": 0x25A1, + "squarewhitewithsmallblack": 0x25A3, + "squarehorizontalfill": 0x25A4, + "squareverticalfill": 0x25A5, + "squareorthogonalcrosshatchfill": 0x25A6, + "squareupperlefttolowerrightfill": 0x25A7, + "squareupperrighttolowerleftfill": 0x25A8, + "squarediagonalcrosshatchfill": 0x25A9, + "H18543": 0x25AA, + "blacksmallsquare": 0x25AA, + "H18551": 0x25AB, + "whitesmallsquare": 0x25AB, + "blackrectangle": 0x25AC, + "filledrect": 0x25AC, + "blackuppointingtriangle": 0x25B2, + "triagup": 0x25B2, + "whiteuppointingtriangle": 0x25B3, + "blackuppointingsmalltriangle": 0x25B4, + "whiteuppointingsmalltriangle": 0x25B5, + "blackrightpointingtriangle": 0x25B6, + "whiterightpointingtriangle": 0x25B7, + "whiterightpointingsmalltriangle": 0x25B9, + "blackrightpointingpointer": 0x25BA, + "triagrt": 0x25BA, + "blackdownpointingtriangle": 0x25BC, + "triagdn": 0x25BC, + "whitedownpointingtriangle": 0x25BD, + "whitedownpointingsmalltriangle": 0x25BF, + "blackleftpointingtriangle": 0x25C0, + "whiteleftpointingtriangle": 0x25C1, + "whiteleftpointingsmalltriangle": 0x25C3, + "blackleftpointingpointer": 0x25C4, + "triaglf": 0x25C4, + "blackdiamond": 0x25C6, + "whitediamond": 0x25C7, + "whitediamondcontainingblacksmalldiamond": 0x25C8, + "fisheye": 0x25C9, + "circle": 0x25CB, + "whitecircle": 0x25CB, + "dottedcircle": 0x25CC, + "bullseye": 0x25CE, + "H18533": 0x25CF, + "blackcircle": 0x25CF, + "circlewithlefthalfblack": 0x25D0, + "circlewithrighthalfblack": 0x25D1, + "bulletinverse": 0x25D8, + "invbullet": 0x25D8, + "invcircle": 0x25D9, + "whitecircleinverse": 0x25D9, + "blacklowerrighttriangle": 0x25E2, + "blacklowerlefttriangle": 0x25E3, + "blackupperlefttriangle": 0x25E4, + "blackupperrighttriangle": 0x25E5, + "openbullet": 0x25E6, + "whitebullet": 0x25E6, + "largecircle": 0x25EF, + "blackstar": 0x2605, + "whitestar": 0x2606, + "telephoneblack": 0x260E, + "whitetelephone": 0x260F, + "pointingindexleftwhite": 0x261C, + "pointingindexupwhite": 0x261D, + "pointingindexrightwhite": 0x261E, + "pointingindexdownwhite": 0x261F, + "yinyang": 0x262F, + "smileface": 0x263A, + "whitesmilingface": 0x263A, + "blacksmilingface": 0x263B, + "invsmileface": 0x263B, + "compass": 0x263C, + "sun": 0x263C, + "female": 0x2640, + "venus": 0x2640, + "earth": 0x2641, + "male": 0x2642, + "mars": 0x2642, + "heartsuitwhite": 0x2661, + "diamondsuitwhite": 0x2662, + "spadesuitwhite": 0x2664, + "clubsuitwhite": 0x2667, + "hotsprings": 0x2668, + "quarternote": 0x2669, + "musicalnote": 0x266A, + "eighthnotebeamed": 0x266B, + "musicalnotedbl": 0x266B, + "beamedsixteenthnotes": 0x266C, + "musicflatsign": 0x266D, + "musicsharpsign": 0x266F, + "checkmark": 0x2713, + "onecircleinversesansserif": 0x278A, + "twocircleinversesansserif": 0x278B, + "threecircleinversesansserif": 0x278C, + "fourcircleinversesansserif": 0x278D, + "fivecircleinversesansserif": 0x278E, + "sixcircleinversesansserif": 0x278F, + "sevencircleinversesansserif": 0x2790, + "eightcircleinversesansserif": 0x2791, + "ninecircleinversesansserif": 0x2792, + "arrowrightheavy": 0x279E, + "ideographicspace": 0x3000, + "ideographiccomma": 0x3001, + "ideographicperiod": 0x3002, + "dittomark": 0x3003, + "jis": 0x3004, + "ideographiciterationmark": 0x3005, + "ideographicclose": 0x3006, + "ideographiczero": 0x3007, + "anglebracketleft": 0x3008, + "anglebracketright": 0x3009, + "dblanglebracketleft": 0x300A, + "dblanglebracketright": 0x300B, + "cornerbracketleft": 0x300C, + "cornerbracketright": 0x300D, + "whitecornerbracketleft": 0x300E, + "whitecornerbracketright": 0x300F, + "blacklenticularbracketleft": 0x3010, + "blacklenticularbracketright": 0x3011, + "postalmark": 0x3012, + "getamark": 0x3013, + "tortoiseshellbracketleft": 0x3014, + "tortoiseshellbracketright": 0x3015, + "whitelenticularbracketleft": 0x3016, + "whitelenticularbracketright": 0x3017, + "whitetortoiseshellbracketleft": 0x3018, + "whitetortoiseshellbracketright": 0x3019, + "wavedash": 0x301C, + "quotedblprimereversed": 0x301D, + "quotedblprime": 0x301E, + "postalmarkface": 0x3020, + "onehangzhou": 0x3021, + "twohangzhou": 0x3022, + "threehangzhou": 0x3023, + "fourhangzhou": 0x3024, + "fivehangzhou": 0x3025, + "sixhangzhou": 0x3026, + "sevenhangzhou": 0x3027, + "eighthangzhou": 0x3028, + "ninehangzhou": 0x3029, + "circlepostalmark": 0x3036, + "asmallhiragana": 0x3041, + "ahiragana": 0x3042, + "ismallhiragana": 0x3043, + "ihiragana": 0x3044, + "usmallhiragana": 0x3045, + "uhiragana": 0x3046, + "esmallhiragana": 0x3047, + "ehiragana": 0x3048, + "osmallhiragana": 0x3049, + "ohiragana": 0x304A, + "kahiragana": 0x304B, + "gahiragana": 0x304C, + "kihiragana": 0x304D, + "gihiragana": 0x304E, + "kuhiragana": 0x304F, + "guhiragana": 0x3050, + "kehiragana": 0x3051, + "gehiragana": 0x3052, + "kohiragana": 0x3053, + "gohiragana": 0x3054, + "sahiragana": 0x3055, + "zahiragana": 0x3056, + "sihiragana": 0x3057, + "zihiragana": 0x3058, + "suhiragana": 0x3059, + "zuhiragana": 0x305A, + "sehiragana": 0x305B, + "zehiragana": 0x305C, + "sohiragana": 0x305D, + "zohiragana": 0x305E, + "tahiragana": 0x305F, + "dahiragana": 0x3060, + "tihiragana": 0x3061, + "dihiragana": 0x3062, + "tusmallhiragana": 0x3063, + "tuhiragana": 0x3064, + "duhiragana": 0x3065, + "tehiragana": 0x3066, + "dehiragana": 0x3067, + "tohiragana": 0x3068, + "dohiragana": 0x3069, + "nahiragana": 0x306A, + "nihiragana": 0x306B, + "nuhiragana": 0x306C, + "nehiragana": 0x306D, + "nohiragana": 0x306E, + "hahiragana": 0x306F, + "bahiragana": 0x3070, + "pahiragana": 0x3071, + "hihiragana": 0x3072, + "bihiragana": 0x3073, + "pihiragana": 0x3074, + "huhiragana": 0x3075, + "buhiragana": 0x3076, + "puhiragana": 0x3077, + "hehiragana": 0x3078, + "behiragana": 0x3079, + "pehiragana": 0x307A, + "hohiragana": 0x307B, + "bohiragana": 0x307C, + "pohiragana": 0x307D, + "mahiragana": 0x307E, + "mihiragana": 0x307F, + "muhiragana": 0x3080, + "mehiragana": 0x3081, + "mohiragana": 0x3082, + "yasmallhiragana": 0x3083, + "yahiragana": 0x3084, + "yusmallhiragana": 0x3085, + "yuhiragana": 0x3086, + "yosmallhiragana": 0x3087, + "yohiragana": 0x3088, + "rahiragana": 0x3089, + "rihiragana": 0x308A, + "ruhiragana": 0x308B, + "rehiragana": 0x308C, + "rohiragana": 0x308D, + "wasmallhiragana": 0x308E, + "wahiragana": 0x308F, + "wihiragana": 0x3090, + "wehiragana": 0x3091, + "wohiragana": 0x3092, + "nhiragana": 0x3093, + "vuhiragana": 0x3094, + "voicedmarkkana": 0x309B, + "semivoicedmarkkana": 0x309C, + "iterationhiragana": 0x309D, + "voicediterationhiragana": 0x309E, + "asmallkatakana": 0x30A1, + "akatakana": 0x30A2, + "ismallkatakana": 0x30A3, + "ikatakana": 0x30A4, + "usmallkatakana": 0x30A5, + "ukatakana": 0x30A6, + "esmallkatakana": 0x30A7, + "ekatakana": 0x30A8, + "osmallkatakana": 0x30A9, + "okatakana": 0x30AA, + "kakatakana": 0x30AB, + "gakatakana": 0x30AC, + "kikatakana": 0x30AD, + "gikatakana": 0x30AE, + "kukatakana": 0x30AF, + "gukatakana": 0x30B0, + "kekatakana": 0x30B1, + "gekatakana": 0x30B2, + "kokatakana": 0x30B3, + "gokatakana": 0x30B4, + "sakatakana": 0x30B5, + "zakatakana": 0x30B6, + "sikatakana": 0x30B7, + "zikatakana": 0x30B8, + "sukatakana": 0x30B9, + "zukatakana": 0x30BA, + "sekatakana": 0x30BB, + "zekatakana": 0x30BC, + "sokatakana": 0x30BD, + "zokatakana": 0x30BE, + "takatakana": 0x30BF, + "dakatakana": 0x30C0, + "tikatakana": 0x30C1, + "dikatakana": 0x30C2, + "tusmallkatakana": 0x30C3, + "tukatakana": 0x30C4, + "dukatakana": 0x30C5, + "tekatakana": 0x30C6, + "dekatakana": 0x30C7, + "tokatakana": 0x30C8, + "dokatakana": 0x30C9, + "nakatakana": 0x30CA, + "nikatakana": 0x30CB, + "nukatakana": 0x30CC, + "nekatakana": 0x30CD, + "nokatakana": 0x30CE, + "hakatakana": 0x30CF, + "bakatakana": 0x30D0, + "pakatakana": 0x30D1, + "hikatakana": 0x30D2, + "bikatakana": 0x30D3, + "pikatakana": 0x30D4, + "hukatakana": 0x30D5, + "bukatakana": 0x30D6, + "pukatakana": 0x30D7, + "hekatakana": 0x30D8, + "bekatakana": 0x30D9, + "pekatakana": 0x30DA, + "hokatakana": 0x30DB, + "bokatakana": 0x30DC, + "pokatakana": 0x30DD, + "makatakana": 0x30DE, + "mikatakana": 0x30DF, + "mukatakana": 0x30E0, + "mekatakana": 0x30E1, + "mokatakana": 0x30E2, + "yasmallkatakana": 0x30E3, + "yakatakana": 0x30E4, + "yusmallkatakana": 0x30E5, + "yukatakana": 0x30E6, + "yosmallkatakana": 0x30E7, + "yokatakana": 0x30E8, + "rakatakana": 0x30E9, + "rikatakana": 0x30EA, + "rukatakana": 0x30EB, + "rekatakana": 0x30EC, + "rokatakana": 0x30ED, + "wasmallkatakana": 0x30EE, + "wakatakana": 0x30EF, + "wikatakana": 0x30F0, + "wekatakana": 0x30F1, + "wokatakana": 0x30F2, + "nkatakana": 0x30F3, + "vukatakana": 0x30F4, + "kasmallkatakana": 0x30F5, + "kesmallkatakana": 0x30F6, + "vakatakana": 0x30F7, + "vikatakana": 0x30F8, + "vekatakana": 0x30F9, + "vokatakana": 0x30FA, + "dotkatakana": 0x30FB, + "prolongedkana": 0x30FC, + "iterationkatakana": 0x30FD, + "voicediterationkatakana": 0x30FE, + "bbopomofo": 0x3105, + "pbopomofo": 0x3106, + "mbopomofo": 0x3107, + "fbopomofo": 0x3108, + "dbopomofo": 0x3109, + "tbopomofo": 0x310A, + "nbopomofo": 0x310B, + "lbopomofo": 0x310C, + "gbopomofo": 0x310D, + "kbopomofo": 0x310E, + "hbopomofo": 0x310F, + "jbopomofo": 0x3110, + "qbopomofo": 0x3111, + "xbopomofo": 0x3112, + "zhbopomofo": 0x3113, + "chbopomofo": 0x3114, + "shbopomofo": 0x3115, + "rbopomofo": 0x3116, + "zbopomofo": 0x3117, + "cbopomofo": 0x3118, + "sbopomofo": 0x3119, + "abopomofo": 0x311A, + "obopomofo": 0x311B, + "ebopomofo": 0x311C, + "ehbopomofo": 0x311D, + "aibopomofo": 0x311E, + "eibopomofo": 0x311F, + "aubopomofo": 0x3120, + "oubopomofo": 0x3121, + "anbopomofo": 0x3122, + "enbopomofo": 0x3123, + "angbopomofo": 0x3124, + "engbopomofo": 0x3125, + "erbopomofo": 0x3126, + "ibopomofo": 0x3127, + "ubopomofo": 0x3128, + "iubopomofo": 0x3129, + "kiyeokkorean": 0x3131, + "ssangkiyeokkorean": 0x3132, + "kiyeoksioskorean": 0x3133, + "nieunkorean": 0x3134, + "nieuncieuckorean": 0x3135, + "nieunhieuhkorean": 0x3136, + "tikeutkorean": 0x3137, + "ssangtikeutkorean": 0x3138, + "rieulkorean": 0x3139, + "rieulkiyeokkorean": 0x313A, + "rieulmieumkorean": 0x313B, + "rieulpieupkorean": 0x313C, + "rieulsioskorean": 0x313D, + "rieulthieuthkorean": 0x313E, + "rieulphieuphkorean": 0x313F, + "rieulhieuhkorean": 0x3140, + "mieumkorean": 0x3141, + "pieupkorean": 0x3142, + "ssangpieupkorean": 0x3143, + "pieupsioskorean": 0x3144, + "sioskorean": 0x3145, + "ssangsioskorean": 0x3146, + "ieungkorean": 0x3147, + "cieuckorean": 0x3148, + "ssangcieuckorean": 0x3149, + "chieuchkorean": 0x314A, + "khieukhkorean": 0x314B, + "thieuthkorean": 0x314C, + "phieuphkorean": 0x314D, + "hieuhkorean": 0x314E, + "akorean": 0x314F, + "aekorean": 0x3150, + "yakorean": 0x3151, + "yaekorean": 0x3152, + "eokorean": 0x3153, + "ekorean": 0x3154, + "yeokorean": 0x3155, + "yekorean": 0x3156, + "okorean": 0x3157, + "wakorean": 0x3158, + "waekorean": 0x3159, + "oekorean": 0x315A, + "yokorean": 0x315B, + "ukorean": 0x315C, + "weokorean": 0x315D, + "wekorean": 0x315E, + "wikorean": 0x315F, + "yukorean": 0x3160, + "eukorean": 0x3161, + "yikorean": 0x3162, + "ikorean": 0x3163, + "hangulfiller": 0x3164, + "ssangnieunkorean": 0x3165, + "nieuntikeutkorean": 0x3166, + "nieunsioskorean": 0x3167, + "nieunpansioskorean": 0x3168, + "rieulkiyeoksioskorean": 0x3169, + "rieultikeutkorean": 0x316A, + "rieulpieupsioskorean": 0x316B, + "rieulpansioskorean": 0x316C, + "rieulyeorinhieuhkorean": 0x316D, + "mieumpieupkorean": 0x316E, + "mieumsioskorean": 0x316F, + "mieumpansioskorean": 0x3170, + "kapyeounmieumkorean": 0x3171, + "pieupkiyeokkorean": 0x3172, + "pieuptikeutkorean": 0x3173, + "pieupsioskiyeokkorean": 0x3174, + "pieupsiostikeutkorean": 0x3175, + "pieupcieuckorean": 0x3176, + "pieupthieuthkorean": 0x3177, + "kapyeounpieupkorean": 0x3178, + "kapyeounssangpieupkorean": 0x3179, + "sioskiyeokkorean": 0x317A, + "siosnieunkorean": 0x317B, + "siostikeutkorean": 0x317C, + "siospieupkorean": 0x317D, + "sioscieuckorean": 0x317E, + "pansioskorean": 0x317F, + "ssangieungkorean": 0x3180, + "yesieungkorean": 0x3181, + "yesieungsioskorean": 0x3182, + "yesieungpansioskorean": 0x3183, + "kapyeounphieuphkorean": 0x3184, + "ssanghieuhkorean": 0x3185, + "yeorinhieuhkorean": 0x3186, + "yoyakorean": 0x3187, + "yoyaekorean": 0x3188, + "yoikorean": 0x3189, + "yuyeokorean": 0x318A, + "yuyekorean": 0x318B, + "yuikorean": 0x318C, + "araeakorean": 0x318D, + "araeaekorean": 0x318E, + "kiyeokparenkorean": 0x3200, + "nieunparenkorean": 0x3201, + "tikeutparenkorean": 0x3202, + "rieulparenkorean": 0x3203, + "mieumparenkorean": 0x3204, + "pieupparenkorean": 0x3205, + "siosparenkorean": 0x3206, + "ieungparenkorean": 0x3207, + "cieucparenkorean": 0x3208, + "chieuchparenkorean": 0x3209, + "khieukhparenkorean": 0x320A, + "thieuthparenkorean": 0x320B, + "phieuphparenkorean": 0x320C, + "hieuhparenkorean": 0x320D, + "kiyeokaparenkorean": 0x320E, + "nieunaparenkorean": 0x320F, + "tikeutaparenkorean": 0x3210, + "rieulaparenkorean": 0x3211, + "mieumaparenkorean": 0x3212, + "pieupaparenkorean": 0x3213, + "siosaparenkorean": 0x3214, + "ieungaparenkorean": 0x3215, + "cieucaparenkorean": 0x3216, + "chieuchaparenkorean": 0x3217, + "khieukhaparenkorean": 0x3218, + "thieuthaparenkorean": 0x3219, + "phieuphaparenkorean": 0x321A, + "hieuhaparenkorean": 0x321B, + "cieucuparenkorean": 0x321C, + "oneideographicparen": 0x3220, + "twoideographicparen": 0x3221, + "threeideographicparen": 0x3222, + "fourideographicparen": 0x3223, + "fiveideographicparen": 0x3224, + "sixideographicparen": 0x3225, + "sevenideographicparen": 0x3226, + "eightideographicparen": 0x3227, + "nineideographicparen": 0x3228, + "tenideographicparen": 0x3229, + "ideographicmoonparen": 0x322A, + "ideographicfireparen": 0x322B, + "ideographicwaterparen": 0x322C, + "ideographicwoodparen": 0x322D, + "ideographicmetalparen": 0x322E, + "ideographicearthparen": 0x322F, + "ideographicsunparen": 0x3230, + "ideographicstockparen": 0x3231, + "ideographichaveparen": 0x3232, + "ideographicsocietyparen": 0x3233, + "ideographicnameparen": 0x3234, + "ideographicspecialparen": 0x3235, + "ideographicfinancialparen": 0x3236, + "ideographiccongratulationparen": 0x3237, + "ideographiclaborparen": 0x3238, + "ideographicrepresentparen": 0x3239, + "ideographiccallparen": 0x323A, + "ideographicstudyparen": 0x323B, + "ideographicsuperviseparen": 0x323C, + "ideographicenterpriseparen": 0x323D, + "ideographicresourceparen": 0x323E, + "ideographicallianceparen": 0x323F, + "ideographicfestivalparen": 0x3240, + "ideographicselfparen": 0x3242, + "ideographicreachparen": 0x3243, + "kiyeokcirclekorean": 0x3260, + "nieuncirclekorean": 0x3261, + "tikeutcirclekorean": 0x3262, + "rieulcirclekorean": 0x3263, + "mieumcirclekorean": 0x3264, + "pieupcirclekorean": 0x3265, + "sioscirclekorean": 0x3266, + "ieungcirclekorean": 0x3267, + "cieuccirclekorean": 0x3268, + "chieuchcirclekorean": 0x3269, + "khieukhcirclekorean": 0x326A, + "thieuthcirclekorean": 0x326B, + "phieuphcirclekorean": 0x326C, + "hieuhcirclekorean": 0x326D, + "kiyeokacirclekorean": 0x326E, + "nieunacirclekorean": 0x326F, + "tikeutacirclekorean": 0x3270, + "rieulacirclekorean": 0x3271, + "mieumacirclekorean": 0x3272, + "pieupacirclekorean": 0x3273, + "siosacirclekorean": 0x3274, + "ieungacirclekorean": 0x3275, + "cieucacirclekorean": 0x3276, + "chieuchacirclekorean": 0x3277, + "khieukhacirclekorean": 0x3278, + "thieuthacirclekorean": 0x3279, + "phieuphacirclekorean": 0x327A, + "hieuhacirclekorean": 0x327B, + "koreanstandardsymbol": 0x327F, + "ideographmooncircle": 0x328A, + "ideographfirecircle": 0x328B, + "ideographwatercircle": 0x328C, + "ideographwoodcircle": 0x328D, + "ideographmetalcircle": 0x328E, + "ideographearthcircle": 0x328F, + "ideographsuncircle": 0x3290, + "ideographnamecircle": 0x3294, + "ideographicfinancialcircle": 0x3296, + "ideographiclaborcircle": 0x3298, + "ideographicsecretcircle": 0x3299, + "ideographicexcellentcircle": 0x329D, + "ideographicprintcircle": 0x329E, + "ideographiccorrectcircle": 0x32A3, + "ideographichighcircle": 0x32A4, + "ideographiccentrecircle": 0x32A5, + "ideographiclowcircle": 0x32A6, + "ideographicleftcircle": 0x32A7, + "ideographicrightcircle": 0x32A8, + "ideographicmedicinecircle": 0x32A9, + "apaatosquare": 0x3300, + "aarusquare": 0x3303, + "intisquare": 0x3305, + "karoriisquare": 0x330D, + "kirosquare": 0x3314, + "kiroguramusquare": 0x3315, + "kiromeetorusquare": 0x3316, + "guramusquare": 0x3318, + "kooposquare": 0x331E, + "sentisquare": 0x3322, + "sentosquare": 0x3323, + "dorusquare": 0x3326, + "tonsquare": 0x3327, + "haitusquare": 0x332A, + "paasentosquare": 0x332B, + "birusquare": 0x3331, + "huiitosquare": 0x3333, + "hekutaarusquare": 0x3336, + "herutusquare": 0x3339, + "peezisquare": 0x333B, + "hoonsquare": 0x3342, + "mansyonsquare": 0x3347, + "mirisquare": 0x3349, + "miribaarusquare": 0x334A, + "meetorusquare": 0x334D, + "yaadosquare": 0x334E, + "rittorusquare": 0x3351, + "wattosquare": 0x3357, + "heiseierasquare": 0x337B, + "syouwaerasquare": 0x337C, + "taisyouerasquare": 0x337D, + "meizierasquare": 0x337E, + "corporationsquare": 0x337F, + "paampssquare": 0x3380, + "nasquare": 0x3381, + "muasquare": 0x3382, + "masquare": 0x3383, + "kasquare": 0x3384, + "KBsquare": 0x3385, + "MBsquare": 0x3386, + "GBsquare": 0x3387, + "calsquare": 0x3388, + "kcalsquare": 0x3389, + "pfsquare": 0x338A, + "nfsquare": 0x338B, + "mufsquare": 0x338C, + "mugsquare": 0x338D, + "squaremg": 0x338E, + "squarekg": 0x338F, + "Hzsquare": 0x3390, + "khzsquare": 0x3391, + "mhzsquare": 0x3392, + "ghzsquare": 0x3393, + "thzsquare": 0x3394, + "mulsquare": 0x3395, + "mlsquare": 0x3396, + "dlsquare": 0x3397, + "klsquare": 0x3398, + "fmsquare": 0x3399, + "nmsquare": 0x339A, + "mumsquare": 0x339B, + "squaremm": 0x339C, + "squarecm": 0x339D, + "squarekm": 0x339E, + "mmsquaredsquare": 0x339F, + "cmsquaredsquare": 0x33A0, + "squaremsquared": 0x33A1, + "kmsquaredsquare": 0x33A2, + "mmcubedsquare": 0x33A3, + "cmcubedsquare": 0x33A4, + "mcubedsquare": 0x33A5, + "kmcubedsquare": 0x33A6, + "moverssquare": 0x33A7, + "moverssquaredsquare": 0x33A8, + "pasquare": 0x33A9, + "kpasquare": 0x33AA, + "mpasquare": 0x33AB, + "gpasquare": 0x33AC, + "radsquare": 0x33AD, + "radoverssquare": 0x33AE, + "radoverssquaredsquare": 0x33AF, + "pssquare": 0x33B0, + "nssquare": 0x33B1, + "mussquare": 0x33B2, + "mssquare": 0x33B3, + "pvsquare": 0x33B4, + "nvsquare": 0x33B5, + "muvsquare": 0x33B6, + "mvsquare": 0x33B7, + "kvsquare": 0x33B8, + "mvmegasquare": 0x33B9, + "pwsquare": 0x33BA, + "nwsquare": 0x33BB, + "muwsquare": 0x33BC, + "mwsquare": 0x33BD, + "kwsquare": 0x33BE, + "mwmegasquare": 0x33BF, + "kohmsquare": 0x33C0, + "mohmsquare": 0x33C1, + "amsquare": 0x33C2, + "bqsquare": 0x33C3, + "squarecc": 0x33C4, + "cdsquare": 0x33C5, + "coverkgsquare": 0x33C6, + "cosquare": 0x33C7, + "dbsquare": 0x33C8, + "gysquare": 0x33C9, + "hasquare": 0x33CA, + "HPsquare": 0x33CB, + "KKsquare": 0x33CD, + "squarekmcapital": 0x33CE, + "ktsquare": 0x33CF, + "lmsquare": 0x33D0, + "squareln": 0x33D1, + "squarelog": 0x33D2, + "lxsquare": 0x33D3, + "mbsquare": 0x33D4, + "squaremil": 0x33D5, + "molsquare": 0x33D6, + "pmsquare": 0x33D8, + "srsquare": 0x33DB, + "svsquare": 0x33DC, + "wbsquare": 0x33DD, + "twentyhangzhou": 0x5344, + "dotlessj": 0xF6BE, + "LL": 0xF6BF, + "ll": 0xF6C0, + "commaaccent": 0xF6C3, + "afii10063": 0xF6C4, + "afii10064": 0xF6C5, + "afii10192": 0xF6C6, + "afii10831": 0xF6C7, + "afii10832": 0xF6C8, + "Acute": 0xF6C9, + "Caron": 0xF6CA, + "Dieresis": 0xF6CB, + "DieresisAcute": 0xF6CC, + "DieresisGrave": 0xF6CD, + "Grave": 0xF6CE, + "Hungarumlaut": 0xF6CF, + "Macron": 0xF6D0, + "cyrBreve": 0xF6D1, + "cyrFlex": 0xF6D2, + "dblGrave": 0xF6D3, + "cyrbreve": 0xF6D4, + "cyrflex": 0xF6D5, + "dblgrave": 0xF6D6, + "dieresisacute": 0xF6D7, + "dieresisgrave": 0xF6D8, + "copyrightserif": 0xF6D9, + "registerserif": 0xF6DA, + "trademarkserif": 0xF6DB, + "onefitted": 0xF6DC, + "rupiah": 0xF6DD, + "threequartersemdash": 0xF6DE, + "centinferior": 0xF6DF, + "centsuperior": 0xF6E0, + "commainferior": 0xF6E1, + "commasuperior": 0xF6E2, + "dollarinferior": 0xF6E3, + "dollarsuperior": 0xF6E4, + "hypheninferior": 0xF6E5, + "hyphensuperior": 0xF6E6, + "periodinferior": 0xF6E7, + "periodsuperior": 0xF6E8, + "asuperior": 0xF6E9, + "bsuperior": 0xF6EA, + "dsuperior": 0xF6EB, + "esuperior": 0xF6EC, + "isuperior": 0xF6ED, + "lsuperior": 0xF6EE, + "msuperior": 0xF6EF, + "osuperior": 0xF6F0, + "rsuperior": 0xF6F1, + "ssuperior": 0xF6F2, + "tsuperior": 0xF6F3, + "Brevesmall": 0xF6F4, + "Caronsmall": 0xF6F5, + "Circumflexsmall": 0xF6F6, + "Dotaccentsmall": 0xF6F7, + "Hungarumlautsmall": 0xF6F8, + "Lslashsmall": 0xF6F9, + "OEsmall": 0xF6FA, + "Ogoneksmall": 0xF6FB, + "Ringsmall": 0xF6FC, + "Scaronsmall": 0xF6FD, + "Tildesmall": 0xF6FE, + "Zcaronsmall": 0xF6FF, + "exclamsmall": 0xF721, + "dollaroldstyle": 0xF724, + "ampersandsmall": 0xF726, + "zerooldstyle": 0xF730, + "oneoldstyle": 0xF731, + "twooldstyle": 0xF732, + "threeoldstyle": 0xF733, + "fouroldstyle": 0xF734, + "fiveoldstyle": 0xF735, + "sixoldstyle": 0xF736, + "sevenoldstyle": 0xF737, + "eightoldstyle": 0xF738, + "nineoldstyle": 0xF739, + "questionsmall": 0xF73F, + "Gravesmall": 0xF760, + "Asmall": 0xF761, + "Bsmall": 0xF762, + "Csmall": 0xF763, + "Dsmall": 0xF764, + "Esmall": 0xF765, + "Fsmall": 0xF766, + "Gsmall": 0xF767, + "Hsmall": 0xF768, + "Ismall": 0xF769, + "Jsmall": 0xF76A, + "Ksmall": 0xF76B, + "Lsmall": 0xF76C, + "Msmall": 0xF76D, + "Nsmall": 0xF76E, + "Osmall": 0xF76F, + "Psmall": 0xF770, + "Qsmall": 0xF771, + "Rsmall": 0xF772, + "Ssmall": 0xF773, + "Tsmall": 0xF774, + "Usmall": 0xF775, + "Vsmall": 0xF776, + "Wsmall": 0xF777, + "Xsmall": 0xF778, + "Ysmall": 0xF779, + "Zsmall": 0xF77A, + "exclamdownsmall": 0xF7A1, + "centoldstyle": 0xF7A2, + "Dieresissmall": 0xF7A8, + "Macronsmall": 0xF7AF, + "Acutesmall": 0xF7B4, + "Cedillasmall": 0xF7B8, + "questiondownsmall": 0xF7BF, + "Agravesmall": 0xF7E0, + "Aacutesmall": 0xF7E1, + "Acircumflexsmall": 0xF7E2, + "Atildesmall": 0xF7E3, + "Adieresissmall": 0xF7E4, + "Aringsmall": 0xF7E5, + "AEsmall": 0xF7E6, + "Ccedillasmall": 0xF7E7, + "Egravesmall": 0xF7E8, + "Eacutesmall": 0xF7E9, + "Ecircumflexsmall": 0xF7EA, + "Edieresissmall": 0xF7EB, + "Igravesmall": 0xF7EC, + "Iacutesmall": 0xF7ED, + "Icircumflexsmall": 0xF7EE, + "Idieresissmall": 0xF7EF, + "Ethsmall": 0xF7F0, + "Ntildesmall": 0xF7F1, + "Ogravesmall": 0xF7F2, + "Oacutesmall": 0xF7F3, + "Ocircumflexsmall": 0xF7F4, + "Otildesmall": 0xF7F5, + "Odieresissmall": 0xF7F6, + "Oslashsmall": 0xF7F8, + "Ugravesmall": 0xF7F9, + "Uacutesmall": 0xF7FA, + "Ucircumflexsmall": 0xF7FB, + "Udieresissmall": 0xF7FC, + "Yacutesmall": 0xF7FD, + "Thornsmall": 0xF7FE, + "Ydieresissmall": 0xF7FF, + "maihanakatleftthai": 0xF884, + "saraileftthai": 0xF885, + "saraiileftthai": 0xF886, + "saraueleftthai": 0xF887, + "saraueeleftthai": 0xF888, + "maitaikhuleftthai": 0xF889, + "maiekupperleftthai": 0xF88A, + "maieklowrightthai": 0xF88B, + "maieklowleftthai": 0xF88C, + "maithoupperleftthai": 0xF88D, + "maitholowrightthai": 0xF88E, + "maitholowleftthai": 0xF88F, + "maitriupperleftthai": 0xF890, + "maitrilowrightthai": 0xF891, + "maitrilowleftthai": 0xF892, + "maichattawaupperleftthai": 0xF893, + "maichattawalowrightthai": 0xF894, + "maichattawalowleftthai": 0xF895, + "thanthakhatupperleftthai": 0xF896, + "thanthakhatlowrightthai": 0xF897, + "thanthakhatlowleftthai": 0xF898, + "nikhahitleftthai": 0xF899, + "radicalex": 0xF8E5, + "arrowvertex": 0xF8E6, + "arrowhorizex": 0xF8E7, + "registersans": 0xF8E8, + "copyrightsans": 0xF8E9, + "trademarksans": 0xF8EA, + "parenlefttp": 0xF8EB, + "parenleftex": 0xF8EC, + "parenleftbt": 0xF8ED, + "bracketlefttp": 0xF8EE, + "bracketleftex": 0xF8EF, + "bracketleftbt": 0xF8F0, + "bracelefttp": 0xF8F1, + "braceleftmid": 0xF8F2, + "braceleftbt": 0xF8F3, + "braceex": 0xF8F4, + "integralex": 0xF8F5, + "parenrighttp": 0xF8F6, + "parenrightex": 0xF8F7, + "parenrightbt": 0xF8F8, + "bracketrighttp": 0xF8F9, + "bracketrightex": 0xF8FA, + "bracketrightbt": 0xF8FB, + "bracerighttp": 0xF8FC, + "bracerightmid": 0xF8FD, + "bracerightbt": 0xF8FE, + "apple": 0xF8FF, + "ff": 0xFB00, + "fi": 0xFB01, + "fl": 0xFB02, + "ffi": 0xFB03, + "ffl": 0xFB04, + "afii57705": 0xFB1F, + "doubleyodpatah": 0xFB1F, + "doubleyodpatahhebrew": 0xFB1F, + "yodyodpatahhebrew": 0xFB1F, + "ayinaltonehebrew": 0xFB20, + "afii57694": 0xFB2A, + "shinshindot": 0xFB2A, + "shinshindothebrew": 0xFB2A, + "afii57695": 0xFB2B, + "shinsindot": 0xFB2B, + "shinsindothebrew": 0xFB2B, + "shindageshshindot": 0xFB2C, + "shindageshshindothebrew": 0xFB2C, + "shindageshsindot": 0xFB2D, + "shindageshsindothebrew": 0xFB2D, + "alefpatahhebrew": 0xFB2E, + "alefqamatshebrew": 0xFB2F, + "alefdageshhebrew": 0xFB30, + "betdagesh": 0xFB31, + "betdageshhebrew": 0xFB31, + "gimeldagesh": 0xFB32, + "gimeldageshhebrew": 0xFB32, + "daletdagesh": 0xFB33, + "daletdageshhebrew": 0xFB33, + "hedagesh": 0xFB34, + "hedageshhebrew": 0xFB34, + "afii57723": 0xFB35, + "vavdagesh": 0xFB35, + "vavdagesh65": 0xFB35, + "vavdageshhebrew": 0xFB35, + "zayindagesh": 0xFB36, + "zayindageshhebrew": 0xFB36, + "tetdagesh": 0xFB38, + "tetdageshhebrew": 0xFB38, + "yoddagesh": 0xFB39, + "yoddageshhebrew": 0xFB39, + "finalkafdagesh": 0xFB3A, + "finalkafdageshhebrew": 0xFB3A, + "kafdagesh": 0xFB3B, + "kafdageshhebrew": 0xFB3B, + "lameddagesh": 0xFB3C, + "lameddageshhebrew": 0xFB3C, + "memdagesh": 0xFB3E, + "memdageshhebrew": 0xFB3E, + "nundagesh": 0xFB40, + "nundageshhebrew": 0xFB40, + "samekhdagesh": 0xFB41, + "samekhdageshhebrew": 0xFB41, + "pefinaldageshhebrew": 0xFB43, + "pedagesh": 0xFB44, + "pedageshhebrew": 0xFB44, + "tsadidagesh": 0xFB46, + "tsadidageshhebrew": 0xFB46, + "qofdagesh": 0xFB47, + "qofdageshhebrew": 0xFB47, + "reshdageshhebrew": 0xFB48, + "shindagesh": 0xFB49, + "shindageshhebrew": 0xFB49, + "tavdages": 0xFB4A, + "tavdagesh": 0xFB4A, + "tavdageshhebrew": 0xFB4A, + "afii57700": 0xFB4B, + "vavholam": 0xFB4B, + "vavholamhebrew": 0xFB4B, + "betrafehebrew": 0xFB4C, + "kafrafehebrew": 0xFB4D, + "perafehebrew": 0xFB4E, + "aleflamedhebrew": 0xFB4F, + "pehfinalarabic": 0xFB57, + "pehinitialarabic": 0xFB58, + "pehmedialarabic": 0xFB59, + "ttehfinalarabic": 0xFB67, + "ttehinitialarabic": 0xFB68, + "ttehmedialarabic": 0xFB69, + "vehfinalarabic": 0xFB6B, + "vehinitialarabic": 0xFB6C, + "vehmedialarabic": 0xFB6D, + "tchehfinalarabic": 0xFB7B, + "tchehinitialarabic": 0xFB7C, + "tchehmeeminitialarabic": 0xFB7C, + "tchehmedialarabic": 0xFB7D, + "ddalfinalarabic": 0xFB89, + "jehfinalarabic": 0xFB8B, + "rrehfinalarabic": 0xFB8D, + "gaffinalarabic": 0xFB93, + "gafinitialarabic": 0xFB94, + "gafmedialarabic": 0xFB95, + "noonghunnafinalarabic": 0xFB9F, + "hehhamzaaboveisolatedarabic": 0xFBA4, + "hehhamzaabovefinalarabic": 0xFBA5, + "hehfinalaltonearabic": 0xFBA7, + "hehinitialaltonearabic": 0xFBA8, + "hehmedialaltonearabic": 0xFBA9, + "yehbarreefinalarabic": 0xFBAF, + "behmeemisolatedarabic": 0xFC08, + "tehjeemisolatedarabic": 0xFC0B, + "tehhahisolatedarabic": 0xFC0C, + "tehmeemisolatedarabic": 0xFC0E, + "meemmeemisolatedarabic": 0xFC48, + "noonjeemisolatedarabic": 0xFC4B, + "noonmeemisolatedarabic": 0xFC4E, + "yehmeemisolatedarabic": 0xFC58, + "shaddadammatanarabic": 0xFC5E, + "shaddakasratanarabic": 0xFC5F, + "shaddafathaarabic": 0xFC60, + "shaddadammaarabic": 0xFC61, + "shaddakasraarabic": 0xFC62, + "behnoonfinalarabic": 0xFC6D, + "tehnoonfinalarabic": 0xFC73, + "noonnoonfinalarabic": 0xFC8D, + "yehnoonfinalarabic": 0xFC94, + "behmeeminitialarabic": 0xFC9F, + "tehjeeminitialarabic": 0xFCA1, + "tehhahinitialarabic": 0xFCA2, + "tehmeeminitialarabic": 0xFCA4, + "lamjeeminitialarabic": 0xFCC9, + "lamhahinitialarabic": 0xFCCA, + "lamkhahinitialarabic": 0xFCCB, + "lammeeminitialarabic": 0xFCCC, + "meemmeeminitialarabic": 0xFCD1, + "noonjeeminitialarabic": 0xFCD2, + "noonmeeminitialarabic": 0xFCD5, + "yehmeeminitialarabic": 0xFCDD, + "parenleftaltonearabic": 0xFD3E, + "parenrightaltonearabic": 0xFD3F, + "lammeemhahinitialarabic": 0xFD88, + "lamlamhehisolatedarabic": 0xFDF2, + "sallallahoualayhewasallamarabic": 0xFDFA, + "twodotleadervertical": 0xFE30, + "emdashvertical": 0xFE31, + "endashvertical": 0xFE32, + "underscorevertical": 0xFE33, + "wavyunderscorevertical": 0xFE34, + "parenleftvertical": 0xFE35, + "parenrightvertical": 0xFE36, + "braceleftvertical": 0xFE37, + "bracerightvertical": 0xFE38, + "tortoiseshellbracketleftvertical": 0xFE39, + "tortoiseshellbracketrightvertical": 0xFE3A, + "blacklenticularbracketleftvertical": 0xFE3B, + "blacklenticularbracketrightvertical": 0xFE3C, + "dblanglebracketleftvertical": 0xFE3D, + "dblanglebracketrightvertical": 0xFE3E, + "anglebracketleftvertical": 0xFE3F, + "anglebracketrightvertical": 0xFE40, + "cornerbracketleftvertical": 0xFE41, + "cornerbracketrightvertical": 0xFE42, + "whitecornerbracketleftvertical": 0xFE43, + "whitecornerbracketrightvertical": 0xFE44, + "overlinedashed": 0xFE49, + "overlinecenterline": 0xFE4A, + "overlinewavy": 0xFE4B, + "overlinedblwavy": 0xFE4C, + "lowlinedashed": 0xFE4D, + "lowlinecenterline": 0xFE4E, + "underscorewavy": 0xFE4F, + "commasmall": 0xFE50, + "periodsmall": 0xFE52, + "semicolonsmall": 0xFE54, + "colonsmall": 0xFE55, + "parenleftsmall": 0xFE59, + "parenrightsmall": 0xFE5A, + "braceleftsmall": 0xFE5B, + "bracerightsmall": 0xFE5C, + "tortoiseshellbracketleftsmall": 0xFE5D, + "tortoiseshellbracketrightsmall": 0xFE5E, + "numbersignsmall": 0xFE5F, + "asterisksmall": 0xFE61, + "plussmall": 0xFE62, + "hyphensmall": 0xFE63, + "lesssmall": 0xFE64, + "greatersmall": 0xFE65, + "equalsmall": 0xFE66, + "dollarsmall": 0xFE69, + "percentsmall": 0xFE6A, + "atsmall": 0xFE6B, + "alefmaddaabovefinalarabic": 0xFE82, + "alefhamzaabovefinalarabic": 0xFE84, + "wawhamzaabovefinalarabic": 0xFE86, + "alefhamzabelowfinalarabic": 0xFE88, + "yehhamzaabovefinalarabic": 0xFE8A, + "yehhamzaaboveinitialarabic": 0xFE8B, + "yehhamzaabovemedialarabic": 0xFE8C, + "aleffinalarabic": 0xFE8E, + "behfinalarabic": 0xFE90, + "behinitialarabic": 0xFE91, + "behmedialarabic": 0xFE92, + "tehmarbutafinalarabic": 0xFE94, + "tehfinalarabic": 0xFE96, + "tehinitialarabic": 0xFE97, + "tehmedialarabic": 0xFE98, + "thehfinalarabic": 0xFE9A, + "thehinitialarabic": 0xFE9B, + "thehmedialarabic": 0xFE9C, + "jeemfinalarabic": 0xFE9E, + "jeeminitialarabic": 0xFE9F, + "jeemmedialarabic": 0xFEA0, + "hahfinalarabic": 0xFEA2, + "hahinitialarabic": 0xFEA3, + "hahmedialarabic": 0xFEA4, + "khahfinalarabic": 0xFEA6, + "khahinitialarabic": 0xFEA7, + "khahmedialarabic": 0xFEA8, + "dalfinalarabic": 0xFEAA, + "thalfinalarabic": 0xFEAC, + "rehfinalarabic": 0xFEAE, + "zainfinalarabic": 0xFEB0, + "seenfinalarabic": 0xFEB2, + "seeninitialarabic": 0xFEB3, + "seenmedialarabic": 0xFEB4, + "sheenfinalarabic": 0xFEB6, + "sheeninitialarabic": 0xFEB7, + "sheenmedialarabic": 0xFEB8, + "sadfinalarabic": 0xFEBA, + "sadinitialarabic": 0xFEBB, + "sadmedialarabic": 0xFEBC, + "dadfinalarabic": 0xFEBE, + "dadinitialarabic": 0xFEBF, + "dadmedialarabic": 0xFEC0, + "tahfinalarabic": 0xFEC2, + "tahinitialarabic": 0xFEC3, + "tahmedialarabic": 0xFEC4, + "zahfinalarabic": 0xFEC6, + "zahinitialarabic": 0xFEC7, + "zahmedialarabic": 0xFEC8, + "ainfinalarabic": 0xFECA, + "aininitialarabic": 0xFECB, + "ainmedialarabic": 0xFECC, + "ghainfinalarabic": 0xFECE, + "ghaininitialarabic": 0xFECF, + "ghainmedialarabic": 0xFED0, + "fehfinalarabic": 0xFED2, + "fehinitialarabic": 0xFED3, + "fehmedialarabic": 0xFED4, + "qaffinalarabic": 0xFED6, + "qafinitialarabic": 0xFED7, + "qafmedialarabic": 0xFED8, + "kaffinalarabic": 0xFEDA, + "kafinitialarabic": 0xFEDB, + "kafmedialarabic": 0xFEDC, + "lamfinalarabic": 0xFEDE, + "laminitialarabic": 0xFEDF, + "lammeemjeeminitialarabic": 0xFEDF, + "lammeemkhahinitialarabic": 0xFEDF, + "lammedialarabic": 0xFEE0, + "meemfinalarabic": 0xFEE2, + "meeminitialarabic": 0xFEE3, + "meemmedialarabic": 0xFEE4, + "noonfinalarabic": 0xFEE6, + "nooninitialarabic": 0xFEE7, + "noonhehinitialarabic": 0xFEE7, + "noonmedialarabic": 0xFEE8, + "hehfinalalttwoarabic": 0xFEEA, + "hehfinalarabic": 0xFEEA, + "hehinitialarabic": 0xFEEB, + "hehmedialarabic": 0xFEEC, + "wawfinalarabic": 0xFEEE, + "alefmaksurafinalarabic": 0xFEF0, + "yehfinalarabic": 0xFEF2, + "alefmaksurainitialarabic": 0xFEF3, + "yehinitialarabic": 0xFEF3, + "alefmaksuramedialarabic": 0xFEF4, + "yehmedialarabic": 0xFEF4, + "lamalefmaddaaboveisolatedarabic": 0xFEF5, + "lamalefmaddaabovefinalarabic": 0xFEF6, + "lamalefhamzaaboveisolatedarabic": 0xFEF7, + "lamalefhamzaabovefinalarabic": 0xFEF8, + "lamalefhamzabelowisolatedarabic": 0xFEF9, + "lamalefhamzabelowfinalarabic": 0xFEFA, + "lamalefisolatedarabic": 0xFEFB, + "lamaleffinalarabic": 0xFEFC, + "zerowidthjoiner": 0xFEFF, + "exclammonospace": 0xFF01, + "quotedblmonospace": 0xFF02, + "numbersignmonospace": 0xFF03, + "dollarmonospace": 0xFF04, + "percentmonospace": 0xFF05, + "ampersandmonospace": 0xFF06, + "quotesinglemonospace": 0xFF07, + "parenleftmonospace": 0xFF08, + "parenrightmonospace": 0xFF09, + "asteriskmonospace": 0xFF0A, + "plusmonospace": 0xFF0B, + "commamonospace": 0xFF0C, + "hyphenmonospace": 0xFF0D, + "periodmonospace": 0xFF0E, + "slashmonospace": 0xFF0F, + "zeromonospace": 0xFF10, + "onemonospace": 0xFF11, + "twomonospace": 0xFF12, + "threemonospace": 0xFF13, + "fourmonospace": 0xFF14, + "fivemonospace": 0xFF15, + "sixmonospace": 0xFF16, + "sevenmonospace": 0xFF17, + "eightmonospace": 0xFF18, + "ninemonospace": 0xFF19, + "colonmonospace": 0xFF1A, + "semicolonmonospace": 0xFF1B, + "lessmonospace": 0xFF1C, + "equalmonospace": 0xFF1D, + "greatermonospace": 0xFF1E, + "questionmonospace": 0xFF1F, + "atmonospace": 0xFF20, + "Amonospace": 0xFF21, + "Bmonospace": 0xFF22, + "Cmonospace": 0xFF23, + "Dmonospace": 0xFF24, + "Emonospace": 0xFF25, + "Fmonospace": 0xFF26, + "Gmonospace": 0xFF27, + "Hmonospace": 0xFF28, + "Imonospace": 0xFF29, + "Jmonospace": 0xFF2A, + "Kmonospace": 0xFF2B, + "Lmonospace": 0xFF2C, + "Mmonospace": 0xFF2D, + "Nmonospace": 0xFF2E, + "Omonospace": 0xFF2F, + "Pmonospace": 0xFF30, + "Qmonospace": 0xFF31, + "Rmonospace": 0xFF32, + "Smonospace": 0xFF33, + "Tmonospace": 0xFF34, + "Umonospace": 0xFF35, + "Vmonospace": 0xFF36, + "Wmonospace": 0xFF37, + "Xmonospace": 0xFF38, + "Ymonospace": 0xFF39, + "Zmonospace": 0xFF3A, + "bracketleftmonospace": 0xFF3B, + "backslashmonospace": 0xFF3C, + "bracketrightmonospace": 0xFF3D, + "asciicircummonospace": 0xFF3E, + "underscoremonospace": 0xFF3F, + "gravemonospace": 0xFF40, + "amonospace": 0xFF41, + "bmonospace": 0xFF42, + "cmonospace": 0xFF43, + "dmonospace": 0xFF44, + "emonospace": 0xFF45, + "fmonospace": 0xFF46, + "gmonospace": 0xFF47, + "hmonospace": 0xFF48, + "imonospace": 0xFF49, + "jmonospace": 0xFF4A, + "kmonospace": 0xFF4B, + "lmonospace": 0xFF4C, + "mmonospace": 0xFF4D, + "nmonospace": 0xFF4E, + "omonospace": 0xFF4F, + "pmonospace": 0xFF50, + "qmonospace": 0xFF51, + "rmonospace": 0xFF52, + "smonospace": 0xFF53, + "tmonospace": 0xFF54, + "umonospace": 0xFF55, + "vmonospace": 0xFF56, + "wmonospace": 0xFF57, + "xmonospace": 0xFF58, + "ymonospace": 0xFF59, + "zmonospace": 0xFF5A, + "braceleftmonospace": 0xFF5B, + "barmonospace": 0xFF5C, + "bracerightmonospace": 0xFF5D, + "asciitildemonospace": 0xFF5E, + "periodhalfwidth": 0xFF61, + "cornerbracketlefthalfwidth": 0xFF62, + "cornerbracketrighthalfwidth": 0xFF63, + "ideographiccommaleft": 0xFF64, + "middledotkatakanahalfwidth": 0xFF65, + "wokatakanahalfwidth": 0xFF66, + "asmallkatakanahalfwidth": 0xFF67, + "ismallkatakanahalfwidth": 0xFF68, + "usmallkatakanahalfwidth": 0xFF69, + "esmallkatakanahalfwidth": 0xFF6A, + "osmallkatakanahalfwidth": 0xFF6B, + "yasmallkatakanahalfwidth": 0xFF6C, + "yusmallkatakanahalfwidth": 0xFF6D, + "yosmallkatakanahalfwidth": 0xFF6E, + "tusmallkatakanahalfwidth": 0xFF6F, + "katahiraprolongmarkhalfwidth": 0xFF70, + "akatakanahalfwidth": 0xFF71, + "ikatakanahalfwidth": 0xFF72, + "ukatakanahalfwidth": 0xFF73, + "ekatakanahalfwidth": 0xFF74, + "okatakanahalfwidth": 0xFF75, + "kakatakanahalfwidth": 0xFF76, + "kikatakanahalfwidth": 0xFF77, + "kukatakanahalfwidth": 0xFF78, + "kekatakanahalfwidth": 0xFF79, + "kokatakanahalfwidth": 0xFF7A, + "sakatakanahalfwidth": 0xFF7B, + "sikatakanahalfwidth": 0xFF7C, + "sukatakanahalfwidth": 0xFF7D, + "sekatakanahalfwidth": 0xFF7E, + "sokatakanahalfwidth": 0xFF7F, + "takatakanahalfwidth": 0xFF80, + "tikatakanahalfwidth": 0xFF81, + "tukatakanahalfwidth": 0xFF82, + "tekatakanahalfwidth": 0xFF83, + "tokatakanahalfwidth": 0xFF84, + "nakatakanahalfwidth": 0xFF85, + "nikatakanahalfwidth": 0xFF86, + "nukatakanahalfwidth": 0xFF87, + "nekatakanahalfwidth": 0xFF88, + "nokatakanahalfwidth": 0xFF89, + "hakatakanahalfwidth": 0xFF8A, + "hikatakanahalfwidth": 0xFF8B, + "hukatakanahalfwidth": 0xFF8C, + "hekatakanahalfwidth": 0xFF8D, + "hokatakanahalfwidth": 0xFF8E, + "makatakanahalfwidth": 0xFF8F, + "mikatakanahalfwidth": 0xFF90, + "mukatakanahalfwidth": 0xFF91, + "mekatakanahalfwidth": 0xFF92, + "mokatakanahalfwidth": 0xFF93, + "yakatakanahalfwidth": 0xFF94, + "yukatakanahalfwidth": 0xFF95, + "yokatakanahalfwidth": 0xFF96, + "rakatakanahalfwidth": 0xFF97, + "rikatakanahalfwidth": 0xFF98, + "rukatakanahalfwidth": 0xFF99, + "rekatakanahalfwidth": 0xFF9A, + "rokatakanahalfwidth": 0xFF9B, + "wakatakanahalfwidth": 0xFF9C, + "nkatakanahalfwidth": 0xFF9D, + "voicedmarkkanahalfwidth": 0xFF9E, + "semivoicedmarkkanahalfwidth": 0xFF9F, + "centmonospace": 0xFFE0, + "sterlingmonospace": 0xFFE1, + "macronmonospace": 0xFFE3, + "yenmonospace": 0xFFE5, + "wonmonospace": 0xFFE6, +} diff --git a/vendor/rsc.io/pdf/page.go b/vendor/rsc.io/pdf/page.go new file mode 100644 index 000000000..9c7d68812 --- /dev/null +++ b/vendor/rsc.io/pdf/page.go @@ -0,0 +1,666 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pdf + +import ( + "fmt" + "strings" +) + +// A Page represent a single page in a PDF file. +// The methods interpret a Page dictionary stored in V. +type Page struct { + V Value +} + +// Page returns the page for the given page number. +// Page numbers are indexed starting at 1, not 0. +// If the page is not found, Page returns a Page with p.V.IsNull(). +func (r *Reader) Page(num int) Page { + num-- // now 0-indexed + page := r.Trailer().Key("Root").Key("Pages") +Search: + for page.Key("Type").Name() == "Pages" { + count := int(page.Key("Count").Int64()) + if count < num { + return Page{} + } + kids := page.Key("Kids") + for i := 0; i < kids.Len(); i++ { + kid := kids.Index(i) + if kid.Key("Type").Name() == "Pages" { + c := int(kid.Key("Count").Int64()) + if num < c { + page = kid + continue Search + } + num -= c + continue + } + if kid.Key("Type").Name() == "Page" { + if num == 0 { + return Page{kid} + } + num-- + } + } + } + return Page{} +} + +// NumPage returns the number of pages in the PDF file. +func (r *Reader) NumPage() int { + return int(r.Trailer().Key("Root").Key("Pages").Key("Count").Int64()) +} + +func (p Page) findInherited(key string) Value { + for v := p.V; !v.IsNull(); v = v.Key("Parent") { + if r := v.Key(key); !r.IsNull() { + return r + } + } + return Value{} +} + +/* +func (p Page) MediaBox() Value { + return p.findInherited("MediaBox") +} + +func (p Page) CropBox() Value { + return p.findInherited("CropBox") +} +*/ + +// Resources returns the resources dictionary associated with the page. +func (p Page) Resources() Value { + return p.findInherited("Resources") +} + +// Fonts returns a list of the fonts associated with the page. +func (p Page) Fonts() []string { + return p.Resources().Key("Font").Keys() +} + +// Font returns the font with the given name associated with the page. +func (p Page) Font(name string) Font { + return Font{p.Resources().Key("Font").Key(name)} +} + +// A Font represent a font in a PDF file. +// The methods interpret a Font dictionary stored in V. +type Font struct { + V Value +} + +// BaseFont returns the font's name (BaseFont property). +func (f Font) BaseFont() string { + return f.V.Key("BaseFont").Name() +} + +// FirstChar returns the code point of the first character in the font. +func (f Font) FirstChar() int { + return int(f.V.Key("FirstChar").Int64()) +} + +// LastChar returns the code point of the last character in the font. +func (f Font) LastChar() int { + return int(f.V.Key("LastChar").Int64()) +} + +// Widths returns the widths of the glyphs in the font. +// In a well-formed PDF, len(f.Widths()) == f.LastChar()+1 - f.FirstChar(). +func (f Font) Widths() []float64 { + x := f.V.Key("Widths") + var out []float64 + for i := 0; i < x.Len(); i++ { + out = append(out, x.Index(i).Float64()) + } + return out +} + +// Width returns the width of the given code point. +func (f Font) Width(code int) float64 { + first := f.FirstChar() + last := f.LastChar() + if code < first || last < code { + return 0 + } + return f.V.Key("Widths").Index(code - first).Float64() +} + +// Encoder returns the encoding between font code point sequences and UTF-8. +func (f Font) Encoder() TextEncoding { + enc := f.V.Key("Encoding") + switch enc.Kind() { + case Name: + switch enc.Name() { + case "WinAnsiEncoding": + return &byteEncoder{&winAnsiEncoding} + case "MacRomanEncoding": + return &byteEncoder{&macRomanEncoding} + case "Identity-H": + // TODO: Should be big-endian UCS-2 decoder + return &nopEncoder{} + default: + println("unknown encoding", enc.Name()) + return &nopEncoder{} + } + case Dict: + return &dictEncoder{enc.Key("Differences")} + case Null: + // ok, try ToUnicode + default: + println("unexpected encoding", enc.String()) + return &nopEncoder{} + } + + toUnicode := f.V.Key("ToUnicode") + if toUnicode.Kind() == Dict { + m := readCmap(toUnicode) + if m == nil { + return &nopEncoder{} + } + return m + } + + return &byteEncoder{&pdfDocEncoding} +} + +type dictEncoder struct { + v Value +} + +func (e *dictEncoder) Decode(raw string) (text string) { + r := make([]rune, 0, len(raw)) + for i := 0; i < len(raw); i++ { + ch := rune(raw[i]) + n := -1 + for j := 0; j < e.v.Len(); j++ { + x := e.v.Index(j) + if x.Kind() == Integer { + n = int(x.Int64()) + continue + } + if x.Kind() == Name { + if int(raw[i]) == n { + r := nameToRune[x.Name()] + if r != 0 { + ch = r + break + } + } + n++ + } + } + r = append(r, ch) + } + return string(r) +} + +// A TextEncoding represents a mapping between +// font code points and UTF-8 text. +type TextEncoding interface { + // Decode returns the UTF-8 text corresponding to + // the sequence of code points in raw. + Decode(raw string) (text string) +} + +type nopEncoder struct { +} + +func (e *nopEncoder) Decode(raw string) (text string) { + return raw +} + +type byteEncoder struct { + table *[256]rune +} + +func (e *byteEncoder) Decode(raw string) (text string) { + r := make([]rune, 0, len(raw)) + for i := 0; i < len(raw); i++ { + r = append(r, e.table[raw[i]]) + } + return string(r) +} + +type cmap struct { + space [4][][2]string + bfrange []bfrange +} + +func (m *cmap) Decode(raw string) (text string) { + var r []rune +Parse: + for len(raw) > 0 { + for n := 1; n <= 4 && n <= len(raw); n++ { + for _, space := range m.space[n-1] { + if space[0] <= raw[:n] && raw[:n] <= space[1] { + text := raw[:n] + raw = raw[n:] + for _, bf := range m.bfrange { + if len(bf.lo) == n && bf.lo <= text && text <= bf.hi { + if bf.dst.Kind() == String { + s := bf.dst.RawString() + if bf.lo != text { + b := []byte(s) + b[len(b)-1] += text[len(text)-1] - bf.lo[len(bf.lo)-1] + s = string(b) + } + r = append(r, []rune(utf16Decode(s))...) + continue Parse + } + if bf.dst.Kind() == Array { + fmt.Printf("array %v\n", bf.dst) + } else { + fmt.Printf("unknown dst %v\n", bf.dst) + } + r = append(r, noRune) + continue Parse + } + } + fmt.Printf("no text for %q", text) + r = append(r, noRune) + continue Parse + } + } + } + println("no code space found") + r = append(r, noRune) + raw = raw[1:] + } + return string(r) +} + +type bfrange struct { + lo string + hi string + dst Value +} + +func readCmap(toUnicode Value) *cmap { + n := -1 + var m cmap + ok := true + Interpret(toUnicode, func(stk *Stack, op string) { + if !ok { + return + } + switch op { + case "findresource": + category := stk.Pop() + key := stk.Pop() + fmt.Println("findresource", key, category) + stk.Push(newDict()) + case "begincmap": + stk.Push(newDict()) + case "endcmap": + stk.Pop() + case "begincodespacerange": + n = int(stk.Pop().Int64()) + case "endcodespacerange": + if n < 0 { + println("missing begincodespacerange") + ok = false + return + } + for i := 0; i < n; i++ { + hi, lo := stk.Pop().RawString(), stk.Pop().RawString() + if len(lo) == 0 || len(lo) != len(hi) { + println("bad codespace range") + ok = false + return + } + m.space[len(lo)-1] = append(m.space[len(lo)-1], [2]string{lo, hi}) + } + n = -1 + case "beginbfrange": + n = int(stk.Pop().Int64()) + case "endbfrange": + if n < 0 { + panic("missing beginbfrange") + } + for i := 0; i < n; i++ { + dst, srcHi, srcLo := stk.Pop(), stk.Pop().RawString(), stk.Pop().RawString() + m.bfrange = append(m.bfrange, bfrange{srcLo, srcHi, dst}) + } + case "defineresource": + category := stk.Pop().Name() + value := stk.Pop() + key := stk.Pop().Name() + fmt.Println("defineresource", key, value, category) + stk.Push(value) + default: + println("interp\t", op) + } + }) + if !ok { + return nil + } + return &m +} + +type matrix [3][3]float64 + +var ident = matrix{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} + +func (x matrix) mul(y matrix) matrix { + var z matrix + for i := 0; i < 3; i++ { + for j := 0; j < 3; j++ { + for k := 0; k < 3; k++ { + z[i][j] += x[i][k] * y[k][j] + } + } + } + return z +} + +// A Text represents a single piece of text drawn on a page. +type Text struct { + Font string // the font used + FontSize float64 // the font size, in points (1/72 of an inch) + X float64 // the X coordinate, in points, increasing left to right + Y float64 // the Y coordinate, in points, increasing bottom to top + W float64 // the width of the text, in points + S string // the actual UTF-8 text +} + +// A Rect represents a rectangle. +type Rect struct { + Min, Max Point +} + +// A Point represents an X, Y pair. +type Point struct { + X float64 + Y float64 +} + +// Content describes the basic content on a page: the text and any drawn rectangles. +type Content struct { + Text []Text + Rect []Rect +} + +type gstate struct { + Tc float64 + Tw float64 + Th float64 + Tl float64 + Tf Font + Tfs float64 + Tmode int + Trise float64 + Tm matrix + Tlm matrix + Trm matrix + CTM matrix +} + +// Content returns the page's content. +func (p Page) Content() Content { + strm := p.V.Key("Contents") + var enc TextEncoding = &nopEncoder{} + + var g = gstate{ + Th: 1, + CTM: ident, + } + + var text []Text + showText := func(s string) { + n := 0 + for _, ch := range enc.Decode(s) { + Trm := matrix{{g.Tfs * g.Th, 0, 0}, {0, g.Tfs, 0}, {0, g.Trise, 1}}.mul(g.Tm).mul(g.CTM) + w0 := g.Tf.Width(int(s[n])) + n++ + if ch != ' ' { + f := g.Tf.BaseFont() + if i := strings.Index(f, "+"); i >= 0 { + f = f[i+1:] + } + text = append(text, Text{f, Trm[0][0], Trm[2][0], Trm[2][1], w0 / 1000 * Trm[0][0], string(ch)}) + } + tx := w0/1000*g.Tfs + g.Tc + if ch == ' ' { + tx += g.Tw + } + tx *= g.Th + g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm) + } + } + + var rect []Rect + var gstack []gstate + Interpret(strm, func(stk *Stack, op string) { + n := stk.Len() + args := make([]Value, n) + for i := n - 1; i >= 0; i-- { + args[i] = stk.Pop() + } + switch op { + default: + //fmt.Println(op, args) + return + + case "cm": // update g.CTM + if len(args) != 6 { + panic("bad g.Tm") + } + var m matrix + for i := 0; i < 6; i++ { + m[i/2][i%2] = args[i].Float64() + } + m[2][2] = 1 + g.CTM = m.mul(g.CTM) + + case "gs": // set parameters from graphics state resource + gs := p.Resources().Key("ExtGState").Key(args[0].Name()) + font := gs.Key("Font") + if font.Kind() == Array && font.Len() == 2 { + //fmt.Println("FONT", font) + } + + case "f": // fill + case "g": // setgray + case "l": // lineto + case "m": // moveto + + case "cs": // set colorspace non-stroking + case "scn": // set color non-stroking + + case "re": // append rectangle to path + if len(args) != 4 { + panic("bad re") + } + x, y, w, h := args[0].Float64(), args[1].Float64(), args[2].Float64(), args[3].Float64() + rect = append(rect, Rect{Point{x, y}, Point{x + w, y + h}}) + + case "q": // save graphics state + gstack = append(gstack, g) + + case "Q": // restore graphics state + n := len(gstack) - 1 + g = gstack[n] + gstack = gstack[:n] + + case "BT": // begin text (reset text matrix and line matrix) + g.Tm = ident + g.Tlm = g.Tm + + case "ET": // end text + + case "T*": // move to start of next line + x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}} + g.Tlm = x.mul(g.Tlm) + g.Tm = g.Tlm + + case "Tc": // set character spacing + if len(args) != 1 { + panic("bad g.Tc") + } + g.Tc = args[0].Float64() + + case "TD": // move text position and set leading + if len(args) != 2 { + panic("bad Td") + } + g.Tl = -args[1].Float64() + fallthrough + case "Td": // move text position + if len(args) != 2 { + panic("bad Td") + } + tx := args[0].Float64() + ty := args[1].Float64() + x := matrix{{1, 0, 0}, {0, 1, 0}, {tx, ty, 1}} + g.Tlm = x.mul(g.Tlm) + g.Tm = g.Tlm + + case "Tf": // set text font and size + if len(args) != 2 { + panic("bad TL") + } + f := args[0].Name() + g.Tf = p.Font(f) + enc = g.Tf.Encoder() + if enc == nil { + println("no cmap for", f) + enc = &nopEncoder{} + } + g.Tfs = args[1].Float64() + + case "\"": // set spacing, move to next line, and show text + if len(args) != 3 { + panic("bad \" operator") + } + g.Tw = args[0].Float64() + g.Tc = args[1].Float64() + args = args[2:] + fallthrough + case "'": // move to next line and show text + if len(args) != 1 { + panic("bad ' operator") + } + x := matrix{{1, 0, 0}, {0, 1, 0}, {0, -g.Tl, 1}} + g.Tlm = x.mul(g.Tlm) + g.Tm = g.Tlm + fallthrough + case "Tj": // show text + if len(args) != 1 { + panic("bad Tj operator") + } + showText(args[0].RawString()) + + case "TJ": // show text, allowing individual glyph positioning + v := args[0] + for i := 0; i < v.Len(); i++ { + x := v.Index(i) + if x.Kind() == String { + showText(x.RawString()) + } else { + tx := -x.Float64() / 1000 * g.Tfs * g.Th + g.Tm = matrix{{1, 0, 0}, {0, 1, 0}, {tx, 0, 1}}.mul(g.Tm) + } + } + + case "TL": // set text leading + if len(args) != 1 { + panic("bad TL") + } + g.Tl = args[0].Float64() + + case "Tm": // set text matrix and line matrix + if len(args) != 6 { + panic("bad g.Tm") + } + var m matrix + for i := 0; i < 6; i++ { + m[i/2][i%2] = args[i].Float64() + } + m[2][2] = 1 + g.Tm = m + g.Tlm = m + + case "Tr": // set text rendering mode + if len(args) != 1 { + panic("bad Tr") + } + g.Tmode = int(args[0].Int64()) + + case "Ts": // set text rise + if len(args) != 1 { + panic("bad Ts") + } + g.Trise = args[0].Float64() + + case "Tw": // set word spacing + if len(args) != 1 { + panic("bad g.Tw") + } + g.Tw = args[0].Float64() + + case "Tz": // set horizontal text scaling + if len(args) != 1 { + panic("bad Tz") + } + g.Th = args[0].Float64() / 100 + } + }) + return Content{text, rect} +} + +// TextVertical implements sort.Interface for sorting +// a slice of Text values in vertical order, top to bottom, +// and then left to right within a line. +type TextVertical []Text + +func (x TextVertical) Len() int { return len(x) } +func (x TextVertical) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x TextVertical) Less(i, j int) bool { + if x[i].Y != x[j].Y { + return x[i].Y > x[j].Y + } + return x[i].X < x[j].X +} + +// TextVertical implements sort.Interface for sorting +// a slice of Text values in horizontal order, left to right, +// and then top to bottom within a column. +type TextHorizontal []Text + +func (x TextHorizontal) Len() int { return len(x) } +func (x TextHorizontal) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x TextHorizontal) Less(i, j int) bool { + if x[i].X != x[j].X { + return x[i].X < x[j].X + } + return x[i].Y > x[j].Y +} + +// An Outline is a tree describing the outline (also known as the table of contents) +// of a document. +type Outline struct { + Title string // title for this element + Child []Outline // child elements +} + +// Outline returns the document outline. +// The Outline returned is the root of the outline tree and typically has no Title itself. +// That is, the children of the returned root are the top-level entries in the outline. +func (r *Reader) Outline() Outline { + return buildOutline(r.Trailer().Key("Root").Key("Outlines")) +} + +func buildOutline(entry Value) Outline { + var x Outline + x.Title = entry.Key("Title").Text() + for child := entry.Key("First"); child.Kind() == Dict; child = child.Key("Next") { + x.Child = append(x.Child, buildOutline(child)) + } + return x +} diff --git a/vendor/rsc.io/pdf/ps.go b/vendor/rsc.io/pdf/ps.go new file mode 100644 index 000000000..90c551ef3 --- /dev/null +++ b/vendor/rsc.io/pdf/ps.go @@ -0,0 +1,138 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pdf + +import ( + "fmt" + "io" +) + +// A Stack represents a stack of values. +type Stack struct { + stack []Value +} + +func (stk *Stack) Len() int { + return len(stk.stack) +} + +func (stk *Stack) Push(v Value) { + stk.stack = append(stk.stack, v) +} + +func (stk *Stack) Pop() Value { + n := len(stk.stack) + if n == 0 { + return Value{} + } + v := stk.stack[n-1] + stk.stack[n-1] = Value{} + stk.stack = stk.stack[:n-1] + return v +} + +func newDict() Value { + return Value{nil, objptr{}, make(dict)} +} + +// Interpret interprets the content in a stream as a basic PostScript program, +// pushing values onto a stack and then calling the do function to execute +// operators. The do function may push or pop values from the stack as needed +// to implement op. +// +// Interpret handles the operators "dict", "currentdict", "begin", "end", "def", and "pop" itself. +// +// Interpret is not a full-blown PostScript interpreter. Its job is to handle the +// very limited PostScript found in certain supporting file formats embedded +// in PDF files, such as cmap files that describe the mapping from font code +// points to Unicode code points. +// +// There is no support for executable blocks, among other limitations. +// +func Interpret(strm Value, do func(stk *Stack, op string)) { + rd := strm.Reader() + b := newBuffer(rd, 0) + b.allowEOF = true + b.allowObjptr = false + b.allowStream = false + var stk Stack + var dicts []dict +Reading: + for { + tok := b.readToken() + if tok == io.EOF { + break + } + if kw, ok := tok.(keyword); ok { + switch kw { + case "null", "[", "]", "<<", ">>": + break + default: + for i := len(dicts) - 1; i >= 0; i-- { + if v, ok := dicts[i][name(kw)]; ok { + stk.Push(Value{nil, objptr{}, v}) + continue Reading + } + } + do(&stk, string(kw)) + continue + case "dict": + stk.Pop() + stk.Push(Value{nil, objptr{}, make(dict)}) + continue + case "currentdict": + if len(dicts) == 0 { + panic("no current dictionary") + } + stk.Push(Value{nil, objptr{}, dicts[len(dicts)-1]}) + continue + case "begin": + d := stk.Pop() + if d.Kind() != Dict { + panic("cannot begin non-dict") + } + dicts = append(dicts, d.data.(dict)) + continue + case "end": + if len(dicts) <= 0 { + panic("mismatched begin/end") + } + dicts = dicts[:len(dicts)-1] + continue + case "def": + if len(dicts) <= 0 { + panic("def without open dict") + } + val := stk.Pop() + key, ok := stk.Pop().data.(name) + if !ok { + panic("def of non-name") + } + dicts[len(dicts)-1][key] = val.data + continue + case "pop": + stk.Pop() + continue + } + } + b.unreadToken(tok) + obj := b.readObject() + stk.Push(Value{nil, objptr{}, obj}) + } +} + +type seqReader struct { + rd io.Reader + offset int64 +} + +func (r *seqReader) ReadAt(buf []byte, offset int64) (int, error) { + if offset != r.offset { + return 0, fmt.Errorf("non-sequential read of stream") + } + n, err := io.ReadFull(r.rd, buf) + r.offset += int64(n) + return n, err +} diff --git a/vendor/rsc.io/pdf/read.go b/vendor/rsc.io/pdf/read.go new file mode 100644 index 000000000..eb8b9aab2 --- /dev/null +++ b/vendor/rsc.io/pdf/read.go @@ -0,0 +1,1079 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pdf implements reading of PDF files. +// +// Overview +// +// PDF is Adobe's Portable Document Format, ubiquitous on the internet. +// A PDF document is a complex data format built on a fairly simple structure. +// This package exposes the simple structure along with some wrappers to +// extract basic information. If more complex information is needed, it is +// possible to extract that information by interpreting the structure exposed +// by this package. +// +// Specifically, a PDF is a data structure built from Values, each of which has +// one of the following Kinds: +// +// Null, for the null object. +// Integer, for an integer. +// Real, for a floating-point number. +// Bool, for a boolean value. +// Name, for a name constant (as in /Helvetica). +// String, for a string constant. +// Dict, for a dictionary of name-value pairs. +// Array, for an array of values. +// Stream, for an opaque data stream and associated header dictionary. +// +// The accessors on Value—Int64, Float64, Bool, Name, and so on—return +// a view of the data as the given type. When there is no appropriate view, +// the accessor returns a zero result. For example, the Name accessor returns +// the empty string if called on a Value v for which v.Kind() != Name. +// Returning zero values this way, especially from the Dict and Array accessors, +// which themselves return Values, makes it possible to traverse a PDF quickly +// without writing any error checking. On the other hand, it means that mistakes +// can go unreported. +// +// The basic structure of the PDF file is exposed as the graph of Values. +// +// Most richer data structures in a PDF file are dictionaries with specific interpretations +// of the name-value pairs. The Font and Page wrappers make the interpretation +// of a specific Value as the corresponding type easier. They are only helpers, though: +// they are implemented only in terms of the Value API and could be moved outside +// the package. Equally important, traversal of other PDF data structures can be implemented +// in other packages as needed. +// +package pdf // import "rsc.io/pdf" + +// BUG(rsc): The package is incomplete, although it has been used successfully on some +// large real-world PDF files. + +// BUG(rsc): There is no support for closing open PDF files. If you drop all references to a Reader, +// the underlying reader will eventually be garbage collected. + +// BUG(rsc): The library makes no attempt at efficiency. A value cache maintained in the Reader +// would probably help significantly. + +// BUG(rsc): The support for reading encrypted files is weak. + +// BUG(rsc): The Value API does not support error reporting. The intent is to allow users to +// set an error reporting callback in Reader, but that code has not been implemented. + +import ( + "bytes" + "compress/zlib" + "crypto/aes" + "crypto/cipher" + "crypto/md5" + "crypto/rc4" + "fmt" + "io" + "io/ioutil" + "os" + "sort" + "strconv" +) + +// A Reader is a single PDF file open for reading. +type Reader struct { + f io.ReaderAt + end int64 + xref []xref + trailer dict + trailerptr objptr + key []byte + useAES bool +} + +type xref struct { + ptr objptr + inStream bool + stream objptr + offset int64 +} + +func (r *Reader) errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} + +// Open opens a file for reading. +func Open(file string) (*Reader, error) { + // TODO: Deal with closing file. + f, err := os.Open(file) + if err != nil { + return nil, err + } + fi, err := f.Stat() + if err != nil { + f.Close() + return nil, err + } + return NewReader(f, fi.Size()) +} + +// NewReader opens a file for reading, using the data in f with the given total size. +func NewReader(f io.ReaderAt, size int64) (*Reader, error) { + return NewReaderEncrypted(f, size, nil) +} + +// NewReaderEncrypted opens a file for reading, using the data in f with the given total size. +// If the PDF is encrypted, NewReaderEncrypted calls pw repeatedly to obtain passwords +// to try. If pw returns the empty string, NewReaderEncrypted stops trying to decrypt +// the file and returns an error. +func NewReaderEncrypted(f io.ReaderAt, size int64, pw func() string) (*Reader, error) { + buf := make([]byte, 10) + f.ReadAt(buf, 0) + if !bytes.HasPrefix(buf, []byte("%PDF-1.")) || buf[7] < '0' || buf[7] > '7' || buf[8] != '\r' && buf[8] != '\n' { + return nil, fmt.Errorf("not a PDF file: invalid header") + } + end := size + const endChunk = 100 + buf = make([]byte, endChunk) + f.ReadAt(buf, end-endChunk) + for len(buf) > 0 && buf[len(buf)-1] == '\n' || buf[len(buf)-1] == '\r' { + buf = buf[:len(buf)-1] + } + buf = bytes.TrimRight(buf, "\r\n\t ") + if !bytes.HasSuffix(buf, []byte("%%EOF")) { + return nil, fmt.Errorf("not a PDF file: missing %%%%EOF") + } + i := findLastLine(buf, "startxref") + if i < 0 { + return nil, fmt.Errorf("malformed PDF file: missing final startxref") + } + + r := &Reader{ + f: f, + end: end, + } + pos := end - endChunk + int64(i) + b := newBuffer(io.NewSectionReader(f, pos, end-pos), pos) + if b.readToken() != keyword("startxref") { + return nil, fmt.Errorf("malformed PDF file: missing startxref") + } + startxref, ok := b.readToken().(int64) + if !ok { + return nil, fmt.Errorf("malformed PDF file: startxref not followed by integer") + } + b = newBuffer(io.NewSectionReader(r.f, startxref, r.end-startxref), startxref) + xref, trailerptr, trailer, err := readXref(r, b) + if err != nil { + return nil, err + } + r.xref = xref + r.trailer = trailer + r.trailerptr = trailerptr + if trailer["Encrypt"] == nil { + return r, nil + } + err = r.initEncrypt("") + if err == nil { + return r, nil + } + if pw == nil || err != ErrInvalidPassword { + return nil, err + } + for { + next := pw() + if next == "" { + break + } + if r.initEncrypt(next) == nil { + return r, nil + } + } + return nil, err +} + +// Trailer returns the file's Trailer value. +func (r *Reader) Trailer() Value { + return Value{r, r.trailerptr, r.trailer} +} + +func readXref(r *Reader, b *buffer) ([]xref, objptr, dict, error) { + tok := b.readToken() + if tok == keyword("xref") { + return readXrefTable(r, b) + } + if _, ok := tok.(int64); ok { + b.unreadToken(tok) + return readXrefStream(r, b) + } + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: cross-reference table not found: %v", tok) +} + +func readXrefStream(r *Reader, b *buffer) ([]xref, objptr, dict, error) { + obj1 := b.readObject() + obj, ok := obj1.(objdef) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: cross-reference table not found: %v", objfmt(obj1)) + } + strmptr := obj.ptr + strm, ok := obj.obj.(stream) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: cross-reference table not found: %v", objfmt(obj)) + } + if strm.hdr["Type"] != name("XRef") { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref stream does not have type XRef") + } + size, ok := strm.hdr["Size"].(int64) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref stream missing Size") + } + table := make([]xref, size) + + table, err := readXrefStreamData(r, strm, table, size) + if err != nil { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: %v", err) + } + + for prevoff := strm.hdr["Prev"]; prevoff != nil; { + off, ok := prevoff.(int64) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref Prev is not integer: %v", prevoff) + } + b := newBuffer(io.NewSectionReader(r.f, off, r.end-off), off) + obj1 := b.readObject() + obj, ok := obj1.(objdef) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref prev stream not found: %v", objfmt(obj1)) + } + prevstrm, ok := obj.obj.(stream) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref prev stream not found: %v", objfmt(obj)) + } + prevoff = prevstrm.hdr["Prev"] + prev := Value{r, objptr{}, prevstrm} + if prev.Kind() != Stream { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref prev stream is not stream: %v", prev) + } + if prev.Key("Type").Name() != "XRef" { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref prev stream does not have type XRef") + } + psize := prev.Key("Size").Int64() + if psize > size { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref prev stream larger than last stream") + } + if table, err = readXrefStreamData(r, prev.data.(stream), table, psize); err != nil { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: reading xref prev stream: %v", err) + } + } + + return table, strmptr, strm.hdr, nil +} + +func readXrefStreamData(r *Reader, strm stream, table []xref, size int64) ([]xref, error) { + index, _ := strm.hdr["Index"].(array) + if index == nil { + index = array{int64(0), size} + } + if len(index)%2 != 0 { + return nil, fmt.Errorf("invalid Index array %v", objfmt(index)) + } + ww, ok := strm.hdr["W"].(array) + if !ok { + return nil, fmt.Errorf("xref stream missing W array") + } + + var w []int + for _, x := range ww { + i, ok := x.(int64) + if !ok || int64(int(i)) != i { + return nil, fmt.Errorf("invalid W array %v", objfmt(ww)) + } + w = append(w, int(i)) + } + if len(w) < 3 { + return nil, fmt.Errorf("invalid W array %v", objfmt(ww)) + } + + v := Value{r, objptr{}, strm} + wtotal := 0 + for _, wid := range w { + wtotal += wid + } + buf := make([]byte, wtotal) + data := v.Reader() + for len(index) > 0 { + start, ok1 := index[0].(int64) + n, ok2 := index[1].(int64) + if !ok1 || !ok2 { + return nil, fmt.Errorf("malformed Index pair %v %v %T %T", objfmt(index[0]), objfmt(index[1]), index[0], index[1]) + } + index = index[2:] + for i := 0; i < int(n); i++ { + _, err := io.ReadFull(data, buf) + if err != nil { + return nil, fmt.Errorf("error reading xref stream: %v", err) + } + v1 := decodeInt(buf[0:w[0]]) + if w[0] == 0 { + v1 = 1 + } + v2 := decodeInt(buf[w[0] : w[0]+w[1]]) + v3 := decodeInt(buf[w[0]+w[1] : w[0]+w[1]+w[2]]) + x := int(start) + i + for cap(table) <= x { + table = append(table[:cap(table)], xref{}) + } + if table[x].ptr != (objptr{}) { + continue + } + switch v1 { + case 0: + table[x] = xref{ptr: objptr{0, 65535}} + case 1: + table[x] = xref{ptr: objptr{uint32(x), uint16(v3)}, offset: int64(v2)} + case 2: + table[x] = xref{ptr: objptr{uint32(x), 0}, inStream: true, stream: objptr{uint32(v2), 0}, offset: int64(v3)} + default: + fmt.Printf("invalid xref stream type %d: %x\n", v1, buf) + } + } + } + return table, nil +} + +func decodeInt(b []byte) int { + x := 0 + for _, c := range b { + x = x<<8 | int(c) + } + return x +} + +func readXrefTable(r *Reader, b *buffer) ([]xref, objptr, dict, error) { + var table []xref + + table, err := readXrefTableData(b, table) + if err != nil { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: %v", err) + } + + trailer, ok := b.readObject().(dict) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref table not followed by trailer dictionary") + } + + for prevoff := trailer["Prev"]; prevoff != nil; { + off, ok := prevoff.(int64) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref Prev is not integer: %v", prevoff) + } + b := newBuffer(io.NewSectionReader(r.f, off, r.end-off), off) + tok := b.readToken() + if tok != keyword("xref") { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref Prev does not point to xref") + } + table, err = readXrefTableData(b, table) + if err != nil { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: %v", err) + } + + trailer, ok := b.readObject().(dict) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: xref Prev table not followed by trailer dictionary") + } + prevoff = trailer["Prev"] + } + + size, ok := trailer[name("Size")].(int64) + if !ok { + return nil, objptr{}, nil, fmt.Errorf("malformed PDF: trailer missing /Size entry") + } + + if size < int64(len(table)) { + table = table[:size] + } + + return table, objptr{}, trailer, nil +} + +func readXrefTableData(b *buffer, table []xref) ([]xref, error) { + for { + tok := b.readToken() + if tok == keyword("trailer") { + break + } + start, ok1 := tok.(int64) + n, ok2 := b.readToken().(int64) + if !ok1 || !ok2 { + return nil, fmt.Errorf("malformed xref table") + } + for i := 0; i < int(n); i++ { + off, ok1 := b.readToken().(int64) + gen, ok2 := b.readToken().(int64) + alloc, ok3 := b.readToken().(keyword) + if !ok1 || !ok2 || !ok3 || alloc != keyword("f") && alloc != keyword("n") { + return nil, fmt.Errorf("malformed xref table") + } + x := int(start) + i + for cap(table) <= x { + table = append(table[:cap(table)], xref{}) + } + if len(table) <= x { + table = table[:x+1] + } + if alloc == "n" && table[x].offset == 0 { + table[x] = xref{ptr: objptr{uint32(x), uint16(gen)}, offset: int64(off)} + } + } + } + return table, nil +} + +func findLastLine(buf []byte, s string) int { + bs := []byte(s) + max := len(buf) + for { + i := bytes.LastIndex(buf[:max], bs) + if i <= 0 || i+len(bs) >= len(buf) { + return -1 + } + if (buf[i-1] == '\n' || buf[i-1] == '\r') && (buf[i+len(bs)] == '\n' || buf[i+len(bs)] == '\r') { + return i + } + max = i + } +} + +// A Value is a single PDF value, such as an integer, dictionary, or array. +// The zero Value is a PDF null (Kind() == Null, IsNull() = true). +type Value struct { + r *Reader + ptr objptr + data interface{} +} + +// IsNull reports whether the value is a null. It is equivalent to Kind() == Null. +func (v Value) IsNull() bool { + return v.data == nil +} + +// A ValueKind specifies the kind of data underlying a Value. +type ValueKind int + +// The PDF value kinds. +const ( + Null ValueKind = iota + Bool + Integer + Real + String + Name + Dict + Array + Stream +) + +// Kind reports the kind of value underlying v. +func (v Value) Kind() ValueKind { + switch v.data.(type) { + default: + return Null + case bool: + return Bool + case int64: + return Integer + case float64: + return Real + case string: + return String + case name: + return Name + case dict: + return Dict + case array: + return Array + case stream: + return Stream + } +} + +// String returns a textual representation of the value v. +// Note that String is not the accessor for values with Kind() == String. +// To access such values, see RawString, Text, and TextFromUTF16. +func (v Value) String() string { + return objfmt(v.data) +} + +func objfmt(x interface{}) string { + switch x := x.(type) { + default: + return fmt.Sprint(x) + case string: + if isPDFDocEncoded(x) { + return strconv.Quote(pdfDocDecode(x)) + } + if isUTF16(x) { + return strconv.Quote(utf16Decode(x[2:])) + } + return strconv.Quote(x) + case name: + return "/" + string(x) + case dict: + var keys []string + for k := range x { + keys = append(keys, string(k)) + } + sort.Strings(keys) + var buf bytes.Buffer + buf.WriteString("<<") + for i, k := range keys { + elem := x[name(k)] + if i > 0 { + buf.WriteString(" ") + } + buf.WriteString("/") + buf.WriteString(k) + buf.WriteString(" ") + buf.WriteString(objfmt(elem)) + } + buf.WriteString(">>") + return buf.String() + + case array: + var buf bytes.Buffer + buf.WriteString("[") + for i, elem := range x { + if i > 0 { + buf.WriteString(" ") + } + buf.WriteString(objfmt(elem)) + } + buf.WriteString("]") + return buf.String() + + case stream: + return fmt.Sprintf("%v@%d", objfmt(x.hdr), x.offset) + + case objptr: + return fmt.Sprintf("%d %d R", x.id, x.gen) + + case objdef: + return fmt.Sprintf("{%d %d obj}%v", x.ptr.id, x.ptr.gen, objfmt(x.obj)) + } +} + +// Bool returns v's boolean value. +// If v.Kind() != Bool, Bool returns false. +func (v Value) Bool() bool { + x, ok := v.data.(bool) + if !ok { + return false + } + return x +} + +// Int64 returns v's int64 value. +// If v.Kind() != Int64, Int64 returns 0. +func (v Value) Int64() int64 { + x, ok := v.data.(int64) + if !ok { + return 0 + } + return x +} + +// Float64 returns v's float64 value, converting from integer if necessary. +// If v.Kind() != Float64 and v.Kind() != Int64, Float64 returns 0. +func (v Value) Float64() float64 { + x, ok := v.data.(float64) + if !ok { + x, ok := v.data.(int64) + if ok { + return float64(x) + } + return 0 + } + return x +} + +// RawString returns v's string value. +// If v.Kind() != String, RawString returns the empty string. +func (v Value) RawString() string { + x, ok := v.data.(string) + if !ok { + return "" + } + return x +} + +// Text returns v's string value interpreted as a ``text string'' (defined in the PDF spec) +// and converted to UTF-8. +// If v.Kind() != String, Text returns the empty string. +func (v Value) Text() string { + x, ok := v.data.(string) + if !ok { + return "" + } + if isPDFDocEncoded(x) { + return pdfDocDecode(x) + } + if isUTF16(x) { + return utf16Decode(x[2:]) + } + return x +} + +// TextFromUTF16 returns v's string value interpreted as big-endian UTF-16 +// and then converted to UTF-8. +// If v.Kind() != String or if the data is not valid UTF-16, TextFromUTF16 returns +// the empty string. +func (v Value) TextFromUTF16() string { + x, ok := v.data.(string) + if !ok { + return "" + } + if len(x)%2 == 1 { + return "" + } + if x == "" { + return "" + } + return utf16Decode(x) +} + +// Name returns v's name value. +// If v.Kind() != Name, Name returns the empty string. +// The returned name does not include the leading slash: +// if v corresponds to the name written using the syntax /Helvetica, +// Name() == "Helvetica". +func (v Value) Name() string { + x, ok := v.data.(name) + if !ok { + return "" + } + return string(x) +} + +// Key returns the value associated with the given name key in the dictionary v. +// Like the result of the Name method, the key should not include a leading slash. +// If v is a stream, Key applies to the stream's header dictionary. +// If v.Kind() != Dict and v.Kind() != Stream, Key returns a null Value. +func (v Value) Key(key string) Value { + x, ok := v.data.(dict) + if !ok { + strm, ok := v.data.(stream) + if !ok { + return Value{} + } + x = strm.hdr + } + return v.r.resolve(v.ptr, x[name(key)]) +} + +// Keys returns a sorted list of the keys in the dictionary v. +// If v is a stream, Keys applies to the stream's header dictionary. +// If v.Kind() != Dict and v.Kind() != Stream, Keys returns nil. +func (v Value) Keys() []string { + x, ok := v.data.(dict) + if !ok { + strm, ok := v.data.(stream) + if !ok { + return nil + } + x = strm.hdr + } + keys := []string{} // not nil + for k := range x { + keys = append(keys, string(k)) + } + sort.Strings(keys) + return keys +} + +// Index returns the i'th element in the array v. +// If v.Kind() != Array or if i is outside the array bounds, +// Index returns a null Value. +func (v Value) Index(i int) Value { + x, ok := v.data.(array) + if !ok || i < 0 || i >= len(x) { + return Value{} + } + return v.r.resolve(v.ptr, x[i]) +} + +// Len returns the length of the array v. +// If v.Kind() != Array, Len returns 0. +func (v Value) Len() int { + x, ok := v.data.(array) + if !ok { + return 0 + } + return len(x) +} + +func (r *Reader) resolve(parent objptr, x interface{}) Value { + if ptr, ok := x.(objptr); ok { + if ptr.id >= uint32(len(r.xref)) { + return Value{} + } + xref := r.xref[ptr.id] + if xref.ptr != ptr || !xref.inStream && xref.offset == 0 { + return Value{} + } + var obj object + if xref.inStream { + strm := r.resolve(parent, xref.stream) + Search: + for { + if strm.Kind() != Stream { + panic("not a stream") + } + if strm.Key("Type").Name() != "ObjStm" { + panic("not an object stream") + } + n := int(strm.Key("N").Int64()) + first := strm.Key("First").Int64() + if first == 0 { + panic("missing First") + } + b := newBuffer(strm.Reader(), 0) + b.allowEOF = true + for i := 0; i < n; i++ { + id, _ := b.readToken().(int64) + off, _ := b.readToken().(int64) + if uint32(id) == ptr.id { + b.seekForward(first + off) + x = b.readObject() + break Search + } + } + ext := strm.Key("Extends") + if ext.Kind() != Stream { + panic("cannot find object in stream") + } + strm = ext + } + } else { + b := newBuffer(io.NewSectionReader(r.f, xref.offset, r.end-xref.offset), xref.offset) + b.key = r.key + b.useAES = r.useAES + obj = b.readObject() + def, ok := obj.(objdef) + if !ok { + panic(fmt.Errorf("loading %v: found %T instead of objdef", ptr, obj)) + return Value{} + } + if def.ptr != ptr { + panic(fmt.Errorf("loading %v: found %v", ptr, def.ptr)) + } + x = def.obj + } + parent = ptr + } + + switch x := x.(type) { + case nil, bool, int64, float64, name, dict, array, stream: + return Value{r, parent, x} + case string: + return Value{r, parent, x} + default: + panic(fmt.Errorf("unexpected value type %T in resolve", x)) + } +} + +type errorReadCloser struct { + err error +} + +func (e *errorReadCloser) Read([]byte) (int, error) { + return 0, e.err +} + +func (e *errorReadCloser) Close() error { + return e.err +} + +// Reader returns the data contained in the stream v. +// If v.Kind() != Stream, Reader returns a ReadCloser that +// responds to all reads with a ``stream not present'' error. +func (v Value) Reader() io.ReadCloser { + x, ok := v.data.(stream) + if !ok { + return &errorReadCloser{fmt.Errorf("stream not present")} + } + var rd io.Reader + rd = io.NewSectionReader(v.r.f, x.offset, v.Key("Length").Int64()) + if v.r.key != nil { + rd = decryptStream(v.r.key, v.r.useAES, x.ptr, rd) + } + filter := v.Key("Filter") + param := v.Key("DecodeParms") + switch filter.Kind() { + default: + panic(fmt.Errorf("unsupported filter %v", filter)) + case Null: + // ok + case Name: + rd = applyFilter(rd, filter.Name(), param) + case Array: + for i := 0; i < filter.Len(); i++ { + rd = applyFilter(rd, filter.Index(i).Name(), param.Index(i)) + } + } + + return ioutil.NopCloser(rd) +} + +func applyFilter(rd io.Reader, name string, param Value) io.Reader { + switch name { + default: + panic("unknown filter " + name) + case "FlateDecode": + zr, err := zlib.NewReader(rd) + if err != nil { + panic(err) + } + pred := param.Key("Predictor") + if pred.Kind() == Null { + return zr + } + columns := param.Key("Columns").Int64() + switch pred.Int64() { + default: + fmt.Println("unknown predictor", pred) + panic("pred") + case 12: + return &pngUpReader{r: zr, hist: make([]byte, 1+columns), tmp: make([]byte, 1+columns)} + } + } +} + +type pngUpReader struct { + r io.Reader + hist []byte + tmp []byte + pend []byte +} + +func (r *pngUpReader) Read(b []byte) (int, error) { + n := 0 + for len(b) > 0 { + if len(r.pend) > 0 { + m := copy(b, r.pend) + n += m + b = b[m:] + r.pend = r.pend[m:] + continue + } + _, err := io.ReadFull(r.r, r.tmp) + if err != nil { + return n, err + } + if r.tmp[0] != 2 { + return n, fmt.Errorf("malformed PNG-Up encoding") + } + for i, b := range r.tmp { + r.hist[i] += b + } + r.pend = r.hist[1:] + } + return n, nil +} + +var passwordPad = []byte{ + 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, + 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A, +} + +func (r *Reader) initEncrypt(password string) error { + // See PDF 32000-1:2008, §7.6. + encrypt, _ := r.resolve(objptr{}, r.trailer["Encrypt"]).data.(dict) + if encrypt["Filter"] != name("Standard") { + return fmt.Errorf("unsupported PDF: encryption filter %v", objfmt(encrypt["Filter"])) + } + n, _ := encrypt["Length"].(int64) + if n == 0 { + n = 40 + } + if n%8 != 0 || n > 128 || n < 40 { + return fmt.Errorf("malformed PDF: %d-bit encryption key", n) + } + V, _ := encrypt["V"].(int64) + if V != 1 && V != 2 && (V != 4 || !okayV4(encrypt)) { + return fmt.Errorf("unsupported PDF: encryption version V=%d; %v", V, objfmt(encrypt)) + } + + ids, ok := r.trailer["ID"].(array) + if !ok || len(ids) < 1 { + return fmt.Errorf("malformed PDF: missing ID in trailer") + } + idstr, ok := ids[0].(string) + if !ok { + return fmt.Errorf("malformed PDF: missing ID in trailer") + } + ID := []byte(idstr) + + R, _ := encrypt["R"].(int64) + if R < 2 { + return fmt.Errorf("malformed PDF: encryption revision R=%d", R) + } + if R > 4 { + return fmt.Errorf("unsupported PDF: encryption revision R=%d", R) + } + O, _ := encrypt["O"].(string) + U, _ := encrypt["U"].(string) + if len(O) != 32 || len(U) != 32 { + return fmt.Errorf("malformed PDF: missing O= or U= encryption parameters") + } + p, _ := encrypt["P"].(int64) + P := uint32(p) + + // TODO: Password should be converted to Latin-1. + pw := []byte(password) + h := md5.New() + if len(pw) >= 32 { + h.Write(pw[:32]) + } else { + h.Write(pw) + h.Write(passwordPad[:32-len(pw)]) + } + h.Write([]byte(O)) + h.Write([]byte{byte(P), byte(P >> 8), byte(P >> 16), byte(P >> 24)}) + h.Write([]byte(ID)) + key := h.Sum(nil) + + if R >= 3 { + for i := 0; i < 50; i++ { + h.Reset() + h.Write(key[:n/8]) + key = h.Sum(key[:0]) + } + key = key[:n/8] + } else { + key = key[:40/8] + } + + c, err := rc4.NewCipher(key) + if err != nil { + return fmt.Errorf("malformed PDF: invalid RC4 key: %v", err) + } + + var u []byte + if R == 2 { + u = make([]byte, 32) + copy(u, passwordPad) + c.XORKeyStream(u, u) + } else { + h.Reset() + h.Write(passwordPad) + h.Write([]byte(ID)) + u = h.Sum(nil) + c.XORKeyStream(u, u) + + for i := 1; i <= 19; i++ { + key1 := make([]byte, len(key)) + copy(key1, key) + for j := range key1 { + key1[j] ^= byte(i) + } + c, _ = rc4.NewCipher(key1) + c.XORKeyStream(u, u) + } + } + + if !bytes.HasPrefix([]byte(U), u) { + return ErrInvalidPassword + } + + r.key = key + r.useAES = V == 4 + + return nil +} + +var ErrInvalidPassword = fmt.Errorf("encrypted PDF: invalid password") + +func okayV4(encrypt dict) bool { + cf, ok := encrypt["CF"].(dict) + if !ok { + return false + } + stmf, ok := encrypt["StmF"].(name) + if !ok { + return false + } + strf, ok := encrypt["StrF"].(name) + if !ok { + return false + } + if stmf != strf { + return false + } + cfparam, ok := cf[stmf].(dict) + if cfparam["AuthEvent"] != nil && cfparam["AuthEvent"] != name("DocOpen") { + return false + } + if cfparam["Length"] != nil && cfparam["Length"] != int64(16) { + return false + } + if cfparam["CFM"] != name("AESV2") { + return false + } + return true +} + +func cryptKey(key []byte, useAES bool, ptr objptr) []byte { + h := md5.New() + h.Write(key) + h.Write([]byte{byte(ptr.id), byte(ptr.id >> 8), byte(ptr.id >> 16), byte(ptr.gen), byte(ptr.gen >> 8)}) + if useAES { + h.Write([]byte("sAlT")) + } + return h.Sum(nil) +} + +func decryptString(key []byte, useAES bool, ptr objptr, x string) string { + key = cryptKey(key, useAES, ptr) + if useAES { + panic("AES not implemented") + } else { + c, _ := rc4.NewCipher(key) + data := []byte(x) + c.XORKeyStream(data, data) + x = string(data) + } + return x +} + +func decryptStream(key []byte, useAES bool, ptr objptr, rd io.Reader) io.Reader { + key = cryptKey(key, useAES, ptr) + if useAES { + cb, err := aes.NewCipher(key) + if err != nil { + panic("AES: " + err.Error()) + } + iv := make([]byte, 16) + io.ReadFull(rd, iv) + cbc := cipher.NewCBCDecrypter(cb, iv) + rd = &cbcReader{cbc: cbc, rd: rd, buf: make([]byte, 16)} + } else { + c, _ := rc4.NewCipher(key) + rd = &cipher.StreamReader{c, rd} + } + return rd +} + +type cbcReader struct { + cbc cipher.BlockMode + rd io.Reader + buf []byte + pend []byte +} + +func (r *cbcReader) Read(b []byte) (n int, err error) { + if len(r.pend) == 0 { + _, err = io.ReadFull(r.rd, r.buf) + if err != nil { + return 0, err + } + r.cbc.CryptBlocks(r.buf, r.buf) + r.pend = r.buf + } + n = copy(b, r.pend) + r.pend = r.pend[n:] + return n, nil +} diff --git a/vendor/rsc.io/pdf/text.go b/vendor/rsc.io/pdf/text.go new file mode 100644 index 000000000..da3d08c28 --- /dev/null +++ b/vendor/rsc.io/pdf/text.go @@ -0,0 +1,158 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pdf + +import ( + "unicode" + "unicode/utf16" +) + +const noRune = unicode.ReplacementChar + +func isPDFDocEncoded(s string) bool { + if isUTF16(s) { + return false + } + for i := 0; i < len(s); i++ { + if pdfDocEncoding[s[i]] == noRune { + return false + } + } + return true +} + +func pdfDocDecode(s string) string { + for i := 0; i < len(s); i++ { + if s[i] >= 0x80 || pdfDocEncoding[s[i]] != rune(s[i]) { + goto Decode + } + } + return s + +Decode: + r := make([]rune, len(s)) + for i := 0; i < len(s); i++ { + r[i] = pdfDocEncoding[s[i]] + } + return string(r) +} + +func isUTF16(s string) bool { + return len(s) >= 2 && s[0] == 0xfe && s[1] == 0xff && len(s)%2 == 0 +} + +func utf16Decode(s string) string { + var u []uint16 + for i := 0; i < len(s); i += 2 { + u = append(u, uint16(s[i])<<8|uint16(s[i+1])) + } + return string(utf16.Decode(u)) +} + +// See PDF 32000-1:2008, Table D.2 +var pdfDocEncoding = [256]rune{ + noRune, noRune, noRune, noRune, noRune, noRune, noRune, noRune, + noRune, 0x0009, 0x000a, noRune, noRune, 0x000d, noRune, noRune, + noRune, noRune, noRune, noRune, noRune, noRune, noRune, noRune, + 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, noRune, + 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, + 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, + 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, + 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, noRune, + 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, noRune, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, +} + +var winAnsiEncoding = [256]rune{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, noRune, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, noRune, 0x017d, noRune, + noRune, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, noRune, 0x017e, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, +} + +var macRomanEncoding = [256]rune{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}